feat(purchase): 重构纸箱使用逻辑并优化采购计算

- 移除 OWN 类型纸箱,统一使用 USED 类型处理
- 简化纸箱使用流程,去除瓜农是否包纸箱的选择
- 更新采购成本计算逻辑,支持按毛重或净重报价
- 优化界面布局,提升用户体验
- 调整数据结构定义,确保类型一致性
- 增加版本号至 v0.0.31
- 添加被驳回订单的编辑功能
- 根据经销商控制表单展示内容
- 修复部分计算逻辑中的过滤条件
- 清理冗余代码和无用字段
This commit is contained in:
shenyifei 2025-12-10 15:47:32 +08:00
parent 6b51d6b1e3
commit 837c27e9bd
16 changed files with 350 additions and 557 deletions

View File

@ -369,6 +369,24 @@ export default function PurchaseOrderList(props: IPurchaseOrderListProps) {
/>
</>
)}
{purchaseOrderVO.state === "REJECTED" && (
<>
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/enter/create", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
</>
)}
</View>
</View>
</View>

View File

@ -56,10 +56,6 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
boxType: "REMAIN",
isUsed: 0,
},
{
boxType: "OWN",
isUsed: 0,
},
],
} as any,
]);

View File

@ -45,7 +45,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
if (supplierVO.isPaper && supplierVO.isLast) {
setPackageTypeEnabled({
OWN: usageMap["OWN"] || 0,
USED: usageMap["USED"] || 0,
EXTRA: 0,
EXTRA_USED: usageMap["EXTRA_USED"] || 0,
@ -53,7 +52,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
});
} else if (supplierVO.isPaper && !supplierVO.isLast) {
setPackageTypeEnabled({
OWN: usageMap["OWN"] || 0,
USED: usageMap["USED"] || 0,
EXTRA: usageMap["EXTRA"] || 0,
EXTRA_USED: 0,
@ -61,10 +59,9 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
});
} else if (!supplierVO.isPaper) {
setPackageTypeEnabled({
OWN: usageMap["OWN"] || 0,
USED: 0,
USED: usageMap["USED"] || 0,
EXTRA: 0,
EXTRA_USED: usageMap["EXTRA_USED"] || 0,
EXTRA_USED: 0,
REMAIN: 0,
});
}
@ -103,33 +100,12 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
// 确定当前供应商需要检查哪些纸箱类型
if (supplierVO.isPaper && supplierVO.isLast) {
// 空磅包含纸箱 + 最后一个瓜农
if (packageTypeEnabled.OWN === 1) {
requiredTypes = ["OWN", "USED"];
if (packageTypeEnabled.REMAIN === 1) {
requiredTypes.push("REMAIN");
}
} else if (packageTypeEnabled.OWN === 2) {
requiredTypes = ["USED", "OWN", "EXTRA_USED"];
if (packageTypeEnabled.REMAIN === 1) {
requiredTypes.push("REMAIN");
}
}
requiredTypes = ["USED", "EXTRA_USED", "REMAIN"];
} else if (supplierVO.isPaper && !supplierVO.isLast) {
// 空磅包含纸箱 + 非最后一个瓜农
if (packageTypeEnabled.OWN === 1) {
requiredTypes = ["OWN", "USED"];
} else if (packageTypeEnabled.OWN === 2) {
requiredTypes = ["USED", "OWN", "EXTRA"];
}
requiredTypes = ["USED", "EXTRA"];
} else if (!supplierVO.isPaper) {
// 空磅不包含纸箱
if (packageTypeEnabled.OWN === 1) {
requiredTypes = ["OWN"];
} else if (packageTypeEnabled.OWN === 2) {
requiredTypes = ["EXTRA_USED"];
}
requiredTypes = ["USED"];
}
console.log("requiredTypes", requiredTypes);
@ -170,7 +146,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
: "记录装车用的纸箱",
EXTRA: "记录额外运输来的所有纸箱",
REMAIN: "记录车上没用完的纸箱",
OWN: "记录装车用的纸箱",
};
Toast.show("toast", {
@ -279,7 +254,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
EXTRA_USED: 0,
EXTRA: 0,
REMAIN: 0,
OWN: 0,
});
console.log("packageTypeEnabled", packageTypeEnabled);
@ -299,7 +273,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
EXTRA_USED: 0,
EXTRA: 0,
REMAIN: 0,
OWN: 0,
},
).map(
([boxType, isUsed]: [
@ -324,416 +297,200 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
return (
<View className="flex flex-1 flex-col gap-2.5 p-2.5">
{/* 替换原来的Tab导航为问答式选择 */}
<View className="rounded-lg bg-white p-2.5 shadow-sm">
<View className="mb-3 text-base font-bold">
{supplierVO.name}使
<View className="flex flex-col gap-2.5 rounded-lg bg-white p-2.5 shadow-sm">
<View className="text-base font-bold">
{supplierVO.name}使
</View>
{/* 是否使用瓜农自己的纸箱 */}
<View className="mb-2.5 flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={packageTypeEnabled.OWN === 1 ? "primary" : "default"}
onClick={() => {
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.OWN === 2) {
setOrderPackageList(
orderPackageList.filter(
(item) =>
item.boxType !== "USED" &&
item.boxType !== "EXTRA_USED" &&
item.boxType !== "EXTRA",
),
);
setPackageTypeEnabled({
...packageTypeEnabled,
USED: 2,
OWN: 1,
EXTRA_USED: 0,
EXTRA: 0,
});
} else {
setPackageTypeEnabled({
...packageTypeEnabled,
USED: 2,
OWN: 1,
});
}
}}
>
</Button>
<Button
size="small"
type={packageTypeEnabled.OWN === 2 ? "primary" : "default"}
onClick={() => {
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.OWN === 1) {
setOrderPackageList(
orderPackageList.filter((item) => item.boxType !== "OWN"),
);
}
if (!supplierVO.isPaper) {
setPackageTypeEnabled({
...packageTypeEnabled,
USED: 1,
OWN: 2,
EXTRA_USED: 1,
});
} else {
setPackageTypeEnabled({
...packageTypeEnabled,
USED: 1,
OWN: 2,
});
}
}}
>
</Button>
</View>
</View>
{/* 根据供应商属性显示不同的问题 */}
{supplierVO.isPaper && supplierVO.isLast && (
/* 当前为最后一个瓜农 */
<>
{packageTypeEnabled.OWN === 1 && (
/* 当选择了使用自己的纸箱时 */
<>
<PackageList
boxType={"OWN"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
{/* 分隔线 */}
<View className="my-4 h-px bg-gray-200" />
{/* 空车带来的纸箱用完了吗? */}
<View className="mb-2.5 flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={
packageTypeEnabled.REMAIN === 2
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
REMAIN: 2,
});
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.REMAIN === 1) {
setOrderPackageList(
orderPackageList.filter(
(item) => item.boxType !== "REMAIN",
),
);
}
}}
>
</Button>
<Button
size="small"
type={
packageTypeEnabled.REMAIN === 1
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
REMAIN: 1,
});
}}
>
</Button>
</View>
</View>
{packageTypeEnabled.REMAIN === 1 && (
<PackageList
boxType={"REMAIN"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
)}
</>
)}
{packageTypeEnabled.OWN === 2 && (
/* 当没有选择使用自己的纸箱时 */
<>
<PackageList
boxType={"USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
{/* 分隔线 */}
<View className="my-4 h-px bg-gray-200" />
{/* 空车带来的纸箱用完了吗? */}
<View className="mb-2.5 flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={
packageTypeEnabled.REMAIN === 2
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
REMAIN: 2,
});
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.REMAIN === 1) {
setOrderPackageList(
orderPackageList.filter(
(item) => item.boxType !== "REMAIN",
),
);
}
}}
>
</Button>
<Button
size="small"
type={
packageTypeEnabled.REMAIN === 1
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
REMAIN: 1,
});
}}
>
</Button>
</View>
</View>
{packageTypeEnabled.REMAIN === 1 && (
<PackageList
boxType={"REMAIN"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
)}
{/* 分隔线 */}
<View className="my-4 h-px bg-gray-200" />
{/* 用额外运输纸箱的了吗? */}
<View className="mb-2.5 flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={
packageTypeEnabled.EXTRA_USED === 1
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA_USED: 1,
});
}}
>
</Button>
<Button
size="small"
type={
packageTypeEnabled.EXTRA_USED === 2
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA_USED: 2,
});
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.EXTRA_USED === 1) {
setOrderPackageList(
orderPackageList.filter(
(item) => item.boxType !== "EXTRA_USED",
),
);
}
}}
>
</Button>
</View>
</View>
{packageTypeEnabled.EXTRA_USED === 1 && (
<PackageList
boxType={"EXTRA_USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
)}
</>
)}
</>
)}
{supplierVO.isPaper && !supplierVO.isLast && (
/* 非最后一个瓜农 */
<>
{packageTypeEnabled.OWN === 1 && (
/* 当选择了使用自己的纸箱时 */
<>
<PackageList
boxType={"OWN"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
{/* 分隔线 */}
<View className="my-4 h-px bg-gray-200" />
</>
)}
{packageTypeEnabled.OWN === 2 && (
/* 当没有选择使用自己的纸箱时 */
<>
<PackageList
boxType={"USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
{/* 分隔线 */}
<View className="my-4 h-px bg-gray-200" />
{/* 有额外运输纸箱过来吗? */}
<View className="mb-2.5 flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={
packageTypeEnabled.EXTRA === 1 ? "primary" : "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA: 1,
});
}}
>
</Button>
<Button
size="small"
type={
packageTypeEnabled.EXTRA === 2 ? "primary" : "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA: 2,
});
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.EXTRA === 1) {
setOrderPackageList(
orderPackageList.filter(
(item) => item.boxType !== "EXTRA",
),
);
}
}}
>
</Button>
</View>
</View>
{packageTypeEnabled.EXTRA === 1 && (
<PackageList
boxType={"EXTRA"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
)}
</>
)}
</>
)}
{!supplierVO.isPaper && (
/* 空磅不包含纸箱 */
<>
{packageTypeEnabled.OWN === 1 && (
/* 当选择了使用自己的纸箱时 */
<>
<PackageList
boxType={"OWN"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
{/* 分隔线 */}
<View className="my-4 h-px bg-gray-200" />
</>
)}
{packageTypeEnabled.OWN === 2 && (
/* 当没有选择使用自己的纸箱时 */
<>
<PackageList
boxType={"EXTRA_USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
supplierVO={supplierVO}
boxBrandList={boxBrandList}
/>
{/* 分隔线 */}
<View className="my-4 h-px bg-gray-200" />
</>
)}
</>
)}
<PackageList
boxType={"USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
boxBrandList={boxBrandList}
/>
</View>
{/* 根据供应商属性显示不同的问题 */}
{supplierVO.isPaper && supplierVO.isLast && (
<>
<View className="flex flex-col gap-2.5 rounded-lg bg-white p-2.5 shadow-sm">
{/* 空车带来的纸箱用完了吗? */}
<View className="flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={
packageTypeEnabled.REMAIN === 2 ? "primary" : "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
REMAIN: 2,
});
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.REMAIN === 1) {
setOrderPackageList(
orderPackageList.filter(
(item) => item.boxType !== "REMAIN",
),
);
}
}}
>
</Button>
<Button
size="small"
type={
packageTypeEnabled.REMAIN === 1 ? "primary" : "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
REMAIN: 1,
});
}}
>
</Button>
</View>
</View>
{packageTypeEnabled.REMAIN === 1 && (
<PackageList
boxType={"REMAIN"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
boxBrandList={boxBrandList}
/>
)}
</View>
<View className="flex flex-col gap-2.5 rounded-lg bg-white p-2.5 shadow-sm">
{/* 用额外运输纸箱的了吗? */}
<View className="flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={
packageTypeEnabled.EXTRA_USED === 1
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA_USED: 1,
});
}}
>
</Button>
<Button
size="small"
type={
packageTypeEnabled.EXTRA_USED === 2
? "primary"
: "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA_USED: 2,
});
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.EXTRA_USED === 1) {
setOrderPackageList(
orderPackageList.filter(
(item) => item.boxType !== "EXTRA_USED",
),
);
}
}}
>
</Button>
</View>
</View>
{packageTypeEnabled.EXTRA_USED === 1 && (
<PackageList
boxType={"EXTRA_USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
boxBrandList={boxBrandList}
/>
)}
</View>
</>
)}
{supplierVO.isPaper && !supplierVO.isLast && (
/* 非最后一个瓜农 */
<View className="flex flex-col gap-2.5 rounded-lg bg-white p-2.5 shadow-sm">
{/* 有额外运输纸箱过来吗? */}
<View className="flex items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={packageTypeEnabled.EXTRA === 1 ? "primary" : "default"}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA: 1,
});
}}
>
</Button>
<Button
size="small"
type={packageTypeEnabled.EXTRA === 2 ? "primary" : "default"}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
EXTRA: 2,
});
// 如果关闭,也需要清除相关数据
if (packageTypeEnabled.EXTRA === 1) {
setOrderPackageList(
orderPackageList.filter(
(item) => item.boxType !== "EXTRA",
),
);
}
}}
>
</Button>
</View>
</View>
{packageTypeEnabled.EXTRA === 1 && (
<PackageList
boxType={"EXTRA"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
boxBrandList={boxBrandList}
/>
)}
</View>
)}
{!supplierVO.isPaper && (
/* 空磅不包含纸箱 */
<View className="rounded-lg bg-white p-2.5 shadow-sm">
<PackageList
boxType={"USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
boxBrandList={boxBrandList}
/>
</View>
)}
</View>
);
},

