Merge branch 'dev_NEW_pro' of http://114.132.189.42:9002/r/product-inventory-management into dev_NEW_pro
| | |
| | | params: query, |
| | | }); |
| | | } |
| | | // 采购退货可选采购台账 |
| | | export function purchaseReturnableList(query) { |
| | | return request({ |
| | | url: "/purchase/ledger/returnableList", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | // 查询合同号 |
| | | export function getSalesNo(query) { |
| | | return request({ |
| | |
| | | @confirm="submitForm" |
| | | @cancel="closeDialog" |
| | | > |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <el-row v-if="isView" :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="状态"> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-col :span="10"> |
| | | <el-form-item label="金额(不含税)" prop="amount"> |
| | | <el-input-number |
| | | v-model="form.amount" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-col :span="7"> |
| | | <el-form-item label="税额"> |
| | | <el-input v-model="form.taxAmount" disabled /> |
| | | <el-input v-model="form.taxAmount" style="width: 100%;" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-col :span="7"> |
| | | <el-form-item label="价税合计"> |
| | | <el-input v-model="form.totalAmount" disabled /> |
| | | <el-input v-model="form.totalAmount" style="width: 100%;" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | prop="amount"> |
| | | <el-input-number v-model="form.amount" |
| | | :min="0" |
| | | :max="collectionAmountInputMax" |
| | | :precision="2" |
| | | style="width: 100%;" |
| | | :disabled="isView" |
| | | placeholder="根据关联单据自动汇总,可修改" /> |
| | | :disabled="isView" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | const isEdit = ref(false); |
| | | const isView = ref(false); |
| | | const currentId = ref(null); |
| | | const originalReceiptAmount = ref(0); |
| | | const submitLoading = ref(false); |
| | | |
| | | const customerList = ref([]); |
| | |
| | | }, |
| | | }); |
| | | |
| | | const maxCollectionAmount = computed(() => { |
| | | const selected = form.stockOutRecordIds || []; |
| | | const editAmount = isEdit.value ? Number(originalReceiptAmount.value) || 0 : 0; |
| | | if (!selected.length) return isEdit.value ? editAmount : undefined; |
| | | const selectedValueSet = new Set(selected.map(id => String(id))); |
| | | const selectedOptions = outboundBatchOptions.value.filter( |
| | | opt => opt.amountLimitAvailable && selectedValueSet.has(String(opt.value)) |
| | | ); |
| | | if (selectedOptions.length !== selectedValueSet.size) { |
| | | return isEdit.value ? Number(editAmount.toFixed(2)) : undefined; |
| | | } |
| | | const sum = selectedOptions.reduce( |
| | | (acc, opt) => acc + (Number(opt.outboundAmount) || 0), |
| | | 0 |
| | | ); |
| | | return Number((sum + editAmount).toFixed(2)); |
| | | }); |
| | | |
| | | const collectionAmountInputMax = computed( |
| | | () => maxCollectionAmount.value ?? Number.MAX_SAFE_INTEGER |
| | | ); |
| | | |
| | | const validateCollectionAmount = (rule, value, callback) => { |
| | | if (value === undefined || value === null || value === "") { |
| | | callback(); |
| | | return; |
| | | } |
| | | const amount = Number(value); |
| | | if (Number.isNaN(amount)) { |
| | | callback(new Error("请输入收款金额")); |
| | | return; |
| | | } |
| | | const max = maxCollectionAmount.value; |
| | | if (max !== undefined && amount - max > 0.000001) { |
| | | callback(new Error(`收款金额不能超过${max.toFixed(2)}`)); |
| | | return; |
| | | } |
| | | callback(); |
| | | }; |
| | | |
| | | const rules = { |
| | | customerId: [{ required: true, message: "请选择客户", trigger: "change" }], |
| | | stockOutRecordIds: [ |
| | |
| | | receiptDate: [ |
| | | { required: true, message: "请选择收款日期", trigger: "change" }, |
| | | ], |
| | | amount: [{ required: true, message: "请输入收款金额", trigger: "blur" }], |
| | | amount: [ |
| | | { required: true, message: "请输入收款金额", trigger: "blur" }, |
| | | { validator: validateCollectionAmount, trigger: ["blur", "change"] }, |
| | | ], |
| | | receiptMethod: [ |
| | | { required: true, message: "请选择收款方式", trigger: "change" }, |
| | | ], |
| | |
| | | return list.map((item, index) => { |
| | | if (typeof item === "string" || typeof item === "number") { |
| | | const text = String(item); |
| | | return { label: text, value: text, outboundAmount: 0 }; |
| | | return { |
| | | label: text, |
| | | value: text, |
| | | outboundAmount: 0, |
| | | amountLimitAvailable: false, |
| | | }; |
| | | } |
| | | const label = |
| | | item.outboundBatches ?? |
| | |
| | | item.label ?? |
| | | `出库单${index + 1}`; |
| | | const value = item.id ?? item.stockOutRecordId ?? label; |
| | | const outboundAmount = Number(item.outboundAmount) || 0; |
| | | const amountReceived = Number(item.amountReceived) || 0; |
| | | const availableAmount = outboundAmount - amountReceived; |
| | | return { |
| | | label: String(label), |
| | | value, |
| | | outboundAmount: (Number(item.outboundAmount)-Number(item.amountReceived)) || 0, |
| | | outboundAmount: |
| | | availableAmount > 0 ? Number(availableAmount.toFixed(2)) : 0, |
| | | amountLimitAvailable: true, |
| | | }; |
| | | }); |
| | | }; |
| | |
| | | label: String(id), |
| | | value: id, |
| | | outboundAmount: 0, |
| | | amountLimitAvailable: false, |
| | | }); |
| | | }); |
| | | }; |
| | |
| | | outboundSelectVisible.value = false; |
| | | syncCollectionAmount(); |
| | | formRef.value?.validateField("stockOutRecordIds"); |
| | | formRef.value?.validateField("amount"); |
| | | }; |
| | | |
| | | const handleOutboundDialogClosed = () => { |
| | |
| | | outboundSelectVisible.value = false; |
| | | isView.value = false; |
| | | isEdit.value = false; |
| | | originalReceiptAmount.value = 0; |
| | | }; |
| | | |
| | | const handleExport = () => { |
| | |
| | | isEdit.value = false; |
| | | isView.value = false; |
| | | dialogTitle.value = "新增收款"; |
| | | originalReceiptAmount.value = 0; |
| | | Object.assign(form, { |
| | | receiptCode: "", |
| | | customerId: "", |
| | |
| | | currentId.value = row.id; |
| | | dialogTitle.value = "编辑收款"; |
| | | fillFormFromRow(row); |
| | | originalReceiptAmount.value = Number(form.amount || 0); |
| | | dialogVisible.value = true; |
| | | loadOutboundBatches(form.customerId, true); |
| | | }; |
| | | |
| | | const view = row => { |
| | | isView.value = true; |
| | | isEdit.value = false; |
| | | dialogTitle.value = "查看收款"; |
| | | originalReceiptAmount.value = 0; |
| | | fillFormFromRow(row); |
| | | dialogVisible.value = true; |
| | | }; |
| | |
| | | <el-button link |
| | | type="primary" |
| | | @click="openForm('edit', scope.row)" |
| | | :disabled="scope.row.stockInStatus === '完全入库'">编辑 |
| | | :disabled="scope.row.approvalStatus === 3">编辑 |
| | | </el-button> |
| | | <el-button link |
| | | type="primary" |
| | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance, watch, defineAsyncComponent} from "vue"; |
| | | import {createPurchaseReturnOrder} from "@/api/procurementManagement/purchase_return_order.js"; |
| | | import {getOptions, purchaseList} from "@/api/procurementManagement/procurementLedger.js"; |
| | | import {getOptions, purchaseReturnableList} from "@/api/procurementManagement/procurementLedger.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | const ProductList = defineAsyncComponent(() => import("@/views/procurementManagement/purchaseReturnOrder/ProductList.vue")); |
| | | const props = defineProps({ |
| | |
| | | const fetchPurchaseLedgerOptions = () => { |
| | | purchaseLedgerOptions.value = [] |
| | | if (formState.value.supplierId) { |
| | | purchaseList({supplierId: formState.value.supplierId,approvalStatus:3}).then((res) => { |
| | | purchaseReturnableList({ supplierId: formState.value.supplierId }).then((res) => { |
| | | purchaseLedgerOptions.value = res.rows; |
| | | }); |
| | | } |
| | |
| | | <div style="padding-top: 20px"> |
| | | <span class="descriptions">产品列表</span> |
| | | <PIMTable :isShowPagination="false" rowKey="id" :column="tableColumn" :tableData="tableData"> |
| | | <template #totalReturnNum="{ row }"> |
| | | {{ calcAlreadyReturned(row) }} |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | </div> |
| | |
| | | {align: "center", label: "规格型号", prop: "model"}, |
| | | {align: "center", label: "单位", prop: "unit", width: 80}, |
| | | {align: "center", label: "总数量", prop: "stockOutNum", width: 120}, |
| | | {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120, dataType: "slot", slot: "totalReturnNum"}, |
| | | {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120}, |
| | | {align: "center", label: "未退货数量", prop: "unQuantity", width: 120}, |
| | | {align: "center", label: "待处理退货数量", prop: "pendingReturnNum", width: 120}, |
| | | {align: "center", label: "退货数量", prop: "returnQuantity", width: 120}, |
| | | {align: "center", label: "退货产品单价", prop: "price", width: 120}, |
| | | {align: "center", label: "退货产品金额", prop: "amount", width: 120}, |
| | |
| | | <el-button type="primary" @click="openProductSelection" :disabled="!form.shippingId">添加产品</el-button> |
| | | </div> |
| | | <PIMTable :isShowPagination="false" rowKey="id" :column="tableColumn" :tableData="tableData"> |
| | | <template #totalReturnNum="{ row }"> |
| | | {{ calcAlreadyReturned(row) }} |
| | | </template> |
| | | <template #returnQuantity="{ row }"> |
| | | <el-input |
| | | v-model="row.returnQuantity" |
| | |
| | | <el-table-column align="center" prop="specificationModel" label="规格型号" /> |
| | | <el-table-column align="center" prop="unit" label="单位" /> |
| | | <el-table-column align="center" prop="stockOutNum" label="总数量" /> |
| | | <el-table-column align="center" label="已退货数量" prop="totalReturnNum"></el-table-column> |
| | | <el-table-column align="center" prop="unQuantity" label="未退货数量" /> |
| | | <el-table-column align="center" label="已退货数量"> |
| | | <template #default="{ row }">{{ calcAlreadyReturned(row) }}</template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column align="center" prop="pendingReturnNum" label="待处理退货数量" /> |
| | | </el-table> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | |
| | | {align: "center", label: "规格型号", prop: "specificationModel" }, |
| | | {align: "center", label: "单位", prop: "unit", width: 80 }, |
| | | {align: "center", label: "总数量", prop: "stockOutNum", width: 120 }, |
| | | {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120, dataType: "slot", slot: "totalReturnNum" }, |
| | | {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120 }, |
| | | {align: "center", label: "待处理退货数量", prop: "pendingReturnNum", width: 120 }, |
| | | {align: "center", label: "未退货数量", prop: "unQuantity", width: 120 }, |
| | | {align: "center", label: "退货数量", prop: "returnQuantity", dataType: "slot", slot: "returnQuantity", width: 120 }, |
| | | {align: "center", label: "退货产品单价", prop: "price", dataType: "slot", slot: "price", width: 120 }, |
| | |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | emit('close'); |
| | | data.form = { |
| | | returnNoCheckbox: true, |
| | | returnNo: "", |
| | | customerId: "", |
| | | shippingId: "", |
| | | projectId: "", |
| | | maker: "", |
| | | makeTime: "", |
| | | status: 0, |
| | | returnReason: "", |
| | | refundAmount: "", |
| | | } |
| | | }; |
| | | |
| | | const initCustomers = async () => { |
| | |
| | | |
| | | const handleReturnQuantityChange = (val, row) => { |
| | | if (val === "" || val === null) return; |
| | | const max = row.unQuantity === undefined || row.unQuantity === null ? Infinity : Number(row.unQuantity || 0); |
| | | const unQuantity = row.unQuantity === undefined || row.unQuantity === null ? Infinity : Number(row.unQuantity || 0);//未退货数量 |
| | | const pendingReturnNum = row.pendingReturnNum === undefined || row.pendingReturnNum === null ? Infinity : Number(row.pendingReturnNum || 0);//待处理退货数量 |
| | | //最大退货数量,如果为编辑状态加上待处理退货数量 |
| | | const max = operationType.value === 'edit' ? unQuantity + pendingReturnNum : unQuantity |
| | | const current = Number(val); |
| | | |
| | | if (current > max) { |
| | |
| | | <template #status="{ row }"> |
| | | <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag> |
| | | </template> |
| | | <template #stockInApprovalStatus="{ row }"> |
| | | <el-tag :type="getStockInApprovalStatusType(row.stockInApprovalStatus)">{{ getStockInApprovalStatusText(row.stockInApprovalStatus) }}</el-tag> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery" /> |
| | |
| | | const defaultColumns = [ |
| | | { label: "退货单号", prop: "returnNo", minWidth: 160 }, |
| | | { label: "单据状态", prop: "status", minWidth: 90, dataType: "slot", slot: "status" }, |
| | | { label: "入库审批状态", prop: "stockInApprovalStatus", minWidth: 120, dataType: "slot", slot: "stockInApprovalStatus" }, |
| | | { label: "制单时间", prop: "makeTime", minWidth: 170 }, |
| | | { label: "客户名称", prop: "customerName", minWidth: 220 }, |
| | | { label: "销售单号", prop: "salesContractNo", minWidth: 160 }, |
| | |
| | | return statusMap[status] || "未知"; |
| | | }; |
| | | |
| | | const getStockInApprovalStatusType = (status) => { |
| | | const statusMap = { |
| | | 0: "", |
| | | 1: "success", |
| | | 2: "warning" |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | }; |
| | | |
| | | const getStockInApprovalStatusText = (status) => { |
| | | const statusMap = { |
| | | 0: "未审批", |
| | | 1: "已审批", |
| | | 2: "审批中" |
| | | }; |
| | | return statusMap[status] || "未知"; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |