系统判断配送限制
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { BadRequestException, Injectable, Logger, NotFoundException, Inject, forwardRef } from '@nestjs/common';
|
||||
import type { CityWarehouse, FulfillmentProvider, Order } from '@prisma/client';
|
||||
import { isXfxProviderCode } from '@dukang/shared-types';
|
||||
import {
|
||||
BOTTLES_PER_BOX,
|
||||
XFX_AUTO_DISPATCH_MAX_BOXES,
|
||||
calcOrderBoxCount,
|
||||
shouldHoldAutoCourierDispatch,
|
||||
} from '@dukang/domain';
|
||||
import { PrismaService } from '../../common/prisma/prisma.module';
|
||||
import { CourierService } from '../../integrations/courier/courier.service';
|
||||
import { CourierPayMode } from '../../integrations/courier/courier.types';
|
||||
@@ -16,6 +22,8 @@ export type ManualShipInput = {
|
||||
|
||||
export type HqLogisticsShipInput = ManualShipInput;
|
||||
|
||||
export const FULFILLMENT_HOLD_LARGE_ORDER = 'LARGE_ORDER_GE_10_BOXES';
|
||||
|
||||
@Injectable()
|
||||
export class FulfillmentService {
|
||||
private readonly logger = new Logger(FulfillmentService.name);
|
||||
@@ -64,10 +72,48 @@ export class FulfillmentService {
|
||||
await this.ensureDeliveryRecord(orderId, 'MANUAL');
|
||||
return;
|
||||
}
|
||||
|
||||
// 大单拦截:≥10 箱不自动推小飞侠,待总部确认后推单或自配送
|
||||
if (shouldHoldAutoCourierDispatch(order.quantity)) {
|
||||
const boxes = calcOrderBoxCount(order.quantity);
|
||||
this.logger.warn(
|
||||
`大单拦截自动推单:${order.orderNo} quantity=${order.quantity} bottles≈${boxes}箱(阈值 ${XFX_AUTO_DISPATCH_MAX_BOXES}箱/${BOTTLES_PER_BOX}瓶)`,
|
||||
);
|
||||
await this.prisma.order.update({
|
||||
where: { id: orderId },
|
||||
data: {
|
||||
fulfillmentHold: true,
|
||||
fulfillmentHoldReason: FULFILLMENT_HOLD_LARGE_ORDER,
|
||||
},
|
||||
});
|
||||
await this.ensureDeliveryRecord(orderId, 'MANUAL', provider.id);
|
||||
await this.prisma.logThirdParty.create({
|
||||
data: {
|
||||
provider: 'XFX',
|
||||
scene: 'ORDER_DISPATCH_HOLD',
|
||||
refType: 'ORDER',
|
||||
refId: order.id,
|
||||
status: 'PENDING',
|
||||
errorMessage: `大单拦截:${order.quantity}瓶(约${boxes}箱),需总部确认后推小飞侠或自配送`.slice(
|
||||
0,
|
||||
512,
|
||||
),
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await this.dispatchApiAuto(order, warehouse, provider);
|
||||
}
|
||||
}
|
||||
|
||||
async clearFulfillmentHold(orderId: bigint) {
|
||||
await this.prisma.order.update({
|
||||
where: { id: orderId },
|
||||
data: { fulfillmentHold: false, fulfillmentHoldReason: null },
|
||||
});
|
||||
}
|
||||
|
||||
async dispatchApiAuto(order: Order, warehouse: CityWarehouse, provider: FulfillmentProvider) {
|
||||
if (!isXfxProviderCode(provider.code)) {
|
||||
this.logger.warn(`承运商 ${provider.code} 自动推单尚未实现,订单 ${order.orderNo} 保持待发货`);
|
||||
@@ -129,6 +175,10 @@ export class FulfillmentService {
|
||||
} else {
|
||||
await tx.orderDelivery.create({ data: { orderId: order.id, ...data } });
|
||||
}
|
||||
await tx.order.update({
|
||||
where: { id: order.id },
|
||||
data: { fulfillmentHold: false, fulfillmentHoldReason: null },
|
||||
});
|
||||
await tx.logThirdParty.create({
|
||||
data: {
|
||||
provider: 'XFX',
|
||||
@@ -260,6 +310,10 @@ export class FulfillmentService {
|
||||
} else {
|
||||
await tx.orderDelivery.create({ data: { orderId: order.id, ...data } });
|
||||
}
|
||||
await tx.order.update({
|
||||
where: { id: order.id },
|
||||
data: { fulfillmentHold: false, fulfillmentHoldReason: null },
|
||||
});
|
||||
});
|
||||
|
||||
await this.tradeService.applyStatusTransition(order.id, order.status, 'SHIPPING', input.operator);
|
||||
|
||||
Reference in New Issue
Block a user