View File

@ -214,7 +214,7 @@ export default function PurchasePreview(props: IPurchasePreviewProps) {
{(() => {
const groupedPackageInfo = groupBy(
supplier.orderPackageList?.filter(
(item) => item.boxType === "OWN" || item.boxType === "USED",
(item) => item.boxType === "USED",
) || [],
(item) => item?.boxBrandName || "",
);

View File

@ -13,6 +13,7 @@ import { Icon } from "@/components";
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
import { uploadFile, validatePrice } from "@/utils";
import { business } from "@/services";
import { globalStore } from "@/store/global-store";
// 定义ref暴露的方法接口
export interface WeighRef {
@ -29,6 +30,7 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
const { value, onChange, index } = props;
const { orderSupplierList } = value;
const { setLoading } = globalStore((state: any) => state);
const isFirst = index === 0;
@ -76,6 +78,7 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
const supplierVO = orderSupplierList[index];
useEffect(() => {
setLoading(true);
// 获取产品列表
business.product
.listProduct({
@ -88,6 +91,7 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
const products = data.data || [];
setProductList(products);
}
setLoading(false);
});
}, []);
@ -549,8 +553,30 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
<SafeArea position={"bottom"} />
</View>
</Popup>
{isFirst && (
<>
{/* 装车方式 */}
{/*<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">*/}
{/* <View className={"flex items-center justify-between gap-2.5"}>*/}
{/* <View className="text-sm">装车需要纸箱吗?</View>*/}
{/* <View className="text-neutral-darkest text-sm font-medium">*/}
{/* <Radio.Group*/}
{/* direction="horizontal"*/}
{/* value={supplierVO.pricingMethod}*/}
{/* onChange={(value) => {*/}
{/* setSupplierVO({*/}
{/* ...supplierVO,*/}
{/* pricingMethod: value as any,*/}
{/* });*/}
{/* }}*/}
{/* >*/}
{/* <Radio value="BY_GROSS_WEIGHT">需要</Radio>*/}
{/* <Radio value="BY_NET_WEIGHT">不需要</Radio>*/}
{/* </Radio.Group>*/}
{/* </View>*/}
{/* </View>*/}
{/*</View>*/}
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className={"flex items-center justify-between gap-2.5"}>
<View className="text-sm"></View>
@ -602,7 +628,7 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
{productList.length > 0 && (
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className={"flex items-center justify-between gap-2.5"}>
<View className="text-sm">西</View>
<View className="text-sm">西</View>
<View className="text-neutral-darkest text-sm font-medium">
<Radio.Group
direction="horizontal"
@ -654,10 +680,33 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
)}
</>
)}
{/* 瓜农包纸箱吗,包纸箱按照毛重报价,不包按照净重报价 */}
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className={"flex items-center justify-between gap-2.5"}>
<View className="text-sm"></View>
<View className="text-neutral-darkest text-sm font-medium">
<Radio.Group
direction="horizontal"
value={supplierVO.pricingMethod}
onChange={(value) => {
setSupplierVO({
...supplierVO,
pricingMethod: value as any,
});
}}
>
<Radio value="BY_GROSS_WEIGHT"></Radio>
<Radio value="BY_NET_WEIGHT"></Radio>
</Radio.Group>
</View>
</View>
</View>
{/* 有定金吗,有定金就要填写本车扣多少定金 */}
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className={"flex items-center justify-between gap-2.5"}>
<View className="text-sm"></View>
<View className="text-sm"></View>
<View className="text-neutral-darkest text-sm font-medium">
<Radio.Group
direction="horizontal"
@ -687,15 +736,15 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
});
}}
>
<Radio value="true"></Radio>
<Radio value="false"></Radio>
<Radio value="true"></Radio>
<Radio value="false"></Radio>
</Radio.Group>
</View>
</View>
{supplierVO.isDepositPaid === true && (
<View className="mt-2.5">
<View className="mb-1 text-sm"></View>
<View className="mb-1 text-sm"></View>
<View
className={`flex h-10 w-full items-center rounded-md ${depositError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
>

View File

@ -8,19 +8,13 @@ import { BoxBrand } from "@/types/typings";
interface IPackageListProps {
boxType: BusinessAPI.OrderPackage["boxType"];
orderPackageList: BusinessAPI.OrderPackage[];
supplierVO: BusinessAPI.OrderSupplier;
boxBrandList?: BoxBrand[];
setOrderPackageList: (orderPackageList: BusinessAPI.OrderPackage[]) => void;
}
export default function PackageList(props: IPackageListProps) {
const {
boxType,
orderPackageList,
supplierVO,
boxBrandList,
setOrderPackageList,
} = props;
const { boxType, orderPackageList, boxBrandList, setOrderPackageList } =
props;
// 批量添加纸箱弹窗状态
const [showBatchModal, setShowBatchModal] = useState(false);
@ -33,10 +27,9 @@ export default function PackageList(props: IPackageListProps) {
// 根据类型设置显示标题
const typeLabels = {
USED: "装车用的纸箱",
EXTRA_USED: supplierVO.isPaper ? "用的额外运输纸箱" : "装车用的纸箱",
EXTRA_USED: "用的额外运输纸箱",
EXTRA: "额外运输来的所有纸箱",
REMAIN: "车上没用完的纸箱",
OWN: "装车用的纸箱",
};
if (!boxBrandList) {

View File

@ -204,26 +204,28 @@ export default function PackageInfoSection(props: {
// 将所有包装信息合并并按品牌、型号、规格分组
const groupedPackageData = purchaseOrderVO.orderSupplierList?.reduce(
(acc, supplier) => {
supplier.orderPackageList?.forEach((pkg) => {
// 生成分组键
const key = `${pkg.boxBrandName}-${pkg.boxProductName}-${pkg.boxSpecId}`;
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;
// 转换规格字段
const boxSpecId = pkg.boxSpecId;
const boxSpecName = pkg.boxSpecName;
if (!acc[key]) {
acc[key] = {
...pkg,
boxSpecId,
boxSpecName,
boxProductCount: 0,
};
}
if (!acc[key]) {
acc[key] = {
...pkg,
boxSpecId,
boxSpecName,
boxProductCount: 0,
};
}
// 累加数量
acc[key].boxProductCount += pkg.boxCount || 0;
});
// 累加数量
acc[key].boxProductCount += pkg.boxCount || 0;
});
return acc;
},

View File

@ -1,2 +1,2 @@
// App 相关常量
export const APP_VERSION = "v0.0.29";
export const APP_VERSION = "v0.0.31";

View File

@ -514,6 +514,20 @@ export default hocAuth(function Page(props: CommonComponent) {
return null;
}
if (
sectionKey === "purchaseForm" &&
purchaseOrderVO.orderDealer.shortName !== "信誉楼"
) {
return null;
}
if (
sectionKey === "deliveryForm" &&
purchaseOrderVO.orderDealer.shortName === "信誉楼"
) {
return null;
}
return (
<>
<View className="text-sm font-bold">{section.title}</View>

View File

@ -69,10 +69,6 @@ const defaultSupplierList: Partial<BusinessAPI.OrderSupplier>[] = [
boxType: "REMAIN",
isUsed: 0,
},
{
boxType: "OWN",
isUsed: 0,
},
],
},
];

View File

@ -913,7 +913,7 @@ declare namespace BusinessAPI {
/** 状态1_启用0_禁用 */
status: boolean;
/** 成本项ID */
costItemIds?: string[];
costItemIds?: number[];
};
type CostDestroyCmd = {
@ -1123,7 +1123,7 @@ declare namespace BusinessAPI {
/** 状态1_启用0_禁用 */
status: boolean;
/** 成本项ID */
costItemIds?: string[];
costItemIds?: number[];
};
type CostVO = {
@ -1150,7 +1150,7 @@ declare namespace BusinessAPI {
/** 状态1_启用0_禁用 */
status: boolean;
/** 项目id集合 */
costItemIds?: string[];
costItemIds?: number[];
/** 创建时间 */
createdAt?: string;
/** 项目列表 */
@ -2648,7 +2648,7 @@ declare namespace BusinessAPI {
| "PRODUCTION_TYPE"
| "OTHER_TYPE";
/** 关联项目id */
costItemIds?: string[];
costItemIds?: number[];
/** 是否选中 */
selected: boolean;
};
@ -2739,7 +2739,7 @@ declare namespace BusinessAPI {
/** 箱子品牌类型1_我方纸箱2_瓜农纸箱3_第三方纸箱4_礼盒 */
boxBrandType: "OUR_BOX" | "FARMER_BOX" | "THIRD_PARTY_BOX" | "GIFT_BOX";
/** 箱子规格ID */
boxSpecId: number;
boxSpecId: string;
/** 箱子规格名称 */
boxSpecName: string;
/** 箱子产品ID */
@ -2754,8 +2754,8 @@ declare namespace BusinessAPI {
boxCostPrice?: number;
/** 销售单价(元/个) */
boxSalePrice?: number;
/** 箱子类型:1_本次使用2_额外运输3_已使用额外运输4_车上剩余5_瓜农纸箱6_空箱 */
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "OWN" | "EMPTY";
/** 箱子类型:1_本次使用2_额外运输3_已使用额外运输4_车上剩余6_空箱 */
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "EMPTY";
};
type OrderRebate = {
@ -2814,6 +2814,8 @@ declare namespace BusinessAPI {
packageUsage: SupplierPackageUsage[];
/** 销售单价(元/斤) */
salePrice: number;
/** 报价方式1_按毛重报价2_按净重报价 */
pricingMethod?: "BY_GROSS_WEIGHT" | "BY_NET_WEIGHT";
/** 发票金额 */
invoiceAmount: number;
/** 空车照片 */
@ -3874,24 +3876,6 @@ declare namespace BusinessAPI {
foreman?: string;
/** 报价方式1_按毛重报价2_按净重报价 */
pricingMethod?: "BY_GROSS_WEIGHT" | "BY_NET_WEIGHT";
/** 销售金额 */
saleAmount?: number;
/** 包装费 */
packageFee?: number;
/** 平均单价(元/斤) */
avgUnitPrice?: number;
/** 是否返点 */
rebate?: boolean;
/** 毛重(斤) */
grossWeight?: number;
/** 净重(斤) */
netWeight?: number;
/** 成本合计 */
totalCost?: number;
/** 运费 */
freightCharge?: number;
/** 瓜农数量 */
supplierCount?: number;
/** 采购订单状态: 0_草稿1_审核中2_已完成3_已驳回4_已关闭 */
state?: "DRAFT" | "WAITING_AUDIT" | "COMPLETED" | "REJECTED" | "CLOSED";
/** 采购单审核状态: 1_待报价审核2_待老板审批3_老板审批通过4_报价审核驳回5_老板审批驳回 */
@ -4842,8 +4826,8 @@ declare namespace BusinessAPI {
};
type SupplierPackageUsage = {
/** 箱子类型:1_本次使用2_额外运输3_已使用额外运输4_车上剩余5_瓜农纸箱6_空箱 */
boxType?: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "OWN" | "EMPTY";
/** 箱子类型:1_本次使用2_额外运输3_已使用额外运输4_车上剩余6_空箱 */
boxType?: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "EMPTY";
/** 是否使用:0_未回答1_使用2_未使用 */
isUsed?: number;
};

View File

@ -33,7 +33,7 @@ export interface BoxBrand {
boxBrandName: string;
boxBrandImage: string;
boxBrandType: "OUR_BOX" | "FARMER_BOX" | "THIRD_PARTY_BOX" | "GIFT_BOX";
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "OWN" | "EMPTY";
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "EMPTY";
boxSpecList: BoxSpec[];
}

View File

@ -75,9 +75,7 @@ export class PurchaseOrderCalculator {
name?: BusinessAPI.OrderCost["name"],
): number {
return this.purchaseOrderVO.orderCostList
?.filter(
(item) => item.type === type && (!name || item.name === name),
)
?.filter((item) => item.type === type && (!name || item.name === name))
.reduce((sum, cost) => {
return new Decimal(sum)
.plus(new Decimal(cost.price || 0).mul(cost.count || 0))
@ -116,19 +114,13 @@ export class PurchaseOrderCalculator {
}
/**
* 西 = (西+) *
* 西 = / *
*/
getSupplierPurchaseCost(): number {
return this.purchaseOrderVO.orderSupplierList.reduce((sum, supplier) => {
// return new Decimal(sum)
// .plus(this.calculateSupplierAmount(supplier))
// .toNumber();
const netWeight = supplier.netWeight || 0;
// 瓜农自己的纸箱重量
const ownBoxWeight =
supplier.orderPackageList
?.filter((pkg) => pkg.boxType === "OWN")
?.filter((pkg) => pkg.boxType === "USED")
?.reduce((sum, pkg) => {
return new Decimal(sum)
.plus(
@ -139,7 +131,11 @@ export class PurchaseOrderCalculator {
return new Decimal(sum)
.plus(
new Decimal(netWeight)
new Decimal(
supplier.pricingMethod === "BY_GROSS_WEIGHT"
? supplier.grossWeight
: supplier.netWeight,
)
.plus(ownBoxWeight)
.mul(supplier.purchasePrice || 0),
)
@ -229,14 +225,13 @@ export class PurchaseOrderCalculator {
return this.purchaseOrderVO.orderSupplierList.reduce((sum, supplier) => {
return new Decimal(sum)
.plus(
supplier.orderPackageList?.reduce((sum, pkg) => {
if (pkg.boxType === "OWN") {
return 0;
}
return new Decimal(sum)
.plus(new Decimal(pkg.boxCount || 0).mul(pkg.boxSalePrice || 0))
.toNumber();
}, 0) || 0,
supplier.orderPackageList
?.filter((pkg) => pkg.boxType === "USED")
.reduce((sum, pkg) => {
return new Decimal(sum)
.plus(new Decimal(pkg.boxCount || 0).mul(pkg.boxSalePrice || 0))
.toNumber();
}, 0) || 0,
)
.toNumber();
}, 0);
@ -488,9 +483,11 @@ export class PurchaseOrderCalculator {
return this.purchaseOrderVO.orderSupplierList.reduce((sum, supplier) => {
return new Decimal(sum)
.plus(
supplier.orderPackageList?.reduce((sum, pkg) => {
return new Decimal(sum).plus(pkg.boxCount || 0).toNumber();
}, 0) || 0,
supplier.orderPackageList
?.filter((pkg) => pkg.boxType === "USED")
?.reduce((sum, pkg) => {
return new Decimal(sum).plus(pkg.boxCount || 0).toNumber();
}, 0) || 0,
)
.toNumber();
}, 0);
@ -503,13 +500,15 @@ export class PurchaseOrderCalculator {
return this.purchaseOrderVO.orderSupplierList.reduce((sum, supplier) => {
return new Decimal(sum)
.plus(
supplier.orderPackageList?.reduce((sum, pkg) => {
return new Decimal(sum)
.plus(
new Decimal(pkg.boxProductWeight || 0).mul(pkg.boxCount || 0),
)
.toNumber();
}, 0) || 0,
supplier.orderPackageList
?.filter((pkg) => pkg.boxType === "USED")
?.reduce((sum, pkg) => {
return new Decimal(sum)
.plus(
new Decimal(pkg.boxProductWeight || 0).mul(pkg.boxCount || 0),
)
.toNumber();
}, 0) || 0,
)
.toNumber();
}, 0);

View File

@ -54,12 +54,6 @@ export class SupplierWeightCalculator {
const usedBoxesWeight = new Decimal(
this.calculateBoxesTotalWeight(supplier.orderPackageList || [], "USED"),
)
.add(
this.calculateBoxesTotalWeight(
supplier.orderPackageList || [],
"OWN",
),
)
.toNumber();
// 计算额外配送的已使用纸箱总重量(斤)

View File

@ -44,15 +44,6 @@ export const convertPurchaseOrderToShipOrder = (
(sum, supplier) => sum + (supplier.netWeight || 0), 0
);
const totalBoxWeight = suppliers.reduce(
(sum, supplier) => {
if (supplier.totalWeight && supplier.netWeight) {
return sum + (supplier.totalWeight - supplier.netWeight);
}
return sum;
}, 0
);
const totalAmount = suppliers.reduce(
(sum, supplier) => sum + (supplier.invoiceAmount || 0), 0
);
@ -61,7 +52,7 @@ export const convertPurchaseOrderToShipOrder = (
itemId: generateShortId(),
shipOrderId: "", // 将在创建发货单时填充
grossWeight: totalGrossWeight,
boxWeight: totalBoxWeight,
boxWeight: totalGrossWeight - totalNetWeight,
netWeight: totalNetWeight,
unitPrice: parseFloat(price),
totalAmount: totalAmount,
@ -74,7 +65,7 @@ export const convertPurchaseOrderToShipOrder = (
const allPackages: BusinessAPI.OrderPackage[] = [];
purchaseOrderVO.orderSupplierList?.forEach(supplier => {
if (supplier.orderPackageList) {
allPackages.push(...supplier.orderPackageList);
allPackages.push(...supplier.orderPackageList.filter(pkg => pkg.boxType === 'USED'));
}
});

File diff suppressed because one or more lines are too long