| | |
| | | <script lang="ts" setup> |
| | | import type { ErpFinancePaymentApi } from '#/api/erp/finance/payment'; |
| | | import type { ErpPurchaseInApi } from '#/api/erp/purchase/in'; |
| | | import type { ErpPurchaseReturnApi } from '#/api/erp/purchase/return'; |
| | | |
| | | import { computed, nextTick, ref, watch } from 'vue'; |
| | | |
| | | import { ErpBizType } from '@vben/constants'; |
| | | import { erpPriceInputFormatter } from '@vben/utils'; |
| | | |
| | | import { Input, InputNumber, message } from 'ant-design-vue'; |
| | | import { Input, InputNumber } from 'ant-design-vue'; |
| | | |
| | | import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | |
| | | import { useFormItemColumns } from '../data'; |
| | | import PurchaseInSelect from './purchase-in-select.vue'; |
| | | import SaleReturnSelect from './sale-return-select.vue'; |
| | | |
| | | interface InvoiceForItem { |
| | | id?: number; |
| | | no?: string; |
| | | price?: number; |
| | | remainingInvoicePrice?: number; |
| | | } |
| | | |
| | | interface Props { |
| | | items?: ErpFinancePaymentApi.FinancePaymentItem[]; |
| | | supplierId?: number; |
| | | disabled?: boolean; |
| | | discountPrice?: number; |
| | | invoice?: InvoiceForItem; |
| | | } |
| | | |
| | | const props = withDefaults(defineProps<Props>(), { |
| | |
| | | supplierId: undefined, |
| | | disabled: false, |
| | | discountPrice: 0, |
| | | invoice: undefined, |
| | | }); |
| | | |
| | | const emit = defineEmits([ |
| | |
| | | ]); |
| | | |
| | | const tableData = ref<ErpFinancePaymentApi.FinancePaymentItem[]>([]); // è¡¨æ ¼æ°æ® |
| | | |
| | | /** å·²æ ¹æ®è¯¥æ¥ç¥¨çæçæç»ï¼é¿å
éå¤çæ */ |
| | | const generatedInvoiceId = ref<number | undefined>(); |
| | | |
| | | /** è·åè¡¨æ ¼åè®¡æ°æ® */ |
| | | const summaries = computed(() => { |
| | |
| | | /** è¡¨æ ¼é
ç½® */ |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | gridOptions: { |
| | | columns: useFormItemColumns(props.disabled), |
| | | columns: useFormItemColumns(), |
| | | data: tableData.value, |
| | | minHeight: 250, |
| | | autoResize: true, |
| | |
| | | return; |
| | | } |
| | | tableData.value = [...items]; |
| | | // ç¼è¾åæ¾æ¶ï¼æ è®°å·²æ ¹æ®å½åæ¥ç¥¨çæè¿ï¼é¿å
éå¤çæ |
| | | generatedInvoiceId.value = props.invoice?.id; |
| | | await nextTick(); // ç¹æ®ï¼ä¿è¯ gridApi å·²ç»åå§å |
| | | await gridApi.grid.reloadData(tableData.value); |
| | | }, |
| | | { |
| | | immediate: true, |
| | | }, |
| | | ); |
| | | |
| | | /** å
³èæ¥ç¥¨ååæ¶ï¼èªå¨çæå¯ä¸ç仿¬¾æç»ï¼ä»æ¬¾åºäºæ¥ç¥¨ï¼ */ |
| | | watch( |
| | | () => props.invoice?.id, |
| | | async (newId) => { |
| | | if (!newId || !props.invoice) { |
| | | return; |
| | | } |
| | | if (generatedInvoiceId.value === newId) { |
| | | return; |
| | | } |
| | | generatedInvoiceId.value = newId; |
| | | const invoice = props.invoice; |
| | | const price = invoice.price ?? 0; |
| | | const remaining = invoice.remainingInvoicePrice ?? price; |
| | | tableData.value = [ |
| | | { |
| | | bizId: invoice.id ?? 0, |
| | | bizType: ErpBizType.PURCHASE_INVOICE, |
| | | bizNo: invoice.no ?? '', |
| | | totalPrice: price, |
| | | paidPrice: price - remaining, |
| | | paymentPrice: remaining, |
| | | remark: '', |
| | | }, |
| | | ]; |
| | | await nextTick(); |
| | | await gridApi.grid.reloadData(tableData.value); |
| | | emit('update:items', [...tableData.value]); |
| | | }, |
| | | ); |
| | | |
| | |
| | | { deep: true }, |
| | | ); |
| | | |
| | | /** æ·»å éè´å
¥åºå */ |
| | | const purchaseInSelectRef = ref(); |
| | | const handleOpenPurchaseIn = () => { |
| | | if (!props.supplierId) { |
| | | message.error('è¯·éæ©ä¾åºå'); |
| | | return; |
| | | } |
| | | purchaseInSelectRef.value?.open(props.supplierId); |
| | | }; |
| | | |
| | | const handleAddPurchaseIn = (rows: ErpPurchaseInApi.PurchaseIn[]) => { |
| | | rows.forEach((row) => { |
| | | const totalPrice = row.totalPrice ?? 0; |
| | | const paidPrice = row.paymentPrice ?? 0; |
| | | const newItem: ErpFinancePaymentApi.FinancePaymentItem = { |
| | | bizId: row.id ?? 0, |
| | | bizType: ErpBizType.PURCHASE_IN, |
| | | bizNo: row.no ?? '', |
| | | totalPrice, |
| | | paidPrice, |
| | | paymentPrice: totalPrice - paidPrice, |
| | | remark: undefined, |
| | | }; |
| | | tableData.value.push(newItem); |
| | | }); |
| | | emit('update:items', [...tableData.value]); |
| | | }; |
| | | |
| | | /** æ·»å éè´éè´§å */ |
| | | const saleReturnSelectRef = ref(); |
| | | const handleOpenSaleReturn = () => { |
| | | if (!props.supplierId) { |
| | | message.error('è¯·éæ©ä¾åºå'); |
| | | return; |
| | | } |
| | | saleReturnSelectRef.value?.open(props.supplierId); |
| | | }; |
| | | |
| | | const handleAddSaleReturn = (rows: ErpPurchaseReturnApi.PurchaseReturn[]) => { |
| | | rows.forEach((row) => { |
| | | const totalPrice = row.totalPrice ?? 0; |
| | | const refundPrice = row.refundPrice ?? 0; |
| | | const newItem: ErpFinancePaymentApi.FinancePaymentItem = { |
| | | bizId: row.id ?? 0, |
| | | bizType: ErpBizType.PURCHASE_RETURN, |
| | | bizNo: row.no ?? '', |
| | | totalPrice: -totalPrice, |
| | | paidPrice: -refundPrice, |
| | | paymentPrice: -totalPrice + refundPrice, |
| | | remark: undefined, |
| | | }; |
| | | tableData.value.push(newItem); |
| | | }); |
| | | emit('update:items', [...tableData.value]); |
| | | }; |
| | | |
| | | /** å é¤è¡ */ |
| | | const handleDelete = async (row: any) => { |
| | | const index = tableData.value.findIndex( |
| | | (item) => item.bizId === row.bizId && item.bizType === row.bizType, |
| | | ); |
| | | if (index !== -1) { |
| | | tableData.value.splice(index, 1); |
| | | } |
| | | // éç¥ç¶ç»ä»¶æ´æ° |
| | | emit('update:items', [...tableData.value]); |
| | | }; |
| | | |
| | | /** å¤çè¡æ°æ®åæ´ */ |
| | | const handleRowChange = (row: any) => { |
| | | const index = tableData.value.findIndex( |
| | |
| | | const validate = () => { |
| | | // æ£æ¥æ¯å¦ææç» |
| | | if (tableData.value.length === 0) { |
| | | throw new Error('请添å 仿¬¾æç»'); |
| | | throw new Error('请å
éæ©å
³èæ¥ç¥¨'); |
| | | } |
| | | // æ£æ¥æ¯è¡ç仿¬¾éé¢ |
| | | for (let i = 0; i < tableData.value.length; i++) { |
| | |
| | | @change="handleRowChange(row)" |
| | | /> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'å é¤', |
| | | type: 'link', |
| | | danger: true, |
| | | popConfirm: { |
| | | title: '确认å é¤è¯¥ä»æ¬¾æç»åï¼', |
| | | confirm: handleDelete.bind(null, row), |
| | | }, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | |
| | | <template #bottom> |
| | | <div class="mt-2 rounded border border-border bg-muted p-2"> |
| | |
| | | <span class="font-medium text-foreground">å计ï¼</span> |
| | | <div class="flex space-x-4"> |
| | | <span> |
| | | åè®¡ä»æ¬¾ï¼{{ erpPriceInputFormatter(summaries.totalPrice) }} |
| | | åºä»éé¢ï¼{{ erpPriceInputFormatter(summaries.totalPrice) }} |
| | | </span> |
| | | <span> |
| | | å·²ä»éé¢ï¼{{ erpPriceInputFormatter(summaries.paidPrice) }} |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <TableAction |
| | | v-if="!disabled" |
| | | class="mt-2 flex justify-center" |
| | | :actions="[ |
| | | { |
| | | label: 'æ·»å éè´å
¥åºå', |
| | | type: 'default', |
| | | onClick: handleOpenPurchaseIn, |
| | | }, |
| | | { |
| | | label: 'æ·»å éè´éè´§å', |
| | | type: 'default', |
| | | onClick: handleOpenSaleReturn, |
| | | }, |
| | | ]" |
| | | /> |
| | | <div |
| | | v-if="!invoice && !disabled" |
| | | class="mt-2 flex justify-center text-sm text-muted-foreground" |
| | | > |
| | | 请å
å¨ä¸æ¹è¡¨åéæ©å
³èæ¥ç¥¨ï¼ç³»ç»å°èªå¨çæä»æ¬¾æç» |
| | | </div> |
| | | </template> |
| | | </Grid> |
| | | |
| | | <!-- éè´å
¥åºåéæ©ç»ä»¶ --> |
| | | <PurchaseInSelect |
| | | ref="purchaseInSelectRef" |
| | | @success="handleAddPurchaseIn" |
| | | /> |
| | | <!-- éè´éè´§åéæ©ç»ä»¶ --> |
| | | <SaleReturnSelect |
| | | ref="saleReturnSelectRef" |
| | | @success="handleAddSaleReturn" |
| | | /> |
| | | </div> |
| | | </template> |