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#

This file contains ambiguous Unicode characters!

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

using 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);
}
}
}
}