//#region import
|
import BaseService from "../baseService";
|
import * as sql from "mssql";
|
import { Like } from "typeorm";
|
import moment = require("moment");
|
import { BaseProductInfo } from "../../entity/basicInfo/base/baseProductInfo";
|
import { SaleOrder } from "../../entity/outbound/sale/saleOrder";
|
import { SaleOrderList } from "../../entity/outbound/sale/saleOrderList";
|
import { SaleOuterList } from "../../entity/outbound/sale/saleOuterList";
|
import { SaleLoadBillList } from "../../entity/outbound/tms/saleLoadBillList";
|
import { SaleLoadBill } from "../../entity/outbound/tms/saleLoadBill";
|
import { SaleOuter } from "../../entity/outbound/sale/saleOuter";
|
import { BaseStorage } from "../../entity/basicInfo/base/baseStorage";
|
import { BaseProductPlaceHolder } from "../../entity/storage/storage/baseProductPlaceHolder";
|
import { BaseProductInfoImage } from "../../entity/basicInfo/base/baseProductInfoImage";
|
import { vSaleOrderPrintListGroup } from "../../entity/outbound/manufacture/vSaleOrderPrintListGroup";
|
import { SaleOrderPrint } from "../../entity/outbound/manufacture/saleOrderPrint";
|
import { SaleOrderPrintList } from "../../entity/outbound/manufacture/saleOrderPrintList";
|
import { ResultInfo } from "../../public/commonInterface";
|
import { BasePosition } from "../../entity/basicInfo/base/basePosition";
|
import { SaleOrderPicking } from "../../entity/outbound/manufacture/saleOrderPicking";
|
import { BaseConsignor } from "../../entity/basicInfo/consignor/baseConsignor";
|
//#endregion
|
|
/**
|
* 出库Service
|
*/
|
export default class OutScanService extends BaseService {
|
//#region saveScan 保存扫描结果(完全打包)
|
/**
|
* 保存扫描结果(完全打包)
|
* @param batchCode 波次号
|
* @param expressCode 快递单号
|
* @param wrapperBarcode 耗材条码List
|
* @param user_Id 用户ID
|
* @param isNoScanBatchCode 不需要扫描波次号
|
* @param weight 重量
|
*/
|
public async saveScan(
|
batchCode: string,
|
expressCode: string,
|
wrapperBarcode: string,
|
isNoScanBatchCode: boolean,
|
weight?: number
|
): Promise<ResultInfo> {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
//#region 验证
|
if (!isNoScanBatchCode && !batchCode) {
|
this.info.msg = "波次不能为空!";
|
return this.info;
|
}
|
if (!expressCode) {
|
this.info.msg = "快递单号/订单号不能为空!";
|
return this.info;
|
}
|
|
let outerModel = await this.dbRead.findOne(SaleOuter, {
|
expressCode: expressCode,
|
userProduct_Id: userInfo.userProduct_Id
|
});
|
|
if (outerModel != null) {
|
this.info.msg = "该快递单号在[打包校验]已经使用过!";
|
return this.info;
|
}
|
|
//获取订单信息
|
let orderInfo = await this.dbRead.findOne(SaleOrder, {
|
where: [
|
{ expressCode: expressCode, userProduct_Id: userInfo.userProduct_Id },
|
{ orderCode: expressCode, userProduct_Id: userInfo.userProduct_Id }
|
]
|
});
|
if (!orderInfo) {
|
this.info.msg = "波次中的明细订单在销售订单中已经不存在了,订单号:" + orderInfo.orderCode;
|
return this.info;
|
}
|
|
//#region 验证耗材是否正确
|
var wrapperBarcodeArray = wrapperBarcode.split("\n").filter(o => o);
|
for (let item of wrapperBarcodeArray) {
|
let skuInfo = await this.dbRead.findOne(BaseProductInfo, {
|
productCode: item
|
});
|
if (!skuInfo) {
|
this.info.msg = "包材[" + item + "]在物料信息中不存在,请先维护好基础数据!";
|
return this.info;
|
}
|
}
|
//#endregion
|
|
//#region 存在占位数和明细数量不相等的情况
|
let query = `/*SELECT *
|
FROM ( SELECT ISNULL(SUM(L.quantityOrder), 0) AS quantityOrder ,
|
ISNULL(( SELECT SUM(H.placeholderStorage) AS placeholderStorage
|
FROM Base_ProductPlaceHolder H
|
WHERE className = '销售订单'
|
AND H.MainID = @0
|
AND H.detailID = L.orderList_Id
|
), 0) AS placeholderStorage
|
FROM dbo.Sale_OrderList AS L
|
WHERE ( L.order_Id = @0 )
|
GROUP BY L.orderList_Id
|
HAVING ISNULL(SUM(L.quantityOrder), 0)> ISNULL(SUM(L.quantityOuted), 0)
|
) a
|
WHERE placeholderStorage <> quantityOrder
|
UNION ALL*/
|
SELECT *
|
FROM ( SELECT ISNULL(SUM(L.placeholderStorage), 0) placeholderStorage ,
|
ISNULL(( SELECT SUM(ISNULL(batchQuantity,0)-ISNULL(quantityOuted, 0)) AS quantityOrder
|
FROM dbo.Sale_OrderList
|
WHERE orderList_Id = L.detailID
|
AND order_Id = @0
|
AND ISNULL(quantityOrder, 0)> ISNULL(quantityOuted, 0)
|
), 0) AS quantityOrder
|
FROM Base_ProductPlaceHolder AS L
|
WHERE className = '销售订单'
|
AND ( L.MainID = @0 )
|
GROUP BY L.detailID
|
) a
|
WHERE placeholderStorage > quantityOrder;`;
|
let datatList = await this.dbRead.query(query, [orderInfo.order_Id]);
|
if (datatList.length > 0) {
|
this.info.msg = "分拣占位数不允许大于明细数量,不允许打包出库!";
|
this.info.result = false;
|
return this.info;
|
}
|
//#endregion
|
|
//#endregion
|
if (isNoScanBatchCode) {
|
batchCode = orderInfo.orderPrintCode;
|
}
|
if (!batchCode) {
|
this.info.msg = "订单未生成波次!";
|
return this.info;
|
}
|
|
//#region 波次号验证
|
let orderPrintInfo = await this.dbRead.findOne(SaleOrderPrint, {
|
orderPrintCode: batchCode
|
});
|
if (!orderPrintInfo) {
|
this.info.msg = "订单未生成波次,或者波次单存在问题!";
|
return this.info;
|
}
|
|
let orderPrintGroupInfo = await this.dbRead
|
.createQueryBuilder(vSaleOrderPrintListGroup, "t")
|
.where("orderPrint_Id=:orderPrint_Id AND (expressCode=:expressCode OR orderCode=:expressCode)", {
|
orderPrint_Id: orderPrintInfo.orderPrint_Id,
|
expressCode: expressCode
|
})
|
.getOne();
|
if (!orderPrintGroupInfo) {
|
this.info.msg = "该波次下不存在该快递单!";
|
return this.info;
|
}
|
if ((orderPrintGroupInfo.quantityOuter || 0) - (orderPrintGroupInfo.quantityOrder || 0) - (orderPrintGroupInfo.freezeQuanity || 0) >= 0) {
|
this.info.msg = "该订单已经打包完成!";
|
return this.info;
|
}
|
if ((orderPrintGroupInfo.quantityOuter || 0) > 0) {
|
this.info.msg = "该订单已经部分打包,不能使用完全出库,请继续使用部分打包!";
|
return this.info;
|
}
|
//#endregion
|
|
//#region 保存
|
let saleOuterInfo = new SaleOuter();
|
saleOuterInfo.consignor_Id = orderInfo.consignor_Id;
|
saleOuterInfo.consignorCode = orderInfo.consignorCode;
|
saleOuterInfo.consignorName = orderInfo.consignorName;
|
saleOuterInfo.expressCorp_Id = orderInfo.expressCorp_Id;
|
saleOuterInfo.expressCorpName = orderInfo.expressCorpName;
|
saleOuterInfo.expressCode = orderInfo.expressCode;
|
saleOuterInfo.client_Id = orderInfo.client_Id || 0;
|
saleOuterInfo.clientCode = orderInfo.clientCode;
|
saleOuterInfo.clientShortName = orderInfo.clientShortName;
|
|
saleOuterInfo.orderType = "订单打包";
|
saleOuterInfo.order_Id = orderInfo.order_Id;
|
saleOuterInfo.orderCode = orderInfo.orderCode;
|
saleOuterInfo.storeOrderCode = orderInfo.storeOrderCode;
|
saleOuterInfo.shippingName = orderInfo.shippingName;
|
saleOuterInfo.shippingAddress = orderInfo.shippingAddress;
|
saleOuterInfo.mobile = orderInfo.mobile;
|
|
saleOuterInfo.storage_Id = orderInfo.storage_Id || 0;
|
saleOuterInfo.storageName = orderInfo.storageName;
|
saleOuterInfo.user_Id = userInfo.user_Id;
|
saleOuterInfo.userTrueName = userInfo.userTrueName;
|
saleOuterInfo.dept_Id = userInfo.dept_Id;
|
saleOuterInfo.deptName = userInfo.deptName;
|
saleOuterInfo.applyDate = new Date();
|
saleOuterInfo.totalQuantityOrder = orderInfo.totalQuantityOrder;
|
saleOuterInfo.createID = userInfo.user_Id;
|
saleOuterInfo.creator = userInfo.userTrueName;
|
saleOuterInfo.createDate = new Date();
|
|
saleOuterInfo.orderPrint_Id = orderInfo.orderPrint_Id;
|
saleOuterInfo.orderPrintCode = orderInfo.orderPrintCode;
|
|
let outerCode = await ctx.service.common.getCodeRegular(268);
|
saleOuterInfo.outerCode = outerCode;
|
saleOuterInfo.weight = weight;
|
await this.dbWrite.save(saleOuterInfo);
|
|
//插入明细
|
query = `INSERT INTO dbo.Sale_OuterList
|
( outer_Id ,
|
order_Id ,
|
orderList_Id ,
|
product_Id ,
|
productCode ,
|
productName ,
|
productModel ,
|
productSpec ,
|
quantityOrder ,
|
purchasePrice ,
|
subTotal ,
|
createID ,
|
creator ,
|
createDate,
|
batchNumber
|
)
|
SELECT ${saleOuterInfo.outer_Id},order_Id,orderList_Id,l.product_Id,l.productCode,l.productName,l.productModel,l.productSpec,l.quantityOrder,
|
s.purchasePrice,s.purchasePrice*l.quantityOrder,${userInfo.user_Id},'${userInfo.userTrueName}',GETDATE(),l.batchNumber
|
FROM dbo.Sale_OrderPrintList AS l INNER JOIN dbo.Base_ProductInfo s
|
ON l.product_Id=s.product_Id
|
WHERE l.order_Id=${orderInfo.order_Id} AND l.orderPrint_Id=${orderPrintInfo.orderPrint_Id};`;
|
if (wrapperBarcodeArray.length > 0) {
|
let where = "'" + wrapperBarcodeArray.join(",") + "'";
|
//插入耗材
|
query += `INSERT INTO dbo.Sale_OuterWrapper
|
( outer_Id ,
|
order_Id ,
|
product_Id ,
|
productCode ,
|
productName ,
|
productModel ,
|
productSpec ,
|
quantity ,
|
purchasePrice ,
|
subTotal ,
|
createID ,
|
creator ,
|
createDate
|
)
|
SELECT ${saleOuterInfo.outer_Id}, ${orderInfo.order_Id},s.product_Id,s.productCode,s.productName,s.productModel,s.productSpec,1,s.purchasePrice,s.purchasePrice,0,'',GETDATE()
|
FROM [dbo].[Func_SplitStrToTable](${where}) AS v
|
INNER JOIN dbo.Base_ProductInfo s ON v.col=s.productModel;`;
|
}
|
query += `
|
UPDATE dbo.Sale_Outer SET
|
totalQuantityOrder=(SELECT SUM(ISNULL(quantityOrder,0)) FROM dbo.Sale_OuterList WHERE outer_Id=SaleOuter.outer_Id),
|
subTotal=(SELECT SUM(ISNULL(subTotal,0)) FROM dbo.Sale_OuterList WHERE outer_Id=SaleOuter.outer_Id)
|
WHERE dbo.Sale_Outer.outer_Id=${saleOuterInfo.outer_Id}`;
|
await this.dbWrite.query(query);
|
//#endregion
|
|
//#region 审核, 确认打包
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("outer_Id", saleOuterInfo.outer_Id);
|
request.input("user_Id", userInfo.user_Id);
|
let result = await request.execute("sp_SaleOuter_Check");
|
|
ctx.service.outbound.orderHelper.setStatusHistory(orderInfo.order_Id, 9, 11, "订单状态", "订单打包");
|
//#endregion
|
|
//#region 返回结果
|
if (result.returnValue == 0) {
|
orderInfo = await this.dbRead.findOne(SaleOrder, orderInfo.order_Id);
|
|
var isOrderPrintFinish = orderPrintInfo.unFinishedCount == 0 ? 1 : 0;
|
var isOrderFinish = orderInfo.statusID == 11 ? 1 : 0; //打包完成
|
this.info.result = true;
|
var data = {
|
orderPrint_Id: orderPrintInfo.orderPrint_Id,
|
order_Id: orderInfo.order_Id,
|
isOrderPrintFinish: isOrderPrintFinish,
|
isOrderFinish: isOrderFinish,
|
outer_Id: saleOuterInfo.outer_Id
|
};
|
this.info.data = data;
|
} else {
|
this.info.result = false;
|
}
|
//#endregion
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region partialSaveScan 部分打包
|
/**
|
* 部分打包
|
* @param batchCode 波次号
|
* @param expressCode 快递单号/订单号
|
* @param wrapperBarcode 包材条码
|
* @param newExpressCode 新单快递单号
|
* @param list 明细List
|
* @param user_Id 用户ID
|
* @param isNoScanBatchCode 不需要扫描波次号
|
* @param weight 重量
|
*/
|
public async partialSaveScan(
|
batchCode: string,
|
expressCode: string,
|
wrapperBarcode: string,
|
newExpressCode: string,
|
list: Array<any>,
|
isNoScanBatchCode: boolean,
|
weight?: number
|
): Promise<ResultInfo> {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
let query = "";
|
|
//获取订单信息
|
let orderInfo = await this.dbRead
|
.createQueryBuilder(SaleOrder, "t")
|
.where("(expressCode=:expressCode OR orderCode=:expressCode) AND userProduct_Id=:userProduct_Id", {
|
expressCode: expressCode,
|
userProduct_Id: userInfo.userProduct_Id
|
})
|
.getOne();
|
if (!orderInfo) {
|
this.info.msg = "波次中的明细订单在销售订单中已经不存在了,订单号:" + orderInfo.orderCode;
|
return this.info;
|
}
|
if ("审核成功,等待打包,波次完成,等待配货,配货中,部分打包,改变物流,部分发运".split(",").indexOf(orderInfo.statusText) < 0) {
|
this.info.msg = orderInfo.orderCode + "订单不允许操作,订单状态为:" + orderInfo.statusText;
|
return this.info;
|
}
|
if (isNoScanBatchCode) {
|
batchCode = orderInfo.orderPrintCode;
|
}
|
|
//#region 校验
|
if (isNoScanBatchCode && !batchCode) {
|
this.info.msg = "波次不能为空!";
|
return this.info;
|
}
|
if (!expressCode) {
|
this.info.msg = "快递单号不能为空!";
|
return this.info;
|
}
|
|
if (!list || list.length == 0) {
|
this.info.msg = "请先扫描条码!";
|
return this.info;
|
}
|
|
let orderPrintInfo = await this.dbRead.findOne(SaleOrderPrint, {
|
orderPrintCode: batchCode,
|
userProduct_Id: userInfo.userProduct_Id
|
});
|
if (!orderPrintInfo) {
|
this.info.msg = "波次不存在!";
|
return this.info;
|
}
|
let printList = await this.dbRead
|
.createQueryBuilder(vSaleOrderPrintListGroup, "t")
|
.where("orderPrint_Id=:orderPrint_Id AND (expressCode=:expressCode OR orderCode=:expressCode)", {
|
orderPrint_Id: orderPrintInfo.orderPrint_Id,
|
expressCode: expressCode
|
})
|
.getOne();
|
|
if (!printList) {
|
this.info.msg = "该波次下不存在该订单!";
|
return this.info;
|
}
|
if ((printList.quantityOuter || 0) - (printList.quantityOrder || 0) - (printList.freezeQuanity || 0) >= 0) {
|
this.info.msg = "该订单已经打包完成!";
|
return this.info;
|
}
|
|
//if (printList.expressCode.IsNullOrEmpty())
|
//{
|
// this.info.msg = "该波次还未生成快递单号,不能打包!";
|
// return this.info;
|
//}
|
//用销售订单的快递单号,因为 可能更改了销售订单的快递单号,但是 波次明细的是改不了的
|
var Outer_ExpressCode = await ctx.service.common.getConfigBool("Outer_ExpressCode"); //启用快递单号校验
|
var _expressCode = newExpressCode || orderInfo.expressCode;
|
if (Outer_ExpressCode && _expressCode) {
|
let outerModel = await this.dbRead.findOne(SaleOuter, {
|
expressCode: expressCode
|
});
|
if (!outerModel) {
|
this.info.msg = "该快递单号[" + _expressCode + "]在[打包校验]已经使用过!";
|
return this.info;
|
}
|
}
|
|
//验证耗材是否正确
|
if (wrapperBarcode) {
|
var wrapperBarcodeArray = wrapperBarcode.replace(/,;/gi, "\n").split("\n");
|
if (wrapperBarcodeArray && wrapperBarcodeArray.length > 0) {
|
let where = "'" + wrapperBarcodeArray.join(",") + "'";
|
query = `SELECT TOP 1 v.col FROM [dbo].[Func_SplitStrToTable](${where}) AS v
|
WHERE NOT EXISTS(
|
SELECT * FROM dbo.Base_ProductInfo WHERE productModel=v.col
|
)`;
|
let notExistsSku = await this.dbRead.query(query);
|
if (notExistsSku && notExistsSku.length) {
|
this.info.result = false;
|
this.info.msg = "包材[" + notExistsSku[0].col + "]在物料信息中不存在,请先维护好基础数据!";
|
return this.info;
|
}
|
}
|
}
|
|
//判断出库的物料数量是否大于可以出库的数量
|
let isExistsSql = "";
|
for (var model of list) {
|
var orderList_Id = model.orderList_Id;
|
var scanCount = model.scanCount;
|
if (isExistsSql) {
|
isExistsSql += " UNION ";
|
}
|
isExistsSql += ` SELECT productCode,( SUM(quantityOrder) - ISNULL(SUM(quantityOuter), 0) ) AS enableQty,
|
${scanCount} AS currentQty FROM dbo.Sale_OrderPrintList WHERE /*orderPrint_Id=${orderPrintInfo.orderPrint_Id}
|
AND*/ orderList_Id=${orderList_Id} GROUP BY productCode having (SUM(quantityOrder) - ISNULL(SUM(quantityOuter), 0)-" + scanCount + ")<0`;
|
}
|
isExistsSql = "SELECT productCode,enableQty,currentQty FROM ( " + isExistsSql + " ) AS v";
|
let table = await this.dbRead.query(query);
|
if (table != null && table.length > 0) {
|
let row = table[0];
|
this.info.msg = "物料[" + row["productCode"] + "]的可出库数量[" + row["enableQty"] + "]小于当前的出库数量[" + row["currentQty"] + "]!";
|
return this.info;
|
}
|
|
//#region 存在占位数和明细数量不相等的情况
|
query = `SELECT *
|
FROM ( SELECT ISNULL(SUM(L.batchQuantity), 0)-SUM(ISNULL(L.quantityOuted, 0)) AS batchQuantity ,
|
ISNULL(( SELECT SUM(H.placeholderStorage) AS placeholderStorage
|
FROM Base_ProductPlaceHolder H
|
WHERE className = '销售订单'
|
AND H.MainID = @0
|
AND H.detailID = L.orderList_Id
|
), 0) AS placeholderStorage
|
FROM dbo.Sale_OrderList AS L
|
WHERE ( L.order_Id = @0 )
|
GROUP BY L.orderList_Id
|
HAVING ISNULL(SUM(L.batchQuantity), 0)> ISNULL(SUM(L.quantityOuted), 0)
|
) a
|
WHERE placeholderStorage <> batchQuantity
|
UNION ALL
|
SELECT *
|
FROM ( SELECT ISNULL(SUM(L.placeholderStorage), 0) placeholderStorage ,
|
( SELECT SUM(ISNULL(batchQuantity,0))-SUM(ISNULL(quantityOuted,0)) AS batchQuantity
|
FROM dbo.Sale_OrderList
|
WHERE orderList_Id = L.detailID
|
AND order_Id = @0
|
AND ISNULL(batchQuantity, 0)> ISNULL(quantityOuted, 0)
|
) AS batchQuantity
|
FROM Base_ProductPlaceHolder AS L
|
WHERE className = '销售订单'
|
AND ( L.MainID = @0 )
|
GROUP BY L.detailID
|
) a
|
WHERE placeholderStorage <> batchQuantity;`;
|
let dataList = await this.dbRead.query(query, [orderInfo.order_Id]);
|
if (dataList.length) {
|
this.info.msg = "分拣占位数和明细数量不相等的情况,不允许打包出库!";
|
this.info.result = false;
|
return this.info;
|
}
|
//#endregion
|
//#endregion
|
|
//#region 保存
|
let saleOuter = new SaleOuter();
|
saleOuter.consignor_Id = orderInfo.consignor_Id;
|
saleOuter.consignorCode = orderInfo.consignorCode;
|
saleOuter.consignorName = orderInfo.consignorName;
|
saleOuter.expressCorp_Id = orderInfo.expressCorp_Id;
|
saleOuter.expressCorpName = orderInfo.expressCorpName;
|
saleOuter.expressCode = _expressCode; //使用新的快递单号
|
saleOuter.client_Id = orderInfo.client_Id || 0;
|
saleOuter.clientCode = orderInfo.clientCode;
|
saleOuter.clientShortName = orderInfo.clientShortName;
|
|
saleOuter.orderType = "订单打包";
|
saleOuter.order_Id = orderInfo.order_Id;
|
saleOuter.orderCode = orderInfo.orderCode;
|
saleOuter.storeOrderCode = orderInfo.storeOrderCode;
|
saleOuter.shippingName = orderInfo.shippingName;
|
saleOuter.shippingAddress = orderInfo.shippingAddress;
|
saleOuter.mobile = orderInfo.mobile;
|
|
saleOuter.storage_Id = orderInfo.storage_Id || 0;
|
saleOuter.storageName = orderInfo.storageName;
|
saleOuter.user_Id = userInfo.user_Id;
|
saleOuter.userTrueName = userInfo.userTrueName;
|
saleOuter.dept_Id = userInfo.dept_Id;
|
saleOuter.deptName = userInfo.deptName;
|
saleOuter.applyDate = new Date();
|
saleOuter.createID = userInfo.user_Id;
|
saleOuter.creator = userInfo.userTrueName;
|
|
saleOuter.orderPrint_Id = orderInfo.orderPrint_Id;
|
saleOuter.orderPrintCode = orderInfo.orderPrintCode;
|
saleOuter.createDate = new Date();
|
let outerCode = await ctx.service.common.getCodeRegular(268);
|
saleOuter.outerCode = outerCode;
|
if (weight != 0) {
|
saleOuter.weight = weight;
|
}
|
await this.setAccountInfo(saleOuter);
|
await this.dbWrite.save(saleOuter);
|
//遍历扫描的明细物料,插入到 打包出库表
|
for (var model of list) {
|
var orderList_Id = model.orderList_Id;
|
var scanCount = model.scanCount;
|
//插入明细
|
let orderDetail = await this.dbRead.findOne(SaleOrderList, model.orderList_Id);
|
let outerDetail = new SaleOuterList();
|
outerDetail.batchNumber = orderDetail.batchNumber;
|
outerDetail.createDate = new Date();
|
outerDetail.createID = userInfo.user_Id;
|
outerDetail.creator = userInfo.userTrueName;
|
|
outerDetail.order_Id = orderDetail.order_Id;
|
outerDetail.orderCode = model.orderCode;
|
outerDetail.orderList_Id = orderDetail.orderList_Id;
|
outerDetail.outer_Id = saleOuter.outer_Id;
|
outerDetail.product_Id = orderDetail.product_Id;
|
outerDetail.productCode = orderDetail.productCode;
|
outerDetail.productModel = orderDetail.productModel;
|
outerDetail.productName = orderDetail.productName;
|
outerDetail.productSpec = orderDetail.productSpec;
|
outerDetail.quantityOrder = model.scanCount;
|
|
outerDetail.salePrice = orderDetail.salePrice;
|
outerDetail.subTotal = orderDetail.subTotal;
|
outerDetail.caseNumber = model.caseNumber;
|
outerDetail.smallUnit = orderDetail.smallUnit;
|
outerDetail.bigUnit = orderDetail.bigUnit;
|
|
outerDetail.order_Id = orderInfo.order_Id;
|
outerDetail.orderCode = orderInfo.orderCode;
|
outerDetail.weight = model.weight;
|
outerDetail.totalWeight = model.ScanWeight;
|
await this.dbWrite.save(outerDetail);
|
}
|
|
query = "";
|
if (wrapperBarcode) {
|
var wrapperBarcodeArray = wrapperBarcode.replace(/,;/gi, "\n").split("\n");
|
if (wrapperBarcodeArray && wrapperBarcodeArray.length > 0) {
|
let where = "'" + wrapperBarcodeArray.join(",") + "'";
|
//插入耗材
|
query += `INSERT INTO dbo.Sale_OuterWrapper
|
( outer_Id ,
|
order_Id ,
|
product_Id ,
|
productCode ,
|
productName ,
|
productModel ,
|
productSpec ,
|
quantity ,
|
purchasePrice ,
|
subTotal ,
|
createID ,
|
creator ,
|
createDate
|
)
|
SELECT ${saleOuter.outer_Id}, @0,s.product_Id,s.productCode,s.productName,s.productModel,s.productSpec,1,s.purchasePrice,s.purchasePrice,0,'',GETDATE()
|
FROM [dbo].[Func_SplitStrToTable](${where}) AS v
|
INNER JOIN dbo.Base_ProductInfo s ON v.col=s.productModel;`;
|
}
|
}
|
query += `UPDATE dbo.Sale_Outer SET subTotal=(SELECT SUM(ISNULL(subTotal,0)) FROM dbo.Sale_OuterList WHERE outer_Id=Sale_Outer.outer_Id),
|
totalQuantityOrder=(SELECT SUM(ISNULL(quantityOrder,0)) FROM dbo.Sale_OuterList WHERE outer_Id=Sale_Outer.outer_Id),
|
totalWeight = (SELECT SUM(ISNULL(weight,0)) FROM dbo.Sale_OuterList WHERE outer_Id=Sale_Outer.outer_Id)
|
WHERE dbo.Sale_Outer.outer_Id=${saleOuter.outer_Id}`;
|
|
await this.dbWrite.query(query, [orderInfo.order_Id]);
|
|
//#region 判断是否部分打包操作
|
//不是部分打包设置,不允许部分出库
|
if (!(await ctx.service.common.getConfigBool("outer_BatchPartialCheck"))) {
|
query = `
|
SELECT * FROM (
|
SELECT quantityOrder, ISNULL((SELECT SUM(L.quantityOrder)
|
FROM dbo.Sale_OuterList L WHERE L.orderList_Id=OL.orderList_Id), 0) AS quantityOuted
|
FROM Sale_OrderList OL
|
WHERE order_Id= @0
|
) t
|
WHERE t.quantityOrder<> t.quantityOuted
|
`;
|
let dataList = await this.dbRead.query(query, [orderInfo.order_Id]);
|
if (dataList && dataList.length) {
|
this.info.msg = "不允许部分打包出库!";
|
this.info.result = false;
|
await this.dbWrite.delete(SaleOuter, {
|
outer_Id: saleOuter.outer_Id
|
});
|
return this.info;
|
}
|
}
|
//#endregion
|
|
//#region 判断是否部分打包操作
|
// 根据配送类型为城配或者省配的按出库订单和扫描结果在tms中生成运单
|
// 模块 快速发货校验
|
// let expandFields = JSON.parse(orderInfo.expandFields); // 转换为代码执行
|
// // // 省际 生成运单 发货库存
|
// if (expandFields["distributionType"] === "省际") {
|
// var tMSBill = new TMSWayBill();
|
// tMSBill.relationCode = orderInfo.orderCode;
|
// //发货方信息
|
// tMSBill.mailCustomer = orderInfo.consignorName;
|
// tMSBill.billingName = orderInfo.billingName;
|
// tMSBill.billingMobile = orderInfo.billingTel;
|
// tMSBill.billingAddress = orderInfo.billingAddress;
|
|
// // 收货方信息
|
// tMSBill.consigneeMobile = orderInfo.mobile;
|
// tMSBill.consigneeName = orderInfo.shippingName;
|
// tMSBill.consigneeAddress = orderInfo.shippingAddress;
|
// tMSBill.provinceName = orderInfo.provinceName; //省
|
// tMSBill.cityName = orderInfo.cityName; //市
|
// tMSBill.regionName = orderInfo.regionName; //区
|
|
// // 费用信息
|
// tMSBill.totalFreight = orderInfo.shippingAmount;
|
// tMSBill.totalWeight = orderInfo.totalWeight;
|
// tMSBill.value = orderInfo.subTotal;
|
|
// tMSBill.wayBillType = "仓配单";
|
// tMSBill.orderStatus = "已入库";
|
// tMSBill.storageName = orderInfo.storageName;
|
// tMSBill.consignorName = orderInfo.consignorName;
|
// tMSBill.wayBillCode = await ctx.service.common.getCodeRegular(499);
|
// tMSBill.orderType = orderInfo.orderType;
|
// tMSBill.totalQuantityOrder = orderInfo.totalQuantityOrder;
|
// tMSBill.totalWeight = orderInfo.totalWeight;
|
// tMSBill.grandTotal = orderInfo.grandTotal;
|
// tMSBill.consigneeName = orderInfo.shippingName;
|
// tMSBill.auditing = 2;
|
// await this.setAccountInfo(tMSBill);
|
// await this.dbWrite.save(tMSBill);
|
// const tmsList = await this.dbRead.find(SaleOrderList, {
|
// where: {
|
// userProduct_Id: userInfo.userProduct_Id,
|
// order_Id: orderInfo.order_Id
|
// }
|
// });
|
// for (const item of tmsList) {
|
// const tMSWayBillList = new TMSWayBillList();
|
// tMSWayBillList.wayBill_Id = tMSBill.wayBill_Id;
|
// tMSWayBillList.productCode = item.productCode;
|
// tMSWayBillList.productName = item.productName;
|
// // tMSWayBillList.statsDetail = "明细状态";
|
// tMSWayBillList.productSpec = item.productSpec;
|
// tMSWayBillList.quantityOrder = item.quantityOrder;
|
// tMSWayBillList.weight = item.weight;
|
// tMSWayBillList.totalWeight = item.totalWeight;
|
// await this.dbWrite.save(tMSWayBillList);
|
// }
|
// }
|
// if (expandFields["distributionType"] === "城配") {
|
// var tMSBill = new TMSWayBill();
|
// tMSBill.relationCode = orderInfo.orderCode;
|
// tMSBill.wayBillType = "仓配单";
|
// tMSBill.orderStatus = "待配送"; //运单状态
|
// tMSBill.storageName = orderInfo.storageName;
|
// tMSBill.consignorName = orderInfo.consignorName;
|
// tMSBill.wayBillCode = await ctx.service.common.getCodeRegular(499);
|
// tMSBill.orderType = orderInfo.orderType;
|
// tMSBill.totalQuantityOrder = orderInfo.totalQuantityOrder;
|
// tMSBill.totalWeight = orderInfo.totalWeight;
|
// tMSBill.grandTotal = orderInfo.grandTotal;
|
// tMSBill.consigneeName = orderInfo.shippingName;
|
// tMSBill.auditing = 2;
|
// await this.setAccountInfo(tMSBill);
|
// await this.dbWrite.save(tMSBill);
|
// const tmsList = await this.dbRead.find(SaleOrderList, {
|
// where: {
|
// userProduct_Id: userInfo.userProduct_Id,
|
// order_Id: orderInfo.order_Id
|
// }
|
// });
|
// for (const item of tmsList) {
|
// const tMSWayBillList = new TMSWayBillList();
|
// tMSWayBillList.wayBill_Id = tMSBill.wayBill_Id;
|
// tMSWayBillList.productCode = item.productCode;
|
// tMSWayBillList.productName = item.productName;
|
// // tMSWayBillList.statsDetail = "明细状态";
|
// tMSWayBillList.productSpec = item.productSpec;
|
// tMSWayBillList.quantityOrder = item.quantityOrder;
|
// tMSWayBillList.weight = item.weight;
|
// tMSWayBillList.totalWeight = item.totalWeight;
|
// await this.dbWrite.save(tMSWayBillList);
|
// }
|
// }
|
//#endregion
|
|
//#endregion
|
|
//#region 审核
|
let fromStatusId = orderInfo.statusID || 0;
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("outer_Id", saleOuter.outer_Id);
|
request.input("user_Id", userInfo.userProduct_Id);
|
request.input("menu_Id", 268);
|
await request.execute("sp_Sale_OuterPartial_Check");
|
|
//有可能是打包完成 ,有可能是部分打包,所以要从新查询出状态
|
orderInfo = await this.dbRead.findOne(SaleOrder, orderInfo.order_Id);
|
let toStatusId = orderInfo.statusID;
|
ctx.service.outbound.orderHelper.setStatusHistory(orderInfo.order_Id, fromStatusId, toStatusId, "订单状态", "订单打包");
|
|
//更新订单快递单号
|
if (newExpressCode) {
|
await this.dbWrite.update(SaleOrder, orderInfo.order_Id, {
|
expressCode: newExpressCode
|
});
|
}
|
//#endregion
|
|
//#region 获取剩余未扫描的数据
|
this.info.result = true;
|
this.info.msg = "打包成功";
|
//#endregion
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region GetData 获取快递单对应的销售订单的信息
|
/**
|
* 获取快递单对应的销售订单的信息
|
* @param expressCode 快单号或订单号
|
* @param batchCode 波次号
|
* @param isNoScanBatchCode 不需要扫描波次号
|
*/
|
public async getData(expressCode: string, batchCode: string, isNoScanBatchCode: boolean) {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
//也可以是 销售订单号,因为有可能生成波次以后,没有打印面单,所以扫描不了快递单号,
|
//但是打印了捡配单,可以扫描销售单号
|
|
try {
|
if (isNoScanBatchCode) {
|
//#region 不需要扫描波次号
|
if (!expressCode) {
|
this.info.msg = "快递单号/订单号都不能为空!";
|
return this.info;
|
}
|
//需要同时扫描订单号和快递单号
|
let where: any,
|
paras: any = {};
|
if (await ctx.service.common.getConfigBool("Outer_OutScanExpressAndOrder")) {
|
where = `Exists
|
(
|
Select order_Id from Sale_Order
|
Where userProduct_Id=:userProduct_Id /*statusText in('波次完成', '等待打包', '打包中', '部分打包') And */
|
And SortingStatus in(2, 5)/*2=已分配, 5=部分分配*/
|
And order_Id=t.order_Id And (expressCode=:expressCode And (orderCode=:expressCode OR storeOrderCode=:expressCode))
|
) AND batchQuantity - ISNULL(quantityOuted, 0)>0`;
|
paras.expressCode = expressCode;
|
paras.userProduct_Id = userInfo.userProduct_Id;
|
} else {
|
where = `Exists
|
(
|
Select order_Id from Sale_Order
|
Where userProduct_Id=:userProduct_Id /*statusText in('波次完成', '等待打包', '打包中', '部分打包') And */
|
And SortingStatus in(2, 5)/*2=已分配, 5=部分分配*/
|
And order_Id=t.order_Id And (expressCode=:expressCode OR orderCode=:expressCode)
|
) AND batchQuantity - ISNULL(quantityOuted, 0)>0`;
|
paras.expressCode = expressCode;
|
paras.userProduct_Id = userInfo.userProduct_Id;
|
}
|
|
// 订单信息
|
let orderInfo = await this.dbRead.findOne(SaleOrder, {
|
userProduct_Id: userInfo.userProduct_Id,
|
orderCode: expressCode
|
});
|
|
let orderDetailList = await this.dbRead.createQueryBuilder(SaleOrderList, "t").where(where, paras).getMany();
|
if (!orderDetailList || orderDetailList.length == 0) {
|
this.info.msg = "该单号下不存在需要扫描的明细!";
|
this.info.result = false;
|
return this.info;
|
}
|
// 对单据进行分组
|
let groupList = orderDetailList.reduce(
|
(all: Array<any>, next) => (all.some(item => item["order_Id"] == next["order_Id"]) ? all : [...all, next]),
|
[]
|
);
|
|
if (groupList.length > 1) {
|
this.info.msg = "快递单号重复了,请修改快递单号!";
|
this.info.result = false;
|
return this.info;
|
}
|
let orderDetailInfo = groupList[0];
|
let sql = `
|
SELECT COUNT(DISTINCT orderPrint_Id) AS cnt FROM dbo.Sale_OrderPrintList
|
WHERE order_Id=${orderDetailInfo.order_Id}
|
HAVING COUNT(DISTINCT orderPrint_Id)>1
|
`;
|
let dataInfo = await this.dbRead.query(sql);
|
if (dataInfo && dataInfo.cnt > 0) {
|
this.info.msg = "改订单已经生成多个波次单,不允许按单出库,请使用波次打包出库!";
|
this.info.result = false;
|
return this.info;
|
}
|
|
let printDetailList = await this.dbRead.find(SaleOrderPrintList, {
|
order_Id: orderDetailInfo.order_Id
|
});
|
|
let list: Array<any> = [];
|
for (var row of orderDetailList) {
|
let detialInfo = printDetailList.find(w => w.orderList_Id == row.orderList_Id);
|
let orderCode = detialInfo.orderCode;
|
|
let total: any = printDetailList
|
.filter(w => w.orderList_Id == row.orderList_Id)
|
.reduce(
|
(totalItem: any, currItem) => {
|
totalItem.freezeQuanity += currItem.freezeQuanity;
|
|
return totalItem;
|
},
|
{ freezeQuanity: 0 }
|
);
|
|
var pInfo = await this.dbRead.findOne(BaseProductInfo, row.product_Id);
|
var newData = {
|
productModel: row.productModel,
|
quantityOrder: row.batchQuantity || 0 - row.quantityOuted || 0 - total.freezeQuanity || 0,
|
productCode: row.productCode,
|
productSpec: row.productSpec,
|
productName: row.productName,
|
quantityOuter: row.quantityOuted || 0,
|
salePrice: row.salePrice || 0,
|
orderList_Id: row.orderList_Id,
|
order_Id: row.order_Id,
|
orderCode: orderCode,
|
relationCode: pInfo.relationCode,
|
relationCode2: pInfo.relationCode2,
|
relationCode3: pInfo.relationCode3,
|
relationCode4: pInfo.relationCode4,
|
relationCode5: pInfo.relationCode5,
|
middleBarcode: pInfo.middleBarcode,
|
middleUnitConvert: pInfo.middleUnitConvert,
|
bigBarcode: pInfo.bigBarcode,
|
unitConvert: pInfo.unitConvert,
|
weight: row.weight,
|
totalWeight: row.totalWeight
|
};
|
if (newData.quantityOrder > 0) {
|
list.push(newData);
|
}
|
}
|
this.info.result = true;
|
this.info.data = list;
|
this.info.msg = null;
|
|
//获得最大箱号值
|
let oCaseNumber = await this.dbRead.findOne(SaleOuterList, {
|
select: ["caseNumber"],
|
where: Like(`%${expressCode}`),
|
order: { caseNumber: "DESC" }
|
});
|
let caseNumber = "";
|
if (oCaseNumber) {
|
caseNumber = expressCode + "-01";
|
} else {
|
let caseNumbers = oCaseNumber.caseNumber.split("-");
|
let num = parseInt(caseNumbers[caseNumbers.length - 1]);
|
let num1 = "0000" + ++num;
|
caseNumber = expressCode + "-" + num1.substring(num1.length - 2);
|
}
|
this.info.dynamic = caseNumber;
|
this.info.data2 = orderInfo;
|
|
return this.info;
|
//#endregion
|
} else {
|
//#region 需要扫描波次号
|
if (!expressCode || !batchCode) {
|
this.info.msg = "波次号、快递单号/订单号都不能为空!";
|
return this.info;
|
}
|
|
let orderPrint = await this.dbRead.findOne(SaleOrderPrint, {
|
orderPrintCode: batchCode
|
});
|
if (orderPrint == null) {
|
this.info.msg = "波次不存在!";
|
return this.info;
|
}
|
let printList = await this.dbRead
|
.createQueryBuilder(vSaleOrderPrintListGroup, "t")
|
.where("orderPrint_Id=:orderPrint_Id AND (expressCode=:expressCode OR orderCode=:expressCode)", {
|
orderPrint_Id: orderPrint.orderPrint_Id,
|
expressCode: expressCode
|
})
|
.getOne();
|
if (printList == null) {
|
this.info.msg = "该波次下不存在该快递单!";
|
return this.info;
|
}
|
|
if ((printList.quantityOuter || 0) - (printList.quantityOrder || 0) - (printList.freezeQuanity || 0) >= 0) {
|
this.info.msg = "该订单已经打包完成!";
|
return this.info;
|
}
|
let query = `
|
SELECT productModel,quantityOrder,productCode,productSpec,productName,ISNULL(quantityOuter,0)-ISNULL(freezeQuanity,0) AS quantityOuter,
|
(SELECT TOP 1 salePrice FROM dbo.Base_ProductInfo WHERE product_Id=l.product_Id) AS salePrice,
|
orderList_Id,m.weight,m.totalWeight
|
FROM dbo.SaleOrderPrint m INNER JOIN dbo.Sale_OrderPrintList l ON m.orderPrint_Id=l.orderPrint_Id
|
WHERE m.orderPrint_Id=${orderPrint.orderPrint_Id} AND l.order_Id=${printList.order_Id} And ISNULL(quantityOuter,0)>ISNULL(freezeQuanity,0)`;
|
|
let table = await this.dbRead.query(query);
|
|
if (!table || table.Rows.length == 0) {
|
this.info.msg = "未找到对应的订单明细数据";
|
} else {
|
let list: Array<any> = [];
|
|
for (let row of table) {
|
list.push({
|
productModel: row["productModel"].GetString(),
|
quantityOrder: row["quantityOrder"].GetInt(),
|
productCode: row["productCode"].GetString(),
|
productSpec: row["productSpec"].GetString(),
|
productName: row["productName"].GetString(),
|
quantityOuter: row["quantityOuter"].GetInt(),
|
salePrice: row["salePrice"].GetDecimal() || 0,
|
orderList_Id: row["orderList_Id"].GetLong(),
|
weight: row["weight"],
|
totalWeight: row["totalWeight"]
|
});
|
}
|
this.info.result = true;
|
this.info.data = list;
|
this.info.msg = printList.expressCorpName;
|
}
|
let orderInfo = await this.dbRead.findOne(SaleOrder, {
|
orderCode: expressCode
|
});
|
this.info.dynamic = orderInfo;
|
|
return this.info;
|
//#endregion
|
}
|
} catch (error) {
|
this.info.result = false;
|
this.info.msg = "错误:" + error.message;
|
return this.info;
|
}
|
}
|
//#endregion
|
|
//#region 根据条码获取物料图片
|
|
/**
|
* 根据条码获取物料图片
|
*/
|
public async getProductImg(barcode: string) {
|
//不管子物料还是父物料,都从视图中得到父物料ID
|
let imgInfo = await this.dbRead
|
.createQueryBuilder(BaseProductInfoImage, "t")
|
.where("product_Id=(SELECT TOP 1 MainProduct_Id FROM dbo.Base_ProductInfo WHERE productModel=:productModel)", {
|
productModel: barcode
|
})
|
.select("serverPath")
|
.getOne();
|
if (imgInfo && imgInfo.serverPath) {
|
this.info.result = true;
|
this.info.data = {
|
serverPath: imgInfo.serverPath
|
};
|
} else {
|
this.info.result = false;
|
this.info.msg = "图片未找到!";
|
}
|
return this.info;
|
}
|
//#endregion
|
|
//#region 波次所在仓库是否支持拍
|
public async isSupportPlate(batchCode: string) {
|
let sql = `DECLARE @IsPlateManager INT=-1
|
SELECT @IsPlateManager=IsPlateManager FROM dbo.Base_Storage WHERE storage_Id=(
|
SELECT TOP 1 storage_Id FROM dbo.SaleOrderPrint WHERE orderPrintCode=@0
|
)
|
SELECT @IsPlateManager as isPlateManager`;
|
let dataInfo = await this.dbRead.query(sql, [batchCode]);
|
if (dataInfo && dataInfo.isPlateManager == 1) {
|
this.info.result = true;
|
} else if (dataInfo.isPlateManager == -1) {
|
this.info.msg = "波次单号不存在";
|
}
|
return this.info;
|
}
|
//#endregion
|
|
//#region 根据波次号、快递单号、拍号获取占位数据
|
public async getHoldingStorageByPlateCode(batchCode: string, expressCode: string, plateCode: string) {
|
let sql = `SELECT p.productModel,h.placeholderStorage
|
FROM
|
dbo.Base_ProductPosition AS p INNER JOIN dbo.Base_ProductPlaceHolder h ON p.ProductPosition_Id=h.ProductPosition_Id
|
INNER JOIN dbo.SaleOrder s ON h.MainID=s.order_Id
|
WHERE s.expressCode=@0 AND orderPrintCode=@1 AND p.plateCode=@2 AND h.className='销售订单'`;
|
let table = await this.dbRead.query(sql, [expressCode, batchCode, plateCode]);
|
let list: Array<any> = [];
|
if (table && table.length > 0) {
|
for (let row of table) {
|
let model = {
|
productModel: row["productModel"],
|
quantity: row["placeholderStorage"]
|
};
|
list.push(model);
|
}
|
list = list.filter(item => item.quantity > 0);
|
} else {
|
this.info.result = false;
|
}
|
this.info.result = true;
|
this.info.data = list;
|
return this.info;
|
}
|
//#endregion
|
|
//#region 拣配所在仓库是否支持拍
|
public async isSupportPlate_Pick(pickCode: string) {
|
let dataInfo = await this.dbRead
|
.createQueryBuilder(BaseStorage, "t")
|
.where(
|
`storage_Id=(
|
SELECT TOP 1 storage_Id FROM dbo.SaleOrderPrintPick WHERE pickCode=@p1
|
)`,
|
{ pickCode: pickCode }
|
)
|
.getOne();
|
if (dataInfo && dataInfo.isPlateManager == 1) {
|
this.info.result = true;
|
} else if (dataInfo.isPlateManager == -1) {
|
this.info.msg = "拣配单号不存在";
|
}
|
return this.info;
|
}
|
//#endregion
|
|
//#region 按单扫描出库 - 获取订单信息GetOrderData
|
/**
|
* 获取快递单对应的销售订单的信息
|
*/
|
public async getOrderData(expressCode: string) {
|
//也可以是 销售订单号,因为有可能生成波次以后,没有打印面单,所以扫描不了快递单号,
|
//但是打印了捡配单,可以扫描销售单号
|
|
//#region 不需要扫描波次号
|
if (!expressCode) {
|
this.info.msg = "快递单号/订单号都不能为空!";
|
return this.info;
|
}
|
|
//需要同时扫描订单号和快递单号
|
let where = `Exists
|
(
|
Select order_Id from Sale_Order
|
Where statusText in('审核成功') And
|
SortingStatus in(2)/*2=已分配, 5=部分分配*/
|
And order_Id=t.order_Id And (expressCode=:expressCode OR orderCode=:expressCode)
|
) AND quantityOrder - ISNULL(quantityOuted, 0)>0`;
|
|
let orderDetailList = await this.dbRead
|
.createQueryBuilder(SaleOrderList, "t")
|
.where(where, {
|
expressCode: expressCode
|
})
|
.getMany();
|
if (!orderDetailList || orderDetailList.length == 0) {
|
this.info.msg = "该单号下不存在需要扫描的明细!";
|
this.info.result = false;
|
return this.info;
|
}
|
// 对单据进行分组
|
let groupList = orderDetailList.reduce(
|
(all: Array<any>, next) => (all.some(item => item["order_Id"] == next["order_Id"]) ? all : [...all, next]),
|
[]
|
);
|
|
if (groupList.length > 1) {
|
this.info.msg = "快递单号重复了,请修改快递单号!";
|
this.info.result = false;
|
return this.info;
|
}
|
|
let query = `
|
SELECT COUNT(DISTINCT orderPrint_Id) AS cnt FROM dbo.Sale_OrderPrintList
|
WHERE order_Id=${orderDetailList[0].order_Id}
|
HAVING COUNT(DISTINCT orderPrint_Id)>1
|
`;
|
let dataInfo = await this.dbRead.query(query);
|
if (dataInfo && dataInfo.cnt > 0) {
|
this.info.msg = "改订单已经生成多个波次单,不允许按单出库,请使用波次打包出库!";
|
this.info.result = false;
|
return this.info;
|
}
|
|
// 占位数据
|
var holderList = await this.dbRead.find(BaseProductPlaceHolder, {
|
className: "销售订单",
|
mainID: orderDetailList[0].order_Id
|
});
|
|
let list: Array<any> = [];
|
for (var row of orderDetailList) {
|
// 对单据进行分组
|
let holdFilterList = holderList.filter(item => item.detailID == row.orderList_Id);
|
let positionNames = holdFilterList
|
.reduce((all: Array<any>, next) => (all.some(item => item["order_Id"] == next["order_Id"]) ? all : [...all, next]), [])
|
.map(item => item.positionName);
|
|
var pInfo = await this.dbRead.findOne(BaseProductInfo, row.product_Id);
|
var newData = {
|
productModel: row.productModel,
|
quantityOrder: row.quantityOrder - (row.quantityOuted || 0),
|
productCode: row.productCode,
|
productSpec: row.productSpec,
|
productName: row.productName,
|
quantityOuter: row.quantityOuted || 0,
|
salePrice: row.salePrice || 0,
|
orderList_Id: row.orderList_Id,
|
order_Id: row.order_Id,
|
orderCode: expressCode,
|
relationCode: pInfo.relationCode,
|
relationCode2: pInfo.relationCode2,
|
relationCode3: pInfo.relationCode3,
|
relationCode4: pInfo.relationCode4,
|
relationCode5: pInfo.relationCode5,
|
middleBarcode: pInfo.middleBarcode,
|
middleUnitConvert: pInfo.middleUnitConvert,
|
bigBarcode: pInfo.bigBarcode,
|
unitConvert: pInfo.unitConvert,
|
positionName: positionNames.join(","),
|
weight: row.weight,
|
totalWeight: row.totalWeight
|
};
|
if (newData.quantityOrder > 0) {
|
list.push(newData);
|
}
|
}
|
this.info.result = true;
|
this.info.data = list;
|
this.info.msg = null;
|
|
return this.info;
|
//#endregion
|
}
|
//#endregion
|
|
//#region 按单扫描出库 - 保存扫描结果(部分打包)
|
/**
|
* 按单扫描出库 - 保存扫描结果(部分打包)
|
* @param expressCode 快递单号/订单号
|
* @param wrapperBarcode 包材条码
|
* @param newExpressCode 新单快递单号
|
* @param list 明细List
|
* @param user_Id 用户ID
|
* @param weight 重量
|
*/
|
public async orderPartialSaveScan(
|
totalPackage: string,
|
totalVolume: string,
|
expressCode: string,
|
wrapperBarcode: string,
|
newExpressCode: string,
|
list: Array<any>,
|
weight?: number
|
) {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
//#region 校验
|
//获取订单信息
|
let orderInfo = await this.dbRead
|
.createQueryBuilder(SaleOrder, "t")
|
.where("(expressCode=:expressCode OR orderCode=:expressCode) AND userProduct_Id=:userProduct_Id", {
|
expressCode: expressCode,
|
userProduct_Id: userInfo.userProduct_Id
|
})
|
.getOne();
|
if (!orderInfo) {
|
this.info.msg = "出库订单中不存在,出库单号:" + expressCode;
|
return this.info;
|
}
|
|
if (["审核成功", "波次完成", "等待打包", "等待配货", "部分打包"].indexOf(orderInfo.statusText) < 0) {
|
this.info.msg = orderInfo.orderCode + "订单不允许操作,订单状态为:" + orderInfo.statusText;
|
return this.info;
|
}
|
|
if (!expressCode) {
|
this.info.msg = "快递单号不能为空!";
|
return this.info;
|
}
|
|
var wrapperBarcodeArray = wrapperBarcode
|
.replace(/,;\\r/gi, "\n")
|
.split("\n")
|
.filter(item => item);
|
|
if (!list || list.length == 0) {
|
this.info.msg = "请先扫描条码!";
|
return this.info;
|
}
|
|
//用销售订单的快递单号,因为 可能更改了销售订单的快递单号,但是 波次明细的是改不了的
|
var Outer_ExpressCode = await ctx.service.common.getConfigBool("Outer_ExpressCode"); //启用快递单号校验
|
var _expressCode = newExpressCode || orderInfo.expressCode;
|
if (Outer_ExpressCode && _expressCode) {
|
let outerModel = await this.dbRead.findOne(SaleOuter, {
|
expressCode: _expressCode
|
});
|
if (outerModel != null) {
|
this.info.msg = "该快递单号[" + _expressCode + "]在[打包校验]已经使用过!";
|
return this.info;
|
}
|
}
|
|
//验证耗材是否正确
|
if (!wrapperBarcodeArray && wrapperBarcodeArray.length > 0) {
|
let where = "'" + wrapperBarcodeArray.join(",") + "'";
|
let query = `SELECT TOP 1 v.col FROM [dbo].[Func_SplitStrToTable](${where}) AS v
|
WHERE NOT EXISTS(
|
SELECT * FROM dbo.Base_ProductInfo WHERE productModel=v.col
|
)`;
|
let notExistsSku = await this.dbRead.query(query);
|
if (notExistsSku && notExistsSku.col) {
|
this.info.result = false;
|
this.info.msg = "包材[" + notExistsSku + "]在物料信息中不存在,请先维护好基础数据!";
|
return this.info;
|
}
|
}
|
|
//#region 存在占位数和明细数量不相等的情况
|
let query = `SELECT *
|
FROM ( SELECT ISNULL(SUM(L.batchQuantity), 0)-SUM(ISNULL(L.quantityOuted, 0)) AS batchQuantity ,
|
ISNULL(( SELECT SUM(H.placeholderStorage) AS placeholderStorage
|
FROM Base_ProductPlaceHolder H
|
WHERE className = '销售订单'
|
AND H.MainID = @0
|
AND H.detailID = L.orderList_Id
|
), 0) AS placeholderStorage
|
FROM dbo.Sale_OrderList AS L
|
WHERE ( L.order_Id = @0 )
|
GROUP BY L.orderList_Id
|
HAVING ISNULL(SUM(L.batchQuantity), 0)> ISNULL(SUM(L.quantityOuted), 0)
|
) a
|
WHERE placeholderStorage <> batchQuantity
|
UNION ALL
|
SELECT *
|
FROM ( SELECT ISNULL(SUM(L.placeholderStorage), 0) placeholderStorage ,
|
( SELECT SUM(ISNULL(batchQuantity,0))-SUM(ISNULL(quantityOuted,0)) AS batchQuantity
|
FROM dbo.Sale_OrderList
|
WHERE orderList_Id = L.detailID
|
AND order_Id = @0
|
AND ISNULL(batchQuantity, 0)> ISNULL(quantityOuted, 0)
|
) AS batchQuantity
|
FROM Base_ProductPlaceHolder AS L
|
WHERE className = '销售订单'
|
AND ( L.MainID = @0 )
|
GROUP BY L.detailID
|
) a
|
WHERE placeholderStorage <> batchQuantity;`;
|
let dataInfo = await this.dbRead.query(query, [orderInfo.order_Id]);
|
if (dataInfo && dataInfo.length > 0) {
|
this.info.msg = "分拣占位数和明细数量不相等的情况,不允许打包出库!";
|
this.info.result = false;
|
return this.info;
|
}
|
//#endregion
|
//#endregion
|
|
//#region 保存
|
let saleOuter = new SaleOuter();
|
saleOuter.consignor_Id = orderInfo.consignor_Id;
|
saleOuter.consignorCode = orderInfo.consignorCode;
|
saleOuter.consignorName = orderInfo.consignorName;
|
saleOuter.expressCorp_Id = orderInfo.expressCorp_Id;
|
saleOuter.expressCorpName = orderInfo.expressCorpName;
|
saleOuter.expressCode = _expressCode; //使用新的快递单号
|
saleOuter.client_Id = orderInfo.client_Id || 0;
|
saleOuter.clientCode = orderInfo.clientCode;
|
saleOuter.clientShortName = orderInfo.clientShortName;
|
|
saleOuter.orderType = "订单打包";
|
saleOuter.order_Id = orderInfo.order_Id;
|
saleOuter.orderCode = orderInfo.orderCode;
|
saleOuter.storeOrderCode = orderInfo.storeOrderCode;
|
saleOuter.shippingName = orderInfo.shippingName;
|
saleOuter.shippingAddress = orderInfo.shippingAddress;
|
saleOuter.mobile = orderInfo.mobile;
|
|
saleOuter.storage_Id = orderInfo.storage_Id || 0;
|
saleOuter.storageName = orderInfo.storageName;
|
saleOuter.user_Id = userInfo.user_Id;
|
saleOuter.userTrueName = userInfo.userTrueName;
|
saleOuter.dept_Id = userInfo.dept_Id;
|
saleOuter.deptName = userInfo.deptName;
|
saleOuter.applyDate = new Date();
|
saleOuter.createID = userInfo.user_Id;
|
saleOuter.creator = userInfo.userTrueName;
|
|
saleOuter.orderPrint_Id = orderInfo.orderPrint_Id;
|
saleOuter.orderPrintCode = orderInfo.orderPrintCode;
|
|
saleOuter.userProduct_Id = userInfo.userProduct_Id;
|
saleOuter.userProductCode = userInfo.userProductCode;
|
saleOuter.userProductAlias = userInfo.userProductAlias;
|
saleOuter.platCorpName = userInfo.platCorpName;
|
saleOuter.platUserCode = userInfo.platUserCode;
|
saleOuter.platUser_Id = userInfo.platUser_Id;
|
|
saleOuter.createDate = new Date();
|
let outerCode = await ctx.service.common.getCodeRegular(268);
|
saleOuter.outerCode = outerCode;
|
saleOuter.totalWeight = orderInfo.totalWeight;
|
if (weight != 0) {
|
saleOuter.weight = weight;
|
}
|
saleOuter.totalPackage = Number(totalPackage);
|
saleOuter.totalVolume = Number(totalVolume);
|
await this.dbWrite.save(saleOuter);
|
//遍历扫描的明细物料,插入到 打包出库表
|
for (var model of list) {
|
//插入明细
|
let orderDetail = await this.dbRead.findOne(SaleOrderList, model.orderList_Id);
|
let outerDetail = new SaleOuterList();
|
outerDetail.batchNumber = orderDetail.batchNumber;
|
outerDetail.createDate = new Date();
|
outerDetail.createID = userInfo.user_Id;
|
outerDetail.creator = userInfo.userTrueName;
|
|
outerDetail.order_Id = orderDetail.order_Id;
|
outerDetail.orderCode = model.orderCode;
|
outerDetail.orderList_Id = orderDetail.orderList_Id;
|
outerDetail.outer_Id = saleOuter.outer_Id;
|
outerDetail.product_Id = orderDetail.product_Id;
|
outerDetail.productCode = orderDetail.productCode;
|
outerDetail.productModel = orderDetail.productModel;
|
outerDetail.productName = orderDetail.productName;
|
outerDetail.productSpec = orderDetail.productSpec;
|
outerDetail.quantityOrder = model.scanCount;
|
|
outerDetail.salePrice = orderDetail.salePrice;
|
outerDetail.subTotal = orderDetail.subTotal;
|
outerDetail.caseNumber = model.caseNumber;
|
|
outerDetail.order_Id = orderInfo.order_Id;
|
outerDetail.orderCode = orderInfo.orderCode;
|
outerDetail.weight = model.weight;
|
outerDetail.totalWeight = model.totalWeight;
|
await this.dbWrite.save(outerDetail);
|
}
|
|
query = "";
|
if (wrapperBarcodeArray != null && wrapperBarcodeArray.length > 0) {
|
let where = "'" + wrapperBarcodeArray.join(",") + "'";
|
//插入耗材
|
query += `INSERT INTO dbo.Sale_OuterWrapper
|
( outer_Id ,
|
order_Id ,
|
product_Id ,
|
productCode ,
|
productName ,
|
productModel ,
|
productSpec ,
|
quantity ,
|
purchasePrice ,
|
subTotal ,
|
createID ,
|
creator ,
|
createDate
|
)
|
SELECT ${saleOuter.outer_Id}, ${orderInfo.order_Id},s.product_Id,s.productCode,s.productName,s.productModel,s.productSpec,1,s.purchasePrice,s.purchasePrice,0,'',GETDATE()
|
FROM [dbo].[Func_SplitStrToTable](${where}) AS v
|
INNER JOIN dbo.Base_ProductInfo s ON v.col=s.productModel;`;
|
}
|
query += `UPDATE dbo.Sale_Outer SET subTotal=(SELECT SUM(ISNULL(subTotal,0)) FROM dbo.Sale_OuterList WHERE outer_Id=Sale_Outer.outer_Id),
|
totalQuantityOrder=(SELECT SUM(ISNULL(quantityOrder,0)) FROM dbo.Sale_OuterList WHERE outer_Id=Sale_Outer.outer_Id),
|
totalWeight=(SELECT SUM(ISNULL(totalWeight,0)) FROM dbo.Sale_OuterList WHERE outer_Id=Sale_Outer.outer_Id)
|
WHERE dbo.Sale_Outer.outer_Id=${saleOuter.outer_Id}`;
|
|
await this.dbWrite.query(query);
|
|
//#region 判断是否部分打包操作
|
//不是部分打包设置,不允许部分出库
|
if (!(await ctx.service.common.getConfigBool("Outer_BatchPartialCheck"))) {
|
query = `
|
SELECT * FROM (
|
SELECT quantityOrder, ISNULL((SELECT SUM(L.quantityOrder) FROM dbo.Sale_OuterList L WHERE L.orderList_Id=OL.orderList_Id), 0) AS quantityOuted
|
FROM Sale_OrderList OL
|
WHERE order_Id= @0
|
) t
|
WHERE t.quantityOrder<> t.quantityOuted
|
`;
|
let dateInfo = await this.dbWrite.query(query, [orderInfo.order_Id]);
|
if (dateInfo && dateInfo.length) {
|
this.info.msg = "不允许部分打包出库!";
|
this.info.result = false;
|
await this.dbWrite.delete(SaleOuter, {
|
outer_Id: saleOuter.outer_Id
|
});
|
return this.info;
|
}
|
}
|
//#endregion
|
|
//#region 审核
|
let fromStatusId = orderInfo.statusID || 0;
|
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("menu_Id", 268);
|
request.input("outer_Id", saleOuter.outer_Id);
|
request.input("user_Id", userInfo.user_Id);
|
request.output("outMsg", sql.NVarChar(2000));
|
let result = await request.execute("sp_Sale_OuterPartial_Check");
|
let outMsg = result.output.outMsg;
|
if (outMsg) {
|
let db = this.app.mongodb;
|
let logColl = db.collection("sp_Sale_OuterPartial_Check");
|
let data = {
|
type: "orderPartialSaveScan",
|
msg: "出库错误:" + outMsg,
|
order_Id: orderInfo.order_Id,
|
orderCode: orderInfo.orderCode,
|
createDate: new Date()
|
};
|
await logColl.insert(data);
|
this.info.result = false;
|
this.info.msg = "出库错误:" + outMsg;
|
// 删除打包结果单
|
this.dbWrite.delete(SaleOuter, {
|
outer_Id: saleOuter.outer_Id
|
});
|
|
return this.info;
|
}
|
//有可能是打包完成 ,有可能是部分打包,所以要从新查询出状态
|
orderInfo = await this.dbRead.findOne(SaleOrder, orderInfo.order_Id);
|
let toStatusId = orderInfo.statusID;
|
await ctx.service.outbound.orderHelper.setStatusHistory(orderInfo.order_Id, fromStatusId, toStatusId, "订单状态", "订单打包");
|
|
//更新订单快递单号
|
if (newExpressCode) {
|
await this.dbWrite.update(SaleOrder, orderInfo.order_Id, {
|
expressCode: newExpressCode
|
});
|
}
|
//#endregion
|
|
//#region 获取剩余未扫描的数据
|
this.info.result = true;
|
this.info.msg = "打包成功";
|
//#endregion
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region 获取入库收货位
|
/// <summary>
|
/// 获取入库收货位
|
/// </summary>
|
/// <returns></returns>
|
public async getOffPosition(storage_Id: number) {
|
let positionList = await this.dbRead.find(BasePosition, {
|
select: ["positionName"],
|
where: {
|
positionType: 5,
|
storage_Id: storage_Id
|
}
|
});
|
|
return positionList;
|
}
|
//#endregion
|
|
/* *****************************************************
|
* 无单扫描入库
|
* *****************************************************/
|
//#region 无单扫描入库获得物料信息
|
/**
|
* 无单扫描入库获得物料信息
|
*/
|
public async getProductInfo(storage_Id: number, positionName: string, productModel: string, consignor_Id: number): Promise<ResultInfo> {
|
let { ctx } = this;
|
this.info.result = false;
|
|
let SKU_ProductToMultiBarcode = ctx.service.common.getConfigBool("SKU_ProductToMultiBarcode"); //支持一品多码
|
var where = "productModel=:productModel";
|
if (SKU_ProductToMultiBarcode) {
|
where = `productModel COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode2 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode3 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode4 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode5 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR middleBarcode COLLATE Chinese_PRC_CS_AS=:productModel
|
OR bigBarcode COLLATE Chinese_PRC_CS_AS=:productModel
|
`;
|
}
|
var prodList = await this.dbRead
|
.createQueryBuilder(BaseProductInfo, "t")
|
.where(where, {
|
productModel: productModel
|
})
|
.getMany();
|
if (prodList != null && prodList.length > 0) {
|
for (let a of prodList) {
|
let sql = `
|
SELECT isnull(SUM(validQty),0) as validQty FROM dbo.vBase_ProductPosition
|
WHERE storage_Id=@0 AND validQty>0 AND positionName=@1 AND productModel=@2 AND consignor_Id=@3`;
|
|
let dataInfo = await this.dbRead.query(sql, [storage_Id, positionName, productModel, consignor_Id]);
|
a["validQty"] = dataInfo.validQty;
|
}
|
|
this.info.result = true;
|
this.info.data = prodList;
|
} else {
|
this.info.result = false;
|
this.info.msg = "扫描的条码在物料信息中不存在,请完善好基础数据!";
|
}
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region 无单扫描出库获得物料信息
|
/**
|
* 无单扫描出库获得物料信息
|
*/
|
public async getProductInfoOut(storage_Id: number, positionName: string, productModel: string, consignor_Id: number) {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
let SKU_ProductToMultiBarcode = await ctx.service.common.getConfigBool("SKU_ProductToMultiBarcode"); //支持一品多码
|
var where = "productModel=:productModel";
|
if (SKU_ProductToMultiBarcode) {
|
where = `productModel COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode2 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode3 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode4 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode5 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR middleBarcode COLLATE Chinese_PRC_CS_AS=:productModel
|
OR bigBarcode COLLATE Chinese_PRC_CS_AS=:productModel
|
`;
|
}
|
var prodList = await this.dbRead
|
.createQueryBuilder(BaseProductInfo, "t")
|
.where(where, {
|
productModel: productModel,
|
userProduct_Id: userInfo.userProduct_Id
|
})
|
.getMany();
|
|
let dataList = [];
|
if (prodList != null && prodList.length > 0) {
|
for (let a of prodList) {
|
let sql = `
|
SELECT isnull(SUM(validQty),0) as validQty, productSpec FROM dbo.vBase_ProductPosition
|
WHERE storage_Id=@0 AND validQty>0 AND positionName=@1 AND productModel=@2 AND consignor_Id=@3 AND userProduct_Id=@4
|
GROUP BY storage_Id, positionName, productModel, consignor_Id, userProduct_Id, productSpec`;
|
|
let ppList = await this.dbRead.query(sql, [storage_Id, positionName, productModel, consignor_Id, userInfo.userProduct_Id]);
|
if (ppList.length) {
|
for (let item of ppList) {
|
a["validQty"] = item.validQty;
|
a.productSpec = item.productSpec;
|
dataList.push(ctx.helper.copyObject(a));
|
}
|
} else {
|
dataList.push(a);
|
}
|
}
|
dataList = dataList.filter(a => {
|
return a["validQty"] > 0;
|
});
|
if (dataList.length == 0) {
|
var storageInfo = await this.dbRead.findOne(BaseStorage, storage_Id);
|
var conInfo = await this.dbRead.findOne(BaseConsignor, consignor_Id);
|
this.info.result = false;
|
this.info.msg = "出库货:" + positionName + ",货主:" + conInfo.consignorName + ",仓库:" + storageInfo.storageName + "中不存在该物料!";
|
} else {
|
this.info.result = true;
|
this.info.data = dataList;
|
}
|
} else {
|
this.info.result = false;
|
this.info.msg = "扫描的条码在物料信息中不存在,请完善好基础数据!";
|
}
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region 无单扫描入库获得物料信息(权限控制)
|
/**
|
* 无单扫描入库获得物料信息
|
*/
|
public async getProductInfoAuth(storage_Id: number, positionName: string, productModel: string) {
|
let { ctx } = this;
|
this.info.result = false;
|
|
let SKU_ProductToMultiBarcode = await ctx.service.common.getConfigBool("SKU_ProductToMultiBarcode"); //支持一品多码
|
var where = "productModel=:productModel";
|
if (SKU_ProductToMultiBarcode) {
|
where = `productModel COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode2 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode3 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode4 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR relationCode5 COLLATE Chinese_PRC_CS_AS=:productModel
|
OR middleBarcode COLLATE Chinese_PRC_CS_AS=:productModel
|
OR bigBarcode COLLATE Chinese_PRC_CS_AS=:productModel
|
`;
|
}
|
var pInfo = await this.dbRead
|
.createQueryBuilder(BaseProductInfo, "t")
|
.where(where, {
|
productModel: productModel
|
})
|
.getMany();
|
if (pInfo != null && pInfo.length > 0) {
|
pInfo.forEach(async a => {
|
let sql = `
|
SELECT isnull(SUM(validQty),0) as validQty FROM dbo.vBase_ProductPosition
|
WHERE storage_Id=@0 AND validQty>0 AND positionName=@1 AND positionName=@2 AND productModel=@3`;
|
|
let dataInfo = await this.dbRead.query(sql, [storage_Id, positionName, positionName, productModel]);
|
a.transitDays = dataInfo.validQty;
|
});
|
this.info.result = true;
|
this.info.data = pInfo;
|
} else {
|
this.info.result = false;
|
this.info.msg = "扫描的条码在物料信息中不存在,请完善好基础数据!";
|
}
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region 无单扫描出库 - 保存
|
/**
|
* 无单扫描出库
|
*/
|
public async noBillOutSave(dataList: Array<any>) {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
let menu_Id = 112;
|
if (dataList.length == 0) {
|
this.info.result = false;
|
this.info.msg = "已扫描数量不能全部为零";
|
return this.info;
|
}
|
|
let excelDT = new sql.Table();
|
excelDT.columns.add("storage_Id", sql.Int);
|
excelDT.columns.add("storageName", sql.NVarChar(50));
|
excelDT.columns.add("product_Id", sql.Int);
|
excelDT.columns.add("finishedQuantity", sql.Int);
|
excelDT.columns.add("positionName", sql.NVarChar(50));
|
excelDT.columns.add("ProduceDate", sql.NVarChar(50));
|
|
excelDT.columns.add("purchasePrice", sql.Decimal(14, 4));
|
excelDT.columns.add("salePrice", sql.Decimal(14, 4));
|
excelDT.columns.add("batchNumber", sql.NVarChar(50));
|
excelDT.columns.add("productSpec", sql.NVarChar(50));
|
excelDT.columns.add("plateCode", sql.NVarChar(50));
|
excelDT.columns.add("enterMode", sql.NVarChar(50));
|
|
for (var dataItem of dataList) {
|
excelDT.rows.add(
|
dataItem.storage_Id,
|
dataItem.storageName,
|
dataItem.product_Id,
|
dataItem.finishedQuantity,
|
dataItem.positionName,
|
dataItem.ProduceDate,
|
|
dataItem.purchasePrice,
|
|
dataItem.salePrice,
|
dataItem.batchNumber,
|
dataItem.productSpec,
|
dataItem.plateCode,
|
dataItem.enterMode
|
);
|
}
|
let orderCode = await ctx.service.common.getCodeRegular(112);
|
let outerCode = await ctx.service.common.getCodeRegular(268);
|
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("orderCode", orderCode);
|
request.input("outerCode", outerCode);
|
request.input("user_Id", userInfo.user_Id);
|
request.input("menu_Id", menu_Id);
|
request.input("excelDT", excelDT);
|
request.output("outMsg", sql.NVarChar(2000));
|
let result = await request.execute("sp_SaleOrder_NoBillOut");
|
let outMsg = result.output.outMsg;
|
|
if (outMsg != null && outMsg.ToString().IsNotNullOrEmpty()) {
|
this.info.msg = outMsg.ToString();
|
this.info.result = false;
|
return this.info;
|
} else {
|
this.info.msg = "确认出库成功";
|
this.info.result = true;
|
return this.info;
|
}
|
}
|
//#endregion
|
|
//#region 无单扫描出库 - 保存(自由选择货主)
|
/**
|
* 无单扫描出库
|
*/
|
public async noBillOutSaveByConsignor(dataList: Array<any>) {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
let menu_Id = 112;
|
if (dataList.length == 0) {
|
this.info.result = false;
|
this.info.msg = "已扫描数量不能全部为零";
|
return this.info;
|
}
|
|
let excelDT = new sql.Table();
|
excelDT.columns.add("storage_Id", sql.Int);
|
excelDT.columns.add("storageName", sql.NVarChar(50));
|
excelDT.columns.add("consignor_Id", sql.Int);
|
excelDT.columns.add("consignorCode", sql.NVarChar(50));
|
excelDT.columns.add("consignorName", sql.NVarChar(50));
|
|
excelDT.columns.add("product_Id", sql.Int);
|
excelDT.columns.add("finishedQuantity", sql.Int);
|
excelDT.columns.add("positionName", sql.NVarChar(50));
|
excelDT.columns.add("ProduceDate", sql.NVarChar(50));
|
excelDT.columns.add("purchasePrice", sql.Decimal(14, 4));
|
excelDT.columns.add("salePrice", sql.Decimal(14, 4));
|
excelDT.columns.add("batchNumber", sql.NVarChar(50));
|
excelDT.columns.add("productSpec", sql.NVarChar(50));
|
excelDT.columns.add("plateCode", sql.NVarChar(50));
|
excelDT.columns.add("enterMode", sql.NVarChar(50));
|
excelDT.columns.add("weight", sql.Decimal(14, 4));
|
excelDT.columns.add("totalWeight", sql.Decimal(14, 4));
|
|
for (var dataItem of dataList) {
|
excelDT.rows.add(
|
dataItem.storage_Id,
|
dataItem.storageName,
|
dataItem.consignor_Id,
|
dataItem.consignorCode,
|
dataItem.consignorName,
|
|
dataItem.product_Id,
|
dataItem.finishedQuantity,
|
dataItem.positionName,
|
dataItem.ProduceDate,
|
dataItem.purchasePrice,
|
dataItem.salePrice,
|
dataItem.batchNumber,
|
dataItem.productSpec,
|
dataItem.plateCode,
|
dataItem.enterMode,
|
dataItem.weight,
|
dataItem.totalWeight
|
);
|
}
|
let orderCode = await ctx.service.common.getCodeRegular(112);
|
let outerCode = await ctx.service.common.getCodeRegular(268);
|
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("orderCode", orderCode);
|
request.input("outerCode", outerCode);
|
request.input("user_Id", userInfo.user_Id);
|
request.input("menu_Id", menu_Id);
|
request.input("excelDT", excelDT);
|
request.output("outMsg", sql.NVarChar(2000));
|
let result = await request.execute("sp_Sale_Order_NoBillOut_ByConsignor");
|
let outMsg = result.output.outMsg;
|
|
if (outMsg) {
|
this.info.msg = outMsg;
|
this.info.result = false;
|
return this.info;
|
} else {
|
this.info.msg = "确认出库成功";
|
this.info.result = true;
|
return this.info;
|
}
|
}
|
//#endregion
|
|
/* *****************************************************
|
* 扫描物流单出库
|
* *****************************************************/
|
//#region 扫描物流单出库明细
|
/**
|
* 扫描物流单出库明细
|
*/
|
public async getSaleOrderList(orderInfo: SaleOrder) {
|
var where = "isnull(quantityOuted, 0)<batchQuantity And order_Id=:order_Id";
|
var detailInfo = await this.dbRead
|
.createQueryBuilder(SaleOrderList, "t")
|
.where(where, {
|
order_Id: orderInfo.order_Id
|
})
|
.getMany();
|
if (detailInfo != null && detailInfo.length > 0) {
|
this.info.result = true;
|
this.info.data = detailInfo;
|
} else {
|
this.info.result = false;
|
this.info.msg = "出库单未包含明细!";
|
}
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region 扫描物流单出库保存
|
/**
|
* 扫描物流单出库明细 保存
|
*/
|
public async saveSaleOuterExpress(order_Id: number) {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
let outerCode = await ctx.service.common.getCodeRegular(268);
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("outerCode", outerCode);
|
request.input("order_Id", order_Id);
|
request.input("user_Id", userInfo.user_Id);
|
request.input("menu_Id", 112);
|
request.output("outMsg", sql.NVarChar(2000));
|
let result = await request.execute("sp_SaleOrder_NoBillOut");
|
let outMsg = result.output.outMsg;
|
|
if (outMsg != null && outMsg.ToString().IsNotNullOrEmpty()) {
|
this.info.msg = outMsg.ToString();
|
this.info.result = false;
|
return this.info;
|
} else {
|
this.info.msg = "确认出库成功";
|
this.info.result = true;
|
return this.info;
|
}
|
}
|
//#endregion
|
|
/* *****************************************************
|
* 扫描装车
|
* *****************************************************/
|
//#region 获得装车数据
|
/**
|
* 获得装车数据
|
*/
|
public async getSaleLoadBill(data) {
|
//#region 校验数据
|
if (data == null) {
|
this.info.msg = "没有可执行的数据";
|
return this.info;
|
}
|
if (data.user_Id == 0) {
|
this.info.msg = "用户ID都不能为空!";
|
return this.info;
|
}
|
if (!data.expressCode) {
|
this.info.msg = "单号不能为空!";
|
return this.info;
|
}
|
|
var where = "(expressCode=:expressCode OR orderCode=:expressCode OR outerCode=:expressCode) And Auditing=2";
|
var outerList = await this.dbRead.createQueryBuilder(SaleOuter, "t").where(where, {
|
expressCode: data.expressCode
|
});
|
this.info.data = outerList;
|
this.info.result = true;
|
//#endregion
|
|
return this.info;
|
}
|
//#endregion
|
|
//#region 扫描装车保存
|
/**
|
* 扫描装车保存
|
*/
|
public async saveSaleLoadBill(data) {
|
let { ctx } = this;
|
this.info.result = false;
|
|
let loadBillCode = await ctx.service.common.getCodeRegular(198);
|
var loadBillInfo: any;
|
loadBillInfo.loadBillCode = loadBillCode;
|
loadBillInfo.loadBillType = "扫描装车";
|
loadBillInfo.loadDate = moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
|
loadBillInfo.orderCount = data.list.length;
|
loadBillInfo.statusID = 1;
|
loadBillInfo.statusText = "新建";
|
await this.dbWrite.save(loadBillInfo);
|
|
var qty = 0;
|
for (var item of data.list) {
|
var outerInfo = await this.dbRead.findOne(SaleOuter, item.outer_Id);
|
var detailInfo = new SaleLoadBillList();
|
detailInfo.createDate = new Date();
|
detailInfo.createID = data.user_Id;
|
detailInfo.creator = data.userTrueName;
|
detailInfo.loadBill_Id = loadBillInfo.loadBill_Id;
|
detailInfo.orderCode = outerInfo.orderCode;
|
detailInfo.orderPrintCode = outerInfo.orderPrintCode;
|
detailInfo.orderPrint_Id = outerInfo.orderPrint_Id;
|
detailInfo.order_Id = outerInfo.order_Id;
|
detailInfo.outerCode = outerInfo.outerCode;
|
detailInfo.outer_Id = outerInfo.outer_Id;
|
await this.dbWrite.save(detailInfo);
|
|
qty += outerInfo.totalQuantityOrder || 0;
|
}
|
loadBillInfo.totalQty = qty;
|
await this.dbWrite.update(SaleLoadBill, loadBillInfo.loadBill_Id, {
|
totalQty: qty
|
});
|
|
this.info.msg = "生成装载单成功";
|
this.info.result = true;
|
return this.info;
|
}
|
//#endregion
|
|
//#region 根据预到货单号获取预到货单数据
|
//(预到货明细中的物料编号有可能是重复的),添加厂家拍号作为查询条件,去掉了货主ID
|
public async getSaleOuterData(expressCode: string) {
|
if (!expressCode) {
|
this.info.msg = "出库单号不能为空!";
|
return this.info;
|
}
|
// 对主表数据进行检验
|
let orderList = await this.dbRead
|
.createQueryBuilder(SaleOrder, "t")
|
.where(
|
"(expressCode=:expressCode OR orderCode=:expressCode OR orderPrintCode=:expressCode) And statusText in('波次完成','拣货中','等待配货','配货中','等待打包')",
|
{
|
expressCode: expressCode
|
}
|
)
|
.getMany();
|
if (orderList.length > 1) {
|
this.info.msg = "当前查询存在多个订单,目前只支持一单一波次的波次单!";
|
this.info.result = false;
|
return this.info;
|
}
|
if (orderList.length == 0) {
|
this.info.msg = "单号不存在!";
|
this.info.result = false;
|
return this.info;
|
}
|
|
let orderInfo = orderList[0];
|
if (["波次完成", "拣货中", "等待配货", "配货中", "等待打包"].indexOf(orderInfo.statusText) < 0) {
|
this.info.msg = orderInfo.expressCode + "出库单状态为" + orderInfo.statusText + ",不允许出库!";
|
this.info.result = false;
|
return this.info;
|
}
|
// 获取明细数据
|
let orderDetailList = await this.dbRead
|
.createQueryBuilder(SaleOrderList, "t")
|
.where("isnull(quantityOuted, 0)<batchQuantity And order_Id=:order_Id", {
|
order_Id: orderInfo.order_Id
|
})
|
.getMany();
|
let info = {
|
orderDetailList: orderDetailList,
|
storageInfo: {
|
storage_Id: orderInfo.storage_Id,
|
storageName: orderInfo.storageName
|
}
|
};
|
if (orderDetailList.length == 0) {
|
this.info.msg = "出库单未包含明细!";
|
this.info.result = false;
|
return this.info;
|
} else {
|
this.info.result = true;
|
this.info.data = info;
|
this.info.msg = null;
|
}
|
return this.info;
|
}
|
//#endregion
|
|
//#region 扫描出库
|
public async saveSaleOrderCode(storage_Id: number, expressCode: string) {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
this.info.result = false;
|
|
if (!expressCode) {
|
this.info.msg = "出库单号不能为空!";
|
return this.info;
|
}
|
// 对主表数据进行检验
|
let orderList = await this.dbRead
|
.createQueryBuilder(SaleOrder, "t")
|
.where(
|
"(expressCode=:expressCode OR orderCode=:expressCode OR orderPrintCode=:expressCode) And statusText in('波次完成','拣货中','等待配货','配货中','等待打包')",
|
{
|
expressCode: expressCode
|
}
|
)
|
.getMany();
|
if (orderList != null && orderList.length > 1) {
|
this.info.msg = "当前查询存在多个订单,目前只支持一单一波次的波次单!";
|
this.info.result = false;
|
return this.info;
|
}
|
let orderInfo = orderList[0];
|
if (["波次完成", "拣货中", "等待配货", "配货中", "等待打包"].indexOf(orderInfo.statusText) < 0) {
|
this.info.msg = orderInfo.expressCode + "出库单状态为" + orderInfo.statusText + ",不允许出库!";
|
this.info.result = false;
|
return this.info;
|
}
|
if (orderInfo.storage_Id !== storage_Id) {
|
this.info.msg = "用户所选仓库,无法操作该单据!";
|
this.info.result = false;
|
return this.info;
|
}
|
|
let outerCode = await ctx.service.common.getCodeRegular(268);
|
const connection: any = await this.dbWrite.connection;
|
let request = new sql.Request(connection.driver.master);
|
request.input("outerCode", outerCode);
|
request.input("order_Id", orderInfo.order_Id);
|
request.input("user_Id", userInfo.user_Id);
|
request.input("menu_Id", 112);
|
request.output("outMsg", sql.NVarChar(2000));
|
let result = await request.execute("sp_Sale_Order_ExpressOut");
|
let outMsg = result.output.outMsg;
|
if (outMsg != null && outMsg.ToString().IsNotNullOrEmpty()) {
|
this.info.msg = outMsg.ToString();
|
this.info.result = false;
|
return this.info;
|
} else {
|
this.info.msg = "确认出库成功";
|
this.info.result = true;
|
return this.info;
|
}
|
}
|
//#endregion
|
|
//#region 妥投相关-获取妥投出库订单明细
|
public async getSaleOrderDetaliList(orderCode: string) {
|
let userInfo = await this.userInfo;
|
this.info.result = false;
|
if (!orderCode) {
|
this.info.msg = "出库单号不能为空!";
|
return this.info;
|
}
|
// 对主表数据进行检验
|
let orderList = await this.dbRead
|
.createQueryBuilder(SaleOrder, "t")
|
.where("userProduct_Id=:userProduct_Id And orderCode=:orderCode And statusText in('发运完成', '部分发运')", {
|
orderCode: orderCode,
|
userProduct_Id: userInfo.userProduct_Id
|
})
|
.getMany();
|
if (orderList.length == 0) {
|
this.info.msg = "出库单号查询无数据!";
|
this.info.result = false;
|
return this.info;
|
}
|
let orderInfo = orderList[0];
|
// 获取明细数据
|
let orderDetailList = await this.dbRead
|
.createQueryBuilder(SaleOrderList, "t")
|
.where("order_Id=:order_Id", {
|
order_Id: orderInfo.order_Id
|
})
|
.getMany();
|
if (orderDetailList.length == 0) {
|
this.info.msg = "出库单未包含明细!";
|
this.info.result = false;
|
return this.info;
|
} else {
|
this.info.result = true;
|
this.info.data = orderDetailList;
|
this.info.msg = null;
|
}
|
return this.info;
|
}
|
//#endregion
|
|
//#region 妥投相关-提交妥投出库订单明细
|
public async saveSaleOrderTuotou(orderCode: string, dataArray: Array<any>) {
|
this.info.result = false;
|
if (!orderCode) {
|
this.info.result = false;
|
this.info.msg = "出库单号不能为空!";
|
return this.info;
|
}
|
// 对主表数据进行检验
|
let orderInfo = await this.dbRead
|
.createQueryBuilder(SaleOrder, "t")
|
.where("orderCode=:orderCode And statusText in('发运完成', '部分发运')", {
|
orderCode: orderCode
|
})
|
.getOne();
|
if (!orderInfo) {
|
this.info.msg = "出库单号查询无数据!";
|
this.info.result = false;
|
return this.info;
|
}
|
for (var model of dataArray) {
|
// 校验数据
|
if (!model.orderList_Id) {
|
this.info.result = false;
|
this.info.msg = "订单明细异常";
|
return this.info;
|
}
|
if (!model.quantityShipped) {
|
this.info.result = false;
|
this.info.msg = "签收数量不能为空!";
|
return this.info;
|
}
|
// 修改明细的已发货数量
|
await this.dbWrite.update(SaleOrderList, model.orderList_Id, {
|
quantityShipped: model.quantityShipped
|
});
|
}
|
// 修改主表的状态
|
await this.dbWrite.update(SaleOrder, orderInfo.order_Id, {
|
statusID: 18,
|
statusText: "已妥投"
|
});
|
this.info.result = true;
|
this.info.msg = "妥投确认成功!";
|
return this.info;
|
}
|
//#endregion
|
|
//#region 拣货开始方法
|
async pickingStart(orderPrintCode: string, printModel: SaleOrderPrint, printListModel: Array<SaleOrderPrintList>): Promise<ResultInfo> {
|
let { ctx } = this;
|
let userInfo = await ctx.helper.userInfo();
|
|
let model = await this.dbRead.findOne(SaleOrderPicking, {
|
orderPrintCode: orderPrintCode,
|
user_Id: userInfo.user_Id
|
});
|
if (model == null) {
|
model = new SaleOrderPicking();
|
model.createID = userInfo.user_Id;
|
model.creator = userInfo.userTrueName;
|
model.startDate = new Date();
|
model.orderPrint_Id = printModel.orderPrint_Id;
|
model.orderPrintCode = printModel.orderPrintCode;
|
model.orderType = printModel.orderType;
|
model.user_Id = userInfo.user_Id;
|
model.userTrueName = userInfo.userTrueName;
|
model.consignor_Id = printModel.consignor_Id;
|
model.consignorCode = printModel.consignorCode;
|
model.consignorName = printModel.consignorName;
|
model.orderPickingCode = await ctx.service.common.getCodeRegular(249);
|
model.storage_Id = printModel.storage_Id;
|
model.storageName = printModel.storageName;
|
|
model.platCorpName = userInfo.platCorpName;
|
model.platUserCode = userInfo.platUserCode;
|
model.platUserName = userInfo.platUserName;
|
model.platUser_Id = userInfo.platUser_Id;
|
model.userProductAlias = userInfo.userProductAlias;
|
model.userProductCode = userInfo.userProductCode;
|
model.userProduct_Id = userInfo.userProduct_Id;
|
|
model.statusText = "开始拣货";
|
|
let sql = `update Sale_OrderPrint set StatusID=5, StatusText='拣货中',PickingStatus='拣货中' Where orderPrint_Id=${printModel.orderPrint_Id};
|
update Sale_Order set StatusID=5, StatusText='拣货中'
|
Where order_Id in(select order_Id from Sale_OrderPrintList Where orderPrint_Id=${printModel.orderPrint_Id});`;
|
await this.dbWrite.query(sql);
|
|
for (let detailEntity of printListModel) {
|
await ctx.service.outbound.orderHelper.setStatusHistory(detailEntity.order_Id, 4, 5, "订单状态", "订单拣货");
|
}
|
await this.dbWrite.save(model);
|
}
|
|
this.info.result = true;
|
this.info.data = {
|
orderPicking_Id: model.orderPicking_Id
|
};
|
|
return this.info;
|
}
|
//#endregion
|
}
|