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.

764 lines
30 KiB
C#

using System;
using System.Collections.Generic;
using FluentScheduler;
using POSV.Entity;
using POSV.HttpApi;
using POSV.HttpResponse;
using POSV.ShoppingCart;
using POSV.Utils;
using System.Linq;
using System.Diagnostics;
using System.Threading;
namespace POSV.Job
{
public class OrderUploadJob : BaseApi, IJob
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly object _lock = new object();
private bool isRunning = false;
public void Execute()
{
//lock (_lock)
//{
//}
var sw = new Stopwatch();
if (!Global.Instance.IsLogin)
{
logger.Debug("未登录忽略本次上传");
return;
}
if (!Global.Instance.Online)
{
logger.Debug("脱机状态,忽略本次上传");
return;
}
if (!Global.Instance.AllowUpload)
{
logger.Info("正在点单,暂不上传");
return;
}
if (isRunning)
{
logger.Info("上传中,请稍候...");
return;
}
if (!Global.isHaveUpLoadTicket) {
logger.Debug("没有需要上传的营业数据,isHaveUpLoadTicket=false");
return;
}
UploadOrderObject(5);
}
private List<OrderObject> UploadOrderObject(int limit)
{
this.isRunning = true;
var sw = new Stopwatch();
var lists = new List<OrderObject>();
//单据明细
var items = new List<OrderItem>();
//支付明细
var pays = new List<PayItem>();
//主单优惠明细
var orderPromotions = new List<PromotionOrder>();
//做法明细
var flavors = new List<FlavorItem>();
//单品优惠明细
var itemPromotions = new List<PromotionItem>();
//外送单
var deliverys = new List<OrderDelivery>();
try
{
sw.Start();
using (var db = Global.Instance.OpenDataBase)
{
//主单数据
lists = db.Query<OrderObject>("where syncStatus = 0 and uploadErrors < 3000 order by uploadErrors limit @0;", limit).ToList();
if (lists.Count > 0)
{
var ids = string.Join("','", lists.ConvertAll(x => x.Id).ToArray());
var condition = " where orderId in ('" + ids + "');";
logger.Debug(condition);
//单据明细
items = db.Query<OrderItem>(condition).ToList();
logger.Debug("单据明细<{0}>", (items != null ? items.Count.ToString() : "*****"));
//支付明细
pays = db.Query<PayItem>(condition).ToList();
logger.Debug("支付明细<{0}>", (pays != null ? pays.Count.ToString() : "*****"));
//主单优惠明细
orderPromotions = db.Query<PromotionOrder>(condition).ToList();
logger.Debug("主单优惠明细<{0}>", (orderPromotions != null ? orderPromotions.Count.ToString() : "*****"));
//做法明细
flavors = db.Query<FlavorItem>(condition).ToList();
logger.Debug("做法明细<{0}>", (flavors != null ? flavors.Count.ToString() : "*****"));
//单品优惠明细
itemPromotions = db.Query<PromotionItem>(condition).ToList();
logger.Debug("单品优惠明细<{0}>", (itemPromotions != null ? itemPromotions.Count.ToString() : "*****"));
//外送单
deliverys = db.Query<OrderDelivery>(condition).ToList();
logger.Debug("外送单明细<{0}>", (deliverys != null ? deliverys.Count.ToString() : "*****"));
}
else {
logger.Info("没有需要上传的营业数据,isHaveUpLoadTicket=false");
Global.isHaveUpLoadTicket = false;
}
}
foreach (var orderObject in lists)
{
orderObject.Items = items.FindAll(x => x.OrderId == orderObject.Id);
//将支付方式附加到主单
orderObject.Pays = pays.FindAll(x => x.OrderId == orderObject.Id);
//将主单优惠附加到主单
orderObject.Promotions = orderPromotions.FindAll(x => x.OrderId == orderObject.Id);
//外送单
orderObject.Delivery = deliverys.FirstOrDefault(x => x.OrderId == orderObject.Id);
//门店管理费用结算数据汇总,zhangy 2020-02-18 Add
decimal orderChargeBack = orderObject.Pays.Sum(x => string.IsNullOrEmpty(x.Ext2) ? 0.00M : Convert.ToDecimal(x.Ext2));
orderObject.OrderChargeBack = orderChargeBack;
foreach (var item in orderObject.Items)
{
List<FlavorItem> flavorsList = flavors.FindAll(x => x.OrderId == orderObject.Id && x.ItemId == item.Id);
if (orderObject.OrderStatus == OrderStatus.退)
{
foreach (FlavorItem flavorItem in flavorsList)
{
flavorItem.isBackTicket = true;
}
}
if (orderObject.OrderType == OrderType. || orderObject.OrderType == OrderType.|| orderObject.OrderType == OrderType.饿)
{
foreach (FlavorItem flavorItem in flavorsList)
{
flavorItem.isWaiMaiTicket = true;
}
}
item.Flavors = flavorsList;
item.Promotions = itemPromotions.FindAll(x => x.OrderId == orderObject.Id && x.ItemId == item.Id);
}
}
}
catch (Exception ex)
{
logger.Error(ex, "加载未上传订单异常");
}
finally
{
if (lists.Count > 0)
{
//var results = new List<OrderObject>();
foreach (var orderObject in lists)
{
ProcessOrderObject(orderObject);
Thread.Sleep(10);
}
sw.Stop();
logger.Info("销售订单上传<{0}>条数据耗时<{1}>", lists.Count, sw.ElapsedMilliseconds);
}
this.isRunning = false;
}
return lists;
}
private bool ProcessOrderObject(OrderObject orderObject)
{
bool isSuccess = true;
try
{
var uploadObject = BuilderUploadObject(orderObject);
string jsonString = JsonUtils.Serialize(uploadObject);
var uploadResult = this.Uploading(jsonString);
if (uploadResult.Item1)
{
orderObject.SyncStatus = 1;
orderObject.TicketId = uploadResult.Item2.Data.TicketId;
orderObject.UploadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//上传失败
isSuccess = true;
}
else
{
orderObject.SyncStatus = 0;
orderObject.TicketId = string.Empty;
//上传失败
isSuccess = false;
}
orderObject.UploadStatus = uploadResult.Item2.Status;
orderObject.UploadMessage = uploadResult.Item2.Message;
orderObject.UploadErrCode = uploadResult.Item2.ErrCode;
orderObject.UploadErrMessage = uploadResult.Item2.ErrMessage;
}
catch (Exception ex)
{
isSuccess = false;
logger.Error(ex, "销售订单上传任务异常");
Global.Instance.BugReport(ex, "销售订单上传任务异常");
}
finally
{
if (!isSuccess)
{
orderObject.UploadErrors += 1;
}
lock (Global.Instance.SyncLock)
{
string sql = @"update pos_order set syncStatus = {0}, uploadErrors = {1}, ticketId = '{2}', uploadTime = '{3}', uploadStatus = {4}, uploadMessage = '{5}', uploadErrCode = '{6}', uploadErrMessage = '{7}' where id = '{8}';";
//索引损坏根据id更新
//string sql = @"update pos_order set syncStatus = {0}, uploadErrors = {1}, ticketId = '{2}', uploadTime = '{3}', uploadStatus = {4}, uploadMessage = '{5}', uploadErrCode = '{6}', uploadErrMessage = '{7}' where id like '{8}';";
SqliteUtils.Execute(string.Format(sql, orderObject.SyncStatus, orderObject.UploadErrors, orderObject.TicketId, orderObject.UploadTime, orderObject.UploadStatus, orderObject.UploadMessage, orderObject.UploadErrCode, orderObject.UploadErrMessage, orderObject.Id));
}
}
return isSuccess;
}
private Dictionary<string, object> BuilderUploadObject(OrderObject order)
{
try
{
var uploadObject = new Dictionary<string, object>();
//上传订单
order.isUpLoadTicket = true;
//前台系统ID
uploadObject["id"] = order.Id;
//单据编号
uploadObject["no"] = order.TradeNo;
//门店ID
uploadObject["storeId"] = order.StoreId;
//门店编号
uploadObject["storeNo"] = order.StoreNo;
//门店名称
uploadObject["storeName"] = order.StoreName;
//单据状态
uploadObject["status"] = (int)order.OrderStatus;
//操作员工号
uploadObject["workNo"] = order.WorkerNo;
//销售时间
uploadObject["saleDate"] = order.FinishDate;
//餐桌号
uploadObject["tableNo"] = order.TableNo;
//人数
uploadObject["people"] = order.People;
//营业模式
uploadObject["busMode"] = (int)order.OrderType;
//班次
uploadObject["shiftNo"] = order.ShiftNo;
//班次名称
uploadObject["shiftName"] = order.ShiftName;
//消费金额
uploadObject["amount"] = order.Amount;
//优惠率
uploadObject["discount"] = order.DiscountRate;
//抹零金额
uploadObject["maling"] = order.MalingAmount;
//优惠额
uploadObject["discountTotal"] = order.DiscountAmount;
//应收金额
uploadObject["receivable"] = order.ReceivableAmount;
//原单号
uploadObject["noOrg"] = order.OrgTradeNo;
//退单原因
uploadObject["backCause"] = order.RefundCause;
//是否使用会员卡(0否1是)
uploadObject["isMember"] = order.IsMember;
//会员卡号
uploadObject["memberNo"] = order.MemberNo;
//本单积分
uploadObject["memberJifen"] = order.AddPoint;
//设备名称
uploadObject["deviceName"] = order.DeviceName;
//设备编号
uploadObject["posNo"] = order.PosNo;
//MacAddress
uploadObject["deviceMac"] = order.MacAddress;
//IpAddress
uploadObject["deviceIp"] = order.IpAddress;
//当日流水号
uploadObject["seqNo"] = order.OrderNo;
//天气
uploadObject["weather"] = order.Weather;
//星期
uploadObject["weeker"] = order.Weeker;
//预估成本
uploadObject["estimatedCost"] = order.EstimatedCost;
//预估毛利金额
uploadObject["estimatedProfitAmount"] = order.EstimatedProfitAmount;
//预估毛利率
uploadObject["estimatedProfitMargin"] = order.EstimatedProfitMargin;
//实际成本
uploadObject["totalCost"] = order.EstimatedCost;
//实际毛利金额
uploadObject["profitAmount"] = order.EstimatedProfitAmount;
//实际毛利率
uploadObject["profitMargin"] = order.EstimatedProfitMargin;
//zhangy 2020-02-18 Add
//支付方式扣率汇总
uploadObject["orderChargeBack"] = order.OrderChargeBack;
//20171223 增加外送上传 杨阿明
var delivery_info = new List<Dictionary<string, object>>();
if (order.Delivery != null)
{
var delivery = new Dictionary<string, object>();
//订餐时间
delivery["id"] = order.Delivery.Id;
//订餐时间
delivery["orderTime"] = order.SaleDate;
//订餐人
delivery["visitorName"] = order.Delivery.VisitorName;
//订餐电话
delivery["orderTel"] = order.Delivery.VisitorTelephone;
//收货人名称
delivery["recipientName"] = order.Delivery.Customer;
//收货人电话
delivery["recipientPhone"] = order.Delivery.Telephone;
//收货人地址
delivery["recipientAddress"] = order.Delivery.Address;
//送餐员工号
delivery["deliveryWorkerNo"] = order.Delivery.WorkerNo;
//送餐员名称
delivery["deliveryWorkerName"] = order.Delivery.WorkerName;
// 预支金额
delivery["advanceAmount"] = order.Delivery.AdvanceAmount;
//加收服务费
delivery["distributionFee"] = order.Delivery.DistributionFee;
//送出时间
delivery["deliveryBeginTime"] = order.Delivery.SendDate;
//送达时间
delivery["deliveryEndTime"] = order.Delivery.SettlementDate;
//交账时间
delivery["settlementTime"] = order.Delivery.SettlementDate;
delivery_info.Add(delivery);
}
uploadObject["deliveryInfo"] = delivery_info;
//整单优惠明细
var ticket_info = new List<Dictionary<string, object>>();
if (order.Promotions != null)
{
foreach (var promotion in order.Promotions)
{
var p = new Dictionary<string, object>();
//前台系统ID
p["id"] = promotion.Id;
//优惠类型
p["type"] = promotion.PromotionType;
//优惠说明
p["info"] = promotion.ToString();
//优惠金额
p["discountMoney"] = promotion.DiscountAmount;
ticket_info.Add(p);
}
}
uploadObject["ticket_info"] = ticket_info;
//单品明细
var order_product = new List<Dictionary<string, object>>();
foreach (var item in order.Items)
{
var row = new Dictionary<string, object>();
//前台系统ID
row["id"] = item.Id;
//购物车-序号
row["lineNo"] = item.OrderNo;
//父记录ID
row["parentId"] = item.ParentId;
//菜品ID
row["productId"] = item.ProductId;
//菜品编号
row["productNo"] = item.ProductNo;
//菜品名称
row["productName"] = item.Name;
//菜品单位
row["productUnitId"] = item.ProductUnitId;
//菜品单位名
row["productUnitName"] = item.ProductUnitName;
//====2018-10-29根据类别取出类别路径
if ("4".Equals(item.TypeId))
{
//美团外卖商品类别特殊处理
//菜品分类路径
row["typePath"] = "4";
//菜品大类ID
row["seriesId"] = "4";
//菜品大类名称
row["seriesName"] = "美团外卖菜品";
}
else if ("5".Equals(item.TypeId))
{
//美团外卖商品类别特殊处理
//菜品分类路径
row["typePath"] = "5";
//菜品大类ID
row["seriesId"] = "5";
//菜品大类名称
row["seriesName"] = "饿了么菜品";
}
else
{
var lists = Global.ProductType._productTypeList;
ProductType productType = lists.FirstOrDefault<ProductType>(x => x.Id.Equals(item.TypeId));
if (productType != null)
{
row["typePath"] = productType.Path;
string[] seriesIds = productType.Path.Split(',');
ProductType productSeries = lists.FirstOrDefault<ProductType>(x => x.Id.Equals(seriesIds[0]));
if (productSeries != null)
{
//菜品大类ID
row["seriesId"] = productSeries.Id;
//菜品大类名称
row["seriesName"] = productSeries.Name;
}
}
}
//====2018-10-29 NED
//类别ID
row["typeId"] = item.TypeId;
//类别名
row["typeName"] = item.TypeName;
//规格ID
row["specId"] = item.SpecId;
//规格名称
row["specName"] = item.SpecName;
//数量
row["count"] = item.Quantity;
//退菜数量
row["rcount"] = item.RefundQuantity;
//销售价格
row["price"] = item.Price;
//折后价格
row["discountPrice"] = item.DiscountPrice;
//菜品原价
row["priceOrg"] = item.SalePrice;
//是否套菜(1普通菜 2 主菜 3 明细菜)
row["isSuit"] = (int)item.RowState;
//套菜ID
row["suitId"] = item.SuitId;
//销售时间
row["saleDate"] = item.FinishDate;
//消费金额
row["amount"] = item.Amount;
//优惠率
row["discount"] = item.DiscountRate;
//优惠额
row["discountTotal"] = item.DiscountAmount;
//应收金额
row["receivable"] = item.ReceivableAmount;
//加价金额
row["addPriceTotal"] = item.FlavorAmount;
//加价优惠金额
row["discountAddTotal"] = item.FlavorDiscountAmount;
//加价应收金额
row["amountAddTotal"] = item.FlavorReceivableAmount;
//消费总额(消费金额+加价总额)
row["amountTotal"] = item.TotalAmonut;
//应收总额(应收金额+做法总额)
row["receivableTotal"] = item.TotalReceivableAmount;
//预估成本
row["estimatedCost"] = item.EstimatedCost;
//预估毛利金额
row["estimatedProfitAmount"] = item.EstimatedProfitAmount;
//预估毛利率
row["estimatedProfitMargin"] = item.EstimatedProfitMargin;
//实际成本
row["totalCost"] = item.EstimatedCost;
//实际毛利金额
row["profitAmount"] = item.EstimatedProfitAmount;
//实际毛利率
row["profitMargin"] = item.EstimatedProfitMargin;
//单品优惠明细
var product_info = new List<Dictionary<string, object>>();
foreach (var promotion in item.Promotions)
{
var p = new Dictionary<string, object>();
//前台系统ID
p["id"] = promotion.Id;
//产品明细ID
p["orderItemId"] = item.Id;
//优惠类型
p["type"] = promotion.PromotionType;
//优惠说明
p["info"] = promotion.ToString();
//优惠金额
p["discountMoney"] = promotion.DiscountAmount;
product_info.Add(p);
}
row["product_info"] = product_info;
//销售单做法
var product_make = new List<Dictionary<string, object>>();
foreach (var flavor in item.Flavors)
{
var f = new Dictionary<string, object>();
//前台系统ID
f["id"] = flavor.Id;
//商品明细ID
f["orderItemId"] = flavor.ItemId;
//做法ID
f["makeId"] = flavor.MakeId;
//做法名称
f["makeName"] = flavor.Name;
//做法加价
f["addPrice"] = flavor.Price;
//做法优惠
f["discountPrice"] = flavor.Price;
//做法数量
f["count"] = flavor.Quantity;
//做法退数量
f["rcount"] = flavor.RefundQuantity;
//加价总额
f["addTotal"] = flavor.Amount;
//折后总额
f["discountAddTotal"] = flavor.Amount;
//折后率
f["discount"] = flavor.DiscountRate;
//做法管理数量标识
f["qtyFlag"] = flavor.QtyFlag;
//手写做法标识
f["hand"] = flavor.Hand;
product_make.Add(f);
}
row["product_make"] = product_make;
order_product.Add(row);
}
uploadObject["order_product"] = order_product;
//收银流水
var pay = new List<Dictionary<string, object>>();
foreach (var p in order.Pays)
{
var pp = new Dictionary<string, object>();
//前台系统ID
pp["id"] = p.Id;
//付款单号
var payNo = string.IsNullOrEmpty(p.PayNo) ? "" : p.PayNo;
pp["payNo"] = payNo.Length > 32 ? payNo.Substring(0,32) : payNo;
//付款方式编号
pp["payTypeNo"] = p.No;
//付款方式
pp["payType"] = p.Name;
//已收金额
pp["money"] = p.Amount;
//实收金额
pp["paid"] = p.PaidAmount;
//找零金额
pp["rchange"] = p.ChangeAmount;
//溢出金额
pp["overAmount"] = p.OverAmount;
//凭证号
pp["voucherNo"] = p.TradeVoucherNo;
//付款时间
pp["payDate"] = p.FinishDate;
//付款卡号
pp["cardno"] = p.CardNo;
//卡支付前余额
pp["cardYe"] = p.CardBeforeBalance;
//卡支付前积分
pp["cardJf"] = p.CardBeforePoint;
//是否实收
pp["incomeFlag"] = p.IncomeFlag;
//第三方扣费类型
pp["otherRateType"] = p.OtherRateType;
//第三方扣费值
pp["otherRateValue"] = p.OtherRateValue;
//第三方扣费
pp["otherRate"] = p.OtherRate;
//支付渠道
pp["payChannel"] = p.PayChannel;
//备注
pp["memo"] = p.Memo;
//zhangy 2020-02-18 Add
//支付方式扣率
pp["deductionRate"] = string.IsNullOrEmpty(p.Ext1) ? "0" : p.Ext1;
//支付方式扣率计算的扣款
pp["chargeBack"] = string.IsNullOrEmpty(p.Ext2) ? "0" : p.Ext2;
pay.Add(pp);
}
uploadObject["pay"] = pay;
return uploadObject;
}catch(Exception ex)
{
logger.Error(ex,"组装订单上传数据异常:");
return null;
}
}
private Tuple<bool, EntityResponse<UploadResult>> Uploading(string jsonString)
{
Tuple<bool, EntityResponse<UploadResult>> result = null;
try
{
logger.Debug("开始上传数据......");
OpenApi api = OpenApiUtils.Instance.NextApi(ApiType.Business);
SortedList<string, string> parameters = OpenApiUtils.Instance.NewParameters(api);
parameters.Add("method", "upload.business.order.plus");
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.order.plus>上传出错:{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;
}
}
}