You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1255 lines
69 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using NLog;
using POSV.Entity;
using POSV.HttpApi;
using POSV.HttpResponse;
using POSV.MessageEvent;
using POSV.ShoppingCart;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace POSV.Utils
{
public class SplitPayUtils : BaseApi
{
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
private static object _lock = new object();
private static SplitPayUtils _instance = null;
public static SplitPayUtils Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
_instance = new SplitPayUtils();
}
}
return _instance;
}
}
public bool SaveSplitPayInfo(OrderObject orderObject)
{
Stopwatch sw = new Stopwatch();
var isExist = false;
try
{
sw.Start();
logger.Info($"开始保存订单<{orderObject.TradeNo}>的分账信息");
var _pid = IdWorkerUtils.Instance.NextId();
using (var db = Global.Instance.OpenDataBase)
{
using (var trans = db.GetTransaction())
{
var tmpLst = db.Query<SplitStorePay>($"where busNo='{orderObject.TradeNo}'").ToList();
if (tmpLst != null)
{
if (tmpLst.Count() > 0)
{
isExist = true;
logger.Info($"订单<{orderObject.TradeNo}>的分账信息已存在,不需要分账");
if (orderObject.IsSplited == 0)
{
var sql = $"update pos_order set isSplited=1 where id={orderObject.Id};";
logger.Info($"日订单<{orderObject.TradeNo}>分账信息已存在,更改分账状态isSplited==>1");
db.Execute(sql);
}
}
}
if (!isExist)
{
#region subin 2023-07-24 add 分账信息
var productIds = "";
//var accountIds = "";
var splitStorePayLst = new List<SplitStorePay>();
var splitFoodList = new List<SplitFoodAccount>();
var productIdList = orderObject.Items.Select(item => item.ProductId).Distinct();
if (productIdList != null && productIdList.Count() > 0)
{
productIds = string.Join(",", productIdList);
splitFoodList = db.Query<SplitFoodAccount>($"where goodId in ('{productIds.Replace(",", "','")}');").ToList();
}
var _fromBizUserId = "";
if (!string.IsNullOrEmpty(Global.Instance.Worker.StoreInfo.Ext1))
{
_fromBizUserId = JsonUtils.Deserialize<StoreAllinParams>(Global.Instance.Worker.StoreInfo.Ext1).BizUserId;
}
else
{
logger.Info($"订单<{orderObject.TradeNo}>分账未配置门店扩展信息Ext1");
}
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)
{
//if (p.No != "50") continue;
var s = splitFoodList.FirstOrDefault(m => m.ProductId == p.ProductId);
if (s != null)
{
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 = orderObject.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.FinishDate,
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 = item.MiddleRefundQuantity * item.SalePrice,
FromBizUserld = _fromBizUserId,
OrderType = (int)orderObject.OrderType,
IsRefund = item.MiddleRefundQuantity > 0 ? 1 : 0,
Quantity = item.Quantity,
RefundQuantity = item.MiddleRefundQuantity,
Pid = _pid
};
if (i == 0)
{
ssp.fee = string.IsNullOrEmpty(pay.Ext2) ? 0 : Convert.ToDecimal(pay.Ext2);
//ssp.Paid = ssp.Paid - ssp.fee;
}
splitStorePayLst.Add(ssp);
//logger.Info($"订单<{orderObject.TradeNo}>[orderType:{orderObject.OrderType}]分账组装数据data{JsonUtils.Serialize(ssp)}");
}
i++;
}
}
}
else if (orderObject.OrderType == OrderType.)
{
int i = 0;
var splitShopList = db.Fetch<SplitShopAccount>();
foreach (var pay in orderObject.Pays)
{
//if (pay.No != "50") continue;
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 = orderObject.TicketId,
BusNo = pay.TradeNo,
PayTypeNo = pay.No,
PayType = pay.Name,
Paid = item.TotalAmonut,
Rchange = 0,
Money = item.TotalAmonut,
OverAmount = 0,
VoucherNo = pay.TradeVoucherNo,
PayDate = pay.FinishDate,
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 = item.MiddleRefundQuantity * item.SalePrice,
//FromBizUserld = JsonUtils.Deserialize<StoreAllinParams>(Global.Instance.Worker.StoreInfo.Ext1).BizUserId,
FromBizUserld = _fromBizUserId,
OrderType = (int)orderObject.OrderType,
IsRefund = item.MiddleRefundQuantity > 0 ? 1 : 0,
Quantity = item.Quantity,
RefundQuantity = item.MiddleRefundQuantity,
Pid = _pid
};
if (i == 0)
{
ssp.fee = string.IsNullOrEmpty(pay.Ext2) ? 0 : Convert.ToDecimal(pay.Ext2);
//ssp.Paid = ssp.Paid - ssp.fee;
}
splitStorePayLst.Add(ssp);
//logger.Info($"订单<{orderObject.TradeNo}>[orderType:{orderObject.OrderType}]分账组装数据data{JsonUtils.Serialize(ssp)}");
}
i++;
}
}
}
else if (orderObject.OrderType == OrderType.)
{
int i = 0;
var splitShopList = db.Fetch<SplitShopAccount>();
foreach (var pay in orderObject.Pays)
{
//if (pay.No != "50") continue;
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 = orderObject.TicketId,
BusNo = pay.TradeNo,
PayTypeNo = pay.No,
PayType = pay.Name,
Paid = item.TotalAmonut,
Rchange = 0,
Money = item.TotalAmonut,
OverAmount = 0,
VoucherNo = pay.TradeVoucherNo,
PayDate = pay.FinishDate,
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 = item.RefundQuantity * item.SalePrice,
//FromBizUserld = JsonUtils.Deserialize<StoreAllinParams>(Global.Instance.Worker.StoreInfo.Ext1).BizUserId,
FromBizUserld = _fromBizUserId,
OrderType = (int)orderObject.OrderType,
IsRefund = item.RefundQuantity > 0 ? 1 : 0,
Quantity = item.Quantity,
RefundQuantity = item.RefundQuantity,
Pid = _pid
};
if (i == 0)
{
ssp.fee = string.IsNullOrEmpty(pay.Ext2) ? 0 : Convert.ToDecimal(pay.Ext2);
//ssp.Paid = ssp.Paid - ssp.fee;
}
splitStorePayLst.Add(ssp);
//logger.Info($"订单<{orderObject.TradeNo}>[orderType:{orderObject.OrderType}]分账组装数据data{JsonUtils.Serialize(ssp)}");
}
i++;
}
}
}
var splitStoreProductLst = splitStorePayLst.Select(item => item.ProductId).Distinct().ToList();
if (productIdList.Count() > splitStorePayLst.Count)
{
isExist = true;
logger.Info($"订单<{orderObject.TradeNo}>分账数据异常!,订单菜品数量({productIds}>分店关联菜品数量({string.Join(",", splitStoreProductLst)})");
}
if (splitStorePayLst.Count > 0)
{
//增加订单的分账总记录
var pssp = new SplitStorePay
{
Id = _pid,
ClientId = "",
ProgramId = "",
TenantId = Global.Instance.Worker.TenantId,
StoreId = Global.Instance.Worker.StoreId,
SplitStoreId = "",
StoreNo = Global.Instance.Worker.StoreInfo.No,
PayNo = splitStorePayLst[0].PayNo,
TicketId = orderObject.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 = 0,//0-新增,1-已同步,2-问题单
UploadErrors = 0,
UploadStatus = 0,
UploadMessage = "",
ProductId = "",
OrderItemId = "",
PayItemId = "",
RefundAmount = splitStorePayLst.Sum(m => m.RefundAmount),
//FromBizUserld = JsonUtils.Deserialize<StoreAllinParams>(Global.Instance.Worker.StoreInfo.Ext1).BizUserId,
FromBizUserld = _fromBizUserId,
OrderType = (int)orderObject.OrderType,
IsRefund = splitStorePayLst.Where(m => m.IsRefund == 1).Count() > 0 ? 1 : 0,
fee = splitStorePayLst.Sum(m => m.fee),
Quantity = splitStorePayLst.Sum(m => m.Quantity),
RefundQuantity = splitStorePayLst.Sum(m => m.RefundQuantity)
};
splitStorePayLst.Add(pssp);
db.InsertBatch<SplitStorePay>(splitStorePayLst.OrderBy(m => m.Id));
//logger.Info("有需要上传的营业分账数据,isHaveUpLoadSplitPay = true");
Global.isHaveUpLoadSplitPay = true;
trans.Complete();
}
else
{
isExist = true;
logger.Info($"订单<{orderObject.TradeNo}没有要分账的菜品信息,将不保存分账信息。");
}
#endregion
}
else
{
trans.Complete();
}
}
}
logger.Info($"完成保存订单<{orderObject.TradeNo}>的分账信息");
}
catch (Exception ex)
{
isExist = true;
logger.Error(ex, $"保存订单<{orderObject.TradeNo}的分账信息异常");
}
finally
{
sw.Stop();
logger.Info($"保存订单<{orderObject.TradeNo}>的分账信息时长<{sw.ElapsedMilliseconds}>");
}
return isExist;
}
/// <summary>
///
/// </summary>
/// <param name="orderObject">原订单信息</param>
/// <param name="_BackOrderObject">退款订单信息</param>
public void UpdateRefund(OrderObject orderObject, OrderObject backOrderObject)
{
var oldSplitPay = new SplitStorePay();
var updateData = new List<SplitStorePay>();
var SplitStorePayEntityLst = new List<SplitStorePayEntity>();
Stopwatch sw = new Stopwatch();
sw.Start();
logger.Info("退款成功后开始修改分账信息");
try
{
using (var db = Global.Instance.OpenDataBase)
{
var splitPayLst = db.Fetch<SplitStorePay>("where orderId=@0;", orderObject.Id);
decimal fee = 0;
var allinPay = backOrderObject.Pays.FirstOrDefault(m => m.No == "50");
if (allinPay != null)
{
var str = allinPay.Ext2;
if (!string.IsNullOrEmpty(str))
{
fee = Convert.ToDecimal(str);
}
}
if (backOrderObject.OrderType == OrderType. || backOrderObject.OrderType == OrderType. || backOrderObject.OrderType == OrderType.)
{
foreach (var item in backOrderObject.Items)
{
//var splitPay = splitPayLst.FirstOrDefault(m => m.OrderId == orderObject.Id && m.OrderItemId == item.Id && m.PayItemId == pay.Id);
var splitPay = splitPayLst.FirstOrDefault(m => m.OrderId == orderObject.Id && m.ProductId == item.ProductId);
if (splitPay != null)
{
splitPay.IsRefund = 1;
splitPay.RefundAmount += item.TotalAmonut;
splitPay.RefundQuantity += item.RefundQuantity;
updateData.Add(splitPay);
var parent = splitPayLst.FirstOrDefault(m => m.Id == splitPay.Pid);
if (parent != null)
{
parent.IsRefund = 1;
parent.RefundAmount += item.TotalAmonut;
parent.RefundQuantity += item.RefundQuantity;
updateData.Add(parent);
}
if (!string.IsNullOrEmpty(splitPay.TicketId) && splitPay.SyncStatus == 1)
{
var entity = new SplitStorePayEntity
{
Id = splitPay.Id,
ClientId = splitPay.ClientId,
ProgramId = splitPay.ProductId,
TenantId = splitPay.TenantId,
StoreId = splitPay.StoreId,
SplitStoreId = splitPay.SplitStoreId,
StoreNo = splitPay.StoreNo,
PayNo = splitPay.PayNo,
TicketId = splitPay.TicketId,
BusNo = splitPay.BusNo,
PayTypeNo = splitPay.PayTypeNo,
PayType = splitPay.PayType,
Paid = splitPay.Paid,
Rchange = splitPay.Rchange,
Money = splitPay.Money,
OverAmount = splitPay.OverAmount,
VoucherNo = splitPay.VoucherNo,
PayDate = splitPay.PayDate,
CardNo = splitPay.CardNo,
IncomeFlag = splitPay.IncomeFlag,
OtherRateType = splitPay.OtherRateType,
OtherRateValue = splitPay.OtherRateValue,
OtherRate = splitPay.OtherRate,
PayClientType = splitPay.PayClientType,
PayChannel = splitPay.PayChannel,
DeductionRate = splitPay.DeductionRate,
ChargeBack = splitPay.ChargeBack,
Memo = splitPay.Memo,
IsInvalid = splitPay.IsInvalid,
OrderId = splitPay.OrderId,
OrderItemId = splitPay.OrderItemId,
PayId = splitPay.PayId,
PayItemId = splitPay.PayItemId,
SyncStatus = splitPay.SyncStatus,
UploadErrors = splitPay.UploadErrors,
UploadStatus = splitPay.UploadStatus,
UploadMessage = splitPay.UploadMessage,
ProductId = splitPay.ProductId,
RefundAmount = splitPay.RefundAmount,
FromBizUserld = splitPay.FromBizUserld,
OrderType = splitPay.OrderType,
IsRefund = splitPay.IsRefund,
Quantity = splitPay.Quantity,
RefundQuantity = splitPay.RefundQuantity,
TableNo = orderObject.TableNo,
People = orderObject.People.ToString(),
OrdTicketId = orderObject.TicketId,
WorkerNo = orderObject.WorkerNo,
UploadErrCode = splitPay.UploadErrCode,
UploadErrMessage = splitPay.UploadErrMessage,
UploadTime = splitPay.UploadTime,
fee = splitPay.fee,
Goodid = splitPay.ProductId,
//UnitPrice=""
};
SplitStorePayEntityLst.Add(entity);
}
}
}
}
else if (backOrderObject.OrderType == OrderType.)
{
foreach (var item in backOrderObject.Items)
{
var splitPay = splitPayLst.FirstOrDefault(m => m.OrderId == orderObject.Id && m.ProductId == item.ProductId);
if (splitPay != null)
{
splitPay.IsRefund = 1;
splitPay.RefundAmount += item.TotalAmonut * -1;
splitPay.RefundQuantity = item.RefundQuantity;
updateData.Add(splitPay);
var parent = splitPayLst.FirstOrDefault(m => m.Id == splitPay.Pid);
if (parent != null)
{
parent.IsRefund = 1;
parent.RefundAmount += splitPay.RefundAmount;
parent.RefundQuantity += item.MiddleRefundQuantity;
//parent.fee += fee;
updateData.Add(parent);
}
if (!string.IsNullOrEmpty(splitPay.TicketId) && splitPay.SyncStatus == 1)
{
var entity = new SplitStorePayEntity
{
Id = splitPay.Id,
ClientId = splitPay.ClientId,
ProgramId = splitPay.ProductId,
TenantId = splitPay.TenantId,
StoreId = splitPay.StoreId,
SplitStoreId = splitPay.SplitStoreId,
StoreNo = splitPay.StoreNo,
PayNo = splitPay.PayNo,
TicketId = splitPay.TicketId,
BusNo = splitPay.BusNo,
PayTypeNo = splitPay.PayTypeNo,
PayType = splitPay.PayType,
Paid = splitPay.Paid,
Rchange = splitPay.Rchange,
Money = splitPay.Money,
OverAmount = splitPay.OverAmount,
VoucherNo = splitPay.VoucherNo,
PayDate = splitPay.PayDate,
CardNo = splitPay.CardNo,
IncomeFlag = splitPay.IncomeFlag,
OtherRateType = splitPay.OtherRateType,
OtherRateValue = splitPay.OtherRateValue,
OtherRate = splitPay.OtherRate,
PayClientType = splitPay.PayClientType,
PayChannel = splitPay.PayChannel,
DeductionRate = splitPay.DeductionRate,
ChargeBack = splitPay.ChargeBack,
Memo = splitPay.Memo,
IsInvalid = splitPay.IsInvalid,
OrderId = splitPay.OrderId,
OrderItemId = splitPay.OrderItemId,
PayId = splitPay.PayId,
PayItemId = splitPay.PayItemId,
SyncStatus = splitPay.SyncStatus,
UploadErrors = splitPay.UploadErrors,
UploadStatus = splitPay.UploadStatus,
UploadMessage = splitPay.UploadMessage,
ProductId = splitPay.ProductId,
RefundAmount = splitPay.RefundAmount,
FromBizUserld = splitPay.FromBizUserld,
OrderType = splitPay.OrderType,
IsRefund = splitPay.IsRefund,
Quantity = splitPay.Quantity,
RefundQuantity = splitPay.RefundQuantity,
TableNo = orderObject.TableNo,
People = orderObject.People.ToString(),
OrdTicketId = orderObject.TicketId,
WorkerNo = orderObject.WorkerNo,
UploadErrCode = splitPay.UploadErrCode,
UploadErrMessage = splitPay.UploadErrMessage,
UploadTime = splitPay.UploadTime,
fee = splitPay.fee,
Goodid = splitPay.ProductId,
//UnitPrice=""
};
SplitStorePayEntityLst.Add(entity);
}
}
}
}
var feeSplitPay = splitPayLst.FirstOrDefault(m => m.fee > 0 && m.Pid != null);
if (feeSplitPay != null)
{
feeSplitPay.IsRefund = 1;
feeSplitPay.fee -= Math.Abs(fee);
updateData.Add(feeSplitPay);
var parent = splitPayLst.FirstOrDefault(m => m.Id == feeSplitPay.Pid);
if (parent != null)
{
parent.fee -= Math.Abs(fee);
updateData.Add(parent);
}
}
using (var trans = db.GetTransaction())
{
foreach (var item in updateData)
{
db.Update(item);
}
trans.Complete();
//logger.Info($"退款成功后更新本地分账信息成功json" + JsonUtils.Serialize(updateData));
logger.Info($"退款成功后,更新本地分账信息:成功");
}
}
}
catch (Exception ex)
{
logger.Error(ex, $"退款成功后修改分账信息错误,订单号:{backOrderObject.TradeNo},原订单号:{orderObject.TradeNo}");
}
finally
{
sw.Stop();
logger.Info("退款成功后本地修改分账信息结束<{0}>", sw.ElapsedMilliseconds);
}
if (SplitStorePayEntityLst.Count > 0)
{
sw.Start();
logger.Info("退款成功后开始修改服务端分账信息");
var api = new SplitPayApi();
foreach (var entity in SplitStorePayEntityLst)
{
var result = api.UpdateSplitPay(entity);
if (result.Item1)
{
//logger.Info($"退款成功后更新服务端原分账信息成功json" + JsonUtils.Serialize(entity));
logger.Info($"退款成功后,更新服务端原分账信息:成功。");
}
else
{
//logger.Info($"退款成功后更新服务端原分账信息失败json" + JsonUtils.Serialize(entity));
logger.Info($"退款成功后,更新服务端原分账信息:失败。");
}
Thread.Sleep(100);
}
sw.Stop();
logger.Info("退款成功后修改服务端分账信息结束<{0}>", sw.ElapsedMilliseconds);
}
else
{
logger.Info("退款成功后未查询到服务端分账信息,不做更新");
}
}
public bool Order2Split(DateTime date)
{
lock (Global.Instance.SyncLock)
{
bool isException = false;
var count = 0;
var sDate = date.ToString("yyyy-MM-dd 00:00:00");
var eDate = date.AddDays(1).ToString("yyyy-MM-dd 00:00:00");
logger.Info($"开始日订单[{date.ToString("yyyy-MM-dd")}]的分账信息存储处理...");
var proValue = 0;
var proMaxValue = 400;
Stopwatch sw = new Stopwatch();
sw.Start();
var pageSize = 150;
var lists = new List<OrderObject>();
//单据明细
var items = new List<OrderItem>();
//支付明细
var pays = new List<PayItem>();
//支付方式分摊明细
var itemPays = new List<OrderItemPay>();
var index = 0;
try
{
while (index < 2)
{
using (var db = Global.Instance.OpenDataBase)
{
//var delSql = "delete from pos_split_store_pay where syncStatus = 1 and uploadStatus = 1;";
//db.Execute(delSql);
count = db.Query<OrderObject>($"where isSplited = 0 and finishDate between '{sDate}' and '{eDate}';").Count();
//主单数据
//lists = db.Query<OrderObject>("where syncStatus = 0 and uploadErrors < 3000 order by uploadErrors limit @0;", 1).ToList();
var tmpPress = 0;
if (count != 0)
{
tmpPress = proMaxValue / 2 / count == 0 ? 1 : proMaxValue / 2 / count;
}
var pageCount = count % pageSize != 0 ? (count / pageSize) + 1 : count / pageSize;
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}]<{count}>条,页尺寸<{pageSize}>,共<{pageCount}>页");
var sqlList = new ConcurrentQueue<string>();
for (int i = 0; i < pageCount; i++)
{
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}],分账[index:{index + 1}]第<{i + 1}>页订单数据");
lists = db.Query<OrderObject>($"where isSplited = 0 and finishDate between '{sDate}' and '{eDate}' limit ({i * pageSize}), {pageSize};").ToList();
var ids = string.Join("','", lists.ConvertAll(x => x.Id).ToArray());
var nos = string.Join("','", lists.ConvertAll(x => x.TradeNo).ToArray());
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}],分账[index:{index + 1}]第<{i + 1}>页订单数据:{nos}");
var condition = " where orderId in ('" + ids + "');";
//单据明细
items = db.Query<OrderItem>(condition).ToList();
//支付明细
pays = db.Query<PayItem>(condition).ToList();
itemPays = db.Query<OrderItemPay>(condition).ToList();
foreach (var orderObject in lists)
{
orderObject.Items = items.FindAll(x => x.OrderId == orderObject.Id);
//将支付方式附加到主单
orderObject.Pays = pays.FindAll(x => x.OrderId == orderObject.Id);
foreach (var item in orderObject.Items)
{
item.ItemPayList = itemPays.FindAll(x => x.OrderId == orderObject.Id & x.ItemId == item.Id);
}
}
if (lists.Count > 0)
{
var p = 0;
foreach (var orderObject in lists)
{
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}]<{orderObject.TradeNo}>分账信息处理...");
var isExist = SaveSplitPayInfo(orderObject);
if (!isExist)
{
var sql = $"update pos_order set isSplited=1 where id={orderObject.Id};";
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}]<{orderObject.TradeNo}>更改分账状态isSplited==>1");
sqlList.Enqueue(sql);
}
else
{
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}]<{orderObject.TradeNo}>的分账信息存储异常");
}
Thread.Sleep(100);
//if (proValue < proMaxValue / (2 - index))
// proValue = (proMaxValue / (2 - index) * index) + tmpPress * ((p + 1) + pageSize * i);
proValue++;
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
p++;
}
}
else
{
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}],[index:{index + 1}]第<{i + 1}>页订单数据无可分账数据");
//proValue = pageSize * (i + 1);
//if (proValue < proMaxValue / (2 - index))
//{
// MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
//}
//else
//{
// MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proMaxValue / (2 - index));
//}
proValue = count * (index + 1);
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
}
}
SqliteUtils.ExecuteTransaction(sqlList);
index++;
}
}
}
catch (Exception ex)
{
isException = true;
logger.Error(ex, "日订单的分账信息存储错误<{0}>");
}
finally
{
sw.Stop();
logger.Info("日订单<{0}>的分账信息存储结束<{1}>", count, sw.ElapsedMilliseconds);
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, count * 2);
}
return isException;
}
}
public Tuple<bool, string> SplitData2Server(DateTime date, int proIndexValue = 0)
{
Tuple<bool, string> result = null;
var sDate = date.ToString("yyyy-MM-dd 00:00:00");
var eDate = date.AddDays(1).ToString("yyyy-MM-dd 00:00:00");
logger.Info($"开始日订单[{date.ToString("yyyy-MM-dd")}]的分账信息上传...");
var pageSize = 1500;
Stopwatch sw = new Stopwatch();
sw.Start();
int index = 0;
//proIndexValue = 401;
var proValue = proIndexValue;
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
var proMaxValue = 990;
var flg = false;
var tmpPress = 0;
lock (Global.Instance.SyncLock)
{
while (index < 3)
{
tmpPress = proIndexValue + (proMaxValue - proIndexValue) / (3 - index);
var icount = 0;
var count = 0;
var total = 0;
try
{
using (var db = Global.Instance.OpenDataBase)
{
count = db.Query<SplitStorePay>($"where syncStatus = 0 and uploadStatus < 4 and pid isnull and payDate between '{sDate}' and '{eDate}' order by payDate;").ToList().Count;
//count = db.Query<SplitStorePay>($"where uploadStatus < 4 and pid isnull and payDate between '{sDate}' and '{eDate}' order by payDate;").ToList().Count;
if (count > 0)
{
var pageCount = count % pageSize != 0 ? count / pageSize + 1 : count / pageSize;
//tmpPress = tmpPress / count == 0 ? 1 : tmpPress / count;
for (int i = 0; i < pageCount; i++)
{
var condition = $" where syncStatus = 0 and uploadStatus < 4 and pid is null and payDate between '{sDate}' and '{eDate}' order by payDate limit {pageSize};";
//var condition = $" where uploadStatus < 4 and pid is null and payDate between '{sDate}' and '{eDate}' order by payDate limit {pageSize};";
var pSplitLst = db.Query<SplitStorePay>(condition).ToList();
var list = new ConcurrentQueue<string>();
foreach (var item in pSplitLst)
{
StringBuilder strBil = new StringBuilder();
strBil.Append("select ord.ticketId as ordTicketId,ord.tableNo,ord.people,ord.workerNo,oi.price as unitPrice,oi.productId as goodid,ssp.* from pos_split_store_pay ssp ");
strBil.Append("left join pos_order_item oi on oi.id=ssp.orderItemId and oi.productId=ssp.productId ");
strBil.Append("left join pos_order ord on ord.id=ssp.orderId ");
strBil.Append("where ssp.pid='{0}';");
string sql = string.Format(strBil.ToString(), item.Id);
var lists = db.Query<SplitStorePayEntity>(sql);
var succLst = new List<SplitStorePayEntity>();
var errLst = new List<SplitStorePayEntity>();
//logger.Info($"需要上传日订单[{date.ToString("yyyy-MM-dd")}]<{item.BusNo}>明细的分账信息<{list.Count()}>条");
if (lists.Count() > 0)
{
total += lists.Count();
var _uploadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var uploadObject = BuilderUploadObject(lists.ToList());
string jsonString = JsonUtils.Serialize(uploadObject);
var uploadResult = this.Uploading(jsonString);
if (uploadResult.Item1)
{
//logger.Info($"日订单<{item.BusNo}>明细的分账信息上传操作成功");
var _clientIds = uploadResult.Item2.Data.ClientIds;
if (!string.IsNullOrEmpty(_clientIds))
{
_clientIds = _clientIds.Substring(0, _clientIds.Length - 1);
var succIdLst = _clientIds.Split(',').ToList();
succLst = lists.Where(m => succIdLst.Exists(t => t.Equals(m.Id))).ToList();
icount += succLst.Count();
errLst = lists.Where(m => !succIdLst.Exists(t => t.Equals(m.Id))).ToList();
}
foreach (var splitPay in succLst)
{
var strSql = $"update pos_split_store_pay set syncStatus = 1, uploadErrors = 0, uploadTime = '{_uploadTime}', uploadStatus = 1, uploadMessage = '', uploadErrCode = '', uploadErrMessage = '' where id = '{splitPay.Id}'; ";
list.Enqueue(strSql);
}
logger.Info($"分账信息第<{index + 1}>次上传,日订单[{date.ToString("yyyy-MM-dd")}]<{item.BusNo}>明细的分账信息<{lists.Count()}>条,上传成功<{succLst.Count()}>");
var errorOrderNo = new List<string>();
foreach (var splitPay in errLst)
{
errorOrderNo.Add(splitPay.ClientId);
splitPay.UploadErrors += 1;
var strSql = $"update pos_split_store_pay set syncStatus = 0, uploadErrors = { splitPay.UploadErrors }, uploadTime = '{_uploadTime}', uploadStatus = 0, uploadMessage = '', uploadErrCode = '{uploadResult.Item2.ErrCode.Replace("'", "")}', uploadErrMessage = '接口调用成功,但上传失败:{splitPay.Id}' where id = '{splitPay.Id}'; ";
list.Enqueue(strSql);
}
if (errorOrderNo.Count() > 0)
{
item.UploadErrors += 1;
var strSql = $"update pos_split_store_pay set syncStatus = 1, uploadErrors = {item.UploadErrors}, uploadTime = '{_uploadTime}', uploadStatus = 0, uploadMessage = '', uploadErrCode = '', uploadErrMessage = '' where id = '{item.Id}'; ";
list.Enqueue(strSql);
var noStrs = string.Join(",", errorOrderNo);
logger.Info($"分账信息第<{index + 1}>次上传,日订单[{date.ToString("yyyy-MM-dd")}]<{item.BusNo}>明细的分账信息<{lists.Count()}>条,上传错误<{errorOrderNo.Count()}>");
}
else
{
var strSql = $"update pos_split_store_pay set syncStatus = 1, uploadErrors = 0, uploadTime = '{_uploadTime}', uploadStatus = 1, uploadMessage = '', uploadErrCode = '', uploadErrMessage = '' where id = '{item.Id}'; ";
list.Enqueue(strSql);
}
}
else
{
foreach (var splitPay in lists)
{
splitPay.UploadErrors += 1;
var strSql = $"update pos_split_store_pay set syncStatus = 0, uploadErrors = { splitPay.UploadErrors }, uploadTime = '', uploadStatus = 0, uploadMessage = '', uploadErrCode = '', uploadErrMessage = '' where id = '{splitPay.Id}'; ";
list.Enqueue(strSql);
}
item.UploadErrors += 1;
var strPSql = $"update pos_split_store_pay set syncStatus = 0, uploadErrors = { item.UploadErrors }, uploadTime = '', uploadStatus = 0, uploadMessage = '', uploadErrCode = '', uploadErrMessage = '' where id = '{item.Id}'; ";
list.Enqueue(strPSql);
logger.Info($"分账信息第<{index + 1}>次上传,日订单[{date.ToString("yyyy-MM-dd")}]<{item.BusNo}>明细的分账信息上传操作失败");
}
Thread.Sleep(100);
}
//if (proValue < tmpPress)
// proValue++;
//MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
proValue++;
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
}
SqliteUtils.ExecuteTransaction(list);
}
}
else
{
logger.Info($"分账信息第<{index + 1}>次上传,日订单[{date.ToString("yyyy-MM-dd")}]无分账信息要上传");
}
}
flg = true;
}
catch (Exception ex)
{
flg = false;
logger.Error(ex, $"分账信息第<{index + 1}>次上传,日订单[{date.ToString("yyyy-MM-dd")}]的分账信息上传错误");
//MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proMaxValue / 3 * index);
}
finally
{
sw.Stop();
logger.Info($"分账信息第<{index + 1}>次上传,日订单<{count}>条,应上传明细<{total}>条,实传<{icount}>条,时长<{sw.ElapsedMilliseconds}>");
//var pressValue = count == 0 ? proValue * (index + 1) : proValue;
//MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, tmpPress);
proValue = proIndexValue + count * (index + 1);
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
index++;
}
}
//MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, 1000);
if (!flg)
{
result = new Tuple<bool, string>(false, "日订单的分账信息上传错误");
}
else
{
result = new Tuple<bool, string>(true, "");
}
return result;
}
}
private List<Dictionary<string, object>> BuilderUploadObject(List<SplitStorePayEntity> list)
{
try
{
//var newUploadObject = new Dictionary<string, object>();
var newLst = new List<Dictionary<string, object>>();
foreach (var splitPay in list)
{
var uploadObject = new Dictionary<string, object>();
//租户ID
uploadObject["tenantId"] = splitPay.TenantId;
//前台系统ID
uploadObject["clientId"] = splitPay.Id;
//设置ID
if (string.IsNullOrEmpty(splitPay.ProgramId))
{
uploadObject["programId"] = "-1";
}
else
{
uploadObject["programId"] = splitPay.ProgramId;
}
//门店ID
uploadObject["storeId"] = splitPay.StoreId;
//分店ID
uploadObject["splitStoreId"] = splitPay.SplitStoreId;
//门店编号
uploadObject["storeNo"] = splitPay.StoreNo;
//付款单号
uploadObject["payNo"] = splitPay.PayNo;
//销售单号
uploadObject["busNo"] = splitPay.BusNo;
//付款方式编号
uploadObject["payTypeNo"] = splitPay.PayTypeNo;
//付款方式
uploadObject["payType"] = splitPay.PayType;
//实收金额
uploadObject["paid"] = splitPay.Paid;
//找零金额
uploadObject["rchange"] = splitPay.Rchange;
//已收金额
uploadObject["money"] = splitPay.Money;
//溢出金额
uploadObject["overAmount"] = splitPay.OverAmount;
//凭证号
uploadObject["voucherNo"] = splitPay.VoucherNo;
//付款时间
uploadObject["payDate"] = splitPay.PayDate;
//付款卡号
uploadObject["cardNo"] = splitPay.CardNo;
//是否实收
uploadObject["incomeFlag"] = splitPay.IncomeFlag;
//第三方扣费类型
uploadObject["otherRateType"] = splitPay.OtherRateType;
//第三方扣费值
uploadObject["otherRateValue"] = splitPay.OtherRateValue;
//第三方扣费
uploadObject["otherRate"] = splitPay.OtherRate;
//支付客户端类型
uploadObject["payClientType"] = splitPay.PayClientType;
//支付渠道
uploadObject["payChannel"] = splitPay.PayChannel;
//扣率
uploadObject["deductionRate"] = splitPay.DeductionRate;
//扣款
uploadObject["chargeBack"] = splitPay.ChargeBack;
//备注
//uploadObject["memo"] = splitPay.Memo;
uploadObject["memo"] = "";
uploadObject["isInvalid"] = splitPay.IsInvalid;
uploadObject["createUser"] = splitPay.CreateUser;
uploadObject["createDate"] = splitPay.CreateDate;
uploadObject["ticketId"] = splitPay.TicketId;
uploadObject["fromBizUserId"] = splitPay.FromBizUserld;
uploadObject["refundAmount"] = splitPay.RefundAmount;
uploadObject["orderType"] = splitPay.OrderType.ToString();
uploadObject["isRefund"] = splitPay.IsRefund;
uploadObject["tableNo"] = splitPay.TableNo;
uploadObject["people"] = splitPay.People;
uploadObject["workNo"] = splitPay.WorkerNo;
uploadObject["unitPrice"] = splitPay.UnitPrice;
uploadObject["goodid"] = splitPay.ProductId;
uploadObject["number"] = Convert.ToInt32(splitPay.Quantity);
uploadObject["rnumber"] = Convert.ToInt32(splitPay.RefundQuantity);
uploadObject["fee"] = Convert.ToInt32(splitPay.fee * 100);
newLst.Add(uploadObject);
}
return newLst;
}
catch (Exception ex)
{
logger.Error(ex, "组装营业分账LIST上传数据异常:");
return null;
}
}
private Tuple<bool, EntityResponse<UploadResult>> Uploading(string jsonString)
{
Tuple<bool, EntityResponse<UploadResult>> result = null;
var isTest = false;
#region 模拟上传操作
if (isTest)
{
logger.Debug("开始构建上传成功模拟数据......");
//构建上传成功模拟数据
var resp2 = new EntityResponse<UploadResult>();
resp2.Status = 1;
resp2.Message = "模拟上传";
resp2.ErrCode = string.Empty;
resp2.ErrMessage = string.Empty;
resp2.Data = new UploadResult
{
TicketId = "11112211",
UploadDate = DateTime.Now
};
logger.Info("模拟上传返回结果:{0}", resp2);
result = new Tuple<bool, EntityResponse<UploadResult>>(false, resp2);
return result;
}
#endregion
try
{
logger.Debug("开始上传营业分账数据*......");
OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business);
SortedList<string, string> parameters = OpenApiUtils.Instance.NewParameters(api);
parameters.Add("method", "upload.business.splitorder");
parameters.Add("storeId", Global.Instance.Authc.StoreId);
parameters.Add("jsonString", jsonString);
var ignore = new List<string>();
ignore.Add("jsonString");
parameters.Add("sign", OpenApiUtils.Instance.Sign(api, parameters, ignore));
string response = HttpClientUtils.PostAsync(api, api.Url, parameters);
logger.Info("上传返回结果*:{0}", response);
if (Constant.IsSuccessful(response))
{
var status = JsonUtils.Deserialize<EntityResponse<UploadResult>>(response);
if (status.Status == 1)
{
logger.Info(status.Message);
result = new Tuple<bool, EntityResponse<UploadResult>>(true, status);
}
else if (status.Status == 2)
{
logger.Info(status.Message);
result = new Tuple<bool, EntityResponse<UploadResult>>(false, status);
}
else
{
string message = string.Format("<{0}>-{1}-{2}", status.ErrCode, status.ErrMessage, status.Message);
logger.Error(string.Format("调用接口<upload.business.splitorder>上传出错*:{0}", message));
result = new Tuple<bool, EntityResponse<UploadResult>>(false, status);
}
}
else
{
string errorMessage = PaserErrors(response);
logger.Error(string.Format("报文<{0}>解析出错*:{1}", response, errorMessage));
//构建错误信息
var resp = new EntityResponse<UploadResult>();
resp.Status = 0;
resp.Message = errorMessage;
resp.ErrCode = string.Empty;
resp.ErrMessage = string.Empty;
resp.Data = null;
result = new Tuple<bool, EntityResponse<UploadResult>>(false, resp);
}
}
catch (Exception ex)
{
string message = string.Format("上传营业分账数据发生异常*");
logger.Error(ex, message);
//构建异常错误
var resp = new EntityResponse<UploadResult>();
resp.Status = 0;
resp.Message = message;
resp.ErrCode = string.Empty;
resp.ErrMessage = string.Empty;
resp.Data = null;
result = new Tuple<bool, EntityResponse<UploadResult>>(false, resp);
}
return result;
}
}
}