|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using POSV.Entity.Pormotion;
|
|
|
using POSV.Utils;
|
|
|
|
|
|
namespace POSV.ShoppingCart
|
|
|
{
|
|
|
public class PromotionUtils
|
|
|
{
|
|
|
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取可打折金额,排除指定优惠
|
|
|
/// </summary>
|
|
|
/// <param name="orderObject"></param>
|
|
|
/// <param name="withOutProm"></param>
|
|
|
/// <returns></returns>
|
|
|
public static List<OrderItem> GetValidPromItems(OrderObject orderObject, string planNo)
|
|
|
{
|
|
|
return orderObject.Items.FindAll(x => x.RowState != OrderRowState.套餐明 &&
|
|
|
(x.Promotions.Count == 0 || (x.Promotions.Count == 1 && x.Promotions[0].PlanNo == planNo))
|
|
|
&& x.DiscountFlag == 1 && !orderObject.Items.Exists(y => y.RowState != OrderRowState.套餐明 && y.ParentId == x.Id));
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取可打折参与优惠的商品总金额,排除指定优惠
|
|
|
/// </summary>
|
|
|
/// <param name="orderObject"></param>
|
|
|
/// <param name="withOutProm"></param>
|
|
|
/// <returns></returns>
|
|
|
public static decimal GetValidPromItemsAmount(OrderObject orderObject, string planNo)
|
|
|
{
|
|
|
var validItems = GetValidPromItems(orderObject, planNo);
|
|
|
return validItems.Sum(x => x.Amount);
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取可打折参与优惠的商品
|
|
|
/// </summary>
|
|
|
/// <param name="orderObject"></param>
|
|
|
/// <returns></returns>
|
|
|
public static List<OrderItem> GetValidPromItems(OrderObject orderObject)
|
|
|
{
|
|
|
return orderObject.Items.FindAll(x => x.RowState != OrderRowState.套餐明 && x.Promotions.Count == 0 && x.DiscountFlag == 1 );
|
|
|
//return orderObject.Items.FindAll(x => x.RowState != OrderRowState.套餐明 && x.Promotions.Count == 0 && x.DiscountFlag == 1 && !orderObject.Items.Exists(y => y.ParentId == x.Id));
|
|
|
}
|
|
|
|
|
|
public static decimal GetValidPromItemsByCoupon(OrderObject orderObject, MemberCouponType type)
|
|
|
{
|
|
|
var validAmount = 0.00M;
|
|
|
if (type == MemberCouponType.CASH)
|
|
|
{
|
|
|
//代金券启用金额
|
|
|
//排除已经参与优惠的商品,计算有效的订单金额
|
|
|
var validItems = orderObject.Items.FindAll(x => x.RowState != OrderRowState.套餐明
|
|
|
&& !orderObject.Items.Exists(y => y.RowState != OrderRowState.套餐明 && y.ParentId == x.Id));
|
|
|
validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
}
|
|
|
else if (type == MemberCouponType.DISCOUNT)
|
|
|
{
|
|
|
//启用金额
|
|
|
//排除已经参与优惠的商品,计算有效的订单金额
|
|
|
var validItems = orderObject.Items.FindAll(x => x.RowState != OrderRowState.套餐明
|
|
|
&& x.Promotions.Count == 0
|
|
|
&& x.DiscountFlag == 0
|
|
|
&& !orderObject.Items.Exists(y => y.RowState != OrderRowState.套餐明 && y.ParentId == x.Id));
|
|
|
validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
}
|
|
|
else if (type == MemberCouponType.GIFT)
|
|
|
{
|
|
|
//启用金额
|
|
|
//排除已经参与优惠的商品,计算有效的订单金额
|
|
|
var 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));
|
|
|
validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
}
|
|
|
else if (type == MemberCouponType.PRODUCT)
|
|
|
{
|
|
|
//启用金额
|
|
|
//排除已经参与优惠的商品,计算有效的订单金额
|
|
|
var 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));
|
|
|
validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
}
|
|
|
return validAmount;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取可打折参与优惠的商品总金额
|
|
|
/// </summary>
|
|
|
/// <param name="orderObject"></param>
|
|
|
/// <returns></returns>
|
|
|
public static decimal GetValidPromItemsAmount(OrderObject orderObject)
|
|
|
{
|
|
|
var validItems = GetValidPromItems(orderObject);
|
|
|
return validItems.Sum(x => x.Amount);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 更新套餐主信息
|
|
|
/// </summary>
|
|
|
/// <param name="item"></param>
|
|
|
public static void UpdateSuitMain(OrderObject orderObject,OrderItem item)
|
|
|
{
|
|
|
if (item.RowState == OrderRowState.套餐主 || item.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
var mainItem = orderObject.Items.Find(x => x.Group == item.Group && x.RowState == OrderRowState.套餐主);
|
|
|
var subItems = orderObject.Items.FindAll(x => x.Group == item.Group && x.RowState == OrderRowState.套餐明);
|
|
|
if (mainItem != null && subItems != null)
|
|
|
{
|
|
|
mainItem.FlavorCount = subItems.Sum(x => x.FlavorCount);
|
|
|
mainItem.FlavorAmount = subItems.Sum(x => x.FlavorAmount);
|
|
|
mainItem.FlavorDiscountAmount = subItems.Sum(x => x.FlavorDiscountAmount);
|
|
|
mainItem.FlavorReceivableAmount = subItems.Sum(x => x.FlavorReceivableAmount);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static void PromotionMake(OrderItem orderItem, PromotionItem promotionItem) {
|
|
|
List<PromotionItem> newItems = new List<PromotionItem>();
|
|
|
|
|
|
switch (promotionItem.PromotionType)
|
|
|
{
|
|
|
case PromotionType.折扣:
|
|
|
case PromotionType.整单折扣:
|
|
|
case PromotionType.电子折扣券:
|
|
|
{
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
promotionItem.DiscountRate =( 1 - promotionItem.MainProductRate);
|
|
|
}
|
|
|
else {
|
|
|
newItems.Add(promotionItem);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.免单:
|
|
|
case PromotionType.赠送:
|
|
|
{
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
promotionItem.DiscountRate = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
promotionItem.DiscountRate = 0;
|
|
|
newItems.Add(promotionItem);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
if (orderItem.Flavors != null && orderItem.Flavors.Count > 0)
|
|
|
{
|
|
|
foreach (FlavorItem flavorItem in orderItem.Flavors)
|
|
|
{
|
|
|
flavorItem.DiscountPrice = OrderUtils.ToRound(flavorItem.Price * promotionItem.DiscountRate);
|
|
|
flavorItem.DiscountAmount = OrderUtils.ToRound(flavorItem.Amount * (1 - promotionItem.DiscountRate));
|
|
|
}
|
|
|
PromotionItem promotionItemMake = new PromotionItem();
|
|
|
promotionItemMake.Id = IdWorkerUtils.Instance.NextId();
|
|
|
promotionItemMake.TenantId = orderItem.TenantId;
|
|
|
promotionItemMake.OrderId = orderItem.OrderId;
|
|
|
promotionItemMake.TradeNo = orderItem.TradeNo;
|
|
|
promotionItemMake.ItemId = orderItem.Id;
|
|
|
promotionItemMake.PromotionType = PromotionType.做法折扣;
|
|
|
promotionItemMake.Amount = orderItem.FlavorAmount;
|
|
|
promotionItemMake.DiscountAmount = orderItem.FlavorDiscountAmount;
|
|
|
promotionItemMake.ReceivableAmount = orderItem.FlavorReceivableAmount;
|
|
|
promotionItemMake.DiscountRate = promotionItem.DiscountRate;
|
|
|
promotionItemMake.Enabled = false;
|
|
|
promotionItemMake.FinishDate = orderItem.FinishDate;
|
|
|
newItems.Add(promotionItemMake);
|
|
|
}
|
|
|
ReplaceItems(orderItem.Promotions, newItems);
|
|
|
}
|
|
|
|
|
|
public static void Calculate(OrderObject orderObject , PromotionOrder promotionItem)
|
|
|
{
|
|
|
switch (promotionItem.PromotionType)
|
|
|
{
|
|
|
case PromotionType.整单折扣:
|
|
|
{
|
|
|
foreach(var orderItem in orderObject.Items)
|
|
|
{
|
|
|
//服务端禁止单品折扣
|
|
|
if(orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许折扣";
|
|
|
continue;
|
|
|
}
|
|
|
//忽略套餐明细,套餐明细依赖套餐主分摊折扣
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//折扣类型
|
|
|
discount.PromotionType = PromotionType.整单折扣;
|
|
|
//方案
|
|
|
discount.PlanName = promotionItem.PlanName;
|
|
|
//输入80代表8折,折扣率为0.8
|
|
|
discount.DiscountRate = promotionItem.DiscountRate;
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = OrderUtils.ToRound(discount.Amount * (1 - discount.DiscountRate));
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = discount.Amount - discount.DiscountAmount;
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "整单折扣操作";
|
|
|
|
|
|
//做法是否参与折扣
|
|
|
if (!Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_ALLOW_MAKEDISCOUNT, false))
|
|
|
{
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (orderItem.RowState == OrderRowState.普通)
|
|
|
{
|
|
|
PromotionMake(orderItem, discount);
|
|
|
}
|
|
|
else if (orderItem.RowState == OrderRowState.套餐主)
|
|
|
{
|
|
|
PromotionMake(orderItem, discount);
|
|
|
List<OrderItem> orderItemDetailList = orderObject.Items.FindAll(x => x.RowState == OrderRowState.套餐明 && orderItem.Id.Equals(x.ParentId));
|
|
|
foreach (OrderItem orderItemDetail in orderItemDetailList)
|
|
|
{
|
|
|
discount.MainProductRate = orderItem.DiscountRate;
|
|
|
PromotionMake(orderItemDetail, discount);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderObject.Amount;
|
|
|
//优惠金额
|
|
|
promotionItem.DiscountAmount = OrderUtils.ToRound(promotionItem.Amount * (1 - promotionItem.DiscountRate));
|
|
|
//优惠后金额
|
|
|
promotionItem.ReceivableAmount = promotionItem.Amount - promotionItem.DiscountAmount;
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.整单议价:
|
|
|
{
|
|
|
//整单议价需要分摊给单品
|
|
|
//单品分摊计算规则:单品的金额 / 整单金额小计 * 议价后金额 = 单品分摊的金额;
|
|
|
//折后单价计算规则:单品分摊后单价 = 单品分摊的金额 / 单品数量
|
|
|
//单品折扣率 = 单品分摊金额 / 单品金额小计
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
decimal sum = 0;
|
|
|
var lists = orderObject.Items.OrderBy(x => x.OrderNo).ToList();
|
|
|
for (int i = 0;i< lists.Count; i++)
|
|
|
{
|
|
|
var orderItem = lists[i];
|
|
|
|
|
|
//服务端禁止单品折扣
|
|
|
if (orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许议价";
|
|
|
continue;
|
|
|
}
|
|
|
//忽略套餐明细,套餐明细依赖套餐主分摊折扣
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//折扣类型
|
|
|
discount.PromotionType = PromotionType.整单议价;
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
//分摊的金额
|
|
|
var _amount = OrderUtils.ToRound(orderItem.Amount / orderObject.Amount * promotionItem.ReceivableAmount);
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if(i+1 == orderObject.Items.Count)
|
|
|
{
|
|
|
_amount = promotionItem.ReceivableAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += _amount;
|
|
|
}
|
|
|
|
|
|
//折扣率
|
|
|
discount.DiscountRate = OrderUtils.ToRound(_amount / orderItem.Amount);
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = orderItem.Amount - _amount;
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = _amount;
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
Replace(orderItem.Promotions , discount);
|
|
|
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.整单立减:
|
|
|
{
|
|
|
//整单立减需要分摊给单品
|
|
|
//单品分摊计算规则:单品的金额 / 整单金额小计 * 立减金额 = 单品分摊的金额;
|
|
|
//折后单价计算规则:单品分摊后单价 = 单品分摊的金额 / 单品数量
|
|
|
//单品折扣率 = 单品分摊金额 / 单品金额小计
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
decimal sum = 0;
|
|
|
var lists = orderObject.Items.OrderBy(x => x.OrderNo).ToList();
|
|
|
|
|
|
var validItems = GetValidPromItems(orderObject);
|
|
|
|
|
|
//有效商品金额
|
|
|
decimal validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
for (int i = 0; i < lists.Count; i++)
|
|
|
{
|
|
|
var orderItem = lists[i];
|
|
|
|
|
|
//服务端禁止单品折扣
|
|
|
if (orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许优惠";
|
|
|
continue;
|
|
|
}
|
|
|
//忽略套餐明细,套餐明细依赖套餐主分摊折扣
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//折扣类型
|
|
|
discount.PromotionType = PromotionType.整单立减;
|
|
|
//折扣方案
|
|
|
discount.PlanName = promotionItem.PlanName;
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
//分摊的金额
|
|
|
//var _amount = OrderUtils.ToRound( promotionItem.DiscountAmount / orderObject.Items.Where(f=>f.RowState != OrderRowState.套餐明).Count());
|
|
|
|
|
|
var _amount = OrderUtils.ToRound(orderItem.Amount / validAmount * promotionItem.DiscountAmount);
|
|
|
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if (i + 1 == orderObject.Items.Count)
|
|
|
{
|
|
|
_amount = promotionItem.DiscountAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += _amount;
|
|
|
}
|
|
|
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = _amount;
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = orderItem.Amount - _amount;
|
|
|
//折扣率
|
|
|
discount.DiscountRate = OrderUtils.ToRound(discount.ReceivableAmount / orderItem.Amount);
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.卡友日:
|
|
|
{
|
|
|
//整单立减需要分摊给单品
|
|
|
//单品分摊计算规则:单品的金额 / 整单金额小计 * 立减金额 = 单品分摊的金额;
|
|
|
//折后单价计算规则:单品分摊后单价 = 单品分摊的金额 / 单品数量
|
|
|
//单品折扣率 = 单品分摊金额 / 单品金额小计
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
decimal sum = 0;
|
|
|
var validItems = GetValidPromItems(orderObject);
|
|
|
//有效商品金额
|
|
|
decimal validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
for (int i = 0; i < validItems.Count; i++)
|
|
|
{
|
|
|
var orderItem = validItems[i];
|
|
|
|
|
|
//服务端禁止单品折扣
|
|
|
if (orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许优惠";
|
|
|
continue;
|
|
|
}
|
|
|
//忽略套餐明细,套餐明细依赖套餐主分摊折扣
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//折扣类型
|
|
|
discount.PromotionType = PromotionType.卡友日;
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
discount.PlanNo = promotionItem.PlanNo;
|
|
|
|
|
|
discount.PlanName = promotionItem.PlanName;
|
|
|
|
|
|
//分摊的金额
|
|
|
var _amount = OrderUtils.ToRound(orderItem.Amount / validAmount * promotionItem.DiscountAmount);
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if (i + 1 == orderObject.Items.Count)
|
|
|
{
|
|
|
_amount = promotionItem.DiscountAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += _amount;
|
|
|
}
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = _amount;
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = orderItem.Amount - _amount;
|
|
|
//折扣率
|
|
|
if(orderItem.Amount == 0)
|
|
|
{
|
|
|
discount.DiscountRate = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
discount.DiscountRate = OrderUtils.ToRound(discount.ReceivableAmount / orderItem.Amount);
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.实体优惠券:
|
|
|
{
|
|
|
//整单立减需要分摊给单品
|
|
|
//单品分摊计算规则:单品的金额 / 整单金额小计 * 立减金额 = 单品分摊的金额;
|
|
|
//折后单价计算规则:单品分摊后单价 = 单品分摊的金额 / 单品数量
|
|
|
//单品折扣率 = 单品分摊金额 / 单品金额小计
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
decimal sum = 0;
|
|
|
var validItems = GetValidPromItems(orderObject);
|
|
|
//有效商品金额
|
|
|
decimal validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
for (int i = 0; i < validItems.Count; i++)
|
|
|
{
|
|
|
var orderItem = validItems[i];
|
|
|
|
|
|
//服务端禁止单品折扣
|
|
|
if (orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许优惠";
|
|
|
continue;
|
|
|
}
|
|
|
//忽略套餐明细,套餐明细依赖套餐主分摊折扣
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//折扣类型
|
|
|
discount.PromotionType = PromotionType.实体优惠券;
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
discount.PlanNo = promotionItem.PlanNo;
|
|
|
|
|
|
discount.PlanName = promotionItem.PlanName;
|
|
|
|
|
|
//分摊的金额
|
|
|
var _amount = OrderUtils.ToRound(orderItem.Amount / validAmount * promotionItem.DiscountAmount);
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if (i + 1 == orderObject.Items.Count)
|
|
|
{
|
|
|
_amount = promotionItem.DiscountAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += _amount;
|
|
|
}
|
|
|
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = _amount;
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = orderItem.Amount - _amount;
|
|
|
//折扣率
|
|
|
if (orderItem.Amount == 0)
|
|
|
{
|
|
|
discount.DiscountRate = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
discount.DiscountRate = OrderUtils.ToRound(discount.ReceivableAmount / orderItem.Amount);
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
//优惠券信息
|
|
|
discount.Ext1 = promotionItem.Ext1;
|
|
|
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.免单:
|
|
|
{
|
|
|
//整单立减需要分摊给单品
|
|
|
//单品分摊计算规则:单品的金额 / 整单金额小计 * 立减金额 = 单品分摊的金额;
|
|
|
//折后单价计算规则:单品分摊后单价 = 单品分摊的金额 / 单品数量
|
|
|
//单品折扣率 = 单品分摊金额 / 单品金额小计
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
decimal sum = 0;
|
|
|
var validItems = GetValidPromItems(orderObject);
|
|
|
//有效商品金额
|
|
|
decimal validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
for (int i = 0; i < validItems.Count; i++)
|
|
|
{
|
|
|
var orderItem = validItems[i];
|
|
|
|
|
|
//服务端禁止单品折扣
|
|
|
if (orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许优惠";
|
|
|
continue;
|
|
|
}
|
|
|
//忽略套餐明细,套餐明细依赖套餐主分摊折扣
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//折扣类型
|
|
|
discount.PromotionType = PromotionType.免单;
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
discount.PlanNo = promotionItem.PlanNo;
|
|
|
|
|
|
discount.PlanName = promotionItem.PlanName;
|
|
|
|
|
|
//分摊的金额
|
|
|
var _amount = OrderUtils.ToRound(orderItem.Amount / validAmount * promotionItem.DiscountAmount);
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if (i + 1 == orderObject.Items.Count)
|
|
|
{
|
|
|
_amount = promotionItem.DiscountAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += _amount;
|
|
|
}
|
|
|
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = _amount;
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = orderItem.Amount - _amount;
|
|
|
//折扣率
|
|
|
if (orderItem.Amount == 0)
|
|
|
{
|
|
|
discount.DiscountRate = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
discount.DiscountRate = OrderUtils.ToRound(discount.ReceivableAmount / orderItem.Amount);
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
//做法是否参与折扣
|
|
|
if (!Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_ALLOW_MAKEDISCOUNT, false))
|
|
|
{
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (orderItem.RowState == OrderRowState.普通)
|
|
|
{
|
|
|
PromotionMake(orderItem, discount);
|
|
|
}
|
|
|
else if (orderItem.RowState == OrderRowState.套餐主)
|
|
|
{
|
|
|
PromotionMake(orderItem, discount);
|
|
|
List<OrderItem> orderItemDetailList = orderObject.Items.FindAll(x => x.RowState == OrderRowState.套餐明 && orderItem.Id.Equals(x.ParentId));
|
|
|
foreach (OrderItem orderItemDetail in orderItemDetailList)
|
|
|
{
|
|
|
discount.MainProductRate = orderItem.DiscountRate;
|
|
|
PromotionMake(orderItemDetail, discount);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.电子代金券:
|
|
|
case PromotionType.电子折扣券:
|
|
|
{
|
|
|
//整单立减需要分摊给单品
|
|
|
//单品分摊计算规则:单品的金额 / 整单金额小计 * 立减金额 = 单品分摊的金额;
|
|
|
//折后单价计算规则:单品分摊后单价 = 单品分摊的金额 / 单品数量
|
|
|
//单品折扣率 = 单品分摊金额 / 单品金额小计
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
decimal sum = 0;
|
|
|
var validItems = GetValidPromItems(orderObject);
|
|
|
//有效商品金额
|
|
|
decimal validAmount = validItems.Sum(x => x.Amount);
|
|
|
|
|
|
for (int i = 0; i < validItems.Count; i++)
|
|
|
{
|
|
|
var orderItem = validItems[i];
|
|
|
|
|
|
//服务端禁止单品折扣
|
|
|
if (orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许优惠";
|
|
|
continue;
|
|
|
}
|
|
|
//忽略套餐明细,套餐明细依赖套餐主分摊折扣
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//折扣类型
|
|
|
discount.PromotionType = promotionItem.PromotionType;
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
discount.PlanNo = promotionItem.PlanNo;
|
|
|
|
|
|
discount.PlanName = promotionItem.PlanName;
|
|
|
|
|
|
//兑换券ID
|
|
|
discount.CouponId = promotionItem.CouponId;
|
|
|
|
|
|
//分摊的金额
|
|
|
var _amount = OrderUtils.ToRound(orderItem.Amount / validAmount * promotionItem.DiscountAmount);
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if (i + 1 == orderObject.Items.Count)
|
|
|
{
|
|
|
_amount = promotionItem.DiscountAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += _amount;
|
|
|
}
|
|
|
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = _amount;
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = orderItem.Amount - _amount;
|
|
|
//折扣率
|
|
|
if (orderItem.Amount == 0)
|
|
|
{
|
|
|
discount.DiscountRate = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
discount.DiscountRate = OrderUtils.ToRound(discount.ReceivableAmount / orderItem.Amount);
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
if (promotionItem.PromotionType == PromotionType.电子折扣券)
|
|
|
{
|
|
|
//做法是否参与折扣
|
|
|
if (!Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_ALLOW_MAKEDISCOUNT, false))
|
|
|
{
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (orderItem.RowState == OrderRowState.套餐明)
|
|
|
{
|
|
|
OrderItem orderItemMain = orderObject.Items.Find(x => x.RowState == OrderRowState.套餐主 && x.Id.Equals(orderItem.ParentId));
|
|
|
discount.MainProductRate = orderItemMain.DiscountRate;
|
|
|
}
|
|
|
PromotionMake(orderItem, discount);
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
}
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
Replace(orderObject.Promotions , promotionItem);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 整单促销,参与集合,排除集合
|
|
|
/// </summary>
|
|
|
/// <param name="orderObject"></param>
|
|
|
/// <param name="promotionItem"></param>
|
|
|
/// <param name="joinList"></param>
|
|
|
/// <param name="outList"></param>
|
|
|
public static void Calculate(OrderObject orderObject, PromotionOrder promotionItem, List<string> joinList, List<string> outList)
|
|
|
{
|
|
|
switch (promotionItem.PromotionType)
|
|
|
{
|
|
|
case PromotionType.满减促销:
|
|
|
{
|
|
|
//整单满减需要分摊给单品
|
|
|
//单品分摊计算规则:单品的金额 / 整单金额小计 * 立减金额 = 单品分摊的金额;
|
|
|
//折后单价计算规则:单品分摊后单价 = 单品分摊的金额 / 单品数量
|
|
|
//单品折扣率 = 单品分摊金额 / 单品金额小计
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
|
|
|
List<OrderItem> joinItemList = GetValidPromItems(orderObject).OrderBy(x => x.OrderNo).ToList();
|
|
|
if (joinList != null && joinList.Count > 0)
|
|
|
{
|
|
|
//获取计算范围内的订单项
|
|
|
joinItemList = joinItemList.FindAll(x => joinList.Exists(y => y == x.SpecId));
|
|
|
}
|
|
|
|
|
|
if (outList != null && outList.Count > 0)
|
|
|
{
|
|
|
//排除不在计算范围内的订单项
|
|
|
joinItemList = joinItemList.FindAll(x => !outList.Exists(y => y == x.SpecId));
|
|
|
}
|
|
|
|
|
|
decimal totalJoinAmount = joinItemList.Sum(x => x.Amount);
|
|
|
decimal sum = 0;
|
|
|
for (int i = 0; i < joinItemList.Count; i++)
|
|
|
{
|
|
|
var orderItem = joinItemList[i];
|
|
|
|
|
|
//折扣优惠,相对固定值是输入的 折扣率
|
|
|
var discount = new PromotionItem();
|
|
|
//折扣标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//折扣类型
|
|
|
discount.PromotionType = PromotionType.满减促销;
|
|
|
//租户ID
|
|
|
discount.TenantId = orderItem.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = orderItem.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = orderItem.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = orderItem.Id;
|
|
|
|
|
|
//分摊数据对应整单优惠的行数据ID
|
|
|
discount.RelationId = promotionItem.Id;
|
|
|
|
|
|
discount.PlanNo = promotionItem.PlanNo;
|
|
|
discount.PlanName = promotionItem.PlanName;
|
|
|
|
|
|
//分摊的金额
|
|
|
var _amount = OrderUtils.ToRound(orderItem.Amount / totalJoinAmount * promotionItem.DiscountAmount);
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if (i + 1 == joinItemList.Count)
|
|
|
{
|
|
|
_amount = promotionItem.DiscountAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += _amount;
|
|
|
}
|
|
|
|
|
|
|
|
|
//优惠前金额
|
|
|
discount.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = _amount;
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = orderItem.Amount - _amount;
|
|
|
//折扣率
|
|
|
if(orderItem.Amount == 0)
|
|
|
{
|
|
|
discount.DiscountRate = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
discount.DiscountRate = OrderUtils.ToRound(discount.ReceivableAmount / orderItem.Amount);
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
discount.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToDiscountPrice(discount.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
Replace(orderItem.Promotions, discount);
|
|
|
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(orderObject, orderItem);
|
|
|
}
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
Replace(orderObject.Promotions, promotionItem);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 套餐分摊
|
|
|
/// </summary>
|
|
|
/// <param name="orderObject"></param>
|
|
|
/// <param name="orderItem"></param>
|
|
|
public static void CalculateSuitShare(OrderObject orderObject, OrderItem orderItem)
|
|
|
{
|
|
|
//判断是否是套餐主
|
|
|
if (orderItem.RowState == OrderRowState.套餐主)
|
|
|
{
|
|
|
//分摊道菜优惠
|
|
|
var _rows = orderObject.Items.FindAll(x => (x.Id == orderItem.Id || x.ParentId == orderItem.Id) && x.Group == orderItem.Group).OrderBy(x => x.OrderNo);
|
|
|
//分摊道菜优惠
|
|
|
PromotionUtils.CalculateSuitShare(orderObject,_rows.ToList());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 套餐分摊
|
|
|
/// </summary>
|
|
|
/// <param name="rows"></param>
|
|
|
public static void CalculateSuitShare(OrderObject orderObject, List<OrderItem> rows)
|
|
|
{
|
|
|
//套餐主菜售价
|
|
|
var _master = rows.Find(x => x.RowState == OrderRowState.套餐主);
|
|
|
|
|
|
//套餐明细列表
|
|
|
var _details = rows.FindAll(x => x.RowState == OrderRowState.套餐明).OrderByDescending(x => x.Amount).ToList();
|
|
|
|
|
|
if (_master == null || _details == null)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//套餐主的金额,不包含加价
|
|
|
var _masterAmount = _master.SalePrice * _master.Quantity * (1 - _master.DiscountRate);
|
|
|
|
|
|
//套菜金额合计 = Sum(道菜售价*道菜数量)
|
|
|
var _detailAmount = _details.Sum(x => x.Amount);
|
|
|
|
|
|
//已经分摊金额的合计,用于处理最后一个单品相减的问题
|
|
|
decimal sum = 0;
|
|
|
var lists = _details.OrderByDescending(x => x.Amount).ToList();
|
|
|
for (int i = 0; i < lists.Count; i++)
|
|
|
{
|
|
|
var item = lists[i];
|
|
|
|
|
|
//道菜优惠
|
|
|
var discount = new PromotionItem();
|
|
|
//标识
|
|
|
discount.Id = IdWorkerUtils.Instance.NextId();
|
|
|
//租户ID
|
|
|
discount.TenantId = item.TenantId;
|
|
|
//订单ID
|
|
|
discount.OrderId = item.OrderId;
|
|
|
//订单编号
|
|
|
discount.TradeNo = item.TradeNo;
|
|
|
//单品编号
|
|
|
discount.ItemId = item.Id;
|
|
|
//类型
|
|
|
discount.PromotionType = PromotionType.道菜分摊;
|
|
|
|
|
|
//道菜明细分摊的金额,相对应套餐主菜售价分摊,主菜的金额 / 道菜明细总金额 * 道菜金额 = 道菜分摊的金额 * 主菜折扣
|
|
|
var itemAmount = OrderUtils.ToRound((item.Amount / _detailAmount) * _masterAmount + item.SuitAmount * (1 - _master.DiscountRate));
|
|
|
|
|
|
//如果是最后一条记录,分摊金额采用减法
|
|
|
if (i + 1 == lists.Count)
|
|
|
{
|
|
|
itemAmount = _masterAmount - sum;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sum += itemAmount;
|
|
|
}
|
|
|
|
|
|
|
|
|
//优惠后金额
|
|
|
discount.ReceivableAmount = itemAmount;
|
|
|
//优惠金额
|
|
|
discount.DiscountAmount = item.Amount - itemAmount;
|
|
|
|
|
|
//是否启用
|
|
|
discount.Enabled = false;
|
|
|
|
|
|
//记录主菜的优惠率
|
|
|
discount.MainProductRate = _master.DiscountRate;
|
|
|
PromotionUtils.Calculate(orderObject,item, discount);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public static void Calculate(OrderObject orderObject, OrderItem orderItem , PromotionItem promotionItem)
|
|
|
{
|
|
|
switch (promotionItem.PromotionType)
|
|
|
{
|
|
|
case PromotionType.折扣:
|
|
|
{
|
|
|
//服务端禁止单品折扣
|
|
|
if (orderItem.DiscountFlag == 0)
|
|
|
{
|
|
|
orderItem.Action = "云端不允许折扣";
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
promotionItem.DiscountAmount = OrderUtils.ToRound(promotionItem.Amount * (1 - promotionItem.DiscountRate));
|
|
|
//优惠后金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "单品折扣操作";
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.议价:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
promotionItem.DiscountAmount = OrderUtils.ToRound(orderItem.Amount-(orderItem.Quantity * promotionItem.DiscountPrice));
|
|
|
//优惠后金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(orderItem.Quantity * promotionItem.DiscountPrice);
|
|
|
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = promotionItem.DiscountPrice;
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.赠送:
|
|
|
{
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "单品赠送操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.道菜分摊:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠率
|
|
|
if(promotionItem.Amount == 0)
|
|
|
{
|
|
|
promotionItem.DiscountRate = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
promotionItem.DiscountRate = OrderUtils.ToRound(promotionItem.DiscountAmount / promotionItem.Amount);
|
|
|
}
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "道菜分摊操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.会员价:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
promotionItem.DiscountAmount = OrderUtils.ToRound((orderItem.Price - orderItem.MemberPrice) * orderItem.Quantity);
|
|
|
//优惠后的金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "会员价优惠操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.商品优惠券:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.ReceivableAmount;
|
|
|
//优惠后的金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
//折扣率
|
|
|
promotionItem.DiscountRate = OrderUtils.ToRound(promotionItem.ReceivableAmount / promotionItem.Amount);
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "商品优惠券操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.会员等级优惠:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠金额
|
|
|
promotionItem.DiscountAmount = promotionItem.DiscountAmount;
|
|
|
//优惠后的金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "会员等级优惠操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.立减:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠后的金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
//折扣率
|
|
|
promotionItem.DiscountRate = OrderUtils.ToRound(promotionItem.ReceivableAmount / promotionItem.Amount);
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "立减优惠操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.卡友日:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠后的金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "会员日优惠操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.商品促销:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠后的金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "商品促销优惠操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.双数特价赠送:
|
|
|
case PromotionType.双数特价优惠:
|
|
|
{
|
|
|
//优惠前金额
|
|
|
promotionItem.Amount = orderItem.Amount;
|
|
|
//优惠后的金额
|
|
|
promotionItem.ReceivableAmount = OrderUtils.ToRound(promotionItem.Amount - promotionItem.DiscountAmount);
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "双数特价促销优惠操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.电子兑换券:
|
|
|
{
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "电子兑换券操作";
|
|
|
}
|
|
|
break;
|
|
|
case PromotionType.电子商品券:
|
|
|
{
|
|
|
//优惠生效
|
|
|
promotionItem.Enabled = true;
|
|
|
|
|
|
//折扣,影响折扣后的单价 = 折扣的总金额 / 购买的数量
|
|
|
orderItem.DiscountPrice = OrderUtils.ToRound(promotionItem.ReceivableAmount / orderItem.Quantity);
|
|
|
|
|
|
orderItem.Action = "电子商品券操作";
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
//做法是否参与折扣
|
|
|
if (!Global.Instance.GlobalConfigBoolValue(ConfigConstant.CASHIER_ALLOW_MAKEDISCOUNT, false)) {
|
|
|
Replace(orderItem.Promotions, promotionItem);
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
}
|
|
|
else {
|
|
|
switch (promotionItem.PromotionType)
|
|
|
{
|
|
|
case PromotionType.折扣:
|
|
|
case PromotionType.赠送:
|
|
|
{
|
|
|
if (orderItem.RowState == OrderRowState.普通)
|
|
|
{
|
|
|
PromotionMake(orderItem, promotionItem);
|
|
|
}
|
|
|
else if (orderItem.RowState == OrderRowState.套餐主)
|
|
|
{
|
|
|
PromotionMake(orderItem, promotionItem);
|
|
|
List<OrderItem> orderItemDetailList = orderObject.Items.FindAll(x => x.RowState == OrderRowState.套餐明 && orderItem.Id.Equals(x.ParentId));
|
|
|
foreach (OrderItem orderItemDetail in orderItemDetailList)
|
|
|
{
|
|
|
promotionItem.MainProductRate = orderItem.DiscountRate;
|
|
|
PromotionMake(orderItemDetail, promotionItem);
|
|
|
}
|
|
|
}
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
Replace(orderItem.Promotions, promotionItem);
|
|
|
UpdateSuitMain(orderObject, orderItem);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
public static bool Exists(List<PromotionItem> items , PromotionType type)
|
|
|
{
|
|
|
return items.Exists(x => x.PromotionType == type);
|
|
|
}
|
|
|
|
|
|
public static void Replace(List<PromotionItem> items , PromotionItem newItem)
|
|
|
{
|
|
|
//是否存在
|
|
|
var exists = Exists(items , newItem.PromotionType);
|
|
|
if (exists)
|
|
|
{
|
|
|
items.RemoveAll(x => x.PromotionType == newItem.PromotionType);
|
|
|
}
|
|
|
|
|
|
items.Add(newItem);
|
|
|
}
|
|
|
|
|
|
public static void ReplaceItems(List<PromotionItem> items, List<PromotionItem> newItems)
|
|
|
{
|
|
|
foreach (PromotionItem newItem in newItems) {
|
|
|
//是否存在
|
|
|
var exists = Exists(items, newItem.PromotionType);
|
|
|
if (exists)
|
|
|
{
|
|
|
items.RemoveAll(x => x.PromotionType == newItem.PromotionType);
|
|
|
}
|
|
|
items.Add(newItem);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static bool Exists(List<PromotionOrder> items , PromotionType type)
|
|
|
{
|
|
|
return items.Exists(x => x.PromotionType == type);
|
|
|
}
|
|
|
|
|
|
|
|
|
public static void Replace(List<PromotionOrder> items , PromotionOrder newItem)
|
|
|
{
|
|
|
//是否存在
|
|
|
var exists = Exists(items , newItem.PromotionType);
|
|
|
if (exists)
|
|
|
{
|
|
|
items.RemoveAll(x => x.PromotionType == newItem.PromotionType);
|
|
|
}
|
|
|
|
|
|
items.Add(newItem);
|
|
|
}
|
|
|
|
|
|
public static void Remove(OrderObject order, string promotionNo)
|
|
|
{
|
|
|
//是否存在
|
|
|
order.Promotions.RemoveAll(x => x.PlanNo == promotionNo);
|
|
|
//删除单品
|
|
|
foreach(var item in order.Items)
|
|
|
{
|
|
|
item.Promotions.RemoveAll(x => x.PlanNo == promotionNo);
|
|
|
//重新算折扣价
|
|
|
item.DiscountPrice = OrderUtils.ToRound((item.Amount - item.DiscountAmount) / item.Quantity);
|
|
|
UpdateSuitMain(order, item);
|
|
|
//套餐道菜分摊
|
|
|
CalculateSuitShare(order, item);
|
|
|
//套餐道菜分摊
|
|
|
//PromotionUtils.CalculateSuitShare(order,item );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|