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.

647 lines
28 KiB
C#

9 months ago
using DevComponents.DotNetBar.Controls;
using POSV.Card;
using POSV.Entity.Pormotion;
using POSV.Helper;
using POSV.MessageEvent;
using POSV.ShoppingCart;
using POSV.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace POSV.Component
{
public partial class CouponForm : BusinessForm
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private OrderObject _orderObject = null;
private bool _lock = true;
public CouponForm(OrderObject orderObject)
{
InitializeComponent();
_orderObject = orderObject;
//this.couponListPanel1.Width += 18;
this.ActiveControl = this.txtCouponCode;
this.superTabControl1.SelectedTabIndex = 0;
this.couponListPanel1.ButtonClick += OnCouponButtonClick;
}
public delegate void EventHandler(object sender, NotifyEventArgs e);
public event EventHandler CouponClick;
protected virtual void OnCouponClick(object sender, NotifyEventArgs e)
{
if (_lock)
{
_lock = false;
try
{
var data = e.Data as ElectronCoupon;
var notAllowMultipleCoupon = Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_NO_ALLOW_MULTIPLE_COUPON, false);
if (notAllowMultipleCoupon)
{
var promotionExists = this._orderObject.Items.Exists(x => x.Promotions.Exists(o => o.PromotionType == PromotionType. || o.PromotionType == PromotionType. || o.PromotionType == PromotionType. || o.PromotionType == PromotionType.));
logger.Info("当前已使用电子兑换券<{0}>", promotionExists);
if (promotionExists && data.ErrorType == (int)MemberCouponStatus.)
{
var dialog = new DialogForm("操作失败", "不允许同一单使用多张优惠券", MessageBoxIcon.Error, MessageBoxButtons.OK);
dialog.TopLevel = true;
dialog.ShowDialog(this);
return;
}
}
switch (data.CardType)
{
case MemberCouponType.DISCOUNT:
case MemberCouponType.CASH:
{
CouponClick?.Invoke(this, e);
}
break;
case MemberCouponType.GIFT:
{
ConsumeGiftCoupon(data, e);
}
break;
case MemberCouponType.PRODUCT:
{
ConsumeProductCoupon(data, e);
}
break;
}
}
catch (Exception ex)
{
logger.Error(ex,"使用电子券发生异常");
_lock = true;
}
finally
{
_lock = true;
}
}
}
private void OnCouponButtonClick(object sender, NotifyEventArgs e)
{
OnCouponClick(sender, e);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (DesignMode) return;
InstallMemberCoupon();
}
/// <summary>
/// 核销卡券
/// </summary>
/// <param name="coupon"></param>
private void ConsumeGiftCoupon(ElectronCoupon coupon, NotifyEventArgs e)
{
if (coupon.CardType == MemberCouponType.GIFT && coupon.GiftType == 1)
{
//如果是兑换券,并且是礼品券
var gift = JsonUtils.Deserialize<CouponGift>(coupon.Gift);
if (gift != null)
{
var dialog = new DialogForm("核销兑换券确认提醒", string.Format("确定核销<{0}>", coupon.Title), MessageBoxIcon.Question, MessageBoxButtons.OKCancel);
if (dialog.ShowDialog(this) == DialogResult.OK)
{
//核销兑换券
logger.Info("发起礼品兑换券核销,电子券<{0}>,券标题<{1}>", coupon.Code, coupon.Title);
var result = CardUtils.ConsumeElecCoupon("", coupon.Code, coupon.Mobile, coupon.CardNo, "saoma", (int)(gift.Worth * 100), (int)(gift.Cost * 100));
logger.Info("礼品兑换券<{0}>核销结果:{1}", coupon.Code, result.Item2);
if (result.Item1)
{
//成功
logger.Info("礼品兑换券<{0}>核销成功", coupon.Code);
//打印电子券核销单
var vars = CardHelper.BuilderCouponConsumeVariable(coupon.Code, coupon.Title);
//卡券核销打印份数
int ticketCount = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_CHECKCOUPON_COUNT, 1);
//打印延迟
int delaySecond = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_CARD_PRINT_DELAY, 1);
CardHelper.PrinterTicket("会员卡券核销", vars, true, false, ticketCount, delaySecond);
coupon.ErrorType = (int)MemberCouponStatus.使;
MsgEvent.Send(Constant.MEMBERCOUPON_CHANGE_NOTIFY, new Tuple<ElectronCoupon, bool>(coupon, true));
dialog = new DialogForm("核销兑换券提醒", string.Format("核销电子券<{0}>成功!", coupon.Title), MessageBoxIcon.Warning, MessageBoxButtons.OK);
dialog.ShowDialog(this);
}
else
{
//失败
dialog = new DialogForm("核销兑换券失败提醒", string.Format("核销失败!原因:{0}", result.Item2), MessageBoxIcon.Error, MessageBoxButtons.OK);
dialog.ShowDialog(this);
}
}
}
else
{
var dialog = new DialogForm("核销兑换券提醒", string.Format("失败!<{0}>商品信息为空!", coupon.Title), MessageBoxIcon.Error, MessageBoxButtons.OK);
dialog.ShowDialog(this);
}
}
else if (coupon.CardType == MemberCouponType.GIFT && coupon.GiftType == 2)
{
//如果是兑换券,并且是商品券
var gift = JsonUtils.Deserialize<List<CouponProductGift>>(coupon.Gift);
if (gift != null)
{
string message = "";
if (coupon.ErrorType == 50)
{
message = string.Format("取消核销<{0}>", coupon.Title);
}
else
{
message = string.Format("确定核销<{0}>", coupon.Title);
}
var dialog = new DialogForm("核销兑换券确认提醒", message, MessageBoxIcon.Question, MessageBoxButtons.OKCancel);
if (dialog.ShowDialog(this) == DialogResult.OK)
{
//使用商品兑换券
logger.Info("商品兑换券<{0}>确定核销", coupon.Code);
CouponClick?.Invoke(this, e);
}
}
}
}
/// <summary>
/// 核销卡券
/// </summary>
/// <param name="coupon"></param>
private void ConsumeProductCoupon(ElectronCoupon coupon, NotifyEventArgs e)
{
if (coupon.CardType == MemberCouponType.PRODUCT)
{
//如果是商品券
var gift = JsonUtils.Deserialize<List<CouponProductGift>>(coupon.Gift);
if (gift != null)
{
string message = "";
if (coupon.ErrorType == 50)
{
message = string.Format("取消核销<{0}>", coupon.Title);
}
else
{
message = string.Format("确定核销<{0}>", coupon.Title);
}
var dialog = new DialogForm("核销商品券确认提醒", message, MessageBoxIcon.Question, MessageBoxButtons.OKCancel);
if (dialog.ShowDialog(this) == DialogResult.OK)
{
//使用商品兑换券
logger.Info("商品券<{0}>确定核销", coupon.Code);
CouponClick?.Invoke(this, e);
}
}
}
}
/// <summary>
/// 加载当前会员拥有的优惠券
/// </summary>
private void InstallMemberCoupon()
{
try
{
Task.Factory.StartNew(() =>
{
List<ElectronCoupon> list = new List<ElectronCoupon>();
if (_orderObject.Member != null)
{
int amount = (int)(PromotionUtils.GetValidPromItemsAmount(_orderObject) * 100);
var resp = CardUtils.QueryElecCoupon("mobile", _orderObject.Member.Mobile, "0", 1);
if (resp.Item1)
{
list = resp.Item3;
if (list == null)
{
list = new List<ElectronCoupon>();
}
}
}
return list;
}).ContinueWith(task =>
{
if (task.IsFaulted)
{
logger.Error(task.Exception.GetBaseException());
}
else
{
var result = AnalyseCoupon(task.Result);
if (this.IsDisposed || !this.IsHandleCreated) return;
this.Invoke(new Action(() =>
{
this.superTabItem1.Text = string.Format(this.superTabItem1.Tag.ToString(), result.Item1.Count);
this.couponListPanel1.RefreshCoupons(result.Item1);
this.superTabItem2.Text = string.Format(this.superTabItem2.Tag.ToString(), result.Item2.Count);
this.couponListPanel2.RefreshCoupons(result.Item2);
//this.Invalidate();
}));
}
});
}
catch (Exception ex)
{
logger.Error(ex, "加载会员优惠券异常");
}
}
/// <summary>
/// 分析当前可用\不可用电子券
/// </summary>
/// <param name="list"></param>
private Tuple<List<ElectronCoupon>, List<ElectronCoupon>> AnalyseCoupon(List<ElectronCoupon> list)
{
List<ElectronCoupon> enableList = new List<ElectronCoupon>();
List<ElectronCoupon> disableList = new List<ElectronCoupon>();
foreach (var coupon in list)
{
var result = CheckCouponValid(coupon);
coupon.ErrorType = (int)result.Item2;
coupon.ErrorInfo = result.Item3;
if (result.Item1)
{
enableList.Add(coupon);
}
else
{
disableList.Add(coupon);
}
}
return new Tuple<List<ElectronCoupon>, List<ElectronCoupon>>(enableList, disableList);
}
private Tuple<bool, MemberCouponStatus, string> CheckCouponValid(ElectronCoupon coupon)
{
MemberCouponStatus statusType = MemberCouponStatus.;
bool status = true;
string message = string.Empty;
//状态可用
if (coupon.Status == 1)
{
//时间有效
var calTime = Convert.ToDateTime(_orderObject.SaleDate);
//当前是否在优惠期限内
var startDate = Convert.ToDateTime(coupon.BeginTimestamp);
var endDate = Convert.ToDateTime(coupon.EndTimestamp);
if (calTime.CompareTo(startDate) < 0 || calTime.CompareTo(endDate) > 0)
{
status = false;
if (calTime.CompareTo(startDate) < 0)
{
statusType = MemberCouponStatus.;
message = "未到可用时间";
}
else
{
statusType = MemberCouponStatus.;
message = "已过期";
}
}
else
{
//时段有效
if (coupon.LimitType == 1)
{
//限制星期
var weekEn = calTime.DayOfWeek.ToString().ToUpper();
if (!coupon.TimeLimit.Contains(weekEn))
{
status = false;
statusType = MemberCouponStatus.;
message = "不在可用时段内";
}
}
if (status)
{
if (coupon.CardType == MemberCouponType.CASH)
{
//代金券启用金额
//排除已经参与优惠的商品,计算有效的订单金额
var validItems = _orderObject.Items.FindAll(x => x.RowState != OrderRowState.
&& !_orderObject.Items.Exists(y => y.RowState != OrderRowState. && y.ParentId == x.Id));
var validAmount = validItems.Sum(x => x.Amount);
if (coupon.LeastCost > 0)
{
//可以参与优惠的金额
var tempLeast = coupon.LeastCost / 100M;
if (validAmount < tempLeast)
{
status = false;
statusType = MemberCouponStatus.;
message = "未达最低消费额";
}
}
}
else if (coupon.CardType == MemberCouponType.DISCOUNT)
{
//启用金额
//排除已经参与优惠的商品,计算有效的订单金额
var validItems = _orderObject.Items.FindAll(x => x.RowState != OrderRowState.
&& (x.Promotions.Count == 0
|| (x.Promotions.Count == 1 && x.Promotions[0].PlanNo == coupon.Code))
&& x.DiscountFlag == 0
&& !_orderObject.Items.Exists(y => y.RowState != OrderRowState. && y.ParentId == x.Id));
var validAmount = validItems.Sum(x => x.Amount);
if (coupon.LeastCost > 0)
{
//可以参与优惠的金额
var tempLeast = coupon.LeastCost / 100M;
if (validAmount < tempLeast)
{
status = false;
statusType = MemberCouponStatus.;
message = "未达最低消费额";
}
}
}
else if (coupon.CardType == MemberCouponType.GIFT)
{
//启用金额
//排除已经参与优惠的商品,计算有效的订单金额
bool isGo = false;
foreach (OrderItem oo in _orderObject.Items)
{
if (oo.Promotions.FindAll(y => y.PlanNo == coupon.Code).Count > 0)
{
isGo = true;
}
}
var validItems = new List<OrderItem>();
if (isGo)
{
validItems = _orderObject.Items.FindAll(x => x.RowState != OrderRowState.
&& !_orderObject.Items.Exists(y => y.RowState != OrderRowState. && y.ParentId == x.Id));
}
else
{
validItems = _orderObject.Items.FindAll(x => x.RowState != OrderRowState.
&& (x.Promotions.Count == 0
|| (x.Promotions.Count > 0 && x.Promotions.FindAll(y => y.PromotionType != PromotionType. && y.PromotionType != PromotionType.).Count <= 0)
)
&& !_orderObject.Items.Exists(y => y.RowState != OrderRowState. && y.ParentId == x.Id));
}
var validAmount = validItems.Sum(x => x.Amount);
if (coupon.LeastCost > 0)
{
//可以参与优惠的金额
var tempLeast = coupon.LeastCost / 100M;
if (validAmount < tempLeast)
{
status = false;
statusType = MemberCouponStatus.;
message = "未达最低消费额";
}
}
}
else if (coupon.CardType == MemberCouponType.PRODUCT)
{
//启用金额
//排除已经参与优惠的商品,计算有效的订单金额
bool isGo = false;
foreach (OrderItem oo in _orderObject.Items)
{
if (oo.Promotions.FindAll(y => y.PlanNo == coupon.Code).Count > 0)
{
isGo = true;
}
}
var validItems = new List<OrderItem>();
if (isGo)
{
validItems = _orderObject.Items.FindAll(x => x.RowState != OrderRowState.
&& !_orderObject.Items.Exists(y => y.RowState != OrderRowState. && y.ParentId == x.Id));
}
else
{
validItems = _orderObject.Items.FindAll(x => x.RowState != OrderRowState.
&& (x.Promotions.Count == 0
|| (x.Promotions.Count > 0 && x.Promotions.FindAll(y => y.PromotionType != PromotionType. && y.PromotionType != PromotionType.).Count <= 0)
)
&& !_orderObject.Items.Exists(y => y.RowState != OrderRowState. && y.ParentId == x.Id));
}
var validAmount = validItems.Sum(x => x.Amount);
if (coupon.LeastCost > 0)
{
//可以参与优惠的金额
var tempLeast = coupon.LeastCost / 100M;
if (validAmount < tempLeast)
{
status = false;
statusType = MemberCouponStatus.;
message = "未达最低消费额";
}
}
}
if (status)
{
status = true;
statusType = MemberCouponStatus.;
message = "可用";
//检查是否正在使用中
var proms = _orderObject.Promotions;
if (proms != null)
{
if (proms.Exists(x => x.PlanNo == coupon.Code))
{
statusType = MemberCouponStatus.使;
PromotionOrder promotion = proms.Find(x => x.PlanNo == coupon.Code);
coupon.RealMoney = OrderUtils.ToRound(promotion.DiscountAmount);
message = "使用中";
}
}
var orderItem = _orderObject.Items;
decimal realMoney = 0.00M;
foreach (OrderItem item in orderItem)
{
var promsItem = item.Promotions;
if (promsItem != null)
{
if (promsItem.Exists(x => x.PlanNo == coupon.Code))
{
statusType = MemberCouponStatus.使;
List<PromotionItem> promotion = promsItem.FindAll(x => x.PlanNo == coupon.Code);
if (promotion != null && promotion.Count > 0)
{
realMoney += OrderUtils.ToRound(promotion.Sum(x => x.DiscountAmount));
}
message = "使用中";
}
}
}
coupon.RealMoney = realMoney;
}
}
}
}
else
{
if (coupon.Status == 2)
{
status = false;
statusType = MemberCouponStatus.使;
message = "已使用";
}
else if (coupon.Status == 3)
{
status = false;
statusType = MemberCouponStatus.;
message = "已过期";
}
else
{
status = false;
statusType = MemberCouponStatus.;
message = "券状态未知";
}
}
return new Tuple<bool, MemberCouponStatus, string>(status, statusType, message);
}
private void OnCloseTouchClick(object sender, TouchEventArgs e)
{
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
private void OnPageUpClick(object sender, EventArgs e)
{
if (this.superTabControl1.SelectedTabIndex == 0)
{
//可用
this.couponListPanel1.PageUp();
}
else
{
//不可用
this.couponListPanel2.PageUp();
}
}
private void OnPageDownClick(object sender, EventArgs e)
{
if (this.superTabControl1.SelectedTabIndex == 0)
{
//可用
this.couponListPanel1.PageDown();
}
else
{
//不可用
this.couponListPanel2.PageDown();
}
}
private void QueryCouponByCode(string code)
{
var result = CardUtils.QueryCouponDetail(code);
if (result != null)
{
if (result.Item1)
{
//获取成功
var data = result.Item3;
if (data != null)
{
var validRes = CheckCouponValid(data);
if (validRes.Item1)
{
//验证通过
OnCouponClick(this, new NotifyEventArgs(NotifyAction.Accept, data));
//关闭
OnCloseTouchClick(this, null);
}
else
{
//非法
var dialog = new DialogForm("验证失败提醒", string.Format("<{0}>优惠券不可用,原因为:{1}", data.Title, validRes.Item3), MessageBoxIcon.Error, MessageBoxButtons.OK);
dialog.TopLevel = true;
dialog.ShowDialog(this);
this.txtCouponCode.Text = string.Empty;
}
}
}
else
{
//获取失败
this.ShowToastNotify(this, result.Item2);
this.txtCouponCode.Text = string.Empty;
}
}
}
private void OnCouponCodeEnterClick(object sender, EnterEventArg e)
{
var couponNo = this.txtCouponCode.Text.Trim();
QueryCouponByCode(couponNo);
}
private void OnQueryClick(object sender, EventArgs e)
{
OnCouponCodeEnterClick(sender, null);
}
private void OnKeyboardClick(object sender, EventArgs e)
{
if (sender is NumericTextBox)
{
var obj = sender as NumericTextBox;
var point = this.PointToScreen(obj.Location);
var p = NumericKeyboard.CalculateLocation(point, obj.Width);
NumericKeyboard.ShowKeyboard(this, p);
}
}
}
}