123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <script setup>
  2. import { computed, provide } from 'vue'
  3. import { optionStatus } from './config'
  4. import { cartTable } from './config'
  5. import Details from './Components/Details.vue'
  6. import Cart from './Components/Cart.vue'
  7. import { useCart } from './Composables/useCart'
  8. import { useDialog } from './Composables/useDialog'
  9. import { useForm } from '@/composables/useForm'
  10. import HistoryProduct from './Components/HistoryProduct.vue'
  11. import AppInputText from '@/components/AppInputText.vue'
  12. import AppInputNumber from '@/components/AppInputNumber.vue'
  13. import AppDropdown from '@/components/AppDropdown.vue'
  14. import AppAutoComplete from '@/components/AppAutoComplete.vue'
  15. import DashboardLayout from '@/layouts/Dashboard/DashboardLayout.vue'
  16. const props = defineProps({
  17. number: String,
  18. ppn: Number,
  19. suppliers: {
  20. type: Array,
  21. default: [],
  22. },
  23. products: {
  24. type: Array,
  25. default: [],
  26. },
  27. productPurchase: Object,
  28. })
  29. const form = useForm({
  30. status: 'pending',
  31. price: null,
  32. qty: null,
  33. supplier: null,
  34. product: null,
  35. ppn: props.ppn,
  36. checkedPpn: false,
  37. })
  38. const onSubmit = () => {
  39. form
  40. .transform((data) => ({
  41. number: props.number,
  42. status: data.status,
  43. ppn: data.checkedPpn,
  44. supplier_id: data.supplier.id,
  45. products: cart,
  46. }))
  47. .post(route('purchases.store'), {
  48. onSuccess: () => {
  49. form.reset()
  50. onClearCart()
  51. },
  52. })
  53. }
  54. provide('form', form)
  55. const productUnit = computed(() => form.product?.unit)
  56. const dropdownStatus = computed(() => {
  57. return optionStatus.filter((val) => val.value != 'success')
  58. })
  59. const {
  60. cart,
  61. cartErrors,
  62. onClearCart,
  63. onAddCart,
  64. onDeleteCart,
  65. totalCartPrice,
  66. } = useCart(form)
  67. const { onShowCreateProduct, onShowCreateSupplier } = useDialog()
  68. </script>
  69. <template>
  70. <DashboardLayout title="Tambah Pembelian">
  71. <DynamicDialog />
  72. <div class="grid">
  73. <div class="col-12 xl:col-8">
  74. <div class="grid">
  75. <div class="col-12">
  76. <Card>
  77. <template #title> Transaksi </template>
  78. <template #content>
  79. <div class="grid">
  80. <div class="col-12 md:col-6">
  81. <AppDropdown
  82. label="Status"
  83. placeholder="status"
  84. :options="dropdownStatus"
  85. :error="form.errors.status"
  86. v-model="form.status"
  87. />
  88. </div>
  89. <div class="col-12 md:col-6">
  90. <AppAutoComplete
  91. empty
  92. label="Supplier"
  93. placeholder="supplier"
  94. field="name"
  95. param="supplier"
  96. refresh-data="suppliers"
  97. :error="form.errors.suppliers_id"
  98. :suggestions="suppliers"
  99. v-model="form.supplier"
  100. >
  101. <template #item="slotProps">
  102. <template v-if="slotProps.item">
  103. <div class="flex flex-column">
  104. <span>{{ slotProps.item.name }}</span>
  105. <span>{{ slotProps.item.phone }}</span>
  106. </div>
  107. </template>
  108. </template>
  109. <template #empty>
  110. <span
  111. class="cursor-pointer"
  112. style="color: var(--primary-color)"
  113. @click="onShowCreateSupplier"
  114. >
  115. Tambah Supplier
  116. </span>
  117. </template>
  118. </AppAutoComplete>
  119. </div>
  120. </div>
  121. </template>
  122. </Card>
  123. </div>
  124. <div class="col-12">
  125. <Card>
  126. <template #title>Produk</template>
  127. <template #content>
  128. <div class="grid">
  129. <div class="col-12 md:col-6">
  130. <AppAutoComplete
  131. empty
  132. label="Produk"
  133. placeholder="produk"
  134. field="name"
  135. param="product"
  136. refresh-data="products"
  137. :disabled="!form.supplier?.id"
  138. :error="form.errors.product"
  139. :suggestions="products"
  140. v-model="form.product"
  141. >
  142. <template #item="slotProps">
  143. <template v-if="slotProps.item">
  144. <div class="flex flex-column">
  145. <span>{{ slotProps.item.number }}</span>
  146. <span>{{ slotProps.item.name }}</span>
  147. </div>
  148. </template>
  149. </template>
  150. <template #empty>
  151. <span
  152. class="cursor-pointer"
  153. style="color: var(--primary-color)"
  154. @click="onShowCreateProduct"
  155. >
  156. Tambah Produk
  157. </span>
  158. </template>
  159. </AppAutoComplete>
  160. </div>
  161. <div class="col-12 md:col-6">
  162. <AppInputText
  163. disabled
  164. label="Satuan"
  165. placeholder="satuan"
  166. v-model="productUnit"
  167. />
  168. </div>
  169. <Divider type="dashed" />
  170. <HistoryProduct
  171. :ppn="ppn"
  172. :product-purchase="productPurchase"
  173. />
  174. <Divider type="dashed" />
  175. <div class="col-12 md:col-6">
  176. <AppInputNumber
  177. label="Harga"
  178. placeholder="harga"
  179. :disabled="!form.product?.id"
  180. v-model="form.price"
  181. />
  182. </div>
  183. <div class="col-12 md:col-6">
  184. <AppInputText
  185. label="Kuantitas"
  186. placeholder="kuantitas"
  187. type="number"
  188. :disabled="!form.product?.id"
  189. v-model="form.qty"
  190. />
  191. </div>
  192. </div>
  193. </template>
  194. <template #footer>
  195. <div class="flex flex-column md:flex-row justify-content-end">
  196. <Button
  197. label="Tambah Produk"
  198. icon="pi pi-check"
  199. class="p-button-outlined"
  200. :class="{ 'p-button-danger': cartErrors.length }"
  201. :disabled="
  202. !form.price || form.qty <= 0 || !form.product?.number
  203. "
  204. @click="onAddCart"
  205. />
  206. </div>
  207. </template>
  208. </Card>
  209. </div>
  210. <div class="col-12">
  211. <Cart
  212. title="Keranjang Produk"
  213. :cart="cart"
  214. :header-table="cartTable"
  215. :btn-edit-show="false"
  216. v-model:checked-ppn="form.checkedPpn"
  217. @delete="onDeleteCart"
  218. />
  219. </div>
  220. </div>
  221. </div>
  222. <div class="col-12 xl:col-4">
  223. <Details
  224. title="Detail Pembelian"
  225. message="Pastikan semua produk sudah benar"
  226. :number="number"
  227. :status="form.status"
  228. :person="form.supplier"
  229. :product="form.product"
  230. :price="totalCartPrice()"
  231. :disabled="
  232. form.processing ||
  233. !form.status ||
  234. !form.supplier?.id ||
  235. cart.length === 0
  236. "
  237. @submit="onSubmit"
  238. />
  239. </div>
  240. </div>
  241. </DashboardLayout>
  242. </template>