PurchaseInItemForm.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <template>
  2. <el-form
  3. ref="formRef"
  4. :model="formData"
  5. :rules="formRules"
  6. v-loading="formLoading"
  7. label-width="0px"
  8. :inline-message="true"
  9. :disabled="disabled"
  10. >
  11. <el-table :data="formData" show-summary :summary-method="getSummaries" class="-mt-10px">
  12. <el-table-column label="序号" type="index" align="center" width="60" />
  13. <el-table-column label="仓库名称" min-width="125">
  14. <template #default="{ row, $index }">
  15. <el-form-item
  16. :prop="`${$index}.warehouseId`"
  17. :rules="formRules.warehouseId"
  18. class="mb-0px!"
  19. >
  20. <el-select
  21. v-model="row.warehouseId"
  22. clearable
  23. filterable
  24. placeholder="请选择仓库"
  25. @change="onChangeWarehouse($event, row)"
  26. >
  27. <el-option
  28. v-for="item in warehouseList"
  29. :key="item.id"
  30. :label="item.name"
  31. :value="item.id"
  32. />
  33. </el-select>
  34. </el-form-item>
  35. </template>
  36. </el-table-column>
  37. <el-table-column label="产品名称" min-width="180">
  38. <template #default="{ row }">
  39. <el-form-item class="mb-0px!">
  40. <el-input disabled v-model="row.productName" />
  41. </el-form-item>
  42. </template>
  43. </el-table-column>
  44. <el-table-column label="库存" min-width="100">
  45. <template #default="{ row }">
  46. <el-form-item class="mb-0px!">
  47. <el-input disabled v-model="row.stockCount" :formatter="erpCountInputFormatter" />
  48. </el-form-item>
  49. </template>
  50. </el-table-column>
  51. <el-table-column label="条码" min-width="150">
  52. <template #default="{ row }">
  53. <el-form-item class="mb-0px!">
  54. <el-input disabled v-model="row.productBarCode" />
  55. </el-form-item>
  56. </template>
  57. </el-table-column>
  58. <el-table-column label="单位" min-width="80">
  59. <template #default="{ row }">
  60. <el-form-item class="mb-0px!">
  61. <el-input disabled v-model="row.productUnitName" />
  62. </el-form-item>
  63. </template>
  64. </el-table-column>
  65. <el-table-column
  66. label="原数量"
  67. fixed="right"
  68. min-width="80"
  69. v-if="formData[0]?.totalCount != null"
  70. >
  71. <template #default="{ row }">
  72. <el-form-item class="mb-0px!">
  73. <el-input disabled v-model="row.totalCount" :formatter="erpCountInputFormatter" />
  74. </el-form-item>
  75. </template>
  76. </el-table-column>
  77. <el-table-column
  78. label="已入库"
  79. fixed="right"
  80. min-width="80"
  81. v-if="formData[0]?.inCount != null"
  82. >
  83. <template #default="{ row }">
  84. <el-form-item class="mb-0px!">
  85. <el-input disabled v-model="row.inCount" :formatter="erpCountInputFormatter" />
  86. </el-form-item>
  87. </template>
  88. </el-table-column>
  89. <el-table-column label="数量" prop="count" fixed="right" min-width="140">
  90. <template #default="{ row, $index }">
  91. <el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!">
  92. <el-input-number
  93. v-model="row.count"
  94. controls-position="right"
  95. :min="0.001"
  96. :precision="3"
  97. class="!w-100%"
  98. />
  99. </el-form-item>
  100. </template>
  101. </el-table-column>
  102. <el-table-column label="产品单价" fixed="right" min-width="120">
  103. <template #default="{ row, $index }">
  104. <el-form-item :prop="`${$index}.productPrice`" class="mb-0px!">
  105. <el-input-number
  106. v-model="row.productPrice"
  107. controls-position="right"
  108. :min="0.01"
  109. :precision="2"
  110. class="!w-100%"
  111. />
  112. </el-form-item>
  113. </template>
  114. </el-table-column>
  115. <el-table-column label="金额" prop="totalProductPrice" fixed="right" min-width="100">
  116. <template #default="{ row, $index }">
  117. <el-form-item :prop="`${$index}.totalProductPrice`" class="mb-0px!">
  118. <el-input
  119. disabled
  120. v-model="row.totalProductPrice"
  121. :formatter="erpPriceInputFormatter"
  122. />
  123. </el-form-item>
  124. </template>
  125. </el-table-column>
  126. <el-table-column label="税率(%)" fixed="right" min-width="115">
  127. <template #default="{ row, $index }">
  128. <el-form-item :prop="`${$index}.taxPercent`" class="mb-0px!">
  129. <el-input-number
  130. v-model="row.taxPercent"
  131. controls-position="right"
  132. :min="0"
  133. :precision="2"
  134. class="!w-100%"
  135. />
  136. </el-form-item>
  137. </template>
  138. </el-table-column>
  139. <el-table-column label="税额" prop="taxPrice" fixed="right" min-width="120">
  140. <template #default="{ row, $index }">
  141. <el-form-item :prop="`${$index}.taxPrice`" class="mb-0px!">
  142. <el-form-item :prop="`${$index}.taxPrice`" class="mb-0px!">
  143. <el-input disabled v-model="row.taxPrice" :formatter="erpPriceInputFormatter" />
  144. </el-form-item>
  145. </el-form-item>
  146. </template>
  147. </el-table-column>
  148. <el-table-column label="税额合计" prop="totalPrice" fixed="right" min-width="100">
  149. <template #default="{ row, $index }">
  150. <el-form-item :prop="`${$index}.totalPrice`" class="mb-0px!">
  151. <el-input disabled v-model="row.totalPrice" :formatter="erpPriceInputFormatter" />
  152. </el-form-item>
  153. </template>
  154. </el-table-column>
  155. <el-table-column label="备注" min-width="150">
  156. <template #default="{ row, $index }">
  157. <el-form-item :prop="`${$index}.remark`" class="mb-0px!">
  158. <el-input v-model="row.remark" placeholder="请输入备注" />
  159. </el-form-item>
  160. </template>
  161. </el-table-column>
  162. <el-table-column align="center" fixed="right" label="操作" width="60">
  163. <template #default="{ $index }">
  164. <el-button :disabled="formData.length === 1" @click="handleDelete($index)" link>
  165. </el-button>
  166. </template>
  167. </el-table-column>
  168. </el-table>
  169. </el-form>
  170. </template>
  171. <script setup lang="ts">
  172. import { StockApi } from '@/api/erp/stock/stock'
  173. import {
  174. erpCountInputFormatter,
  175. erpPriceInputFormatter,
  176. erpPriceMultiply,
  177. getSumValue
  178. } from '@/utils'
  179. import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
  180. const props = defineProps<{
  181. items: undefined
  182. disabled: false
  183. }>()
  184. const formLoading = ref(false) // 表单的加载中
  185. const formData = ref([])
  186. const formRules = reactive({
  187. warehouseId: [{ required: true, message: '仓库不能为空', trigger: 'blur' }],
  188. productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
  189. count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
  190. })
  191. const formRef = ref([]) // 表单 Ref
  192. const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
  193. const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
  194. /** 初始化设置入库项 */
  195. watch(
  196. () => props.items,
  197. async (val) => {
  198. val.forEach((item) => {
  199. if (item.warehouseId == null) {
  200. item.warehouseId = defaultWarehouse.value?.id
  201. }
  202. if (item.stockCount === null && item.warehouseId != null) {
  203. setStockCount(item)
  204. }
  205. })
  206. formData.value = val
  207. },
  208. { immediate: true }
  209. )
  210. /** 监听合同产品变化,计算合同产品总价 */
  211. watch(
  212. () => formData.value,
  213. (val) => {
  214. if (!val || val.length === 0) {
  215. return
  216. }
  217. // 循环处理
  218. val.forEach((item) => {
  219. item.totalProductPrice = erpPriceMultiply(item.productPrice, item.count)
  220. item.taxPrice = erpPriceMultiply(item.totalProductPrice, item.taxPercent / 100.0)
  221. if (item.totalProductPrice != null) {
  222. item.totalPrice = item.totalProductPrice + (item.taxPrice || 0)
  223. } else {
  224. item.totalPrice = undefined
  225. }
  226. })
  227. },
  228. { deep: true }
  229. )
  230. /** 合计 */
  231. const getSummaries = (param: SummaryMethodProps) => {
  232. const { columns, data } = param
  233. const sums: string[] = []
  234. columns.forEach((column, index: number) => {
  235. if (index === 0) {
  236. sums[index] = '合计'
  237. return
  238. }
  239. if (['count', 'totalProductPrice', 'taxPrice', 'totalPrice'].includes(column.property)) {
  240. const sum = getSumValue(data.map((item) => Number(item[column.property])))
  241. sums[index] =
  242. column.property === 'count' ? erpCountInputFormatter(sum) : erpPriceInputFormatter(sum)
  243. } else {
  244. sums[index] = ''
  245. }
  246. })
  247. return sums
  248. }
  249. /** 新增按钮操作 */
  250. const handleAdd = () => {
  251. const row = {
  252. id: undefined,
  253. productId: undefined,
  254. productUnitName: undefined, // 产品单位
  255. productBarCode: undefined, // 产品条码
  256. productPrice: undefined,
  257. stockCount: undefined,
  258. count: 1,
  259. totalProductPrice: undefined,
  260. taxPercent: undefined,
  261. taxPrice: undefined,
  262. totalPrice: undefined,
  263. remark: undefined
  264. }
  265. formData.value.push(row)
  266. }
  267. /** 删除按钮操作 */
  268. const handleDelete = (index: number) => {
  269. formData.value.splice(index, 1)
  270. }
  271. /** 加载库存 */
  272. const setStockCount = async (row: any) => {
  273. if (!row.productId) {
  274. return
  275. }
  276. const count = await StockApi.getStockCount(row.productId)
  277. row.stockCount = count || 0
  278. }
  279. /** 表单校验 */
  280. const validate = () => {
  281. return formRef.value.validate()
  282. }
  283. defineExpose({ validate })
  284. /** 初始化 */
  285. onMounted(async () => {
  286. warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
  287. defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
  288. })
  289. </script>