fix order/fulfillment unit
This commit is contained in:
@@ -191,7 +191,7 @@ async function loadFulfillmentSkuList(): Promise<void> {
|
||||
continue;
|
||||
}
|
||||
const originalUnit = getSellableUnitList(item).find(unit => unit.id === item.skuUnitId);
|
||||
const defaultUnit = originalUnit || getSellableUnitList(item)[0];
|
||||
const defaultUnit = getFulfillmentUnitForAvailableQuantity(item, originalUnit || getSellableUnitList(item)[0]);
|
||||
if (defaultUnit?.id) {
|
||||
fulfillmentUnitMap[item.id] = defaultUnit.id;
|
||||
}
|
||||
@@ -217,7 +217,26 @@ function getItemDescription(item: GaoSalesOrderItem): string {
|
||||
}
|
||||
|
||||
function getBaseUnitName(item: GaoSalesOrderItem): string {
|
||||
return item.skuId ? fulfillmentSkuMap[item.skuId]?.unitList?.find(unit => unit.isBase)?.name || "基础单位" : "基础单位";
|
||||
return getBaseUnit(item)?.name || "基础单位";
|
||||
}
|
||||
|
||||
function getBaseUnit(item: GaoSalesOrderItem): ProductSkuUnit | undefined {
|
||||
return getSellableUnitList(item).find(unit => unit.isBase);
|
||||
}
|
||||
|
||||
function shouldDowngradeUnit(item: GaoSalesOrderItem, unit?: ProductSkuUnit): boolean {
|
||||
const sku = item.skuId ? fulfillmentSkuMap[item.skuId] : undefined;
|
||||
if (!unit || unit.isBase || sku?.allowDecimalQuantity !== false) {
|
||||
return false;
|
||||
}
|
||||
return Number(getAvailableBaseQuantity(item)) < Number(unit.baseQuantityPerUnit);
|
||||
}
|
||||
|
||||
function getFulfillmentUnitForAvailableQuantity(item: GaoSalesOrderItem, unit?: ProductSkuUnit): ProductSkuUnit | undefined {
|
||||
if (!shouldDowngradeUnit(item, unit)) {
|
||||
return unit;
|
||||
}
|
||||
return getBaseUnit(item) || unit;
|
||||
}
|
||||
|
||||
function fillAllQuantity(item: GaoSalesOrderItem): void {
|
||||
@@ -242,6 +261,22 @@ function getFulfillmentUnit(item: GaoSalesOrderItem): ProductSkuUnit | undefined
|
||||
return getSellableUnitList(item).find(unit => unit.id === fulfillmentUnitMap[item.id || ""]);
|
||||
}
|
||||
|
||||
function setFulfillmentUnit(item: GaoSalesOrderItem, unit: ProductSkuUnit): void {
|
||||
if (!item.id) {
|
||||
return;
|
||||
}
|
||||
const currentUnit = getFulfillmentUnit(item);
|
||||
const currentQuantity = quantityMap[item.id];
|
||||
if (currentQuantity && currentUnit?.id !== unit.id) {
|
||||
quantityMap[item.id] = convertPackageQuantity(
|
||||
currentQuantity,
|
||||
currentUnit?.baseQuantityPerUnit ?? "1",
|
||||
unit.baseQuantityPerUnit
|
||||
) || "";
|
||||
}
|
||||
fulfillmentUnitMap[item.id] = unit.id!;
|
||||
}
|
||||
|
||||
function openUnitPicker(item: GaoSalesOrderItem): void {
|
||||
if (!item.id) {
|
||||
return;
|
||||
@@ -257,8 +292,11 @@ function openUnitPicker(item: GaoSalesOrderItem): void {
|
||||
|
||||
function confirmUnitPicker(value: Array<string | number>): void {
|
||||
const skuUnitId = String(value[0] || "");
|
||||
if (unitPickerSourceItemId.value && skuUnitId) {
|
||||
fulfillmentUnitMap[unitPickerSourceItemId.value] = skuUnitId;
|
||||
const item = sourceItems.value.find(sourceItem => sourceItem.id === unitPickerSourceItemId.value);
|
||||
const selectedUnit = item ? getSellableUnitList(item).find(unit => unit.id === skuUnitId) : undefined;
|
||||
const fulfillmentUnit = item ? getFulfillmentUnitForAvailableQuantity(item, selectedUnit) : selectedUnit;
|
||||
if (item?.id && fulfillmentUnit?.id) {
|
||||
setFulfillmentUnit(item, fulfillmentUnit);
|
||||
}
|
||||
unitPickerVisible.value = false;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
v-for="item in fulfillment.itemList || []"
|
||||
:key="item.id"
|
||||
:title="item.productNameSnapshot || '未命名产品'"
|
||||
:note="`待履约(基础单位)${item.reservedBaseBefore || 0} → ${item.reservedBaseAfter || 0}`"
|
||||
>
|
||||
<template #description>
|
||||
<div class="item-description">
|
||||
@@ -41,7 +40,7 @@
|
||||
:fallback="item.specSummarySnapshot || item.skuNameSnapshot || '默认 SKU'"
|
||||
:unit="item.unitSnapshot"
|
||||
/>
|
||||
<span v-text="`履约数量 ${item.quantity || 0}`" />
|
||||
<span v-text="getFulfillmentQuantityText(item)" />
|
||||
</div>
|
||||
</template>
|
||||
<template #leftIcon>
|
||||
@@ -94,7 +93,9 @@
|
||||
<t-dialog
|
||||
v-model:visible="reasonVisible"
|
||||
:title="reasonAction === 'reject' ? '拒绝履约' : '撤销履约'"
|
||||
cancel-btn="取消"
|
||||
:confirm-btn="reasonAction === 'reject' ? '拒绝' : '撤销'"
|
||||
@cancel="reasonVisible = false"
|
||||
@confirm="submitReason"
|
||||
>
|
||||
<t-textarea v-model.trim="reason" borderless autosize placeholder="请输入原因" />
|
||||
@@ -102,24 +103,33 @@
|
||||
<bottom-popup
|
||||
v-model="revokeVisible"
|
||||
title="履约冲正"
|
||||
height="min(55vh, 32rem)"
|
||||
left-button-text="取消"
|
||||
right-button-text="提交"
|
||||
@left-button-click="revokeVisible = false"
|
||||
@right-button-click="submitRevoke"
|
||||
>
|
||||
<t-form label-align="top">
|
||||
<t-form-item label="冲正原因" required-mark><t-textarea v-model.trim="revokeReason" borderless autosize /></t-form-item>
|
||||
<t-form-item label="库存是否退回门店"><t-switch v-model="returnedToStore" /></t-form-item>
|
||||
<t-form class="revoke-form">
|
||||
<t-form-item label="冲正原因" required-mark>
|
||||
<t-textarea
|
||||
v-model="revokeReason"
|
||||
borderless
|
||||
autosize
|
||||
/>
|
||||
</t-form-item>
|
||||
<t-form-item label="库存退回门店" content-align="right">
|
||||
<t-switch v-model="returnedToStore" />
|
||||
</t-form-item>
|
||||
<t-form-item label-width="0">
|
||||
<photo-scroller
|
||||
:model-value="photoUrlList"
|
||||
v-model:photo-items="photoItems"
|
||||
:upload="uploadPhotoList"
|
||||
:edit-mode="true"
|
||||
required
|
||||
title="冲正凭证照片"
|
||||
/>
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
<photo-scroller
|
||||
:model-value="photoUrlList"
|
||||
v-model:photo-items="photoItems"
|
||||
:upload="uploadPhotoList"
|
||||
:edit-mode="true"
|
||||
required
|
||||
title="冲正凭证照片"
|
||||
/>
|
||||
</bottom-popup>
|
||||
</div>
|
||||
</template>
|
||||
@@ -133,11 +143,11 @@ import SalesOrderAPI from "@/api/SalesOrderAPI";
|
||||
import PhotoScroller from "@/components/PhotoScroller.vue";
|
||||
import ProductSkuSnapshotTags from "@/components/ProductSkuSnapshotTags.vue";
|
||||
import { useNavBarStore } from "@/store/navBarStore";
|
||||
import type { OrderFulfillment } from "@/types/Fulfillment";
|
||||
import type { OrderFulfillment, OrderFulfillmentItem } from "@/types/Fulfillment";
|
||||
import type { GaoSalesOrderItemType, SalesOrder } from "@/types/SalesOrder";
|
||||
import type { PhotoItem } from "@/types/Photo";
|
||||
import type { Attachment } from "timi-web-api";
|
||||
import { createPackageRequestNo } from "@/utils/package";
|
||||
import { createPackageRequestNo, getPackageQuantityText } from "@/utils/package";
|
||||
import { getAttachmentReadURL } from "@/utils/attachment";
|
||||
import { getErrorMessage } from "@/utils/error";
|
||||
import { getProductPhotoURL } from "@/utils/product";
|
||||
@@ -186,6 +196,10 @@ const sourceItemType = computed<GaoSalesOrderItemType | undefined>(() => {
|
||||
return order.value?.itemList?.find(item => item.id === sourceOrderItemId)?.itemType;
|
||||
});
|
||||
|
||||
function getFulfillmentQuantityText(item: OrderFulfillmentItem): string {
|
||||
return `履约数量 ${getPackageQuantityText(item.quantity)} ${item.unitSnapshot || "单位"}`;
|
||||
}
|
||||
|
||||
async function loadData(): Promise<void> {
|
||||
const id = String(route.params.id || "");
|
||||
if (!id) return;
|
||||
@@ -339,4 +353,8 @@ onUnmounted(() => navBarStore.clearRight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.revoke-form {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user