| //#region import | 
| import { default as BaseController } from "../baseController"; | 
| import { Post } from "egg-shell-decorators"; | 
| import * as mssql from "mssql"; | 
| import { In, Like, MoreThan, Raw } from "typeorm"; | 
| import { SaleOuter } from "../../entity/outbound/sale/saleOuter"; | 
| import { SaleSendList } from "../../entity/outbound/sale/saleSendList"; | 
| import { SaleOrderPrintList } from "../../entity/outbound/manufacture/saleOrderPrintList"; | 
| import { SaleSortingRulePosition } from "../../entity/outbound/sortingrule/saleSortingRulePosition"; | 
| import { BaseExpressSpareCode } from "../../entity/express/spare/baseExpressSpareCode"; | 
| import * as XLSX from "xlsx"; | 
| import * as path from "path"; | 
| import { BaseStorage } from "../../entity/basicInfo/base/baseStorage"; | 
| import { BaseExpressCorp } from "../../entity/basicInfo/base/baseExpressCorp"; | 
| import { SaleOrderList } from "../../entity/outbound/sale/saleOrderList"; | 
| import { SaleOrder } from "../../entity/outbound/sale/saleOrder"; | 
| import { BaseClient } from "../../entity/crm/client/baseClient"; | 
| import { BaseConsignor } from "../../entity/basicInfo/consignor/baseConsignor"; | 
| import { BaseProductInfo } from "../../entity/basicInfo/base/baseProductInfo"; | 
| import { isNumber } from "util"; | 
| import moment = require("moment"); | 
| import { SaleOrderMerge } from "../../entity/outbound/sale/saleOrderMerge"; | 
| import { BaseProductPlaceHolder } from "../../entity/storage/storage/baseProductPlaceHolder"; | 
| import { SaleReturn } from "../../entity/outbound/service/saleReturn"; | 
| import { SaleOrderStatusHistory } from "../../entity/outbound/order/saleOrderStatusHistory"; | 
| import { BasePlateType } from "../../entity/basicInfo/base/basePlateType"; | 
| import { vBaseProductPlaceHolder } from "../../entity/storage/storage/vBaseProductPlaceHolder"; | 
| import { BaseProductPosition } from "../../entity/storage/product/baseProductPosition"; | 
| import { BasePosition } from "../../entity/basicInfo/base/basePosition"; | 
| import { SaleReturnList } from "../../entity/outbound/service/saleReturnList"; | 
| import { PurchaseOrder } from "../../entity/inbound/purchase/purchaseOrder"; | 
| import { PurchaseOrderList } from "../../entity/inbound/purchase/purchaseOrderList"; | 
| import { BasePlate } from "../../entity/basicInfo/base/basePlate"; | 
| import { vBaseProductPosition } from "../../entity/storage/product/vBaseProductPosition"; | 
| import { BaseDestination } from "../../entity/basicInfo/workshop/baseDestination"; | 
| import { BaseProductInfoHistory } from "../../entity/basicInfo/base/baseProductInfoHistory"; | 
| import * as xlsxStye from "xlsx-style"; | 
| import { LackOrder } from "../../entity/outbound/sale/lackOrder"; | 
| import { SysUserLog } from "../../entity/sys/core/sysUserLog"; | 
| //import { LackOrderList } from "../../entity/outbound/sale/lackOrderList"; | 
| //#endregion | 
|   | 
| /** | 
|  * 出库单 | 
|  */ | 
| export default class OrderController extends BaseController { | 
|   //#region 批量审核 | 
|   /** | 
|    * 修改日期:2019/1/11 | 
|    * 如果明细为空则不让审核通过 | 
|    */ | 
|   @Post() | 
|   public async multiConfirm() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     let product_Ids = []; | 
|   | 
|     try { | 
|       //#region 校验数据 | 
|       if (!Array.isArray(body.selectIDs)) { | 
|         this.info.result = false; | 
|         this.info.msg = "数据不存在"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       let orders = await this.dbRead.findByIds(SaleOrder, body.selectIDs); | 
|       for (var orderInfo of orders) { | 
|         let erp_expressCorp_Id = await this.ctx.service.common.getConfig("erp_expressCorp_Id"); | 
|         if (!orderInfo.expressCorp_Id) { | 
|           let corpInfo = await this.dbRead.findOne(BaseExpressCorp, { | 
|             userProduct_Id: userInfo.userProduct_Id, | 
|             expressCorp_Id: Number(erp_expressCorp_Id) | 
|           }); | 
|           if (corpInfo) { | 
|             orderInfo.expressCorp_Id = Number(erp_expressCorp_Id); | 
|             orderInfo.expressCorpName = corpInfo.expressCorpName; | 
|             orderInfo.expressCorpType = corpInfo.expressCorpType; | 
|           } | 
|         } | 
|         if (!orderInfo.storage_Id) { | 
|           this.info.result = false; | 
|           this.info.msg = orderInfo.orderCode + "仓库不能为空"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|         if (["用户取消"].indexOf(orderInfo.statusText) >= 0) { | 
|           this.info.result = false; | 
|           this.info.msg = `出库单【${orderInfo.orderCode}】状态为【${orderInfo.statusText}】不允许进行审核操作!`; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|         var detailList = await this.dbRead.find(SaleOrderList, { | 
|           order_Id: orderInfo.order_Id | 
|         }); | 
|         product_Ids.concat(detailList.map(item => item.product_Id)); | 
|   | 
|         if (!detailList.length) { | 
|           this.info.result = false; | 
|           this.info.msg = orderInfo.orderCode + "请填写运单明细!"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|         if (detailList.filter(row => row.quantityOrder <= 0).length > 0) { | 
|           this.info.result = false; | 
|           this.info.msg = orderInfo.orderCode + "订单的明细预出库数量不允许小于零!"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|       } | 
|       //#endregion | 
|   | 
|       //#region 审核 | 
|       await this.dbWrite.update( | 
|         SaleOrder, | 
|         { | 
|           order_Id: In(body.selectIDs) | 
|         }, | 
|         { | 
|           statusID: 2, | 
|           statusText: "审核成功", | 
|           auditor: userInfo.userTrueName, | 
|           auditing: 2, | 
|           auditDate: new Date() | 
|         } | 
|       ); | 
|       //#endregion | 
|   | 
|       //#region 新增保存后记录订单状态轨迹 | 
|       for (var orderInfo of orders) { | 
|         ctx.service.outbound.orderHelper.setStatusHistory(orderInfo.order_Id, orderInfo.statusID, 2, "订单状态", "订单审核"); | 
|       } | 
|       //#endregion | 
|   | 
|       //#region 激活分拣 | 
|       //激活分拣池 | 
|       const connection: any = await this.dbWrite.connection; | 
|       let request = new mssql.Request(connection.driver.master); | 
|       request.input("Order_Ids", body.selectIDs.join(",")); | 
|       request.input("Product_Ids", product_Ids.join(",")); | 
|       request.input("createID", userInfo.user_Id); | 
|       request.input("creator", userInfo.userTrueName); | 
|       let result = await request.execute("sp_SortOrder"); | 
|       let outMsg = result.returnValue; | 
|       if (outMsg != null && outMsg) { | 
|         this.info.msg = outMsg; | 
|         this.info.result = false; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       //启动分拣 | 
|       setTimeout(async () => { | 
|         for (let id of body.selectIDs) { | 
|           const connection: any = await this.dbWrite.connection; | 
|           let request = new mssql.Request(connection.driver.master); | 
|           request.input("order_Id", id); | 
|           request.input("user_Id", userInfo.user_Id); | 
|           request.output("outMsg", mssql.NVarChar(2000)); | 
|           let result = await request.execute("sp_Sale_Order_Sorting"); | 
|           let outMsg = result.output.outMsg; | 
|           if (outMsg != null && outMsg) { | 
|             this.info.msg = outMsg; | 
|             this.info.result = false; | 
|           } | 
|         } | 
|       }, 0); | 
|       //#endregion | 
|       this.info.result = true; | 
|       this.info.msg = "审核成功"; | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 开始分拣 | 
|   /** | 
|    * 修改日期:2019/1/12 | 
|    * 开始分拣 | 
|    */ | 
|   @Post() | 
|   public async sorting() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     if (!Array.isArray(body.selectIDs)) { | 
|       this.info.result = false; | 
|       this.info.msg = "数据不存在"; | 
|       ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     try { | 
|       // 执行分拣 | 
|       for (let id of body.selectIDs) { | 
|         const connection: any = await this.dbWrite.connection; | 
|         let request = new mssql.Request(connection.driver.master); | 
|         request.input("order_Id", id); | 
|         request.input("user_Id", userInfo.user_Id); | 
|         request.output("outMsg", mssql.NVarChar(2000)); | 
|         let result = await request.execute("sp_Sale_Order_Sorting"); | 
|         let outMsg = result.output.outMsg; | 
|         if (outMsg != null && outMsg) { | 
|           this.info.msg = outMsg; | 
|           this.info.result = false; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|         this.info.msg = "分拣完成"; | 
|         this.info.result = true; | 
|       } | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 销售订单改变快递公司 | 
|   @Post() | 
|   public async changeExpressCorp() { | 
|     let userInfo = await this.userInfo; | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     if (!Array.isArray(body.ids) || !body.ids.length) { | 
|       this.info.result = false; | 
|       this.info.msg = "没有可执行的单号"; | 
|       return; | 
|     } | 
|     let orderList = await this.dbRead.find(SaleOrder, { | 
|       order_Id: In(body.ids), | 
|       userProduct_Id: userInfo.userProduct_Id | 
|     }); | 
|   | 
|     for (let orderInfo of orderList) { | 
|       await this.dbWrite.update( | 
|         SaleOrder, | 
|         { | 
|           order_Id: orderInfo.order_Id, | 
|           statusText: In(["待审核", "审核成功", "改变物流", "发运完成", "打包完成"]) | 
|         }, | 
|         { | 
|           expressCode: null, | 
|           expressCorp_Id: body.expressCorp_Id, | 
|           expressCorpName: body.expressCorpName, | 
|           expressCorpType: body.expressCorpType | 
|         } | 
|       ); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleOuter, | 
|         { | 
|           order_Id: orderInfo.order_Id, | 
|           statusText: In(["待审核", "审核成功", "改变物流", "发运完成", "打包完成"]) | 
|         }, | 
|         { | 
|           expressCode: null, | 
|           expressCorp_Id: body.expressCorp_Id, | 
|           expressCorpName: body.expressCorpName | 
|         } | 
|       ); | 
|   | 
|       // 圆通号段分配清除 | 
|       await this.dbWrite.update( | 
|         BaseExpressSpareCode, | 
|         { | 
|           order_Id: orderInfo.order_Id | 
|         }, | 
|         { | 
|           order_Id: null, | 
|           orderCode: null | 
|         } | 
|       ); | 
|   | 
|       ctx.service.outbound.orderHelper.setStatusHistory(body.order_Id, orderInfo.statusID, 25, "订单状态", "改变物流"); | 
|     } | 
|   | 
|     //调度快递接口数据 | 
|     const connection: any = await this.dbWrite.connection; | 
|     let request = new mssql.Request(connection.driver.master); | 
|     let result = await request.execute("sp_Interface_ExpressOrder"); | 
|     let outMsg = result.output.outMsg; | 
|     if (outMsg != null && outMsg) { | 
|       this.info.msg = outMsg; | 
|       this.info.result = false; | 
|       ctx.body = this.info; | 
|     } | 
|   | 
|     if (result) { | 
|       this.info.result = true; | 
|       this.info.msg = "确认成功"; | 
|     } else { | 
|       this.info.result = false; | 
|       this.info.msg = "执行失败"; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region updateExpressCode 更新快递单号 | 
|   @Post() | 
|   public async updateExpressCode() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|   | 
|     //#region 更新运单号 | 
|     if (!body.expressCode) { | 
|       await this.dbWrite.update( | 
|         SaleOrder, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: null | 
|         } | 
|       ); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleOuter, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: null | 
|         } | 
|       ); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleSendList, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: null | 
|         } | 
|       ); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleOrderPrintList, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: null | 
|         } | 
|       ); | 
|     } else { | 
|       await this.dbWrite.update( | 
|         SaleOrder, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: body.expressCode | 
|         } | 
|       ); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleOuter, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: body.expressCode | 
|         } | 
|       ); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleSendList, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: body.expressCode | 
|         } | 
|       ); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleOrderPrintList, | 
|         { | 
|           order_Id: body.order_Id, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           expressCode: body.expressCode | 
|         } | 
|       ); | 
|     } | 
|   | 
|     this.info.result = true; | 
|     this.info.msg = "快递单号更新成功!"; | 
|   | 
|     ctx.body = this.info; | 
|     //#endregion | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 获得分拣规则 | 
|   @Post() | 
|   public async getSortingRule() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|   | 
|     var orderList_Id = body.orderList_Id; | 
|     var dataList = await this.dbRead.find(SaleSortingRulePosition, { | 
|       orderList_Id: orderList_Id | 
|     }); | 
|     this.info.result = true; | 
|     this.info.data = dataList; | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 添加单据 | 
|   @Post() | 
|   public async addNewOrder() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       let userInfo = await ctx.helper.userInfo(); | 
|       var taskForm = body.taskForm; | 
|       if (!taskForm.product_Id) { | 
|         this.info.result = false; | 
|         this.info.msg = "请选择物料号"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       if (!taskForm.destination_Id) { | 
|         this.info.result = false; | 
|         this.info.msg = "请选择目的地"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       if (["焊装出库", "调件出库"].indexOf(taskForm.orderType) >= 0) { | 
|         // if (!taskForm.outTransId) { | 
|         //   this.info.result = false; | 
|         //   this.info.msg = "请选择出库口"; | 
|         //   ctx.body = this.info; | 
|         //   return; | 
|         // } | 
|   | 
|         let where = { | 
|           order_Id: Raw(() => { | 
|             return `order_Id IN(Select Order_Id from Sale_OrderList L where SaleOrder.order_Id=L.order_Id And L.Product_Id=${taskForm.product_Id})`; | 
|           }), | 
|           userProduct_Id: userInfo.userProduct_Id, | 
|           orderType: In(["焊装出库", "调件出库"]), | 
|           statusText: "新建" | 
|         }; | 
|         let orderInfo = await this.dbRead.findOne(SaleOrder, where); | 
|         if (orderInfo) { | 
|           this.info.result = false; | 
|           this.info.msg = `物料[${taskForm.productName}]已创建,不可重复创建!`; | 
|           this.ctx.body = this.info; | 
|           return; | 
|         } | 
|       } | 
|       let consignorInfo = await this.dbRead.findOne(BaseConsignor, { userProduct_Id: userInfo.userProduct_Id }); | 
|       // 获取物料信息 | 
|       let productInfo = await this.dbRead.findOne(BaseProductInfo, { | 
|         product_Id: taskForm.product_Id | 
|       }); | 
|   | 
|       // 记录当前用户常用的物料 | 
|       var historyInfo = await this.dbRead | 
|         .createQueryBuilder(BaseProductInfoHistory, "t") | 
|         .where("user_Id=:user_Id and userProduct_Id=:userProduct_Id and product_Id=:product_Id", { | 
|           user_Id: userInfo.user_Id, | 
|           userProduct_Id: userInfo.userProduct_Id, | 
|           product_Id: productInfo.product_Id | 
|         }) | 
|         .getOne(); | 
|       if (historyInfo) { | 
|         historyInfo.useNum += 1; | 
|         await this.dbWrite.save(historyInfo); | 
|       } else { | 
|         historyInfo = new BaseProductInfoHistory(); | 
|         historyInfo.user_Id = userInfo.user_Id; | 
|         historyInfo.userProduct_Id = userInfo.userProduct_Id; | 
|         historyInfo.product_Id = productInfo.product_Id; | 
|         historyInfo.useNum = 1; | 
|         await this.setAccountInfo(historyInfo); | 
|         await this.dbWrite.save(historyInfo); | 
|       } | 
|   | 
|       let plateTypeInfo = await this.dbRead.findOne(BasePlateType, { | 
|         plateType: productInfo.plateType | 
|       }); | 
|       if (!plateTypeInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = `${productInfo.plateType}器具种类基本信息中不存在`; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       if (!plateTypeInfo.storage_Id) { | 
|         this.info.result = false; | 
|         this.info.msg = `${productInfo.plateType}器具种类未设置仓库信息`; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       // 获取目的地 | 
|       let destinationInfo = await this.dbRead.findOne(BaseDestination, { | 
|         destination_Id: taskForm.destination_Id | 
|       }); | 
|       let ppList = await this.dbRead.find(vBaseProductPosition, { | 
|         where: { | 
|           storage_Id: plateTypeInfo.storage_Id, | 
|           product_Id: taskForm.product_Id, | 
|           validQty: MoreThan(0), | 
|           positionType: 1 | 
|         }, | 
|         order: { | 
|           inStorageDate: "ASC" | 
|         } | 
|       }); | 
|       if (!ppList.length) { | 
|         this.info.result = false; | 
|         this.info.msg = `${productInfo.productCode}物料库存不足`; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       // 创建单据, validQty需要出库数量 | 
|       let createOrder = async (validQty: number, ppInfo?: vBaseProductPosition) => { | 
|         var orderInfo = new SaleOrder(); | 
|         orderInfo.orderCode = await ctx.service.common.getCodeRegular(112); | 
|         orderInfo.consignorName = consignorInfo.consignorName; | 
|         orderInfo.consignor_Id = consignorInfo.consignor_Id; | 
|         orderInfo.consignorCode = consignorInfo.consignorCode; | 
|         orderInfo.storageName = plateTypeInfo.storageName; | 
|         orderInfo.storage_Id = plateTypeInfo.storage_Id; | 
|         orderInfo.statusText = "新建"; | 
|         orderInfo.statusID = 1; | 
|         orderInfo.sortingStatus = 1; | 
|         orderInfo.orderType = taskForm.orderType; | 
|         orderInfo.orderExit = taskForm.orderExit; // 出库区域 | 
|         // 立体库需要 | 
|         if (ppInfo) { | 
|           orderInfo.plateCode = ppInfo.plateCode; | 
|           orderInfo.plateType = ppInfo.plateType; | 
|         } | 
|         orderInfo.totalQuantityOrder = validQty; | 
|         orderInfo.destinationName = destinationInfo.destinationName; | 
|         orderInfo.destination_Id = destinationInfo.destination_Id; | 
|         orderInfo.outTransId = taskForm.outTransId; | 
|         await this.setAccountInfo(orderInfo); | 
|         await this.dbWrite.save(orderInfo); | 
|   | 
|         var orderListInfo = new SaleOrderList(); | 
|         orderListInfo.order_Id = orderInfo.order_Id; | 
|         orderListInfo.productName = productInfo.productName; | 
|         orderListInfo.productCode = productInfo.productCode; | 
|         orderListInfo.product_Id = productInfo.product_Id; | 
|         orderListInfo.productModel = productInfo.productModel; | 
|         orderListInfo.sortingStatus = 1; | 
|         if (ppInfo) { | 
|           orderListInfo.quantityOrder = ppInfo.productStorage; | 
|           orderListInfo.positionName = ppInfo.positionName; | 
|           orderListInfo.planQty = ppInfo.productStorage; | 
|         } | 
|         await this.dbWrite.save(orderListInfo); | 
|       }; | 
|   | 
|       // 需要出库数量 | 
|       let validQty = body.taskForm.validQty; | 
|       if (["EU箱出库", "外协件出库"].indexOf(taskForm.orderType) >= 0) { | 
|         await createOrder(validQty); | 
|       } else { | 
|         // 焊装出库任务,调件出库任务 | 
|         for (let ppInfo of ppList) { | 
|           if (validQty <= 0) break; | 
|           if (validQty > ppInfo.validQty) { | 
|             await createOrder(ppInfo.validQty, ppInfo); | 
|             validQty -= ppInfo.validQty; | 
|           } else { | 
|             await createOrder(validQty, ppInfo); | 
|             validQty = 0; | 
|           } | 
|         } | 
|       } | 
|       this.info.result = true; | 
|       this.info.msg = "添加成功!"; | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 出库指令 | 
|   @Post() | 
|   public async outCommand() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       let userInfo = await ctx.helper.userInfo(); | 
|       var ids = body.ids; | 
|       if (!Array.isArray(ids) || !ids.length) { | 
|         this.info.result = false; | 
|         this.info.msg = "至少选择一条进行出库指令"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       for (let id of ids) { | 
|         let orderInfo = await this.dbRead.findOne(SaleOrder, id); // 获取出库主表数据 | 
|         let orderInfoList = await this.dbRead.find(SaleOrderList, { | 
|           order_Id: id | 
|         }); | 
|         if (orderInfo.statusID === 2) {//枚举Sale_Order_StatusEnum,2 表示已下发  | 
|           this.info.result = true; | 
|           this.info.msg = "任务指令单已生成,不允许重复生成"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|   | 
|         for (let id of ids) { | 
|           await this.dbWrite.update( | 
|             SaleOrder, | 
|             { | 
|               order_Id: id, | 
|               userProduct_Id: userInfo.userProduct_Id | 
|             }, | 
|             { | 
|               statusText: "待下架", | 
|               statusID: 7 | 
|             } | 
|           ); | 
|           for (var item of orderInfoList) { | 
|             await this.dbWrite.update( | 
|               SaleOrderList, | 
|               { | 
|                 orderList_Id: item.orderList_Id, | 
|                 userProduct_Id: userInfo.userProduct_Id | 
|               }, | 
|               { | 
|                 extendField03: "待下架" | 
|               } | 
|             ); | 
|           } | 
|         } | 
|         this.info.result = true; | 
|         this.info.msg = "出库指令执行成功!"; | 
|       } | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 出库指令 | 
|   @Post() | 
|   public async lackAnalysis() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       let userInfo = await ctx.helper.userInfo(); | 
|       var ids = body.ids; | 
|   | 
|       let orderInfo = await this.dbRead.findOne(SaleOrder, ids); // 获取出库主表数据 | 
|       let orderInfoList = await this.dbRead.find(SaleOrderList, { | 
|         order_Id: ids | 
|       }); | 
|       //let lackInfo= | 
|       if (orderInfo.statusText === "部分出库") { | 
|         this.info.result = true; | 
|         this.info.msg = "任务指令单已生成,不允许重复生成"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       if (orderInfo.statusText === "新建") { | 
|         this.info.result = true; | 
|         this.info.msg = "任务指令单已生成,不允许重复生成"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       await this.dbWrite.update( | 
|         SaleOrder, | 
|         { | 
|           order_Id: ids, | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }, | 
|         { | 
|           statusText: "部分出库", | 
|           statusID: 1 | 
|         } | 
|       ); | 
|       for (var item of orderInfoList) { | 
|         await this.dbWrite.update( | 
|           SaleOrderList, | 
|           { | 
|             orderList_Id: item.orderList_Id, | 
|             userProduct_Id: userInfo.userProduct_Id | 
|           }, | 
|           { | 
|             extendField03: "待下架", | 
|             quantityOrder: 0, | 
|             validQuantity: item.validQuantity - item.quantityOrder | 
|           } | 
|         ); | 
|         let orderInfos = await this.dbRead.find(SaleOrderList, { | 
|           order_Id: ids, | 
|           validQuantity: MoreThan(0) | 
|         }); | 
|         if (orderInfos.length === 0) { | 
|           await this.dbWrite.update( | 
|             SaleOrder, | 
|             { | 
|               order_Id: ids, | 
|               userProduct_Id: userInfo.userProduct_Id | 
|             }, | 
|             { | 
|               statusText: "已完成", | 
|               statusID: 7 | 
|             } | 
|           ); | 
|         } | 
|       } | 
|       let where = await ctx.service.common.getWhere(); | 
|       let fieldStr = `k.SaleCode AS '销售单号',k.SaleCodeItem AS '销售项号',K.MaterailCode AS '物料编号', | 
|       K.MaterailName AS '物料名称',K.LackQuantity AS '缺料数量',k.TemporaryQuantity AS '暂存区数量', | 
|       k.StorageQuantity AS '立库区数量',k.StorageUnit AS 库存单位`; | 
|       let fields = fieldStr.split(","); | 
|       let wayBillList: Array<any> = await this.dbRead | 
|         .createQueryBuilder(LackOrder, "t") | 
|         .select(fields) | 
|         .innerJoin("LackOrderList", "k", "k.LackId = t.LackId") | 
|         .where(where) | 
|         .andWhere("t.WorkCode = WorkCode", { | 
|           WorkCode: orderInfo.orderCode | 
|         }) | 
|         // .orderBy({ | 
|         //   lackId: "DESC" | 
|         // }) | 
|         .take(5000) | 
|         .getRawMany(); | 
|       let lackOrders = await this.dbRead.findOne(LackOrder, { | 
|         workCode: orderInfo.orderCode | 
|       }); | 
|   | 
|       let root = path.resolve(); | 
|       let url = "/download/缺料统计表.xlsx"; | 
|       let fileName = root + url.replace(/\//g, path.sep); | 
|       let pathToCreate = fileName.substring(0, fileName.lastIndexOf(path.sep)); | 
|       ctx.helper.mkdir(pathToCreate); | 
|       let opts = { | 
|         cellStyles: true, | 
|         origin: 2 // 跳过前N行 | 
|       }; | 
|   | 
|       let jsonWorkSheet = XLSX.utils.json_to_sheet(wayBillList, opts); | 
|   | 
|       // 构造workBook | 
|       let workBook = { | 
|         SheetNames: ["缺料单"], | 
|         Sheets: { | 
|           缺料单: jsonWorkSheet | 
|           // 商品信息: arrayWorkSheet | 
|         } | 
|       }; | 
|       jsonWorkSheet["!cols"] = [ | 
|         //设置宽度 | 
|         { wpx: 100 }, //1-第一列 | 
|         { wpx: 140 }, //2-第二列 | 
|         { wpx: 180 }, //3 | 
|         { wpx: 180 }, //3 | 
|         { wpx: 100 }, //3 | 
|         { wpx: 100 }, //3 | 
|         { wpx: 100 }, //3 | 
|         { wpx: 100 }, //3 | 
|         { wpx: 100 } //3 | 
|       ]; | 
|   | 
|       let worksheet = workBook.Sheets["缺料单"]; | 
|       // let worksheet1 = workBook.Sheets["商品信息"]; | 
|       // 设置标题格式 | 
|       for (let index = 0; index < 29; index++) { | 
|         let col = XLSX.utils.encode_col(index); // 转为字母 | 
|         let cell = worksheet[col + "1"]; | 
|         if (!cell) continue; | 
|   | 
|         cell.s = { | 
|           alignment: { | 
|             //对齐方式 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           }, | 
|           font: { | 
|             sz: 12, | 
|             bold: false | 
|           } | 
|         }; | 
|       } | 
|       // 设置标题格式 | 
|       for (let index = 0; index < 11; index++) { | 
|         let col = XLSX.utils.encode_col(index); // 转为字母 | 
|         let cell = worksheet[col + "1"]; | 
|         if (!cell) continue; | 
|   | 
|         cell.s = { | 
|           alignment: { | 
|             //对齐方式 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           }, | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "宋体" | 
|           }, | 
|           fill: { | 
|             fgColor: { | 
|               rgb: "ff0000" // 单元格背景颜色 | 
|             } | 
|           } | 
|         }; | 
|       } | 
|       worksheet["A1"] = { | 
|         v: "广州西门子配变智能化工厂-立库区PICKLIST缺料报表", | 
|         s: { | 
|           font: { | 
|             sz: 30, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             vertical: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["A2"] = { | 
|         v: "生产订单号:", | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["B2"] = { | 
|         v: lackOrders.workCode, | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["C2"] = { | 
|         v: "跟踪号:", | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["D2"] = { | 
|         v: lackOrders.trackCode, | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["E2"] = { | 
|         v: "总套数:", | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["F2"] = { | 
|         v: lackOrders.totalCount, | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["G2"] = { | 
|         v: "出库套数:", | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["H2"] = { | 
|         v: lackOrders.counting + "_" + lackOrders.finishCount, | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["I2"] = { | 
|         v: "完成套数:", | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       worksheet["J2"] = { | 
|         v: lackOrders.finishCount, | 
|         s: { | 
|           font: { | 
|             sz: 10, | 
|             bold: true, | 
|             name: "Arial" | 
|           }, | 
|           alignment: { | 
|             //垂直水平居中 | 
|             vertical: "center", | 
|             horizontal: "center" | 
|           } | 
|         } | 
|       }; | 
|       var wopts = { bookType: "xlsx", bookSST: false, type: "file" }; | 
|       xlsxStye.writeFileSync(workBook, fileName, wopts); | 
|   | 
|       // XLSX.writeFile(workBook, fileName); | 
|   | 
|       //#endregion | 
|       this.info.result = true; | 
|       this.info.data = { | 
|         url: url | 
|       }; | 
|       this.info.msg = "导出成功!"; | 
|   | 
|       this.info.result = true; | 
|       this.info.msg = "缺料分析指令执行成功!"; | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 领取任务/结束任务 | 
|   @Post() | 
|   public async getTask() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       var id = body.id; | 
|       var relationState = body.relationState; | 
|       if (!id) { | 
|         this.info.result = false; | 
|         this.info.msg = "请选中一条"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       var dataInfo = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: id | 
|       }); | 
|       dataInfo.relationState = relationState; | 
|       await this.dbWrite.save(dataInfo); | 
|       this.info.result = true; | 
|       this.info.msg = "操作成功!"; | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 返修 | 
|   @Post() | 
|   public async backRepairOrder() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       var order_Id = body.order_Id; | 
|       var nowQuantityOrder = body.nowQuantityOrder; | 
|       // var nowQuantityOrder = body.nowQuantityOrder; | 
|       var orderList_Id = body.orderList_Id; | 
|       if (!order_Id) { | 
|         this.info.result = false; | 
|         this.info.msg = "order_Id不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       var orderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: order_Id | 
|       }); | 
|       if (orderInfo.statusText !== "完全出库") { | 
|         this.info.result = false; | 
|         this.info.msg = "只有完全出库可以进行操作!"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       var saleOrderList = await this.dbRead.findOne(SaleOrderList, { | 
|         orderList_Id: orderList_Id | 
|       }); | 
|   | 
|       // 当前商品只会占一条库存明细 | 
|       var holderInfo = await this.dbRead.findOne(vBaseProductPlaceHolder, { | 
|         mainID: order_Id, | 
|         detailID: orderList_Id, | 
|         className: "销售订单" | 
|       }); | 
|       if (!holderInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = "获取库存异常"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       var postionInfo = await this.dbRead.findOne(BaseProductPosition, { | 
|         productPosition_Id: holderInfo.productPosition_Id | 
|       }); | 
|   | 
|       orderInfo.statusText = "已回库"; | 
|       await this.dbWrite.save(orderInfo); | 
|   | 
|       // 新建焊装返修回库单 | 
|       var purchaseInfo = new PurchaseOrder(); | 
|       purchaseInfo.orderCode = await ctx.service.common.getCodeRegular(1803); | 
|       purchaseInfo.plateCode = orderInfo.plateCode; | 
|       purchaseInfo.plateName = orderInfo.plateName; | 
|       purchaseInfo.sourceId = saleOrderList.order_Id; | 
|       purchaseInfo.repairType = "焊装返修"; | 
|       purchaseInfo.orderType = "焊装返修"; | 
|       purchaseInfo.storageName = orderInfo.storageName; | 
|       purchaseInfo.storage_Id = orderInfo.storage_Id; | 
|       purchaseInfo.statusText = "新建"; | 
|       purchaseInfo.totalQuantity = nowQuantityOrder; | 
|       purchaseInfo.consignor_Id = orderInfo.consignor_Id; | 
|       purchaseInfo.consignorCode = orderInfo.consignorCode; | 
|       purchaseInfo.consignorName = orderInfo.consignorName; | 
|       // purchaseInfo.partStatus = "焊装待返修"; | 
|       await this.dbWrite.save(purchaseInfo); | 
|   | 
|       var purchaselistInfo = new PurchaseOrderList(); | 
|       purchaselistInfo.order_Id = purchaseInfo.order_Id; | 
|       purchaselistInfo.sourceMainID = saleOrderList.order_Id; | 
|       purchaselistInfo.sourceListID = saleOrderList.orderList_Id; | 
|       purchaselistInfo.product_Id = postionInfo.product_Id; | 
|       purchaselistInfo.productCode = postionInfo.productCode; | 
|       purchaselistInfo.productName = postionInfo.productName; | 
|       purchaselistInfo.productModel = postionInfo.productModel; | 
|       purchaselistInfo.quantity = nowQuantityOrder; | 
|       purchaselistInfo.ratePrice = postionInfo.ratePrice; | 
|       purchaselistInfo.purchaseMoney = nowQuantityOrder * postionInfo.ratePrice; | 
|       purchaselistInfo.totalPackageQty = nowQuantityOrder; | 
|       purchaselistInfo.batchNumber = postionInfo.batchNumber; | 
|       purchaselistInfo.produceDate = postionInfo.produceDate; | 
|       await this.dbWrite.save(purchaseInfo); | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 余料回库 | 
|   @Post() | 
|   public async backOutOrder() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       var order_Id = body.order_Id; | 
|       //var nowQuantityOrder = body.order_Id; | 
|       var nowQuantityOrder = body.nowQuantityOrder; | 
|       var orderList_Id = body.orderList_Id; | 
|       if (!order_Id) { | 
|         this.info.result = false; | 
|         this.info.msg = "order_Id不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       var orderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: order_Id | 
|       }); | 
|       if (orderInfo.statusText !== "完全出库") { | 
|         this.info.result = false; | 
|         this.info.msg = "只有完全出库可以进行操作!"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       var saleOrderList = await this.dbRead.findOne(SaleOrderList, { | 
|         orderList_Id: orderList_Id | 
|       }); | 
|   | 
|       // 当前商品只会占一条库存明细 | 
|       var holderInfo = await this.dbRead.findOne(vBaseProductPlaceHolder, { | 
|         mainID: order_Id, | 
|         detailID: orderList_Id, | 
|         className: "销售订单" | 
|       }); | 
|       if (!holderInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = "获取库存异常"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       var postionInfo = await this.dbRead.findOne(BaseProductPosition, { | 
|         productPosition_Id: holderInfo.productPosition_Id | 
|       }); | 
|   | 
|       // 通过物料寻找器具种类,取器具种类的库区和仓库 寻找空货位 | 
|       var baseProductInfo = await this.dbRead.findOne(BaseProductInfo, { | 
|         product_Id: saleOrderList.product_Id | 
|       }); | 
|       if (!baseProductInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = "获取商品信息异常"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       var basePlateTypeInfo = await this.dbRead.findOne(BasePlateType, { | 
|         plateType_Id: baseProductInfo.plateType_Id | 
|       }); | 
|   | 
|       if (!basePlateTypeInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = "获取器具种类异常"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       let basePositionInfo = await this.dbRead | 
|         .createQueryBuilder(BasePosition, "t") | 
|         .where( | 
|           "storage_Id=:storage_Id and areaCode=:areaCode and   NOT EXISTS(SELECT 1 FROM dbo.vBase_ProductPosition where positionName=t.positionName  and validQty>0 )", | 
|           { storage_Id: basePlateTypeInfo.storage_Id, areaCode: basePlateTypeInfo.areaCode } | 
|         ) | 
|         .getOne(); | 
|       if (!basePositionInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = basePlateTypeInfo.storageName + basePlateTypeInfo.areaCode + "没有空货位了"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       postionInfo.positionName = basePositionInfo.positionName; | 
|       postionInfo.areaCode = basePositionInfo.areaCode; | 
|       postionInfo.storageName = basePositionInfo.storageName; | 
|       postionInfo.storage_Id = basePositionInfo.storage_Id; | 
|       postionInfo.productPosition_Id = null; | 
|       postionInfo.productStorage = nowQuantityOrder; | 
|       await this.dbWrite.save(postionInfo); | 
|   | 
|       orderInfo.statusText = "已回库"; | 
|       await this.dbWrite.save(orderInfo); | 
|   | 
|       // 新建出库余料回库单 | 
|       var saleReturnInfo = new SaleReturn(); | 
|       saleReturnInfo.returnCode = await ctx.service.common.getCodeRegular(112); | 
|       saleReturnInfo.order_Id = orderInfo.order_Id; | 
|       saleReturnInfo.orderCode = orderInfo.orderCode; | 
|       saleReturnInfo.consignor_Id = orderInfo.consignor_Id; | 
|       saleReturnInfo.consignorCode = orderInfo.consignorCode; | 
|       saleReturnInfo.consignorName = orderInfo.consignorName; | 
|       saleReturnInfo.orderType = "出库余料回库"; | 
|       saleReturnInfo.storage_Id = basePositionInfo.storage_Id; | 
|       saleReturnInfo.storageName = basePositionInfo.storageName; | 
|       saleReturnInfo.statusText = "全部收货"; | 
|       saleReturnInfo.totalQuantity = postionInfo.productStorage; | 
|       await this.dbWrite.save(saleReturnInfo); | 
|   | 
|       var saleReturnListInfo = new SaleReturnList(); | 
|       saleReturnListInfo.return_Id = saleReturnInfo.return_Id; | 
|       saleReturnListInfo.product_Id = postionInfo.product_Id; | 
|       saleReturnListInfo.productCode = postionInfo.productCode; | 
|       saleReturnListInfo.productName = postionInfo.productName; | 
|       saleReturnListInfo.quantityOrder = postionInfo.productStorage; | 
|       saleReturnListInfo.plateCode = orderInfo.plateCode; | 
|       saleReturnListInfo.plateName = orderInfo.plateName; | 
|       await this.dbWrite.save(saleReturnListInfo); | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 出库操作 | 
|   @Post() | 
|   public async outOrder() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       var order_Id = body.order_Id; | 
|       var nowQuantityOrder = body.nowQuantityOrder; | 
|       var orderList_Id = body.orderList_Id; | 
|       if (!order_Id) { | 
|         this.info.result = false; | 
|         this.info.msg = "order_Id不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       var orderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: order_Id | 
|       }); | 
|       if (orderInfo.statusText !== "下架完成") { | 
|         this.info.result = false; | 
|         this.info.msg = "只有下架完成可以进行操作!"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       var saleOrderList = await this.dbRead.findOne(SaleOrderList, { | 
|         orderList_Id: orderList_Id | 
|       }); | 
|       // 减去该单原库存明细库存 当前商品只会占一条库存明细 | 
|       var holderInfo = await this.dbRead.findOne(vBaseProductPlaceHolder, { | 
|         mainID: order_Id, | 
|         detailID: orderList_Id, | 
|         className: "销售订单" | 
|       }); | 
|       if (holderInfo && holderInfo.placeholderStorage > 0 && holderInfo.placeholderStorage >= nowQuantityOrder) { | 
|         var postionInfo = await this.dbRead.findOne(BaseProductPosition, { | 
|           productPosition_Id: holderInfo.productPosition_Id | 
|         }); | 
|         postionInfo.productStorage = postionInfo.productStorage - nowQuantityOrder; | 
|         await this.dbWrite.save(postionInfo); | 
|       } else { | 
|         this.info.result = false; | 
|         this.info.msg = "占位异常,请核对占位信息"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       // 清除该单据所有占位 | 
|       var holderList = await this.dbRead.find(BaseProductPlaceHolder, { | 
|         mainID: order_Id, | 
|         className: "销售订单" | 
|       }); | 
|       for (var hold of holderList) { | 
|         hold.placeholderStorage = 0; | 
|         await this.dbWrite.save(hold); | 
|       } | 
|   | 
|       orderInfo.statusID = nowQuantityOrder === holderInfo.placeholderStorage ? 12 : 36; | 
|       orderInfo.statusText = nowQuantityOrder === holderInfo.placeholderStorage ? "完全出库" : "部分出库"; | 
|       await this.dbWrite.save(orderInfo); | 
|       saleOrderList.quantityOuted = nowQuantityOrder; | 
|       saleOrderList.validQuantity = saleOrderList.quantityOrder - nowQuantityOrder; | 
|       await this.dbWrite.save(saleOrderList); | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 根据器具编号获取部分出库的单据 | 
|   @Post() | 
|   public async GetBackByplateCode() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       var plateCode = body.plateCode; | 
|       if (!plateCode) { | 
|         this.info.result = false; | 
|         this.info.msg = "器具编号不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       var dataInfo = await this.dbRead.findOne(SaleOrder, { | 
|         where: { | 
|           plateCode: plateCode, | 
|           statusText: "部分出库" | 
|         }, | 
|         order: { createDate: "DESC" } | 
|       }); | 
|       if (dataInfo) { | 
|         var saleOrderList = await this.dbRead.find(SaleOrderList, { | 
|           order_Id: dataInfo.order_Id | 
|         }); | 
|         dataInfo.saleOrderList = saleOrderList; | 
|         this.info.data = dataInfo; | 
|         this.info.result = true; | 
|         this.info.msg = "获取成功"; | 
|       } else { | 
|         this.info.result = false; | 
|         this.info.msg = "当前器具编号未获取到部分出库的单据"; | 
|       } | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 根据器具编号获取完全出库的单据 | 
|   @Post() | 
|   public async GetOutByplateCode() { | 
|     let { ctx } = this; | 
|     try { | 
|       let body = ctx.request.body; | 
|       var plateCode = body.plateCode; | 
|       if (!plateCode) { | 
|         this.info.result = false; | 
|         this.info.msg = "器具编号不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       var dataInfo = await this.dbRead.findOne(SaleOrder, { | 
|         where: { | 
|           plateCode: plateCode, | 
|           statusText: "完全出库" | 
|         }, | 
|         order: { createDate: "DESC" } | 
|       }); | 
|       if (dataInfo) { | 
|         var saleOrderList = await this.dbRead.find(SaleOrderList, { | 
|           order_Id: dataInfo.order_Id | 
|         }); | 
|         dataInfo.saleOrderList = saleOrderList; | 
|         this.info.data = dataInfo; | 
|         this.info.result = true; | 
|         this.info.msg = "获取成功"; | 
|       } else { | 
|         this.info.result = false; | 
|         this.info.msg = "当前器具编号未获取到完全出库的单据"; | 
|       } | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 设置分拣规则 | 
|   @Post() | 
|   public async setSortingRule() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|   | 
|     var ruleInfo = new SaleSortingRulePosition(); | 
|     ruleInfo.batchNumber = body.batchNumber; | 
|     ruleInfo.consignor_Id = body.consignor_Id; | 
|     ruleInfo.consignorCode = body.consignorCode; | 
|     ruleInfo.consignorName = body.consignorName; | 
|     ruleInfo.createDate = new Date(); | 
|     ruleInfo.createID = userInfo.user_Id; | 
|     ruleInfo.creator = userInfo.userTrueName; | 
|     ruleInfo.enable = 1; | 
|   | 
|     ruleInfo.order_Id = body.order_Id; | 
|     ruleInfo.orderCode = body.orderCode; | 
|     ruleInfo.orderList_Id = body.orderList_Id; | 
|     ruleInfo.plateCode = body.plateCode; | 
|     ruleInfo.positionName = body.positionName; | 
|     ruleInfo.produceDate = body.produceDate || null; | 
|     ruleInfo.product_Id = body.product_Id; | 
|     ruleInfo.productCode = body.productCode; | 
|     ruleInfo.singleSignCode = body.singleSignCode; | 
|     ruleInfo.storage_Id = body.storage_Id; | 
|     ruleInfo.storageName = body.storageName; | 
|     await this.dbWrite.save(ruleInfo); | 
|   | 
|     this.info.result = true; | 
|     this.info.msg = "添加成功!"; | 
|   | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 关闭分拣规则 | 
|   @Post() | 
|   public async deleteSortingRule() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|   | 
|     var rule_Id = body.rule_Id; | 
|     await this.dbWrite.delete(SaleSortingRulePosition, { | 
|       rule_Id: rule_Id, | 
|       userProduct_Id: userInfo.userProduct_Id | 
|     }); | 
|   | 
|     this.info.result = true; | 
|     this.info.msg = "关闭成功!"; | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 出库单数据导入 | 
|   @Post() | 
|   public async importExcel() { | 
|     setTimeout(async () => { | 
|       await this.importExcelWork(); | 
|     }, 0); | 
|   | 
|     this.info.result = true; | 
|     this.ctx.body = this.info; | 
|   } | 
|   | 
|   private async importExcelWork() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let startDate = new Date(); | 
|     let fileUrl = body.fileUrl; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     let storage = null; | 
|     if (!fileUrl) { | 
|       this.setMsg(`上传文件不存在`, "red"); | 
|       return; | 
|     } | 
|     try { | 
|       let rootPath = path.resolve(); // 获得根目录 | 
|       let filePath = rootPath + path.sep + fileUrl.replace(/\//gi, path.sep); // 上传文件路径 | 
|       var workbook = XLSX.readFile(filePath); //整个 excel 文档 | 
|       var sheetNames = workbook.SheetNames; //获取所有工作薄名 | 
|       var sheet1 = workbook.Sheets[sheetNames[0]]; //根据工作薄名获取工作薄 | 
|       let dataList = XLSX.utils.sheet_to_json(sheet1); // 获得当前sheet表单数据转为json格式 | 
|       this.info.result = true; | 
|       if (!dataList.length) { | 
|         this.setMsg(`没有可导入的数据`, "red"); | 
|         return; | 
|       } | 
|       storage = await this.dbRead.findOne(BaseStorage, { | 
|         storageName: body.storageName, | 
|         userProduct_Id: userInfo.userProduct_Id | 
|       }); | 
|   | 
|       // 全部快递公司 | 
|       // let expressList = await this.dbRead.find(BaseExpressCorp, { | 
|       //   userProduct_Id: userInfo.userProduct_Id | 
|       // });                        暂时不要 | 
|       // 全部货主信息 | 
|       let consignorList = await this.dbRead.find(BaseConsignor, { | 
|         consignorName: body.consignorName, | 
|         userProduct_Id: userInfo.userProduct_Id | 
|       }); | 
|       // 记录已经验证过的物料,不在读取数据库 | 
|       let existProductList = []; | 
|       let index = 0; | 
|       for (let item of dataList) { | 
|         let productCode = "" + item["物料编号"]; | 
|         // let expressCorpName = "" + item["快递公司"]; | 
|         let storeOrderCode = "" + (item["店铺单号"] || ""); | 
|         // let consignorName = "" + item["货主"]; | 
|   | 
|         // if (consignorName) { | 
|         //   consignorName = body.consignorName; | 
|         // } | 
|   | 
|         let _index = index + 1; | 
|         if (_index % 20 === 1) { | 
|           this.setMsg(`第${_index}行开始校验`, "blue"); | 
|         } | 
|         // !item["收货人"] || !item["地址"] || 收货人、地址、|| !item["快递公司"]  不能删除,德胜不需要 | 
|         if (!item["数量"]) { | 
|           this.setMsg(`${_index}、标黄[货主、数量、快递公司]部分数据不能为空`, "red"); | 
|         } | 
|         //判断店铺是否已重复导入 | 
|         if (storeOrderCode) { | 
|           let isExists = await this.dbRead.findOne(SaleOrder, { | 
|             // consignorName: "" + item["货主"], | 
|             storeOrderCode: storeOrderCode, | 
|             userProduct_Id: userInfo.userProduct_Id | 
|           }); | 
|           if (isExists) { | 
|             this.setMsg(`${_index}、店铺订单号[${item["店铺单号"]}"]已存在,不能再次导入`, "red"); | 
|           } | 
|         } | 
|         //判断快递公司是否存在        德胜的不要 | 
|         // if (item["快递公司"]) { | 
|         //   let isexisorder = expressList.find(item => item.expressCorpName === expressCorpName); | 
|         //   if (!isexisorder) { | 
|         //     this.setMsg(`${_index}、快递公司【${item["快递公司"]}】不存在`, "red"); | 
|         //   } | 
|         // } | 
|         //判断物料 | 
|         let isexesproduct = await this.dbRead.findOne(BaseProductInfo, { | 
|           userProduct_Id: userInfo.userProduct_Id, | 
|           productCode: productCode | 
|         }); | 
|   | 
|         if (!isexesproduct) { | 
|           this.setMsg(`${_index}、物料编号在物料信息中[${productCode}"]不存在,数据导入失败`, "red"); | 
|         } else { | 
|           existProductList.push(isexesproduct); | 
|         } | 
|         //判断货主 | 
|         // let isExisConsign = consignorList.find(item => item.consignorName === consignorName); | 
|         // if (!isExisConsign) { | 
|         //   this.setMsg(`${_index}、货主[${consignorName}"]不存在,数据导入失败`, "red"); | 
|         // } | 
|         index++; | 
|       } | 
|   | 
|       if (this.isMsgError) { | 
|         this.setMsg(`导入数据有错误,请处理好重新导入`, "red"); | 
|         this.setMsg("-1"); | 
|         return; | 
|       } | 
|   | 
|       //订单分组 | 
|       let orderGroupList = dataList.reduce( | 
|         (all: Array<any>, next) => | 
|           all.some( | 
|             item => | 
|               item["货主"] == next["货主"] && | 
|               item["客户名称"] == next["客户名称"] && | 
|               item["收货人"] == next["收货人"] && | 
|               item["手机"] == next["手机"] && | 
|               item["快递公司"] == next["快递公司"] && | 
|               item["地址"] == next["地址"] && | 
|               item["订单类型"] == next["订单类型"] && | 
|               item["业务员"] == next["业务员"] | 
|           ) | 
|             ? all | 
|             : [...all, next], | 
|         [] | 
|       ); | 
|       let groupIndex = 0; | 
|       let details = []; | 
|       for (let orderitem of orderGroupList) { | 
|         groupIndex++; | 
|         let orderCode = await ctx.service.common.getCodeRegular(112); | 
|         // if (groupIndex % 20 === 1) { | 
|         this.setMsg(`${groupIndex}/${orderGroupList.length}单、${orderCode}订单开始导入`, "blue"); | 
|         // } | 
|         // #region 创建主表数据 | 
|         // let expressCorp = await this.dbRead.findOne(BaseExpressCorp, { | 
|         //   expressCorpName: "" + orderitem["快递公司"], | 
|         //   userProduct_Id: userInfo.userProduct_Id | 
|         // }); | 
|         //判断货主 | 
|         let consign = await this.dbRead.findOne(BaseConsignor, { | 
|           // consignorName: "" + orderitem["货主"], | 
|           consignorName: "" + orderitem["货主"], | 
|   | 
|           userProduct_Id: userInfo.userProduct_Id | 
|         }); | 
|         let isExisConsign = consignorList.find(item => item.consignorName === body.consignorName); | 
|         // let corp = null; | 
|         // let expressCorpName = orderitem["快递公司"];   // 德胜不需要,别的要 | 
|         let orderInfo = new SaleOrder(); | 
|         // if (expressCorpName) {                         // 德胜不需要,别的要 | 
|         //   let corp = expressList.find(item => item.expressCorpName === expressCorpName); | 
|         //   if (corp) { | 
|         //     orderInfo.expressCorp_Id = corp.expressCorp_Id; | 
|         //     orderInfo.expressCorpName = expressCorpName; | 
|         //     orderInfo.expressCorpType = corp.expressCorpType; | 
|         //   } | 
|         // } | 
|         orderInfo.orderCode = orderCode; | 
|         orderInfo.orderType = orderitem["订单类型"]; | 
|         orderInfo.storeOrderCode = orderitem["店铺单号"]; | 
|         if (!orderitem["货主"]) { | 
|           orderInfo.consignor_Id = isExisConsign.consignor_Id; | 
|           orderInfo.consignorCode = isExisConsign.consignorCode; | 
|           orderInfo.consignorName = isExisConsign.consignorName; | 
|         } else { | 
|           orderInfo.consignor_Id = consign.consignor_Id; | 
|           orderInfo.consignorCode = consign.consignorCode; | 
|           orderInfo.consignorName = consign.consignorName; | 
|         } | 
|   | 
|         orderInfo.storageName = storage.storageName; | 
|         //客户信息 | 
|         // let kh = await this.dbRead.findOne(BaseClient, { | 
|         //   clientShortName: "" + orderitem["客户名称"] | 
|         // }); | 
|   | 
|         // sql = `Select top 1 client_Id, clientCode from Base_Client Where clientShortName='${orderitem.clientShortName}'`; | 
|         // let ht = await this.dbWrite.query(sql); | 
|         // orderInfo.client_Id = kh.client_Id; | 
|         // orderInfo.clientCode = kh.clientCode; | 
|         orderInfo.clientShortName = orderitem["客户名称"] || orderitem["门店名称"]; | 
|         orderInfo.clientCode = orderitem["客户编号"] || orderitem["门店编号"]; | 
|         orderInfo.shippingName = orderitem["收货人"]; | 
|         orderInfo.expressCode = orderitem["快递单号"]; | 
|         orderInfo.provinceName = orderitem["省份"]; | 
|         orderInfo.cityName = orderitem["城市"]; | 
|         orderInfo.regionName = orderitem["区县"]; | 
|         orderInfo.shippingAddress = orderitem["地址"]; | 
|         orderInfo.mobile = orderitem["手机"]; | 
|         orderInfo.telephone = orderitem["座机"]; | 
|         // if (expressCorp) { | 
|         //   orderInfo.expressCorp_Id = expressCorp.expressCorp_Id; | 
|         //   orderInfo.expressCorpName = expressCorp.expressCorpName; | 
|         //   orderInfo.expressCorpType = expressCorp.expressCorpType; | 
|   | 
|         // } | 
|         orderInfo.shippingAmount = 0; | 
|         orderInfo.totalPaid = 0; | 
|         orderInfo.totalQuantityOrder = 0; | 
|         if (storage) { | 
|           orderInfo.storage_Id = storage.storage_Id; | 
|           orderInfo.storageName = storage.storageName; | 
|         } | 
|         orderInfo.createID = userInfo.user_Id; | 
|         orderInfo.creator = userInfo.userTrueName; | 
|         orderInfo.createDate = new Date(); | 
|   | 
|         orderInfo.statusID = 1; | 
|         orderInfo.statusText = "待审核"; | 
|         orderInfo.auditing = 0; | 
|         orderInfo.sortingStatus = 1; | 
|         orderInfo.remark = null; | 
|         orderInfo.userTrueName = orderitem["业务员"]; | 
|         orderInfo.applyDate = new Date(); | 
|         orderInfo.platUser_Id = userInfo.platUser_Id; | 
|         orderInfo.platUserCode = userInfo.platUserCode; | 
|         orderInfo.platUserName = userInfo.platUserName; | 
|         orderInfo.platCorpName = userInfo.platCorpName; | 
|         orderInfo.userProduct_Id = userInfo.userProduct_Id; | 
|         orderInfo.userProductCode = userInfo.userProductCode; | 
|         orderInfo.userProductAlias = userInfo.userProductAlias; | 
|   | 
|         // 获得当前运单下明细 | 
|         let detailList = dataList.filter( | 
|           row => | 
|             row["货主"] === orderitem["货主"] && | 
|             row["客户名称"] === orderitem["客户名称"] && | 
|             row["收货人"] === orderitem["收货人"] && | 
|             row["手机"] === orderitem["手机"] && | 
|             row["快递公司"] === orderitem["快递公司"] && | 
|             row["地址"] === orderitem["地址"] && | 
|             row["订单类型"] === orderitem["订单类型"] && | 
|             row["业务员"] === orderitem["业务员"] | 
|         ); | 
|   | 
|         // 主表求和字段计算 | 
|         let total: any = detailList.reduce( | 
|           (totalItem: any, currItem) => { | 
|             totalItem.totalQuantityOrder += parseFloat(currItem["数量"]); | 
|             totalItem.discountAmount += 0; | 
|             totalItem.weight += 0; | 
|             totalItem.grandTotal += 0; | 
|             return totalItem; | 
|           }, | 
|           { totalQuantityOrder: 0, discountAmount: 0, weight: 0, grandTotal: 0 } | 
|         ); | 
|   | 
|         orderInfo.totalQuantityOrder = total.totalQuantityOrder; | 
|         orderInfo.discountAmount = total.discountAmount; | 
|         orderInfo.weight = total.weight; | 
|         orderInfo.grandTotal = total.grandTotal; | 
|         await this.dbWrite.insert(SaleOrder, orderInfo); | 
|         //#endregion | 
|         // let saleorderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         //   orderCode: orderCode, | 
|         //   userProduct_Id: userInfo.userProduct_Id | 
|         // }); | 
|         //#region 明细数据 | 
|         for (let _detailInfo of detailList) { | 
|           let expandFields = {}; // 扩展字段值 | 
|           let prodInfo = existProductList.find(item => item.productCode === "" + _detailInfo["物料编号"]); | 
|           let detail = new SaleOrderList(); | 
|           detail.order_Id = orderInfo.order_Id; | 
|           detail.product_Id = prodInfo.product_Id; | 
|           detail.productCode = "" + prodInfo.productCode; | 
|           detail.productName = _detailInfo["物料名称"] || prodInfo.productName; | 
|           detail.productModel = _detailInfo["物料编号"] || "" + prodInfo.productModel; | 
|           detail.productSpec = _detailInfo["物料规格"] || prodInfo.productSpec; | 
|   | 
|           detail.quantityOrder = _detailInfo["数量"]; | 
|           detail.salePrice = _detailInfo["销售单价"] || prodInfo.salePrice || 0; | 
|           detail.discountRate = _detailInfo["货品折扣"] || 1; | 
|           detail.salePriceDiscount = detail.salePrice * detail.discountRate; | 
|           detail.subTotal = detail.salePriceDiscount * detail.quantityOrder; | 
|           detail.discountAmount = _detailInfo["优惠金额"] || 0; | 
|           detail.rowTotal = detail.salePrice || detail.quantityOrder; | 
|           detail.rowPaid = _detailInfo["实收金额"] || 0; | 
|           detail.attachAmount = _detailInfo["附加金额"]; | 
|           detail.purchasePrice = prodInfo.purchasePrice || 0; | 
|           detail.createID = userInfo.user_Id; | 
|           detail.creator = userInfo.userTrueName; | 
|           detail.createDate = new Date(); | 
|           detail.remark = null; | 
|           detail.weight = prodInfo.weight; | 
|           detail.totalWeight = _detailInfo["数量"] * prodInfo.weight; | 
|           detail.smallUnit = prodInfo.smallUnit; | 
|           detail.bigUnit = prodInfo.bigUnit; | 
|           detail.remark = _detailInfo["备注"]; | 
|           detail.batchNumber = _detailInfo["批次号"]; | 
|           detail.singleSignCode = _detailInfo["定制唯一码"]; | 
|   | 
|           detail.rate = prodInfo.rate; | 
|           detail.ratePrice = prodInfo.salePrice * prodInfo.rate; | 
|           detail.rateMoney = prodInfo.ratePrice * detail.quantityOrder; | 
|           // 拓展字段 | 
|           expandFields["purchaseamount"] = _detailInfo["数量"] * prodInfo.purchasePrice || 0; | 
|           expandFields["salesvolume"] = _detailInfo["数量"] * _detailInfo["销售单价"] || prodInfo.salePrice || 0; | 
|           expandFields["volume"] = _detailInfo["体积"]; | 
|           detail.expandFields = JSON.stringify(expandFields); | 
|           details.push(detail); | 
|           if (details.length >= 50) { | 
|             await this.dbWrite.insert(SaleOrderList, details); | 
|             details = []; | 
|           } | 
|         } | 
|         //#endregion | 
|       } | 
|       if (details.length > 0) { | 
|         await this.dbWrite.insert(SaleOrderList, details); | 
|         details = []; | 
|       } | 
|       let sql = ` | 
|       UPDATE dbo.Sale_Order SET | 
|       totalQuantityOrder = (SELECT SUM(quantityOrder) FROM dbo.Sale_OrderList WHERE order_Id = Sale_Order.order_Id), | 
|       discountAmount = (SELECT SUM(discountAmount) FROM dbo.Sale_OrderList WHERE order_Id = Sale_Order.order_Id),    /*优惠金额*/ | 
|       subTotal = (SELECT SUM(subTotal) FROM dbo.Sale_OrderList WHERE order_Id = Sale_Order.order_Id),    /*折后金额*/ | 
|       unpaid = (SELECT SUM(subTotal) FROM dbo.Sale_OrderList WHERE order_Id = Sale_Order.order_Id),    /*未支付*/ | 
|       totalPaid = 0,                /*实收金额*/ | 
|       grandTotal = (SELECT SUM(rowTotal) FROM dbo.Sale_OrderList WHERE order_Id = Sale_Order.order_Id),            /*销售金额*/ | 
|       totalWeight = ISNULL((SELECT SUM(totalWeight) FROM dbo.Sale_OrderList WHERE order_Id = dbo.Sale_Order.order_Id), 0) | 
|       WHERE dbo.Sale_Order.userProduct_Id = '${userInfo.userProduct_Id}' And CreateDate>=DateAdd(day, -1, getdate());`; | 
|       await this.dbWrite.query(sql); | 
|   | 
|       let endDate = moment(Date.now()); | 
|       let totalSeconds = endDate.diff(startDate, "seconds"); | 
|       let msg = `导入完成,共耗时${totalSeconds}秒`; | 
|       this.setMsg(msg); | 
|     } catch (ex) { | 
|       this.setMsg("出现异常:" + ex.message, "red"); | 
|     } | 
|     this.setMsg("-1"); | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 新增出库单 | 
|   /** | 
|    * 新增出库单 | 
|    */ | 
|   @Post() | 
|   public async add() { | 
|     let { ctx } = this; | 
|     let body = ctx.body; | 
|     let userInfo = await this.userInfo; | 
|     let db = this.app.mongodb; | 
|     try { | 
|       // 记录数据到mongodb日志中 | 
|       let collection = db.collection("apiSaleOrder"); | 
|       let mongoData = JSON.parse(JSON.stringify(body)); | 
|       mongoData.createDate = new Date(); | 
|       mongoData.userProduct_Id = userInfo.userProduct_Id; | 
|       let re = await collection.insert(mongoData); | 
|       ctx.logger.info("apiSaleOrder将数据保存至MongoDB after:" + JSON.stringify(re)); | 
|     } catch {} | 
|   | 
|     if (!userInfo && !userInfo.userProduct_Id) { | 
|       this.info.result = false; | 
|       this.info.msg = "数据不存在"; | 
|       ctx.body = this.info; | 
|       return; | 
|     } | 
|     let userProduct_Id = userInfo.userProduct_Id; | 
|   | 
|     if (!body.consignorCode) { | 
|       this.info.result = false; | 
|       this.info.msg = "货主编号不能为空"; | 
|       ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     if (!body.consignorName) { | 
|       this.info.result = false; | 
|       this.info.msg = "货主名称不能为空"; | 
|       ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     if (!Array.isArray(body.details) || !body.details.length) { | 
|       this.info.result = false; | 
|       this.info.msg = "出库单明细不能为空"; | 
|       ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     try { | 
|       if (!body.consignorCode) { | 
|         this.info.result = false; | 
|         this.info.msg = "货主编号不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       if (!body.consignorName) { | 
|         this.info.result = false; | 
|         this.info.msg = "货主名称不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       if (!body.storeOrderCode) { | 
|         this.info.result = false; | 
|         this.info.msg = "ERP订单号不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       if (!Array.isArray(body.details) || !body.details.length) { | 
|         this.info.result = false; | 
|         this.info.msg = "出库单明细不能为空"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       // 验证单号是否已推送 | 
|       let storeOrderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         storeOrderCode: body.storeOrderCode, | 
|         userProduct_Id: userProduct_Id | 
|       }); | 
|       if (storeOrderInfo) { | 
|         this.info.result = true; | 
|         this.info.statusCode = 660; | 
|         this.info.msg = body.storeOrderCode + "已存在,不允许重复推送"; | 
|         this.info.data = { | 
|           order_Id: storeOrderInfo.order_Id, | 
|           orderCode: storeOrderInfo.orderCode | 
|         }; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       // 验证货主 | 
|       let consignorInfo = await this.dbRead.findOne(BaseConsignor, { | 
|         consignorCode: body.consignorCode, | 
|         userProduct_Id: userProduct_Id | 
|       }); | 
|       if (!consignorInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = "货主不存在"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       this.body.consignor_Id = consignorInfo.consignor_Id; | 
|       this.body.consignorCode = consignorInfo.consignorCode; | 
|   | 
|       // 接口推送时需要仓库 | 
|       let erp_storage_Id = await this.ctx.service.common.getConfigBool("erp_storage_Id"); | 
|       if (erp_storage_Id) { | 
|         // 验证仓库 | 
|         let storageInfo = await this.dbRead.findOne(BaseStorage, { | 
|           storageName: body.storageName, | 
|           userProduct_Id: userProduct_Id | 
|         }); | 
|         if (!storageInfo) { | 
|           this.info.result = false; | 
|           this.info.msg = "仓库不存在"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|         this.body.storage_Id = storageInfo.storage_Id; | 
|       } else { | 
|         // 清掉仓库 | 
|         this.body.storage_Id = null; | 
|         this.body.storageName = null; | 
|       } | 
|       this.body.applyDate = new Date(); | 
|   | 
|       let detailInfo: SaleOrderList; | 
|       for (detailInfo of this.body.details) { | 
|         let prodInfo = await this.dbRead.findOne(BaseProductInfo, { | 
|           where: { | 
|             productCode: detailInfo.productCode, | 
|             userProduct_Id: userProduct_Id | 
|           } | 
|         }); | 
|         if (!prodInfo) { | 
|           this.info.result = false; | 
|           this.info.msg = detailInfo.productCode + "物料编号不存在"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|         detailInfo.product_Id = prodInfo.product_Id; | 
|         detailInfo.productModel = prodInfo.productModel; | 
|         detailInfo.productName = prodInfo.productName; | 
|         detailInfo.productSpec = prodInfo.productSpec; | 
|         detailInfo.weight = prodInfo.weight; | 
|         detailInfo.totalWeight = prodInfo.weight * detailInfo.quantityOrder; | 
|   | 
|         if (!isNumber(detailInfo.quantityOrder)) { | 
|           this.info.result = false; | 
|           this.info.msg = detailInfo.productModel + "数量必须为数字"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|         if (!detailInfo.quantityOrder || detailInfo.quantityOrder <= 0) { | 
|           this.info.result = false; | 
|           this.info.msg = detailInfo.productModel + "数量必须大于0"; | 
|           ctx.body = this.info; | 
|           return; | 
|         } | 
|       } | 
|   | 
|       // 主表求和字段计算 | 
|       let total: any = this.body.details.reduce( | 
|         (totalItem: any, currItem) => { | 
|           totalItem.totalQuantityOrder += currItem["quantityOrder"]; | 
|           totalItem.rowTotal += currItem.quantityOrder * (currItem.salePrice || 0); | 
|           totalItem.subTotal += currItem.quantityOrder * (currItem.salePriceDiscount || 0); | 
|   | 
|           return totalItem; | 
|         }, | 
|         { totalQuantityOrder: 0, rowTotal: 0, subTotal: 0 } | 
|       ); | 
|   | 
|       let code = await this.ctx.service.common.getCodeRegular(112); | 
|       let dataInfo = new SaleOrder(); | 
|       dataInfo = Object.assign(dataInfo, this.body); | 
|       dataInfo.orderCode = code; | 
|       dataInfo.statusID = 1; | 
|       dataInfo.statusText = "待审核"; | 
|       dataInfo.orderType = body.orderType || "常规出库单"; | 
|       dataInfo.totalQuantityOrder = total.totalQuantityOrder; | 
|       dataInfo.weight = 0; | 
|       dataInfo.totalWeight = 0; | 
|       dataInfo.grandTotal = total.rowTotal; | 
|       dataInfo.subTotal = total.subTotal; | 
|       dataInfo.unpaid = dataInfo.subTotal; | 
|       dataInfo.totalPaid = 0; | 
|   | 
|       // 接口默认快递类型、快递公司 | 
|       let erp_expressCorp_Id = await this.ctx.service.common.getConfig("erp_expressCorp_Id"); | 
|       if (erp_expressCorp_Id) { | 
|         let corpInfo = await this.dbWrite.findOne(BaseExpressCorp, erp_expressCorp_Id); | 
|         if (corpInfo) { | 
|           dataInfo.expressCorp_Id = Number(erp_expressCorp_Id); | 
|           dataInfo.expressCorpName = corpInfo.expressCorpName; | 
|           dataInfo.expressCorpType = corpInfo.expressCorpType; | 
|         } | 
|       } | 
|   | 
|       // let erp_expressCorp_Id = this.ctx.service.common.getConfig("erp_expressCorp_Id"); | 
|       // if (!dataInfo.expressCorp_Id) { | 
|       //   let corpInfo = await this.dbRead.findOne(BaseExpressCorp, { | 
|       //     userProduct_Id: userInfo.userProduct_Id, | 
|       //     expressCorp_Id: Number(erp_expressCorp_Id) | 
|       //   }); | 
|       //   if (corpInfo) { | 
|       //     dataInfo.expressCorp_Id = Number(erp_expressCorp_Id); | 
|       //     dataInfo.expressCorpName = corpInfo.expressCorpName; | 
|       //     dataInfo.expressCorpType = corpInfo.expressCorpType; | 
|       //   } | 
|       // } | 
|   | 
|       await this.setAccountInfo(dataInfo); | 
|       await this.dbWrite.save(dataInfo); | 
|   | 
|       for (let detailInfo of this.body.details) { | 
|         let detail = new SaleOrderList(); | 
|         detail = Object.assign(detail, detailInfo); | 
|         detail.order_Id = dataInfo.order_Id; | 
|         await this.dbWrite.save(detail); | 
|       } | 
|   | 
|       this.info.result = true; | 
|       this.info.msg = "订单保存成功"; | 
|       this.info.data = { | 
|         order_Id: dataInfo.order_Id, | 
|         orderCode: dataInfo.orderCode | 
|       }; | 
|       let logColl = db.collection("taskLogs"); | 
|       let data = { | 
|         type: "order.add", | 
|         msg: "订单保存成功", | 
|         order_Id: dataInfo.order_Id, | 
|         orderCode: dataInfo.orderCode, | 
|         createDate: new Date() | 
|       }; | 
|       await logColl.insert(data); | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.data = error.message; | 
|       let logColl = db.collection("taskLogs"); | 
|       let data = { | 
|         type: "order.add", | 
|         msg: "推送订单失败," + error.messages, | 
|         order_Id: null, | 
|         orderCode: body.storeOrderCode, | 
|         createDate: new Date() | 
|       }; | 
|       await logColl.insert(data); | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 取消订单 | 
|   @Post() | 
|   public async cancel() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|   | 
|     try { | 
|       // 记录数据到mongodb日志中 | 
|       let db = this.app.mongodb; | 
|       let collection = db.collection("apiSaleOrderCancel"); | 
|       let mongoData = JSON.parse(JSON.stringify(body)); | 
|       mongoData.createDate = new Date(); | 
|       mongoData.userProduct_Id = userInfo.userProduct_Id; | 
|       let re = await collection.insert(mongoData); | 
|       ctx.logger.info("apiSaleOrderCancel将数据保存至MongoDB after:" + JSON.stringify(re)); | 
|     } catch {} | 
|   | 
|     try { | 
|       //#region 校验数据 | 
|       let orderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         storeOrderCode: body.storeOrderCode, | 
|         consignorCode: body.consignorCode, | 
|         userProduct_Id: userInfo.userProduct_Id | 
|       }); | 
|       if (!orderInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = "出库单不存在"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       if (["部分打包", "打包完成", "部分发运", "发运完成"].indexOf(orderInfo.statusText) >= 0) { | 
|         this.info.result = false; | 
|         this.info.msg = orderInfo.statusText + "不允许取消"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       //#endregion | 
|   | 
|       //#region 取消操作 | 
|       // 删除占位 | 
|       await this.dbWrite.delete(BaseProductPlaceHolder, { | 
|         className: "销售订单", | 
|         mainID: orderInfo.order_Id, | 
|         userProduct_Id: userInfo.userProduct_Id | 
|       }); | 
|       // 更新订单状态为:用户取消 | 
|       await this.dbWrite.update( | 
|         SaleOrder, | 
|         { | 
|           order_Id: orderInfo.order_Id | 
|         }, | 
|         { | 
|           statusID: 0, | 
|           statusText: "用户取消" | 
|         } | 
|       ); | 
|       //#endregion | 
|   | 
|       this.info.result = true; | 
|       this.info.msg = "取消成功"; | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 取消订单 - 自动回退库存 | 
|   @Post() | 
|   public async autoReturnOrder() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     let db = this.app.mongodb; | 
|   | 
|     try { | 
|       // 记录数据到mongodb日志中 | 
|       let db = this.app.mongodb; | 
|       let collection = db.collection("apiReturnOrder"); | 
|       let mongoData = JSON.parse(JSON.stringify(body)); | 
|       mongoData.createDate = new Date(); | 
|       mongoData.userProduct_Id = userInfo.userProduct_Id; | 
|       let re = await collection.insert(mongoData); | 
|       ctx.logger.info("apiReturnOrder将数据保存至MongoDB after:" + JSON.stringify(re)); | 
|     } catch {} | 
|   | 
|     try { | 
|       let order_Id = body.order_Id; | 
|       //#region 校验数据 | 
|       let orderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: body.order_Id, | 
|         userProduct_Id: userInfo.userProduct_Id | 
|       }); | 
|       if (!orderInfo) { | 
|         this.info.result = false; | 
|         this.info.msg = "出库单不存在"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|   | 
|       if (["发运完成"].indexOf(orderInfo.statusText) < 0) { | 
|         this.info.result = false; | 
|         this.info.msg = "当前状态为:" + orderInfo.statusText + ",只有发运完成的才允许做退货操作"; | 
|         ctx.body = this.info; | 
|         return; | 
|       } | 
|       //#endregion | 
|   | 
|       const connection: any = await this.dbWrite.connection; | 
|       let request = new mssql.Request(connection.driver.master); | 
|       request.input("order_Id", order_Id); | 
|       request.input("user_Id", userInfo.userProduct_Id); | 
|       request.output("outMsg", mssql.NVarChar(2000)); | 
|       let result = await request.execute("sp_Sale_Return_AutoShelve"); | 
|       let outMsg = result.output.outMsg; | 
|       if (outMsg) { | 
|         this.info.msg = outMsg; | 
|         this.info.result = false; | 
|         let logColl = db.collection("taskLogs"); | 
|         let data = { | 
|           type: "autoReturnOrder", | 
|           msg: "确认退货失败," + outMsg, | 
|           order_Id: orderInfo.order_Id, | 
|           orderCode: orderInfo.orderCode, | 
|           createDate: new Date() | 
|         }; | 
|         await logColl.insert(data); | 
|       } else { | 
|         let returnInfo = await this.dbRead.findOne(SaleReturn, { | 
|           select: ["return_Id", "returnCode"], | 
|           where: { | 
|             order_Id: order_Id | 
|           } | 
|         }); | 
|         this.info.msg = "确认退货成功"; | 
|         this.info.result = true; | 
|         this.info.data = returnInfo; | 
|         let logColl = db.collection("taskLogs"); | 
|         let data = { | 
|           type: "autoReturnOrder", | 
|           msg: "确认退货成功", | 
|           order_Id: orderInfo.order_Id, | 
|           orderCode: orderInfo.orderCode, | 
|           createDate: new Date() | 
|         }; | 
|         await logColl.insert(data); | 
|       } | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误信息:" + ex.message; | 
|     } | 
|     ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region  合并订单 | 
|   @Post() | 
|   public async addOrderMerge() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let mainOrderCode = body.mainOrderCode; | 
|     let orderIds = body.selectIDs; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     if (mainOrderCode || orderIds) { | 
|       this.info.result = false; | 
|       this.info.msg = "主订单和要合并的订单都不能为空!"; | 
|       ctx.body = this.info; | 
|     } | 
|     if (orderIds.length < 2) { | 
|       this.info.result = false; | 
|       this.info.msg = "两个以上订单才能合并!"; | 
|       ctx.body = this.info; | 
|     } | 
|     // let items = await this.dbRead.find() | 
|     let dicOriginOrderStatusID = []; | 
|     let ids: any = {}; | 
|     const items = await this.dbRead | 
|       .createQueryBuilder() | 
|       .from(SaleOrderMerge, "post") | 
|       .where({ | 
|         order_Id: In(orderIds) | 
|       }) | 
|       .getRawMany(); | 
|     if (items.length > 0) { | 
|       let orderCodes = ""; | 
|       for (let info in items) { | 
|         orderCodes += info["OrderCode"] + ","; | 
|       } | 
|       this.info.result = false; | 
|       this.info.msg = "订单" + orderCodes + "已经合并过了!"; | 
|       ctx.body = this.info; | 
|     } | 
|     try { | 
|       let mergedOrderCode = await ctx.service.common.getCodeRegular(112); | 
|       mergedOrderCode = mergedOrderCode.replace(/SO/, "MO"); | 
|       const table = await this.dbRead | 
|         .createQueryBuilder() | 
|         .select("order_Id") | 
|         .addSelect("statusID") | 
|         .from(SaleOrder, "post") | 
|         .where({ | 
|           order_Id: In(orderIds) | 
|         }) | 
|         .getRawMany(); | 
|       for (let info of table) { | 
|         ids = { | 
|           oid: info["order_Id"], | 
|           status_id: info["statusID"] | 
|         }; | 
|         dicOriginOrderStatusID.push(ids); | 
|       } | 
|   | 
|       // 合并sql | 
|       const connection: any = await this.dbWrite.connection; | 
|       let request = new mssql.Request(connection.driver.master); | 
|       request.input("MergedOrderCode", mergedOrderCode); | 
|       request.input("OrderIds", orderIds); | 
|       request.input("MainOrderCode", mainOrderCode); | 
|       request.input("User_Id", userInfo.user_Id); | 
|       request.output("outMsg", mssql.NVarChar(2000)); | 
|       let result = await request.execute("sp_Sale_OrderMerge"); | 
|       let outMsg = result.output.outMsg; | 
|       if (outMsg != null && outMsg) { | 
|         this.info.msg = outMsg; | 
|         this.info.result = false; | 
|       } | 
|       //记录订单历史状态 | 
|       let sql = `SELECT TOP 1 order_Id FROM dbo.Sale_Order WHERE OrderCode =@0 ORDER BY Order_Id DESC`; | 
|       let toOrderId = await this.dbRead.query(sql, [mergedOrderCode]); | 
|       if (!toOrderId) { | 
|         this.info.result = false; | 
|         this.info.msg = "合并失败,未知情况"; | 
|         ctx.body = this.info; | 
|       } | 
|       let toOrder = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: toOrderId[0].order_Id | 
|       }); | 
|       let orderIdArray = orderIds; | 
|       for (let fromOrderId of orderIdArray) { | 
|         let from_statusid = dicOriginOrderStatusID["fromOrderId"]; | 
|         let fromOrder = await this.dbRead.findOne(SaleOrder, { | 
|           order_Id: parseInt(fromOrderId) | 
|         }); | 
|         ctx.service.outbound.orderHelper.setStatusHistory(fromOrder.order_Id, from_statusid, 33, "订单状态", "合并订单(到" + toOrder.orderCode + ")"); | 
|         ctx.service.outbound.orderHelper.setStatusHistory(toOrder.order_Id, 0, 1, "订单状态", "合并订单(原" + fromOrder.orderCode + ")"); | 
|       } | 
|       this.info.result = true; | 
|       this.info.msg = "合并成功"; | 
|       ctx.body = this.info; | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "合并失败:" + error.message; | 
|       ctx.body = this.info; | 
|     } | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 批量关闭订单 | 
|   @Post() | 
|   public async closeOrder() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let ids = body.order_Ids; | 
|     let className = "销售订单"; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     try { | 
|       // let sql = ` Update Base_ProductPlaceHolder Set PlaceholderStorage=0 Where MainID in(select col from dbo.split(@0, ',')) And ClassName=@1; | 
|       // Update Sale_OrderList Set LackStorage=null Where Order_Id in(select col from dbo.split(@0, ',')); | 
|       // Update Sale_Order Set StatusID=37, StatusText='已关闭', SortingStatus=1, SortingDate=null, Auditing=0, | 
|       // ModifyID=@2, Modifier=@3, ModifyDate=getdate() | 
|       // Where Order_Id in(select col from dbo.split(@0, ',')); | 
|       // Update Sale_OrderList set SortingStatus=1, LackStorage=QuantityOrder Where Order_Id in(select col from dbo.split(@0, ','));`; | 
|   | 
|       // await this.dbRead.query(sql, [ids, className, userInfo.user_Id, userInfo.userTrueName]); | 
|   | 
|       await this.dbWrite | 
|         .createQueryBuilder() | 
|         .update(BaseProductPlaceHolder) | 
|         .set({ | 
|           placeholderStorage: 0 | 
|         }) | 
|         .where("MainID in(select col from dbo.split(:selectIDs, ',')) and ClassName=:className", { | 
|           selectIDs: ids, | 
|           className: className | 
|         }) | 
|         .execute(); | 
|   | 
|       await this.dbWrite | 
|         .createQueryBuilder() | 
|         .update(SaleOrderList) | 
|         .set({ | 
|           lackStorage: null, | 
|           sortingStatus: 1 | 
|         }) | 
|         .where("Order_Id in(select col from dbo.split(:selectIDs, ',')) ", { | 
|           selectIDs: ids | 
|         }) | 
|         .execute(); | 
|   | 
|       await this.dbWrite.update( | 
|         SaleOrder, | 
|         { | 
|           order_Id: In(ids) | 
|         }, | 
|         { | 
|           statusID: 37, | 
|           statusText: "已关闭", | 
|           sortingStatus: 1, | 
|           // sortingDate: null, | 
|           auditing: 0, | 
|           modifyID: userInfo.user_Id, | 
|           modifier: userInfo.userTrueName | 
|         } | 
|       ); | 
|   | 
|       this.info.result = true; | 
|       this.info.msg = "批量关闭成功"; | 
|       let orderList = await this.dbRead.find(SaleOrder, { | 
|         order_Id: In(ids) | 
|       }); | 
|       for (let orderInfo of orderList) { | 
|         await ctx.service.outbound.orderHelper.setStatusHistory(orderInfo.order_Id, orderInfo.statusID, 37, "订单状态", "订单关闭"); | 
|       } | 
|       ctx.body = this.info; | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "关闭失败:" + error.message; | 
|       ctx.body = this.info; | 
|     } | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 拆分订单 | 
|   @Post() | 
|   public async splitOrder() { | 
|     let { ctx } = this; | 
|     let userInfo = await this.userInfo; | 
|     let body = ctx.request.body; | 
|     let order_Id = body.order_Id; | 
|     let productModelList = body.productModelList; | 
|     let sql = ""; | 
|     let orderInfo = await this.dbRead.findOne(SaleOrder, { | 
|       order_Id: order_Id | 
|     }); | 
|     if (orderInfo.statusText != "待审核") { | 
|       this.info.result = false; | 
|       this.info.msg = "只有待审核的出库单才允许拆分"; | 
|       ctx.body = this.info; | 
|     } | 
|     try { | 
|       let saleOrderList = await this.dbRead.find(SaleOrderList, { | 
|         order_Id: order_Id | 
|       }); | 
|       let newOrderInfo = new SaleOrder(); | 
|       newOrderInfo = { ...orderInfo }; | 
|       if (productModelList.length > 0) { | 
|         //#region 新订单处理 | 
|         newOrderInfo.order_Id = 0; | 
|         newOrderInfo.orderCode = await ctx.service.common.getCodeRegular(112); | 
|         //拆分订单的时候,如果店铺订单号是空的,则用销售单号作为-1、-2这样的前缀 | 
|         let storeOrderCode = orderInfo.storeOrderCode ? orderInfo.storeOrderCode : orderInfo.orderCode; | 
|         let codes = storeOrderCode.split("-"); | 
|         let leftChar = ""; | 
|         if (codes.length >= 2) { | 
|           let lastNum = codes[codes.length - 1]; | 
|           if (lastNum.length <= 2) { | 
|             leftChar = storeOrderCode.replace("-" + lastNum, ""); | 
|           } else { | 
|             leftChar = storeOrderCode; | 
|           } | 
|         } else { | 
|           leftChar = storeOrderCode; | 
|         } | 
|         //查找最后的一个订单编号 | 
|         // let sqlStoreOrderCode = "SELECT TOP 1 StoreOrderCode FROM dbo.Sale_Order WHERE StoreOrderCode LIKE '" + leftChar + | 
|         //   "%' ORDER BY StoreOrderCode DESC"; | 
|         let lastOrder = await this.dbRead.findOne(SaleOrder, { | 
|           select: ["storeOrderCode"], | 
|           where: { | 
|             userProduct_Id: userInfo.userProduct_Id, | 
|             storeOrderCode: Like(`%${leftChar}%`) | 
|           }, | 
|           order: { | 
|             storeOrderCode: "DESC" | 
|           } | 
|         }); | 
|   | 
|         let lastOrderCode = ""; | 
|         if (lastOrder) { | 
|           lastOrderCode = lastOrder.storeOrderCode; | 
|         } | 
|         //如果店铺订单号是空的则用销售单号 | 
|         if (!lastOrderCode) { | 
|           lastOrderCode = orderInfo.orderCode; | 
|         } | 
|         codes = lastOrderCode.split("-"); | 
|         let newStoreOrderCode; | 
|         if (codes.length >= 2) { | 
|           let lastNum = codes[codes.length - 1]; | 
|           if (lastNum.length <= 2) { | 
|             newStoreOrderCode = lastOrderCode.substring(0, lastOrderCode.lastIndexOf("-" + lastNum)); | 
|             let c = Number(lastNum) + 1; | 
|             newStoreOrderCode += "-" + c; | 
|           } else { | 
|             newStoreOrderCode = lastOrderCode + "-1"; | 
|           } | 
|         } else { | 
|           newStoreOrderCode = lastOrderCode + "-1"; | 
|         } | 
|   | 
|         newOrderInfo.storeOrderCode = newStoreOrderCode; | 
|         newOrderInfo.statusID = orderInfo.statusID; | 
|         newOrderInfo.statusText = orderInfo.statusText; | 
|         newOrderInfo.auditDate = orderInfo.auditDate; | 
|         newOrderInfo.auditing = orderInfo.auditing; | 
|         newOrderInfo.auditor = orderInfo.auditor; | 
|         newOrderInfo.createDate = new Date(); | 
|   | 
|         newOrderInfo.sortingDate = null; | 
|         newOrderInfo.sortingStatus = 1; | 
|         await this.dbWrite.insert(SaleOrder, newOrderInfo); | 
|         let newOrder_Id = newOrderInfo.order_Id; | 
|         for (let dyn of productModelList) { | 
|           let orderList_Id = dyn.orderList_Id; | 
|           let detail = saleOrderList.filter(s => s.orderList_Id == orderList_Id)[0]; | 
|           if (dyn.quantity >= detail.quantityOrder) { | 
|             detail.order_Id = newOrderInfo.order_Id; | 
|             await this.dbWrite.update( | 
|               SaleOrderList, | 
|               { | 
|                 orderList_Id: detail.orderList_Id | 
|               }, | 
|               { | 
|                 order_Id: newOrderInfo.order_Id | 
|               } | 
|             ); | 
|           } else { | 
|             // 如果拆分的数量小于明细数量,将原来明细数量减少,同时在新订单下面新增明细 | 
|             let newdetail = new SaleOrderList(); | 
|             newdetail = { ...detail }; | 
|             newdetail.orderList_Id = 0; | 
|             newdetail.order_Id = newOrderInfo.order_Id; | 
|             newdetail.quantityOrder = dyn.quantity; | 
|             newdetail.rowTotal = dyn.quantity * newdetail.salePrice; | 
|             newdetail.subTotal = newdetail.rowTotal - newdetail.discountAmount; | 
|             await this.dbWrite.insert(SaleOrderList, newdetail); | 
|   | 
|             detail.quantityOrder -= dyn.quantity; | 
|             detail.rowTotal = detail.quantityOrder * detail.salePrice; | 
|             detail.subTotal = detail.rowTotal - detail.discountAmount; | 
|             await this.dbWrite.save(detail); | 
|           } | 
|         } | 
|         //#endregion | 
|   | 
|         //#region 新单状态的处理 | 
|         if (newOrder_Id > 0) { | 
|           sql = ` | 
|           UPDATE Sale_Order SET | 
|           TotalQuantityOrder = (SELECT SUM(QuantityOrder) FROM dbo.Sale_OrderList WHERE Order_Id = Sale_Order.Order_Id), | 
|           SubTotal = (SELECT SUM(RowTotal) FROM dbo.Sale_OrderList WHERE Order_Id = Sale_Order.Order_Id) | 
|           WHERE Order_Id IN(@0, @1); | 
|   | 
|           UPDATE Sale_Order SET | 
|             BaseTaxAmount = TaxAmount * StoreBaseRate, | 
|             BaseShippingAmount = ShippingAmount * StoreBaseRate, | 
|             BaseDiscountAmount = DiscountAmount * StoreBaseRate, | 
|             GrandTotal = SubTotal + ISNULL(ShippingAmount, 0), | 
|             BaseGrandTotal = (SubTotal + ISNULL(ShippingAmount, 0)) * StoreBaseRate, | 
|             BaseTotalPaid = TotalPaid * StoreBaseRate, | 
|             BaseTotalRefunded = TotalRefunded * StoreBaseRate, | 
|             BaseTotalCanceled = TotalCanceled * StoreBaseRate, | 
|             BaseTotalInvoiced = TotalInvoiced * StoreBaseRate, | 
|             BaseTotalOnlineRefunded = TotalOnlineRefunded * StoreBaseRate, | 
|             BaseTotalOffRefunded = TotalOffRefunded * StoreBaseRate | 
|           WHERE Order_Id IN(@0, @1);`; | 
|           await this.dbRead.query(sql, [orderInfo.order_Id, newOrder_Id]); | 
|   | 
|           this.info.result = true; | 
|           this.info.msg = "拆分成功,新单号为" + newOrderInfo.orderCode + "!"; | 
|           await ctx.service.outbound.orderHelper.setStatusHistory(orderInfo.order_Id, orderInfo.statusID, 0, "订单状态", "拆分订单"); | 
|         } else { | 
|           this.info.result = false; | 
|           this.info.msg = "拆分失败,请重试!"; | 
|         } | 
|         this.ctx.body = this.info; | 
|         //#endregion | 
|       } | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "拆分失败," + error.message; | 
|       ctx.body = this.info; | 
|     } | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 出库单明细导入Excel | 
|   /// <summary> | 
|   /// 导入Excel | 
|   /// </summary> | 
|   /// <returns></returns> | 
|   @Post() | 
|   public async detailimportExel() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     let redis = ctx.app.redis.clients.get("common"); // 将消息放入redis缓存 | 
|     let fileUrl = body.url; | 
|     redis.expire(body.key, 5 * 60); | 
|     if (!fileUrl) { | 
|       redis.rpush(body.key, "上传文件不存在"); | 
|       return; | 
|     } | 
|     try { | 
|       let rootPath = path.resolve(); // 获得根目录 | 
|       let filePath = rootPath + path.sep + fileUrl.replace(/\//gi, path.sep); // 上传文件路径 | 
|       var workbook = XLSX.readFile(filePath); //整个 excel 文档 | 
|       var sheetNames = workbook.SheetNames; //获取所有工作薄名 | 
|       var sheet1 = workbook.Sheets[sheetNames[0]]; //根据工作薄名获取工作薄 | 
|       let dataList = XLSX.utils.sheet_to_json(sheet1); // 获得当前sheet表单数据转为json格式 | 
|   | 
|       //#region 验证数据正确性 | 
|       this.info.result = true; | 
|       if (!dataList.length) { | 
|         redis.rpush(body.key, "没有可导入的数据"); | 
|         return; | 
|       } | 
|       let msg = ""; | 
|       let i = 0; | 
|       for (let row of dataList) { | 
|         i++; | 
|         let productCode = row["物料编号"]; | 
|         let productModel = row["条形码"]; | 
|         let quantity = row["预出库数量"]; | 
|         if (!productCode) { | 
|           msg += `${i}、物料编号不能为空`; | 
|           redis.rpush(body.key, msg); | 
|           this.info.result = false; | 
|         } | 
|         if (!productModel) { | 
|           msg += `${i}、条形码不能为空`; | 
|           redis.rpush(body.key, msg); | 
|           this.info.result = false; | 
|         } | 
|         if (!quantity) { | 
|           msg += `${i}、预出库数量不能为空`; | 
|           redis.rpush(body.key, msg); | 
|           this.info.result = false; | 
|         } | 
|         // #endregion | 
|   | 
|         if (msg) { | 
|           this.info.result = false; | 
|           this.info.msg = msg; | 
|         } else { | 
|           let productinfo = await this.dbRead.findOne(BaseProductInfo, { | 
|             productModel: productModel, | 
|             userProduct_Id: userInfo.userProduct_Id | 
|           }); | 
|           // 日期转换 | 
|           let produceDate = row["生产日期"]; | 
|           let d = moment(new Date(1900, 0, produceDate - 1)); | 
|           // 物料基础数据处理 | 
|           let productSpec = row["物料规格"] ? row["物料规格"] : productinfo.productSpec; | 
|           let salePrice = row["销售单价"] ? row["销售单价"] : productinfo.salePrice; | 
|           let weight = row["单位重量"] ? row["单位重量"] : productinfo.weight; | 
|           let bigUnit = row["大单位"] ? row["大单位"] : productinfo.bigUnit; | 
|           let rate = row["税率"] ? row["税率"] : productinfo.rate; | 
|           let ratePrice = row["含税价"] ? row["含税价"] : productinfo.ratePrice; | 
|           let _detail = new SaleOrderList(); | 
|           _detail.order_Id = body.order_Id; | 
|           _detail.createID = userInfo.user_Id; | 
|           _detail.creator = userInfo.userTrueName; | 
|           _detail.product_Id = productinfo.product_Id; | 
|           _detail.productCode = row["物料编号"]; | 
|           _detail.productName = productinfo.productName; | 
|           _detail.productModel = row["条形码"]; | 
|           _detail.productSpec = productSpec; | 
|           _detail.quantityOrder = row["预出库数量"]; | 
|           _detail.salePrice = salePrice; | 
|           _detail.discountRate = row["货品折扣"] ? row["货品折扣"] : 0; | 
|           _detail.discountAmount = row["优惠金额"]; | 
|           if (produceDate != null) { | 
|             _detail.produceDate = d.toDate(); | 
|           } | 
|           _detail.singleSignCode = row["定制唯一码"]; | 
|           _detail.weight = weight; | 
|           _detail.smallUnit = row["小单位"]; | 
|           _detail.bigUnit = bigUnit; | 
|           _detail.rate = rate; | 
|           _detail.ratePrice = ratePrice; | 
|           //折扣单价 | 
|           _detail.rateMoney = ratePrice * _detail.quantityOrder; | 
|           _detail.salePriceDiscount = _detail.salePrice * _detail.discountRate; | 
|           _detail.rowTotal = _detail.quantityOrder * _detail.salePrice; | 
|           _detail.subTotal = _detail.quantityOrder * _detail.salePriceDiscount; | 
|           _detail.totalWeight = _detail.quantityOrder * _detail.weight; | 
|           _detail.rowTotal = _detail.rowTotal * rate; | 
|           await this.dbWrite.insert(SaleOrderList, _detail); | 
|   | 
|           // 更新主表合计 | 
|           let sql = ` | 
|         update Sale_Order set | 
|           grandTotal=(select sum(rowTotal) from Sale_OrderList where order_Id=Sale_Order.order_Id), | 
|           totalQuantityOrder=(select sum(quantityOrder) from Sale_OrderList where order_Id=Sale_Order.order_Id), | 
|           weight=(select sum(totalWeight) from Sale_OrderList where order_Id=Sale_Order.order_Id), | 
|           totalWeight=(select sum(totalWeight) from Sale_OrderList where order_Id=Sale_Order.order_Id), | 
|           subTotal=(select sum(subTotal) from Sale_OrderList where order_Id=Sale_Order.order_Id) | 
|           where order_Id=@0; | 
|         `; | 
|           await this.dbWrite.query(sql, [body.order_Id]); | 
|         } | 
|       } | 
|       this.info.result = true; | 
|       this.info.msg = "导入成功"; | 
|     } catch (ex) { | 
|       this.info.msg = "出现异常:" + ex.message; | 
|       this.info.result = false; | 
|     } | 
|   | 
|     ctx.body = this.info; | 
|   } | 
|   | 
|   // #endregion | 
|   | 
|   //#region 一键出库 | 
|   @Post() | 
|   public async quickOut() { | 
|     let userInfo = await this.userInfo; | 
|     let body = this.ctx.request.body; | 
|     if (!isNumber(body.order_Id)) { | 
|       this.info.msg = "单据不存在"; | 
|       this.info.result = false; | 
|       this.ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     try { | 
|       const connection: any = await this.dbWrite.connection; | 
|       let request = new mssql.Request(connection.driver.master); | 
|       request.input("order_Id", body.order_Id); | 
|       request.input("user_Id", userInfo.user_Id); | 
|   | 
|       request.output("outMsg", mssql.NVarChar(2000)); | 
|       let result = await request.execute("sp_Sale_Order_AutoOut"); | 
|       let outMsg = result.output.outMsg; | 
|       if (outMsg != null && outMsg) { | 
|         this.info.msg = outMsg; | 
|         this.info.result = false; | 
|       } else { | 
|         this.info.msg = "确认出库成功"; | 
|         this.info.result = true; | 
|       } | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误:" + error.message; | 
|     } | 
|     this.ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region modifyfeeItems 修改一次性收费项 | 
|   @Post() | 
|   public async modifyfeeItems() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     //#region 修改一次性收费项 | 
|     await this.dbWrite.update( | 
|       SaleOrder, | 
|       { | 
|         order_Id: body.order_Id, | 
|         userProduct_Id: userInfo.userProduct_Id | 
|       }, | 
|       { | 
|         feeItem_Ids: body.feeItem_Ids | 
|       } | 
|     ); | 
|     this.info.result = true; | 
|     this.info.msg = "一次性收费项更新成功!"; | 
|   | 
|     ctx.body = this.info; | 
|     //#endregion | 
|   } | 
|   //#endregion | 
|   | 
|   //#region  发货信息导入 | 
|   @Post() | 
|   public async outimportExcel() { | 
|     setTimeout(async () => { | 
|       await this.importoutExcelWork(); | 
|     }, 0); | 
|   | 
|     this.info.result = true; | 
|     this.ctx.body = this.info; | 
|   } | 
|   | 
|   private async importoutExcelWork() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let startDate = new Date(); | 
|     let fileUrl = body.fileUrl; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     // let storage = null; | 
|     // let consignorList = null; | 
|     // let productlist = null; | 
|     if (!fileUrl) { | 
|       this.setMsg(`上传文件不存在`, "red"); | 
|       return; | 
|     } | 
|     try { | 
|       let rootPath = path.resolve(); // 获得根目录 | 
|       let filePath = rootPath + path.sep + fileUrl.replace(/\//gi, path.sep); // 上传文件路径 | 
|       var workbook = XLSX.readFile(filePath); //整个 excel 文档 | 
|       var sheetNames = workbook.SheetNames; //获取所有工作薄名 | 
|       var sheet1 = workbook.Sheets[sheetNames[0]]; //根据工作薄名获取工作薄 | 
|       let dataList = XLSX.utils.sheet_to_json(sheet1); // 获得当前sheet表单数据转为json格式 | 
|       this.info.result = true; | 
|       if (!dataList.length) { | 
|         this.setMsg(`没有可导入的数据`, "red"); | 
|         return; | 
|       } | 
|       let orders = await this.dbRead.find(SaleOrder, { | 
|         where: [ | 
|           { | 
|             orderCode: In(dataList.map(item => item["出库订单号"])) | 
|           }, | 
|           { | 
|             storeOrderCode: In(dataList.map(item => item["店铺订单号"])) | 
|           } | 
|         ] | 
|       }); | 
|       // 验证 | 
|       let index = 0; | 
|       for (let item of dataList) { | 
|         let _index = index + 1; | 
|         if (!item["出库订单号"]) { | 
|           if (!item["店铺订单号"]) { | 
|             this.setMsg(`第${_index}行、标黄[出库订单号、店铺订单号]不能都为空!`, "red"); | 
|           } | 
|         } | 
|         let istrue = orders.find(row => { | 
|           return row.orderCode === item["出库订单号"] || row.storeOrderCode === item["店铺订单号"]; | 
|         }); | 
|         if (!istrue) { | 
|           this.setMsg(`第${_index}行、出库订单中没有该出库单号或者该店铺订单号,请修改!`, "red"); | 
|         } | 
|         if (item["订单状态"] === "已妥投") { | 
|           if (istrue.statusText != "打包完成" && istrue.statusText != "发运完成") { | 
|             this.setMsg(`第${_index}行、只有订单状态为打包完成或者发运完成的才可妥投!`, "red"); | 
|           } | 
|         } | 
|         index++; | 
|       } | 
|       if (this.isMsgError) { | 
|         this.setMsg(`导入数据有错误,请处理好重新导入`, "red"); | 
|         this.setMsg("-1"); | 
|         return; | 
|       } | 
|       for (let row of dataList) { | 
|         let orderCode = row["出库订单号"]; | 
|         let storeOrderCode = row["店铺订单号"]; | 
|         let history = new SaleOrderStatusHistory(); | 
|         let orderinfo = orders.find(item => item.orderCode === orderCode || item.storeOrderCode === storeOrderCode); | 
|         if (row["快递单号"]) { | 
|           orderinfo.expressCode = row["快递单号"]; | 
|         } | 
|         if (row["订单状态"] == "已妥投") { | 
|           orderinfo.statusText = row["订单状态"]; | 
|         } | 
|         if (row["妥投天数"]) { | 
|           orderinfo.tuotouDays = row["妥投天数"]; | 
|         } | 
|         if (row["订单重量"]) { | 
|           orderinfo.totalWeight = row["订单重量"]; | 
|         } | 
|         history.order_Id = orderinfo.order_Id; | 
|         history.statusType = "订单状态"; | 
|         history.operationType = "信息导入"; | 
|         history.fromStatus = orderinfo.statusText; | 
|         history.fromStatusID = orderinfo.statusID; | 
|         history.toStatus = "已妥投"; | 
|         history.billCode = orderinfo.orderCode; | 
|         history.creator = userInfo.userTrueName; | 
|         // history.createDate = new Date(); | 
|         history.createDate = moment().add(-row["妥投天数"], "day").toDate(); | 
|   | 
|         await this.dbWrite.save(orderinfo); | 
|         await this.dbWrite.save(history); | 
|       } | 
|       let endDate = moment(Date.now()); | 
|       let totalSeconds = endDate.diff(startDate, "seconds"); | 
|       let msg = `导入完成,共耗时${totalSeconds}秒`; | 
|       this.setMsg(msg); | 
|     } catch (ex) { | 
|       this.setMsg("出现异常:" + ex.message, "red"); | 
|     } | 
|     this.setMsg("-1"); | 
|   } | 
|   | 
|   //#endregion | 
|   | 
|   //#region 根据货主得到门店 | 
|   @Post() | 
|   public async getShortName() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|     let dataList = await this.dbRead.find(BaseClient, { | 
|       consignorCode: body.consignorCode, | 
|       userProduct_Id: userInfo.userProduct_Id | 
|     }); | 
|     this.info.result = true; | 
|     this.info.data = dataList; | 
|     this.ctx.body = this.info; | 
|   } | 
|   | 
|   //#endregion | 
|   | 
|   //#region 获取明细页面数据 | 
|   @Post() | 
|   public async getdetailList() { | 
|     let { ctx } = this; | 
|     let body = ctx.request.body; | 
|     let userInfo = await ctx.helper.userInfo(); | 
|   | 
|     let sql = `SELECT b.productCode ,V.validQuantity,T.destinationName,T.orderType,T.OrderExit FROM Sale_Order AS T LEFT JOIN dbo.Sale_OrderList AS B ON T.order_Id = B.Order_Id LEFT JOIN vBase_ProductPositionGroup AS V ON | 
|     V.ProductCode = B.ProductCode | 
|     WHERE OrderCode = @0 and UserProduct_Id=@1`; //orderCode | 
|     let orderlinfo = await this.dbRead.query(sql, [body.orderCode, userInfo.userProduct_Id]); | 
|   | 
|     let dataList = await this.dbRead.find(BaseClient, { | 
|       consignorCode: body.consignorCode, | 
|       userProduct_Id: userInfo.userProduct_Id | 
|     }); | 
|     this.info.result = true; | 
|     this.info.data = dataList; | 
|     this.info.data2 = orderlinfo; | 
|     this.ctx.body = this.info; | 
|   } | 
|   | 
|   //#endregion | 
|   | 
|   //#region 青岛一汽一键出库 | 
|   @Post() | 
|   public async QingqiQuickOut() { | 
|     let body = this.ctx.request.body; | 
|     if (!body.id) { | 
|       this.info.msg = "单据不存在"; | 
|       this.info.result = false; | 
|       this.ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     try { | 
|       let saleOrderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: body.id | 
|       }); | 
|       let baseProductPlaceHolderList = await this.dbRead.find(BaseProductPlaceHolder, { | 
|         className: "销售订单", | 
|         code: saleOrderInfo.orderCode | 
|       }); | 
|       // 目的地是分拣区的 将订单分拣库存货位变成分拣区货位并更新单据为下架完成 | 
|       if (saleOrderInfo.destinationName === "分拣区") { | 
|         for (var holderInfo of baseProductPlaceHolderList) { | 
|           var productPositionInfo = await this.dbRead.findOne(BaseProductPosition, { | 
|             productPosition_Id: holderInfo.productPosition_Id | 
|           }); | 
|           productPositionInfo.positionName = "分拣区"; | 
|           await this.dbWrite.save(productPositionInfo); | 
|         } | 
|         saleOrderInfo.statusText = "下架完成"; | 
|         await this.dbWrite.save(saleOrderInfo); | 
|       } else { | 
|         // 目的地是其他的,出库消减库存清除占位,并更新单据为出库完成 | 
|         for (var holderInfo of baseProductPlaceHolderList) { | 
|           var productPositionInfo = await this.dbRead.findOne(BaseProductPosition, { | 
|             productPosition_Id: holderInfo.productPosition_Id | 
|           }); | 
|           // 消减库存 | 
|           productPositionInfo.productStorage = productPositionInfo.productStorage - holderInfo.placeholderStorage; | 
|           await this.dbWrite.save(productPositionInfo); | 
|           // 清除占位 | 
|           holderInfo.placeholderStorage = 0; | 
|           await this.dbWrite.save(holderInfo); | 
|         } | 
|         saleOrderInfo.statusText = "出库完成"; | 
|         await this.dbWrite.save(saleOrderInfo); | 
|         await this.dbWrite.update( | 
|           BasePlate, | 
|           { | 
|             plateCode: saleOrderInfo.plateCode | 
|           }, | 
|           { | 
|             currentArea: saleOrderInfo.storageName, | 
|             currentLocation: saleOrderInfo.destinationName, | 
|             plateState: "已出库" | 
|           } | 
|         ); | 
|       } | 
|       this.info.result = true; | 
|       this.info.msg = "一键出库完成。"; | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误:" + error.message; | 
|     } | 
|     this.ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 青岛一汽拣选更新获取明细 | 
|   @Post() | 
|   public async getOrderDetails() { | 
|     let body = this.ctx.request.body; | 
|     if (!body.order_Id) { | 
|       this.info.msg = "单据不存在"; | 
|       this.info.result = false; | 
|       this.ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     try { | 
|       let saleOrderList = await this.dbRead.find(SaleOrderList, { | 
|         order_Id: body.order_Id | 
|       }); | 
|       for (var saleOrderInfo of saleOrderList) { | 
|         // 占位 | 
|         let baseProductPlaceHolderInfo = await this.dbRead.findOne(BaseProductPlaceHolder, { | 
|           className: "销售订单", | 
|           mainID: saleOrderInfo.order_Id, | 
|           detailID: saleOrderInfo.orderList_Id | 
|         }); | 
|         saleOrderInfo.validQuantity = baseProductPlaceHolderInfo.placeholderStorage; | 
|       } | 
|       this.info.result = true; | 
|       this.info.data = saleOrderList; | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误:" + error.message; | 
|     } | 
|     this.ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 青岛一汽拣选更新提交 | 
|   @Post() | 
|   public async saveCheck() { | 
|     let body = this.ctx.request.body; | 
|     if (!body.jsonDetails) { | 
|       this.info.msg = "单据不存在"; | 
|       this.info.result = false; | 
|       this.ctx.body = this.info; | 
|       return; | 
|     } | 
|     try { | 
|       var flag = true; | 
|       for (var val of body.jsonDetails) { | 
|         let saleOrderListInfo = await this.dbRead.findOne(SaleOrderList, { | 
|           orderList_Id: val.orderList_Id | 
|         }); | 
|         // 占位 | 
|         let holderInfo = await this.dbRead.findOne(BaseProductPlaceHolder, { | 
|           className: "销售订单", | 
|           mainID: saleOrderListInfo.order_Id, | 
|           detailID: saleOrderListInfo.orderList_Id | 
|         }); | 
|         // 库存 | 
|         var productPositionInfo = await this.dbRead.findOne(BaseProductPosition, { | 
|           productPosition_Id: holderInfo.productPosition_Id | 
|         }); | 
|         // 消减库存 | 
|         productPositionInfo.productStorage = productPositionInfo.productStorage - parseInt(val.pickUpNum); | 
|         await this.dbWrite.save(productPositionInfo); | 
|         // 清除占位 | 
|         holderInfo.placeholderStorage = holderInfo.placeholderStorage - parseInt(val.pickUpNum); | 
|         await this.dbWrite.save(holderInfo); | 
|   | 
|         saleOrderListInfo.validQuantity = productPositionInfo.productStorage; | 
|         saleOrderListInfo.quantityOuted = productPositionInfo.orignStorage - productPositionInfo.productStorage; | 
|         if (saleOrderListInfo.validQuantity !== 0) { | 
|           flag = false; | 
|         } | 
|         await this.dbWrite.save(saleOrderListInfo); | 
|       } | 
|   | 
|       let saleOrderInfo = await this.dbRead.findOne(SaleOrder, { | 
|         order_Id: body.jsonDetails[0].order_Id | 
|       }); | 
|       if (flag) { | 
|         saleOrderInfo.statusText = "完全出库"; | 
|         await this.dbWrite.save(saleOrderInfo); | 
|       } else { | 
|         saleOrderInfo.statusText = "部分出库"; | 
|         await this.dbWrite.save(saleOrderInfo); | 
|       } | 
|   | 
|       this.info.result = true; | 
|       this.info.msg = "拣选更新完成"; | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误:" + error.message; | 
|     } | 
|     this.ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 青岛一汽预料回库获取明细 | 
|   @Post() | 
|   public async getBackOrderDetails() { | 
|     let body = this.ctx.request.body; | 
|     if (!body.order_Id) { | 
|       this.info.msg = "单据不存在"; | 
|       this.info.result = false; | 
|       this.ctx.body = this.info; | 
|       return; | 
|     } | 
|   | 
|     try { | 
|       let saleOrderList = await this.dbRead.find(SaleOrderList, { | 
|         order_Id: body.order_Id | 
|       }); | 
|       for (var saleOrderInfo of saleOrderList) { | 
|         // 占位 | 
|         let baseProductPlaceHolderInfo = await this.dbRead.findOne(BaseProductPlaceHolder, { | 
|           className: "销售订单", | 
|           mainID: saleOrderInfo.order_Id, | 
|           detailID: saleOrderInfo.orderList_Id | 
|         }); | 
|         saleOrderInfo.validQuantity = baseProductPlaceHolderInfo.placeholderStorage; | 
|       } | 
|       this.info.result = true; | 
|       this.info.data = saleOrderList; | 
|     } catch (error) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误:" + error.message; | 
|     } | 
|     this.ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   //#region 添加新增记录 | 
|   @Post() | 
|   public async orderLog() { | 
|     try { | 
|       let userInfo = await this.userInfo; | 
|       if (this.body.statusText === "新建" || this.body.statusText === "待下架") { | 
|         if (this.body.orderType === "出库任务") { | 
|           // 添加日志 | 
|           let userLog = new SysUserLog(); | 
|           userLog.operateType = "出库任务"; | 
|           userLog.action = "新建单号:-" + this.body.orderCode; | 
|           userLog.iP = this.ctx.request.ip; | 
|           userLog.userTrueName = userInfo.userTrueName; | 
|   | 
|           await this.setAccountInfo(userLog); | 
|           await this.dbWrite.save(userLog); | 
|         } | 
|         if (this.body.orderType === "手动出库") { | 
|           // 添加日志 | 
|           let userLog = new SysUserLog(); | 
|           userLog.operateType = "手动出库"; | 
|           userLog.action = "新建单号:-" + this.body.orderCode; | 
|           userLog.iP = this.ctx.request.ip; | 
|           userLog.userTrueName = userInfo.userTrueName; | 
|   | 
|           await this.setAccountInfo(userLog); | 
|           await this.dbWrite.save(userLog); | 
|         } | 
|   | 
|         this.info.result = true; | 
|       } | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误消息:" + ex.message; | 
|     } | 
|     this.ctx.body = this.info; | 
|   } | 
|   //#endregion | 
|   | 
|   //#region 删除 | 
|   @Post() | 
|   public async deleteOrderCode() { | 
|     try { | 
|       let userInfo = await this.userInfo; | 
|       // 根据id删除 | 
|       await this.dbWrite.delete(SaleOrder, { | 
|         order_Id: In(this.body.ids) | 
|       }); | 
|       if (this.body.orderType === "出库任务") { | 
|         // 添加日志 | 
|         let userLog = new SysUserLog(); | 
|         userLog.operateType = "出库任务"; | 
|         userLog.action = "删除单号:-" + this.body.orderCode; | 
|         userLog.iP = this.ctx.request.ip; | 
|         userLog.userTrueName = userInfo.userTrueName; | 
|   | 
|         await this.setAccountInfo(userLog); | 
|         await this.dbWrite.save(userLog); | 
|       } | 
|       if (this.body.orderType === "手动出库") { | 
|         // 添加日志 | 
|         let userLog = new SysUserLog(); | 
|         userLog.operateType = "手动出库"; | 
|         userLog.action = "删除单号:-" + this.body.orderCode; | 
|         userLog.iP = this.ctx.request.ip; | 
|         userLog.userTrueName = userInfo.userTrueName; | 
|   | 
|         await this.setAccountInfo(userLog); | 
|         await this.dbWrite.save(userLog); | 
|       } | 
|   | 
|       this.info.result = true; | 
|       this.info.msg = "删除成功!"; | 
|     } catch (ex) { | 
|       this.info.result = false; | 
|       this.info.msg = "错误消息:" + ex.message; | 
|     } | 
|     this.ctx.body = this.info; | 
|   } | 
|   //#endregion | 
| } |