UNPKG

sf-apple-sdk

Version:

Apple SF SDK for SF WMS

391 lines (390 loc) 19.7 kB
// src/services/outbound.service.ts import { LocationEnum } from "../types/location.js"; import { Scene } from "../types/index.js"; import { SERVICE_CODE } from "../constants/service.js"; import { TransactionCode, TransactionCodeSfOutOrderTypeMap, } from "../constants/transaction-code.js"; import { post } from "../utils/post.js"; /** * 出库单接口 Service 3.5 ✅ * 下发出库单数据 */ export class OutboundService { constructor(options) { this.options = options; } /** * 通用下发到SF出库单 * 非必要,不建议调用 */ async sendOutbound(data) { if (!data.saleOrders?.length) { throw new Error("SaleOrders 长度至少为1"); } const res = await post({ url: this.options.baseURL, checkword: this.options.checkword, sysSource: this.options.sysSource, serviceCode: SERVICE_CODE.SALE_ORDER_SERVICE, specialStr: this.options.specialStr, body: { CompanyCode: this.options.sysSource, Checkword: this.options.checkword, AccessCode: this.options.accessCode, ServiceCode: SERVICE_CODE.SALE_ORDER_SERVICE, SaleOrders: data.saleOrders, }, }); return res; } /** * 统一场景出库 */ async sceneOut(data) { try { let transactionCode = ""; let sfOrderType = "10"; // 默认: 销售订单 const location = { from: { location_code: "", location_name: "", }, to: { location_code: "", location_name: "", location_type: "", }, }; let ec_platform_code; let ec_order_number; if (data.scene === Scene.return_factory_out) { // 采购退货出库 - 工厂退大仓 transactionCode = TransactionCode.return_factory; sfOrderType = TransactionCodeSfOutOrderTypeMap.return_factory; // 残次品仓 -> 工厂 location.from = { location_code: `${this.options.hqid}-${this.options.defectiveWarehouseCode}`, location_name: `${this.options.defectiveWarehouseName}`, }; location.to = { location_code: "Factory", location_name: "Factory", location_type: LocationEnum.factory, }; } // else if (data.scene === Scene.sales_2c_out) { // // 销售出库 - 2C消费者 // transactionCode = TransactionCode.sale_out; // sfOrderType = TransactionCodeSfOutOrderTypeMap.sale_out!; // // 良品仓 -> 2C消费者 // location.from = { // location_code: `${this.options.hqid}-${this.options.goodWarehouseCode}`, // location_name: `${this.options.goodWarehouseName}`, // }; // location.to = { // location_code: "EDTC", // 2C消费者 // location_name: "EDTC", // location_type: LocationEnum.edtc, // }; // } /** 企业订单 or 企业员工 都使用 sales_2b_out 场景 */ else if (data.scene === Scene.sales_2b_e_out) { // 销售出库 - 企业员工 transactionCode = TransactionCode.sale_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.sale_out; location.from = { location_code: `${this.options.hqid}-${this.options.goodWarehouseCode}`, location_name: `${this.options.goodWarehouseName}`, }; // 良品仓 -> 企业员工 location.to = { location_code: "EDTC", // 企业员工 location_name: "EDTC", location_type: LocationEnum.edtc, }; if (data?.ec_platform?.ec_order_number) { ec_platform_code = this.options.ecPlatformCode; ec_order_number = data.ec_platform?.ec_order_number; } } else if (data.scene === Scene.sales_2b_out) { // 销售出库 - 企业 无需报数 ✅ transactionCode = TransactionCode.sale_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.sale_out; // 良品仓 -> 企业 location.from = { location_code: `${this.options.hqid}-${this.options.goodWarehouseCode}`, location_name: `${this.options.goodWarehouseName}`, }; location.to = { location_code: "EDTC", // 企业 location_name: "EDTC", // 企业 location_type: LocationEnum.edtc, // 企业 }; } else if (data.scene === Scene.sales_2ro_out) { // 销售出库 - 经销商办公室 transactionCode = TransactionCode.sale_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.sale_out; // 良品仓 -> 经销商办公室 location.from = { location_code: `${this.options.hqid}-${this.options.goodWarehouseCode}`, location_name: `${this.options.goodWarehouseName}`, }; location.to = { location_code: this.options.officeCode, location_name: this.options.officeName, location_type: LocationEnum.reseller_office, }; } else if (data.scene === Scene.gift_out) { // 礼品出库 transactionCode = TransactionCode.gift_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.gift_out; // 礼品仓 -> 消费者 location.from = { location_code: `${this.options.hqid}-${this.options.giftWarehouseCode}`, location_name: `${this.options.giftWarehouseName}`, }; location.to = { location_code: `Expense`, location_name: `Expense`, location_type: LocationEnum.expense, }; } else if (data.scene === Scene.borrow_out) { // 借机出库 transactionCode = TransactionCode.borrow_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.borrow_out; // 借机仓 -> 消费者 location.from = { location_code: `${this.options.hqid}-${this.options.borrowWarehouseCode}`, location_name: `${this.options.borrowWarehouseName}`, }; location.to = { location_code: `Expense`, location_name: `Expense`, location_type: LocationEnum.expense, }; } else if (data.scene === Scene.seed_out) { // Seed出库 transactionCode = TransactionCode.seed_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.seed_out; // Seed仓 -> 消费者 location.from = { location_code: `${this.options.hqid}-${this.options.seedWarehouseCode}`, location_name: `${this.options.seedWarehouseName}`, }; location.to = { location_code: `Expense`, location_name: `Expense`, location_type: LocationEnum.expense, }; } else if (data.scene === Scene.quality_change_out) { if (!data.transfer?.origin_bill_code) { throw new Error("品质变更出库 transfer.origin_bill_code 是必填的"); } // 品质变更出库 良品 -> 残次品 transactionCode = TransactionCode.quality_change_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.quality_change_out; // 良品仓 -> 残次品仓 location.from = { location_code: `${this.options.hqid}-${this.options.goodWarehouseCode}`, location_name: `${this.options.goodWarehouseName}`, }; location.to = { location_code: `${this.options.hqid}-${this.options.defectiveWarehouseCode}`, location_name: `${this.options.defectiveWarehouseName}`, location_type: LocationEnum.sf_apple_warehouse, }; } else if (data.scene === Scene.defective_out) { // 残次品处理 残次品出库 残次品出售 transactionCode = TransactionCode.defective_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.defective_out; // 残次品仓 -> 消费者 location.from = { location_code: `${this.options.hqid}-${this.options.defectiveWarehouseCode}`, location_name: `${this.options.defectiveWarehouseName}`, }; location.to = { location_code: `Expense`, location_name: `Expense`, location_type: LocationEnum.expense, }; } else if (data.scene === Scene.difference_out) { // 差异调拨出库 if (!data.transfer?.origin_bill_code) { throw new Error("差异调拨出库 transfer.origin_bill_code 是必填的"); } transactionCode = TransactionCode.difference_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.difference_out; // 大仓 -> 大仓 location.from = { location_code: data.transfer.from_location_code, location_name: data.transfer.from_location_name, }; location.to = { location_code: data.transfer.to_location_code, location_name: data.transfer.to_location_name, location_type: LocationEnum.sf_apple_warehouse, }; } else if (data.scene === Scene.transfer_out) { // 仓间调拨出库 if (!data.transfer?.origin_bill_code) { throw new Error("仓间调拨出库 transfer.origin_bill_code 是必填的"); } transactionCode = TransactionCode.transfer_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.transfer_out; // 调拨出库 from to 都是大仓 location.from = { location_code: data.transfer.from_location_code, location_name: data.transfer.from_location_name, }; location.to = { location_code: data.transfer.to_location_code, location_name: data.transfer.to_location_name, location_type: LocationEnum.sf_apple_warehouse, }; } else if (data.scene === Scene.cycle_out) { // 盘点出库 from to 都是大仓 if (!data.cycle) { throw new Error("盘点出库 cycle 是必填的"); } transactionCode = TransactionCode.cycle_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.cycle_out; // 盘点出库 from to 都是大仓 location.from = { location_code: `${this.options.hqid}-${data.cycle?.from_location_code}`, location_name: `${data.cycle?.from_location_name}`, }; location.to = { location_code: `${this.options.hqid}-${data.cycle?.to_location_code}`, location_name: `${data.cycle?.to_location_name}`, location_type: LocationEnum.sf_apple_warehouse, }; } else if (data.scene === Scene.value_added_service_transfer_out) { if (!data.transfer?.origin_bill_code) { throw new Error("增值服务调拨出库 transfer.origin_bill_code 是必填的"); } transactionCode = TransactionCode.value_added_service_transfer_out; sfOrderType = TransactionCodeSfOutOrderTypeMap.value_added_service_transfer_out; location.from = { location_code: `${this.options.hqid}-${this.options.goodWarehouseCode}`, location_name: `${this.options.goodWarehouseName}`, }; location.to = { location_code: `${this.options.hqid}-${this.options.deployWarehouseCode}`, location_name: `${this.options.deployWarehouseName}`, location_type: LocationEnum.sf_apple_warehouse, }; } if (data?.jxqz && data.jxqz === "Y") { if (!data?.jxqz_time) { throw new Error("极校前置时间 jxqz_time 是必填的"); } } const items = data.skus.map((sku) => { return { SkuNo: sku.sku_code, ItemQuantity: sku.qty, LotAttr4: location.from.location_code, // FromLocationCode UserDef2: sku.mpn, ItemUom: sku?.unit, SerialNumbers: sku?.sn_list, InventoryStatus: sku.inventory_status, }; }); const result = await this.sendOutbound({ saleOrders: [ { WarehouseCode: this.options.warehouseCode, ErpOrder: data.bill_code, ErpOrderType: transactionCode, // 苹果要求的 TransactionCode SfOrderType: data.jxqz === "Y" ? "JXQZ" : sfOrderType, DestinationFacilityName: data.receiver.company_name, // 电子签收单 消费 SalesRepresentative: data.sender?.sales_name, ExpeditedPrereleaseTime: data.jxqz === "Y" ? data?.jxqz_time : undefined, TradePlatform: ec_platform_code, TradeOrder: ec_order_number, OrderCarrier: { /** 顺丰速运、自提 */ Carrier: data.jxqz === "Y" ? "CP" : data.scene === Scene.sales_2b_out || data.scene === Scene.sales_2b_e_out || data.scene === Scene.sales_2ro_out || data.scene === Scene.gift_out || data.scene === Scene.borrow_out || data.scene === Scene.seed_out ? "CP" : "ZT", /** 极校前置优先级最高,其次是销售出库(标准快递),最后是其他场景(自提) */ CarrierProduct: data.jxqz === "Y" ? "SE0129" : data.scene === Scene.sales_2b_out || data.scene === Scene.sales_2b_e_out || data.scene === Scene.sales_2ro_out || data.scene === Scene.gift_out || data.scene === Scene.borrow_out || data.scene === Scene.seed_out ? data.carrier_product_code : "ZT", CarrierAddedServices: [ { ServiceCode: data.need_electronic_receipt === "Y" ? "IN149" : undefined, Attr01: data.need_electronic_receipt ? "3" : undefined, // 需要使用电子回单的,该字段传 3 }, ], }, OrderReceiverInfo: { ReceiverCompany: location.to.location_name || undefined, // ToLocationName ReceiverName: data.receiver.person_name, // 电子签收单 消费 ReceiverPhone: data.receiver.person_phone, // 电子签收单 消费 ReceiverProvince: data.receiver.province, ReceiverCity: data.receiver.city, ReceiverArea: data.receiver.area, ReceiverAddress: data.receiver.address, // 电子签收单 消费 ReceiverIdCard: data.receiver?.person_id_card, ReceiverCountry: "中国", }, OrderSenderInfo: { SenderCompany: data.sender?.company_name, SenderName: data.sender?.person_name, SenderPhone: data.sender?.person_phone, }, OrderExtendAttribute: { UserDef4: location.to.location_code || undefined, // ToLocationCode 两个字段都传 UserDef5: data.transfer?.origin_bill_code, // 存回传 Apple 厂商的调拨单原参考 erp单号 UserDef7: location.to.location_code || undefined, // ToLocationCode 两个字段都传 UserDef8: data.scene === Scene.sales_2ro_out ? this.options.officeName : data.scene === Scene.sales_2b_e_out ? data.receiver.company_name : undefined, // 经销商AccountName 或者 客户企业名称 UserDef9: data.scene === Scene.sales_2b_out || data.scene === Scene.sales_2b_e_out || data.scene === Scene.sales_2ro_out ? this.options.hqid : undefined, // 经销商 ASAB hqid UserDef11: location.to.location_type || undefined, // ToLocationType UserDef12: `${data.receiver.province}|${data.receiver.city}|${data.receiver.area}|${data.receiver.address}`, // 使用 | 拼接省市区县详细地址,例如:广东|深圳市|南山区|中山路 1 号 UserDef15: location.from.location_name || undefined, // FromLocationName }, OrderItems: items, }, ], }); return result; } catch (error) { throw error; } } }