update customer package
This commit is contained in:
@@ -84,30 +84,28 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PackageAPI from "@/api/PackageAPI";
|
||||
import SalesOrderAPI from "@/api/SalesOrderAPI";
|
||||
import FulfillmentAPI from "@/api/FulfillmentAPI";
|
||||
import PhotoScroller from "@/components/PhotoScroller.vue";
|
||||
import { useNavBarStore } from "@/store/navBarStore";
|
||||
import type { CustomerPackageItem, GaoCustomerPackage } from "@/types/Package";
|
||||
import type { OrderFulfillmentItemRequest } from "@/types/Fulfillment";
|
||||
import type { SalesOrder, SalesOrderItem } from "@/types/SalesOrder";
|
||||
import { useUserStore } from "timi-web-api";
|
||||
import type { GaoOrderFulfillmentItemRequest } from "@/types/Fulfillment";
|
||||
import type { GaoSalesOrderItem, SalesOrder } from "@/types/SalesOrder";
|
||||
import type { PhotoItem } from "@/types/Photo";
|
||||
import type { Attachment } from "timi-web-api";
|
||||
import { createPackageRequestNo, getPackageQuantityText, normalizePackageQuantity } from "@/utils/package";
|
||||
import { comparePackageQuantity, createPackageRequestNo, getPackageQuantityText, normalizePackageQuantity } from "@/utils/package";
|
||||
import { getErrorMessage } from "@/utils/error";
|
||||
import { Message } from "@/utils/message";
|
||||
import { permissionCodes } from "@/utils/permission";
|
||||
import { uploadPhotoList } from "@/utils/photo";
|
||||
import { getProductPhotoURL } from "@/utils/product";
|
||||
|
||||
type SourceItem = SalesOrderItem | CustomerPackageItem;
|
||||
defineOptions({ name: "OrderFulfillmentCreate" });
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const navBarStore = useNavBarStore();
|
||||
const userStore = useUserStore();
|
||||
const order = ref<SalesOrder>();
|
||||
const customerPackage = ref<GaoCustomerPackage>();
|
||||
const quantityMap = reactive<Record<string, string>>({});
|
||||
const deliveredAtText = ref("");
|
||||
const draftTime = ref("");
|
||||
@@ -117,12 +115,14 @@ const requestNo = ref("");
|
||||
const isSaving = ref(false);
|
||||
const photoItems = ref<PhotoItem[]>([]);
|
||||
const photoUrlList = computed(() => photoItems.value.map(item => item.url));
|
||||
const isPackage = computed(() => !!customerPackage.value);
|
||||
const sourceItems = computed<SourceItem[]>(() => customerPackage.value?.itemList || order.value?.itemList || []);
|
||||
const isPackage = computed(() => order.value?.orderType === "PACKAGE");
|
||||
const expectedItemType = computed(() => isPackage.value ? "PACKAGE_ENTITLEMENT" : "DIRECT_PRODUCT");
|
||||
const sourceItems = computed<GaoSalesOrderItem[]>(() => (order.value?.itemList || []).filter(item => item.itemType === expectedItemType.value));
|
||||
const canOperateStock = computed(() => userStore.hasPermissions(permissionCodes.productStock.create));
|
||||
const canFulfillByPayment = computed(() => order.value?.paymentStatus === "PAID" || (order.value?.paymentStatus === "PARTIALLY_PAID" && canOperateStock.value));
|
||||
|
||||
async function loadData(): Promise<void> {
|
||||
const salesOrderId = String(route.query.salesOrderId || "");
|
||||
const customerPackageId = String(route.query.customerPackageId || "");
|
||||
if (!salesOrderId) {
|
||||
Message.warning("请从订单详情或客户套餐详情进入履约创建");
|
||||
await router.replace("/management/order-fulfillments");
|
||||
@@ -130,26 +130,20 @@ async function loadData(): Promise<void> {
|
||||
}
|
||||
try {
|
||||
order.value = await SalesOrderAPI.detail(salesOrderId);
|
||||
if (customerPackageId) customerPackage.value = await PackageAPI.customerPackageDetail(customerPackageId);
|
||||
} catch (error) {
|
||||
Message.error(getErrorMessage(error, "履约来源加载失败"));
|
||||
}
|
||||
}
|
||||
|
||||
function getAvailableQuantity(item: SourceItem): string {
|
||||
if (isPackage.value) {
|
||||
return getPackageQuantityText((item as CustomerPackageItem).availableQuantity);
|
||||
}
|
||||
const orderItem = item as SalesOrderItem;
|
||||
const availableQuantity = Math.max(0, Number(orderItem.quantity || 0) - Number(orderItem.reservedQuantity || 0) - Number(orderItem.fulfilledQuantity || 0));
|
||||
return getPackageQuantityText(availableQuantity.toFixed(3));
|
||||
function getAvailableQuantity(item: GaoSalesOrderItem): string {
|
||||
return getPackageQuantityText(item.availableQuantity);
|
||||
}
|
||||
|
||||
function getItemDescription(item: SourceItem): string {
|
||||
function getItemDescription(item: GaoSalesOrderItem): string {
|
||||
return ` · 剩余 ${getAvailableQuantity(item)}`;
|
||||
}
|
||||
|
||||
function fillAllQuantity(item: SourceItem): void {
|
||||
function fillAllQuantity(item: GaoSalesOrderItem): void {
|
||||
if (item.id) {
|
||||
quantityMap[item.id] = getAvailableQuantity(item);
|
||||
}
|
||||
@@ -178,6 +172,14 @@ function validate(): boolean {
|
||||
Message.warning("请从订单详情或客户套餐详情进入履约创建");
|
||||
return false;
|
||||
}
|
||||
if (order.value.status !== "ACTIVE") {
|
||||
Message.warning("当前订单不是进行中状态,不能创建履约");
|
||||
return false;
|
||||
}
|
||||
if (!canFulfillByPayment.value) {
|
||||
Message.warning("订单尚未满足履约收款条件");
|
||||
return false;
|
||||
}
|
||||
if (!buildAttachments().length) {
|
||||
Message.warning("履约必须上传至少一张照片");
|
||||
return false;
|
||||
@@ -188,10 +190,15 @@ function validate(): boolean {
|
||||
return false;
|
||||
}
|
||||
for (const item of selected) {
|
||||
if (!normalizePackageQuantity(quantityMap[item.id || ""])) {
|
||||
const quantity = normalizePackageQuantity(quantityMap[item.id || ""]);
|
||||
if (!quantity) {
|
||||
Message.warning("履约数量必须是正数,最多三位小数");
|
||||
return false;
|
||||
}
|
||||
if (0 < comparePackageQuantity(quantity, item.availableQuantity ?? "0")) {
|
||||
Message.warning(`${item.productNameSnapshot || "产品"} 的可履约数量不足`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -201,10 +208,10 @@ async function save(): Promise<void> {
|
||||
if (!requestNo.value) requestNo.value = createPackageRequestNo();
|
||||
isSaving.value = true;
|
||||
try {
|
||||
const itemList: OrderFulfillmentItemRequest[] = sourceItems.value
|
||||
const itemList: GaoOrderFulfillmentItemRequest[] = sourceItems.value
|
||||
.filter(item => !!item.id && quantityMap[item.id])
|
||||
.map(item => ({
|
||||
...(isPackage.value ? { sourceCustomerPackageItemId: item.id } : { sourceOrderItemId: item.id }),
|
||||
sourceOrderItemId: item.id!,
|
||||
quantity: normalizePackageQuantity(quantityMap[item.id || ""])!
|
||||
}));
|
||||
const result = await FulfillmentAPI.create({
|
||||
|
||||
Reference in New Issue
Block a user