ERPTurbo_Client/packages/app-client/src/components/purchase/section/PackageInfoSection.tsx
shenyifei f8199f7b55 refactor(purchase): 优化订单计算逻辑和组件数据处理
- 移除CostSummarySection中formatCurrency调用,保持数值类型
- 根据订单类型动态显示PackageInfoSection销售单价列
- 为ProductionLossSection和TaxProvisionSection添加calculator参数
- 为TaxSubsidySection添加calculator参数支持
- 优化审计页面提交逻辑,添加calculator计算回填
- 简化组件onChange回调处理
- 改进CostCalculator中空值判断逻辑
2025-12-26 14:50:33 +08:00

266 lines
7.4 KiB
TypeScript

import { formatCurrency } from "@/utils";
import { useEffect, useState } from "react";
import { Table } from "@nutui/nutui-react-taro";
import { Icon } from "@/components";
import { View } from "@tarojs/components";
import { Decimal } from "decimal.js";
export default function PackageInfoSection(props: {
orderVO: BusinessAPI.OrderVO;
onChange?: (orderVO: BusinessAPI.OrderVO) => void;
readOnly?: boolean;
}) {
const { orderVO, readOnly } = props;
const defaultColumns = [
{
title: "纸箱型号",
key: "boxProductName",
fixed: "left",
},
{
title: "个数",
key: "boxProductCount",
},
...(orderVO.type === "PRODUCTION_PURCHASE"
? [
{
title: "销售单价(元/斤)",
key: "boxSalePrice",
render: (
value: BusinessAPI.OrderPackage & {
orderPackageId?: string;
isTotalRow?: boolean;
},
) => {
// 合计行不显示编辑按钮
if (value.isTotalRow) {
return formatCurrency(value.boxSalePrice as number);
}
return (
<View
className="flex w-full items-center justify-between"
onClick={(e) => {
if (!readOnly) {
e.stopPropagation();
}
}}
>
<View className={!readOnly ? "cursor-pointer underline" : ""}>
{formatCurrency(value.boxSalePrice as number)}
</View>
{!readOnly && (
<View className="-m-2 ml-2 flex items-center justify-center p-2">
<Icon
name={"pen-to-square"}
size={16}
color={"#1a73e8"}
/>
</View>
)}
</View>
);
},
},
{
title: "销售金额(元)",
key: "boxSalePayment",
},
]
: []),
{
title: "箱重(斤)",
key: "boxProductWeight",
render: (
value: BusinessAPI.OrderPackage & {
orderPackageId?: string;
isTotalRow?: boolean;
},
) => formatCurrency(value.boxProductWeight),
},
{
title: "品牌",
key: "boxBrandName",
},
];
const [columns, setColumns] = useState<any[]>(defaultColumns);
useEffect(() => {
if (!readOnly) {
setColumns([...defaultColumns]);
}
}, [readOnly]);
// 将所有包装信息合并并按品牌、型号、规格分组
const groupedPackageData = orderVO.orderSupplierList?.reduce(
(acc, supplier) => {
supplier.orderPackageList
?.filter((pkg) => pkg.boxType === "USED")
?.forEach((pkg) => {
// 生成分组键
const key = `${pkg.boxBrandName}-${pkg.boxProductName}-${pkg.boxSpecId}`;
// 转换规格字段
const boxSpecId = pkg.boxSpecId;
const boxSpecName = pkg.boxSpecName;
if (!acc[key]) {
acc[key] = {
...pkg,
boxSpecId,
boxSpecName,
boxProductCount: 0,
};
}
// 累加数量
acc[key].boxProductCount += pkg.boxCount || 0;
});
return acc;
},
{} as Record<string, any>,
);
// 转换为数组格式
const packageData = Object.values(groupedPackageData || {});
// 计算合计数据
const calculateTotals = () => {
if (!packageData || packageData.length === 0) {
return {};
}
// 计算各项合计
let totalBoxProductCount = new Decimal(0);
let totalBoxSalePayment = new Decimal(0);
let totalBoxProductWeight = new Decimal(0);
packageData.forEach((pkg: any) => {
totalBoxProductCount = totalBoxProductCount.add(pkg.boxProductCount || 0);
totalBoxSalePayment = totalBoxSalePayment.add(
new Decimal(pkg?.boxSalePrice || 0)
.mul(pkg.boxProductCount || 0)
.toDecimalPlaces(0, Decimal.ROUND_HALF_UP),
);
totalBoxProductWeight = totalBoxProductWeight.add(
new Decimal(pkg?.boxProductWeight || 0)
.mul(pkg.boxProductCount || 0)
.toDecimalPlaces(0, Decimal.ROUND_HALF_UP),
);
});
return {
boxProductName: "合计",
boxProductCount: totalBoxProductCount.toNumber(),
boxSalePayment: totalBoxSalePayment.toNumber(),
boxProductWeight: totalBoxProductWeight.toNumber(),
isTotalRow: true, // 标记这是合计行
};
};
const totalsData = calculateTotals();
// 创建包含合计行的数据
const dataWithTotals = [...packageData];
if (Object.keys(totalsData).length > 0) {
dataWithTotals.push(totalsData);
}
// 自定义列配置,对合计行特殊处理
const columnsWithTotalsRender = columns.map((column) => {
if (column.key === "boxProductName") {
// 品牌列显示"合计"
return {
...column,
render: (rowData: any) => {
if (rowData.isTotalRow) {
return (
<span style={{ fontWeight: "bold" }}>
{rowData.boxProductName}
</span>
);
}
return rowData.boxProductName;
},
};
} else if (column.key === "boxProductCount") {
// 个数列显示合计
return {
...column,
render: (rowData: any) => {
if (rowData.isTotalRow) {
return (
<span style={{ fontWeight: "bold" }}>
{rowData.boxProductCount}
</span>
);
}
return rowData.boxProductCount;
},
};
} else if (column.key === "boxSalePrice") {
// 销售单价列合计行处理
return {
...column,
render: (rowData: any) => {
if (rowData.isTotalRow) {
return (
<span style={{ fontWeight: "bold" }}>
{formatCurrency(rowData.boxSalePrice as number)}
</span>
);
}
return column.render(rowData, rowData);
},
};
} else if (column.key === "boxSalePayment") {
// 销售金额列显示合计
return {
...column,
render: (rowData: any) => {
if (rowData.isTotalRow) {
return (
<span style={{ fontWeight: "bold" }}>
{formatCurrency(rowData.boxSalePayment)}
</span>
);
}
return new Decimal(rowData?.boxSalePrice || 0)
.mul(rowData.boxProductCount)
.toDecimalPlaces(0, Decimal.ROUND_HALF_UP)
.toNumber();
},
};
} else if (column.key === "boxProductWeight") {
// 重量列合计行处理
return {
...column,
render: (rowData: any) => {
if (rowData.isTotalRow) {
return (
<span style={{ fontWeight: "bold" }}>
{formatCurrency(rowData.boxProductWeight)}
</span>
);
}
return column.render(rowData, rowData);
},
};
}
// 其他列保持原有render函数或者默认显示
return column;
});
return (
<Table
className={"table-sum"}
columns={columnsWithTotalsRender}
data={dataWithTotals}
striped
/>
);
}