add SalesOrderStraightThroughRequest paymentAmount

This commit is contained in:
Timi
2026-09-14 00:47:47 +08:00
parent 844879773f
commit a87609261b
4 changed files with 116 additions and 30 deletions
+46 -12
View File
@@ -170,6 +170,24 @@
/>
</div>
</t-form-item>
<t-form-item
v-if="canReceiveImmediately"
class="payment-item"
:class="{ disabled: receiveFullPayment }"
:label="receiveFullPayment ? '收款和核销金额' : '已部分收款和核销'"
label-width="9rem"
content-align="right"
>
<t-input
:model-value="receiveFullPayment ? formatPackageAmount(parsedSaleAmount || 0) : paymentAmountText"
type="number"
align="right"
borderless
:disabled="receiveFullPayment"
:placeholder="paymentAmountPlaceholder"
@update:model-value="paymentAmountText = String($event)"
/>
</t-form-item>
<t-form-item label="已全额收款和核销" content-align="right">
<t-switch
v-model="receiveFullPayment"
@@ -187,7 +205,7 @@
<t-form-item label-width="0">
<div class="red">全部履约会同步启用全额收款;请先准备全部产品库存,任意一步失败,整张订单都会回滚。</div>
</t-form-item>
<t-form-item v-if="receiveFullPayment && parsedSaleAmount" label-width="0">
<t-form-item v-if="(paymentVerified && parsedPaymentAmount) || (receiveFullPayment && parsedSaleAmount)" label-width="0">
<photo-scroller
:model-value="paymentPhotoUrlList"
v-model:photo-items="paymentPhotoItems"
@@ -486,9 +504,16 @@ const isSaving = ref(false);
const photoItems = ref<PhotoItem[]>([]);
const paymentPhotoItems = ref<PhotoItem[]>([]);
const fulfillmentPhotoItems = ref<PhotoItem[]>([]);
const paymentAmountText = ref("0");
const photoUrlList = computed(() => photoItems.value.map(item => item.url));
const paymentPhotoUrlList = computed(() => paymentPhotoItems.value.map(item => item.url));
const fulfillmentPhotoUrlList = computed(() => fulfillmentPhotoItems.value.map(item => item.url));
const receiveFullPayment = ref(false);
const fulfillAll = ref(false);
const parsedPaymentAmount = computed(() => parsePackageAmount(paymentAmountText.value));
const paymentVerified = computed(() => !receiveFullPayment.value
&& 0 < paymentAmountText.value.trim().length
&& parsedPaymentAmount.value !== 0);
function buildAttachments(source: PhotoItem[] = photoItems.value): PackageAttachment[] {
return source.flatMap(item => item.tempFileId ? [{
@@ -497,9 +522,6 @@ function buildAttachments(source: PhotoItem[] = photoItems.value): PackageAttach
}] : []);
}
const receiveFullPayment = ref(false);
const fulfillAll = ref(false);
const {
isSaleable,
canPriceOverride,
@@ -514,6 +536,8 @@ const {
config,
selectedCustomerList,
note,
paymentVerified,
paymentAmount: parsedPaymentAmount,
receiveFullPayment,
fulfillAll,
hasPermission: permissionCode => userStore.hasPermissions(permissionCode),
@@ -524,6 +548,7 @@ const {
});
const parsedSaleAmount = computed(() => parsePackageAmount(saleAmountText.value));
const paymentAmountPlaceholder = computed(() => `订单总金额:${formatPackageAmount(parsedSaleAmount.value || 0)}`);
const canReceiveImmediately = computed(() => userStore.hasPermissions(permissionCodes.fundReceive.create)
&& userStore.hasPermissions(permissionCodes.fundReceive.verify));
const canFulfillImmediately = computed(() => userStore.hasPermissions(permissionCodes.orderFulfillment.create)
@@ -537,7 +562,7 @@ watch(fulfillAll, value => {
});
watch(receiveFullPayment, value => {
if (!value && parsedSaleAmount.value !== 0) {
if (!value && parsedSaleAmount.value !== 0 && (!paymentVerified.value || parsedPaymentAmount.value !== parsedSaleAmount.value)) {
fulfillAll.value = false;
}
});
@@ -744,12 +769,14 @@ async function submitRecord(): Promise<void> {
if (!validatePurchaseForm() || !validateItemDecimalQuantity()) {
return;
}
if (receiveFullPayment.value || fulfillAll.value) {
if (paymentVerified.value || receiveFullPayment.value || fulfillAll.value) {
const dialog = DialogPlugin.confirm({
title: "确认直通完成交易",
content: fulfillAll.value
? "将一次性购买套餐、核销全额收款,并完成全部履约和库存扣减。提交后如需更正,只能走撤销或冲正流程。"
: "将一次性购买套餐并核销全额收款。提交后如需更正,只能走资金冲正流程。",
? "将一次性购买套餐、完成收款核销,并完成全部履约和库存扣减。提交后如需更正,只能走撤销或冲正流程。"
: paymentVerified.value
? "将一次性购买套餐并登记已核销收款。提交后如需更正,只能走资金冲正流程。"
: "将一次性购买套餐并核销全额收款。提交后如需更正,只能走资金冲正流程。",
cancelBtn: "取消",
confirmBtn: "确认并提交",
onCancel() {
@@ -775,7 +802,7 @@ async function purchasePackage(): Promise<void> {
return;
}
await settingStore.playRegisterSuccessSound();
Message.success(fulfillAll.value ? "套餐、收款及履约已完成" : receiveFullPayment.value ? "套餐及全额收款已完成" : "套餐购买已提交");
Message.success(fulfillAll.value ? "套餐、收款及履约已完成" : paymentVerified.value ? "套餐及已核销收款已完成" : receiveFullPayment.value ? "套餐及全额收款已完成" : "套餐购买已提交");
await router.replace({
name: "SalesOrderDetail",
params: { id: result.salesOrderId },
@@ -947,15 +974,14 @@ watch(config, value => {
}
.item {
padding: 10px;
padding: 6px;
box-shadow: .25rem .25rem 1rem rgba(0, 0, 0, .08);
border-radius: 1rem;
.avatar {
width: 2rem;
height: 2rem;
flex: none;
border-radius: .5rem;
border-radius: .5rem !important;
}
&::after {
@@ -998,6 +1024,14 @@ watch(config, value => {
}
}
}
.payment-item.disabled {
color: var(--td-text-color-disabled);
:deep(.t-form__label) {
color: var(--td-text-color-disabled);
}
}
}
.time-actions {
+18 -6
View File
@@ -10,6 +10,8 @@ interface UsePackagePurchaseOptions {
config: Ref<GaoPackageConfig | undefined>;
selectedCustomerList: Ref<Customer[]>;
note: Ref<string>;
paymentVerified: Ref<boolean>;
paymentAmount: Ref<number | undefined>;
receiveFullPayment: Ref<boolean>;
fulfillAll: Ref<boolean>;
hasPermission: (permissionCode: string) => boolean;
@@ -95,7 +97,9 @@ export function usePackagePurchase(options: UsePackagePurchaseOptions) {
saleAmount,
purchasedAt: options.buildRegisteredAt(),
attachmentList: options.buildAttachments(),
straightThrough: options.receiveFullPayment.value || options.fulfillAll.value ? {
straightThrough: options.paymentVerified.value || options.receiveFullPayment.value || options.fulfillAll.value ? {
paymentVerified: options.paymentVerified.value,
paymentAmount: options.paymentAmount.value,
receiveFullPayment: options.receiveFullPayment.value,
paymentAttachmentList: options.buildPaymentAttachments(),
fulfillAll: options.fulfillAll.value,
@@ -155,20 +159,28 @@ export function usePackagePurchase(options: UsePackagePurchaseOptions) {
const canFulfillImmediately = options.hasPermission(permissionCodes.orderFulfillment.create)
&& options.hasPermission(permissionCodes.orderFulfillment.verify)
&& (saleAmount === 0 || canReceiveImmediately);
if (options.receiveFullPayment.value && !canReceiveImmediately) {
if ((options.paymentVerified.value || options.receiveFullPayment.value) && !canReceiveImmediately) {
Message.warning("当前账号没有收款登记和核销权限");
return false;
}
if (options.paymentVerified.value && (options.paymentAmount.value === undefined || options.paymentAmount.value <= 0 || options.paymentAmount.value > saleAmount)) {
Message.warning("已核销收款金额必须大于 0 且不能超过成交价");
return false;
}
if (options.fulfillAll.value && !canFulfillImmediately) {
Message.warning("当前账号没有交易直通所需权限");
return false;
}
if (options.fulfillAll.value && saleAmount !== 0 && !options.receiveFullPayment.value) {
Message.warning("全部履约直通必须同时直接全额收款");
if (options.fulfillAll.value && saleAmount !== 0 && !options.paymentVerified.value && !options.receiveFullPayment.value) {
Message.warning("全部履约直通必须同时完成收款核销");
return false;
}
if (options.receiveFullPayment.value && saleAmount !== 0 && !options.buildPaymentAttachments().length) {
Message.warning("直接全额收款必须上传收款凭证照片");
if (options.fulfillAll.value && options.paymentVerified.value && options.paymentAmount.value !== saleAmount) {
Message.warning("全部履约直通必须先完成全额收款核销");
return false;
}
if ((options.paymentVerified.value || options.receiveFullPayment.value) && saleAmount !== 0 && !options.buildPaymentAttachments().length) {
Message.warning("收款核销必须上传收款凭证照片");
return false;
}
if (options.fulfillAll.value && !options.buildFulfillmentAttachments().length) {