fix(logistics): 修复shopyy订单发货逻辑并优化freightwaves集成
修复shopyy平台订单发货时fulfillment接口调用问题,调整请求数据结构 优化freightwaves服务集成,添加订单查询功能 移除冗余代码,清理注释
This commit is contained in:
parent
926e531d4f
commit
2f57dc0d8c
|
|
@ -152,7 +152,7 @@ export class FreightwavesService {
|
||||||
// 默认配置
|
// 默认配置
|
||||||
private config: FreightwavesConfig = {
|
private config: FreightwavesConfig = {
|
||||||
appSecret: 'gELCHguGmdTLo!zfihfM91hae8G@9Sz23Mh6pHrt',
|
appSecret: 'gELCHguGmdTLo!zfihfM91hae8G@9Sz23Mh6pHrt',
|
||||||
apiBaseUrl: 'http://tms.freightwaves.ca:8901/',
|
apiBaseUrl: 'http://tms.freightwaves.ca:8901',
|
||||||
partner: '25072621035200000060'
|
partner: '25072621035200000060'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -267,7 +267,7 @@ export class FreightwavesService {
|
||||||
partner: this.config.partner,
|
partner: this.config.partner,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await this.sendRequest<CreateOrderResponseData>('shipService/order/createOrder', requestData);
|
const response = await this.sendRequest<CreateOrderResponseData>('/shipService/order/createOrder', requestData);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import { StockPoint } from '../entity/stock_point.entity';
|
||||||
import { OrderService } from './order.service';
|
import { OrderService } from './order.service';
|
||||||
import { convertKeysFromCamelToSnake } from '../utils/object-transform.util';
|
import { convertKeysFromCamelToSnake } from '../utils/object-transform.util';
|
||||||
import { SiteService } from './site.service';
|
import { SiteService } from './site.service';
|
||||||
|
import { ShopyyService } from './shopyy.service';
|
||||||
|
|
||||||
@Provide()
|
@Provide()
|
||||||
export class LogisticsService {
|
export class LogisticsService {
|
||||||
|
|
@ -80,6 +81,9 @@ export class LogisticsService {
|
||||||
@Inject()
|
@Inject()
|
||||||
wpService: WPService;
|
wpService: WPService;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
shopyyService: ShopyyService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
orderService: OrderService;
|
orderService: OrderService;
|
||||||
|
|
||||||
|
|
@ -358,47 +362,9 @@ export class LogisticsService {
|
||||||
|
|
||||||
let resShipmentOrder;
|
let resShipmentOrder;
|
||||||
try {
|
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,
|
|
||||||
// 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',
|
|
||||||
// custom_field: {
|
|
||||||
// 'order_id': order.externalOrderId
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
resShipmentOrder = await this.mepShipment(data, order);
|
resShipmentOrder = await this.mepShipment(data, order);
|
||||||
|
|
||||||
// if (data.shipmentPlatform === 'uniuni') {
|
|
||||||
// // 添加运单
|
|
||||||
// resShipmentOrder = await this.uniExpressService.createShipment(reqBody);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (data.shipmentPlatform === 'freightwaves') {
|
|
||||||
// // 添加运单
|
|
||||||
// resShipmentOrder = await this.freightcomService.createShipment(reqBody);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 记录物流信息,并将订单状态转到完成
|
// 记录物流信息,并将订单状态转到完成
|
||||||
if (resShipmentOrder.status === 'SUCCESS' || resShipmentOrder.code === '00000200') {
|
if (resShipmentOrder.status === 'SUCCESS' || resShipmentOrder.code === '00000200') {
|
||||||
order.orderStatus = ErpOrderStatus.COMPLETED;
|
order.orderStatus = ErpOrderStatus.COMPLETED;
|
||||||
|
|
@ -427,28 +393,28 @@ export class LogisticsService {
|
||||||
unique_id = resShipmentOrder.data?.shipOrderId;
|
unique_id = resShipmentOrder.data?.shipOrderId;
|
||||||
state = ErpOrderStatus.COMPLETED;
|
state = ErpOrderStatus.COMPLETED;
|
||||||
}
|
}
|
||||||
const res = await this.wpService.createFulfillment(site, order.externalOrderId, {
|
|
||||||
tracking_number: co,
|
|
||||||
tracking_provider: tracking_provider,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (order.orderStatus === ErpOrderStatus.COMPLETED) {
|
|
||||||
const shipment = await shipmentRepo.save({
|
|
||||||
tracking_provider: tracking_provider,
|
|
||||||
tracking_id: res.data.tracking_id,
|
|
||||||
unique_id: unique_id,
|
|
||||||
stockPointId: String(data.stockPointId), // todo
|
|
||||||
state: state,
|
|
||||||
return_tracking_number: co,
|
|
||||||
fee: data.details.shipmentFee,
|
|
||||||
order: order
|
|
||||||
});
|
|
||||||
order.shipmentId = shipment.id;
|
|
||||||
shipmentId = shipment.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同步订单状态到woocommerce
|
// 同步订单状态到woocommerce
|
||||||
if (order.source_type != "shopyy") {
|
if (order.source_type != "shopyy") {
|
||||||
|
const res = await this.wpService.createFulfillment(site, order.externalOrderId, {
|
||||||
|
tracking_number: co,
|
||||||
|
tracking_provider: tracking_provider,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (order.orderStatus === ErpOrderStatus.COMPLETED) {
|
||||||
|
const shipment = await shipmentRepo.save({
|
||||||
|
tracking_provider: tracking_provider,
|
||||||
|
tracking_id: res.data.tracking_id,
|
||||||
|
unique_id: unique_id,
|
||||||
|
stockPointId: String(data.stockPointId), // todo
|
||||||
|
state: state,
|
||||||
|
return_tracking_number: co,
|
||||||
|
fee: data.details.shipmentFee,
|
||||||
|
order: order
|
||||||
|
});
|
||||||
|
order.shipmentId = shipment.id;
|
||||||
|
shipmentId = shipment.id;
|
||||||
|
}
|
||||||
if (order.status !== OrderStatus.COMPLETED) {
|
if (order.status !== OrderStatus.COMPLETED) {
|
||||||
await this.wpService.updateOrder(site, order.externalOrderId, {
|
await this.wpService.updateOrder(site, order.externalOrderId, {
|
||||||
status: OrderStatus.COMPLETED,
|
status: OrderStatus.COMPLETED,
|
||||||
|
|
@ -456,6 +422,33 @@ export class LogisticsService {
|
||||||
order.status = OrderStatus.COMPLETED;
|
order.status = OrderStatus.COMPLETED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (order.source_type === "shopyy") {
|
||||||
|
const res = await this.shopyyService.createFulfillment(site, order.externalOrderId, {
|
||||||
|
tracking_number: co,
|
||||||
|
tracking_company: resShipmentOrder.shipCompany,
|
||||||
|
carrier_code: resShipmentOrder.shipperOrderId,
|
||||||
|
});
|
||||||
|
if (order.orderStatus === ErpOrderStatus.COMPLETED) {
|
||||||
|
const shipment = await shipmentRepo.save({
|
||||||
|
tracking_provider: tracking_provider,
|
||||||
|
tracking_id: res.data.tracking_id,
|
||||||
|
unique_id: unique_id,
|
||||||
|
stockPointId: String(data.stockPointId), // todo
|
||||||
|
state: state,
|
||||||
|
return_tracking_number: co,
|
||||||
|
fee: data.details.shipmentFee,
|
||||||
|
order: order
|
||||||
|
});
|
||||||
|
order.shipmentId = shipment.id;
|
||||||
|
shipmentId = shipment.id;
|
||||||
|
}
|
||||||
|
if (order.status !== OrderStatus.COMPLETED) {
|
||||||
|
// await this.shopyyService.updateOrder(site, order.externalOrderId, {
|
||||||
|
// status: OrderStatus.COMPLETED,
|
||||||
|
// });
|
||||||
|
order.status = OrderStatus.COMPLETED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
order.orderStatus = ErpOrderStatus.COMPLETED;
|
order.orderStatus = ErpOrderStatus.COMPLETED;
|
||||||
|
|
||||||
|
|
@ -796,7 +789,7 @@ export class LogisticsService {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
signService: 0
|
signService: 0
|
||||||
// signService: 0, // 签名服务 0不使用, 1使用
|
// 非跨境订单不需要declaration
|
||||||
// declaration: {
|
// declaration: {
|
||||||
// "boxNo": "", //箱子编号
|
// "boxNo": "", //箱子编号
|
||||||
// "sku": "", //SKU
|
// "sku": "", //SKU
|
||||||
|
|
@ -812,10 +805,11 @@ export class LogisticsService {
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
// 调用freightwaves费用试算或创建订单API
|
|
||||||
// 注意:根据实际需要调用对应的方法
|
|
||||||
// resShipmentOrder = await this.freightwavesService.rateTry(reqBody); // 费用试算
|
|
||||||
resShipmentOrder = await this.freightwavesService.createOrder(reqBody); // 创建订单
|
resShipmentOrder = await this.freightwavesService.createOrder(reqBody); // 创建订单
|
||||||
|
const queryRes = await this.freightwavesService.queryOrder({ shipOrderId: resShipmentOrder.shipOrderId }); // 查询订单
|
||||||
|
console.log('queryRes:', queryRes); // 打印查询结果
|
||||||
|
resShipmentOrder.push(queryRes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resShipmentOrder;
|
return resShipmentOrder;
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ import { Site } from '../entity/site.entity';
|
||||||
import { UnifiedReviewDTO } from '../dto/site-api.dto';
|
import { UnifiedReviewDTO } from '../dto/site-api.dto';
|
||||||
import { ShopyyGetOneOrderResult, ShopyyReview } from '../dto/shopyy.dto';
|
import { ShopyyGetOneOrderResult, ShopyyReview } from '../dto/shopyy.dto';
|
||||||
import { BatchOperationDTO, BatchOperationResultDTO } from '../dto/batch.dto';
|
import { BatchOperationDTO, BatchOperationResultDTO } from '../dto/batch.dto';
|
||||||
import { UnifiedSearchParamsDTO,ShopyyGetAllOrdersParams } from '../dto/api.dto';
|
import { UnifiedSearchParamsDTO, ShopyyGetAllOrdersParams } from '../dto/api.dto';
|
||||||
/**
|
/**
|
||||||
* ShopYY平台服务实现
|
* ShopYY平台服务实现
|
||||||
*/
|
*/
|
||||||
@Provide()
|
@Provide()
|
||||||
export class ShopyyService {
|
export class ShopyyService {
|
||||||
@Inject()
|
@Inject()
|
||||||
logger:ILogger;
|
logger: ILogger;
|
||||||
/**
|
/**
|
||||||
* 获取ShopYY评论列表
|
* 获取ShopYY评论列表
|
||||||
* @param site 站点配置
|
* @param site 站点配置
|
||||||
|
|
@ -184,9 +184,9 @@ export class ShopyyService {
|
||||||
*/
|
*/
|
||||||
public async fetchResourcePaged<T>(site: any, endpoint: string, params: Record<string, any> = {}) {
|
public async fetchResourcePaged<T>(site: any, endpoint: string, params: Record<string, any> = {}) {
|
||||||
const response = await this.request(site, endpoint, 'GET', null, params);
|
const response = await this.request(site, endpoint, 'GET', null, params);
|
||||||
return this.mapPageResponse<T>(response,params);
|
return this.mapPageResponse<T>(response, params);
|
||||||
}
|
}
|
||||||
mapPageResponse<T>(response:any,query: Record<string, any>){
|
mapPageResponse<T>(response: any, query: Record<string, any>) {
|
||||||
if (response?.code !== 0) {
|
if (response?.code !== 0) {
|
||||||
throw new Error(response?.msg)
|
throw new Error(response?.msg)
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +272,7 @@ export class ShopyyService {
|
||||||
const response = await this.request(site, `products/${productId}/variations/${variationId}`, 'GET');
|
const response = await this.request(site, `products/${productId}/variations/${variationId}`, 'GET');
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
mapOrderSearchParams(params: UnifiedSearchParamsDTO){
|
mapOrderSearchParams(params: UnifiedSearchParamsDTO) {
|
||||||
const { after, before, ...restParams } = params;
|
const { after, before, ...restParams } = params;
|
||||||
return {
|
return {
|
||||||
...restParams,
|
...restParams,
|
||||||
|
|
@ -311,7 +311,7 @@ export class ShopyyService {
|
||||||
async getAllOrders(site: any | number, params: ShopyyGetAllOrdersParams = {}, maxPages: number = 10, concurrencyLimit: number = 100): Promise<any> {
|
async getAllOrders(site: any | number, params: ShopyyGetAllOrdersParams = {}, maxPages: number = 10, concurrencyLimit: number = 100): Promise<any> {
|
||||||
const firstPage = await this.getOrders(site, 1, 100, params);
|
const firstPage = await this.getOrders(site, 1, 100, params);
|
||||||
|
|
||||||
const { items: firstPageItems, totalPages} = firstPage;
|
const { items: firstPageItems, totalPages } = firstPage;
|
||||||
|
|
||||||
// 如果只有一页数据,直接返回
|
// 如果只有一页数据,直接返回
|
||||||
if (totalPages <= 1) {
|
if (totalPages <= 1) {
|
||||||
|
|
@ -475,13 +475,16 @@ export class ShopyyService {
|
||||||
async createFulfillment(site: Site, orderId: string, data: any): Promise<any> {
|
async createFulfillment(site: Site, orderId: string, data: any): Promise<any> {
|
||||||
// ShopYY API: POST /orders/{id}/shipments
|
// ShopYY API: POST /orders/{id}/shipments
|
||||||
const fulfillmentData = {
|
const fulfillmentData = {
|
||||||
tracking_number: data.tracking_number,
|
data: [{
|
||||||
carrier_code: data.carrier_code,
|
order_number: orderId,
|
||||||
carrier_name: data.carrier_name,
|
tracking_company: data.tracking_company,
|
||||||
shipping_method: data.shipping_method
|
tracking_number: data.tracking_number,
|
||||||
|
carrier_code: data.carrier_code,
|
||||||
|
note: "note",
|
||||||
|
mode: ""
|
||||||
|
}]
|
||||||
};
|
};
|
||||||
|
const response = await this.request(site, `orders/fulfillments`, 'POST', fulfillmentData);
|
||||||
const response = await this.request(site, `orders/${orderId}/fulfillments`, 'POST', fulfillmentData);
|
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -494,7 +497,7 @@ export class ShopyyService {
|
||||||
*/
|
*/
|
||||||
async deleteFulfillment(site: any, orderId: string, fulfillmentId: string): Promise<boolean> {
|
async deleteFulfillment(site: any, orderId: string, fulfillmentId: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
// ShopYY API: DELETE /orders/{order_id}/shipments/{fulfillment_id}
|
// ShopYY API: DELETE /orders/fulfillments/{fulfillment_id}
|
||||||
await this.request(site, `orders/${orderId}/fulfillments/${fulfillmentId}`, 'DELETE');
|
await this.request(site, `orders/${orderId}/fulfillments/${fulfillmentId}`, 'DELETE');
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -647,7 +650,7 @@ export class ShopyyService {
|
||||||
const result = response.data;
|
const result = response.data;
|
||||||
|
|
||||||
// 转换 ShopYY 批量操作结果为统一格式
|
// 转换 ShopYY 批量操作结果为统一格式
|
||||||
const errors: Array<{identifier: string, error: string}> = [];
|
const errors: Array<{ identifier: string, error: string }> = [];
|
||||||
|
|
||||||
// 假设 ShopYY 返回格式与 WooCommerce 类似: { create: [...], update: [...], delete: [...] }
|
// 假设 ShopYY 返回格式与 WooCommerce 类似: { create: [...], update: [...], delete: [...] }
|
||||||
// 错误信息可能在每个项目的 error 字段中
|
// 错误信息可能在每个项目的 error 字段中
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue