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.

1227 lines
66 KiB
C#

9 months ago
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();
sw.Start();
logger.Info($"开始保存订单<{orderObject.TradeNo}>的分账信息");
var isExist = false;
try
{
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 (!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
}
}
}
}
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));
}
}
}
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));
}
else
{
logger.Info($"退款成功后更新服务端原分账信息失败json" + JsonUtils.Serialize(entity));
}
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 = 20;
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>();
try
{
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 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")}],分账第<{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")}],分账第<{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)
{
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);
}
}
else
{
logger.Info($"日订单[{date.ToString("yyyy-MM-dd")}],第<{i + 1}>页订单数据无可分账数据");
}
if (i > proMaxValue)
{
proValue = 20;
}
else
{
proValue = i;
}
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, proValue);
}
SqliteUtils.ExecuteTransaction(sqlList);
}
}
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, proMaxValue);
}
return isException;
}
}
public Tuple<bool, string> SplitData2Server(DateTime date)
{
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 = 10;
Stopwatch sw = new Stopwatch();
sw.Start();
int index = 0;
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, 25);
var proValue = 24;
var flg = false;
lock (Global.Instance.SyncLock)
{
while (index < 3)
{
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;
var spp = 1;
if (pageCount > 0 && pageCount == proValue)
{
spp = 1;
}
else if (pageCount > 0 && pageCount <= 6)
{
spp = 4;
}
else if (pageCount > 7 && pageCount <= 12)
{
spp = 2;
}
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>();
int j = 0;
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}>明细的分账信息上传操作失败");
}
j++;
Thread.Sleep(100);
}
}
proValue += spp;
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")}]的分账信息上传错误");
}
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, pressValue);
index++;
}
}
MsgEvent.Send(Constant.SPLITPAY_UPLOAD_PROGRESS, 100);
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;
}
}
}