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.

1803 lines
78 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog;
using POSV.Bean;
using POSV.Card;
using POSV.Entity;
using POSV.Printer;
using POSV.ShoppingCart;
using POSV.Utils;
using System.Threading;
using POSV.ServiceCenter;
using POS.Language.Language;
namespace POSV.Helper
{
public class PrintHelper
{
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
private static object _lock = new object();
/// <summary>
/// 获取系统配置的收银小票打印机
/// </summary>
/// <returns></returns>
public static PrinterObject GetTicketPrinterObject(bool cutPager, bool openCashbox)
{
var pobject = new PrinterObject();
var json = Global.Instance.GlobalConfigStringValue(ConfigConstant.PERIPHERAL_CASHIER_TICKET);
if (string.IsNullOrEmpty(json))
{
json = JsonUtils.Serialize(ConfigConstant.PeripheralGroupDefaultValue());
}
var printer = JsonUtils.Deserialize<PrinterItem>(json);
pobject.Id = printer.Id;
pobject.Name = printer.Name;
pobject.PortType = (PortType)Enum.Parse(typeof(PortType), printer.Port);
pobject.DynamicLibrary = (DynamicLibrary)Enum.Parse(typeof(DynamicLibrary), printer.DynamicLibrary);
pobject.PageWidth = printer.PageWidth;
pobject.CutPager = cutPager;
pobject.OpenCashbox = openCashbox;
pobject.Data[PrinterObject.COM_PORT_NAME] = printer.Data[Constant.COM_PORT_NAME];
pobject.Data[PrinterObject.COM_PORT_BAUD] = printer.Data[Constant.COM_PORT_BAUD];
pobject.Data[PrinterObject.LPT_NAME] = printer.Data[Constant.LPT_NAME];
pobject.Data[PrinterObject.DRIVE_NAME] = printer.Data[Constant.DRIVE_NAME];
pobject.Data[PrinterObject.NET_IP_ADDRESS] = printer.Data[Constant.NET_IP_ADDRESS];
pobject.Data[PrinterObject.USB_PID] = printer.Data[Constant.USB_PID];
pobject.Data[PrinterObject.USB_VID] = printer.Data[Constant.USB_VID];
pobject.EscPosCommand.InitCommand = printer.InitCommand;
pobject.EscPosCommand.NormalCommand = printer.NormalCommand;
pobject.EscPosCommand.DoubleHeightCommand = printer.DoubleHeightCommand;
pobject.EscPosCommand.DoubleWidthCommand = printer.DoubleWidthCommand;
pobject.EscPosCommand.DoubleWidthHeightCommand = printer.DoubleWidthHeightCommand;
pobject.EscPosCommand.CutPageCommand = printer.CutPageCommand;
pobject.EscPosCommand.CashboxCommand = printer.CashboxCommand;
pobject.EscPosCommand.AlignCenterCommand = printer.AlignCenterCommand;
pobject.EscPosCommand.AlignLeftCommand = printer.AlignLeftCommand;
pobject.EscPosCommand.AlignRightCommand = printer.AlignRightCommand;
pobject.EscPosCommand.BeepCommand = printer.BeepCommand;
//回退行数
pobject.EscPosCommand.FeedBackCommand = printer.FeedBackCommand;
//退纸行数
int feedBackRow = Global.Instance.GlobalConfigIntValue(ConfigConstant.CONFIG_CASHIER_FEEDBACK_ROW, 0);
pobject.FeedBackRow = feedBackRow;
return pobject;
}
/// <summary>
/// 打印订单小票、标签、厨显、厨打、出品打印
/// </summary>
/// <param name="orderObject"></param>
public static void PrintOrderObject(OrderObject order)
{
//异步操作前,复制当前订单对象,防止外部更改后,影响打印
var orderObject = ObjectUtils.Copy(order);
//收银小票打印
Task.Factory.StartNew(() =>
{
PrintOrderObjectTicket(orderObject);
});
//打印标签
Task.Factory.StartNew(() =>
{
LabelPrintHelper.PrintOrderLabel(orderObject);
});
//通知厨显
Task.Factory.StartNew(() =>
{
UploadSCNewOrder.UploadNewOrder2SC4KDS(orderObject);
});
//厨打小票打印
Task.Factory.StartNew(() =>
{
ChuDaHelper.KitchenPrinter(orderObject);
});
//厨打标签打印
Task.Factory.StartNew(() =>
{
ChuDaHelper.KitchenLabelPrinter(orderObject);
});
//出品小票打印
Task.Factory.StartNew(() =>
{
ChuDaHelper.MadePrinter(orderObject);
});
}
/// <summary>
/// 打印订单小票
/// </summary>
/// <param name="orderObject"></param>
/// <returns></returns>
public static bool PrintOrderObjectTicket(OrderObject orderObject)
{
bool isException = false;
try
{
//20240330 subin 收银小票,打印外带和自提的小票,不打印堂食票
if (orderObject.BusMode == "堂食" || orderObject.OrderType == OrderType.)
{
logger.Info($"订单类型<{orderObject.OrderType}>,不打印收银小票");
return true;
}
//构建收银小票模版参数
List<VariableValue> vars = null;
if (orderObject.OrderType == OrderType.)
{
vars = BuilderDeliveryTicketVariable(orderObject);
}
else
{
vars = PrintHelper.BuilderTicketVariable(orderObject);
}
//自动切纸
bool cutPager = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_CUT_PAGER, false);
//是否允许打开钱箱
bool openCashbox = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_OPEN_CASHBOX, false);
//不允许现金和银行卡以外方式打开钱箱
bool notAllowOpenCashBox = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_CASH_OPEN_CASHBOX, true);
if (orderObject.Pays.Exists(x => x.No == "01" || x.No == "03"))
{
notAllowOpenCashBox = false;
}
openCashbox = openCashbox && !notAllowOpenCashBox;
//票头空白行
int headerLine = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_HEADER_EMPTY, 0);
//票尾空白行
int footerLine = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_FOOTER_EMPTY, 0);
//小票打印份数
int ticketCount = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_TICKET_COUNT, 1);
//打印延迟
int delaySecond = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_PRINT_DELAY, 1);
for (int i = 1; i <= ticketCount; i++)
{
if (openCashbox && (i != 1))
{
openCashbox = false;
}
//执行收银小票打印
switch (orderObject.OrderType)
{
case OrderType.:
{
logger.Info("开始打印电话外送小票<{0}>", orderObject.TradeNo);
var prt = PrintHelper.PrinterTicket("电话外卖", vars, cutPager, false, headerLine, footerLine);
logger.Info("电话外送小票打印结果<{0},{1},{2}>", orderObject.TradeNo, prt.Item1, prt.Item2);
}
break;
default:
{
logger.Info("开始打印收银小票<{0}>", orderObject.TradeNo);
var prt = PrintHelper.PrinterTicket("收银小票", vars, cutPager, openCashbox, headerLine, footerLine);
logger.Info("收银第<{0}>次小票打印结果<{1},{2},{3}>", i, orderObject.TradeNo, prt.Item1, prt.Item2);
}
break;
}
if (delaySecond > 0)
{
Thread.Sleep(delaySecond * 1000);
}
}
}
catch (Exception ex)
{
isException = true;
logger.Error(ex, "打印订单小票信息异常");
}
return isException;
}
/// <summary>
/// 构建收银小票的参数变量
/// </summary>
/// <param name="orderObject"></param>
/// <returns></returns>
public static List<Printer.VariableValue> BuilderTicketVariable(OrderObject orderObject)
{
var vars = new List<Printer.VariableValue>();
var v = new Printer.VariableValue();
v.Key = "默认数据源";
v.DataType = DataType.Simple;
var data = new Dictionary<string, string>();
if (Global.Instance.IsStudyMode() && string.IsNullOrEmpty(orderObject.OrderNo))//练习模式固定序号
{
data.Add("@序号@", Constant.STUDYMODE_DEFAULT_ORDERNO);
}
else
{
data.Add("@序号@", orderObject.OrderNo);
}
data.Add("@营业模式@", LangProxy.ToLang(orderObject.OrderType.ToString()));
var tradeNo = orderObject.TradeNo;
//票号长度
int length = Global.Instance.GlobalConfigIntValue(ConfigConstant.CONFIG_CASHIER_TICKETNO_LENGTH, 0);
bool isRandom = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CONFIG_CASHIER_RANDOM_TICKETNO, false);
if (isRandom)
{
tradeNo = orderObject.ObjectId;
}
if (length > 0 && (tradeNo.Length - length > 0))
{
data.Add("@票号@", tradeNo.Substring(tradeNo.Length - length));
}
else
{
data.Add("@票号@", tradeNo);
}
//var storeName = string.IsNullOrEmpty(Global.Instance.Worker.StoreInfo.PrintName) ? orderObject.StoreName : Global.Instance.Worker.StoreInfo.PrintName;
data.Add("@门店名称@", Global.Instance.Worker.StoreInfo.PrintName);
data.Add("@门店编码@", orderObject.StoreNo);
if (orderObject.PrintType == 0)
{
data.Add("@单据类型@", LangProxy.ToLang("结账单"));
}
if (orderObject.PrintType == 1)
{
data.Add("@单据类型@", LangProxy.ToLang("退单"));
}
data.Add("@重打标识@", string.Format("{0}", orderObject.RPrint));
data.Add("@门店地址@", Global.Instance.Worker.StoreInfo.Address);
data.Add("@门店电话@", Global.Instance.Worker.StoreInfo.OrderTel);
data.Add("@收银员编码@", orderObject.WorkerNo);
data.Add("@收银员名称@", orderObject.WorkerName);
data.Add("@POS编码@", orderObject.PosNo);
data.Add("@桌号@", orderObject.TableName);
data.Add("@消费金额@", StringUtils.GetString(orderObject.Amount));
data.Add("@优惠金额@", StringUtils.GetString(orderObject.DiscountAmount));
data.Add("@应收金额@", StringUtils.GetString(orderObject.ReceivableAmount));
data.Add("@实收金额@", StringUtils.GetString(orderObject.ReceivedAmount - orderObject.MalingAmount));
data.Add("@找零金额@", StringUtils.GetString(orderObject.ChangeAmount));
data.Add("@抹零金额@", StringUtils.GetString(orderObject.MalingAmount));
data.Add("@销项税@", StringUtils.GetString(orderObject.ItemsSaleTax.ToString("0.00")));
data.Add("@打印时间@", orderObject.FinishDate);
data.Add("@条码内容@", orderObject.TradeNo);
data.Add("@条码说明@", orderObject.TradeNo);
data.Add("@二维码内容@", orderObject.TradeNo);
data.Add("@二维码说明@", orderObject.TradeNo);
var notAllowTitle = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_TITLE, false);
data.Add("@是否打印标题@", (!notAllowTitle).ToString().ToLower());
var allowOrderNo = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_ORDERNO, false);
data.Add("@是否打印序号@", allowOrderNo.ToString().ToLower());
var notAllowStoreAddress = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_STORE_ADDRESS, false);
data.Add("@是否打印地址@", (!notAllowStoreAddress).ToString().ToLower());
var notAllowStoreTelphone = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_STORE_TELPHONE, false);
data.Add("@是否打印电话@", (!notAllowStoreTelphone).ToString().ToLower());
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"images" + Path.DirectorySeparatorChar + "bmp");
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
List<StorePrintImage> images = null;
using (var db = Global.Instance.OpenDataBase)
{
images = db.Query<StorePrintImage>().ToList();
}
if (images != null && images.Count > 0)
{
var headerImage = images.FirstOrDefault(x => x.Type == 0);
var allowHeaderBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_HEADER_BITMAP, false);
if (headerImage != null && allowHeaderBitmap)
{
var fileName = string.Empty;
if (!string.IsNullOrEmpty(headerImage.StorageFileName) && headerImage.StorageFileName.Contains("/"))
{
fileName = headerImage.StorageFileName.Substring(headerImage.StorageFileName.LastIndexOf('/') + 1);
}
string targetFileName = filePath + Path.DirectorySeparatorChar + fileName;
if (File.Exists(targetFileName))
{
data.Add("@是否票头图片@", "true");
data.Add("@票头图片@", targetFileName);
data.Add("@票头图片说明@", headerImage.Description == null ? "" : headerImage.Description);
}
else
{
data.Add("@是否票头图片@", "false");
data.Add("@票头图片说明@", "");
}
}
else
{
data.Add("@是否票头图片@", "false");
data.Add("@票头图片说明@", "");
}
var footerImage = images.FirstOrDefault(x => x.Type == 1);
var allowFooterBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_FOOTER_BITMAP, false);
if (footerImage != null && allowFooterBitmap)
{
var fileName = string.Empty;
if (!string.IsNullOrEmpty(footerImage.StorageFileName) && footerImage.StorageFileName.Contains("/"))
{
fileName = footerImage.StorageFileName.Substring(footerImage.StorageFileName.LastIndexOf('/') + 1);
}
string targetFileName = filePath + Path.DirectorySeparatorChar + fileName;
if (File.Exists(targetFileName))
{
data.Add("@是否票尾图片@", "true");
data.Add("@票尾图片@", targetFileName);
data.Add("@票尾图片说明@", footerImage.Description == null ? "" : footerImage.Description);
}
else
{
data.Add("@是否票尾图片@", "false");
data.Add("@票尾图片说明@", "");
}
}
else
{
data.Add("@是否票尾图片@", "false");
data.Add("@票尾图片说明@", "");
}
}
else
{
data.Add("@票头图片说明@", "");
data.Add("@是否票头图片@", "false");
data.Add("@票尾图片说明@", "");
data.Add("@是否票尾图片@", "false");
}
var allowBarCodeBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_BARCODE, false);
data.Add("@是否打印条码@", allowBarCodeBitmap.ToString().ToLower());
var allowQRCodeBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_QRCODE, false);
data.Add("@是否打印二维码@", allowQRCodeBitmap.ToString().ToLower());
if (string.IsNullOrEmpty(orderObject.MemberNo) && !orderObject.Pays.Exists(x => x.No == "02"))
{
//不使用会员卡且没有使用储值卡支付的
data.Add("@是否打印会员分隔线@", "false");
}
v.Value = JsonUtils.Serialize(data);
vars.Add(v);
v = new Printer.VariableValue();
v.Key = "点单列表";
v.DataType = DataType.List;
var list = new List<Dictionary<string, string>>();
decimal totalQuantity = 0;
decimal totalAmount = 0;
decimal totalDiscountAmount = 0;
//练习模式
string studyName = string.Empty;
if (Global.Instance.IsStudyMode())
{
studyName = LangProxy.ToLang(Constant.STUDYMODE_PRINTSTR);
}
//排序,避免显示列表和打印列表不一致
var items = orderObject.Items.OrderBy(x => x.OrderNo);
//禁止打印套餐明细
var notAllowPrintSuitDetail = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_SUIT_DETAIL, false);
//列表是否显示折后价
bool showDiscountPrice = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_DISCOUNTPRICE, false);
//是否打印规格
var notAllowSepc = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_SPEC, false);
//判断参数配置中是否定义显示简称
var showShortName = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_SHORTNAME, false);
//禁止打印做法
var notAllowFlavor = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_FLAVOR, false);
//免费做法打印为一行
var isOneRow = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_TICKET_FREEMAKEINONEROW, false);
foreach (var item in items)
{
var row = new Dictionary<string, string>();
//销售界面名称的显示
string showName = (showShortName && !string.IsNullOrEmpty(item.ShortName)) ? item.ShortName : item.Name;
//规格名称
string specName = (notAllowSepc || string.IsNullOrEmpty(item.SpecName)) ? "" : Global.Instance.Additional.Item1 + item.SpecName + Global.Instance.Additional.Item2;
//附加规格到名称中
string displayName = studyName + showName + specName;
if (item.RowState == OrderRowState.)
{
if (notAllowPrintSuitDetail)
{
continue;
}
displayName = " " + displayName;
}
if (item.RowState == OrderRowState. || item.RowState == OrderRowState.)
{
if (item.Promotions != null)
{
//禁止收银前台赠送
bool notAllowShowGive = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NOT_ALLOW_SHOW_GIVE, true);
if (!notAllowShowGive && item.Promotions.Exists(x => x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("赠") + Global.Instance.Additional.Item2 + displayName;
}
//禁止收银前台折扣
bool notAllowShowDiscount = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NOT_ALLOW_SHOW_DISCOUNT, true);
if (!notAllowShowDiscount && item.Promotions.Exists(x => x.PromotionType == PromotionType. || x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("折") + Global.Instance.Additional.Item2 + displayName;
}
//禁止收银前台议价
bool notAllowShowBargain = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NOT_ALLOW_SHOW_BARGAIN, true);
if (!notAllowShowBargain && item.Promotions.Exists(x => x.PromotionType == PromotionType. || x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("议") + Global.Instance.Additional.Item2 + displayName;
}
//双数特价
if (item.Promotions.Exists(x => x.PromotionType == PromotionType. || x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("双") + Global.Instance.Additional.Item2 + displayName;
}
}
}
row.Add("@品名@", displayName);
row.Add("@数量@", (item.Quantity - item.RefundQuantity) + "");
decimal _salePrice = item.Price;
if (showDiscountPrice)
{
_salePrice = item.DiscountPrice;
}
decimal _amount = item.Amount;
if (showDiscountPrice)
{
_amount = item.Amount - item.DiscountAmount;
}
if (item.RowState == OrderRowState.)
{
row.Add("@单价@", "");
row.Add("@小计@", "");
row.Add("@优惠@", "");
}
else
{
row.Add("@单价@", _salePrice + "");
row.Add("@小计@", _amount + "");
row.Add("@优惠@", item.DiscountAmount + "");
}
list.Add(row);
//允许打印做法或者做法包含加价
bool existAddPriceFlavor = item.Flavors.Exists(x => x.Price != 0);
if (!notAllowFlavor || existAddPriceFlavor)
{
if (isOneRow)
{
//零价格做法、加料单独一行
var zeroFlavors = item.Flavors.FindAll(x => x.Price == 0);
var flavorStr = string.Join(",", zeroFlavors.ConvertAll<string>(x => x.Name + ((x.Quantity - x.RefundQuantity) > 1 ? (x.Quantity - x.RefundQuantity).ToString() : "")).ToArray());
row = new Dictionary<string, string>();
row.Add("@品名@", " " + flavorStr);
row.Add("@数量@", string.Empty);
row.Add("@单价@", string.Empty);
row.Add("@小计@", string.Empty);
row.Add("@优惠@", string.Empty);
list.Add(row);
//有价加料
var priceFlavors = item.Flavors.FindAll(x => x.Price != 0);
foreach (var flavor in priceFlavors)
{
row = new Dictionary<string, string>();
row.Add("@品名@", " " + flavor.Name + "X" + (flavor.Quantity - flavor.RefundQuantity));
row.Add("@数量@", string.Empty);
row.Add("@单价@", flavor.Price + "");
row.Add("@小计@", flavor.Amount + "");
row.Add("@优惠@", flavor.DiscountAmount + "");
list.Add(row);
//做法的合计的数据
//totalQuantity += (flavor.Quantity - flavor.RefundQuantity);
totalAmount += flavor.Amount;
totalDiscountAmount += flavor.DiscountAmount;
}
}
else
{
foreach (var flavor in item.Flavors)
{
row = new Dictionary<string, string>();
row.Add("@品名@", " " + flavor.Name);
if (flavor.QtyFlag == 1)
{
row.Add("@数量@", (flavor.Quantity - flavor.RefundQuantity) + "");
}
else
{
row.Add("@数量@", string.Empty);
}
if (flavor.Price != 0)
{
row.Add("@单价@", flavor.Price + "");
row.Add("@小计@", flavor.Amount + "");
row.Add("@优惠@", flavor.DiscountAmount + "");
}
else
{
row.Add("@单价@", string.Empty);
row.Add("@小计@", string.Empty);
row.Add("@优惠@", string.Empty);
}
list.Add(row);
//做法的合计的数据
if (flavor.QtyFlag == 1)
{
totalQuantity += (flavor.Quantity - flavor.RefundQuantity);
}
totalAmount += flavor.Amount;
totalDiscountAmount += flavor.DiscountAmount;
}
}
}
//单品的合计的数据
if (item.RowState != OrderRowState.)
{
totalQuantity += (item.Quantity - item.RefundQuantity);
totalAmount += item.Amount;
totalDiscountAmount += item.DiscountAmount;
}
}
var total = new Dictionary<string, string>();
total.Add("@品名@", LangProxy.ToLang("合计"));
total.Add("@数量@", totalQuantity + "");
total.Add("@单价@", "");
total.Add("@小计@", totalAmount + "");
total.Add("@优惠@", totalDiscountAmount + "");
list.Add(total);
v.Value = JsonUtils.Serialize(list);
vars.Add(v);
v = new Printer.VariableValue();
v.Key = "支付方式列表";
v.DataType = DataType.List;
list = new List<Dictionary<string, string>>();
var malingPayMode = OrderUtils.GetMalingPayMode();
//禁止抹零打印支付列表
var notAllowMaling = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_MALING, true);
foreach (var item in orderObject.Pays)
{
if (notAllowMaling && malingPayMode != null && malingPayMode.No.Equals(item.No))
{
continue;
}
var row = new Dictionary<string, string>();
row.Add("@支付名称@", LangProxy.ToLang(item.Name) + "");
row.Add("@支付金额@", item.Amount + "");
row.Add("@支付凭证@", item.TradeVoucherNo + "");
list.Add(row);
}
v.Value = JsonUtils.Serialize(list);
vars.Add(v);
//会员信息
var memberDic = new Dictionary<string, string>();
if (!string.IsNullOrEmpty(orderObject.MemberNo))
{
var cardNo = string.IsNullOrEmpty(orderObject.CardFaceNo) ? orderObject.MemberNo : orderObject.CardFaceNo;
memberDic.Add("@会员号@", CardUtils.CardNoEncrypt(cardNo));
memberDic.Add("@消费前积分@", orderObject.PrePoint + "");
memberDic.Add("@本次积分@", orderObject.AddPoint + "");
memberDic.Add("@当前积分@", orderObject.AftPoint + "");
//memberDic.Add("@消费前积分@", orderObject.AddPoint + "");
}
else
{
memberDic.Add("@是否打印会员信息@", "false");
}
vars.Add(new VariableValue() { Key = "会员卡信息", DataType = DataType.Simple, Value = JsonUtils.Serialize(memberDic) });
//储值卡信息
list = new List<Dictionary<string, string>>();
var memberPayList = orderObject.Pays.FindAll(x => x.No == "02");
if (memberPayList.Count > 0)
{
foreach (var item in memberPayList)
{
var cardNo = string.IsNullOrEmpty(item.CardFaceNo) ? item.CardNo : item.CardFaceNo;
var row = new Dictionary<string, string>();
row.Add("@卡号@", CardUtils.CardNoEncrypt(cardNo));
row.Add("@可用余额@", item.CardAftAmount + "");
list.Add(row);
}
}
else
{
var row = new Dictionary<string, string>();
row.Add("@是否打印储值卡信息@", "false");
list.Add(row);
}
vars.Add(new VariableValue() { Key = "储值卡列表", DataType = DataType.List, Value = JsonUtils.Serialize(list) });
//储值卡列表2
list = new List<Dictionary<string, string>>();
var memberPayList2 = orderObject.Pays.FindAll(x => x.No == "02");
if (memberPayList2.Count > 0)
{
foreach (var item in memberPayList2)
{
var cardNo = string.IsNullOrEmpty(item.CardFaceNo) ? item.CardNo : item.CardFaceNo;
var row = new Dictionary<string, string>();
row.Add("@卡信息@", string.Format(LangProxy.ToLang("卡号:{0}"), CardUtils.CardNoEncrypt(cardNo)));
list.Add(row);
row = new Dictionary<string, string>();
row.Add("@卡信息@", string.Format(LangProxy.ToLang("消费前余额:{0}"), item.CardBeforeBalance + ""));
list.Add(row);
row = new Dictionary<string, string>();
row.Add("@卡信息@", string.Format(LangProxy.ToLang("本次消费:{0}"), item.PaidAmount + ""));
list.Add(row);
row = new Dictionary<string, string>();
row.Add("@卡信息@", string.Format(LangProxy.ToLang("消费后余额:{0}"), item.CardAftAmount + ""));
list.Add(row);
}
}
vars.Add(new VariableValue() { Key = "储值卡列表2", DataType = DataType.List, Value = JsonUtils.Serialize(list) });
return vars;
}
/// <summary>
/// 构建电话外卖小票的参数变量
/// </summary>
/// <param name="orderObject"></param>
/// <returns></returns>
public static List<Printer.VariableValue> BuilderDeliveryTicketVariable(OrderObject orderObject)
{
var vars = new List<Printer.VariableValue>();
var v = new Printer.VariableValue();
v.Key = "默认数据源";
v.DataType = DataType.Simple;
var data = new Dictionary<string, string>();
data.Add("@序号@", orderObject.OrderNo);
data.Add("@营业模式@", orderObject.OrderType.ToString());
var tradeNo = orderObject.TradeNo;
//票号长度
int length = Global.Instance.GlobalConfigIntValue(ConfigConstant.CONFIG_CASHIER_TICKETNO_LENGTH, 0);
bool isRandom = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CONFIG_CASHIER_RANDOM_TICKETNO, false);
if (isRandom)
{
tradeNo = orderObject.ObjectId;
}
if (length > 0 && (tradeNo.Length - length > 0))
{
data.Add("@票号@", tradeNo.Substring(tradeNo.Length - length));
}
else
{
data.Add("@票号@", tradeNo);
}
data.Add("@重打标识@", string.Format("{0}", orderObject.RPrint));
var storeName = string.IsNullOrEmpty(Global.Instance.Worker.StoreInfo.PrintName) ? orderObject.StoreName : Global.Instance.Worker.StoreInfo.PrintName;
data.Add("@门店名称@", storeName);
data.Add("@门店编码@", orderObject.StoreNo);
data.Add("@门店地址@", Global.Instance.Worker.StoreInfo.Address);
data.Add("@门店电话@", Global.Instance.Worker.StoreInfo.OrderTel);
data.Add("@收银员编码@", orderObject.WorkerNo);
data.Add("@收银员名称@", orderObject.WorkerName);
data.Add("@POS编码@", orderObject.PosNo);
data.Add("@桌号@", orderObject.TableName);
data.Add("@单注@", "");
data.Add("@消费金额@", StringUtils.GetString(orderObject.Amount));
data.Add("@优惠金额@", StringUtils.GetString(orderObject.DiscountAmount));
data.Add("@应收金额@", StringUtils.GetString(orderObject.ReceivableAmount));
data.Add("@实收金额@", StringUtils.GetString(orderObject.ReceivedAmount - orderObject.MalingAmount));
data.Add("@找零金额@", StringUtils.GetString(orderObject.ChangeAmount));
data.Add("@抹零金额@", StringUtils.GetString(orderObject.MalingAmount));
data.Add("@打印时间@", orderObject.FinishDate);
data.Add("@条码内容@", orderObject.TradeNo);
data.Add("@条码说明@", orderObject.TradeNo);
data.Add("@二维码内容@", orderObject.TradeNo);
data.Add("@二维码说明@", orderObject.TradeNo);
var notAllowTitle = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_TITLE, false);
data.Add("@是否打印标题@", (!notAllowTitle).ToString().ToLower());
var allowOrderNo = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_ORDERNO, false);
data.Add("@是否打印序号@", allowOrderNo.ToString().ToLower());
var notAllowStoreAddress = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_STORE_ADDRESS, false);
data.Add("@是否打印地址@", (!notAllowStoreAddress).ToString().ToLower());
var notAllowStoreTelphone = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_STORE_TELPHONE, false);
data.Add("@是否打印电话@", (!notAllowStoreTelphone).ToString().ToLower());
data.Add("@是否票头图片@", "false");
data.Add("@是否票尾图片@", "false");
var allowBarCodeBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_BARCODE, false);
data.Add("@是否打印条码@", allowBarCodeBitmap.ToString().ToLower());
var allowQRCodeBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_QRCODE, false);
data.Add("@是否打印二维码@", allowQRCodeBitmap.ToString().ToLower());
v.Value = JsonUtils.Serialize(data);
vars.Add(v);
v = new Printer.VariableValue();
v.Key = "点单列表";
v.DataType = DataType.List;
var list = new List<Dictionary<string, string>>();
decimal totalQuantity = 0;
decimal totalAmount = 0;
decimal totalDiscountAmount = 0;
//排序,避免显示列表和打印列表不一致
var items = orderObject.Items.OrderBy(x => x.OrderNo);
foreach (var item in items)
{
var row = new Dictionary<string, string>();
//判断参数配置中是否定义显示简称
var showShortName = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_SHORTNAME, false);
//销售界面名称的显示
string showName = (showShortName && !string.IsNullOrEmpty(item.ShortName)) ? item.ShortName : item.Name;
//是否打印规格
var notAllowSepc = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_SPEC, false);
//规格名称
string specName = (notAllowSepc || string.IsNullOrEmpty(item.SpecName)) ? "" : Global.Instance.Additional.Item1 + item.SpecName + Global.Instance.Additional.Item2;
//附加规格到名称中
string displayName = showName + specName;
if (item.RowState == OrderRowState.)
{
displayName = " " + displayName;
}
if (item.RowState == OrderRowState. || item.RowState == OrderRowState.)
{
if (item.Promotions != null)
{
//禁止收银前台赠送
bool notAllowShowGive = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NOT_ALLOW_SHOW_GIVE, true);
if (!notAllowShowGive && item.Promotions.Exists(x => x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("赠") + Global.Instance.Additional.Item2 + displayName;
}
//禁止收银前台折扣
bool notAllowShowDiscount = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NOT_ALLOW_SHOW_DISCOUNT, true);
if (!notAllowShowDiscount && item.Promotions.Exists(x => x.PromotionType == PromotionType. || x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("折") + Global.Instance.Additional.Item2 + displayName;
}
//禁止收银前台议价
bool notAllowShowBargain = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NOT_ALLOW_SHOW_BARGAIN, true);
if (!notAllowShowBargain && item.Promotions.Exists(x => x.PromotionType == PromotionType. || x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("议") + Global.Instance.Additional.Item2 + displayName;
}
//双数特价
if (item.Promotions.Exists(x => x.PromotionType == PromotionType. || x.PromotionType == PromotionType.))
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("双") + Global.Instance.Additional.Item2 + displayName;
}
}
}
row.Add("@品名@", displayName);
row.Add("@数量@", (item.Quantity - item.RefundQuantity) + "");
//列表是否显示折后价
bool showDiscountPrice = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_DISCOUNTPRICE, false);
decimal _salePrice = item.Price;
if (showDiscountPrice)
{
_salePrice = item.DiscountPrice;
}
decimal _amount = item.Amount;
if (showDiscountPrice)
{
_amount = item.Amount - item.DiscountAmount;
}
if (item.RowState == OrderRowState.)
{
row.Add("@单价@", "");
row.Add("@小计@", "");
row.Add("@优惠@", "");
}
else
{
row.Add("@单价@", _salePrice + "");
row.Add("@小计@", _amount + "");
row.Add("@优惠@", item.DiscountAmount + "");
}
list.Add(row);
//禁止打印做法
var notAllowFlavor = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_FLAVOR, false);
//允许打印做法或者做法包含加价
if (!notAllowFlavor || item.Flavors.Count > 0)
{
foreach (var flavor in item.Flavors)
{
row = new Dictionary<string, string>();
row.Add("@品名@", " " + flavor.Name);
row.Add("@数量@", (flavor.Quantity - flavor.RefundQuantity) + "");
if (flavor.Price != 0)
{
row.Add("@单价@", flavor.Price + "");
row.Add("@小计@", flavor.Amount + "");
row.Add("@优惠@", flavor.DiscountAmount + "");
}
else
{
row.Add("@单价@", string.Empty);
row.Add("@小计@", string.Empty);
row.Add("@优惠@", string.Empty);
}
list.Add(row);
//做法的合计的数据
totalQuantity += (flavor.Quantity - flavor.RefundQuantity);
totalAmount += flavor.Amount;
totalDiscountAmount += flavor.DiscountAmount;
}
}
//单品的合计的数据
if (item.RowState != OrderRowState.)
{
totalQuantity += (item.Quantity - item.RefundQuantity);
totalAmount += item.Amount;
totalDiscountAmount += item.DiscountAmount;
}
}
var total = new Dictionary<string, string>();
total.Add("@品名@", "合计");
total.Add("@数量@", totalQuantity + "");
total.Add("@单价@", "");
total.Add("@小计@", totalAmount + "");
total.Add("@优惠@", totalDiscountAmount + "");
list.Add(total);
v.Value = JsonUtils.Serialize(list);
vars.Add(v);
if (orderObject.Delivery != null)
{
v = new Printer.VariableValue();
v.Key = "外送信息";
v.DataType = DataType.Simple;
var delivery = new Dictionary<string, string>();
delivery.Add("@订餐人称呼@", orderObject.Delivery.Customer);
delivery.Add("@订餐人电话@", orderObject.Delivery.Telephone);
delivery.Add("@订餐人地址@", orderObject.Delivery.Address);
delivery.Add("@外送描述@", orderObject.Delivery.Description);
v.Value = JsonUtils.Serialize(delivery);
vars.Add(v);
}
return vars;
}
/// <summary>
/// 获取系统配置的厨打打印机
/// </summary>
/// <returns></returns>
public static PrinterObject GetKitchenPrinterObject(PrinterItem printer, bool cutPager)
{
var pobject = new PrinterObject();
pobject.Id = printer.Id;
pobject.Name = printer.Name;
pobject.PortType = (PortType)Enum.Parse(typeof(PortType), printer.Port);
pobject.DynamicLibrary = (DynamicLibrary)Enum.Parse(typeof(DynamicLibrary), printer.DynamicLibrary);
pobject.PageWidth = printer.PageWidth;
pobject.CutPager = cutPager;
pobject.OpenCashbox = false;
pobject.Data[PrinterObject.COM_PORT_NAME] = printer.Data[Constant.COM_PORT_NAME];
pobject.Data[PrinterObject.COM_PORT_BAUD] = printer.Data[Constant.COM_PORT_BAUD];
pobject.Data[PrinterObject.LPT_NAME] = printer.Data[Constant.LPT_NAME];
pobject.Data[PrinterObject.DRIVE_NAME] = printer.Data[Constant.DRIVE_NAME];
pobject.Data[PrinterObject.NET_IP_ADDRESS] = printer.Data[Constant.NET_IP_ADDRESS];
pobject.Data[PrinterObject.USB_PID] = printer.Data[Constant.USB_PID];
pobject.Data[PrinterObject.USB_VID] = printer.Data[Constant.USB_VID];
pobject.EscPosCommand.InitCommand = printer.InitCommand;
pobject.EscPosCommand.NormalCommand = printer.NormalCommand;
pobject.EscPosCommand.DoubleHeightCommand = printer.DoubleHeightCommand;
pobject.EscPosCommand.DoubleWidthCommand = printer.DoubleWidthCommand;
pobject.EscPosCommand.DoubleWidthHeightCommand = printer.DoubleWidthHeightCommand;
pobject.EscPosCommand.CutPageCommand = printer.CutPageCommand;
pobject.EscPosCommand.CashboxCommand = printer.CashboxCommand;
pobject.EscPosCommand.AlignCenterCommand = printer.AlignCenterCommand;
pobject.EscPosCommand.AlignLeftCommand = printer.AlignLeftCommand;
pobject.EscPosCommand.AlignRightCommand = printer.AlignRightCommand;
return pobject;
}
/// <summary>
/// 收银小票打印
/// </summary>
/// <param name="prefix"></param>
/// <param name="args"></param>
/// <param name="cutPager"></param>
/// <param name="openCashbox"></param>
/// <param name="headerLine"></param>
/// <param name="footerLine"></param>
/// <param name="footerLine"></param>
/// <returns></returns>
public static Tuple<bool, string> PrinterTicket(string prefix, List<VariableValue> args, bool cutPager, bool openCashbox, int headerLine, int footerLine)
{
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
Tuple<bool, string> result = new Tuple<bool, string>(false, "小票打印异常");
try
{
var pobject = GetTicketPrinterObject(cutPager, openCashbox);
if ("None".Equals(pobject.Name))
{
logger.Warn("收银参数设置不启用小票打印");
result = new Tuple<bool, string>(false, "不启用小票打印");
return result;
}
string fileName = string.Format(@"template\printer\{0}_{1}_{2}.designer", prefix, Global.Instance.Authc.TenantId, pobject.PageWidth);
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
if (!File.Exists(filePath))
{
fileName = string.Format(@"template\printer\{0}_通用模版_{1}.designer", prefix, pobject.PageWidth);
}
string template = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
if (File.Exists(template))
{
string json = System.IO.File.ReadAllText(template);
DesignerSurface surface = JSON.Deserialize<DesignerSurface>(json);
if (pobject.PortType == PortType. && pobject.Name.Contains("针式驱动打印"))
{
WinPrint.Print(pobject.Data.FirstOrDefault(f => f.Key == "drive").Value, surface, args);
result = new Tuple<bool, string>(true, "");
}
else
{
PrinterTemplate printer = surface.Parse(args);
var pcontent = printer.Parse(pobject, args, headerLine, footerLine);
result = PrinterUtils.PrintContent(pobject, pcontent);
}
}
else
{
result = new Tuple<bool, string>(false, "打印模版没有配置");
}
}
catch (Exception ex)
{
result = new Tuple<bool, string>(false, "打印异常了");
}
finally
{
sw.Stop();
logger.Info("收银小票打印耗时<{0}>", sw.ElapsedMilliseconds);
}
return result;
}
public static Tuple<bool, string> PrinterTicket(string prefix, List<VariableValue> args, bool cutPager, bool openCashbox)
{
return PrinterTicket(prefix, args, cutPager, openCashbox, 0, 0);
}
public static Tuple<bool, List<Printer.VariableValue>> BuilderKitchenVariable(OrderObject orderObject, List<OrderItem> items, KitchenPrinterItem printer, bool isChuda)
{
var vars = new List<Printer.VariableValue>();
var v = new Printer.VariableValue();
v.Key = "默认数据源";
v.DataType = DataType.Simple;
var data = new Dictionary<string, string>();
if (Global.Instance.IsStudyMode() && string.IsNullOrEmpty(orderObject.OrderNo))
{
data.Add("@序号@", Constant.STUDYMODE_DEFAULT_ORDERNO);
}
else
{
data.Add("@序号@", orderObject.OrderNo);
}
data.Add("@是否打印订单备注@", string.IsNullOrEmpty(orderObject.Ext1) ? "false" : "true");
data.Add("@订单备注@", string.IsNullOrEmpty(orderObject.Ext1) ? "" : orderObject.Ext1);
//Yao 2023-06-23 增加微信点餐 中的微信堂食和微信外带
//orderObject.OrderNo = "D203";
logger.Info("当前序号:{0}|{1}", orderObject.OrderNo, orderObject.OrderType);
//if (orderObject.OrderType == OrderType.微信点餐)
//{
//if (orderObject.OrderNo[0] == 'T')
// data.Add("@营业模式@", "微信堂食"); //微信堂食
// else if (orderObject.OrderNo[0] == 'D')
// data.Add("@营业模式@", "微信外带"); //微信外带
// else
data.Add("@营业模式@", LangProxy.ToLang(orderObject.OrderType.ToString()));
if (printer.Length > 0)
{
var str = orderObject.TradeNo;
if (str.Length < printer.Length)
{
str = str.PadLeft(printer.Length, '0');
}
data.Add("@票号@", str.Substring(str.Length - printer.Length));
}
else
{
data.Add("@票号@", orderObject.TradeNo);
}
var storeName = string.IsNullOrEmpty(Global.Instance.Worker.StoreInfo.PrintName) ? orderObject.StoreName : Global.Instance.Worker.StoreInfo.PrintName;
data.Add("@门店名称@", storeName);
data.Add("@门店编码@", orderObject.StoreNo);
data.Add("@门店地址@", Global.Instance.Worker.StoreInfo.Address);
data.Add("@门店电话@", Global.Instance.Worker.StoreInfo.OrderTel);
data.Add("@收银员编码@", orderObject.WorkerNo);
data.Add("@收银员名称@", orderObject.WorkerName);
data.Add("@POS编码@", orderObject.PosNo);
data.Add("@桌号@", orderObject.TableName);
data.Add("@打印时间@", orderObject.FinishDate);
data.Add("@重打标识@", string.Format("{0}", orderObject.RPrint));
data.Add("@方案名称@", orderObject.Ext3);
//zhangy 2020-05-09 Add 厨打添加订餐人和手机号
data.Add("@订餐人@", string.IsNullOrEmpty(orderObject.Ext2) ? "" : orderObject.Ext2);
if (orderObject.OrderStatus == OrderStatus. || orderObject.OrderStatus == OrderStatus.退)
{
data.Add("@是否打印退单标识@", "true");
data.Add("@退单@", "已退单");
}
else
{
data.Add("@是否打印退单标识@", "false");
data.Add("@退单@", "已退单");
}
decimal totalAmount = 0.00M;
foreach (OrderItem orderItem in items)
{
totalAmount += orderItem.TotalReceivableAmount;
}
data.Add("@总金额@", string.Format("{0}", totalAmount));
if (orderObject.OrderStatus == OrderStatus.退)
{
data.Add("@退单标识@", "true");
}
else
{
data.Add("@退单标识@", "false");
}
v.Value = JsonUtils.Serialize(data);
vars.Add(v);
v = new Printer.VariableValue();
v.Key = "点单列表";
v.DataType = DataType.List;
//练习模式
string studyName = string.Empty;
if (Global.Instance.IsStudyMode())
{
studyName = Constant.STUDYMODE_PRINTSTR;
}
var list = new List<Dictionary<string, string>>();
int seq = 1;
foreach (var item in items)
{
var seqStr = seq + ".";
var row = new Dictionary<string, string>();
//判断参数配置中是否定义显示简称
var showShortName = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_SHORTNAME, false);
//销售界面名称的显示
string showName = (showShortName && !string.IsNullOrEmpty(item.ShortName)) ? item.ShortName : item.Name;
//是否打印规格
var notAllowSepc = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_SPEC, false);
//规格名称
string specName = (notAllowSepc || string.IsNullOrEmpty(item.SpecName)) ? "" : Global.Instance.Additional.Item1 + item.SpecName + Global.Instance.Additional.Item2;
//附加规格到名称中
string displayName = showName + specName;
if (item.RowState == OrderRowState.)
{
displayName = Global.Instance.Additional.Item1 + LangProxy.ToLang("套") + Global.Instance.Additional.Item2 + displayName;
}
row.Add("@品名@", studyName + displayName);
decimal quantity = 0.00M;
if (isChuda)
{
//厨打
if (orderObject.OrderStatus == OrderStatus.退)
{
quantity = 0 - item.RefundQuantity;
}
else
{
if (orderObject.RPrint)
{
//重打
quantity = item.Quantity;
}
else
{
if (item.Quantity > item.ChudaQty)
{
quantity = item.Quantity - item.ChudaQty;
}
else
{
continue;
}
}
}
}
else
{
//出品
if (orderObject.OrderStatus == OrderStatus.退)
{
quantity = 0 - item.RefundQuantity;
}
else
{
if (orderObject.RPrint)
{
//重打
quantity = item.Quantity;
}
else
{
if (item.Quantity > item.ChupinQty)
{
quantity = item.Quantity - item.ChupinQty;
}
else
{
continue;
}
}
}
}
row.Add("@数量@", quantity + "");
row.Add("@单位@", item.ProductUnitName == null ? "" : item.ProductUnitName);
//列表是否显示折后价
bool showDiscountPrice = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_DISCOUNTPRICE, false);
decimal _salePrice = item.Price;
if (showDiscountPrice)
{
_salePrice = item.DiscountPrice;
}
decimal _amount = item.Amount;
if (showDiscountPrice)
{
_amount = item.Amount - item.DiscountAmount;
}
if (item.RowState == OrderRowState.)
{
row.Add("@序号@", seqStr);
row.Add("@单价@", "");
row.Add("@小计@", "");
row.Add("@优惠@", "");
}
else
{
row.Add("@序号@", seqStr);
row.Add("@单价@", _salePrice + "");
row.Add("@小计@", _amount + "");
row.Add("@优惠@", item.DiscountAmount + "");
}
list.Add(row);
//打印做法
if (item.Flavors.Count > 0)
{
foreach (var flavor in item.Flavors.Where(f => !f.Description.Equals("打包费") && !f.Description.Equals("配送费") && !f.Description.Equals("商家优惠")))
{
row = new Dictionary<string, string>();
row.Add("@序号@", "");
row.Add("@品名@", " " + flavor.Name);
row.Add("@数量@", (flavor.Quantity - flavor.RefundQuantity) + "");
row.Add("@单位@", "");
if (flavor.Price != 0)
{
row.Add("@单价@", flavor.Price + "");
row.Add("@小计@", flavor.Amount + "");
row.Add("@优惠@", flavor.DiscountAmount + "");
}
else
{
row.Add("@单价@", string.Empty);
row.Add("@小计@", string.Empty);
row.Add("@优惠@", string.Empty);
}
list.Add(row);
}
}
seq++;
}
if (list.Count > 0)
{
v.Value = JsonUtils.Serialize(list);
vars.Add(v);
return new Tuple<bool, List<VariableValue>>(true, vars);
}
else
{
return new Tuple<bool, List<VariableValue>>(false, null);
}
}
public static List<Printer.VariableValue> BuilderKitchenVariable(OrderObject orderObject)
{
var vars = new List<Printer.VariableValue>();
var v = new Printer.VariableValue();
v.Key = "默认数据源";
v.DataType = DataType.Simple;
var data = new Dictionary<string, string>();
data.Add("@序号@", orderObject.OrderNo);
//Yao 2023-06-23 增加微信点餐 中的微信堂食和微信外带
logger.Info("当前序号:{0}", orderObject.OrderNo);
//if (orderObject.OrderNo[0] == 'T')
// data.Add("@营业模式@", "微信堂食"); //微信堂食
//else if (orderObject.OrderNo[0] == 'D')
// data.Add("@营业模式@", "微信外带"); //微信外带
//else
//data.Add("@营业模式@", LangProxy.ToLang(orderObject.OrderType.ToString()));
data.Add("@票号@", orderObject.TradeNo);
var storeName = string.IsNullOrEmpty(Global.Instance.Worker.StoreInfo.PrintName) ? orderObject.StoreName : Global.Instance.Worker.StoreInfo.PrintName;
data.Add("@门店名称@", storeName);
data.Add("@门店编码@", orderObject.StoreNo);
data.Add("@门店地址@", Global.Instance.Worker.StoreInfo.Address);
data.Add("@门店电话@", Global.Instance.Worker.StoreInfo.OrderTel);
data.Add("@收银员编码@", orderObject.WorkerNo);
data.Add("@收银员名称@", orderObject.WorkerName);
data.Add("@POS编码@", orderObject.PosNo);
data.Add("@桌号@", orderObject.TableName);
data.Add("@打印时间@", orderObject.SaleDate);
data.Add("@条码内容@", orderObject.TradeNo);
data.Add("@条码说明@", orderObject.TradeNo);
data.Add("@二维码内容@", orderObject.TradeNo);
data.Add("@二维码说明@", orderObject.TradeNo);
data.Add("@票头图片@", orderObject.TradeNo);
data.Add("@票尾图片@", orderObject.TradeNo);
var notAllowTitle = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_TITLE, false);
data.Add("@是否打印标题@", (!notAllowTitle).ToString().ToLower());
var allowOrderNo = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_ORDERNO, false);
data.Add("@是否打印序号@", allowOrderNo.ToString().ToLower());
var notAllowStoreAddress = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_STORE_ADDRESS, false);
data.Add("@是否打印地址@", (!notAllowStoreAddress).ToString().ToLower());
var notAllowStoreTelphone = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_STORE_TELPHONE, false);
data.Add("@是否打印电话@", (!notAllowStoreTelphone).ToString().ToLower());
var allowHeaderBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_HEADER_BITMAP, false);
data.Add("@是否票头图片@", allowHeaderBitmap.ToString().ToLower());
var allowFooterBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_FOOTER_BITMAP, false);
data.Add("@是否票尾图片@", allowFooterBitmap.ToString().ToLower());
var allowBarCodeBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_BARCODE, false);
data.Add("@是否打印条码@", allowBarCodeBitmap.ToString().ToLower());
var allowQRCodeBitmap = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_ALLOW_QRCODE, false);
data.Add("@是否打印二维码@", allowQRCodeBitmap.ToString().ToLower());
v.Value = JsonUtils.Serialize(data);
vars.Add(v);
v = new Printer.VariableValue();
v.Key = "点单列表";
v.DataType = DataType.List;
var list = new List<Dictionary<string, string>>();
decimal totalQuantity = 0;
decimal totalAmount = 0;
decimal totalDiscountAmount = 0;
foreach (var item in orderObject.Items)
{
var row = new Dictionary<string, string>();
//判断参数配置中是否定义显示简称
var showShortName = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_SHORTNAME, false);
//销售界面名称的显示
string showName = (showShortName && !string.IsNullOrEmpty(item.ShortName)) ? item.ShortName : item.Name;
//是否打印规格
var notAllowSepc = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_SPEC, false);
//规格名称
string specName = (notAllowSepc || string.IsNullOrEmpty(item.SpecName)) ? "" : Global.Instance.Additional.Item1 + item.SpecName + Global.Instance.Additional.Item2;
//附加规格到名称中
string displayName = showName + specName;
if (item.RowState == OrderRowState.)
{
displayName = Global.Instance.Additional.Item1 + "套" + Global.Instance.Additional.Item2 + displayName;
}
row.Add("@品名@", displayName);
row.Add("@数量@", (item.Quantity - item.RefundQuantity) + "");
//列表是否显示折后价
bool showDiscountPrice = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_SHOW_DISCOUNTPRICE, false);
decimal _salePrice = item.Price;
if (showDiscountPrice)
{
_salePrice = item.DiscountPrice;
}
decimal _amount = item.Amount;
if (showDiscountPrice)
{
_amount = item.Amount - item.DiscountAmount;
}
row.Add("@单价@", _salePrice + "");
row.Add("@小计@", _amount + "");
row.Add("@优惠@", item.DiscountAmount + "");
list.Add(row);
//禁止打印做法
var notAllowFlavor = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_CASHIER_NOT_ALLOW_FLAVOR, false);
//允许打印做法或者做法包含加价
if (!notAllowFlavor || item.Flavors.Count > 0)
{
foreach (var flavor in item.Flavors)
{
row = new Dictionary<string, string>();
row.Add("@品名@", " " + flavor.Name);
row.Add("@数量@", (flavor.Quantity - flavor.RefundQuantity) + "");
row.Add("@单价@", flavor.Price + "");
row.Add("@小计@", flavor.Amount + "");
row.Add("@优惠@", flavor.DiscountAmount + "");
list.Add(row);
//做法的合计的数据
totalQuantity += (flavor.Quantity - flavor.RefundQuantity);
totalAmount += flavor.Amount;
totalDiscountAmount += flavor.DiscountAmount;
}
}
//单品的合计的数据
totalQuantity += (item.Quantity - item.RefundQuantity);
totalAmount += item.Amount;
totalDiscountAmount += item.DiscountAmount;
}
var total = new Dictionary<string, string>();
total.Add("@品名@", "合计");
total.Add("@数量@", totalQuantity + "");
total.Add("@单价@", "");
total.Add("@小计@", totalAmount + "");
total.Add("@优惠@", totalDiscountAmount + "");
list.Add(total);
v.Value = JsonUtils.Serialize(list);
vars.Add(v);
return vars;
}
/// <summary>
/// 厨打单打印
/// </summary>
/// <param name="prefix"></param>
/// <param name="args"></param>
/// <param name="cutPager"></param>
/// <returns></returns>
public static Tuple<bool, string> PrinterKitchen(KitchenPrinterItem kpi, string prefix, List<VariableValue> args, bool cutPager, int headerLine, int footerLine)
{
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
Tuple<bool, string> result = null;
try
{
var pobject = GetKitchenPrinterObject(kpi.PrinterItem, cutPager);
var beep = Global.Instance.GlobalConfigBoolValue(ConfigConstant.PERIPHERAL_KITCHEN_ALLOW_BEEP_CHUDA, false);
//厨房单蜂鸣
pobject.Beep = beep;
if ("None".Equals(pobject.Name))
{
logger.Warn("没有配置厨打方案对应的打印机");
result = new Tuple<bool, string>(false, "厨打方案打印机未配置");
return result;
}
string fileName = string.Format(@"template\printer\{0}_{1}_{2}.designer", prefix, Global.Instance.Authc.TenantId, pobject.PageWidth);
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
if (!File.Exists(filePath))
{
fileName = string.Format(@"template\printer\{0}_通用模版_{1}.designer", prefix, pobject.PageWidth);
}
string template = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
if (File.Exists(template))
{
string json = System.IO.File.ReadAllText(template);
DesignerSurface surface = JSON.Deserialize<DesignerSurface>(json);
PrinterTemplate printer = surface.Parse(args);
var pcontent = printer.Parse(pobject, args);
if (pobject.PortType == PortType. && pobject.Name.Contains("针式驱动打印"))
{
WinPrint.Print(pobject.Data.FirstOrDefault(f => f.Key == "drive").Value, surface, args);
result = new Tuple<bool, string>(true, "");
}
else
{
if (pcontent != null)
{
for (int i = 0; i < headerLine; i++)
{
var _header = new PrintContent();
_header.Format = RowFormat.Line;
_header.Content = new StringBuilder();
_header.AlignStyle = AlignStyle.;
_header.FontStyle = FontStyle.;
_header.BitmapFile = string.Empty;
pcontent.Insert(0, _header);
}
for (int i = 0; i < footerLine; i++)
{
var _footer = new PrintContent();
_footer.Format = RowFormat.Line;
_footer.Content = new StringBuilder();
_footer.AlignStyle = AlignStyle.;
_footer.FontStyle = FontStyle.;
_footer.BitmapFile = string.Empty;
pcontent.Add(_footer);
}
}
result = PrinterUtils.PrintContent(pobject, pcontent);
}
}
else
{
result = new Tuple<bool, string>(false, "厨打模版没有配置");
}
}
catch (Exception ex)
{
logger.Error(ex, "厨打异常");
result = new Tuple<bool, string>(false, "打印异常了");
}
finally
{
sw.Stop();
logger.Info("厨打耗时<{0}>", sw.ElapsedMilliseconds);
}
return result;
}
public static List<Printer.VariableValue> BuilderMemberRegisterVariable(string storeNo, string storeName, string workerNo, string workerName, string posNo, MemberInfoQueryResponse member)
{
var vars = new List<Printer.VariableValue>();
var v = new Printer.VariableValue();
v.Key = "默认数据源";
v.DataType = DataType.Simple;
var data = new Dictionary<string, string>();
data.Add("@门店名称@", storeName);
data.Add("@门店编码@", storeNo);
data.Add("@收银员编码@", workerNo);
data.Add("@收银员名称@", workerName);
data.Add("@POS编码@", posNo);
if (member.CardList != null && member.CardList.Count > 0)
{
var card = member.CardList[0];
//string cardNo = card.CardNo;
//if (!string.IsNullOrEmpty(card.FaceNo))
//{
// cardNo = card.FaceNo;
//}
data.Add("@会员卡号@", card.CardNo);
data.Add("@卡类型@", card.CardTypeName);
}
else
{
data.Add("@会员卡号@", "");
data.Add("@卡类型@", "");
}
data.Add("@手机号码@", member.Mobile);
data.Add("@打印时间@", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
data.Add("@会员姓名@", member.Name);
data.Add("@会员类型@", member.MemberTypeName);
data.Add("@备注@", member.Description);
v.Value = JsonUtils.Serialize(data);
vars.Add(v);
return vars;
}
public static Tuple<bool, string> PrinterMemberRegister(string prefix, List<VariableValue> args, bool cutPager)
{
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
Tuple<bool, string> result = null;
try
{
//采用收银打印机
var pobject = GetTicketPrinterObject(cutPager, false);
if ("None".Equals(pobject.Name))
{
logger.Warn("收银参数设置不启用会员登记打印");
result = new Tuple<bool, string>(false, "不启用会员登记打印");
return result;
}
string fileName = string.Format(@"template\printer\{0}_{1}_{2}.designer", prefix, Global.Instance.Authc.TenantId, pobject.PageWidth);
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
if (!File.Exists(filePath))
{
fileName = string.Format(@"template\printer\{0}_通用模版_{1}.designer", prefix, pobject.PageWidth);
}
string template = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
if (File.Exists(template))
{
string json = System.IO.File.ReadAllText(template);
DesignerSurface surface = JSON.Deserialize<DesignerSurface>(json);
PrinterTemplate printer = surface.Parse(args);
var pcontent = printer.Parse(pobject, args);
result = PrinterUtils.PrintContent(pobject, pcontent);
}
else
{
result = new Tuple<bool, string>(false, "会员登记模版没有配置");
}
}
catch (Exception ex)
{
result = new Tuple<bool, string>(false, "打印异常了");
}
finally
{
sw.Stop();
logger.Info("会员登记小票打印耗时<{0}>", sw.ElapsedMilliseconds);
}
return result;
}
/// <summary>
/// 开钱箱
/// </summary>
/// <returns></returns>
public static Tuple<bool, string> OpenCashBox()
{
Tuple<bool, string> result = null;
var pobject = GetTicketPrinterObject(false, true);
if ("None".Equals(pobject.Name))
{
logger.Warn("收银参数未设置小票打印机,无法开钱箱");
result = new Tuple<bool, string>(false, "未配置打印机,无法开钱箱");
return result;
}
logger.Info("工号[{0}]手动打开钱箱", Global.Instance.Worker.No);
var content = new List<PrintContent>();
PrinterTemplate printer = new PrinterTemplate();
content.Add(printer.OpenCashbox(pobject));
//启动新任务
Task.Factory.StartNew(() =>
{
PrinterUtils.PrintContent(pobject, content);
});
return new Tuple<bool, string>(true, "执行开钱箱成功!");
}
}
}