Commit c56bed1e by 陶然

init

parent 71e4d546
......@@ -106,24 +106,14 @@ namespace Kivii.Finances.Entities
/// </summary>
Unsupported = 0,
/// <summary>
///银行账户,可清零或调帐,不用于客户,只用于组织内
/// </summary>
Bank,
/// <summary>
///现金账户,用于收到的现金,只用于组织内,个人业务员使用,不用于客户,如业务员收取现金
/// </summary>
Cash,
/// <summary>
///刷卡账户,用于收到的刷卡,只用于组织内,个人业务员使用
/// </summary>
Pos,
///// <summary>
/////银行账户,可清零或调帐,不用于客户,只用于组织内
///// </summary>
//Bank,
AliPay,
//AliPay,
WeChat,
//WeChat,
/// <summary>
///存款账户,指客户的存款账户,同部门只能拥有一个, 多部门可存在多个账户
......@@ -151,6 +141,16 @@ namespace Kivii.Finances.Entities
Balance,
/// <summary>
///现金账户,用于收到的现金,只用于组织内,个人业务员使用,不用于客户,如业务员收取现金
/// </summary>
Cash,
/// <summary>
///刷卡账户,用于收到的刷卡,只用于组织内,个人业务员使用
/// </summary>
Pos,
/// <summary>
/// 折扣账户,各部门仅有一个,也可所属到个人
/// </summary>
Discount,
......
......@@ -105,6 +105,9 @@ namespace Kivii.Finances.Entities
[IgnoreUpdate]
[StringLength(100), Default("")]
public string SerialNumber { get; set; }
[Ignore]
public List<Settlement> Details { get; set; }
#endregion
#region 金额相关
......@@ -183,11 +186,4 @@ namespace Kivii.Finances.Entities
public string UpdaterName { get; set; }
#endregion
}
public class BillWithSettlements:Bill
{
[Ignore]
public List<Settlement> Settlements { get; set; }
}
}
......@@ -155,10 +155,10 @@ namespace Kivii.Finances.Entities
[DecimalLength(15, 2), Default(0)]
public decimal AmountInvoice { get; set; }
[ApiMember(Description = "已关联金额,关联的收款或者刷卡现金账户金额")]
[InternalSetter]
[DecimalLength(15, 2), Default(0)]
public decimal AmountUsed { get; set; }
//[ApiMember(Description = "已关联金额,关联的收款或者刷卡现金账户金额")]
//[InternalSetter]
//[DecimalLength(15, 2), Default(0)]
//public decimal AmountUsed { get; set; }
[ApiMember(Description = "单位")]
[IgnoreUpdate]
......
......@@ -7,7 +7,12 @@ using System.Threading.Tasks;
namespace Kivii.Finances.Entities
{
[Api(Description = "付款单")]
/// <summary>
/// Pay对象是 Payment与Account之间互相转变的动作
/// 或者Account与Account之间转账
/// 此动作可附带Biz相关内容,比如Settlement
/// </summary>
[Api(Description = "支付")]
[Alias(Configs.TableNamePay)]
public class Pay : EntityWithMetadata, IEntityInAssemblyDb, IEntityHasBiz,
IEntityHasOffset, IEntityHasSummary,
......@@ -39,7 +44,6 @@ namespace Kivii.Finances.Entities
[InternalSetter]
[StringLength(100)]
public string BizType { get; set; }
#endregion
#region 收付双方
......@@ -52,6 +56,14 @@ namespace Kivii.Finances.Entities
[StringLength(100), Required]
public string PayerName { get; set; }
[ApiMember(Description = "付方来源")]
[StringLength(50), Required]
public PayType FromType { get; set; }
[ApiMember(Description = "付方来源Kvid")]
[IgnoreUpdate]
[Required]
public Guid FromKvid { get; set; }
[IgnoreUpdate]
[DefaultEmptyGuid]
......@@ -61,6 +73,15 @@ namespace Kivii.Finances.Entities
[IgnoreUpdate]
[StringLength(100), Required]
public string PayeeName { get; set; }
[ApiMember(Description = "收方来源")]
[StringLength(50), Required]
public PayType ToType { get; set; }
[ApiMember(Description = "收方来源Kvid")]
[IgnoreUpdate]
[Required]
public Guid ToKvid { get; set; }
#endregion
#region 基本信息
......@@ -69,41 +90,32 @@ namespace Kivii.Finances.Entities
[StringLength(100), Default("")]
public string SerialNumber { get; set; }
[ApiMember(Description = "消费类型")]
[ApiMember(Description = "支付类型")]
[StringLength(50), Default("")]
public string Type { get; set; }
//[ApiMember(Description = "付款Kvid")]
//[InternalSetter]
//[DefaultEmptyGuid]
//public Guid PaymentKvid { get; set; }
[ApiMember(Description = "支付日期")]
[InternalSetter]
public DateTime? PayedTime { get; set; }
#endregion
#region 费用相关
/// <summary>
/// 结算金额,结算明细统计
/// </summary>
[ApiMember(Description = "结算金额,结算明细统计")]
[InternalSetter]
[DecimalLength(15, 2), Default(0)]
public decimal AmountSettlement { get; set; }
//[ApiMember(Description = "结算金额,结算明细统计")]
//[InternalSetter]
//[DecimalLength(15, 2), Default(0)]
//public decimal AmountSettlement { get; set; }
[ApiMember(Description = "实付金额,客户实际支付的金额")]
[ApiMember(Description = "发生金额")]
[InternalSetter]
[DecimalLength(15, 2), Default(0)]
public decimal Amount { get; set; }
[ApiMember(Description = "折扣金额,客户实际支付的金额少于结算金额时补齐的金额")]
[ApiMember(Description = "折扣金额,发生金额-实付金额")]
[InternalSetter]
[DecimalLength(15, 2), Default(0)]
public decimal AmountDiscount { get; set; }
[ApiMember(Description = "已付金额,实付金额和折扣金额的和")]
[ApiMember(Description = "实付金额")]
[InternalSetter]
[DecimalLength(15, 2), Default(0)]
public decimal AmountPayment { get; set; }
......
......@@ -63,7 +63,7 @@ namespace Kivii.Finances.Entities
#region 收付双方 Payer付款单位,贷方 Payee收款单位,借方,账号相关
[IgnoreUpdate]
[DefaultEmptyGuid, Required]
[DefaultEmptyGuid]
public Guid PayerKvid { get; set; }
[ApiMember(Description = "付款单位,贷方")]
......@@ -91,7 +91,7 @@ namespace Kivii.Finances.Entities
public string PayerAccountSerialNumber { get; set; }
[IgnoreUpdate]
[DefaultEmptyGuid, Required]
[DefaultEmptyGuid]
public Guid PayeeKvid { get; set; }
[ApiMember(Description = "收款单位,借方")]
......@@ -261,19 +261,14 @@ namespace Kivii.Finances.Entities
WeChat,
/// <summary>
/// 动态拆分,必有Biz,即为用于关联支付Pay业务,子集Pay用于结算,当有Pay冲销则此状态Amount AmountUsed AmountSplited都发生变化
/// </summary>
DynamicSplit,
/// <summary>
/// 刷卡,直接从刷卡内部账户拨款到Payment的类型(区别于Account类型[消费使用],开票申请使用)
/// </summary>
Pos,
/// <summary>
/// 支付,此类型必有Biz,即为动态拆分的子集用于关联具体Settlement业务
/// 动态支付,当收款登记时被用于关联Pay
/// </summary>
Pay,
DynamicPay,
/// <summary>
/// 转账,必有Biz
......
......@@ -95,10 +95,10 @@ namespace Kivii.Finances.Entities
[DecimalLength(15, 2), Default(0)]
public decimal AmountPayment { get; set; }
[ApiMember(Description = "支付Kvid")]
[InternalSetter]
[DefaultEmptyGuid]
public Guid PayKvid { get; set; }
//[ApiMember(Description = "支付Kvid")]
//[InternalSetter]
//[DefaultEmptyGuid]
//public Guid PayKvid { get; set; }
[ApiMember(Description = "单位")]
[IgnoreUpdate]
......
......@@ -23,7 +23,8 @@ namespace Kivii.Finances
public static Account GetBalanceAccount(this CurrencyUnit currency)
{
(currency == CurrencyUnit.Unsupported).ThrowIfTrue("不支持的货币单位,不能查询平衡账户");
var key = KiviiContext.GetUrnKey(currency.ToString());
var key = KiviiContext.GetUrnKey($"{currency}{KiviiContext.CurrentMember.OrganizationKvid}");
//var key = KiviiContext.GetUrnKey(currency.ToString());
//如果包含这个币种,直接返回
if (_balanceAccounts.ContainsKey(key))
{
......@@ -36,7 +37,7 @@ namespace Kivii.Finances
var balanceAccounts = conn.Select<Account>(o => o.Type == AccountType.Balance);
foreach (var account in balanceAccounts)
{
_balanceAccounts[KiviiContext.GetUrnKey(account.Currency.ToString())] = account;
_balanceAccounts[KiviiContext.GetUrnKey($"{currency}{KiviiContext.CurrentMember.OrganizationKvid}")] = account;
}
//如果从数据库中得到了,直接返回
if (_balanceAccounts.ContainsKey(key))
......@@ -44,15 +45,15 @@ namespace Kivii.Finances
return _balanceAccounts[key];
}
//每个币种只有一个平衡帐户,通过自定义的Kvid防止多系统或多线程冲突引起在数据库中创建多个平衡帐户,Kvid的开头为BALANCE的象形写法
var currencyString = ((int)currency).ToString().PadLeft(4, '0');
var balanceKvid = new Guid($"BA1A0CE0-{currencyString}-0000-0000-000000000000");
////每个币种只有一个平衡帐户,通过自定义的Kvid防止多系统或多线程冲突引起在数据库中创建多个平衡帐户,Kvid的开头为BALANCE的象形写法
//var currencyString = ((int)currency).ToString().PadLeft(4, '0');
var balanceKvid = Guid.NewGuid();//new Guid($"BA1A0CE0-{currencyString}-0000-0000-000000000000");
Account rtns = new Account();
rtns.Kvid = balanceKvid;
rtns.Type = AccountType.Balance;
rtns.Currency = currency;
rtns.OwnerKvid = Guid.Empty;
rtns.OwnerName = "K5平台";
rtns.OwnerKvid = KiviiContext.CurrentMember.OrganizationKvid;
rtns.OwnerName = KiviiContext.CurrentMember.OrganizationName;
rtns.Name = "系统平衡帐户";
rtns.SerialNumber = "";
rtns.CreditLine = 0;
......@@ -61,7 +62,7 @@ namespace Kivii.Finances
rtns.Remark = "";
if (conn.Insert(rtns) == 1)
{
_balanceAccounts[KiviiContext.GetUrnKey(rtns.Currency.ToString())] = rtns;
_balanceAccounts[KiviiContext.GetUrnKey($"{rtns.Currency}{KiviiContext.CurrentMember.OrganizationKvid}")] = rtns;
return rtns;
}
throw new Exception("系统创建平衡帐户失败,请联系系统管理员。");
......@@ -105,7 +106,7 @@ namespace Kivii.Finances
rtns.OwnerName = KiviiContext.CurrentMember.DepartmentName;
rtns.Name = $"折扣帐户({rtns.OwnerName})";
rtns.SerialNumber = "";
rtns.CreditLine = 0;
rtns.CreditLine = 10000000000;
rtns.Amount = 0;
rtns.Summary = "";
rtns.Remark = "";
......@@ -215,6 +216,7 @@ namespace Kivii.Finances
}
/// <summary>
/// complate!
/// 新增账户明细
/// </summary>
/// <param name="accountDetail"></param>
......@@ -226,8 +228,8 @@ namespace Kivii.Finances
(accountDetail.Amount == 0).ThrowIfFalse("账户余额不能被赋除0之外的值!");
(accountDetail.AmountPayment <= 0).ThrowIfTrue("账户明细发生金额不能少于0!");
accountDetail.AccountKvid.ThrowIfEmpty("账户Kvid不能为空!");
accountDetail.PayeeAccountKvid.ThrowIfEmpty("收款账户不能为空!");
accountDetail.PayerAccountKvid.ThrowIfEmpty("付款账户不能为空!");
//accountDetail.PayeeAccountKvid.ThrowIfEmpty("收款账户不能为空!");
//accountDetail.PayerAccountKvid.ThrowIfEmpty("付款账户不能为空!");
bool useTransaction = conn == null;//是否启用事务,如果外部未传入conn,启用内部事务
if (conn == null) conn = KiviiContext.GetOpenedDbConnection<AccountDetail>();
......
using Kivii.Finances.Entities;
using Kivii.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
......
......@@ -49,14 +49,16 @@ namespace Kivii.Finances
if (payment.AmountInvoice >= payment.Amount) continue;
foreach (var invoice in invoices)
{
var amountLeave = payment.Amount - payment.AmountInvoice;//可以开票的金额
if (amountLeave <= 0) break;
var amountCorrelating = invoice.Amount - invoice.AmountPayment;//要关联的金额
if (amountCorrelating <= 0) continue;
var amountLeave = payment.Amount - payment.AmountInvoice;//可以开票的金额
if (amountLeave <= 0) continue;
var amount = amountLeave <= amountCorrelating ? amountLeave : amountCorrelating;
invoice.PayedTime = payedTime;
invoice.AddOnlyProperties(o => o.PayedTime);
invoice.AmountPayment += amount;
invoice.AddOnlyProperties(o => o.AmountPayment);
#region 建立关联关系
var relationInvoice = new Invoice();
......
using Kivii.Finances.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Kivii.Finances
{
public static class InvoiceExtension
{
public static Invoice Offset(this Invoice invoice, string remark)
{
invoice.ThrowIfNull("发票不能为空!");
(invoice.Currency == CurrencyUnit.Unsupported).ThrowIfTrue("不支持的货币单位");
(invoice.OffsetKvid != Guid.Empty).ThrowIfTrue("发票已作废,无需重复操作!");
#region invoice冲账
var newInvoiceKvid = Guid.NewGuid();
invoice.OffsetKvid = newInvoiceKvid;
invoice.AddOnlyProperties(o => o.OffsetKvid);
invoice.Remark = $"{remark}";
invoice.AddOnlyProperties(o => o.Remark);
//新建一个和原来一样的
var offsetInvoice = new Invoice();
offsetInvoice.PopulateWith(invoice);
offsetInvoice.OffsetKvid = invoice.Kvid;//新的冲帐关联用原来的Kvid
offsetInvoice.BizId = string.Empty;
offsetInvoice.BizKvid = Guid.Empty;
offsetInvoice.BizType = string.Empty;
offsetInvoice.Kvid = newInvoiceKvid;
offsetInvoice.RootKvid = newInvoiceKvid;
offsetInvoice.ParentKvid = Guid.Empty;
offsetInvoice.SerialNumber = invoice.SerialNumber.IsNullOrEmpty() ? "" : ("-" + invoice.SerialNumber);
offsetInvoice.Remark = $"{remark}";
offsetInvoice.Amount = 0 - offsetInvoice.Amount;//反向值
offsetInvoice.AmountPayment = 0 - offsetInvoice.AmountPayment;
offsetInvoice.OperateTime = DateTime.Now;
#endregion
return offsetInvoice;
}
}
}
using Kivii.Finances.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Kivii.Finances
{
public static class SettlementExtension
{
public static Settlement Offset (this Settlement settlement,string remark)
{
settlement.ThrowIfNull("付款记录不能为空!");
(settlement.OffsetKvid != Guid.Empty).ThrowIfTrue("收项已冲账");
(settlement.Currency == CurrencyUnit.Unsupported).ThrowIfTrue("不支持的货币单位");
#region pay冲账
var newSettlementKvid = Guid.NewGuid();
settlement.OffsetKvid = newSettlementKvid;
settlement.AddOnlyProperties(o => o.OffsetKvid);
settlement.Remark = $"{remark}";
settlement.AddOnlyProperties(o => o.Remark);
//新建一个和原来一样的
var offsetSettlement = new Settlement();
offsetSettlement.PopulateWith(settlement);
offsetSettlement.OffsetKvid = settlement.Kvid;//新的冲帐关联用原来的Kvid
offsetSettlement.Kvid = newSettlementKvid;
offsetSettlement.SerialNumber = settlement.SerialNumber.IsNullOrEmpty() ? "" : ("-" + settlement.SerialNumber);
offsetSettlement.Remark = $"{remark}";
offsetSettlement.AmountPlan = 0 - offsetSettlement.AmountPlan;
offsetSettlement.AmountPayment = 0 - offsetSettlement.AmountPayment;
offsetSettlement.Amount = 0 - offsetSettlement.Amount;//反向值
#endregion
return offsetSettlement;
}
}
}
......@@ -72,12 +72,15 @@
<Compile Include="Extensions\AccountExtension.cs" />
<Compile Include="Extensions\BillExtension.cs" />
<Compile Include="Extensions\InvoiceApplyExtension.cs" />
<Compile Include="Extensions\InvoiceExtension.cs" />
<Compile Include="Extensions\PayExtension.cs" />
<Compile Include="Extensions\PaymentExtension.cs" />
<Compile Include="Extensions\SettlementExtension.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Transforms\RestfulAccount.cs" />
<Compile Include="Transforms\RestfulAccountDetail.cs" />
<Compile Include="Transforms\RestfulBill.cs" />
<Compile Include="Transforms\RestfulInvoice.cs" />
<Compile Include="Transforms\RestfulInvoice.Debit.cs" />
<Compile Include="Transforms\RestfulInvoice.Offset.Deficit.cs" />
<Compile Include="Transforms\RestfulInvoiceApply.Apply.cs" />
......@@ -91,6 +94,7 @@
<Compile Include="Transforms\RestfulPayment.Split.cs" />
<Compile Include="Transforms\RestfulPayment.UnBiz.Refund.cs" />
<Compile Include="Transforms\RestfulSettlement.cs" />
<Compile Include="Transforms\RestfulSettlement.Offset.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
......
......@@ -23,9 +23,9 @@ namespace Kivii.Finances.Transforms
if (Item.Amount != 0) throw new Exception("开户时,户内金额只能为零!");
if (Item.Type == AccountType.Deposit && dbConnection.Exists<Account>(o => o.Name == Item.Name && o.OwnerKvid == Item.OwnerKvid && o.Type == AccountType.Deposit && o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid)) throw new Exception("当前组织已存在此客户的存款账户");
if (Item.Type == AccountType.WeChat && dbConnection.Exists<Account>(o => o.OwnerKvid == Item.OwnerKvid && o.Type == AccountType.WeChat && o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid)) throw new Exception("当前组织已存在微信账户!");
if (Item.Type == AccountType.AliPay && dbConnection.Exists<Account>(o => o.OwnerKvid == Item.OwnerKvid && o.Type == AccountType.AliPay && o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid)) throw new Exception("当前组织已存在支付宝账户!");
if (Item.Type == AccountType.Bank && dbConnection.Exists<Account>(o => o.OwnerKvid == Item.OwnerKvid && o.Type == AccountType.Bank && o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid)) throw new Exception("当前组织已存在银行账户!");
//if (Item.Type == AccountType.WeChat && dbConnection.Exists<Account>(o => o.OwnerKvid == Item.OwnerKvid && o.Type == AccountType.WeChat && o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid)) throw new Exception("当前组织已存在微信账户!");
//if (Item.Type == AccountType.AliPay && dbConnection.Exists<Account>(o => o.OwnerKvid == Item.OwnerKvid && o.Type == AccountType.AliPay && o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid)) throw new Exception("当前组织已存在支付宝账户!");
//if (Item.Type == AccountType.Bank && dbConnection.Exists<Account>(o => o.OwnerKvid == Item.OwnerKvid && o.Type == AccountType.Bank && o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid)) throw new Exception("当前组织已存在银行账户!");
_trans = dbConnection.OpenTransaction();
return base.OnPreRestfulCreate(req, res, dbConnection, rtns);
......@@ -66,7 +66,7 @@ namespace Kivii.Finances.Transforms
[Api(Description = "账户查询")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class AccountQuery : RestfulExecution<Account>
public class AccountQueryEx : RestfulExecution<Account>
{
#region QueryArgs
public virtual int? Skip { get; set; }
......@@ -103,7 +103,7 @@ namespace Kivii.Finances.Transforms
}
[RequiresAnyRole(SystemRoles.Everyone)]
public class AccountQueryEx : RestfulQuery<Account>
public class AccountQuery : RestfulQuery<Account>
{
}
......@@ -135,4 +135,21 @@ namespace Kivii.Finances.Transforms
return rtns;
}
}
[Api(Description = "获取平衡账户")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class AccountGetBalance : RestfulExecution<Account>
{
public CurrencyUnit Currency { get; set; }
public override object OnExecution(IRequest req, IResponse res)
{
(Currency == CurrencyUnit.Unsupported).ThrowIfTrue("不支持的货币单位!");
var rtns = new RestfulReadResponse<Account>();
rtns.Result = Currency.GetBalanceAccount();
return rtns;
}
}
}
......@@ -89,23 +89,33 @@ namespace Kivii.Finances.Transforms
[RequiresAnyRole(SystemRoles.Everyone)]
public class BillRead : RestfulRead<Bill>
{
public bool IncludeDetail { get; set; }
public override bool OnPostRestfulRead(IRequest req, IResponse res, IDbConnection dbConnection, IRestfulReadResponse<Bill> rtns)
{
if (!IncludeDetail) return base.OnPostRestfulRead(req, res, dbConnection, rtns);
var queryDetails = dbConnection.From<BillDetail>();
queryDetails.Where(o => o.BillKvid == rtns.Result.Kvid);
queryDetails.Select(o => o.BizKvid);
rtns.Result.Details = dbConnection.Select<Settlement>(o => Sql.In(o.Kvid, queryDetails));
return base.OnPostRestfulRead(req, res, dbConnection, rtns);
}
}
[RequiresAnyRole(SystemRoles.Everyone)]
public class BillQuery : RestfulQuery<Bill>
{
/// <summary>
/// true:只查已经归档的账单
/// false:只查未支付的账单
/// true:只查已经付款的账单
/// false:只查未付款的账单
/// 不传入: 全部账单
/// </summary>
public bool? Payed { get; set; }
public bool? IsPayed { get; set; }
public override bool OnPreRestfulQuery(IRequest req, IResponse res, IDbConnection dbConnection, IRestfulQueryResponse<Bill> rtns, ref Expression<Func<Bill, bool>> where)
{
if (Payed == null) return base.OnPreRestfulQuery(req, res, dbConnection, rtns, ref where);
if (Payed.Value) where = o => o.Amount == o.AmountPayment;
if (!Payed.Value) where = o => o.Amount > o.AmountPayment;
if (IsPayed == null) return base.OnPreRestfulQuery(req, res, dbConnection, rtns, ref where);
else if (IsPayed.Value) where = o => o.Amount == o.AmountPayment;
else where = o => o.Amount > o.AmountPayment || o.AmountPayment == 0;
return base.OnPreRestfulQuery(req, res, dbConnection, rtns, ref where);
}
}
......
......@@ -12,23 +12,114 @@ namespace Kivii.Finances.Transforms
[Api(Description = "发票作废")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceOffset:RestfulExecution<Invoice>
public class InvoiceOffset : RestfulExecution<Invoice>
{
public Guid Kvid { get; set; }
public List<Guid> Kvids { get; set; }
public string Remark { get; set; }
public override object OnExecution(IRequest req, IResponse res)
{
Kvid.ThrowIfEmpty("请传入要冲销的发票Kvid!");
if (Kvid == Guid.Empty && Kvids.IsNullOrEmpty()) throw new Exception("请传入要作废的发票Kvid!");
if (Kvids.IsNullOrEmpty()) Kvids = new List<Guid>();
if (Kvid != Guid.Empty) Kvids.Add(Kvid);
var conn = KiviiContext.GetOpenedDbConnection<Invoice>();
var invoice = conn.SingleById<Invoice>(Kvid);
invoice.ThrowIfNull("未找到对应发票!");
invoice.BizKvid.ThrowIfNotEmpty("发票已关联业务! 请先解除关联!");
invoice.OffsetKvid.ThrowIfNotEmpty("发票已作废!");
var apply = conn.SingleById<InvoiceApply>(invoice.ApplyKvid);
var invoices = conn.SelectByIds<Invoice>(Kvids);
if (invoices.IsNullOrEmpty()) throw new Exception("未找到所选发票信息!");
if (invoices.Exists(o => o.BizKvid != Guid.Empty || o.OffsetKvid != Guid.Empty || o.RootKvid != o.Kvid || o.Amount <= 0)) throw new Exception("存在不正确的发票类型");
if (invoices.Count != Kvids.Count) throw new Exception("所选发票信息与查询后结果不一致!");
var relationInvoices = conn.Select<Invoice>(o => Sql.In(o.ParentKvid, Kvids) && o.OffsetKvid == Guid.Empty && o.Type == "Relation");
List<Payment> existPayments = null;
List<Payment> splitPayments = null;
List<Invoice> offsets = new List<Invoice>();
if (!relationInvoices.IsNullOrEmpty())
{
existPayments = conn.Select<Payment>(o => Sql.In(o.Kvid, relationInvoices.ConvertAll(p => p.BizKvid)));//Type:Bank,Pos,Cash,WeChat...
if (!existPayments.IsNullOrEmpty())
{
splitPayments = conn.Select<Payment>(o => o.OffsetKvid == Guid.Empty && o.Type == PaymentType.Split && Sql.In(o.ParentKvid, existPayments.ConvertAll(p => p.Kvid)));
foreach (var item in existPayments)
{
var relations = relationInvoices.Where(o => o.BizKvid == item.Kvid).ToList();
if (!relations.IsNullOrEmpty())
{
item.AmountInvoice -= relations.Sum(o => o.Amount);
if (item.AmountInvoice < 0) item.AmountInvoice = 0;
item.AddOnlyProperties(o => o.AmountInvoice);
}
if (!splitPayments.IsNullOrEmpty())//要是所选Payment存在拆分项,满足条件就要更新AmountInvoice
{
decimal amountInvoice = 0;
amountInvoice.PopulateWith(item.AmountInvoice);// = payment.AmountInvoice;
foreach (var split in splitPayments)
{
if (amountInvoice <= 0) split.AmountInvoice = 0;
else split.AmountInvoice = split.Amount >= amountInvoice ? amountInvoice : split.Amount;
split.AddOnlyProperties(o => o.AmountInvoice);
amountInvoice -= split.AmountInvoice;
}
}
}
}
foreach (var item in relationInvoices)
{
var offset = item.Offset($"发票作废:{Remark}");
offsets.Add(offset);
}
}
foreach (var item in invoices)
{
var offset = item.Offset($"发票作废:{Remark}");
offsets.Add(offset);
}
var rtns = new RestfulUpdateResponse<Invoice>();
rtns.Results = new List<Invoice>();
return base.OnExecution(req, res);
var trans = conn.OpenTransaction();
try
{
foreach (var item in invoices)
{
conn.UpdateOnly(item);
rtns.Results.Add(item);
}
//删除关联Payment的发票数据
if (!relationInvoices.IsNullOrEmpty())
{
foreach (var item in relationInvoices)
{
conn.UpdateOnly(item);
}
}
foreach (var item in offsets)
{
conn.Insert(item);
}
//更新已关联的payment的AmountInvoice
if (!existPayments.IsNullOrEmpty())
{
foreach (var item in existPayments)
{
if (item.OnlyProperties.Count > 0) conn.UpdateOnly(item);
}
}
//更新已关联的payment的父级或子级AmountInvoice
if (!splitPayments.IsNullOrEmpty())
{
foreach (var item in splitPayments)
{
if (item.OnlyProperties.Count > 0) conn.UpdateOnly(item);
}
}
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
return rtns;
}
}
......@@ -36,19 +127,70 @@ namespace Kivii.Finances.Transforms
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceOffsetCancel : RestfulExecution<Invoice>
{
}
public Guid Kvid { get; set; }
public List<Guid> Kvids { get; set; }
[Api(Description = "发票红冲")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceDeficit : RestfulExecution<Invoice>
public override object OnExecution(IRequest req, IResponse res)
{
if (Kvid == Guid.Empty && Kvids.IsNullOrEmpty()) throw new Exception("请传入要作废的发票Kvid!");
if (Kvids.IsNullOrEmpty()) Kvids = new List<Guid>();
if (Kvid != Guid.Empty) Kvids.Add(Kvid);
var conn = KiviiContext.GetOpenedDbConnection<Invoice>();
var invoices = conn.SelectByIds<Invoice>(Kvids);
if (invoices.IsNullOrEmpty()) throw new Exception("未找到所选发票信息!");
if (invoices.Exists(o => o.OffsetKvid == Guid.Empty)) throw new Exception("存在不正确的未作废发票,无法撤回!");
if (invoices.Exists(o => o.Amount <= 0)) throw new Exception("请选择原作废发票信息进行撤销!");
if (invoices.Count != Kvids.Count) throw new Exception("所选发票信息与查询后结果不一致!");
//发票作废后 想要撤销操作,不管当初此发票是否已经有到账,都会变成借票的发票,需要冲销抵扣才行
var offsetInvoices = conn.Select<Invoice>(o => Sql.In(o.OffsetKvid, invoices.ConvertAll(p => p.OffsetKvid)));
offsetInvoices.ThrowIfNullOrEmpty("未找到原作废项目!");
}
var rtns = new RestfulExecutionResponse<Invoice>();
rtns.Results = new List<Invoice>();
[Api(Description = "红冲撤回")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceDeficitCancel : RestfulExecution<Invoice>
var trans = conn.OpenTransaction();
try
{
//原发票还原
var updateInvoices = conn.From<Invoice>();
updateInvoices = updateInvoices.Update(o => new { o.OffsetKvid, o.PayedTime, o.AmountPayment, o.Remark });
updateInvoices = updateInvoices.Where(o => Sql.In(o.Kvid, invoices.ConvertAll(p => p.Kvid)));
conn.UpdateOnly<Invoice>(new Invoice { OffsetKvid = Guid.Empty, PayedTime = null, AmountPayment = 0, Remark = string.Empty }, updateInvoices);
foreach (var item in invoices)
{
item.OffsetKvid = Guid.Empty;
item.PayedTime = null;
item.AmountPayment = 0;
item.Remark = string.Empty;
item.RemoveAllOnlyProperties();
rtns.Results.Add(item);
}
//删除Offset发票数据
var updateOffsetInvoices = conn.From<Invoice>();
updateOffsetInvoices = updateOffsetInvoices.Update(o => o.Status);
updateOffsetInvoices = updateOffsetInvoices.Where(o => Sql.In(o.Kvid, offsetInvoices.ConvertAll(p => p.Kvid)));
conn.UpdateOnly<Invoice>(new Invoice { Status = -1 }, updateOffsetInvoices);
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
return base.OnExecution(req, res);
}
}
//[Api(Description = "发票红冲")]
//[RequiresAnyRole(SystemRoles.Everyone)]
//public class InvoiceDeficit : RestfulExecution<Invoice>
//{
//}
//[Api(Description = "红冲撤回")]
//[RequiresAnyRole(SystemRoles.Everyone)]
//public class InvoiceDeficitCancel : RestfulExecution<Invoice>
//{
//}
}
using Kivii.Finances.Entities;
using Kivii.Linq;
using Kivii.Web;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Kivii.Finances.Transforms
{
[Api(Description = "发票查询")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceQueryEx : RestfulExecution<Invoice>
{
#region QueryArgs
public virtual int? Skip { get; set; }
public virtual int? Take { get; set; }
public virtual string OrderBy { get; set; }
public string OrderByDesc { get; set; }
public virtual string Include { get; set; }
public virtual string Fields { get; set; }
public string QueryKeys { get; set; }
public string QueryValues { get; set; }
#endregion
public DateTime? BeginTime { get; set; }
public DateTime? EndTime { get; set; }
public bool? Debited { get; set; }//借票到账未到账查询
public override object OnExecution(IRequest req, IResponse res)
{
(BeginTime != null && EndTime != null && BeginTime.Value > EndTime.Value).ThrowIfTrue("开始日期不能大于结束时间!");
var conn = KiviiContext.GetOpenedDbConnection<Invoice>();
var dynamicParams = Request.GetRequestParams();
var autoQuery = Request.TryResolve<IAutoQueryDb>();
autoQuery.IncludeTotal = true;
var request = new RestfulQuery<Invoice>();
request = request.PopulateWith(this);
var sqlExpress = autoQuery.CreateQuery(Request, conn, request, dynamicParams);
sqlExpress.Where(o => o.RootKvid == o.Kvid);
//sqlExpress.Where(o => o.RootKvid == o.Kvid && o.OffsetKvid == Guid.Empty && o.Category == InvoiceApplyType.Debit.ToString());
if (BeginTime != null) sqlExpress.And(o => o.OperateTime >= BeginTime.Value);
if (EndTime != null) sqlExpress.And(o => o.OperateTime < EndTime.Value);
if (Debited != null)
{
if (Debited.Value) sqlExpress.And(o => o.AmountPayment == o.Amount);
else sqlExpress.And(o => o.AmountPayment < o.Amount);
}
var rtns = autoQuery.Execute(Request, conn, request, sqlExpress);
if (Debited != null)
{
if (!Debited.Value)
{
var queryAccount = conn.From<Account>();
queryAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Balance, AccountType.Cash, AccountType.Pos));
queryAccount.Select(o => o.Kvid);
var queryPayment = conn.From<Payment>();
queryPayment.Where(o => o.RootKvid == o.Kvid && o.OffsetKvid == Guid.Empty && o.AmountInvoice < o.Amount && (Sql.In(o.PayerAccountKvid, queryAccount)));
queryPayment.Select(o => o.PayerName);
var paymentNames = conn.Column<string>(queryPayment).Distinct().ToList();
foreach (var item in rtns.Results)
{
if (paymentNames.Exists(o => o == item.PayerName))
{
item.Type = "Debit";
}
}
rtns.Results = rtns.Results.OrderBy(o => o.Type).ToList();
}
}
return rtns;
}
}
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceQuery : RestfulQuery<Invoice>
{ }
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceRead : RestfulRead<Invoice>
{ }
}
......@@ -11,7 +11,7 @@ namespace Kivii.Finances.Transforms
{
[Api(Description = "开票申请查询")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceApplyQueryEx:RestfulExecution<InvoiceApply>
public class InvoiceApplyQueryEx : RestfulExecution<InvoiceApply>
{
#region QueryArgs
public virtual int? Skip { get; set; }
......@@ -54,4 +54,8 @@ namespace Kivii.Finances.Transforms
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceApplyRead : RestfulRead<InvoiceApply>
{ }
[RequiresAnyRole(SystemRoles.Everyone)]
public class InvoiceApplyDetailQuery : RestfulQuery<InvoiceApplyDetail>
{ }
}
......@@ -26,28 +26,37 @@ namespace Kivii.Finances.Transforms
if (Items.IsNullOrEmpty()) Items = new List<Payment>();
if (Item != null) Items.Add(Item);
if (Items.Exists(o => o.Currency != CurrencyUnit.CNY)) throw new Exception("暂仅支持生成人民币货币单位流水!");
////这两步验证用于验证针对当前登录组织是收款还是付款
//if (Items.Exists(o => o.PayerAccountKvid == Guid.Empty && o.PayeeAccountKvid == Guid.Empty)) throw new Exception("收付款账户不能同时为空!");
//if (Items.Exists(o => o.PayerAccountKvid != Guid.Empty && o.PayeeAccountKvid != Guid.Empty)) throw new Exception("收付款账户不能同时指定!");
var typeBanks = Items.Where(o => o.Type == PaymentType.Bank).ToList();
var typeCashs = Items.Where(o => o.Type == PaymentType.Cash).ToList();
var typePoss = Items.Where(o => o.Type == PaymentType.Pos).ToList();
var conn = KiviiContext.GetOpenedDbConnection<Payment>();
//var allAccountKvids = new List<Guid>();
//allAccountKvids.AddRange(Items.ConvertAll(o => o.PayeeAccountKvid).ToList());
//allAccountKvids.AddRange(Items.ConvertAll(o => o.PayerAccountKvid).ToList());
//allAccountKvids = allAccountKvids.Distinct().ToList();
//var accounts = conn.Select<Account>(o => Sql.In(o.Kvid, allAccountKvids));
//accounts.ThrowIfNullOrEmpty("未找到相关账号!");
var accountBalance = CurrencyUnit.CNY.GetBalanceAccount();
var allAccountDetails = new List<AccountDetail>();
var allAcceptPayments = new List<Payment>();
var allAcceptPays = new List<Pay>();
//生成银行流水
if (!typeBanks.IsNullOrEmpty())
{
var bankAccounts = conn.Select<Account>(o => o.Type == AccountType.Bank && o.Currency == CurrencyUnit.CNY && o.OwnerKvid == KiviiContext.CurrentMember.OrganizationKvid);
if (bankAccounts.IsNullOrEmpty()) throw new Exception("未找到当前登录人所在组织的银行账户!");
foreach (var item in typeBanks)
{
(item.PayeeAccountSerialNumber.IsNullOrEmpty()).ThrowIfTrue("银行流水收款单位PayeeAccountSerialNumber不能为空");
var bankAccount = bankAccounts.FirstOrDefault(o => o.SerialNumber == item.PayeeAccountSerialNumber);
if (bankAccount == null) throw new Exception($"未找到当前银行流水{item.PayerName}[{item.PayeeAccountSerialNumber}]对应系统银行账户!");
if (item.Amount <= 0) continue;
//Account account = null;
//if (item.PayerAccountKvid != Guid.Empty) account = accounts.FirstOrDefault(o => o.Kvid == item.PayerAccountKvid);
//if (item.PayeeAccountKvid != Guid.Empty) account = accounts.FirstOrDefault(o => o.Kvid == item.PayeeAccountKvid);
//if (account == null) continue;
var itemKvid = Guid.NewGuid();
item.AmountInvoice = 0;
item.AmountSplited = 0;
......@@ -68,16 +77,14 @@ namespace Kivii.Finances.Transforms
item.PayerAccountOwnerName = item.PayerAccountOwnerName.IsNullOrEmpty() ? accountBalance.OwnerName : item.PayerAccountOwnerName;
item.PayerAccountSerialNumber = item.PayerAccountSerialNumber.IsNullOrEmpty() ? accountBalance.SerialNumber : item.PayerAccountSerialNumber;
item.PayeeAccountKvid = bankAccount.Kvid;
item.PayeeAccountName = bankAccount.Name;
item.PayeeAccountOwnerName = bankAccount.OwnerName;
item.PayeeAccountSerialNumber = bankAccount.SerialNumber;
item.PayeeAccountKvid = Guid.Empty;
item.OperateTime = (item.OperateTime == DateTime.MinValue ? DateTime.Now : item.OperateTime);
item.OperatorName = KiviiContext.CurrentMember.FullName;
item.OperatorKvid = KiviiContext.CurrentMember.Kvid;
var accountDetails = item.Accept();
var accountDetail = item.Accept(out Pay pay);
allAcceptPayments.Add(item);
allAccountDetails.AddRange(accountDetails);
allAccountDetails.Add(accountDetail);
allAcceptPays.Add(pay);
}
}
......@@ -133,16 +140,14 @@ namespace Kivii.Finances.Transforms
item.PayerAccountOwnerName = item.PayerAccountOwnerName.IsNullOrEmpty() ? cashAccount.OwnerName : item.PayerAccountOwnerName;
item.PayerAccountSerialNumber = item.PayerAccountSerialNumber.IsNullOrEmpty() ? cashAccount.SerialNumber : item.PayerAccountSerialNumber;
item.PayeeAccountKvid = accountBalance.Kvid;
item.PayeeAccountName = accountBalance.Name;
item.PayeeAccountOwnerName = accountBalance.OwnerName;
item.PayeeAccountSerialNumber = accountBalance.SerialNumber;
item.PayeeAccountKvid = Guid.Empty;
item.OperateTime = (item.OperateTime == DateTime.MinValue ? DateTime.Now : item.OperateTime);
item.OperatorName = KiviiContext.CurrentMember.FullName;
item.OperatorKvid = KiviiContext.CurrentMember.Kvid;
var accountDetails = item.Accept();
var accountDetail = item.Accept(out Pay pay);
allAcceptPayments.Add(item);
allAccountDetails.AddRange(accountDetails);
allAccountDetails.Add(accountDetail);
allAcceptPays.Add(pay);
}
}
//生成Pos流水
......@@ -173,16 +178,14 @@ namespace Kivii.Finances.Transforms
item.PayerAccountOwnerName = item.PayerAccountOwnerName.IsNullOrEmpty() ? posAccount.OwnerName : item.PayerAccountOwnerName;
item.PayerAccountSerialNumber = item.PayerAccountSerialNumber.IsNullOrEmpty() ? posAccount.SerialNumber : item.PayerAccountSerialNumber;
item.PayeeAccountKvid = accountBalance.Kvid;
item.PayeeAccountName = accountBalance.Name;
item.PayeeAccountOwnerName = accountBalance.OwnerName;
item.PayeeAccountSerialNumber = accountBalance.SerialNumber;
item.PayeeAccountKvid = Guid.Empty;
item.OperateTime = (item.OperateTime == DateTime.MinValue ? DateTime.Now : item.OperateTime);
item.OperatorName = KiviiContext.CurrentMember.FullName;
item.OperatorKvid = KiviiContext.CurrentMember.Kvid;
var accountDetails = item.Accept();
var accountDetail = item.Accept(out Pay pay);
allAcceptPayments.Add(item);
allAccountDetails.AddRange(accountDetails);
allAccountDetails.Add(accountDetail);
allAcceptPays.Add(pay);
}
}
......@@ -202,6 +205,13 @@ namespace Kivii.Finances.Transforms
}
}
if (!allAccountDetails.IsNullOrEmpty()) allAccountDetails.ForEach(o => o.Insert(conn));
if (!allAcceptPays.IsNullOrEmpty())
{
foreach (var item in allAcceptPays)
{
conn.Insert(item);
}
}
trans.Commit();
}
catch (Exception ex)
......
......@@ -72,6 +72,8 @@ namespace Kivii.Finances.Transforms
if (Amount <= 0) throw new Exception("金额不能为小于0!");
if (payment.AmountSplited == payment.Amount) throw new Exception("无剩余收款可认领!");
if (payment.AmountSplited + Amount > payment.Amount) throw new Exception("认领金额超出范围!");
var amountSplit = conn.Scalar<Payment, decimal>(o => Sql.Sum(o.Amount), p => p.ParentKvid == payment.Kvid && p.OffsetKvid == Guid.Empty);
if (amountSplit + Amount > payment.Amount) throw new Exception("认领金额超出范围!");
bank = payment;
split = bank.BizSplit(Amount, ownerKvid, ownerName, conn);
......@@ -120,8 +122,7 @@ namespace Kivii.Finances.Transforms
conn.Insert(split);
rtns.Results.Add(split);
}
if (bank != null) conn.UpdateOnly(bank);
payment.RecalculateAmountSplit(conn);
if (log != null) conn.Insert(log);
}
......@@ -257,7 +258,7 @@ namespace Kivii.Finances.Transforms
}
foreach (var item in banks)
{
conn.UpdateOnly(item);
item.RecalculateAmountSplit(conn);
}
foreach (var log in logs)
{
......@@ -292,6 +293,7 @@ namespace Kivii.Finances.Transforms
if (payments == null) throw new Exception("收款不存在!");
if (payments.Exists(o => o.Type != PaymentType.Split)) throw new Exception("非银行到账不可以认领!");
if (payments.Exists(o => o.OffsetKvid != Guid.Empty)) throw new Exception("已冲销收款不可撤销认领!");
(conn.Exists<InvoiceApply>(o => o.OperateType == InvoiceApplyType.Related && o.OffsetKvid == Guid.Empty && o.AmountInvoice != o.Amount && Sql.In(o.BizKvid, payments.ConvertAll(p => p.Kvid)))).ThrowIfTrue("存在申请开票中的到账,暂无法撤销认领!");
var rtns = new RestfulExecutionResponse<Payment>();
rtns.Results = new List<Payment>();
//if (payments.Exists(o => o.AmountUsed > 0)) throw new Exception("存在到账已使用,不可撤销认领!");
......@@ -318,37 +320,27 @@ namespace Kivii.Finances.Transforms
#region 没有使用的撤销
if (!paymentUnuseds.IsNullOrEmpty())
{
var rootKvids = paymentUnuseds.ConvertAll(o => o.RootKvid).Distinct().ToList();
var roots = conn.SelectByIds<Payment>(rootKvids);
var parentKvids = paymentUnuseds.ConvertAll(o => o.ParentKvid).Distinct().ToList();
var parents = conn.SelectByIds<Payment>(parentKvids);
var rootUpdates = new List<Payment>();
var parentUpdates = new List<Payment>();
var splitOffsets = new List<Payment>();
var offsets = new List<Payment>();
foreach (var split in paymentUnuseds)
{
var root = roots.FirstOrDefault(o => o.Kvid == split.ParentKvid);
if (root == null) continue;
var parent = parents.FirstOrDefault(o => o.Kvid == split.ParentKvid);
if (parent == null) continue;
var offset = split.Offset($"认领撤销:{Remark}");
offsets.Add(offset);
splitOffsets.Add(split);
if (root.AmountSplited >= split.Amount) root.AmountSplited -= split.Amount;
else root.AmountSplited = 0;
root.AddOnlyProperties(o => o.AmountSplited);
if (rootUpdates.Exists(o => o.Kvid == root.Kvid)) rootUpdates.RemoveAll(o => o.Kvid == root.Kvid);
rootUpdates.Add(root);
parentUpdates.Add(parent);
}
var trans = conn.OpenTransaction();
try
{
foreach (var item in rootUpdates)
{
conn.UpdateOnly(item);
}
foreach (var item in splitOffsets)
{
conn.UpdateOnly(item);
......@@ -358,6 +350,10 @@ namespace Kivii.Finances.Transforms
{
conn.Insert(item);
}
foreach (var item in parentUpdates)
{
item.RecalculateAmountSplit(conn);
}
trans.Commit();
}
catch (Exception ex)
......
......@@ -30,6 +30,8 @@ namespace Kivii.Finances.Transforms
if (payment.OffsetKvid != Guid.Empty) throw new Exception("已冲销收款不可操作!");
if (payment.AmountSplited == payment.Amount) throw new Exception("无剩余收款可操作!");
if (payment.AmountSplited + Amount > payment.Amount) throw new Exception("操作金额超出范围!");
//if (payment.AmountInvoice > 0) throw new Exception("已开票,无法非业务处理!");
if (payment.AmountUsed > 0) throw new Exception("已使用金额,无法非业务处理!");
var split = payment.UnBizSplit(Amount, PaymentType.UnBiz);
......@@ -49,8 +51,8 @@ namespace Kivii.Finances.Transforms
var trans = conn.OpenTransaction();
try
{
conn.UpdateOnly(payment);
conn.Insert(split);
payment.RecalculateAmountSplit(conn);
conn.Insert(log);
rtns.Results.Add(split);
......@@ -84,6 +86,8 @@ namespace Kivii.Finances.Transforms
if (payments.Exists(o => o.Type != PaymentType.Bank)) throw new Exception("非银行到账不可以操作!");
if (payments.Exists(o => o.OffsetKvid != Guid.Empty)) throw new Exception("已冲销收款不可操作!");
if (payments.Exists(o => o.AmountSplited >= o.Amount)) throw new Exception("无剩余收款可操作!");
//if (payments.Exists(o => o.AmountInvoice > 0)) throw new Exception("已开票,无法非业务处理!");
if (payments.Exists(o => o.AmountUsed > 0)) throw new Exception("已使用,无法非业务处理!");
var banks = new List<Payment>();
var splits = new List<Payment>();
......@@ -123,7 +127,7 @@ namespace Kivii.Finances.Transforms
}
foreach (var item in banks)
{
conn.UpdateOnly(item);
item.RecalculateAmountSplit(conn);
}
foreach (var log in logs)
{
......@@ -159,29 +163,24 @@ namespace Kivii.Finances.Transforms
if (payments.Exists(o => o.Type != PaymentType.UnBiz)) throw new Exception("非银行到账不可以操作!");
if (payments.Exists(o => o.OffsetKvid != Guid.Empty)) throw new Exception("已冲销收款不可撤销操作!");
if (payments.Exists(o => o.AmountUsed > 0)) throw new Exception("存在到账已使用,不可撤销操作!");
(conn.Exists<InvoiceApply>(o => o.OperateType == InvoiceApplyType.Related && o.OffsetKvid == Guid.Empty && o.AmountInvoice != o.Amount && Sql.In(o.BizKvid, payments.ConvertAll(p => p.Kvid)))).ThrowIfTrue("存在申请开票中的到账,暂无法撤销认领!");
var rootKvids = payments.ConvertAll(o => o.RootKvid).Distinct().ToList();
var roots = conn.SelectByIds<Payment>(rootKvids);
var parentKvids = payments.ConvertAll(o => o.ParentKvid).Distinct().ToList();
var parents = conn.SelectByIds<Payment>(parentKvids);
var rootUpdates = new List<Payment>();
var parentUpdates = new List<Payment>();
var splitOffsets = new List<Payment>();
var offsets = new List<Payment>();
foreach (var split in payments)
{
var root = roots.FirstOrDefault(o => o.Kvid == split.ParentKvid);
if (root == null) continue;
var parent = parents.FirstOrDefault(o => o.Kvid == split.ParentKvid);
if (parent == null) continue;
var offset = split.Offset($"非业务撤销:{Remark}");
offsets.Add(offset);
splitOffsets.Add(split);
if (root.AmountSplited >= split.Amount) root.AmountSplited -= split.Amount;
else root.AmountSplited = 0;
root.AddOnlyProperties(o => o.AmountSplited);
if (rootUpdates.Exists(o => o.Kvid == root.Kvid)) rootUpdates.RemoveAll(o => o.Kvid == root.Kvid);
rootUpdates.Add(root);
parentUpdates.Add(parent);
}
var rtns = new RestfulExecutionResponse<Payment>();
......@@ -190,10 +189,6 @@ namespace Kivii.Finances.Transforms
var trans = conn.OpenTransaction();
try
{
foreach (var item in rootUpdates)
{
conn.UpdateOnly(item);
}
foreach (var item in splitOffsets)
{
conn.UpdateOnly(item);
......@@ -203,6 +198,10 @@ namespace Kivii.Finances.Transforms
{
conn.Insert(item);
}
foreach (var item in parentUpdates)
{
item.RecalculateAmountSplit(conn);
}
trans.Commit();
}
catch (Exception ex)
......@@ -236,6 +235,8 @@ namespace Kivii.Finances.Transforms
if (payment.OffsetKvid != Guid.Empty) throw new Exception("已冲销收款不可操作!");
if (payment.AmountSplited == payment.Amount) throw new Exception("无剩余收款可操作!");
if (payment.AmountSplited + Amount > payment.Amount) throw new Exception("操作金额超出范围!");
//if (payment.AmountInvoice > 0) throw new Exception("已开票,无法退款处理!");
if (payment.AmountUsed > 0) throw new Exception("已使用金额,无法退款处理!");
var split = payment.UnBizSplit(Amount, PaymentType.Refund);
......@@ -255,8 +256,8 @@ namespace Kivii.Finances.Transforms
var trans = conn.OpenTransaction();
try
{
conn.UpdateOnly(payment);
conn.Insert(split);
payment.RecalculateAmountSplit(conn);
conn.Insert(log);
rtns.Results.Add(split);
......@@ -290,6 +291,8 @@ namespace Kivii.Finances.Transforms
if (payments.Exists(o => o.Type != PaymentType.Bank)) throw new Exception("非银行到账不可以操作!");
if (payments.Exists(o => o.OffsetKvid != Guid.Empty)) throw new Exception("已冲销收款不可操作!");
if (payments.Exists(o => o.AmountSplited >= o.Amount)) throw new Exception("无剩余收款可操作!");
//if (payments.Exists(o => o.AmountInvoice > 0)) throw new Exception("已开票,无法退款处理!");
if (payments.Exists(o => o.AmountUsed > 0)) throw new Exception("已使用,无法退款处理!");
var banks = new List<Payment>();
var splits = new List<Payment>();
......@@ -329,7 +332,7 @@ namespace Kivii.Finances.Transforms
}
foreach (var item in banks)
{
conn.UpdateOnly(item);
item.RecalculateAmountSplit(conn);
}
foreach (var log in logs)
{
......@@ -365,29 +368,24 @@ namespace Kivii.Finances.Transforms
if (payments.Exists(o => o.Type != PaymentType.Refund)) throw new Exception("非银行到账不可以操作!");
if (payments.Exists(o => o.OffsetKvid != Guid.Empty)) throw new Exception("已冲销收款不可撤销操作!");
if (payments.Exists(o => o.AmountUsed > 0)) throw new Exception("存在到账已使用,不可撤销操作!");
(conn.Exists<InvoiceApply>(o => o.OperateType == InvoiceApplyType.Related && o.OffsetKvid == Guid.Empty && o.AmountInvoice != o.Amount && Sql.In(o.BizKvid, payments.ConvertAll(p => p.Kvid)))).ThrowIfTrue("存在申请开票中的到账,暂无法撤销认领!");
var rootKvids = payments.ConvertAll(o => o.RootKvid).Distinct().ToList();
var roots = conn.SelectByIds<Payment>(rootKvids);
var parentKvids = payments.ConvertAll(o => o.ParentKvid).Distinct().ToList();
var parents = conn.SelectByIds<Payment>(parentKvids);
var rootUpdates = new List<Payment>();
var parentUpdates = new List<Payment>();
var splitOffsets = new List<Payment>();
var offsets = new List<Payment>();
foreach (var split in payments)
{
var root = roots.FirstOrDefault(o => o.Kvid == split.ParentKvid);
if (root == null) continue;
var parent = parents.FirstOrDefault(o => o.Kvid == split.ParentKvid);
if (parent == null) continue;
var offset = split.Offset($"退款撤销:{Remark}");
offsets.Add(offset);
splitOffsets.Add(split);
if (root.AmountSplited >= split.Amount) root.AmountSplited -= split.Amount;
else root.AmountSplited = 0;
root.AddOnlyProperties(o => o.AmountSplited);
if (rootUpdates.Exists(o => o.Kvid == root.Kvid)) rootUpdates.RemoveAll(o => o.Kvid == root.Kvid);
rootUpdates.Add(root);
parentUpdates.Add(parent);
}
var rtns = new RestfulExecutionResponse<Payment>();
......@@ -396,10 +394,6 @@ namespace Kivii.Finances.Transforms
var trans = conn.OpenTransaction();
try
{
foreach (var item in rootUpdates)
{
conn.UpdateOnly(item);
}
foreach (var item in splitOffsets)
{
conn.UpdateOnly(item);
......@@ -409,6 +403,10 @@ namespace Kivii.Finances.Transforms
{
conn.Insert(item);
}
foreach (var item in parentUpdates)
{
item.RecalculateAmountSplit(conn);
}
trans.Commit();
}
catch (Exception ex)
......
......@@ -59,18 +59,15 @@ namespace Kivii.Finances.Transforms
}
if (IsPayee != null)
{
var queryBankAccount = conn.From<Account>();
queryBankAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Bank, AccountType.WeChat, AccountType.AliPay));
queryBankAccount.Select(o => o.Kvid);
var queryAccount = conn.From<Account>();
queryAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Balance, AccountType.Cash, AccountType.Pos));
queryAccount.Select(o => o.Kvid);
var queryCashAccount = conn.From<Account>();
queryCashAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Cash, AccountType.Pos));
queryCashAccount.Select(o => o.Kvid);
if (IsPayee.Value)//收款
{
sqlExpress.And(o => (Sql.In(o.PayeeAccountKvid, queryBankAccount) || Sql.In(o.PayerAccountKvid, queryCashAccount)));
sqlExpress.And(o => (Sql.In(o.PayerAccountKvid, queryAccount)));
}
else sqlExpress.And(o => Sql.In(o.PayerAccountKvid, queryBankAccount));
else sqlExpress.And(o => Sql.In(o.PayeeAccountKvid, queryAccount));
}
var rtns = autoQuery.Execute(Request, conn, request, sqlExpress);
......@@ -78,6 +75,50 @@ namespace Kivii.Finances.Transforms
}
}
[Api(Description = "到账收款登记查询")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class PaymentPayQuery : RestfulExecution<Payment>
{
#region QueryArgs
public virtual int? Skip { get; set; }
public virtual int? Take { get; set; }
public virtual string OrderBy { get; set; }
public string OrderByDesc { get; set; }
public virtual string Include { get; set; }
public virtual string Fields { get; set; }
public string QueryKeys { get; set; }
public string QueryValues { get; set; }
#endregion
public override object OnExecution(IRequest req, IResponse res)
{
var conn = KiviiContext.GetOpenedDbConnection<Payment>();
var dynamicParams = Request.GetRequestParams();
var autoQuery = Request.TryResolve<IAutoQueryDb>();
autoQuery.IncludeTotal = true;
var request = new RestfulQuery<Payment>();
request = request.PopulateWith(this);
var sqlExpress = autoQuery.CreateQuery(Request, conn, request, dynamicParams);
sqlExpress.Where(o => o.OffsetKvid == Guid.Empty && Sql.In(o.Type, PaymentType.AliPay, PaymentType.WeChat, PaymentType.Split, PaymentType.Cash, PaymentType.Pos));
sqlExpress.And(o => o.AmountUsed == 0 || o.AmountUsed < o.Amount);
var queryAccount = conn.From<Account>();
queryAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Balance, AccountType.Cash, AccountType.Pos));
queryAccount.Select(o => o.Kvid);
sqlExpress.And(o => (Sql.In(o.PayerAccountKvid, queryAccount)));
var rtns = autoQuery.Execute(Request, conn, request, sqlExpress);
return rtns;
}
}
[Api(Description = "到账开票查询")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class PaymentInvoiceApplyQuery : RestfulExecution<Payment>
......@@ -113,7 +154,7 @@ namespace Kivii.Finances.Transforms
request = request.PopulateWith(this);
var sqlExpress = autoQuery.CreateQuery(Request, conn, request, dynamicParams);
sqlExpress.Where(o => o.OffsetKvid == Guid.Empty && Sql.In(o.Type, PaymentType.AliPay, PaymentType.WeChat, PaymentType.Cash, PaymentType.Pos, PaymentType.Split));
sqlExpress.And(o => o.AmountInvoice <= 0 && o.AmountInvoice < o.Amount);
sqlExpress.And(o => o.AmountInvoice <= 0 || o.AmountInvoice < o.Amount);
var queryInvoiceApplyRelations = conn.From<InvoiceApply>();
queryInvoiceApplyRelations.Where(o => o.OperateType == InvoiceApplyType.Related && o.OffsetKvid == Guid.Empty);
......@@ -159,15 +200,11 @@ namespace Kivii.Finances.Transforms
var sqlExpress = autoQuery.CreateQuery(Request, conn, request, dynamicParams);
sqlExpress.Where(o => o.OffsetKvid == Guid.Empty && Sql.In(o.Type, PaymentType.AliPay, PaymentType.WeChat, PaymentType.Bank, PaymentType.Cash, PaymentType.Pos) && o.AmountInvoice < o.Amount);
var queryBankAccount = conn.From<Account>();
queryBankAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Bank, AccountType.WeChat, AccountType.AliPay));
queryBankAccount.Select(o => o.Kvid);
var queryAccount = conn.From<Account>();
queryAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Balance, AccountType.Cash, AccountType.Pos));
queryAccount.Select(o => o.Kvid);
var queryCashAccount = conn.From<Account>();
queryCashAccount.Where(o => o.OrganizationKvid == KiviiContext.CurrentMember.OrganizationKvid && Sql.In(o.Type, AccountType.Cash, AccountType.Pos));
queryCashAccount.Select(o => o.Kvid);
sqlExpress.And(o => (Sql.In(o.PayeeAccountKvid, queryBankAccount) || Sql.In(o.PayerAccountKvid, queryCashAccount)));
sqlExpress.And(o => (Sql.In(o.PayerAccountKvid, queryAccount)));
var rtns = autoQuery.Execute(Request, conn, request, sqlExpress);
return rtns;
......@@ -211,4 +248,83 @@ namespace Kivii.Finances.Transforms
return rtns;
}
}
[Api(Description = "认领查询")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class PaymentSplitQuery : RestfulExecution<Payment>
{
#region QueryArgs
public virtual int? Skip { get; set; }
public virtual int? Take { get; set; }
public virtual string OrderBy { get; set; }
public string OrderByDesc { get; set; }
public virtual string Include { get; set; }
public virtual string Fields { get; set; }
public string QueryKeys { get; set; }
public string QueryValues { get; set; }
#endregion
public bool? IsBiz { get; set; }//Split,Pos,Cash,WeChat..
public override object OnExecution(IRequest req, IResponse res)
{
var conn = KiviiContext.GetOpenedDbConnection<Payment>();
var dynamicParams = Request.GetRequestParams();
var autoQuery = Request.TryResolve<IAutoQueryDb>();
autoQuery.IncludeTotal = true;
var request = new RestfulQuery<Payment>();
request = request.PopulateWith(this);
var sqlExpress = autoQuery.CreateQuery(Request, conn, request, dynamicParams);
if (IsBiz == null) sqlExpress.Where(o => o.OffsetKvid == Guid.Empty && Sql.In(o.Type, PaymentType.WeChat, PaymentType.Cash, PaymentType.AliPay, PaymentType.Pos, PaymentType.Split, PaymentType.Refund, PaymentType.UnBiz));
else if (IsBiz.Value) sqlExpress.Where(o => o.OffsetKvid == Guid.Empty && Sql.In(o.Type, PaymentType.WeChat, PaymentType.Cash, PaymentType.AliPay, PaymentType.Pos, PaymentType.Split));
else sqlExpress.Where(o => o.OffsetKvid == Guid.Empty && Sql.In(o.Type, PaymentType.Refund, PaymentType.UnBiz));
var rtns = autoQuery.Execute(Request, conn, request, sqlExpress);
return rtns;
}
}
[Api(Description = "充值查询")]
[RequiresAnyRole(SystemRoles.Everyone)]
public class PaymentTransferQuery : RestfulExecution<Payment>
{
#region QueryArgs
public virtual int? Skip { get; set; }
public virtual int? Take { get; set; }
public virtual string OrderBy { get; set; }
public string OrderByDesc { get; set; }
public virtual string Include { get; set; }
public virtual string Fields { get; set; }
public string QueryKeys { get; set; }
public string QueryValues { get; set; }
#endregion
public override object OnExecution(IRequest req, IResponse res)
{
var conn = KiviiContext.GetOpenedDbConnection<Payment>();
var dynamicParams = Request.GetRequestParams();
var autoQuery = Request.TryResolve<IAutoQueryDb>();
autoQuery.IncludeTotal = true;
var request = new RestfulQuery<Payment>();
request = request.PopulateWith(this);
var sqlExpress = autoQuery.CreateQuery(Request, conn, request, dynamicParams);
sqlExpress.Where(o => o.Type == PaymentType.Transfer);
var rtns = autoQuery.Execute(Request, conn, request, sqlExpress);
return rtns;
}
}
}
......@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
......@@ -25,14 +26,22 @@ namespace Kivii.Finances.Transforms
Items.Exists(o => o.PayerName.IsNullOrEmpty()).ThrowIfTrue("付款单位不能为空!");
Items.Exists(o => o.Currency == CurrencyUnit.Unsupported).ThrowIfTrue("不支持的货币单位!");
Items.Exists(o => o.Details.IsNullOrEmpty()).ThrowIfTrue("结算明细不能为空!");
var bizKvids = Items.ConvertAll(p => p.BizKvid);
bizKvids.RemoveAll(o => o == Guid.Empty);
var bizids = Items.ConvertAll(p => p.BizId);
bizids.RemoveAll(o => o.IsNullOrEmpty());
var connF = KiviiContext.GetOpenedDbConnection<Settlement>();
if (connF.Exists<Settlement>(o => o.OffsetKvid == Guid.Empty && Sql.In(o.BizKvid, Items.ConvertAll(p => p.BizKvid)))) throw new Exception("存在重复结算的对象!");
if (connF.Exists<Settlement>(o => o.OffsetKvid == Guid.Empty && (Sql.In(o.BizKvid, bizKvids) || Sql.In(o.BizId, bizids)))) throw new Exception("存在重复结算的对象!");
var connE = KiviiContext.GetOpenedDbConnection<G>();
//如果泛型类型不是Settlement本身就需要判断
if (typeof(G) != typeof(Settlement)) connE.Exists<EntitySettlement<G>>(o => o.OffsetKvid == Guid.Empty && Sql.In(o.BizKvid, Items.ConvertAll(p => p.BizKvid))).ThrowIfTrue("存在重复结算的对象!");
if (typeof(G) != typeof(Settlement)) connE.Exists<EntitySettlement<G>>(o => o.OffsetKvid == Guid.Empty && (Sql.In(o.BizKvid, bizKvids) || Sql.In(o.BizId, bizids))).ThrowIfTrue("存在重复结算的对象!");
var allDetails = new List<SettlementDetail>();
Items.ForEach(o => allDetails.AddRange(o.Details));
if (connE.Exists<EntitySettlementDetail<G>>(o => o.OffsetKvid != Guid.Empty && Sql.In(o.BizKvid, allDetails.ConvertAll(p => p.BizKvid)))) throw new Exception("存在重复结算的明细项目!");
var detailBizKvids = allDetails.ConvertAll(p => p.BizKvid);
detailBizKvids.RemoveAll(o => o == Guid.Empty);
var detailBizids = allDetails.ConvertAll(p => p.BizId);
detailBizids.RemoveAll(o => o.IsNullOrEmpty());
if (connE.Exists<EntitySettlementDetail<G>>(o => o.OffsetKvid != Guid.Empty && (Sql.In(o.BizKvid, detailBizKvids) || Sql.In(o.BizId, detailBizids)))) throw new Exception("存在重复结算的明细项目!");
var rtns = new RestfulCreateResponse<Settlement>();
rtns.Results = new List<Settlement>();
......@@ -163,7 +172,19 @@ namespace Kivii.Finances.Transforms
[RequiresAnyRole(SystemRoles.Everyone)]
public class SettlementQuery : RestfulQuery<Settlement>
{
public Guid BillKvid { get; set; }
public override bool OnPreRestfulQuery(IRequest req, IResponse res, IDbConnection dbConnection, IRestfulQueryResponse<Settlement> rtns, ref Expression<Func<Settlement, bool>> where)
{
if (BillKvid != Guid.Empty)
{
var queryDetails = dbConnection.From<BillDetail>();
queryDetails.Where(o => o.BillKvid == BillKvid);
queryDetails.Select(o => o.BizKvid);
where = o => Sql.In(o.Kvid, queryDetails);
}
return base.OnPreRestfulQuery(req, res, dbConnection, rtns, ref where);
}
}
[Api(Description = "结算查询Ex")]
......@@ -204,8 +225,8 @@ namespace Kivii.Finances.Transforms
var sqlExpress = autoQuery.CreateQuery(Request, conn, request, dynamicParams);
if (IsPayed != null)
{
if (IsPayed.Value) sqlExpress.And(o => o.PayKvid != Guid.Empty);
else sqlExpress.And(o => o.PayKvid == Guid.Empty);
if (IsPayed.Value) sqlExpress.And(o => o.AmountPayment == o.Amount);
else sqlExpress.And(o => o.AmountPayment < o.Amount || o.AmountPayment == 0);
}
if (IsBilled != null)
{
......@@ -235,9 +256,9 @@ namespace Kivii.Finances.Transforms
var connF = KiviiContext.GetOpenedDbConnection<Settlement>();
var connE = KiviiContext.GetOpenedDbConnection<EntitySettlement<G>>();
connF.Exists<Settlement>(o => o.PayKvid != Guid.Empty && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("删除错误:删除的结算中包含已收款的结算!");
connF.Exists<Settlement>(o => o.AmountPayment != 0 && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("删除错误:删除的结算中包含已收款的结算!");
//如果泛型类型不是Settlement本身就需要判断
if (typeof(G) != typeof(Settlement)) connE.Exists<EntitySettlement<G>>(o => o.PayKvid != Guid.Empty && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("删除错误:删除的结算中包含已收款的结算!");
if (typeof(G) != typeof(Settlement)) connE.Exists<EntitySettlement<G>>(o => o.AmountPayment != 0 && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("删除错误:删除的结算中包含已收款的结算!");
var settlements = connF.Select<Settlement>(o => Sql.In(o.Kvid, Kvids));
//var entitySettlements = connE.Select<EntitySettlement<G>>(o => Sql.In(o.Kvid, Kvids));
......@@ -397,10 +418,10 @@ namespace Kivii.Finances.Transforms
Kvids.ThrowIfNullOrEmpty("参数错误:未传入要调价的结算Kvids");
(Amount < 0).ThrowIfTrue("调整总价格不能为负值!");
var connFins = KiviiContext.GetOpenedDbConnection<Settlement>();
connFins.Exists<Settlement>(o => (o.PayKvid != Guid.Empty || o.OffsetKvid != Guid.Empty) && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("调价错误:存在已支付或待支付或已冲销的结算!");
connFins.Exists<Settlement>(o => (o.AmountPayment != 0 || o.OffsetKvid != Guid.Empty) && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("调价错误:存在已支付或待支付或已冲销的结算!");
var connG = KiviiContext.GetOpenedDbConnection<EntitySettlement<G>>();
//如果泛型类型不是Settlement本身就需要判断
if (typeof(G) != typeof(Settlement)) connG.Exists<EntitySettlement<G>>(o => (o.PayKvid != Guid.Empty || o.OffsetKvid != Guid.Empty) && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("调价错误:存在已支付或待支付或已冲销的结算!");
if (typeof(G) != typeof(Settlement)) connG.Exists<EntitySettlement<G>>(o => (o.AmountPayment != 0 || o.OffsetKvid != Guid.Empty) && Sql.In(o.Kvid, Kvids)).ThrowIfTrue("调价错误:存在已支付或待支付或已冲销的结算!");
var querySettlements = connFins.From<Settlement>();
querySettlements.Where(o => Sql.In(o.Kvid, Kvids));
......@@ -408,7 +429,7 @@ namespace Kivii.Finances.Transforms
var settlements = connFins.Select(querySettlements);
settlements.ThrowIfNullOrEmpty("未找到要调价的结算单!");
(settlements.Count != Kvids.Count).ThrowIfTrue("所选结算单信息不完整!");
settlements.Exists(o => o.PayKvid != Guid.Empty || o.OffsetKvid != Guid.Empty).ThrowIfTrue("调价错误:存在已支付或待支付或已冲销的结算!");
settlements.Exists(o => o.AmountPayment != 0 || o.OffsetKvid != Guid.Empty).ThrowIfTrue("调价错误:存在已支付或待支付或已冲销的结算!");
var amountSum = settlements.Sum(o => o.Amount);
var rates = new Dictionary<Guid, decimal>();
foreach (var item in settlements)
......
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