using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using NLog; using POSV.Entity; using POSV.Utils; using POSV.Entity.Pormotion; using Newtonsoft.Json.Linq; using System.Threading.Tasks; namespace POSV.ShoppingCart { public class OrderUtils { private static Logger logger = NLog.LogManager.GetCurrentClassLogger(); private static object _lock = new object(); private static OrderUtils _instance = null; public static OrderUtils Instance { get { if (_instance == null) { lock (_lock) { _instance = new OrderUtils(); } } return _instance; } } /// /// 收银小票的前缀<1>,格式为YYMMDDHHMM+POS编码+4位流水号 /// /// /// public Tuple GenerateTicketNoEx(int length = 4) { string serialNumber = string.Empty; string message = string.Empty; //获取消息中心配置 var messageCenter = Global.Instance.EnableServiceCenter; //应用了全局票号 var globalTicketNo = Global.Instance.GlobalConfigBoolValue(ConfigConstant.DEVICE_TICKETNO_ENABLE, false); if (messageCenter.Item1 && globalTicketNo) { //获取消息中心的流水号 var global = MessageCenterUtils.Instance.GetGlobalTicketNo(length); //获取成功 if (global.Item1) { serialNumber = global.Item3; //将消息中心的流水号更新到本次,避免获取失败时候本地流水相对连续 this.UpdateSerialNumber(ConfigConstant.GROUP_BUSINESS, ConfigConstant.VOUCHER_NO, serialNumber); } else { //获取流水号失败 serialNumber = string.Empty; } message = global.Item2; } else { //本地数据库获取 serialNumber = GenerateSerialNumber(4, ConfigConstant.GROUP_BUSINESS, ConfigConstant.VOUCHER_NO); message = "本地流水号获取成功"; } if (!string.IsNullOrEmpty(serialNumber)) { string result = string.Format("1{0}{1}{2}", DateTime.Now.ToString("yyMMddHHmm"), Global.Instance.Authc.PosNo, serialNumber); return new Tuple(true, message, result); } else { return new Tuple(false, message, string.Empty); } } /// /// 本地收银小票的前缀<1>,格式为YYMMDDHHMM+POS编码+4位流水号 /// /// public string GenerateTicketNo() { string serialNumber = GenerateSerialNumber(4, ConfigConstant.GROUP_BUSINESS, ConfigConstant.VOUCHER_NO); return string.Format("1{0}{1}{2}", DateTime.Now.ToString("yyMMddHHmm"), Global.Instance.Authc.PosNo, serialNumber); } /// /// 支付单的前缀<2>,格式为YYMMDDHHMM+POS编码+4位流水号 /// /// public string GeneratePayNo() { return string.Format("2{0}{1}{2}", DateTime.Now.ToString("yyMMddHHmm"), Global.Instance.Authc.PosNo, GenerateSerialNumber(4, ConfigConstant.GROUP_BUSINESS, ConfigConstant.PAY_NO)); } /// /// 交班小票的前缀<3>,格式为YYMMDDHHMM+POS编码+4位流水号 /// /// public string GenerateShiftNo() { return string.Format("3{0}{1}{2}", DateTime.Now.ToString("yyMMddHHmm"), Global.Instance.Authc.PosNo, GenerateSerialNumber(4, ConfigConstant.GROUP_BUSINESS, ConfigConstant.SHIFT_NO)); } /// /// 生成班次编号 /// /// public string GenerateBatchNo() { return string.Format("{0}", GenerateSerialNumber(4, ConfigConstant.GROUP_BUSINESS, ConfigConstant.BATCH_NO)); } public void UpdateSerialNumber(string group, string key, string val) { lock (Global.Instance.SyncLock) { string sql = string.Format(SqlConstant.ConfigQueryByGroupAndKey, group, key); Config config = null; using (var db = Global.Instance.OpenDataBase) { using (var transaction = db.GetTransaction()) { config = db.FirstOrDefault(sql); if (config == null) { config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.TenantId = Global.Instance.Worker.TenantId; config.Group = group; config.Keys = key; } config.Values = val; db.Save(config); transaction.Complete(); } } } } /// /// 生成系统流水号 /// /// public string GenerateSerialNumber(int len, string group, string key) { lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { using (var transaction = db.GetTransaction()) { string sql = string.Format(SqlConstant.ConfigQueryByGroupAndKey, group, key); Config config = db.FirstOrDefault(sql); int value = 0; if (config != null) { int.TryParse(config.Values, out value); if (value >= 9999) { value = 0; } } else { config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.TenantId = Global.Instance.Worker.TenantId; config.Group = group; config.Keys = key; } Interlocked.Increment(ref value); string result = value.ToString().PadLeft(len, '0'); //0003 config.Values = result; db.Save(config); transaction.Complete(); return result; } } } } /// /// 根据设置的位数获取最大数值 /// /// /// private int getMaxValueByLength(int len) { int maxVal = 0; switch (len) { case 1: { maxVal = 9; } break; case 2: { maxVal = 99; } break; case 3: { maxVal = 999; } break; case 4: { maxVal = 9999; } break; case 5: default: { maxVal = 99999; } break; } return maxVal; } /// /// 生成序号 /// /// /// public Tuple GenerateOrderNoEx() { string serialNumber = string.Empty; string message = string.Empty; //获取消息中心配置 var messageCenter = Global.Instance.EnableServiceCenter; //应用到全局序号 var globalOrderNo = Global.Instance.GlobalConfigBoolValue(ConfigConstant.DEVICE_ORDERNO_ENABLE, false); if (messageCenter.Item1 && globalOrderNo) { //序号的设置长度 int length = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_ORDERNO_LENGTH, 0); //每天生成的序号最小值 var initialValue = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_ORDERNO_BEGIN, 401);//Yao 2023/08/07 流水号更改为201开始 //获取消息中心的序号 var global = MessageCenterUtils.Instance.GetGlobalOrderNo(length, initialValue); //获取成功 if (global.Item1) { serialNumber = global.Item3; //将消息中心的流水号更新到本次,避免获取失败时候本地流水相对连续 this.UpdateSerialNumber(ConfigConstant.GROUP_BUSINESS, ConfigConstant.ORDER_NO, serialNumber); } else { //获取流水号失败 serialNumber = string.Empty; } message = global.Item2; } else { //本地数据库获取 serialNumber = GenerateOrderNo(); message = "本地序号获取成功"; } if (!string.IsNullOrEmpty(serialNumber)) { return new Tuple(true, message, serialNumber); } else { return new Tuple(false, message, string.Empty); } } /// /// 生成序号 /// /// public string GenerateOrderNo() { lock (Global.Instance.SyncLock) { int val = 0; //序号的设置长度 int len = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_ORDERNO_LENGTH, 0); //根据设置的位数获取对应的最大值 int maxVal = getMaxValueByLength(len); //Yao 2023/08/07 修改最大数为300 using (var db = Global.Instance.OpenDataBase) { using (var transaction = db.GetTransaction()) { string sql = string.Format(SqlConstant.ConfigQueryByGroupAndKey, ConfigConstant.GROUP_BUSINESS, ConfigConstant.ORDER_NO); Config config = db.FirstOrDefault(sql); if (config != null) { var date = DateTime.Now; DateTime.TryParse(config.ModifyDate, out date); //DateTime currentTime = DateTime.Now; //TimeSpan difference = currentTime - date; //int differenceInMinutes = (int)difference.TotalMinutes; //if (differenceInMinutes >= 0 && differenceInMinutes > 30)//Yao 2023/08/07 更改为不在一天,相差30分钟,就需要重新置 if (DateTime.Now.Date.CompareTo(date.Date) != 0) { //val = 0; //Yao 2023/08/07 修改为200开始 val = 400; } else { int.TryParse(config.Values, out val); } } else { config = new Config(); config.Id = IdWorkerUtils.Instance.NextId(); config.TenantId = Global.Instance.Worker.TenantId; config.Group = ConfigConstant.GROUP_BUSINESS; config.Keys = ConfigConstant.ORDER_NO; } Interlocked.Increment(ref val); //循环使用 if (maxVal != 0 && val > maxVal) { //val = 1; //Yao 2023/08/07 修改为401开始 val = 401; } //每天生成的序号最小值 var orderNoBegin = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_ORDERNO_BEGIN, 401);//Yao 2023/08/07 1改为401 //忽略最小值设置不正确 if (maxVal >= orderNoBegin && val < orderNoBegin) { val = orderNoBegin; } config.Values = val.ToString(); db.Save(config); transaction.Complete(); return val.ToString().PadLeft(len, '0'); } } } } /// /// 获取支付方式 /// /// /// public static List GetPayModeList() { lock (Global.Instance.SyncLock) { var result = new List(); using (var db = Global.Instance.OpenDataBase) { result = db.Query().ToList(); } return result; } } /// /// 获取充值支付参数 /// /// /// public static List GetRechargeParameterList() { lock (Global.Instance.SyncLock) { var result = new List(); using (var db = Global.Instance.OpenDataBase) { result = db.Query().ToList(); } return result; } } /// /// /// /// /// public static PayMode GetPayMode(string no) { return GetPayModeList().SingleOrDefault(x => no.Equals(x.No)); } /// /// /// /// /// public static RechargeParameter GetRechargeParameter(List signs) { RechargeParameter rechargeParameter = null; foreach (string str in signs) { rechargeParameter = GetRechargeParameterList().SingleOrDefault(x => str.Equals(x.Sign)); if (rechargeParameter != null) { break; } } return rechargeParameter; } /// /// 获取支付方式 /// /// /// public static List GetPayTypeList() { lock (Global.Instance.SyncLock) { var result = new List(); using (var db = Global.Instance.OpenDataBase) { result = db.Query().ToList(); } return result; } } /// /// 获取现金 /// /// public static PayMode GetDefaultPayMode() { return GetPayMode("01"); } /// /// 获取电话外卖挂账 /// /// public static PayMode GetDeliveryPayMode() { return GetPayMode("20"); } /// /// 获取离线支付挂账 /// /// public static PayMode GetOfflinePayMode() { return GetPayMode("31"); } /// /// 获取抹零 /// /// public static PayMode GetMalingPayMode() { return GetPayMode("06"); } /// /// 获取美团券支付方式 /// /// public static PayMode GetMeituanPayMode() { return GetPayMode("12"); } /// /// 将选择支付方式 转换 为 PayItem /// /// public static PayItem ToPayItem(PayMode type) { PayItem item = new PayItem(); item.Id = IdWorkerUtils.Instance.NextId(); item.TenantId = Global.Instance.Authc.TenantId; item.PayNo = OrderUtils.Instance.GeneratePayNo(); item.ShiftNo = Global.Instance.BusinessPlanLog.No; item.ShiftName = Global.Instance.BusinessPlanLog.Name; item.Name = type.Name; item.No = type.No; item.PointFlag = type.PointFlag; return item; } public static decimal MalingAmount(decimal receivableAmount, PayType type) { decimal maling = Convert.ToDecimal(0.00); //前台结算以下付款方式全额付款时实款实收:微信、支付宝、银行钱包、储值卡 var allow = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NOT_ALLOW_MANTISSA); //会员卡 02 //银联卡 03 //支付宝 04 //微信支付 05 if (allow && type != null) { if ("02".Equals(type.No) || "03".Equals(type.No) || "04".Equals(type.No) || "05".Equals(type.No)) { return maling; } } //默认因数,不扩大不缩小 decimal factor = Convert.ToDecimal(1.00); string mantissa = Global.Instance.GlobalConfigStringValue(ConfigConstant.CASHIER_MANTISSA); if (string.IsNullOrEmpty(mantissa)) { mantissa = "4";//抹掉角以下的金额 } //参与抹零计算的应收金额 = 整单金额合计 - 优惠合计 switch (mantissa) { case "0"://0-实款实收 factor = 1; maling = 0; break; case "1"://1-元以下的金额四舍五入 factor = 1; maling = receivableAmount * factor - Math.Floor(Math.Round(receivableAmount * factor, MidpointRounding.AwayFromZero)); break; case "2"://2-角以下的金额四舍五入 factor = 10; maling = receivableAmount * factor - Math.Floor(Math.Round(receivableAmount * factor, MidpointRounding.AwayFromZero)); break; case "3"://3-抹掉元以下的金额,舍弃小数部分 factor = 1; maling = receivableAmount * factor - Math.Floor(receivableAmount * factor); break; case "4"://4-抹掉角以下的金额 factor = 10; maling = receivableAmount * factor - Math.Floor(receivableAmount * factor); break; default: factor = 1; maling = 0; break; } return maling / factor; } /// /// 转为折后单价,保留4位小数位数 /// /// /// public static decimal ToDiscountPrice(decimal num) { return DecimalUtils.ToRound(num, 4); } /// /// 保留小数位数 /// /// 数字 /// 小数位数 /// public static decimal ToRound(decimal num) { int scale = Global.Instance.GlobalConfigIntValue(ConfigConstant.CASHIER_PRICE_DIGIT, 2); return DecimalUtils.ToRound(num, scale); } public static decimal ToRound(int num) { decimal result; decimal.TryParse(num.ToString(), out result); return ToRound(result); } /// /// 输入的折扣率,转换为友好显示 /// 输入0.8,转换为80 /// /// /// public static string ToDisplayRate(decimal rate) { int _rate = Convert.ToInt32(rate * 100); return (int)(_rate / 10) + ((_rate % 10) == 0 ? "" : ("." + _rate % 10)); } /// /// 订单保存前校验 /// /// public void OrderObjectCheck(OrderObject orderObject) { logger.Info(JsonUtils.Serialize(orderObject)); int itemGroupCount = orderObject.Items.GroupBy(x => x.Id).ToList().Count;//订单明细数量 int itemCount = orderObject.Items.Count();//订单明细数量 if (itemGroupCount != itemCount) { logger.Info(string.Format("订单详情ID重复了:订单编号{0}", orderObject.TradeNo)); foreach (OrderItem item in orderObject.Items) { var newItemId = IdWorkerUtils.Instance.NextId(); //做法明细 if (item.Flavors.Count > 0) { //修改单品优惠明细完成时间,确保主单的完成时间和单品优惠明细完成时间一致 foreach (var f in item.Flavors) { f.ItemId = newItemId; } } //单品优惠 if (item.Promotions.Count > 0) { //修改单品优惠明细完成时间,确保主单的完成时间和单品优惠明细完成时间一致 foreach (var p in item.Promotions) { p.ItemId = newItemId; } } item.Id = newItemId; } } } /// /// 保存整个订单 /// /// /// public bool SaveOrderObject(OrderObject orderObject) { if (Global.Instance.IsStudyMode()) { logger.Info("练习模式,订单<{0}>忽略入库保存", orderObject.TradeNo); return false; } lock (Global.Instance.SyncLock) { Stopwatch sw = new Stopwatch(); sw.Start(); logger.Info("开始保存订单信息"); bool isException = false; try { if (string.IsNullOrEmpty(orderObject.OrderNo)) { string orderNo = string.Empty; var order = OrderUtils.Instance.GenerateOrderNoEx(); if (order.Item1) { orderNo = order.Item3; } else { logger.Info("**采用本机序号**"); orderNo = OrderUtils.Instance.GenerateOrderNo(); } //订单序号 orderObject.OrderNo = orderNo; } var finishDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //订单完成时间 orderObject.FinishDate = finishDate; //判断门店是否是根据主食统计人数 if (Global.Instance.Worker.StoreInfo.StapleFlag == 1) { //获取订单中的主食数量 int people = 0; foreach (var item in orderObject.Items) { if (item.TapleFlag == 1) { people += Convert.ToInt32(item.Quantity - item.RefundQuantity); } } orderObject.People = people; } OrderObjectCheck(orderObject); using (var db = Global.Instance.OpenDataBase) { using (var trans = db.GetTransaction()) { //遍历获取成本价 foreach (OrderItem item in orderObject.Items) { ProductSpec productSpec = Global.ProductSpec._productSpecList?.Find(x => x.Id.Equals(item.SpecId)); if (productSpec != null) { item.CostPrice = productSpec.CostPrice; } else { item.CostPrice = 0.00M; } } //1、保存主单信息 db.Insert(orderObject); //如果是外卖订单更新配送付款状态 if (orderObject.OrderType == OrderType.微信点餐 && orderObject.OrderStatus == OrderStatus.已退单) { string backSql = "update pos_wx_waimai_order set status = 1 where ticketNo ='" + orderObject.OrgTradeNo + "';"; db.Execute(backSql); } //整单优惠 if (orderObject.Promotions.Count > 0) { //修改整单优惠明细完成时间,确保主单的完成时间和整单优惠明细完成时间一致 foreach (var p in orderObject.Promotions) { p.FinishDate = finishDate; } //2、保存主单优惠信息 db.InsertBatch(orderObject.Promotions); } //单品优惠 foreach (var item in orderObject.Items) { item.OrderId = orderObject.Id; //修改订单明细完成时间,确保主单的完成时间和订单明细完成时间一致 item.FinishDate = finishDate; //做法明细 if (item.Flavors.Count > 0) { //修改单品优惠明细完成时间,确保主单的完成时间和单品优惠明细完成时间一致 foreach (var f in item.Flavors) { f.FinishDate = finishDate; } //3、保存单品做法信息 db.InsertBatch(item.Flavors); } //支付分摊 if (item.ItemPayList != null && item.ItemPayList.Count > 0) { foreach (var p in item.ItemPayList) { p.FinishDate = finishDate; } //保存支付分摊明细 db.InsertBatch(item.ItemPayList); } //单品优惠 if (item.Promotions.Count > 0) { //修改单品优惠明细完成时间,确保主单的完成时间和单品优惠明细完成时间一致 foreach (var p in item.Promotions) { p.FinishDate = finishDate; } //4、保存单品优惠信息 db.InsertBatch(item.Promotions); } } //5、保存单品信息 db.InsertBatch(orderObject.Items); //修改支付明细完成时间,确保主单的完成时间和支付明细完成时间一致 foreach (var pay in orderObject.Pays) { pay.FinishDate = finishDate; #region subin 20231003 注释修改 //注释 //zhangy 2020-02-18 Add 档口结算信息赋默认值 //pay.Ext1 = "0"; //pay.Ext2 = "0"; //修改 pay.Ext1 = string.IsNullOrEmpty(pay.Ext1) ? "0" : pay.Ext1; pay.Ext2 = string.IsNullOrEmpty(pay.Ext2) ? "0" : pay.Ext2; #endregion //添加支付汇总的必填字段 var payMode = OrderUtils.GetPayMode(pay.No); if (payMode == null) { pay.IncomeFlag = 1; pay.OtherRateType = 0; pay.OtherRateValue = 0.00M; } else { pay.IncomeFlag = payMode.IncomeFlag; pay.OtherRateType = payMode.OtherRateType; pay.OtherRateValue = payMode.OtherRateValue; //zhangy 2020-02-18 Add 添加结算参数计算 SetPayModeDiscount(pay, payMode); ////zhangy 2020-02-18 Add 添加结算参数计算 #region zhangy 2020-02-18 Add 添加结算参数计算 //string settlement = payMode.Settlement; //logger.Info(">>>>>>结算参数:"+payMode.Settlement); //if (!string.IsNullOrEmpty(settlement)) //{ // var lists = JsonUtils.Deserialize>(settlement); // if(lists.Count > 0) // { // string date = Convert.ToDateTime(pay.FinishDate).ToString("yyyy-MM-dd"); // //查找最后一条 // var obj = lists.Where(x=> string.Compare(x.StartDate, date, StringComparison.Ordinal) <= 0 && string.Compare(x.EndDate, date, StringComparison.Ordinal) >= 0).LastOrDefault(); // if (obj != null) // { // // // decimal deductionRate = obj.Discount; // ///deductionRate // pay.Ext1 = Convert.ToString(deductionRate); // decimal chargeBack = DecimalUtils.ToRound(pay.PaidAmount * deductionRate,4); // pay.Ext2 = Convert.ToString(chargeBack); // } // } //} #endregion } } //6、保存支付明细信息 db.InsertBatch(orderObject.Pays); //7、保存外送单信息 if (orderObject.Delivery != null) { //订单完成时间 orderObject.Delivery.FinishDate = finishDate; db.Insert(orderObject.Delivery); } //8、保存耗料信息 List orderBurdenList = new List(); //第一步组装耗料数量 foreach (var item in orderObject.Items) { //第一步先看看商品是否是管理库存的直销品 var lists = Global.Product._productList; var selectProduct = new List(); selectProduct = lists.FindAll(x => x.Id.Equals(item.ProductId)); if (selectProduct != null && selectProduct.Count > 0) { ProductExt productExt = selectProduct[0]; if (productExt.StockFlag == 1) { OrderProductBurden orderProductBurden = new OrderProductBurden(); orderProductBurden.OrderId = orderObject.Id; orderProductBurden.TenantId = orderObject.TenantId; orderProductBurden.TradeNo = orderObject.TradeNo; orderProductBurden.BurdenProductId = item.ProductId; orderProductBurden.BurdenSpecId = item.SpecId; orderProductBurden.SalesUnitId = item.ProductUnitId; orderProductBurden.SalesAmount = item.Quantity - item.RefundQuantity; orderBurdenList.Add(orderProductBurden); } } //第二步获取门店耗料 StringBuilder sqlBuf = new StringBuilder(); sqlBuf.Append("select burdenProductId,burdenSpecId,salesUnitId,salesAmount from pos_product_burden where productId='{0}' and specId='{1}'"); string productBurdenSql = string.Format(sqlBuf.ToString(), item.ProductId, item.SpecId); List productBurdenList = db.Query(productBurdenSql).ToList(); if (productBurdenList != null && productBurdenList.Count > 0) { foreach (ProductBurden productBurden in productBurdenList) { OrderProductBurden orderProductBurden = new OrderProductBurden(); orderProductBurden.OrderId = orderObject.Id; orderProductBurden.TenantId = orderObject.TenantId; orderProductBurden.TradeNo = orderObject.TradeNo; orderProductBurden.BurdenProductId = productBurden.BurdenProductId; orderProductBurden.BurdenSpecId = productBurden.BurdenSpecId; orderProductBurden.SalesUnitId = productBurden.SalesUnitId; orderProductBurden.SalesAmount = productBurden.SalesAmount * (item.Quantity - item.RefundQuantity); orderBurdenList.Add(orderProductBurden); } } //做法耗料 foreach (var flavorItem in item.Flavors) { StringBuilder sqlBuf1 = new StringBuilder(); sqlBuf1.Append("select burdenProductId,burdenSpecId,salesUnitId,salesAmount from pos_make_burden where makeId='{0}'"); string makeBurdenSql = string.Format(sqlBuf1.ToString(), flavorItem.MakeId); List makeBurdenList = db.Query(makeBurdenSql).ToList(); if (makeBurdenList != null && makeBurdenList.Count > 0) { foreach (MakeBurden makeBurden in makeBurdenList) { OrderProductBurden orderProductBurden = new OrderProductBurden(); orderProductBurden.OrderId = orderObject.Id; orderProductBurden.TenantId = orderObject.TenantId; orderProductBurden.TradeNo = orderObject.TradeNo; orderProductBurden.BurdenProductId = makeBurden.BurdenProductId; orderProductBurden.BurdenSpecId = makeBurden.BurdenSpecId; orderProductBurden.SalesUnitId = makeBurden.SalesUnitId; orderProductBurden.SalesAmount = makeBurden.SalesAmount * (flavorItem.Quantity - flavorItem.RefundQuantity); orderBurdenList.Add(orderProductBurden); } } } } //第二部合并耗料数量 if (orderBurdenList != null && orderBurdenList.Count > 0) { List temList = orderBurdenList.OrderBy(x => x.BurdenSpecId).ToList(); Dictionary typeMap = new Dictionary(); string burdenProductId_temp = ""; string burdenSpecId_temp = ""; string salesUnitId_temp = ""; int i = 0; List> result = new List>(); decimal salesAmount = 0.00M; int listLength = temList.Count; foreach (OrderProductBurden orderProductBurden in temList) { string burdenSpecId = orderProductBurden.BurdenSpecId; if (!burdenSpecId_temp.Equals(burdenSpecId)) { if (i != 0) { typeMap.Add("orderId", orderProductBurden.OrderId); typeMap.Add("tenantId", orderProductBurden.TenantId); typeMap.Add("tradeNo", orderProductBurden.TradeNo); typeMap.Add("burdenProductId", burdenProductId_temp); typeMap.Add("burdenSpecId", burdenSpecId_temp); typeMap.Add("salesUnitId", salesUnitId_temp); typeMap.Add("salesAmount", salesAmount); result.Add(typeMap); //分类改变时,清除缓存 typeMap = new Dictionary(); } salesAmount = 0.00M; burdenProductId_temp = orderProductBurden.BurdenProductId; burdenSpecId_temp = orderProductBurden.BurdenSpecId; salesUnitId_temp = orderProductBurden.SalesUnitId; } salesAmount = salesAmount + orderProductBurden.SalesAmount; i = i + 1; if (i == listLength) { typeMap.Add("orderId", orderProductBurden.OrderId); typeMap.Add("tenantId", orderProductBurden.TenantId); typeMap.Add("tradeNo", orderProductBurden.TradeNo); typeMap.Add("burdenProductId", burdenProductId_temp); typeMap.Add("burdenSpecId", burdenSpecId_temp); typeMap.Add("salesUnitId", salesUnitId_temp); typeMap.Add("salesAmount", salesAmount); result.Add(typeMap); //分类改变时,清除缓存 typeMap = new Dictionary(); } } List list = new List(); foreach (Dictionary map in result) { OrderProductBurden entity = new OrderProductBurden(); entity.Id = IdWorkerUtils.Instance.NextId(); entity.StoreId = orderObject.StoreId; entity.OrderId = StringUtils.GetString(map["orderId"]); entity.TenantId = StringUtils.GetString(map["tenantId"]); entity.TradeNo = StringUtils.GetString(map["tradeNo"]); entity.BurdenProductId = StringUtils.GetString(map["burdenProductId"]); entity.BurdenSpecId = StringUtils.GetString(map["burdenSpecId"]); entity.SalesUnitId = StringUtils.GetString(map["salesUnitId"]); entity.SalesAmount = StringUtils.GetDecimal(map["salesAmount"]); list.Add(entity); } db.InsertBatch(list); } //9、保存分账信息 #region subin 2023-07-24 add 分账信息 //var productIds = ""; ////var accountIds = ""; //var splitStorePayLst = new List(); //try //{ // //var productIds=string.Join(this._orderObject.Items) // var splitFoodList = new List(); // var productIdList = orderObject.Items.Select(item => item.ProductId).Distinct(); // if (productIdList != null && productIdList.Count() > 0) // { // productIds = string.Join(",", productIdList); // splitFoodList = db.Query($"where goodId in ('{productIds.Replace(",", "','")}');").ToList(); // } // //if (!string.IsNullOrEmpty(productIds)) // //{ // // //accountIds = string.Join(",", splitFoodList.Select(item => item.AccountId).Distinct()); // //} // // var splitStoreIds = string.Join(",", splitFoodList.Select(item => item.ShopId).Distinct()); // #region MyRegion // //foreach (var pay in orderObject.Pays) // //{ // // foreach (var item in splitStoreIds.Split(',')) // // { // // splitStorePayLst.Add(new SplitStorePay // // { // // ClientId = "", // // ProgramId = "", // // TenantId = pay.TenantId, // // StoreId = orderObject.StoreId, // // SplitStoreId = item, // // StoreNo = orderObject.StoreNo, // // PayNo = pay.PayNo, // // TicketId = "", // // BusNo = pay.TradeNo, // // PayTypeNo = pay.No, // // PayType = pay.Name, // // Paid = 0, // // Rchange = 0, // // Money = 0, // // OverAmount = 0, // // VoucherNo = pay.TradeVoucherNo, // // PayDate = "", // // CardNo = "", // // IncomeFlag = pay.IncomeFlag, // // OtherRateType = pay.OtherRateType, // // OtherRateValue = pay.OtherRateValue, // // OtherRate = pay.OtherRate, // // PayClientType = -1, // // PayChannel = (int)pay.PayChannel, // // DeductionRate = 0, // // ChargeBack = 0, // // Memo = orderObject.Ext1, // // IsInvalid = "0", // // OrderId = pay.OrderId, // // PayId = pay.Id // // }); // // } // //} // //foreach (var item in orderObject.Items) // //{ // // foreach (var s in splitStoreIds.Split(',')) // // { // // //分店的商品Id集合 // // var splitProductIds = splitFoodList.Where(m => m.ShopId == s).Select(m => m.ProductId).Distinct(); // // //item.ItemPayList.Where() // // } // //} // #endregion // var splitShopList = db.Fetch(); // var _fromBizUserId = ""; // if (!string.IsNullOrEmpty(Global.Instance.Worker.StoreInfo.Ext1)) // { // _fromBizUserId = JsonUtils.Deserialize(Global.Instance.Worker.StoreInfo.Ext1).BizUserId; // } // if (orderObject.OrderType == OrderType.堂食 || orderObject.OrderType == OrderType.外带 || orderObject.OrderType == OrderType.餐桌) // { // int i = 0; // foreach (var item in orderObject.Items) // { // foreach (var p in item.ItemPayList) // { // var s = splitFoodList.FirstOrDefault(m => m.ProductId == p.ProductId); // if (s != null) // { // //var _fromBizUser = splitShopList.FirstOrDefault(m => m.Id == s.ShopId); // //_fromBizUserId = _fromBizUser != null ? _fromBizUser.BizUserId : ""; // var pay = orderObject.Pays.FirstOrDefault(m => m.Id == p.PayId); // var ssp = new SplitStorePay // { // Id = IdWorkerUtils.Instance.NextId(), // ClientId = "", // ProgramId = "", // TenantId = p.TenantId, // StoreId = orderObject.StoreId, // SplitStoreId = s.ShopId, // StoreNo = orderObject.StoreNo, // PayNo = pay.PayNo, // TicketId = "", // BusNo = pay.TradeNo, // PayTypeNo = p.No, // PayType = p.Name, // Paid = p.ShareAmount, // Rchange = 0, // Money = p.ShareAmount, // OverAmount = 0, // VoucherNo = pay.TradeVoucherNo, // PayDate = pay.PayTime, // CardNo = pay.CardNo, // IncomeFlag = pay.IncomeFlag, // OtherRateType = pay.OtherRateType, // OtherRateValue = pay.OtherRateValue, // OtherRate = pay.OtherRate, // PayClientType = -1, // PayChannel = (int)pay.PayChannel, // DeductionRate = 0, // ChargeBack = 0, // Memo = orderObject.Ext1, // IsInvalid = "0", // OrderId = pay.OrderId, // OrderItemId = item.Id, // PayId = p.PayId, // PayItemId = p.Id, // SyncStatus = 0, // UploadErrors = 0, // UploadStatus = 0, // UploadMessage = "", // ProductId = item.ProductId, // RefundAmount = 0, // FromBizUserld = _fromBizUserId, // OrderType = (int)orderObject.OrderType, // IsRefund = 0, // Quantity = (orderObject.OrgTradeNo != null && !"".Equals(orderObject.OrgTradeNo)) ? 0 : item.Quantity, // RefundQuantity = (orderObject.OrgTradeNo != null && !"".Equals(orderObject.OrgTradeNo)) ? item.MiddleRefundQuantity : 0, // }; // if (i == 0) // { // ssp.fee = string.IsNullOrEmpty(pay.Ext2) ? 0 : Convert.ToDecimal(pay.Ext2); // //ssp.Paid = ssp.Paid - ssp.fee; // } // splitStorePayLst.Add(ssp); // } // i++; // } // } // } // else if (orderObject.OrderType == OrderType.微信点餐) // { // int i = 0; // foreach (var pay in orderObject.Pays) // { // foreach (var item in orderObject.Items) // { // var s = splitFoodList.FirstOrDefault(m => m.ProductId == item.ProductId); // if (s != null) // { // //var _fromBizUser = splitShopList.FirstOrDefault(m => m.Id == s.ShopId); // //_fromBizUserId = _fromBizUser != null ? _fromBizUser.BizUserId : ""; // var ssp = new SplitStorePay // { // Id = IdWorkerUtils.Instance.NextId(), // ClientId = "", // ProgramId = "", // TenantId = item.TenantId, // StoreId = orderObject.StoreId, // SplitStoreId = s.ShopId, // StoreNo = orderObject.StoreNo, // PayNo = pay.PayNo, // TicketId = "", // BusNo = pay.TradeNo, // PayTypeNo = pay.No, // PayType = pay.Name, // Paid = item.TotalReceivableAmount, // Rchange = 0, // Money = item.TotalReceivableAmount, // OverAmount = 0, // VoucherNo = pay.TradeVoucherNo, // PayDate = pay.PayTime, // CardNo = pay.CardNo, // IncomeFlag = pay.IncomeFlag, // OtherRateType = pay.OtherRateType, // OtherRateValue = pay.OtherRateValue, // OtherRate = pay.OtherRate, // PayClientType = -1, // PayChannel = (int)pay.PayChannel, // DeductionRate = 0, // ChargeBack = 0, // Memo = orderObject.Ext1, // IsInvalid = "0", // OrderId = orderObject.Id, // PayId = pay.Id, // SyncStatus = 0, // UploadErrors = 0, // UploadStatus = 0, // UploadMessage = "", // ProductId = item.ProductId, // OrderItemId = item.Id, // PayItemId = "", // RefundAmount = 0, // //FromBizUserld = JsonUtils.Deserialize(Global.Instance.Worker.StoreInfo.Ext1).BizUserId, // FromBizUserld = _fromBizUserId, // OrderType = (int)orderObject.OrderType, // IsRefund = 0 // }; // splitStorePayLst.Add(ssp); // if (i == 0) // { // ssp.fee = string.IsNullOrEmpty(pay.Ext2) ? 0 : Convert.ToDecimal(pay.Ext2); // //ssp.Paid = ssp.Paid - ssp.fee; // } // } // i++; // } // } // } // var splitStoreProductLst = splitStorePayLst.Select(item => item.ProductId).Distinct().ToList(); // if (productIdList.Count() > splitStorePayLst.Count) // { // logger.Info($"订单[{orderObject.TradeNo}]分账数据异常!,订单菜品数量({productIds})>分店关联菜品数量({string.Join(",", splitStoreProductLst)})"); // } // if (splitStorePayLst.Count > 0) // { // //增加订单的分账总记录 // var pssp = new SplitStorePay // { // Id = IdWorkerUtils.Instance.NextId(), // ClientId = "", // ProgramId = "", // TenantId = Global.Instance.Worker.TenantId, // StoreId = Global.Instance.Worker.StoreId, // SplitStoreId = "", // StoreNo = Global.Instance.Worker.StoreInfo.No, // PayNo = splitStorePayLst[0].PayNo, // TicketId = "", // BusNo = orderObject.TradeNo, // PayTypeNo = splitStorePayLst.Where(m => m.PayTypeNo == "50").Count() > 0 ? "50" : "0", // PayType = splitStorePayLst.Where(m => m.PayTypeNo == "50").Count() > 0 ? "通联支付" : "", // Paid = splitStorePayLst.Sum(m => m.Paid), // Rchange = splitStorePayLst.Sum(m => m.Rchange), // Money = splitStorePayLst.Sum(m => m.Money), // OverAmount = splitStorePayLst.Sum(m => m.OverAmount), // VoucherNo = splitStorePayLst[0].VoucherNo, // PayDate = splitStorePayLst[0].PayDate, // CardNo = "", // IncomeFlag = 1, // OtherRateType = 0, // OtherRateValue = 0, // OtherRate = splitStorePayLst.Sum(m => m.OtherRate), // PayClientType = -1, // PayChannel = 50, // DeductionRate = 0, // ChargeBack = splitStorePayLst.Sum(m => m.ChargeBack), // Memo = orderObject.Ext1, // IsInvalid = "0", // OrderId = orderObject.Id, // PayId = "", // SyncStatus = 1, // UploadErrors = 0, // UploadStatus = 0, // UploadMessage = "", // ProductId = "", // OrderItemId = "", // PayItemId = "", // RefundAmount = splitStorePayLst.Sum(m => m.RefundAmount), // //FromBizUserld = JsonUtils.Deserialize(Global.Instance.Worker.StoreInfo.Ext1).BizUserId, // FromBizUserld = _fromBizUserId, // OrderType = (int)orderObject.OrderType, // IsRefund = 0, // fee = splitStorePayLst.Sum(m => m.fee) // }; // foreach (var item in splitStorePayLst) // { // item.Pid = pssp.Id; // } // splitStorePayLst.Add(pssp); // db.InsertBatch(splitStorePayLst); // logger.Info("有需要上传的营业分账数据,isHaveUpLoadSplitPay = true"); // Global.isHaveUpLoadSplitPay = true; // } // else // { // logger.Info($"订单[{orderObject.Id}],没有要分账的菜品信息,将不保存分账信息。"); // } //} //catch (Exception ex) //{ // logger.Error(ex, $"保存订单的分账信息异常,单号ID:{orderObject.Id}"); //} #endregion //更新是否有订单需要上传的状态 logger.Info("有需要上传的营业数据,isHaveUpLoadTicket = true"); Global.isHaveUpLoadTicket = true; Global.isHaveBurdenTicket = true; logger.Info("有需要同步到服务中心的订单,isHaveCenterTicket = true"); Global.isHaveCenterTicket = true; //订单保存成功更新核销状态 logger.Info("单号:[{0}]更改扫码支付状态 payStatus==>1......开始", string.Format("{0}_{1}", Global.Instance.BusinessPlanLog.StoreNo, orderObject.TradeNo)); string sql = "update pos_saoma_pay_ticket set payStatus =1 where orderNo = '{0}'"; sql = string.Format(sql, string.Format("{0}_{1}", Global.Instance.BusinessPlanLog.StoreNo, orderObject.TradeNo)); db.Execute(sql, null); logger.Info("单号:[{0}]更改扫码支付状态 payStatus==>1......更新成功", string.Format("{0}_{1}", Global.Instance.BusinessPlanLog.StoreNo, orderObject.TradeNo)); trans.Complete(); } } } catch (Exception ex) { isException = true; logger.Error(ex, "存储订单信息异常"); } finally { sw.Stop(); logger.Info("保存订单信息结束<{0}>", sw.ElapsedMilliseconds); //subin 20231025 注释,分账由实时改为交班时分账 //Task.Factory.StartNew(() => //{ // SplitPayUtils.Instance.SaveSplitPayInfo(orderObject); //}); //subin 20231025 注释 end } return isException; } } //zhangy 2020-02-18 Add 添加结算参数计算 public static void SetPayModeDiscount(PayItem pay, PayMode payMode) { var settlement = payMode.Settlement; logger.Info(">>>>>>结算参数:" + JsonUtils.Serialize(settlement)); #region subin 20231003 注释修改 //注释 //zhangy 2020-02-18 Add 档口结算信息赋默认值 //pay.Ext1 = "0"; //pay.Ext2 = "0"; //修改 pay.Ext1 = string.IsNullOrEmpty(pay.Ext1) ? "0" : pay.Ext1; pay.Ext2 = string.IsNullOrEmpty(pay.Ext2) ? "0" : pay.Ext2; #endregion if (settlement != null && settlement.Count > 0) { //var lists = JsonUtils.Deserialize>(settlement); string date = Convert.ToDateTime(pay.FinishDate).ToString("yyyy-MM-dd"); //查找最后一条 var obj = settlement.Where(x => string.Compare(x.StartDate, date, StringComparison.Ordinal) <= 0 && string.Compare(x.EndDate, date, StringComparison.Ordinal) >= 0).LastOrDefault(); if (obj != null) { // decimal deductionRate = obj.Discount; ///deductionRate pay.Ext1 = Convert.ToString(deductionRate); decimal chargeBack = DecimalUtils.ToRound(pay.PaidAmount * deductionRate, 4); pay.Ext2 = Convert.ToString(chargeBack); } } } /// /// 获取未上传记录的天数 /// /// /// public static List GetUnUpLoadDay() { List newList = new List(); try { using (var db = Global.Instance.OpenDataBase) { StringBuilder sqlBuld = new StringBuilder(); sqlBuld.Append(" select strftime('%Y-%m-%d',finishDate) from pos_order where syncStatus = 0 "); sqlBuld.Append(" and storeId = '{0}' "); sqlBuld.Append(" group by 1 "); string sql = string.Format(sqlBuld.ToString(), Global.Instance.Authc.StoreId); newList = db.Query(sql).ToList(); if (newList == null) { newList = new List(); } } } catch (Exception ex) { logger.Error(ex, "获取未上传数据天数失败"); } return newList; } public static OrderObject getOrderObjectByTranNo(string tradeNo) { OrderObject orderObject = null; try { //单据明细 var items = new List(); //支付明细 var pays = new List(); //主单优惠明细 var orderPromotions = new List(); //做法明细 var flavors = new List(); //单品优惠明细 var itemPromotions = new List(); //单品分摊明细 var itemPayList = new List(); //电话外送 OrderDelivery orderDelivery = null; using (var db = Global.Instance.OpenDataBase) { //主单数据 orderObject = db.FirstOrDefault("where tradeNo =@0;", tradeNo); if (orderObject == null) { return null; } var condition = " where orderId = '" + orderObject.Id + "';"; logger.Debug(condition); //单据明细 items = db.Query(condition).ToList(); logger.Debug("单据明细<{0}>", (items != null ? items.Count.ToString() : "*****")); //支付明细 pays = db.Query(condition).ToList(); logger.Debug("支付明细<{0}>", (pays != null ? pays.Count.ToString() : "*****")); //主单优惠明细 orderPromotions = db.Query(condition).ToList(); logger.Debug("主单优惠明细<{0}>", (orderPromotions != null ? orderPromotions.Count.ToString() : "*****")); //做法明细 flavors = db.Query(condition).ToList(); logger.Debug("做法明细<{0}>", (flavors != null ? flavors.Count.ToString() : "*****")); //单品优惠明细 itemPromotions = db.Query(condition).ToList(); logger.Debug("单品优惠明细<{0}>", (itemPromotions != null ? itemPromotions.Count.ToString() : "*****")); //外送明细 orderDelivery = db.FirstOrDefault(condition); //单品分摊明细 itemPayList = db.Query(condition).ToList(); } //外送详情 orderObject.Delivery = orderDelivery; //订单明细 orderObject.Items = items; //将支付方式附加到主单 orderObject.Pays = pays; //将主单优惠附加到主单 orderObject.Promotions = orderPromotions; foreach (var item in orderObject.Items) { List flavorsList = flavors.FindAll(x => x.ItemId == item.Id); if (orderObject.OrderStatus == OrderStatus.已退单) { foreach (FlavorItem flavorItem in flavorsList) { flavorItem.isBackTicket = true; } } item.Flavors = flavorsList; item.Promotions = itemPromotions.FindAll(x => x.ItemId == item.Id); //单品支付方式分摊 if (itemPayList != null && itemPayList.Count > 0 && itemPayList.Exists(x => x.ItemId == item.Id)) { item.ItemPayList = itemPayList.FindAll(x => x.ItemId == item.Id); } else { item.ItemPayList = new List(); } } } catch (Exception ex) { logger.Error(ex, "获取订单信息异常"); } return orderObject; } /// /// 保存挂单信息 /// /// /// public Tuple SaveOrderTemp(OrderObject orderObject) { lock (Global.Instance.SyncLock) { OrderTemp temp = null; Stopwatch sw = new Stopwatch(); sw.Start(); logger.Info("开始保存挂单数据"); bool isSucc = false; try { temp = new OrderTemp(); temp.Id = IdWorkerUtils.Instance.NextId(); temp.TenantId = orderObject.TenantId; temp.StoreId = Global.Instance.Worker.StoreId; temp.OrderId = orderObject.Id; temp.TradeNo = orderObject.TradeNo; temp.TableNo = orderObject.TableNo; temp.TableName = orderObject.TableName; temp.Paid = orderObject.PaidAmount; temp.TotalQuantity = orderObject.TotalQuantity; temp.WorkerName = Global.Instance.Worker.Name; temp.WorkerNo = Global.Instance.Worker.No; temp.OrderJson = JsonUtils.Serialize(orderObject); temp.SaleDate = orderObject.SaleDate; temp.PosNo = Global.Instance.Authc.PosNo; using (var db = Global.Instance.OpenDataBase) { using (var trans = db.GetTransaction()) { db.Save(temp); trans.Complete(); } } isSucc = true; } catch (Exception ex) { logger.Error(ex, "保存挂单数据异常"); isSucc = false; } finally { sw.Stop(); logger.Info("保存挂单结束<{0}>", sw.ElapsedMilliseconds); } return new Tuple(isSucc, temp); } } } }