Feature: 增加换货功能
This commit is contained in:
parent
9c54d60d91
commit
64d01d2870
|
|
@ -16,6 +16,7 @@ import { OrderFee } from '../entity/order_fee.entity';
|
|||
import { OrderRefund } from '../entity/order_refund.entity';
|
||||
import { OrderRefundItem } from '../entity/order_retund_item.entity';
|
||||
import { OrderSale } from '../entity/order_sale.entity';
|
||||
import { OrderSaleOriginal } from '../entity/order_item_original.entity';
|
||||
import { OrderShipping } from '../entity/order_shipping.entity';
|
||||
import { Service } from '../entity/service.entity';
|
||||
import { ShippingAddress } from '../entity/shipping_address.entity';
|
||||
|
|
@ -57,6 +58,7 @@ export default {
|
|||
OrderRefund,
|
||||
OrderRefundItem,
|
||||
OrderSale,
|
||||
OrderSaleOriginal,
|
||||
OrderShipment,
|
||||
ShipmentItem,
|
||||
Shipment,
|
||||
|
|
|
|||
|
|
@ -108,6 +108,22 @@ export class OrderController {
|
|||
}
|
||||
}
|
||||
|
||||
@ApiOkResponse({
|
||||
type: BooleanRes,
|
||||
})
|
||||
@Post('/updateOrderItems/:orderId')
|
||||
async updateOrderItems(
|
||||
@Param('orderId') orderId: number,
|
||||
@Body() data: any
|
||||
) {
|
||||
try {
|
||||
const res = await this.orderService.updateOrderSales(orderId, data);
|
||||
return successResponse(res);
|
||||
} catch (error) {
|
||||
return errorResponse(error?.message || '更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOkResponse({
|
||||
type: BooleanRes,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
import { ApiProperty } from '@midwayjs/swagger';
|
||||
import { Exclude, Expose } from 'class-transformer';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { Order } from './order.entity';
|
||||
|
||||
@Entity('order_sale_original')
|
||||
@Exclude()
|
||||
export class OrderSaleOriginal {
|
||||
@ApiProperty()
|
||||
@PrimaryGeneratedColumn()
|
||||
@Expose()
|
||||
id?: number;
|
||||
|
||||
@ApiProperty()
|
||||
@ManyToOne(() => Order)
|
||||
@JoinColumn({ name: 'order_id' })
|
||||
@Expose()
|
||||
orderId: number; // 订单 ID
|
||||
|
||||
@ApiProperty()
|
||||
@Column()
|
||||
@Expose()
|
||||
siteId: string; // 来源站点唯一标识
|
||||
|
||||
@ApiProperty()
|
||||
@Column()
|
||||
@Expose()
|
||||
externalOrderItemId: string; // WooCommerce 订单item ID
|
||||
|
||||
@ApiProperty()
|
||||
@Column()
|
||||
@Expose()
|
||||
productId: number;
|
||||
|
||||
@ApiProperty()
|
||||
@Column()
|
||||
@Expose()
|
||||
name: string;
|
||||
|
||||
@ApiProperty({ description: 'sku', type: 'string' })
|
||||
@Expose()
|
||||
@Column()
|
||||
sku: string;
|
||||
|
||||
@ApiProperty()
|
||||
@Column()
|
||||
@Expose()
|
||||
quantity: number;
|
||||
|
||||
@ApiProperty()
|
||||
@Column({ default: false })
|
||||
@Expose()
|
||||
isPackage: boolean;
|
||||
|
||||
@ApiProperty({
|
||||
example: '2022-12-12 11:11:11',
|
||||
description: '创建时间',
|
||||
})
|
||||
@CreateDateColumn()
|
||||
@Expose()
|
||||
createdAt?: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '2022-12-12 11:11:11',
|
||||
description: '更新时间',
|
||||
})
|
||||
@UpdateDateColumn()
|
||||
@Expose()
|
||||
updatedAt?: Date;
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ export class OrderSale {
|
|||
siteId: string; // 来源站点唯一标识
|
||||
|
||||
@ApiProperty()
|
||||
@Column()
|
||||
@Column({ nullable: true })
|
||||
@Expose()
|
||||
externalOrderItemId: string; // WooCommerce 订单item ID
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { OrderItem } from '../entity/order_item.entity';
|
|||
import { OrderSale } from '../entity/order_sale.entity';
|
||||
import { UniExpressService } from './uni_express.service';
|
||||
import { StockPoint } from '../entity/stock_point.entity';
|
||||
import { OrderService } from './order.service';
|
||||
|
||||
@Provide()
|
||||
export class LogisticsService {
|
||||
|
|
@ -74,6 +75,9 @@ export class LogisticsService {
|
|||
@Inject()
|
||||
wpService: WPService;
|
||||
|
||||
@Inject()
|
||||
orderService: OrderService;
|
||||
|
||||
@Inject()
|
||||
dataSourceManager: TypeORMDataSourceManager;
|
||||
|
||||
|
|
@ -124,7 +128,6 @@ export class LogisticsService {
|
|||
async updateShipmentState(shipment: Shipment) {
|
||||
try {
|
||||
const data = await this.uniExpressService.getOrderStatus(shipment.return_tracking_number);
|
||||
// console.log('res', data, data.data[0].state);
|
||||
shipment.state = data.data[0].state;
|
||||
if (shipment.state in [203, 215, 216, 230]) { // todo,写常数
|
||||
shipment.finished = true;
|
||||
|
|
@ -240,7 +243,6 @@ export class LogisticsService {
|
|||
order.shipmentId = null;
|
||||
orderRepo.save(order);
|
||||
|
||||
await manager.delete('shipment_item', { shipment_id: shipmentId });
|
||||
shipmentRepo.remove(shipment);
|
||||
|
||||
const res = await this.uniExpressService.deleteShipment(shipment.return_tracking_number);
|
||||
|
|
@ -293,7 +295,7 @@ export class LogisticsService {
|
|||
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,待确认
|
||||
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,
|
||||
|
|
@ -317,6 +319,7 @@ export class LogisticsService {
|
|||
|
||||
async createShipment(orderId: number, data: ShipmentBookDTO, userId: number) {
|
||||
const order = await this.orderModel.findOneBy({ id: orderId });
|
||||
const { sales } = data;
|
||||
if (!order) {
|
||||
throw new Error('订单不存在');
|
||||
}
|
||||
|
|
@ -339,7 +342,7 @@ export class LogisticsService {
|
|||
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,待确认
|
||||
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,
|
||||
|
|
@ -373,7 +376,6 @@ export class LogisticsService {
|
|||
await dataSource.transaction(async manager => {
|
||||
const orderRepo = manager.getRepository(Order);
|
||||
const shipmentRepo = manager.getRepository(Shipment);
|
||||
const shipmentItemRepo = manager.getRepository(ShipmentItem);
|
||||
const tracking_provider = 'UniUni'; // todo: id未确定,后写进常数
|
||||
|
||||
// 同步物流信息到woocommerce
|
||||
|
|
@ -396,17 +398,6 @@ export class LogisticsService {
|
|||
});
|
||||
order.shipmentId = shipment.id;
|
||||
shipmentId = shipment.id;
|
||||
|
||||
// onchange shipment
|
||||
await data.sales.forEach(async (item) => {
|
||||
console.log('item', item)
|
||||
const shipmentItem: ShipmentItem = new ShipmentItem;
|
||||
shipmentItem.sku = item.sku;
|
||||
shipmentItem.quantity = item.quantity;
|
||||
shipmentItem.shipment_id = shipmentId;
|
||||
shipmentItem.order_id = orderId;
|
||||
await shipmentItemRepo.save(shipmentItem);
|
||||
});
|
||||
}
|
||||
|
||||
// 同步订单状态到woocommerce
|
||||
|
|
@ -428,6 +419,9 @@ export class LogisticsService {
|
|||
throw transactionError;
|
||||
}
|
||||
|
||||
// 更新产品发货信息
|
||||
this.orderService.updateOrderSales(order.id, sales);
|
||||
|
||||
return { data: {
|
||||
shipmentId
|
||||
} };
|
||||
|
|
@ -439,11 +433,6 @@ export class LogisticsService {
|
|||
}
|
||||
}
|
||||
|
||||
async updateShipmentItem(shipmentId: number, sales: OrderSale[]) {
|
||||
const shipment:Shipment = await this.shipmentModel.findOneBy({ id: shipmentId });
|
||||
console.log(shipment);
|
||||
}
|
||||
|
||||
async syncShipment() {
|
||||
try {
|
||||
const shipments = await this.shipmentModel.find({
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { WpSite } from '../interface';
|
|||
import { ShipmentItem } from '../entity/shipment_item.entity';
|
||||
import { UpdateStockDTO } from '../dto/stock.dto';
|
||||
import { StockService } from './stock.service';
|
||||
import { OrderSaleOriginal } from '../entity/order_item_original.entity';
|
||||
|
||||
@Provide()
|
||||
export class OrderService {
|
||||
|
|
@ -50,6 +51,9 @@ export class OrderService {
|
|||
@InjectEntityModel(OrderSale)
|
||||
orderSaleModel: Repository<OrderSale>;
|
||||
|
||||
@InjectEntityModel(OrderSaleOriginal)
|
||||
orderSaleOriginalModel: Repository<OrderSaleOriginal>;
|
||||
|
||||
@InjectEntityModel(WpProduct)
|
||||
wpProductModel: Repository<WpProduct>;
|
||||
|
||||
|
|
@ -214,12 +218,10 @@ export class OrderService {
|
|||
entity.id = existingOrder.id;
|
||||
return entity;
|
||||
}
|
||||
console.log('/////////////');
|
||||
entity.orderStatus = this.mapOrderStatus(entity.status);
|
||||
const customer = await this.customerModel.findOne({
|
||||
where: { email: order.customer_email },
|
||||
});
|
||||
console.log('error? ', this.customerModel);
|
||||
if(!customer) {
|
||||
await this.customerModel.save({
|
||||
email: order.customer_email,
|
||||
|
|
@ -1182,6 +1184,21 @@ export class OrderService {
|
|||
}
|
||||
}
|
||||
|
||||
// update order_sale_origin if not exist
|
||||
|
||||
try {
|
||||
const order_sale_origin_count = await this.orderSaleOriginalModel.countBy({ orderId: id });
|
||||
if (order_sale_origin_count === 0) {
|
||||
sales.forEach(async sale => {
|
||||
const { id: saleId, ...saleData } = sale;
|
||||
await this.orderSaleOriginalModel.save(saleData);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log('create order sale origin error: ', error.message);
|
||||
}
|
||||
|
||||
return {
|
||||
...order,
|
||||
siteName: site.siteName,
|
||||
|
|
@ -1297,6 +1314,7 @@ export class OrderService {
|
|||
return dataSource.transaction(async manager => {
|
||||
const orderRepo = manager.getRepository(Order);
|
||||
const orderSaleRepo = manager.getRepository(OrderSale);
|
||||
const OrderSaleOriginalRepo = manager.getRepository(OrderSaleOriginal);
|
||||
const productRepo = manager.getRepository(Product);
|
||||
const order = await orderRepo.save({
|
||||
siteId: '-1',
|
||||
|
|
@ -1314,7 +1332,7 @@ export class OrderService {
|
|||
});
|
||||
for (const sale of sales) {
|
||||
const product = await productRepo.findOne({ where: { sku: sale.sku } });
|
||||
await orderSaleRepo.save({
|
||||
const saleItem = {
|
||||
orderId: order.id,
|
||||
siteId: '-1',
|
||||
externalOrderItemId: '-1',
|
||||
|
|
@ -1322,7 +1340,9 @@ export class OrderService {
|
|||
name: product.name,
|
||||
sku: sale.sku,
|
||||
quantity: sale.quantity,
|
||||
});
|
||||
};
|
||||
await orderSaleRepo.save(saleItem);
|
||||
await OrderSaleOriginalRepo.save(saleItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1363,4 +1383,42 @@ export class OrderService {
|
|||
pageSize,
|
||||
};
|
||||
}
|
||||
|
||||
async updateOrderSales(orderId: number, sales: OrderSale[]) {
|
||||
try {
|
||||
const dataSource = this.dataSourceManager.getDataSource('default');
|
||||
let transactionError = undefined;
|
||||
|
||||
await dataSource.transaction(async manager => {
|
||||
const orderRepo = manager.getRepository(Order);
|
||||
const orderSaleRepo = manager.getRepository(OrderSale);
|
||||
const productRepo = manager.getRepository(Product);
|
||||
|
||||
const order = await orderRepo.findOneBy({ id: orderId });
|
||||
let product:Product;
|
||||
await orderSaleRepo.delete({ orderId });
|
||||
for (const sale of sales) {
|
||||
product = await productRepo.findOneBy({ sku: sale.sku });
|
||||
await orderSaleRepo.save({
|
||||
orderId,
|
||||
siteId: order.siteId,
|
||||
productId: product.id,
|
||||
name: product.name,
|
||||
sku: sale.sku,
|
||||
quantity: sale.quantity
|
||||
});
|
||||
};
|
||||
}).catch(error => {
|
||||
transactionError = error;
|
||||
});
|
||||
|
||||
if (transactionError !== undefined) {
|
||||
throw new Error(`更新物流信息错误:${transactionError.message}`);
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new Error(`更新发货产品失败:${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue