| | |
| | | <el-option label="审核不通过" :value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="付款状态:"> |
| | | <el-select v-model="filters.paymentStatus" placeholder="请选择付款状态" clearable style="width: 150px;"> |
| | | <el-option label="未付款" :value="0" /> |
| | | <el-option label="部分付款" :value="1" /> |
| | | <el-option label="已付款" :value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="申请日期:"> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | |
| | | }" |
| | | @pagination="changePage" |
| | | > |
| | | <template #amount="{ row }"> |
| | | <span class="text-danger">¥{{ formatMoney(row.amount) }}</span> |
| | | <template #paymentAmount="{ row }"> |
| | | <span class="text-primary">¥{{ formatMoney(row.paymentAmount) }}</span> |
| | | </template> |
| | | <template #paidAmount="{ row }"> |
| | | <span class="text-success">¥{{ formatMoney(row.paidAmount) }}</span> |
| | | </template> |
| | | <template #paymentMethod="{ row }"> |
| | | <el-tag>{{ getPaymentMethodLabel(row.paymentMethod) }}</el-tag> |
| | |
| | | <template #status="{ row }"> |
| | | <el-tag :type="getStatusType(row.status)">{{ getStatusLabel(row.status) }}</el-tag> |
| | | </template> |
| | | <template #paymentStatus="{ row }"> |
| | | <el-tag :type="getPaymentStatusType(row.paymentStatus)">{{ getPaymentStatusLabel(row.paymentStatus) }}</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button type="primary" link @click="view(row)">查看</el-button> |
| | | <el-button type="primary" link @click="edit(row)" v-if="isPendingStatus(row.status)">编辑</el-button> |
| | | <el-button type="success" link @click="handleAudit(row)" v-if="isPendingStatus(row.status)">审核</el-button> |
| | | <el-button type="warning" link @click="openPaymentDialog(row)" v-if="isApprovedStatus(row.status)">付款</el-button> |
| | | <el-button type="warning" link @click="openPaymentDialog(row)" v-if="canPay(row)">付款</el-button> |
| | | <el-button type="danger" link @click="handleDelete(row)" v-if="isPendingStatus(row.status)">删除</el-button> |
| | | </template> |
| | | </PIMTable> |
| | |
| | | <el-input-number |
| | | v-model="form.paymentAmount" |
| | | :min="0" |
| | | :precision="2" |
| | | :precision="4" |
| | | style="width: 100%;" |
| | | :disabled="isView" |
| | | placeholder="根据入库单自动汇总,可修改" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="申请金额"> |
| | | <el-input :model-value="formatMoney(paymentForm.applyAmount)" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="已付款金额"> |
| | | <el-input :model-value="formatMoney(paymentForm.paidAmountInfo)" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="剩余可付款"> |
| | | <el-input :model-value="formatMoney(paymentForm.remainAmount)" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="供应商"> |
| | | <el-input v-model="paymentForm.supplierName" disabled /> |
| | |
| | | <el-input-number |
| | | v-model="paymentForm.paymentAmount" |
| | | :min="0" |
| | | :precision="2" |
| | | :precision="4" |
| | | style="width: 100%;" |
| | | /> |
| | | </el-form-item> |
| | |
| | | invoiceApplicationNo: "", |
| | | supplierId: "", |
| | | status: "", |
| | | paymentStatus: "", |
| | | dateRange: [], |
| | | }); |
| | | |
| | |
| | | }); |
| | | |
| | | const columns = [ |
| | | { label: "申请单号", prop: "applyCode", width: "150" }, |
| | | { label: "申请单号", prop: "invoiceApplicationNo", width: "150" }, |
| | | { label: "供应商", prop: "supplierName", width: "180" }, |
| | | { label: "付款金额", prop: "amount", dataType: "slot", slot: "amount" }, |
| | | { label: "申请金额", prop: "paymentAmount", dataType: "slot", slot: "paymentAmount" }, |
| | | { label: "已付款金额", prop: "paidAmount", dataType: "slot", slot: "paidAmount" }, |
| | | { label: "付款方式", prop: "paymentMethod", dataType: "slot", slot: "paymentMethod", width: "120" }, |
| | | { label: "申请日期", prop: "applyDate", width: "120" }, |
| | | { label: "状态", prop: "status", dataType: "slot", slot: "status", width: "100" }, |
| | | { label: "审核状态", prop: "status", dataType: "slot", slot: "status", width: "100" }, |
| | | { label: "付款状态", prop: "paymentStatus", dataType: "slot", slot: "paymentStatus", width: "100" }, |
| | | { label: "操作", prop: "operation", dataType: "slot", slot: "operation", width: "260", fixed: "right" }, |
| | | ]; |
| | | |
| | |
| | | bankAccount: "", |
| | | bankName: "", |
| | | remark: "", |
| | | applyAmount: 0, |
| | | paidAmountInfo: 0, |
| | | remainAmount: 0, |
| | | }); |
| | | |
| | | const paymentRules = { |
| | |
| | | |
| | | const STATUS_LABEL_MAP = { 0: "待审核", 1: "审核通过", 2: "审核不通过" }; |
| | | const STATUS_TYPE_MAP = { 0: "warning", 1: "success", 2: "danger" }; |
| | | |
| | | const PAYMENT_STATUS_LABEL_MAP = { 0: "未付款", 1: "部分付款", 2: "已付款" }; |
| | | const PAYMENT_STATUS_TYPE_MAP = { 0: "warning", 1: "primary", 2: "success" }; |
| | | |
| | | const form = reactive({ |
| | | invoiceApplicationNo: "", |
| | |
| | | |
| | | const formatMoney = (value) => { |
| | | if (value === undefined || value === null) return "0.00"; |
| | | return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
| | | const parts = Number(value).toFixed(4).split("."); |
| | | parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
| | | return parts.join("."); |
| | | }; |
| | | |
| | | const normalizeStatus = (status) => { |
| | |
| | | return Number.isNaN(num) ? 0 : num; |
| | | }; |
| | | |
| | | const normalizePaymentStatus = (ps) => { |
| | | if (ps === undefined || ps === null || ps === "") return 0; |
| | | const num = Number(ps); |
| | | return Number.isNaN(num) ? 0 : num; |
| | | }; |
| | | |
| | | const isPendingStatus = (status) => normalizeStatus(status) === 0; |
| | | |
| | | const isApprovedStatus = (status) => normalizeStatus(status) === 1; |
| | | |
| | | const canPay = (row) => isApprovedStatus(row.status) && normalizePaymentStatus(row.paymentStatus) !== 2; |
| | | |
| | | const getPaymentStatusLabel = (ps) => PAYMENT_STATUS_LABEL_MAP[normalizePaymentStatus(ps)] ?? "未付款"; |
| | | |
| | | const getPaymentStatusType = (ps) => PAYMENT_STATUS_TYPE_MAP[normalizePaymentStatus(ps)] ?? "warning"; |
| | | |
| | | const isBankTransferPayment = (method) => { |
| | | if (method === undefined || method === null || method === "") return false; |
| | |
| | | .reduce((acc, row) => acc + getInboundRowTaxInclusiveAmount(row), 0); |
| | | } |
| | | |
| | | form.paymentAmount = sum > 0 ? Number(sum.toFixed(2)) : 0; |
| | | form.paymentAmount = sum > 0 ? Number(sum.toFixed(4)) : 0; |
| | | }; |
| | | |
| | | const inboundBatchDisplayText = computed(() => { |
| | |
| | | |
| | | const normalizeTableRow = (row) => ({ |
| | | ...row, |
| | | applyCode: row.invoiceApplicationNo ?? row.applyCode, |
| | | amount: row.paymentAmount ?? row.amount, |
| | | reason: row.paymentContent ?? row.reason, |
| | | status: normalizeStatus(row.status), |
| | | paymentStatus: normalizePaymentStatus(row.paymentStatus), |
| | | paidAmount: Number(row.paidAmount ?? 0), |
| | | stockInRecordIds: row.stockInRecordIds ?? "", |
| | | inboundBatches: formatInboundBatches(row.inboundBatches), |
| | | }); |
| | |
| | | if (filters.status !== "" && filters.status != null) { |
| | | params.status = filters.status; |
| | | } |
| | | if (filters.paymentStatus !== "" && filters.paymentStatus != null) { |
| | | params.paymentStatus = filters.paymentStatus; |
| | | } |
| | | if (filters.dateRange?.length === 2) { |
| | | params.startDate = filters.dateRange[0]; |
| | | params.endDate = filters.dateRange[1]; |
| | |
| | | filters.invoiceApplicationNo = ""; |
| | | filters.supplierId = ""; |
| | | filters.status = ""; |
| | | filters.paymentStatus = ""; |
| | | filters.dateRange = []; |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | |
| | | }; |
| | | |
| | | const openPaymentDialog = (row) => { |
| | | const applyAmount = Number(row.paymentAmount ?? row.amount ?? 0); |
| | | const paidAmount = Number(row.paidAmount ?? 0); |
| | | Object.assign(paymentForm, { |
| | | paymentNumber: "", |
| | | invoiceApplicationNo: row.invoiceApplicationNo ?? row.applyCode ?? "", |
| | |
| | | supplierId: row.supplierId, |
| | | accountPaymentApplicationId: row.id, |
| | | paymentDate: new Date().toISOString().split("T")[0], |
| | | paymentAmount: Number(row.paymentAmount ?? row.amount ?? 0), |
| | | paymentAmount: Math.max(0, applyAmount - paidAmount), |
| | | paymentMethod: row.paymentMethod ?? getDefaultPaymentMethod(), |
| | | bankAccount: row.bankAccountNum ?? row.bankAccount ?? "", |
| | | bankName: row.bankAccountName ?? row.bankName ?? "", |
| | | remark: "", |
| | | applyAmount, |
| | | paidAmountInfo: paidAmount, |
| | | remainAmount: Math.max(0, applyAmount - paidAmount), |
| | | }); |
| | | paymentDialogVisible.value = true; |
| | | nextTick(() => { |
| | |
| | | const submitPayment = () => { |
| | | paymentFormRef.value?.validate((valid) => { |
| | | if (!valid) return; |
| | | const maxRemain = paymentForm.applyAmount - paymentForm.paidAmountInfo; |
| | | if (paymentForm.paymentAmount > maxRemain) { |
| | | ElMessage.warning(`付款金额不能超过剩余可付款金额 ¥${formatMoney(maxRemain)}`); |
| | | return; |
| | | } |
| | | paymentSubmitLoading.value = true; |
| | | addAccountPurchasePayment({ |
| | | accountPaymentApplicationId: paymentForm.accountPaymentApplicationId, |
| | |
| | | }; |
| | | |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm(`确认删除申请单「${row.applyCode ?? row.invoiceApplicationNo}」吗?`, "提示", { |
| | | ElMessageBox.confirm(`确认删除申请单「${row.invoiceApplicationNo ?? row.applyCode}」吗?`, "提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .text-primary { |
| | | color: #409eff; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .text-success { |
| | | color: #67c23a; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .inbound-batch-input :deep(.el-input__wrapper) { |
| | | cursor: pointer; |
| | | } |