| | |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="请选择" clearable @change="changeDaterange" /> |
| | | </el-form-item> |
| | | <el-form-item label="发货状态:"> |
| | | <el-select v-model="searchForm.deliveryStatus" placeholder="请选择" clearable style="width: 140px"> |
| | | <el-option label="未发货" :value="1" /> |
| | | <el-option label="审批中" :value="2" /> |
| | | <el-option label="审批失败" :value="3" /> |
| | | <el-option label="已发货" :value="4" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery"> 搜索 </el-button> |
| | | </el-form-item> |
| | |
| | | <template #default="props"> |
| | | <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable"> |
| | | <el-table-column align="center" label="序号" type="index"/> |
| | | <el-table-column label="楼层编号" prop="floorCode" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="产品大类" prop="productCategory" /> |
| | | <el-table-column label="规格型号" prop="specificationModel" /> |
| | | <el-table-column label="厚度" prop="thickness" min-width="90"> |
| | |
| | | {{ scope.row.thickness ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="宽(mm)" prop="width" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.width ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="高(mm)" prop="height" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.height ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="周长(cm)" prop="perimeter" min-width="90"> |
| | | <template #default="scope"> |
| | | {{ scope.row.perimeter ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="总面积(cm²)" prop="actualTotalArea" min-width="100"> |
| | | <template #default="scope"> |
| | | {{ scope.row.actualTotalArea ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="加工要求" prop="processRequirement" min-width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="备注" prop="remark" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="重箱" prop="heavyBox" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.heavyBox ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产品状态" |
| | | width="100px" |
| | | align="center"> |
| | |
| | | <el-tag v-else type="danger">不足</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="发货状态" width="140" align="center"> |
| | | <!-- <el-table-column label="发货状态" width="140" align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getShippingStatusType(scope.row)" size="small"> |
| | | {{ getShippingStatusText(scope.row) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> --> |
| | | <el-table-column label="快递公司" prop="expressCompany" show-overflow-tooltip /> |
| | | <el-table-column label="快递单号" prop="expressNumber" show-overflow-tooltip /> |
| | | <el-table-column label="发货车牌" minWidth="100px" align="center"> |
| | |
| | | <el-table-column label="付款方式" prop="paymentMethod" show-overflow-tooltip /> |
| | | <el-table-column label="合同金额(元)" prop="contractAmount" width="220" show-overflow-tooltip |
| | | :formatter="formattedNumber" /> |
| | | <el-table-column label="发货状态" width="140" align="center"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="Number(scope.row.deliveryStatus) === 1" type="info">未发货</el-tag> |
| | | <el-tag v-else-if="Number(scope.row.deliveryStatus) === 2" type="warning">审批中</el-tag> |
| | | <el-tag v-else-if="Number(scope.row.deliveryStatus) === 3" type="danger">审批失败</el-tag> |
| | | <el-tag v-else-if="Number(scope.row.deliveryStatus) === 4" type="success">已发货</el-tag> |
| | | <el-tag v-else type="info">-</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip /> |
| | | <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip /> |
| | | <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip /> |
| | |
| | | <el-table-column label="厚度" prop="thickness" min-width="90"> |
| | | <template #default="scope"> |
| | | {{ scope.row.thickness ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="宽(mm)" prop="width" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.width ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="高(mm)" prop="height" min-width="80"> |
| | | <template #default="scope"> |
| | | {{ scope.row.height ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="面积(m²)" prop="actualTotalArea" min-width="100"> |
| | | <template #default="scope"> |
| | | {{ scope.row.actualTotalArea ?? "" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数量" prop="quantity" /> |
| | |
| | | <el-input-number |
| | | v-model="item.quantity" |
| | | :min="0" |
| | | :step="0.1" |
| | | :precision="2" |
| | | :step="1" |
| | | :precision="0" |
| | | style="width: 100%;" |
| | | placeholder="请输入数量" |
| | | :disabled="operationType === 'view'" |
| | | @change="calculateFromUnitPrice(true)" |
| | | /> |
| | | </div> |
| | | <el-button |
| | |
| | | entryDate: null, // 录入日期 |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | deliveryStatus: undefined, // 发货状态:1未发货 2审批中 3审批失败 4已发货 |
| | | }, |
| | | form: { |
| | | salesContractNo: "", |
| | |
| | | type: "货车", // 货车, 快递 |
| | | }, |
| | | deliveryRules: { |
| | | type: [ |
| | | type: [ |
| | | { required: true, message: "请选择发货类型", trigger: "change" } |
| | | ] |
| | | }, |
| | |
| | | otherAmountSelectOptions.value = records.map((item) => ({ |
| | | id: item.id, |
| | | processName: item.processName ?? "", |
| | | unitPrice: item.unitPrice ?? 0, |
| | | })); |
| | | } finally { |
| | | otherAmountSelectOptionsLoading.value = false; |
| | |
| | | return { |
| | | id: s.id, |
| | | processName: opt?.processName ?? s.processName ?? "", |
| | | unitPrice: opt?.unitPrice ?? s.unitPrice ?? 0, |
| | | quantity: Number(s.quantity ?? 0) || 0, |
| | | }; |
| | | }); |
| | |
| | | productForm.value.salesProductProcessList.push({ |
| | | id: opt.id, |
| | | processName: opt.processName, |
| | | unitPrice: opt.unitPrice ?? 0, |
| | | quantity: 0, |
| | | }); |
| | | calculateFromUnitPrice(true); |
| | | |
| | | // 选择完成后关闭弹窗,下一次可再次点击“新增”继续添加 |
| | | otherAmountAddDialogVisible.value = false; |
| | |
| | | if (operationType.value === "view") return; |
| | | if (!Array.isArray(productForm.value?.salesProductProcessList)) return; |
| | | productForm.value.salesProductProcessList.splice(index, 1); |
| | | calculateFromUnitPrice(true); |
| | | }; |
| | | |
| | | // 发货审批人节点(仿协同审批 infoFormDia.vue) |
| | |
| | | recalcAreaTotals(); |
| | | // 其他金额只提交 {id, processName, quantity}(后端字段:salesProductProcessList) |
| | | productForm.value.salesProductProcessList = (Array.isArray(productForm.value.salesProductProcessList) |
| | | ? productForm.value.salesProductProcessList |
| | | : [] |
| | | ) |
| | | .map((it) => ({ |
| | | id: it?.id, |
| | | processName: it?.processName ?? "", |
| | | quantity: Number(it?.quantity ?? 0) || 0, |
| | | })) |
| | | .filter((it) => it.id !== null && it.id !== undefined && it.id !== ""); |
| | | ? productForm.value.salesProductProcessList |
| | | : [] |
| | | ) |
| | | .map((it) => ({ |
| | | id: it?.id, |
| | | processName: it?.processName ?? "", |
| | | unitPrice: Number(it?.unitPrice ?? 0) || 0, |
| | | quantity: Number(it?.quantity ?? 0) || 0, |
| | | })) |
| | | .filter((it) => it.id !== null && it.id !== undefined && it.id !== ""); |
| | | |
| | | if (operationType.value === "edit") { |
| | | submitProductEdit(); |
| | |
| | | return; |
| | | } |
| | | const settlePieceArea = parseFloat(productForm.value.settlePieceArea) || 1; |
| | | // 含税总价计算 = 单价 * 结算面积 * 数量 |
| | | productForm.value.taxInclusiveTotalPrice = |
| | | proxy.calculateTaxIncludeTotalPrice( |
| | | productForm.value.taxInclusiveUnitPrice * settlePieceArea, |
| | | productForm.value.quantity |
| | | ); |
| | | // 含税总价计算 = 单价 * 结算面积 * 数量 + 其他金额总和 |
| | | const basePrice = proxy.calculateTaxIncludeTotalPrice( |
| | | productForm.value.taxInclusiveUnitPrice * settlePieceArea, |
| | | productForm.value.quantity |
| | | ); |
| | | const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => { |
| | | return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0); |
| | | }, 0); |
| | | productForm.value.taxInclusiveTotalPrice = (parseFloat(basePrice) + otherAmountTotal).toFixed(2); |
| | | if (productForm.value.taxRate) { |
| | | // 不含税总价计算 |
| | | productForm.value.taxExclusiveTotalPrice = |
| | |
| | | |
| | | isCalculating.value = true; |
| | | |
| | | // 计算含税单价 = 含税总价 / 数量 |
| | | productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2); |
| | | // 计算含税单价 = (含税总价 - 其他金额总和) / 数量 |
| | | const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => { |
| | | return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0); |
| | | }, 0); |
| | | const basePrice = totalPrice - otherAmountTotal; |
| | | productForm.value.taxInclusiveUnitPrice = (basePrice / quantity).toFixed(2); |
| | | |
| | | // 如果有税率,计算不含税总价 |
| | | if (productForm.value.taxRate) { |
| | |
| | | const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal); |
| | | productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2); |
| | | |
| | | // 计算含税单价 = 含税总价 / 数量 |
| | | productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2); |
| | | // 计算含税单价 = (含税总价 - 其他金额总和) / 数量 |
| | | const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => { |
| | | return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0); |
| | | }, 0); |
| | | const basePrice = inclusiveTotalPrice - otherAmountTotal; |
| | | productForm.value.taxInclusiveUnitPrice = (basePrice / quantity).toFixed(2); |
| | | |
| | | isCalculating.value = false; |
| | | }; |
| | |
| | | |
| | | isCalculating.value = true; |
| | | |
| | | // 计算含税总价 = 单价 * 结算面积 * 数量 |
| | | productForm.value.taxInclusiveTotalPrice = (unitPrice * settlePieceArea * quantity).toFixed(2); |
| | | // 计算含税总价 = 单价 * 结算面积 * 数量 + 其他金额总和 |
| | | const basePrice = unitPrice * settlePieceArea * quantity; |
| | | const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => { |
| | | return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0); |
| | | }, 0); |
| | | productForm.value.taxInclusiveTotalPrice = (basePrice + otherAmountTotal).toFixed(2); |
| | | |
| | | // 如果有税率,计算不含税总价 |
| | | if (productForm.value.taxRate) { |
| | |
| | | |
| | | isCalculating.value = true; |
| | | |
| | | // 计算含税总价 = 单价 * 结算面积 * 数量 |
| | | productForm.value.taxInclusiveTotalPrice = (unitPrice * settlePieceArea * quantity).toFixed(2); |
| | | // 计算含税总价 = 单价 * 结算面积 * 数量 + 其他金额总和 |
| | | const basePrice = unitPrice * settlePieceArea * quantity; |
| | | const otherAmountTotal = (productForm.value.salesProductProcessList || []).reduce((total, item) => { |
| | | return total + (Number(item.unitPrice) || 0) * (Number(item.quantity) || 0); |
| | | }, 0); |
| | | productForm.value.taxInclusiveTotalPrice = (basePrice + otherAmountTotal).toFixed(2); |
| | | |
| | | // 如果有税率,计算不含税总价 |
| | | if (productForm.value.taxRate) { |
| | |
| | | * @param row 行数据 |
| | | */ |
| | | const canShip = (row) => { |
| | | |
| | | // 产品状态必须是充足(approveStatus === 1) |
| | | if (row.approveStatus !== 1) { |
| | | return false; |
| | | } |
| | | |
| | | // 如果后端返回了台账级发货状态(deliveryStatus) |
| | | // 1=已发货,则禁止再次发货 |
| | | const deliveryStatus = row.deliveryStatus; |
| | | if ( |
| | | deliveryStatus !== null && |
| | | deliveryStatus !== undefined && |
| | | String(deliveryStatus).trim() !== "" |
| | | ) { |
| | | if (Number(deliveryStatus) === 1) return false; |
| | | } |
| | | |
| | | // 获取发货状态 |
| | | const shippingStatus = row.shippingStatus; |
| | | |
| | |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning("请选择数据"); |
| | | return; |
| | | } |
| | | |
| | | // 只允许【未发货/审批失败】进入发货流程 |
| | | const canDeliveryLedgers = selectedRows.value.filter((r) => { |
| | | const status = Number(r.deliveryStatus); |
| | | return status === 1 || status === 3; |
| | | }); |
| | | if (canDeliveryLedgers.length === 0) { |
| | | proxy.$modal.msgWarning("仅未发货或审批失败的台账可以发货"); |
| | | return; |
| | | } |
| | | |
| | | // 已发货台账:弹窗提醒,不能再次发货(4 视为已发货) |
| | | const shippedLedgers = selectedRows.value.filter((r) => Number(r.deliveryStatus) === 4); |
| | | if (shippedLedgers.length === selectedRows.value.length) { |
| | | try { |
| | | await ElMessageBox.alert("所选销售台账均已发货,不能再次发货。", "提示", { |
| | | type: "warning", |
| | | confirmButtonText: "知道了", |
| | | }); |
| | | } catch { |
| | | /* 关闭弹窗 */ |
| | | } |
| | | return; |
| | | } |
| | | if (shippedLedgers.length > 0) { |
| | | try { |
| | | await ElMessageBox.alert( |
| | | "选中的销售台账中包含已发货记录,已发货的不能再次发货,系统将仅为未发货台账处理。", |
| | | "提示", |
| | | { |
| | | type: "warning", |
| | | confirmButtonText: "知道了", |
| | | } |
| | | ); |
| | | } catch { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | const customerNames = selectedRows.value.map((r) => String(r.customerName || "").trim()); |
| | |
| | | try { |
| | | const targets = []; |
| | | for (const ledger of selectedRows.value) { |
| | | // 台账已发货:不允许再次发货 |
| | | if (Number(ledger.deliveryStatus) === 1) continue; |
| | | let products = []; |
| | | try { |
| | | const res = await productList({ salesLedgerId: ledger.id, type: 1 }); |
| | |
| | | } catch { |
| | | products = []; |
| | | } |
| | | |
| | | for (const product of products) { |
| | | if (!canShip(product)) continue; |
| | | targets.push({ |
| | |
| | | }); |
| | | } |
| | | |
| | | // 打开发货弹框 |
| | | // 打开发货弹框(单条) |
| | | const openDeliveryForm = (row) => { |
| | | // 检查是否可以发货 |
| | | if (!canShip(row)) { |
| | | proxy.$modal.msgWarning("只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货"); |
| | | // 只允许【未发货/审批失败】发货;已发货/审批中不允许 |
| | | const status = Number(row.deliveryStatus); |
| | | if (status !== 1 && status !== 3) { |
| | | proxy.$modal.msgWarning("只有发货状态为未发货或审批失败的记录才可以发货"); |
| | | return; |
| | | } |
| | | |
| | | |
| | | currentDeliveryRows.value = [row]; |
| | | deliveryForm.value = { |
| | | type: "货车", |