Commit 382f26d5 by 陶然

新增性能分析

parent 4181e7df
...@@ -11,7 +11,7 @@ using System.Threading.Tasks; ...@@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace Kivii.Finances.Transforms namespace Kivii.Finances.Transforms
{ {
[Api(Description = "款登记")] [Api(Description = "款登记")]
[RequiresAnyRole(SystemRoles.Everyone)] [RequiresAnyRole(SystemRoles.Everyone)]
public class PayPaying : RestfulExecution<Pay> public class PayPaying : RestfulExecution<Pay>
{ {
...@@ -51,143 +51,282 @@ namespace Kivii.Finances.Transforms ...@@ -51,143 +51,282 @@ namespace Kivii.Finances.Transforms
if (PayingMethods.Count == 1)//单笔付款登记 if (PayingMethods.Count == 1)//单笔付款登记
{ {
var payingMethod = PayingMethods[0]; using (KiviiContext.Profiler("单个方式收款"))
if (payingMethod.Type == PayType.Payment)
{ {
var payment = conn.SingleById<Payment>(payingMethod.Kvid); var payingMethod = PayingMethods[0];
payment.ThrowIfNull("所选付款数据不存在!"); if (payingMethod.Type == PayType.Payment)
(payment.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
if (payment.Type != PaymentType.Split && payment.Type != PaymentType.Pos && payment.Type != PaymentType.Cash && payment.Type != PaymentType.AliPay && payment.Type != PaymentType.WeChat) throw new Exception("请选择正确的付款方式!");
var amount = amountSettlement - amountPayed;
if (payment.Amount - payment.AmountUsed < amount) amount = payment.Amount - payment.AmountUsed;
(payingMethod.Amount > 0 && payingMethod.Amount > payment.Amount - payment.AmountUsed).ThrowIfTrue($"所选付款方式余额不足,可用余额:{payment.Amount - payment.AmountUsed}");
if (payingMethod.Amount > 0 && payingMethod.Amount < amount) amount = payingMethod.Amount;//外部指定分摊多少钱就按照指定的费用进行分摊 否则就按照能使用的最大金额进行分摊
//if (payment.Amount - payment.AmountUsed < amountSettlement) throw new Exception($"所选付款方式余额不足,可用余额:{payment.Amount - payment.AmountUsed}");
//(payment.AmountInvoice != payment.Amount).ThrowIfTrue("所选到账尚未开票,请先开票后再分摊!");
var dynamicPayPayment = settlements.Paying(payment, accountBiz, out var pays, out var accountDetail, amount);
var trans = conn.OpenTransaction();
List<IDbTransaction> subTrans = new List<IDbTransaction>();
try
{ {
foreach (var item in pays) var payment = conn.SingleById<Payment>(payingMethod.Kvid);
payment.ThrowIfNull("所选付款数据不存在!");
(payment.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
if (payment.Type != PaymentType.Split && payment.Type != PaymentType.Pos && payment.Type != PaymentType.Cash && payment.Type != PaymentType.AliPay && payment.Type != PaymentType.WeChat) throw new Exception("请选择正确的付款方式!");
var amount = amountSettlement - amountPayed;
if (payment.Amount - payment.AmountUsed < amount) amount = payment.Amount - payment.AmountUsed;
(payingMethod.Amount > 0 && payingMethod.Amount > payment.Amount - payment.AmountUsed).ThrowIfTrue($"所选付款方式余额不足,可用余额:{payment.Amount - payment.AmountUsed}");
if (payingMethod.Amount > 0 && payingMethod.Amount < amount) amount = payingMethod.Amount;//外部指定分摊多少钱就按照指定的费用进行分摊 否则就按照能使用的最大金额进行分摊
//if (payment.Amount - payment.AmountUsed < amountSettlement) throw new Exception($"所选付款方式余额不足,可用余额:{payment.Amount - payment.AmountUsed}");
//(payment.AmountInvoice != payment.Amount).ThrowIfTrue("所选到账尚未开票,请先开票后再分摊!");
var dynamicPayPayment = settlements.Paying(payment, accountBiz, out var pays, out var accountDetail, amount);
var trans = conn.OpenTransaction();
List<IDbTransaction> subTrans = new List<IDbTransaction>();
try
{ {
conn.Insert(item); foreach (var item in pays)
rtns.Results.Add(item); {
conn.Insert(item);
rtns.Results.Add(item);
}
dynamicPayPayment.SerialNumber = payment.GetSubSerialNumber(conn);
conn.Insert(dynamicPayPayment);//创建DynamicSplitPayment
accountDetail.Insert(conn);
payment.RecalculateAmountUsed(conn);//重新统计到账的使用情况
#region 同步更新泛型Settlement表中数据
foreach (var item in settlements)
{
if (!item.OnlyProperties.IsNullOrEmpty()) conn.UpdateOnly(item);//更新了AmountPayment
}
var groupSettlement = settlements.GroupBy(o => o.BizType);
if (_realMethod == null)
{
var function = new Func<IDbConnection, List<Settlement>, object>(onExecution<Entity>);
_realMethod = this.GetType().GetMethod(function.Method.Name, BindingFlags.NonPublic | BindingFlags.Instance);
}
foreach (var group in groupSettlement)
{
var entityType = Text.AssemblyUtils.FindType(group.Key);
if (entityType == null) continue;
if (entityType == typeof(Settlement)) continue;
var result = _realMethod.MakeGenericMethod(entityType).Invoke(this, new object[2] { conn, group.ToList() });
if (result != null) subTrans.Add(result as IDbTransaction);
}
#endregion
trans.Commit();
subTrans.ForEach(o => o?.Commit());
} }
dynamicPayPayment.SerialNumber = payment.GetSubSerialNumber(conn); catch (Exception ex)
conn.Insert(dynamicPayPayment);//创建DynamicSplitPayment
accountDetail.Insert(conn);
payment.RecalculateAmountUsed(conn);//重新统计到账的使用情况
#region 同步更新泛型Settlement表中数据
foreach (var item in settlements)
{ {
if (!item.OnlyProperties.IsNullOrEmpty()) conn.UpdateOnly(item);//更新了AmountPayment trans.Rollback();
subTrans.ForEach(o => o?.Rollback());
throw ex;
} }
var groupSettlement = settlements.GroupBy(o => o.BizType); }
if (_realMethod == null) if (payingMethod.Type == PayType.Account)
{
var account = conn.SingleById<Account>(payingMethod.Kvid);
account.ThrowIfNull("未找到所选账户!");
(account.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
(account.Type != AccountType.Deposit).ThrowIfTrue("请选择正确的客户存款账户!");
var amount = amountSettlement - amountPayed;
if (account.Amount + account.CreditLine < amount) amount = account.Amount + account.CreditLine;
(payingMethod.Amount > 0 && payingMethod.Amount > account.Amount + account.CreditLine).ThrowIfTrue($"所选付款方式余额不足,可用余额:{account.Amount + account.CreditLine}");
if (payingMethod.Amount > 0 && payingMethod.Amount < amount) amount = payingMethod.Amount;//外部指定分摊多少钱就按照指定的费用进行分摊 否则就按照能使用的最大金额进行分摊
//(account.Amount + account.CreditLine < amountSettlement).ThrowIfTrue($"所选付款方式余额不足,可用余额:{account.Amount + account.CreditLine}");
var accountDetails = settlements.Paying(account, accountBiz, out var pays, amount);
var trans = conn.OpenTransaction();
List<IDbTransaction> subTrans = new List<IDbTransaction>();
try
{ {
var function = new Func<IDbConnection, List<Settlement>, object>(onExecution<Entity>); foreach (var item in pays)
_realMethod = this.GetType().GetMethod(function.Method.Name, BindingFlags.NonPublic | BindingFlags.Instance); {
conn.Insert(item);
rtns.Results.Add(item);
}
accountDetails.ForEach(o => o.Insert(conn));//创建账户明细
#region 同步更新泛型Settlement表中数据
foreach (var item in settlements)
{
if (!item.OnlyProperties.IsNullOrEmpty()) conn.UpdateOnly(item);//更新了Paykvid和AmountPayment
}
var groupSettlement = settlements.GroupBy(o => o.BizType);
if (_realMethod == null)
{
var function = new Func<IDbConnection, List<Settlement>, object>(onExecution<Entity>);
_realMethod = this.GetType().GetMethod(function.Method.Name, BindingFlags.NonPublic | BindingFlags.Instance);
}
foreach (var group in groupSettlement)
{
var entityType = Text.AssemblyUtils.FindType(group.Key);
if (entityType == null) continue;
if (entityType == typeof(Settlement)) continue;
var result = _realMethod.MakeGenericMethod(entityType).Invoke(this, new object[2] { conn, group.ToList() });
if (result != null) subTrans.Add(result as IDbTransaction);
}
#endregion
trans.Commit();
subTrans.ForEach(o => o?.Commit());
} }
foreach (var group in groupSettlement) catch (Exception ex)
{ {
var entityType = Text.AssemblyUtils.FindType(group.Key); trans.Rollback();
if (entityType == null) continue; subTrans.ForEach(o => o?.Rollback());
if (entityType == typeof(Settlement)) continue; throw ex;
var result = _realMethod.MakeGenericMethod(entityType).Invoke(this, new object[2] { conn, group.ToList() });
if (result != null) subTrans.Add(result as IDbTransaction);
} }
#endregion
trans.Commit();
subTrans.ForEach(o => o?.Commit());
} }
catch (Exception ex) if (payingMethod.Type == PayType.Discount)
{ {
trans.Rollback(); var discountAccount = conn.SingleById<Account>(payingMethod.Kvid);
subTrans.ForEach(o => o?.Rollback()); discountAccount.ThrowIfNull("未找到所选账户!");
throw ex; (discountAccount.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
(discountAccount.Type != AccountType.Discount).ThrowIfTrue("请选择正确的折扣账户!");
(discountAccount.OwnerKvid != KiviiContext.CurrentMember.DepartmentKvid).ThrowIfTrue("存在非本部门的折扣账户!");
var amount = amountSettlement - amountPayed;
if (payingMethod.Amount > 0 && payingMethod.Amount < amount) amount = payingMethod.Amount;//外部指定分摊多少钱就按照指定的费用进行分摊 否则就按照能使用的最大金额进行分摊
var accountDetails = settlements.Paying(discountAccount, accountBiz, out var pays, amount, payingMethod.Remark);
var trans = conn.OpenTransaction();
List<IDbTransaction> subTrans = new List<IDbTransaction>();
try
{
foreach (var item in pays)
{
conn.Insert(item);
rtns.Results.Add(item);
}
accountDetails.ForEach(o => o.Insert(conn));//创建账户明细
#region 同步更新泛型Settlement表中数据
foreach (var item in settlements)
{
if (!item.OnlyProperties.IsNullOrEmpty()) conn.UpdateOnly(item);//更新了Paykvid和AmountPayment
}
var groupSettlement = settlements.GroupBy(o => o.BizType);
if (_realMethod == null)
{
var function = new Func<IDbConnection, List<Settlement>, object>(onExecution<Entity>);
_realMethod = this.GetType().GetMethod(function.Method.Name, BindingFlags.NonPublic | BindingFlags.Instance);
}
foreach (var group in groupSettlement)
{
var entityType = Text.AssemblyUtils.FindType(group.Key);
if (entityType == null) continue;
if (entityType == typeof(Settlement)) continue;
var result = _realMethod.MakeGenericMethod(entityType).Invoke(this, new object[2] { conn, group.ToList() });
if (result != null) subTrans.Add(result as IDbTransaction);
}
#endregion
trans.Commit();
subTrans.ForEach(o => o?.Commit());
}
catch (Exception ex)
{
trans.Rollback();
subTrans.ForEach(o => o?.Rollback());
throw ex;
}
} }
} }
if (payingMethod.Type == PayType.Account) return rtns;
}
else//组合付款登记
{
using (KiviiContext.Profiler("组合方式收款"))
{ {
var account = conn.SingleById<Account>(payingMethod.Kvid); var paymentKvids = PayingMethods.Where(o => o.Type == PayType.Payment).ToList().ConvertAll(o => o.Kvid);
account.ThrowIfNull("未找到所选账户!"); var accountKvids = PayingMethods.Where(o => o.Type == PayType.Account).ToList().ConvertAll(o => o.Kvid);
(account.Currency != currency).ThrowIfTrue("存在不相符的货币单位!"); var discountKvids = PayingMethods.Where(o => o.Type == PayType.Discount).ToList().ConvertAll(o => o.Kvid);
(account.Type != AccountType.Deposit).ThrowIfTrue("请选择正确的客户存款账户!"); List<Payment> payments = null;
var amount = amountSettlement - amountPayed; if (!paymentKvids.IsNullOrEmpty())
if (account.Amount + account.CreditLine < amount) amount = account.Amount + account.CreditLine; {
(payingMethod.Amount > 0 && payingMethod.Amount > account.Amount + account.CreditLine).ThrowIfTrue($"所选付款方式余额不足,可用余额:{account.Amount + account.CreditLine}"); payments = conn.SelectByIds<Payment>(paymentKvids);
if (payingMethod.Amount > 0 && payingMethod.Amount < amount) amount = payingMethod.Amount;//外部指定分摊多少钱就按照指定的费用进行分摊 否则就按照能使用的最大金额进行分摊 payments.ThrowIfNullOrEmpty("未找到所选付款数据!");
//(account.Amount + account.CreditLine < amountSettlement).ThrowIfTrue($"所选付款方式余额不足,可用余额:{account.Amount + account.CreditLine}"); payments.Exists(o => o.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
var accountDetails = settlements.Paying(account, accountBiz, out var pays, amount); if (payments.Exists(o => o.Type != PaymentType.Split && o.Type != PaymentType.Pos && o.Type != PaymentType.Cash && o.Type != PaymentType.AliPay && o.Type != PaymentType.WeChat)) throw new Exception("请选择正确的付款方式!");
if (payments.Exists(o => (o.Amount - o.AmountUsed) <= 0)) throw new Exception($"所选付款方式余额不足!");
//if (payments.Exists(o => (o.AmountInvoice != o.Amount))) throw new Exception($"所选付款尚未开票!");
var trans = conn.OpenTransaction(); }
List<IDbTransaction> subTrans = new List<IDbTransaction>(); List<Account> accounts = null;
try if (!accountKvids.IsNullOrEmpty())
{ {
foreach (var item in pays) accounts = conn.SelectByIds<Account>(accountKvids);
{ accounts.ThrowIfNullOrEmpty("未找到所选账户!");
conn.Insert(item); accounts.Exists(o => o.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
rtns.Results.Add(item); if (accounts.Exists(o => o.Type != AccountType.Deposit)) throw new Exception("请选择正确的客户存款账户!");
} if (accounts.Exists(o => (o.Amount + o.CreditLine) <= 0)) throw new Exception($"所选付款方式余额不足!");
accountDetails.ForEach(o => o.Insert(conn));//创建账户明细
#region 同步更新泛型Settlement表中数据 }
foreach (var item in settlements) List<Account> discounts = null;
{ if (!discountKvids.IsNullOrEmpty())
if (!item.OnlyProperties.IsNullOrEmpty()) conn.UpdateOnly(item);//更新了Paykvid和AmountPayment {
} discounts = conn.SelectByIds<Account>(discountKvids);
var groupSettlement = settlements.GroupBy(o => o.BizType); discounts.ThrowIfNullOrEmpty("未找到所选账户!");
if (_realMethod == null) discounts.Exists(o => o.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
if (discounts.Exists(o => o.Type != AccountType.Discount)) throw new Exception("请选择正确的折扣账户!");
if (discounts.Exists(o => o.OwnerKvid != KiviiContext.CurrentMember.DepartmentKvid)) throw new Exception($"存在非本部门的折扣账户!");
}
var dynamicSplitPayments = new List<Payment>();
var allPays = new List<Pay>();
var allAccountDetails = new List<AccountDetail>();
//var allDiscounts = new List<Discount>();
if (!payments.IsNullOrEmpty())
{
foreach (var item in payments)
{ {
var function = new Func<IDbConnection, List<Settlement>, object>(onExecution<Entity>); var payingMethod = PayingMethods.FirstOrDefault(o => o.Kvid == item.Kvid);
_realMethod = this.GetType().GetMethod(function.Method.Name, BindingFlags.NonPublic | BindingFlags.Instance); if (payingMethod == null) continue;
(payingMethod.Amount <= 0).ThrowIfTrue("组合付款缺少当前方式指定金额!");
(payingMethod.Amount > item.Amount - item.AmountUsed).ThrowIfTrue($"所选付款方式余额不足,可用余额:{item.Amount - item.AmountUsed}");
var dynamicPayPayment = settlements.Paying(item, accountBiz, out var pays, out var accountDetail, payingMethod.Amount);
allPays.AddRange(pays);
dynamicSplitPayments.Add(dynamicPayPayment);
allAccountDetails.Add(accountDetail);
} }
foreach (var group in groupSettlement) }
if (!accounts.IsNullOrEmpty())
{
foreach (var item in accounts)
{ {
var entityType = Text.AssemblyUtils.FindType(group.Key); var payingMethod = PayingMethods.FirstOrDefault(o => o.Kvid == item.Kvid);
if (entityType == null) continue; if (payingMethod == null) continue;
if (entityType == typeof(Settlement)) continue; (payingMethod.Amount <= 0).ThrowIfTrue("组合付款缺少当前方式指定金额!");
var result = _realMethod.MakeGenericMethod(entityType).Invoke(this, new object[2] { conn, group.ToList() }); (payingMethod.Amount > item.Amount + item.CreditLine).ThrowIfTrue($"所选付款方式余额不足,可用余额:{item.Amount + item.CreditLine}");
if (result != null) subTrans.Add(result as IDbTransaction); var accountDetails = settlements.Paying(item, accountBiz, out var pays, payingMethod.Amount);
allPays.AddRange(pays);
allAccountDetails.AddRange(accountDetails);
} }
#endregion
trans.Commit();
subTrans.ForEach(o => o?.Commit());
} }
catch (Exception ex) if (!discounts.IsNullOrEmpty())
{ {
trans.Rollback(); foreach (var item in discounts)
subTrans.ForEach(o => o?.Rollback()); {
throw ex; var payingMethod = PayingMethods.FirstOrDefault(o => o.Kvid == item.Kvid);
if (payingMethod == null) continue;
(payingMethod.Amount <= 0).ThrowIfTrue("组合付款缺少当前方式指定金额!");
var accountDetails = settlements.Paying(item, accountBiz, out var pays, payingMethod.Amount);
allPays.AddRange(pays);
allAccountDetails.AddRange(accountDetails);
//allDiscounts.Add(discount);
}
} }
}
if (payingMethod.Type == PayType.Discount)
{
var discountAccount = conn.SingleById<Account>(payingMethod.Kvid);
discountAccount.ThrowIfNull("未找到所选账户!");
(discountAccount.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
(discountAccount.Type != AccountType.Discount).ThrowIfTrue("请选择正确的折扣账户!");
(discountAccount.OwnerKvid != KiviiContext.CurrentMember.DepartmentKvid).ThrowIfTrue("存在非本部门的折扣账户!");
var amount = amountSettlement - amountPayed;
if (payingMethod.Amount > 0 && payingMethod.Amount < amount) amount = payingMethod.Amount;//外部指定分摊多少钱就按照指定的费用进行分摊 否则就按照能使用的最大金额进行分摊
var accountDetails = settlements.Paying(discountAccount, accountBiz, out var pays, amount, payingMethod.Remark);
var trans = conn.OpenTransaction(); var trans = conn.OpenTransaction();
List<IDbTransaction> subTrans = new List<IDbTransaction>(); List<IDbTransaction> subTrans = new List<IDbTransaction>();
try try
{ {
foreach (var item in pays) foreach (var item in allPays)
{ {
conn.Insert(item); conn.Insert(item);
rtns.Results.Add(item); rtns.Results.Add(item);
} }
accountDetails.ForEach(o => o.Insert(conn));//创建账户明细 foreach (var item in dynamicSplitPayments)
{
item.SerialNumber = item.GetSubSerialNumber(conn);
conn.Insert(item);//创建DynamicSplitPayment
}
allAccountDetails.ForEach(o => o.Insert(conn));//创建账户明细
foreach (var item in payments)
{
item.RecalculateAmountUsed(conn);
}
#region 同步更新泛型Settlement表中数据 #region 同步更新泛型Settlement表中数据
foreach (var item in settlements) foreach (var item in settlements)
{ {
...@@ -221,140 +360,6 @@ namespace Kivii.Finances.Transforms ...@@ -221,140 +360,6 @@ namespace Kivii.Finances.Transforms
} }
return rtns; return rtns;
} }
else//组合付款登记
{
var paymentKvids = PayingMethods.Where(o => o.Type == PayType.Payment).ToList().ConvertAll(o => o.Kvid);
var accountKvids = PayingMethods.Where(o => o.Type == PayType.Account).ToList().ConvertAll(o => o.Kvid);
var discountKvids = PayingMethods.Where(o => o.Type == PayType.Discount).ToList().ConvertAll(o => o.Kvid);
List<Payment> payments = null;
if (!paymentKvids.IsNullOrEmpty())
{
payments = conn.SelectByIds<Payment>(paymentKvids);
payments.ThrowIfNullOrEmpty("未找到所选付款数据!");
payments.Exists(o => o.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
if (payments.Exists(o => o.Type != PaymentType.Split && o.Type != PaymentType.Pos && o.Type != PaymentType.Cash && o.Type != PaymentType.AliPay && o.Type != PaymentType.WeChat)) throw new Exception("请选择正确的付款方式!");
if (payments.Exists(o => (o.Amount - o.AmountUsed) <= 0)) throw new Exception($"所选付款方式余额不足!");
//if (payments.Exists(o => (o.AmountInvoice != o.Amount))) throw new Exception($"所选付款尚未开票!");
}
List<Account> accounts = null;
if (!accountKvids.IsNullOrEmpty())
{
accounts = conn.SelectByIds<Account>(accountKvids);
accounts.ThrowIfNullOrEmpty("未找到所选账户!");
accounts.Exists(o => o.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
if (accounts.Exists(o => o.Type != AccountType.Deposit)) throw new Exception("请选择正确的客户存款账户!");
if (accounts.Exists(o => (o.Amount + o.CreditLine) <= 0)) throw new Exception($"所选付款方式余额不足!");
}
List<Account> discounts = null;
if (!discountKvids.IsNullOrEmpty())
{
discounts = conn.SelectByIds<Account>(discountKvids);
discounts.ThrowIfNullOrEmpty("未找到所选账户!");
discounts.Exists(o => o.Currency != currency).ThrowIfTrue("存在不相符的货币单位!");
if (discounts.Exists(o => o.Type != AccountType.Discount)) throw new Exception("请选择正确的折扣账户!");
if (discounts.Exists(o => o.OwnerKvid != KiviiContext.CurrentMember.DepartmentKvid)) throw new Exception($"存在非本部门的折扣账户!");
}
var dynamicSplitPayments = new List<Payment>();
var allPays = new List<Pay>();
var allAccountDetails = new List<AccountDetail>();
//var allDiscounts = new List<Discount>();
if (!payments.IsNullOrEmpty())
{
foreach (var item in payments)
{
var payingMethod = PayingMethods.FirstOrDefault(o => o.Kvid == item.Kvid);
if (payingMethod == null) continue;
(payingMethod.Amount <= 0).ThrowIfTrue("组合付款缺少当前方式指定金额!");
(payingMethod.Amount > item.Amount - item.AmountUsed).ThrowIfTrue($"所选付款方式余额不足,可用余额:{item.Amount - item.AmountUsed}");
var dynamicPayPayment = settlements.Paying(item, accountBiz, out var pays, out var accountDetail, payingMethod.Amount);
allPays.AddRange(pays);
dynamicSplitPayments.Add(dynamicPayPayment);
allAccountDetails.Add(accountDetail);
}
}
if (!accounts.IsNullOrEmpty())
{
foreach (var item in accounts)
{
var payingMethod = PayingMethods.FirstOrDefault(o => o.Kvid == item.Kvid);
if (payingMethod == null) continue;
(payingMethod.Amount <= 0).ThrowIfTrue("组合付款缺少当前方式指定金额!");
(payingMethod.Amount > item.Amount + item.CreditLine).ThrowIfTrue($"所选付款方式余额不足,可用余额:{item.Amount + item.CreditLine}");
var accountDetails = settlements.Paying(item, accountBiz, out var pays, payingMethod.Amount);
allPays.AddRange(pays);
allAccountDetails.AddRange(accountDetails);
}
}
if (!discounts.IsNullOrEmpty())
{
foreach (var item in discounts)
{
var payingMethod = PayingMethods.FirstOrDefault(o => o.Kvid == item.Kvid);
if (payingMethod == null) continue;
(payingMethod.Amount <= 0).ThrowIfTrue("组合付款缺少当前方式指定金额!");
var accountDetails = settlements.Paying(item, accountBiz, out var pays, payingMethod.Amount);
allPays.AddRange(pays);
allAccountDetails.AddRange(accountDetails);
//allDiscounts.Add(discount);
}
}
var trans = conn.OpenTransaction();
List<IDbTransaction> subTrans = new List<IDbTransaction>();
try
{
foreach (var item in allPays)
{
conn.Insert(item);
rtns.Results.Add(item);
}
foreach (var item in dynamicSplitPayments)
{
item.SerialNumber = item.GetSubSerialNumber(conn);
conn.Insert(item);//创建DynamicSplitPayment
}
allAccountDetails.ForEach(o => o.Insert(conn));//创建账户明细
foreach (var item in payments)
{
item.RecalculateAmountUsed(conn);
}
#region 同步更新泛型Settlement表中数据
foreach (var item in settlements)
{
if (!item.OnlyProperties.IsNullOrEmpty()) conn.UpdateOnly(item);//更新了Paykvid和AmountPayment
}
var groupSettlement = settlements.GroupBy(o => o.BizType);
if (_realMethod == null)
{
var function = new Func<IDbConnection, List<Settlement>, object>(onExecution<Entity>);
_realMethod = this.GetType().GetMethod(function.Method.Name, BindingFlags.NonPublic | BindingFlags.Instance);
}
foreach (var group in groupSettlement)
{
var entityType = Text.AssemblyUtils.FindType(group.Key);
if (entityType == null) continue;
if (entityType == typeof(Settlement)) continue;
var result = _realMethod.MakeGenericMethod(entityType).Invoke(this, new object[2] { conn, group.ToList() });
if (result != null) subTrans.Add(result as IDbTransaction);
}
#endregion
trans.Commit();
subTrans.ForEach(o => o?.Commit());
}
catch (Exception ex)
{
trans.Rollback();
subTrans.ForEach(o => o?.Rollback());
throw ex;
}
return rtns;
}
} }
private IDbTransaction onExecution<T>(IDbConnection conn, List<Settlement> settlements) where T : IEntity private IDbTransaction onExecution<T>(IDbConnection conn, List<Settlement> settlements) where T : IEntity
......
...@@ -62,65 +62,67 @@ namespace Kivii.Finances.Transforms ...@@ -62,65 +62,67 @@ namespace Kivii.Finances.Transforms
try try
{ {
foreach (var item in Items) using (KiviiContext.Profiler("创建结算"))
{ {
if (item.Amount != item.Details.Sum(o => o.Amount) || item.AmountPlan != item.Details.Sum(o => o.AmountPlan)) throw new Exception("项目明细总费用和结算主体总费用不一致!"); foreach (var item in Items)
var settlementKvid = Guid.NewGuid();
#region 生成财务 Settlement 主结算
var settlement = new Settlement();
settlement.PopulateWith(item);
settlement.Kvid = settlementKvid;
settlement.OwnerKvid = KiviiContext.CurrentMember.DepartmentKvid;
settlement.OwnerName = KiviiContext.CurrentMember.DepartmentName;
settlement.BizId = item.BizId;
settlement.BizKvid = item.BizKvid;
settlement.BizType = typeof(G).FullName;
settlement.OperateTime = item.OperateTime == DateTime.MinValue ? DateTime.Now : item.OperateTime;
settlement.OperatorName = KiviiContext.CurrentMember.FullName;
settlement.OperatorKvid = KiviiContext.CurrentMember.Kvid;
connF.Insert(settlement);
settlement.RemoveAllOnlyProperties();
rtns.Results.Add(settlement);
if (typeof(G) != typeof(Settlement))
{ {
var entitySettlement = new EntitySettlement<G>(); if (item.Amount != item.Details.Sum(o => o.Amount) || item.AmountPlan != item.Details.Sum(o => o.AmountPlan)) throw new Exception("项目明细总费用和结算主体总费用不一致!");
entitySettlement.PopulateInstance(settlement); var settlementKvid = Guid.NewGuid();
connE.Insert(entitySettlement); #region 生成财务 Settlement 主结算
} var settlement = new Settlement();
#endregion settlement.PopulateWith(item);
settlement.Kvid = settlementKvid;
settlement.OwnerKvid = KiviiContext.CurrentMember.DepartmentKvid;
settlement.OwnerName = KiviiContext.CurrentMember.DepartmentName;
settlement.BizId = item.BizId;
settlement.BizKvid = item.BizKvid;
settlement.BizType = typeof(G).FullName;
settlement.OperateTime = item.OperateTime == DateTime.MinValue ? DateTime.Now : item.OperateTime;
settlement.OperatorName = KiviiContext.CurrentMember.FullName;
settlement.OperatorKvid = KiviiContext.CurrentMember.Kvid;
connF.Insert(settlement);
settlement.RemoveAllOnlyProperties();
rtns.Results.Add(settlement);
if (typeof(G) != typeof(Settlement))
{
var entitySettlement = new EntitySettlement<G>();
entitySettlement.PopulateInstance(settlement);
connE.Insert(entitySettlement);
}
#endregion
#region 回写更新G数据 #region 回写更新G数据
var instance = Activator.CreateInstance(typeof(G)) as IEntityHasSettlement; var instance = Activator.CreateInstance(typeof(G)) as IEntityHasSettlement;
if (instance != null) if (instance != null)
{ {
instance.Kvid = item.BizKvid; instance.Kvid = item.BizKvid;
instance.AmountSettlement = settlement.Amount; instance.AmountSettlement = settlement.Amount;
instance.AddOnlyProperties(o => o.AmountSettlement); instance.AddOnlyProperties(o => o.AmountSettlement);
connE.UpdateOnly(instance); connE.UpdateOnly(instance);
} }
#endregion #endregion
#region 生成泛型SettlementDetail #region 生成泛型SettlementDetail
foreach (var detail in item.Details) foreach (var detail in item.Details)
{ {
detail.SettlementKvid = settlementKvid; detail.SettlementKvid = settlementKvid;
detail.Quantity = detail.Quantity <= 0 ? 1 : detail.Quantity; detail.Quantity = detail.Quantity <= 0 ? 1 : detail.Quantity;
detail.QuantityUnit = detail.QuantityUnit.IsNullOrEmpty() ? "次" : detail.QuantityUnit; detail.QuantityUnit = detail.QuantityUnit.IsNullOrEmpty() ? "次" : detail.QuantityUnit;
detail.QuantityUnitPrice = detail.Amount / detail.Quantity; detail.QuantityUnitPrice = detail.Amount / detail.Quantity;
detail.Currency = item.Currency; detail.Currency = item.Currency;
detail.OperateTime = DateTime.Now; detail.OperateTime = DateTime.Now;
detail.OperatorKvid = KiviiContext.CurrentMember.Kvid; detail.OperatorKvid = KiviiContext.CurrentMember.Kvid;
detail.OperatorName = KiviiContext.CurrentMember.FullName; detail.OperatorName = KiviiContext.CurrentMember.FullName;
var entityDetail = new EntitySettlementDetail<G>(); var entityDetail = new EntitySettlementDetail<G>();
entityDetail.PopulateInstance(detail); entityDetail.PopulateInstance(detail);
connE.Insert(entityDetail); connE.Insert(entityDetail);
}
#endregion
} }
#endregion
} }
tranE?.Commit(); tranE?.Commit();
tranF?.Commit(); tranF?.Commit();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment