Fix: #3
|
|
@ -162,6 +162,21 @@ export class LogisticsController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOkResponse(
|
||||||
|
{type: BooleanRes}
|
||||||
|
)
|
||||||
|
@Post('/getShipmentFee')
|
||||||
|
async getShipmentFee(
|
||||||
|
@Body() data: ShipmentBookDTO
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const fee = await this.logisticsService.getShipmentFee(data);
|
||||||
|
return successResponse(fee);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || '创建失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOkResponse(
|
@ApiOkResponse(
|
||||||
{type: BooleanRes}
|
{type: BooleanRes}
|
||||||
)
|
)
|
||||||
|
|
@ -182,7 +197,6 @@ export class LogisticsController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ApiOkResponse()
|
@ApiOkResponse()
|
||||||
@Post('/getPaymentMethods')
|
@Post('/getPaymentMethods')
|
||||||
async getpaymentmethods() {
|
async getpaymentmethods() {
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,9 @@ export class PackagingEnvelope {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export class ShippingDetailsDTO {
|
export class ShippingDetailsDTO {
|
||||||
|
@ApiProperty()
|
||||||
|
shipmentFee: number;
|
||||||
|
|
||||||
@ApiProperty({ type: Location })
|
@ApiProperty({ type: Location })
|
||||||
@Rule(RuleType.object<Location>())
|
@Rule(RuleType.object<Location>())
|
||||||
origin: Location;
|
origin: Location;
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,6 @@ export class Shipment {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@Column({ name: 'order_id', nullable: true })
|
|
||||||
@Expose()
|
|
||||||
orderId: string;
|
|
||||||
|
|
||||||
@OneToOne(() => Order)
|
@OneToOne(() => Order)
|
||||||
@JoinColumn({ name: 'order_id' })
|
@JoinColumn({ name: 'order_id' })
|
||||||
order: Order;
|
order: Order;
|
||||||
|
|
@ -39,6 +35,10 @@ export class Shipment {
|
||||||
@JoinColumn({ name: 'stock_point_id' })
|
@JoinColumn({ name: 'stock_point_id' })
|
||||||
stockPoint: StockPoint;
|
stockPoint: StockPoint;
|
||||||
|
|
||||||
|
@Column({ nullable: false, default: 0})
|
||||||
|
@Expose()
|
||||||
|
fee: number;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
@Expose()
|
@Expose()
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,40 @@ export class LogisticsService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getShipmentFee(data: ShipmentBookDTO) {
|
||||||
|
try {
|
||||||
|
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId});
|
||||||
|
const reqBody = {
|
||||||
|
sender: data.details.origin.contact_name,
|
||||||
|
start_phone: data.details.origin.phone_number,
|
||||||
|
start_postal_code: data.details.origin.address.postal_code.replace(/\s/g, ''),
|
||||||
|
pickup_address: data.details.origin.address.address_line_1,
|
||||||
|
pickup_warehouse: stock_point.upStreamStockPointId,
|
||||||
|
shipper_country_code: data.details.origin.address.country,
|
||||||
|
receiver: data.details.destination.contact_name,
|
||||||
|
city: data.details.destination.address.city,
|
||||||
|
province: data.details.destination.address.region, // todo,待确认
|
||||||
|
country: data.details.destination.address.country,
|
||||||
|
postal_code: data.details.destination.address.postal_code.replace(/\s/g, ''),
|
||||||
|
delivery_address: data.details.destination.address.address_line_1,
|
||||||
|
receiver_phone: data.details.destination.phone_number.number,
|
||||||
|
receiver_email: data.details.destination.email_addresses,
|
||||||
|
// item_description: data.sales, // todo: 货品信息
|
||||||
|
length: data.details.packaging_properties.packages[0].measurements.cuboid.l,
|
||||||
|
width: data.details.packaging_properties.packages[0].measurements.cuboid.w,
|
||||||
|
height: data.details.packaging_properties.packages[0].measurements.cuboid.h,
|
||||||
|
dimension_uom: data.details.packaging_properties.packages[0].measurements.cuboid.unit,
|
||||||
|
weight: data.details.packaging_properties.packages[0].measurements.weight.value,
|
||||||
|
weight_uom: data.details.packaging_properties.packages[0].measurements.weight.unit,
|
||||||
|
currency: 'CAD',
|
||||||
|
}
|
||||||
|
const resShipmentFee = await this.uniExpressService.getRates(reqBody);
|
||||||
|
return resShipmentFee.data.totalAfterTax * 100;
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async createShipment(orderId: number, data: ShipmentBookDTO, userId: number) {
|
async createShipment(orderId: number, data: ShipmentBookDTO, userId: number) {
|
||||||
const order = await this.orderModel.findOneBy({ id: orderId });
|
const order = await this.orderModel.findOneBy({ id: orderId });
|
||||||
if (!order) {
|
if (!order) {
|
||||||
|
|
@ -215,6 +249,8 @@ export class LogisticsService {
|
||||||
) {
|
) {
|
||||||
throw new Error('订单状态不正确 ');
|
throw new Error('订单状态不正确 ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let resShipmentOrder;
|
||||||
try {
|
try {
|
||||||
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId});
|
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId});
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
|
|
@ -238,28 +274,24 @@ export class LogisticsService {
|
||||||
height: data.details.packaging_properties.packages[0].measurements.cuboid.h,
|
height: data.details.packaging_properties.packages[0].measurements.cuboid.h,
|
||||||
dimension_uom: data.details.packaging_properties.packages[0].measurements.cuboid.unit,
|
dimension_uom: data.details.packaging_properties.packages[0].measurements.cuboid.unit,
|
||||||
weight: data.details.packaging_properties.packages[0].measurements.weight.value,
|
weight: data.details.packaging_properties.packages[0].measurements.weight.value,
|
||||||
weight_uom: `${data.details.packaging_properties.packages[0].measurements.weight.unit}S`, // todo,换成KGS和LBS
|
weight_uom: data.details.packaging_properties.packages[0].measurements.weight.unit,
|
||||||
currency: 'CAD',
|
currency: 'CAD',
|
||||||
}
|
}
|
||||||
console.log('body', reqBody);
|
|
||||||
|
|
||||||
throw new Error('test ');
|
|
||||||
|
|
||||||
// todo: 两个请求做异步 参考promise.all()方法
|
|
||||||
// 获取预估费率
|
|
||||||
const resShipmentFee = await this.uniExpressService.getRates(reqBody);
|
|
||||||
// 添加运单
|
// 添加运单
|
||||||
const resShipmentOrder = await this.uniExpressService.createShipment(reqBody);
|
resShipmentOrder = await this.uniExpressService.createShipment(reqBody);
|
||||||
|
|
||||||
// 记录物流信息,并将订单状态转到完成
|
// 记录物流信息,并将订单状态转到完成
|
||||||
if (resShipmentOrder.status === 'SUCCESS') {
|
if (resShipmentOrder.status === 'SUCCESS') {
|
||||||
order.orderStatus = ErpOrderStatus.COMPLETED;
|
order.orderStatus = ErpOrderStatus.COMPLETED;
|
||||||
|
} else {
|
||||||
|
throw new Error('运单生成失败');
|
||||||
}
|
}
|
||||||
const dataSource = this.dataSourceManager.getDataSource('default');
|
const dataSource = this.dataSourceManager.getDataSource('default');
|
||||||
dataSource.transaction(async manager => {
|
let transactionError = undefined;
|
||||||
|
await dataSource.transaction(async manager => {
|
||||||
const orderRepo = manager.getRepository(Order);
|
const orderRepo = manager.getRepository(Order);
|
||||||
const shipmentRepo = manager.getRepository(Shipment);
|
const shipmentRepo = manager.getRepository(Shipment);
|
||||||
|
|
||||||
if (order.orderStatus === ErpOrderStatus.COMPLETED) {
|
if (order.orderStatus === ErpOrderStatus.COMPLETED) {
|
||||||
const shipment = await shipmentRepo.save({
|
const shipment = await shipmentRepo.save({
|
||||||
tracking_provider: 'uniuni-express', // todo: id未确定,后写进常数
|
tracking_provider: 'uniuni-express', // todo: id未确定,后写进常数
|
||||||
|
|
@ -267,90 +299,38 @@ export class LogisticsService {
|
||||||
stockPointId: '1', // todo
|
stockPointId: '1', // todo
|
||||||
state: resShipmentOrder.data.uni_status_code,
|
state: resShipmentOrder.data.uni_status_code,
|
||||||
return_tracking_number: resShipmentOrder.data.tno,
|
return_tracking_number: resShipmentOrder.data.tno,
|
||||||
order_id: order.id
|
fee: data.details.shipmentFee,
|
||||||
|
order_id: orderId
|
||||||
});
|
});
|
||||||
order.shipmentId = shipment.id;
|
order.shipmentId = shipment.id;
|
||||||
|
|
||||||
// 同步物流信息到woocommerce
|
// 同步物流信息到woocommerce
|
||||||
const site = this.geSite(order.siteId);
|
const site = await this.geSite(order.siteId);
|
||||||
await this.wpService.createShipment(site, order.externalOrderId, {
|
await this.wpService.createShipment(site, order.externalOrderId, {
|
||||||
tracking_number: shipment.primary_tracking_number,
|
tracking_number: shipment.return_tracking_number,
|
||||||
tracking_provider: shipment?.rate?.carrier_name,
|
tracking_provider: shipment?.tracking_provider,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await orderRepo.save(order);
|
await orderRepo.save(order);
|
||||||
|
|
||||||
|
}).catch(error => {
|
||||||
|
transactionError = error
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (transactionError !== undefined) {
|
||||||
|
console.log('err', transactionError);
|
||||||
|
throw transactionError;
|
||||||
|
}
|
||||||
|
|
||||||
return { data: {
|
return { data: {
|
||||||
resShipmentFee,
|
|
||||||
resShipmentOrder
|
resShipmentOrder
|
||||||
} };
|
} };
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
throw new Error(`上游请求错误:${error}`);
|
if (resShipmentOrder.status === 'SUCCESS') {
|
||||||
|
await this.uniExpressService.deleteShipment(resShipmentOrder.data.tno);
|
||||||
|
}
|
||||||
|
throw new Error(`上游请求错误:${error}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// const dataSource = this.dataSourceManager.getDataSource('default');
|
|
||||||
// return dataSource.transaction(async manager => {
|
|
||||||
// const productRepo = manager.getRepository(Product);
|
|
||||||
// const shipmentRepo = manager.getRepository(Shipment);
|
|
||||||
// const shipmentItemRepo = manager.getRepository(ShipmentItem);
|
|
||||||
// const orderShipmentRepo = manager.getRepository(OrderShipment);
|
|
||||||
// const stockRecordRepo = manager.getRepository(StockRecord);
|
|
||||||
// const stockRepo = manager.getRepository(Stock);
|
|
||||||
// const orderRepo = manager.getRepository(Order);
|
|
||||||
|
|
||||||
// await shipmentRepo.save(shipment);
|
|
||||||
// await this.getShipment(shipment.id);
|
|
||||||
// const shipmentItems = [];
|
|
||||||
// for (const item of data?.sales) {
|
|
||||||
// const product = await productRepo.findOne({ where: { sku: item.sku } });
|
|
||||||
// shipmentItems.push({
|
|
||||||
// shipment_id: shipment.id,
|
|
||||||
// productId: product.id,
|
|
||||||
// name: product.name,
|
|
||||||
// sku: item.sku,
|
|
||||||
// quantity: item.quantity,
|
|
||||||
// });
|
|
||||||
// const stock = await stockRepo.findOne({
|
|
||||||
// where: {
|
|
||||||
// stockPointId: data.stockPointId,
|
|
||||||
// productSku: item.sku,
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// stock.quantity -= item.quantity;
|
|
||||||
// await stockRepo.save(stock);
|
|
||||||
// await stockRecordRepo.save({
|
|
||||||
// stockPointId: data.stockPointId,
|
|
||||||
// productSku: item.sku,
|
|
||||||
// operationType: StockRecordOperationType.OUT,
|
|
||||||
// quantityChange: item.quantity,
|
|
||||||
// operatorId: userId,
|
|
||||||
// note: `订单${[orderId, ...data.orderIds].join(',')} 发货`,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// await shipmentItemRepo.save(shipmentItems);
|
|
||||||
// await orderShipmentRepo.save({
|
|
||||||
// order_id: orderId,
|
|
||||||
// shipment_id: shipment.id,
|
|
||||||
// stockPointId: data.stockPointId,
|
|
||||||
// });
|
|
||||||
// for (const orderId of data?.orderIds) {
|
|
||||||
// await orderShipmentRepo.save({
|
|
||||||
// order_id: orderId,
|
|
||||||
// shipment_id: shipment.id,
|
|
||||||
// stockPointId: data.stockPointId,
|
|
||||||
// });
|
|
||||||
// const order = await orderRepo.findOneBy({ id: orderId });
|
|
||||||
// order.orderStatus = ErpOrderStatus.COMPLETED;
|
|
||||||
// order.status = OrderStatus.COMPLETED;
|
|
||||||
// await orderRepo.save(order);
|
|
||||||
// }
|
|
||||||
// order.orderStatus = ErpOrderStatus.COMPLETED;
|
|
||||||
// order.status = OrderStatus.COMPLETED;
|
|
||||||
// await orderRepo.save(order);
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async syncShipment() {
|
async syncShipment() {
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,22 @@ export class UniExpressService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteShipment(tno: string) {
|
||||||
|
const body = {
|
||||||
|
tno
|
||||||
|
};
|
||||||
|
const token = await this.getToken();
|
||||||
|
const config: AxiosRequestConfig= {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
url: `${this.url}/orders/cancelorder`,
|
||||||
|
data: body
|
||||||
|
};
|
||||||
|
return await axios.request(config);
|
||||||
|
}
|
||||||
|
|
||||||
async getLabel(tracking_number: string) {
|
async getLabel(tracking_number: string) {
|
||||||
const body = {
|
const body = {
|
||||||
packageId: tracking_number
|
packageId: tracking_number
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue