Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
Kivii.Biz.Finances.V2.0
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陶然
Kivii.Biz.Finances.V2.0
Commits
e75d3231
Commit
e75d3231
authored
Sep 04, 2023
by
陶然
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化使用到了Cache的接口
parent
cf5a051b
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1013 additions
and
955 deletions
+1013
-955
AssemblyInfo.cs
Src/Properties/AssemblyInfo.cs
+2
-2
RestfulInvoice.cs
Src/Transforms/RestfulInvoice.cs
+148
-138
RestfulPay.cs
Src/Transforms/RestfulPay.cs
+300
-292
RestfulPayment.Accept.cs
Src/Transforms/RestfulPayment.Accept.cs
+198
-188
RestfulPayment.Split.cs
Src/Transforms/RestfulPayment.Split.cs
+204
-186
RestfulSettlement.cs
Src/Transforms/RestfulSettlement.cs
+161
-149
No files found.
Src/Properties/AssemblyInfo.cs
View file @
e75d3231
...
@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
...
@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("5.4.2023.
419
0")]
[assembly: AssemblyVersion("5.4.2023.
904
0")]
[assembly: AssemblyFileVersion("5.4.2023.
419
0")]
[assembly: AssemblyFileVersion("5.4.2023.
904
0")]
Src/Transforms/RestfulInvoice.cs
View file @
e75d3231
...
@@ -264,164 +264,174 @@ namespace Kivii.Finances.Transforms
...
@@ -264,164 +264,174 @@ namespace Kivii.Finances.Transforms
(
Payments
.
Exists
(
o
=>
o
.
Amount
<=
0
)).
ThrowIfTrue
(
"未指定到账开票金额!"
);
(
Payments
.
Exists
(
o
=>
o
.
Amount
<=
0
)).
ThrowIfTrue
(
"未指定到账开票金额!"
);
(
Payments
.
Sum
(
o
=>
o
.
Amount
)
!=
Items
.
Sum
(
o
=>
o
.
Amount
)).
ThrowIfTrue
(
"到账开票金额和发票金额不一致!"
);
(
Payments
.
Sum
(
o
=>
o
.
Amount
)
!=
Items
.
Sum
(
o
=>
o
.
Amount
)).
ThrowIfTrue
(
"到账开票金额和发票金额不一致!"
);
}
}
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Invoice
>();
//var exists = conn.Select<Invoice>(o => Sql.In(o.SerialNumber, Items.ConvertAll(p => p.SerialNumber)));
//(conn.Exists<Invoice>(o => Sql.In(o.SerialNumber, Items.ConvertAll(p => p.SerialNumber)))).ThrowIfTrue("存在重复录入的发票信息");
List
<
Payment
>
preCorrelatingPayments
=
new
List
<
Payment
>();
List
<
Payment
>
parentPayments
=
new
List
<
Payment
>();
//也要更新父级的AmountInvoice
var
insertInvoices
=
new
List
<
Invoice
>();
var
insertInvoiceDetails
=
new
List
<
InvoiceDetail
>();
if
(!
Payments
.
IsNullOrEmpty
())
{
var
existPayments
=
conn
.
SelectByIds
<
Payment
>(
Payments
.
ConvertAll
(
o
=>
o
.
Kvid
));
existPayments
.
ThrowIfNullOrEmpty
(
"未找到指定的到账信息!"
);
(
existPayments
.
Count
!=
Payments
.
Count
).
ThrowIfTrue
(
"指定的到账信息与查询到的到账信息不匹配!"
);
existPayments
.
Exists
(
o
=>
o
.
Type
!=
PaymentType
.
Bank
&&
o
.
Type
!=
PaymentType
.
AliPay
&&
o
.
Type
!=
PaymentType
.
Cash
&&
o
.
Type
!=
PaymentType
.
Pos
&&
o
.
Type
!=
PaymentType
.
Split
&&
o
.
Type
!=
PaymentType
.
Assign
&&
o
.
Type
!=
PaymentType
.
WeChat
).
ThrowIfTrue
(
"存在不正确的到账类型"
);
foreach
(
var
item
in
existPayments
)
{
var
payment
=
Payments
.
FirstOrDefault
(
o
=>
o
.
Kvid
==
item
.
Kvid
);
if
(
payment
==
null
)
continue
;
if
(
item
.
Amount
-
item
.
AmountInvoice
<
payment
.
Amount
)
throw
new
Exception
(
$"所选到账
{
item
.
SerialNumber
}
,不足以继续开票指定金额
{
payment
.
Amount
}
元,当前到账剩余开票金额为:
{
item
.
Amount
-
item
.
AmountInvoice
}
元"
);
if
(
item
.
Amount
-
item
.
AmountInvoice
>=
payment
.
Amount
)
//说明选中的到账足以开票指定的金额
{
item
.
Amount
=
payment
.
Amount
;
item
.
AmountInvoice
=
0
;
item
.
RemoveAllOnlyProperties
();
preCorrelatingPayments
.
Add
(
item
);
}
}
(
preCorrelatingPayments
.
Sum
(
o
=>
o
.
Amount
)
!=
Items
.
Sum
(
o
=>
o
.
Amount
)).
ThrowIfTrue
(
"指定的到账开票金额和发票金额不一致!"
);
}
var
category
=
preCorrelatingPayments
.
IsNullOrEmpty
()
?
InvoiceApplyType
.
Debit
:
InvoiceApplyType
.
Payment
;
foreach
(
var
info
in
Items
)
{
//重复的发票,如果传了对应到账,那重复的发票就要抛异常,否则跳过
if
(
conn
.
Exists
<
Invoice
>(
o
=>
o
.
SerialNumber
==
info
.
SerialNumber
))
{
if
(!
Payments
.
IsNullOrEmpty
())
throw
new
Exception
(
$"存在重复录入的发票信息:
{
info
.
SerialNumber
}
"
);
else
continue
;
}
#
region
开票成功的情况处理
var
invoiceKvid
=
Guid
.
NewGuid
();
var
invoice
=
new
Invoice
();
invoice
.
RootKvid
=
invoiceKvid
;
invoice
.
Kvid
=
invoiceKvid
;
//invoice.ApplyKvid = ApplyKvid;
invoice
.
OwnerKvid
=
info
.
OwnerKvid
;
invoice
.
OwnerName
=
info
.
OwnerName
;
if
(
invoice
.
OwnerKvid
==
Guid
.
Empty
&&
invoice
.
OwnerName
.
IsNullOrEmpty
())
{
invoice
.
OwnerKvid
=
KiviiContext
.
CurrentMember
.
DepartmentKvid
;
invoice
.
OwnerName
=
KiviiContext
.
CurrentMember
.
DepartmentName
;
}
invoice
.
Currency
=
CurrencyUnit
.
CNY
;
invoice
.
Type
=
info
.
Type
;
invoice
.
Category
=
info
.
Category
.
IsNullOrEmpty
()
?
category
.
ToString
()
:
info
.
Category
;
invoice
.
OperateTime
=
info
.
OperateTime
;
invoice
.
SerialCode
=
info
.
SerialCode
;
invoice
.
SerialNumber
=
info
.
SerialNumber
;
//invoice.Status = 1;
invoice
.
TaxRate
=
info
.
TaxRate
;
invoice
.
Amount
=
info
.
Amount
;
invoice
.
AmountUntaxed
=
Math
.
Round
(
invoice
.
Amount
/
(
1
+
invoice
.
TaxRate
),
2
);
invoice
.
AmountTax
=
invoice
.
Amount
-
invoice
.
AmountUntaxed
;
invoice
.
PayeeKvid
=
info
.
PayeeKvid
;
invoice
.
PayeeName
=
info
.
PayeeName
;
invoice
.
PayeeTaxNumber
=
info
.
PayeeTaxNumber
;
invoice
.
PayeeCompanyAddress
=
info
.
PayeeCompanyAddress
;
invoice
.
PayeePhone
=
info
.
PayeePhone
;
invoice
.
PayeeRegisteredBank
=
info
.
PayeeRegisteredBank
;
invoice
.
PayeeBankAccount
=
info
.
PayeeBankAccount
;
invoice
.
PayerKvid
=
info
.
PayerKvid
;
invoice
.
PayerName
=
info
.
PayerName
;
invoice
.
PayerTaxNumber
=
info
.
PayerTaxNumber
;
invoice
.
PayerCompanyAddress
=
info
.
PayerCompanyAddress
;
invoice
.
PayerPhone
=
info
.
PayerPhone
;
invoice
.
PayerRegisteredBank
=
info
.
PayerRegisteredBank
;
invoice
.
PayerBankAccount
=
info
.
PayerBankAccount
;
invoice
.
OperatorName
=
info
.
OperatorName
;
invoice
.
Remark
=
info
.
Remark
;
invoice
.
Metadata
=
new
Dictionary
<
string
,
string
>();
if
(!
info
.
Metadata
.
IsNullOrEmpty
())
{
invoice
.
Metadata
=
info
.
Metadata
;
invoice
.
Metadata
[
"PayeeOperatorName"
]
=
info
.
Metadata
.
ContainsKey
(
"PayeeOperatorName"
)
?
info
.
Metadata
[
"PayeeOperatorName"
]
:
""
;
invoice
.
Metadata
[
"ReviewerName"
]
=
info
.
Metadata
.
ContainsKey
(
"ReviewerName"
)
?
info
.
Metadata
[
"ReviewerName"
]
:
""
;
}
insertInvoices
.
Add
(
invoice
);
foreach
(
var
infoDetail
in
info
.
Details
)
{
var
detail
=
new
InvoiceDetail
();
detail
.
PopulateInstance
(
infoDetail
);
detail
.
InvoiceKvid
=
invoiceKvid
;
detail
.
TaxRate
=
invoice
.
TaxRate
;
detail
.
AmountUntaxed
=
invoice
.
AmountUntaxed
;
detail
.
Amount
=
invoice
.
Amount
;
detail
.
AmountTax
=
invoice
.
AmountTax
;
detail
.
Quantity
=
detail
.
Quantity
<=
0
?
1
:
detail
.
Quantity
;
detail
.
QuantityUnitPrice
=
Math
.
Round
(
detail
.
Amount
/
detail
.
Quantity
,
2
);
detail
.
QuantityUnitPriceUntaxed
=
Math
.
Round
(
detail
.
AmountUntaxed
/
detail
.
Quantity
,
2
);
insertInvoiceDetails
.
Add
(
detail
);
}
#
endregion
}
if
(!
preCorrelatingPayments
.
IsNullOrEmpty
())
{
var
correlatedInvoices
=
insertInvoices
.
Correlating
(
preCorrelatingPayments
);
insertInvoices
.
AddRange
(
correlatedInvoices
);
var
currentParentKvids
=
preCorrelatingPayments
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Split
||
o
.
Type
==
PaymentType
.
Assign
).
ToList
().
ConvertAll
(
p
=>
p
.
ParentKvid
);
if
(!
currentParentKvids
.
IsNullOrEmpty
())
parentPayments
=
conn
.
Select
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
Sql
.
In
(
o
.
Kvid
,
currentParentKvids
));
}
var
rtns
=
new
RestfulUpdateResponse
<
Invoice
>();
rtns
.
Results
=
new
List
<
Invoice
>();
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheValue
=
cache
.
Get
<
List
<
string
>
>(
cacheKey
);
var
cacheValue
=
cache
.
Get
<
int
?
>(
cacheKey
);
if
(
!
cacheValue
.
IsNullOrEmpty
()
)
if
(
cacheValue
!=
null
)
{
{
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
.
Count
}
条,请稍后再试!"
);
if
(
cacheValue
<
0
)
throw
new
Exception
(
$"仍在处理中,请稍后查看结果!"
);
else
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
}
条,请稍后查看结果!"
);
}
}
var
caches
=
new
List
<
string
>()
;
int
?
caches
=
Items
.
Count
;
caches
.
AddRange
(
insertInvoice
s
.
ConvertAll
(
o
=>
o
.
SerialNumber
));
//caches.AddRange(Item
s.ConvertAll(o => o.SerialNumber));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
#
endregion
#
endregion
var
trans
=
conn
.
OpenTransaction
();
try
try
{
{
if
(!
insertInvoices
.
IsNullOrEmpty
())
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Invoice
>();
//var exists = conn.Select<Invoice>(o => Sql.In(o.SerialNumber, Items.ConvertAll(p => p.SerialNumber)));
//(conn.Exists<Invoice>(o => Sql.In(o.SerialNumber, Items.ConvertAll(p => p.SerialNumber)))).ThrowIfTrue("存在重复录入的发票信息");
List
<
Payment
>
preCorrelatingPayments
=
new
List
<
Payment
>();
List
<
Payment
>
parentPayments
=
new
List
<
Payment
>();
//也要更新父级的AmountInvoice
var
insertInvoices
=
new
List
<
Invoice
>();
var
insertInvoiceDetails
=
new
List
<
InvoiceDetail
>();
if
(!
Payments
.
IsNullOrEmpty
())
{
{
foreach
(
var
item
in
insertInvoices
)
var
existPayments
=
conn
.
SelectByIds
<
Payment
>(
Payments
.
ConvertAll
(
o
=>
o
.
Kvid
));
existPayments
.
ThrowIfNullOrEmpty
(
"未找到指定的到账信息!"
);
(
existPayments
.
Count
!=
Payments
.
Count
).
ThrowIfTrue
(
"指定的到账信息与查询到的到账信息不匹配!"
);
existPayments
.
Exists
(
o
=>
o
.
Type
!=
PaymentType
.
Bank
&&
o
.
Type
!=
PaymentType
.
AliPay
&&
o
.
Type
!=
PaymentType
.
Cash
&&
o
.
Type
!=
PaymentType
.
Pos
&&
o
.
Type
!=
PaymentType
.
Split
&&
o
.
Type
!=
PaymentType
.
Assign
&&
o
.
Type
!=
PaymentType
.
WeChat
).
ThrowIfTrue
(
"存在不正确的到账类型"
);
foreach
(
var
item
in
existPayments
)
{
{
if
(
item
.
Type
==
"Relation"
)
item
.
SerialNumber
=
item
.
GetSubSerialNumber
(
conn
);
var
payment
=
Payments
.
FirstOrDefault
(
o
=>
o
.
Kvid
==
item
.
Kvid
);
conn
.
Insert
(
item
);
if
(
payment
==
null
)
continue
;
if
(
item
.
Type
!=
"Relation"
)
rtns
.
Results
.
Add
(
item
);
if
(
item
.
Amount
-
item
.
AmountInvoice
<
payment
.
Amount
)
throw
new
Exception
(
$"所选到账
{
item
.
SerialNumber
}
,不足以继续开票指定金额
{
payment
.
Amount
}
元,当前到账剩余开票金额为:
{
item
.
Amount
-
item
.
AmountInvoice
}
元"
);
caches
.
Remove
(
item
.
SerialNumber
);
if
(
item
.
Amount
-
item
.
AmountInvoice
>=
payment
.
Amount
)
//说明选中的到账足以开票指定的金额
cache
.
Replace
(
cacheKey
,
caches
);
{
item
.
Amount
=
payment
.
Amount
;
item
.
AmountInvoice
=
0
;
item
.
RemoveAllOnlyProperties
();
preCorrelatingPayments
.
Add
(
item
);
}
}
(
preCorrelatingPayments
.
Sum
(
o
=>
o
.
Amount
)
!=
Items
.
Sum
(
o
=>
o
.
Amount
)).
ThrowIfTrue
(
"指定的到账开票金额和发票金额不一致!"
);
}
var
category
=
preCorrelatingPayments
.
IsNullOrEmpty
()
?
InvoiceApplyType
.
Debit
:
InvoiceApplyType
.
Payment
;
foreach
(
var
info
in
Items
)
{
//重复的发票,如果传了对应到账,那重复的发票就要抛异常,否则跳过
if
(
conn
.
Exists
<
Invoice
>(
o
=>
o
.
SerialNumber
==
info
.
SerialNumber
))
{
if
(!
Payments
.
IsNullOrEmpty
())
throw
new
Exception
(
$"存在重复录入的发票信息:
{
info
.
SerialNumber
}
"
);
else
continue
;
}
#
region
开票成功的情况处理
var
invoiceKvid
=
Guid
.
NewGuid
();
var
invoice
=
new
Invoice
();
invoice
.
RootKvid
=
invoiceKvid
;
invoice
.
Kvid
=
invoiceKvid
;
//invoice.ApplyKvid = ApplyKvid;
invoice
.
OwnerKvid
=
info
.
OwnerKvid
;
invoice
.
OwnerName
=
info
.
OwnerName
;
if
(
invoice
.
OwnerKvid
==
Guid
.
Empty
&&
invoice
.
OwnerName
.
IsNullOrEmpty
())
{
invoice
.
OwnerKvid
=
KiviiContext
.
CurrentMember
.
DepartmentKvid
;
invoice
.
OwnerName
=
KiviiContext
.
CurrentMember
.
DepartmentName
;
}
invoice
.
Currency
=
CurrencyUnit
.
CNY
;
invoice
.
Type
=
info
.
Type
;
invoice
.
Category
=
info
.
Category
.
IsNullOrEmpty
()
?
category
.
ToString
()
:
info
.
Category
;
invoice
.
OperateTime
=
info
.
OperateTime
;
invoice
.
SerialCode
=
info
.
SerialCode
;
invoice
.
SerialNumber
=
info
.
SerialNumber
;
//invoice.Status = 1;
invoice
.
TaxRate
=
info
.
TaxRate
;
invoice
.
Amount
=
info
.
Amount
;
invoice
.
AmountUntaxed
=
Math
.
Round
(
invoice
.
Amount
/
(
1
+
invoice
.
TaxRate
),
2
);
invoice
.
AmountTax
=
invoice
.
Amount
-
invoice
.
AmountUntaxed
;
invoice
.
PayeeKvid
=
info
.
PayeeKvid
;
invoice
.
PayeeName
=
info
.
PayeeName
;
invoice
.
PayeeTaxNumber
=
info
.
PayeeTaxNumber
;
invoice
.
PayeeCompanyAddress
=
info
.
PayeeCompanyAddress
;
invoice
.
PayeePhone
=
info
.
PayeePhone
;
invoice
.
PayeeRegisteredBank
=
info
.
PayeeRegisteredBank
;
invoice
.
PayeeBankAccount
=
info
.
PayeeBankAccount
;
invoice
.
PayerKvid
=
info
.
PayerKvid
;
invoice
.
PayerName
=
info
.
PayerName
;
invoice
.
PayerTaxNumber
=
info
.
PayerTaxNumber
;
invoice
.
PayerCompanyAddress
=
info
.
PayerCompanyAddress
;
invoice
.
PayerPhone
=
info
.
PayerPhone
;
invoice
.
PayerRegisteredBank
=
info
.
PayerRegisteredBank
;
invoice
.
PayerBankAccount
=
info
.
PayerBankAccount
;
invoice
.
OperatorName
=
info
.
OperatorName
;
invoice
.
Remark
=
info
.
Remark
;
invoice
.
Metadata
=
new
Dictionary
<
string
,
string
>();
if
(!
info
.
Metadata
.
IsNullOrEmpty
())
{
invoice
.
Metadata
=
info
.
Metadata
;
invoice
.
Metadata
[
"PayeeOperatorName"
]
=
info
.
Metadata
.
ContainsKey
(
"PayeeOperatorName"
)
?
info
.
Metadata
[
"PayeeOperatorName"
]
:
""
;
invoice
.
Metadata
[
"ReviewerName"
]
=
info
.
Metadata
.
ContainsKey
(
"ReviewerName"
)
?
info
.
Metadata
[
"ReviewerName"
]
:
""
;
}
insertInvoices
.
Add
(
invoice
);
foreach
(
var
infoDetail
in
info
.
Details
)
{
var
detail
=
new
InvoiceDetail
();
detail
.
PopulateInstance
(
infoDetail
);
detail
.
InvoiceKvid
=
invoiceKvid
;
detail
.
TaxRate
=
invoice
.
TaxRate
;
detail
.
AmountUntaxed
=
invoice
.
AmountUntaxed
;
detail
.
Amount
=
invoice
.
Amount
;
detail
.
AmountTax
=
invoice
.
AmountTax
;
detail
.
Quantity
=
detail
.
Quantity
<=
0
?
1
:
detail
.
Quantity
;
detail
.
QuantityUnitPrice
=
Math
.
Round
(
detail
.
Amount
/
detail
.
Quantity
,
2
);
detail
.
QuantityUnitPriceUntaxed
=
Math
.
Round
(
detail
.
AmountUntaxed
/
detail
.
Quantity
,
2
);
insertInvoiceDetails
.
Add
(
detail
);
}
}
#
endregion
}
}
if
(!
insertInvoiceDetails
.
IsNullOrEmpty
())
insertInvoiceDetails
.
ForEach
(
o
=>
conn
.
Insert
(
o
));
if
(!
preCorrelatingPayments
.
IsNullOrEmpty
())
if
(!
preCorrelatingPayments
.
IsNullOrEmpty
())
{
{
preCorrelatingPayments
.
ForEach
(
o
=>
conn
.
UpdateOnly
(
o
));
var
correlatedInvoices
=
insertInvoices
.
Correlating
(
preCorrelatingPayments
);
insertInvoices
.
AddRange
(
correlatedInvoices
);
var
currentParentKvids
=
preCorrelatingPayments
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Split
||
o
.
Type
==
PaymentType
.
Assign
).
ToList
().
ConvertAll
(
p
=>
p
.
ParentKvid
);
if
(!
currentParentKvids
.
IsNullOrEmpty
())
parentPayments
=
conn
.
Select
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
Sql
.
In
(
o
.
Kvid
,
currentParentKvids
));
}
var
rtns
=
new
RestfulUpdateResponse
<
Invoice
>();
rtns
.
Results
=
new
List
<
Invoice
>();
var
trans
=
conn
.
OpenTransaction
();
try
{
if
(!
insertInvoices
.
IsNullOrEmpty
())
{
foreach
(
var
item
in
insertInvoices
)
{
if
(
item
.
Type
==
"Relation"
)
item
.
SerialNumber
=
item
.
GetSubSerialNumber
(
conn
);
conn
.
Insert
(
item
);
if
(
item
.
Type
!=
"Relation"
)
rtns
.
Results
.
Add
(
item
);
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
}
if
(!
insertInvoiceDetails
.
IsNullOrEmpty
())
insertInvoiceDetails
.
ForEach
(
o
=>
conn
.
Insert
(
o
));
if
(!
preCorrelatingPayments
.
IsNullOrEmpty
())
{
preCorrelatingPayments
.
ForEach
(
o
=>
conn
.
UpdateOnly
(
o
));
}
if
(!
parentPayments
.
IsNullOrEmpty
())
{
parentPayments
.
ForEach
(
o
=>
o
.
RecalculateAmountInvoice
(
conn
));
}
trans
.
Commit
();
cache
.
Remove
(
cacheKey
);
return
rtns
;
}
}
if
(!
parentPayments
.
IsNullOrEmpty
()
)
catch
(
Exception
ex
)
{
{
parentPayments
.
ForEach
(
o
=>
o
.
RecalculateAmountInvoice
(
conn
));
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
throw
ex
;
}
}
trans
.
Commit
();
cache
.
Remove
(
cacheKey
);
return
rtns
;
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
{
{
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
cache
.
Remove
(
cacheKey
);
throw
ex
;
throw
ex
;
}
}
...
...
Src/Transforms/RestfulPay.cs
View file @
e75d3231
...
@@ -27,196 +27,350 @@ namespace Kivii.Finances.Transforms
...
@@ -27,196 +27,350 @@ namespace Kivii.Finances.Transforms
PayingMethods
.
Exists
(
o
=>
o
.
Kvid
==
Guid
.
Empty
).
ThrowIfTrue
(
"付款登记Kvid不能为空!"
);
PayingMethods
.
Exists
(
o
=>
o
.
Kvid
==
Guid
.
Empty
).
ThrowIfTrue
(
"付款登记Kvid不能为空!"
);
(
PayingMethods
.
Count
(
o
=>
o
.
Type
==
PayType
.
Discount
)
>
1
).
ThrowIfTrue
(
"金额抵扣登记方式超过限制次数,仅可使用一次"
);
(
PayingMethods
.
Count
(
o
=>
o
.
Type
==
PayType
.
Discount
)
>
1
).
ThrowIfTrue
(
"金额抵扣登记方式超过限制次数,仅可使用一次"
);
var
amountMethod
=
PayingMethods
.
Sum
(
o
=>
o
.
Amount
);
var
amountMethod
=
PayingMethods
.
Sum
(
o
=>
o
.
Amount
);
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Pay
>();
var
settlements
=
conn
.
Select
<
Settlement
>(
o
=>
Sql
.
In
(
o
.
Kvid
,
SettlementKvids
));
settlements
.
ThrowIfNullOrEmpty
(
"未找到结算单!"
);
if
(
settlements
.
Count
!=
SettlementKvids
.
Count
)
throw
new
Exception
(
"所选结算项与实际结算项不符合!"
);
if
(
settlements
.
Exists
(
o
=>
o
.
OffsetKvid
!=
Guid
.
Empty
))
throw
new
Exception
(
"所选结算项存在已作废项!"
);
if
(
settlements
.
Sum
(
o
=>
o
.
AmountPayment
)
>=
settlements
.
Sum
(
o
=>
o
.
Amount
))
throw
new
Exception
(
"所选结算项存在已付款登记!"
);
//if (settlements.Exists(o => o.AmountPayment >= o.Amount)) throw new Exception("所选结算项存在已付款登记!");
(
settlements
.
ConvertAll
(
o
=>
o
.
Currency
).
Distinct
().
ToList
().
Count
!=
1
).
ThrowIfTrue
(
"存在不相符的货币单位!"
);
var
currency
=
settlements
.
ConvertAll
(
o
=>
o
.
Currency
).
Distinct
().
ToList
()[
0
];
(
currency
==
CurrencyUnit
.
Unsupported
).
ThrowIfTrue
(
"不支持的货币单位!"
);
var
amountSettlement
=
settlements
.
Sum
(
o
=>
o
.
Amount
);
var
amountSettlementPlan
=
settlements
.
Sum
(
o
=>
o
.
AmountPlan
);
var
amountPayed
=
settlements
.
Sum
(
o
=>
o
.
AmountPayment
);
(
amountMethod
>
amountSettlement
-
amountPayed
).
ThrowIfTrue
(
"所选结算总金额大于所需金额!"
);
var
rtns
=
new
RestfulExecutionResponse
<
Pay
>();
rtns
.
Results
=
new
List
<
Pay
>();
var
accountBiz
=
currency
.
GetBizAccount
();
//conn.Single<Account>(o => o.OwnerKvid == KiviiContext.CurrentMember.OrganizationKvid && o.Type == AccountType.Biz && o.Currency == Item.Currency);
accountBiz
.
ThrowIfNull
(
$"未能正确获取系统
{
currency
}
业务账户!请联系管理员!"
);
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheValue
=
cache
.
Get
<
List
<
string
>
>(
cacheKey
);
var
cacheValue
=
cache
.
Get
<
int
?
>(
cacheKey
);
if
(
!
cacheValue
.
IsNullOrEmpty
()
)
if
(
cacheValue
!=
null
)
{
{
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
.
Count
}
条,请稍后再试!"
);
if
(
cacheValue
<
0
)
throw
new
Exception
(
$"仍在处理中,请稍后查看结果!"
);
else
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
}
条,请稍后查看结果!"
);
}
}
var
caches
=
new
List
<
string
>()
;
int
?
caches
=
SettlementKvids
.
Count
;
caches
.
AddRange
(
settlements
.
ConvertAll
(
o
=>
o
.
BizId
));
//caches.AddRange(Items.ConvertAll(o => o.SerialNumber
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
#
endregion
#
endregion
if
(
PayingMethods
.
Count
==
1
)
//单笔付款登记
try
{
{
using
(
KiviiContext
.
Profiler
(
"单个方式收款"
))
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Pay
>();
var
settlements
=
conn
.
Select
<
Settlement
>(
o
=>
Sql
.
In
(
o
.
Kvid
,
SettlementKvids
));
settlements
.
ThrowIfNullOrEmpty
(
"未找到结算单!"
);
if
(
settlements
.
Count
!=
SettlementKvids
.
Count
)
throw
new
Exception
(
"所选结算项与实际结算项不符合!"
);
if
(
settlements
.
Exists
(
o
=>
o
.
OffsetKvid
!=
Guid
.
Empty
))
throw
new
Exception
(
"所选结算项存在已作废项!"
);
if
(
settlements
.
Sum
(
o
=>
o
.
AmountPayment
)
>=
settlements
.
Sum
(
o
=>
o
.
Amount
))
throw
new
Exception
(
"所选结算项存在已付款登记!"
);
//if (settlements.Exists(o => o.AmountPayment >= o.Amount)) throw new Exception("所选结算项存在已付款登记!");
(
settlements
.
ConvertAll
(
o
=>
o
.
Currency
).
Distinct
().
ToList
().
Count
!=
1
).
ThrowIfTrue
(
"存在不相符的货币单位!"
);
var
currency
=
settlements
.
ConvertAll
(
o
=>
o
.
Currency
).
Distinct
().
ToList
()[
0
];
(
currency
==
CurrencyUnit
.
Unsupported
).
ThrowIfTrue
(
"不支持的货币单位!"
);
var
amountSettlement
=
settlements
.
Sum
(
o
=>
o
.
Amount
);
var
amountSettlementPlan
=
settlements
.
Sum
(
o
=>
o
.
AmountPlan
);
var
amountPayed
=
settlements
.
Sum
(
o
=>
o
.
AmountPayment
);
(
amountMethod
>
amountSettlement
-
amountPayed
).
ThrowIfTrue
(
"所选结算总金额大于所需金额!"
);
var
rtns
=
new
RestfulExecutionResponse
<
Pay
>();
rtns
.
Results
=
new
List
<
Pay
>();
var
accountBiz
=
currency
.
GetBizAccount
();
//conn.Single<Account>(o => o.OwnerKvid == KiviiContext.CurrentMember.OrganizationKvid && o.Type == AccountType.Biz && o.Currency == Item.Currency);
accountBiz
.
ThrowIfNull
(
$"未能正确获取系统
{
currency
}
业务账户!请联系管理员!"
);
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
.
Assign
&&
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
.
Assign
&&
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
);
//重新统计到账的使用情况
if
(
payment
.
Type
==
PaymentType
.
Split
)
payment
.
RecalculateAssignAmount
(
conn
);
#
region
同步更新泛型
Settlement
表中数据
foreach
(
var
item
in
settlements
)
{
if
(!
item
.
OnlyProperties
.
IsNullOrEmpty
())
conn
.
UpdateOnly
(
item
);
//更新了AmountPayment
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
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
());
cache
.
Remove
(
cacheKey
);
}
}
dynamicPayPayment
.
SerialNumber
=
payment
.
GetSubSerialNumber
(
conn
);
catch
(
Exception
ex
)
conn
.
Insert
(
dynamicPayPayment
);
//创建DynamicSplitPayment
accountDetail
.
Insert
(
conn
);
payment
.
RecalculateAmountUsed
(
conn
);
//重新统计到账的使用情况
if
(
payment
.
Type
==
PaymentType
.
Split
)
payment
.
RecalculateAssignAmount
(
conn
);
#
region
同步更新泛型
Settlement
表中数据
foreach
(
var
item
in
settlements
)
{
{
if
(!
item
.
OnlyProperties
.
IsNullOrEmpty
())
conn
.
UpdateOnly
(
item
);
//更新了AmountPayment
trans
.
Rollback
();
caches
.
Remove
(
item
.
BizId
);
subTrans
.
ForEach
(
o
=>
o
?.
Rollback
());
cache
.
Replace
(
cacheKey
,
caches
);
cache
.
Remove
(
cacheKey
);
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
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
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
());
cache
.
Remove
(
cacheKey
);
}
}
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
;
cache
.
Remove
(
cacheKey
);
var
result
=
_realMethod
.
MakeGenericMethod
(
entityType
).
Invoke
(
this
,
new
object
[
2
]
{
conn
,
group
.
ToList
()
});
throw
ex
;
if
(
result
!=
null
)
subTrans
.
Add
(
result
as
IDbTransaction
);
}
}
#
endregion
trans
.
Commit
();
subTrans
.
ForEach
(
o
=>
o
?.
Commit
());
cache
.
Remove
(
cacheKey
);
}
}
catch
(
Exception
ex
)
if
(
payingMethod
.
Type
==
PayType
.
Discount
)
{
{
trans
.
Rollback
();
var
discountAccount
=
conn
.
SingleById
<
Account
>(
payingMethod
.
Kvid
);
subTrans
.
ForEach
(
o
=>
o
?.
Rollback
());
discountAccount
.
ThrowIfNull
(
"未找到所选账户!"
);
cache
.
Remove
(
cacheKey
);
(
discountAccount
.
Currency
!=
currency
).
ThrowIfTrue
(
"存在不相符的货币单位!"
);
throw
ex
;
(
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
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
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
());
cache
.
Remove
(
cacheKey
);
}
catch
(
Exception
ex
)
{
trans
.
Rollback
();
subTrans
.
ForEach
(
o
=>
o
?.
Rollback
());
cache
.
Remove
(
cacheKey
);
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
}
"
);
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
{
{
foreach
(
var
item
in
pays
)
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
.
Assign
&&
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($"所选付款尚未开票!");
foreach
(
var
item
in
payments
)
{
{
conn
.
Insert
(
item
);
if
(
item
.
Type
==
PaymentType
.
Split
)
rtns
.
Results
.
Add
(
item
);
{
if
(
payments
.
Exists
(
o
=>
o
.
ParentKvid
==
item
.
Kvid
&&
o
.
Type
==
PaymentType
.
Assign
))
throw
new
Exception
(
"存在同一笔流水重复选择!"
);
}
if
(
item
.
Type
==
PaymentType
.
Assign
)
{
if
(
payments
.
Exists
(
o
=>
o
.
Kvid
==
item
.
ParentKvid
&&
o
.
Type
==
PaymentType
.
Split
))
throw
new
Exception
(
"存在同一笔流水重复选择!"
);
}
}
}
accountDetails
.
ForEach
(
o
=>
o
.
Insert
(
conn
));
//创建账户明细
}
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
(
$"所选付款方式余额不足!"
);
#
region
同步更新泛型
Settlement
表中数据
}
foreach
(
var
item
in
settlements
)
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
)
{
{
if
(!
item
.
OnlyProperties
.
IsNullOrEmpty
())
conn
.
UpdateOnly
(
item
);
//更新了Paykvid和AmountPayment
var
payingMethod
=
PayingMethods
.
FirstOrDefault
(
o
=>
o
.
Kvid
==
item
.
Kvid
);
caches
.
Remove
(
item
.
BizId
);
if
(
payingMethod
==
null
)
continue
;
cache
.
Replace
(
cacheKey
,
caches
);
(
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
);
}
}
var
groupSettlement
=
settlements
.
GroupBy
(
o
=>
o
.
BizType
);
}
if
(
_realMethod
==
null
)
if
(!
accounts
.
IsNullOrEmpty
())
{
foreach
(
var
item
in
accounts
)
{
{
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
.
CreditLine
).
ThrowIfTrue
(
$"所选付款方式余额不足,可用余额:
{
item
.
Amount
+
item
.
CreditLine
}
"
);
var
accountDetails
=
settlements
.
Paying
(
item
,
accountBiz
,
out
var
pays
,
payingMethod
.
Amount
);
allPays
.
AddRange
(
pays
);
allAccountDetails
.
AddRange
(
accountDetails
);
}
}
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
());
cache
.
Remove
(
cacheKey
);
}
}
catch
(
Exception
ex
)
if
(!
discounts
.
IsNullOrEmpty
()
)
{
{
trans
.
Rollback
();
foreach
(
var
item
in
discounts
)
subTrans
.
ForEach
(
o
=>
o
?.
Rollback
());
{
cache
.
Remove
(
cacheKey
);
var
payingMethod
=
PayingMethods
.
FirstOrDefault
(
o
=>
o
.
Kvid
==
item
.
Kvid
);
throw
ex
;
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
p
ays
)
foreach
(
var
item
in
allP
ays
)
{
{
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
);
if
(
item
.
Type
==
PaymentType
.
Split
)
item
.
RecalculateAssignAmount
(
conn
);
}
#
region
同步更新泛型
Settlement
表中数据
#
region
同步更新泛型
Settlement
表中数据
foreach
(
var
item
in
settlements
)
foreach
(
var
item
in
settlements
)
{
{
if
(!
item
.
OnlyProperties
.
IsNullOrEmpty
())
conn
.
UpdateOnly
(
item
);
//更新了Paykvid和AmountPayment
if
(!
item
.
OnlyProperties
.
IsNullOrEmpty
())
conn
.
UpdateOnly
(
item
);
//更新了Paykvid和AmountPayment
caches
.
Remove
(
item
.
BizId
)
;
caches
--
;
cache
.
Replace
(
cacheKey
,
caches
);
cache
.
Replace
(
cacheKey
,
caches
);
}
}
var
groupSettlement
=
settlements
.
GroupBy
(
o
=>
o
.
BizType
);
var
groupSettlement
=
settlements
.
GroupBy
(
o
=>
o
.
BizType
);
...
@@ -247,159 +401,13 @@ namespace Kivii.Finances.Transforms
...
@@ -247,159 +401,13 @@ namespace Kivii.Finances.Transforms
throw
ex
;
throw
ex
;
}
}
}
}
return
rtns
;
}
}
return
rtns
;
}
}
else
//组合付款登记
catch
(
Exception
ex
)
{
{
using
(
KiviiContext
.
Profiler
(
"组合方式收款"
))
cache
.
Remove
(
cacheKey
);
{
throw
ex
;
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
.
Assign
&&
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($"所选付款尚未开票!");
foreach
(
var
item
in
payments
)
{
if
(
item
.
Type
==
PaymentType
.
Split
)
{
if
(
payments
.
Exists
(
o
=>
o
.
ParentKvid
==
item
.
Kvid
&&
o
.
Type
==
PaymentType
.
Assign
))
throw
new
Exception
(
"存在同一笔流水重复选择!"
);
}
if
(
item
.
Type
==
PaymentType
.
Assign
)
{
if
(
payments
.
Exists
(
o
=>
o
.
Kvid
==
item
.
ParentKvid
&&
o
.
Type
==
PaymentType
.
Split
))
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
);
if
(
item
.
Type
==
PaymentType
.
Split
)
item
.
RecalculateAssignAmount
(
conn
);
}
#
region
同步更新泛型
Settlement
表中数据
foreach
(
var
item
in
settlements
)
{
if
(!
item
.
OnlyProperties
.
IsNullOrEmpty
())
conn
.
UpdateOnly
(
item
);
//更新了Paykvid和AmountPayment
caches
.
Remove
(
item
.
BizId
);
cache
.
Replace
(
cacheKey
,
caches
);
}
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
());
cache
.
Remove
(
cacheKey
);
}
catch
(
Exception
ex
)
{
trans
.
Rollback
();
subTrans
.
ForEach
(
o
=>
o
?.
Rollback
());
cache
.
Remove
(
cacheKey
);
throw
ex
;
}
}
return
rtns
;
}
}
}
}
...
...
Src/Transforms/RestfulPayment.Accept.cs
View file @
e75d3231
...
@@ -31,223 +31,233 @@ namespace Kivii.Finances.Transforms
...
@@ -31,223 +31,233 @@ namespace Kivii.Finances.Transforms
//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("收付款账户不能同时为空!");
//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
();
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
var
typeCashs
=
Items
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Cash
).
ToList
();
var
cache
=
KiviiContext
.
GetCacheClient
();
var
typePoss
=
Items
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Pos
).
ToList
();
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheValue
=
cache
.
Get
<
int
?>(
cacheKey
);
var
serialNumbers
=
Items
.
ConvertAll
(
o
=>
o
.
SerialNumber
);
if
(
cacheValue
!=
null
)
serialNumbers
.
RemoveAll
(
o
=>
o
.
IsNullOrEmpty
());
serialNumbers
=
serialNumbers
.
Distinct
().
ToList
();
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Payment
>();
var
accountBalance
=
CurrencyUnit
.
CNY
.
GetBalanceAccount
();
List
<
Payment
>
existPayments
=
null
;
if
(!
serialNumbers
.
IsNullOrEmpty
())
existPayments
=
conn
.
Select
<
Payment
>(
o
=>
Sql
.
In
(
o
.
SerialNumber
,
serialNumbers
));
var
allAccountDetails
=
new
List
<
AccountDetail
>();
var
allAcceptPayments
=
new
List
<
Payment
>();
var
allAcceptPays
=
new
List
<
Pay
>();
//生成银行流水
if
(!
typeBanks
.
IsNullOrEmpty
())
{
{
foreach
(
var
item
in
typeBanks
)
if
(
cacheValue
<
0
)
throw
new
Exception
(
$"仍在处理中,请稍后查看结果!"
);
{
else
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
}
条,请稍后查看结果!"
);
#
region
验证是否为重复项
if
(!
existPayments
.
IsNullOrEmpty
())
{
var
exist
=
existPayments
.
FirstOrDefault
(
o
=>
o
.
SerialNumber
==
item
.
SerialNumber
);
if
(
exist
!=
null
)
continue
;
}
else
{
var
exist
=
conn
.
Single
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
o
.
PayeeName
==
item
.
PayeeName
&&
o
.
PayerName
==
item
.
PayerName
&&
o
.
OperateTime
==
item
.
OperateTime
&&
o
.
Amount
==
item
.
Amount
&&
o
.
RootKvid
==
o
.
Kvid
);
if
(
exist
!=
null
)
continue
;
}
#
endregion
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
;
item
.
AmountUsed
=
0
;
item
.
OffsetKvid
=
Guid
.
Empty
;
item
.
BizId
=
string
.
Empty
;
item
.
BizType
=
string
.
Empty
;
item
.
BizKvid
=
Guid
.
Empty
;
item
.
Kvid
=
itemKvid
;
item
.
RootKvid
=
item
.
Kvid
;
item
.
ParentKvid
=
Guid
.
Empty
;
item
.
PayerAccountKvid
=
accountBalance
.
Kvid
;
item
.
PayerAccountName
=
item
.
PayerAccountName
.
IsNullOrEmpty
()
?
accountBalance
.
Name
:
item
.
PayerAccountName
;
item
.
PayerAccountOwnerName
=
item
.
PayerAccountOwnerName
.
IsNullOrEmpty
()
?
accountBalance
.
OwnerName
:
item
.
PayerAccountOwnerName
;
item
.
PayerAccountSerialNumber
=
item
.
PayerAccountSerialNumber
.
IsNullOrEmpty
()
?
accountBalance
.
SerialNumber
:
item
.
PayerAccountSerialNumber
;
item
.
PayeeAccountKvid
=
Guid
.
Empty
;
if
(
item
.
PayeeName
.
IsNullOrEmpty
())
item
.
PayeeName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
item
.
OperateTime
=
(
item
.
OperateTime
==
DateTime
.
MinValue
?
DateTime
.
Now
:
item
.
OperateTime
);
item
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
item
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
var
accountDetail
=
item
.
Accept
(
out
Pay
pay
);
allAcceptPayments
.
Add
(
item
);
allAccountDetails
.
Add
(
accountDetail
);
allAcceptPays
.
Add
(
pay
);
}
}
}
int
?
caches
=
Items
.
Count
;
//caches.AddRange(Items.ConvertAll(o => o.SerialNumber));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
#
endregion
//生成现金流水
try
if
(!
typeCashs
.
IsNullOrEmpty
())
{
{
var
cashAccount
=
CurrencyUnit
.
CNY
.
GetPersonalAccount
(
AccountType
.
Cash
);
var
typeBanks
=
Items
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Bank
).
ToList
();
if
(
cashAccount
==
null
)
throw
new
Exception
(
"未找到当前登录人的现金账户!"
);
var
typeCashs
=
Items
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Cash
).
ToList
();
foreach
(
var
item
in
typeCashs
)
var
typePoss
=
Items
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Pos
).
ToList
();
var
serialNumbers
=
Items
.
ConvertAll
(
o
=>
o
.
SerialNumber
);
serialNumbers
.
RemoveAll
(
o
=>
o
.
IsNullOrEmpty
());
serialNumbers
=
serialNumbers
.
Distinct
().
ToList
();
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Payment
>();
var
accountBalance
=
CurrencyUnit
.
CNY
.
GetBalanceAccount
();
List
<
Payment
>
existPayments
=
null
;
if
(!
serialNumbers
.
IsNullOrEmpty
())
existPayments
=
conn
.
Select
<
Payment
>(
o
=>
Sql
.
In
(
o
.
SerialNumber
,
serialNumbers
));
var
allAccountDetails
=
new
List
<
AccountDetail
>();
var
allAcceptPayments
=
new
List
<
Payment
>();
var
allAcceptPays
=
new
List
<
Pay
>();
//生成银行流水
if
(!
typeBanks
.
IsNullOrEmpty
())
{
{
#
region
验证是否为重复项
foreach
(
var
item
in
typeBanks
)
if
(!
existPayments
.
IsNullOrEmpty
())
{
var
exist
=
existPayments
.
FirstOrDefault
(
o
=>
o
.
SerialNumber
==
item
.
SerialNumber
);
if
(
exist
!=
null
)
continue
;
}
else
{
{
var
exist
=
conn
.
Single
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
o
.
PayeeName
==
item
.
PayeeName
&&
o
.
PayerName
==
item
.
PayerName
&&
o
.
OperateTime
==
item
.
OperateTime
&&
o
.
Amount
==
item
.
Amount
&&
o
.
RootKvid
==
o
.
Kvid
);
#
region
验证是否为重复项
if
(
exist
!=
null
)
continue
;
if
(!
existPayments
.
IsNullOrEmpty
())
{
var
exist
=
existPayments
.
FirstOrDefault
(
o
=>
o
.
SerialNumber
==
item
.
SerialNumber
);
if
(
exist
!=
null
)
continue
;
}
else
{
var
exist
=
conn
.
Single
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
o
.
PayeeName
==
item
.
PayeeName
&&
o
.
PayerName
==
item
.
PayerName
&&
o
.
OperateTime
==
item
.
OperateTime
&&
o
.
Amount
==
item
.
Amount
&&
o
.
RootKvid
==
o
.
Kvid
);
if
(
exist
!=
null
)
continue
;
}
#
endregion
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
;
item
.
AmountUsed
=
0
;
item
.
OffsetKvid
=
Guid
.
Empty
;
item
.
BizId
=
string
.
Empty
;
item
.
BizType
=
string
.
Empty
;
item
.
BizKvid
=
Guid
.
Empty
;
item
.
Kvid
=
itemKvid
;
item
.
RootKvid
=
item
.
Kvid
;
item
.
ParentKvid
=
Guid
.
Empty
;
item
.
PayerAccountKvid
=
accountBalance
.
Kvid
;
item
.
PayerAccountName
=
item
.
PayerAccountName
.
IsNullOrEmpty
()
?
accountBalance
.
Name
:
item
.
PayerAccountName
;
item
.
PayerAccountOwnerName
=
item
.
PayerAccountOwnerName
.
IsNullOrEmpty
()
?
accountBalance
.
OwnerName
:
item
.
PayerAccountOwnerName
;
item
.
PayerAccountSerialNumber
=
item
.
PayerAccountSerialNumber
.
IsNullOrEmpty
()
?
accountBalance
.
SerialNumber
:
item
.
PayerAccountSerialNumber
;
item
.
PayeeAccountKvid
=
Guid
.
Empty
;
if
(
item
.
PayeeName
.
IsNullOrEmpty
())
item
.
PayeeName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
item
.
OperateTime
=
(
item
.
OperateTime
==
DateTime
.
MinValue
?
DateTime
.
Now
:
item
.
OperateTime
);
item
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
item
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
var
accountDetail
=
item
.
Accept
(
out
Pay
pay
);
allAcceptPayments
.
Add
(
item
);
allAccountDetails
.
Add
(
accountDetail
);
allAcceptPays
.
Add
(
pay
);
}
}
#
endregion
if
(
item
.
Amount
<=
0
)
continue
;
var
itemKvid
=
Guid
.
NewGuid
();
item
.
AmountInvoice
=
0
;
item
.
AmountSplited
=
item
.
Amount
;
item
.
AmountUsed
=
0
;
item
.
OffsetKvid
=
Guid
.
Empty
;
item
.
BizId
=
string
.
Empty
;
item
.
BizType
=
string
.
Empty
;
item
.
BizKvid
=
Guid
.
Empty
;
item
.
Kvid
=
itemKvid
;
item
.
RootKvid
=
item
.
Kvid
;
item
.
ParentKvid
=
Guid
.
Empty
;
item
.
PayerAccountKvid
=
cashAccount
.
Kvid
;
item
.
PayerAccountName
=
item
.
PayerAccountName
.
IsNullOrEmpty
()
?
cashAccount
.
Name
:
item
.
PayerAccountName
;
item
.
PayerAccountOwnerName
=
item
.
PayerAccountOwnerName
.
IsNullOrEmpty
()
?
cashAccount
.
OwnerName
:
item
.
PayerAccountOwnerName
;
item
.
PayerAccountSerialNumber
=
item
.
PayerAccountSerialNumber
.
IsNullOrEmpty
()
?
cashAccount
.
SerialNumber
:
item
.
PayerAccountSerialNumber
;
item
.
PayeeAccountKvid
=
Guid
.
Empty
;
if
(
item
.
PayeeName
.
IsNullOrEmpty
())
item
.
PayeeName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
item
.
OperateTime
=
(
item
.
OperateTime
==
DateTime
.
MinValue
?
DateTime
.
Now
:
item
.
OperateTime
);
item
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
item
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
var
accountDetail
=
item
.
Accept
(
out
Pay
pay
);
allAcceptPayments
.
Add
(
item
);
allAccountDetails
.
Add
(
accountDetail
);
allAcceptPays
.
Add
(
pay
);
}
}
}
//生成Pos流水
//生成现金流水
if
(!
typePoss
.
IsNullOrEmpty
())
if
(!
typeCashs
.
IsNullOrEmpty
())
{
var
posAccount
=
CurrencyUnit
.
CNY
.
GetPersonalAccount
(
AccountType
.
Pos
);
if
(
posAccount
==
null
)
throw
new
Exception
(
"未找到当前登录人的刷卡账户!"
);
foreach
(
var
item
in
typePoss
)
{
{
#
region
验证是否为重复项
var
cashAccount
=
CurrencyUnit
.
CNY
.
GetPersonalAccount
(
AccountType
.
Cash
);
if
(!
existPayments
.
IsNullOrEmpty
())
if
(
cashAccount
==
null
)
throw
new
Exception
(
"未找到当前登录人的现金账户!"
);
foreach
(
var
item
in
typeCashs
)
{
{
var
exist
=
existPayments
.
FirstOrDefault
(
o
=>
o
.
SerialNumber
==
item
.
SerialNumber
);
#
region
验证是否为重复项
if
(
exist
!=
null
)
continue
;
if
(!
existPayments
.
IsNullOrEmpty
())
{
var
exist
=
existPayments
.
FirstOrDefault
(
o
=>
o
.
SerialNumber
==
item
.
SerialNumber
);
if
(
exist
!=
null
)
continue
;
}
else
{
var
exist
=
conn
.
Single
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
o
.
PayeeName
==
item
.
PayeeName
&&
o
.
PayerName
==
item
.
PayerName
&&
o
.
OperateTime
==
item
.
OperateTime
&&
o
.
Amount
==
item
.
Amount
&&
o
.
RootKvid
==
o
.
Kvid
);
if
(
exist
!=
null
)
continue
;
}
#
endregion
if
(
item
.
Amount
<=
0
)
continue
;
var
itemKvid
=
Guid
.
NewGuid
();
item
.
AmountInvoice
=
0
;
item
.
AmountSplited
=
item
.
Amount
;
item
.
AmountUsed
=
0
;
item
.
OffsetKvid
=
Guid
.
Empty
;
item
.
BizId
=
string
.
Empty
;
item
.
BizType
=
string
.
Empty
;
item
.
BizKvid
=
Guid
.
Empty
;
item
.
Kvid
=
itemKvid
;
item
.
RootKvid
=
item
.
Kvid
;
item
.
ParentKvid
=
Guid
.
Empty
;
item
.
PayerAccountKvid
=
cashAccount
.
Kvid
;
item
.
PayerAccountName
=
item
.
PayerAccountName
.
IsNullOrEmpty
()
?
cashAccount
.
Name
:
item
.
PayerAccountName
;
item
.
PayerAccountOwnerName
=
item
.
PayerAccountOwnerName
.
IsNullOrEmpty
()
?
cashAccount
.
OwnerName
:
item
.
PayerAccountOwnerName
;
item
.
PayerAccountSerialNumber
=
item
.
PayerAccountSerialNumber
.
IsNullOrEmpty
()
?
cashAccount
.
SerialNumber
:
item
.
PayerAccountSerialNumber
;
item
.
PayeeAccountKvid
=
Guid
.
Empty
;
if
(
item
.
PayeeName
.
IsNullOrEmpty
())
item
.
PayeeName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
item
.
OperateTime
=
(
item
.
OperateTime
==
DateTime
.
MinValue
?
DateTime
.
Now
:
item
.
OperateTime
);
item
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
item
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
var
accountDetail
=
item
.
Accept
(
out
Pay
pay
);
allAcceptPayments
.
Add
(
item
);
allAccountDetails
.
Add
(
accountDetail
);
allAcceptPays
.
Add
(
pay
);
}
}
else
}
//生成Pos流水
if
(!
typePoss
.
IsNullOrEmpty
())
{
var
posAccount
=
CurrencyUnit
.
CNY
.
GetPersonalAccount
(
AccountType
.
Pos
);
if
(
posAccount
==
null
)
throw
new
Exception
(
"未找到当前登录人的刷卡账户!"
);
foreach
(
var
item
in
typePoss
)
{
{
var
exist
=
conn
.
Single
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
o
.
PayeeName
==
item
.
PayeeName
&&
o
.
PayerName
==
item
.
PayerName
&&
o
.
OperateTime
==
item
.
OperateTime
&&
o
.
Amount
==
item
.
Amount
&&
o
.
RootKvid
==
o
.
Kvid
);
#
region
验证是否为重复项
if
(
exist
!=
null
)
continue
;
if
(!
existPayments
.
IsNullOrEmpty
())
{
var
exist
=
existPayments
.
FirstOrDefault
(
o
=>
o
.
SerialNumber
==
item
.
SerialNumber
);
if
(
exist
!=
null
)
continue
;
}
else
{
var
exist
=
conn
.
Single
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
o
.
PayeeName
==
item
.
PayeeName
&&
o
.
PayerName
==
item
.
PayerName
&&
o
.
OperateTime
==
item
.
OperateTime
&&
o
.
Amount
==
item
.
Amount
&&
o
.
RootKvid
==
o
.
Kvid
);
if
(
exist
!=
null
)
continue
;
}
#
endregion
if
(
item
.
Amount
<=
0
)
continue
;
var
itemKvid
=
Guid
.
NewGuid
();
item
.
AmountInvoice
=
0
;
item
.
AmountSplited
=
item
.
Amount
;
item
.
AmountUsed
=
0
;
item
.
OffsetKvid
=
Guid
.
Empty
;
item
.
BizId
=
string
.
Empty
;
item
.
BizType
=
string
.
Empty
;
item
.
BizKvid
=
Guid
.
Empty
;
item
.
Kvid
=
itemKvid
;
item
.
RootKvid
=
item
.
Kvid
;
item
.
ParentKvid
=
Guid
.
Empty
;
item
.
PayerAccountKvid
=
posAccount
.
Kvid
;
item
.
PayerAccountName
=
item
.
PayerAccountName
.
IsNullOrEmpty
()
?
posAccount
.
Name
:
item
.
PayerAccountName
;
item
.
PayerAccountOwnerName
=
item
.
PayerAccountOwnerName
.
IsNullOrEmpty
()
?
posAccount
.
OwnerName
:
item
.
PayerAccountOwnerName
;
item
.
PayerAccountSerialNumber
=
item
.
PayerAccountSerialNumber
.
IsNullOrEmpty
()
?
posAccount
.
SerialNumber
:
item
.
PayerAccountSerialNumber
;
item
.
PayeeAccountKvid
=
Guid
.
Empty
;
if
(
item
.
PayeeName
.
IsNullOrEmpty
())
item
.
PayeeName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
item
.
OperateTime
=
(
item
.
OperateTime
==
DateTime
.
MinValue
?
DateTime
.
Now
:
item
.
OperateTime
);
item
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
item
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
var
accountDetail
=
item
.
Accept
(
out
Pay
pay
);
allAcceptPayments
.
Add
(
item
);
allAccountDetails
.
Add
(
accountDetail
);
allAcceptPays
.
Add
(
pay
);
}
}
#
endregion
if
(
item
.
Amount
<=
0
)
continue
;
var
itemKvid
=
Guid
.
NewGuid
();
item
.
AmountInvoice
=
0
;
item
.
AmountSplited
=
item
.
Amount
;
item
.
AmountUsed
=
0
;
item
.
OffsetKvid
=
Guid
.
Empty
;
item
.
BizId
=
string
.
Empty
;
item
.
BizType
=
string
.
Empty
;
item
.
BizKvid
=
Guid
.
Empty
;
item
.
Kvid
=
itemKvid
;
item
.
RootKvid
=
item
.
Kvid
;
item
.
ParentKvid
=
Guid
.
Empty
;
item
.
PayerAccountKvid
=
posAccount
.
Kvid
;
item
.
PayerAccountName
=
item
.
PayerAccountName
.
IsNullOrEmpty
()
?
posAccount
.
Name
:
item
.
PayerAccountName
;
item
.
PayerAccountOwnerName
=
item
.
PayerAccountOwnerName
.
IsNullOrEmpty
()
?
posAccount
.
OwnerName
:
item
.
PayerAccountOwnerName
;
item
.
PayerAccountSerialNumber
=
item
.
PayerAccountSerialNumber
.
IsNullOrEmpty
()
?
posAccount
.
SerialNumber
:
item
.
PayerAccountSerialNumber
;
item
.
PayeeAccountKvid
=
Guid
.
Empty
;
if
(
item
.
PayeeName
.
IsNullOrEmpty
())
item
.
PayeeName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
item
.
OperateTime
=
(
item
.
OperateTime
==
DateTime
.
MinValue
?
DateTime
.
Now
:
item
.
OperateTime
);
item
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
item
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
var
accountDetail
=
item
.
Accept
(
out
Pay
pay
);
allAcceptPayments
.
Add
(
item
);
allAccountDetails
.
Add
(
accountDetail
);
allAcceptPays
.
Add
(
pay
);
}
}
}
var
rtns
=
new
RestfulCreateResponse
<
Payment
>();
var
rtns
=
new
RestfulCreateResponse
<
Payment
>();
rtns
.
Results
=
new
List
<
Payment
>();
rtns
.
Results
=
new
List
<
Payment
>();
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
var
trans
=
conn
.
OpenTransaction
();
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheValue
=
cache
.
Get
<
List
<
string
>>(
cacheKey
);
if
(!
cacheValue
.
IsNullOrEmpty
())
{
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
.
Count
}
条,请稍后再试!"
);
}
var
caches
=
new
List
<
string
>();
caches
.
AddRange
(
allAcceptPayments
.
ConvertAll
(
o
=>
o
.
SerialNumber
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
#
endregion
var
trans
=
conn
.
OpenTransaction
();
try
try
{
if
(!
allAcceptPayments
.
IsNullOrEmpty
())
{
{
foreach
(
var
item
in
allAcceptPayments
)
if
(!
allAcceptPayments
.
IsNullOrEmpty
()
)
{
{
conn
.
Insert
(
item
);
foreach
(
var
item
in
allAcceptPayments
)
item
.
RemoveAllOnlyProperties
();
{
rtns
.
Results
.
Add
(
item
);
conn
.
Insert
(
item
);
caches
.
Remove
(
item
.
SerialNumber
);
item
.
RemoveAllOnlyProperties
();
cache
.
Replace
(
cacheKey
,
caches
);
rtns
.
Results
.
Add
(
item
);
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
}
}
}
if
(!
allAccountDetails
.
IsNullOrEmpty
())
allAccountDetails
.
ForEach
(
o
=>
o
.
Insert
(
conn
));
if
(!
allAccountDetails
.
IsNullOrEmpty
())
allAccountDetails
.
ForEach
(
o
=>
o
.
Insert
(
conn
));
if
(!
allAcceptPays
.
IsNullOrEmpty
())
if
(!
allAcceptPays
.
IsNullOrEmpty
())
{
foreach
(
var
item
in
allAcceptPays
)
{
{
conn
.
Insert
(
item
);
foreach
(
var
item
in
allAcceptPays
)
{
conn
.
Insert
(
item
);
}
}
}
trans
.
Commit
();
cache
.
Remove
(
cacheKey
);
}
}
trans
.
Commit
();
catch
(
Exception
ex
)
cache
.
Remove
(
cacheKey
);
{
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
throw
ex
;
}
return
rtns
;
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
{
{
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
cache
.
Remove
(
cacheKey
);
throw
ex
;
throw
ex
;
}
}
return
rtns
;
}
}
}
}
}
}
Src/Transforms/RestfulPayment.Split.cs
View file @
e75d3231
...
@@ -177,144 +177,153 @@ namespace Kivii.Finances.Transforms
...
@@ -177,144 +177,153 @@ namespace Kivii.Finances.Transforms
public
override
object
OnExecution
(
IRequest
req
,
IResponse
res
)
public
override
object
OnExecution
(
IRequest
req
,
IResponse
res
)
{
{
if
(
Kvids
.
IsNullOrEmpty
())
throw
new
Exception
(
"请选择要认领的收款!"
);
if
(
Kvids
.
IsNullOrEmpty
())
throw
new
Exception
(
"请选择要认领的收款!"
);
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Payment
>();
var
payments
=
conn
.
SelectByIds
<
Payment
>(
Kvids
);
if
(
payments
==
null
)
throw
new
Exception
(
"收款不存在!"
);
if
(
payments
.
Exists
(
o
=>
o
.
Type
!=
PaymentType
.
Bank
&&
o
.
Type
!=
PaymentType
.
Split
))
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
(
"无剩余收款可认领!"
);
var
ownerKvid
=
Guid
.
Empty
;
var
ownerName
=
string
.
Empty
;
switch
(
OwnerType
)
{
case
OwnerType
.
Department
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
DepartmentKvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
DepartmentName
;
break
;
}
case
OwnerType
.
Organization
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
OrganizationKvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
break
;
}
case
OwnerType
.
Member
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
FullName
;
break
;
}
}
if
(
OwnerKvid
!=
Guid
.
Empty
)
{
ownerKvid
=
OwnerKvid
;
ownerName
=
OwnerName
;
}
var
banks
=
new
List
<
Payment
>();
var
splits
=
new
List
<
Payment
>();
var
splitsSetOwner
=
new
List
<
Payment
>();
var
logs
=
new
List
<
EntityLog
<
Payment
>>();
foreach
(
var
payment
in
payments
)
{
if
(
payment
.
Type
==
PaymentType
.
Bank
)
{
var
amount
=
payment
.
Amount
-
payment
.
AmountSplited
;
if
(
amount
<=
0
)
continue
;
var
splitPayment
=
payment
.
BizSplit
(
amount
,
Remark
,
ownerKvid
,
ownerName
,
conn
);
splits
.
Add
(
splitPayment
);
banks
.
Add
(
payment
);
#
region
记录日志
var
log
=
new
EntityLog
<
Payment
>();
log
.
OwnerKvid
=
payment
.
Kvid
;
log
.
BizId
=
splitPayment
.
SerialNumber
;
log
.
BizKvid
=
splitPayment
.
Kvid
;
log
.
BizType
=
typeof
(
Payment
).
FullName
;
log
.
Title
=
DateTime
.
Now
.
ToString
(
"yyyy-MM-dd HH:mm:ss"
);
log
.
Remark
=
KiviiContext
.
CurrentMember
.
FullName
+
$"在
{
log
.
Title
}
对流水号为:
{
payment
.
SerialNumber
}
的收款进行认领至
{
ownerName
}
,认领金额为:
{
splitPayment
.
Amount
}
元."
;
logs
.
Add
(
log
);
#
endregion
}
if
(
payment
.
Type
==
PaymentType
.
Split
)
{
payment
.
OwnerKvid
=
ownerKvid
;
payment
.
AddOnlyProperties
(
o
=>
o
.
OwnerKvid
);
payment
.
OwnerName
=
ownerName
;
payment
.
AddOnlyProperties
(
o
=>
o
.
OwnerName
);
payment
.
Remark
=
Remark
;
payment
.
AddOnlyProperties
(
o
=>
o
.
Remark
);
splitsSetOwner
.
Add
(
payment
);
#
region
记录日志
var
log
=
new
EntityLog
<
Payment
>();
log
.
OwnerKvid
=
payment
.
ParentKvid
;
log
.
BizId
=
payment
.
SerialNumber
;
log
.
BizKvid
=
payment
.
Kvid
;
log
.
BizType
=
typeof
(
Payment
).
FullName
;
log
.
Title
=
DateTime
.
Now
.
ToString
(
"yyyy-MM-dd HH:mm:ss"
);
log
.
Remark
=
KiviiContext
.
CurrentMember
.
FullName
+
$"在
{
log
.
Title
}
对流水号为:
{
payment
.
SerialNumber
}
的收款进行认领至
{
ownerName
}
,认领金额为:
{
payment
.
Amount
}
元."
;
logs
.
Add
(
log
);
#
endregion
}
}
var
rtns
=
new
RestfulExecutionResponse
<
Payment
>();
rtns
.
Results
=
new
List
<
Payment
>();
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheValue
=
cache
.
Get
<
List
<
string
>
>(
cacheKey
);
var
cacheValue
=
cache
.
Get
<
int
?
>(
cacheKey
);
if
(
!
cacheValue
.
IsNullOrEmpty
()
)
if
(
cacheValue
!=
null
)
{
{
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
.
Count
}
条,请稍后再试!"
);
if
(
cacheValue
<
0
)
throw
new
Exception
(
$"仍在处理中,请稍后查看结果!"
);
else
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
}
条,请稍后查看结果!"
);
}
}
var
caches
=
new
List
<
string
>()
;
int
?
caches
=
Kvids
.
Count
;
caches
.
AddRange
(
split
s
.
ConvertAll
(
o
=>
o
.
SerialNumber
));
//caches.AddRange(Item
s.ConvertAll(o => o.SerialNumber));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
#
endregion
#
endregion
//开启事务进行数据库操作
var
trans
=
conn
.
OpenTransaction
();
try
try
{
{
foreach
(
var
split
in
splits
)
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Payment
>();
var
payments
=
conn
.
SelectByIds
<
Payment
>(
Kvids
);
if
(
payments
==
null
)
throw
new
Exception
(
"收款不存在!"
);
if
(
payments
.
Exists
(
o
=>
o
.
Type
!=
PaymentType
.
Bank
&&
o
.
Type
!=
PaymentType
.
Split
))
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
(
"无剩余收款可认领!"
);
var
ownerKvid
=
Guid
.
Empty
;
var
ownerName
=
string
.
Empty
;
switch
(
OwnerType
)
{
{
conn
.
Insert
(
split
);
case
OwnerType
.
Department
:
rtns
.
Results
.
Add
(
split
);
{
caches
.
Remove
(
split
.
SerialNumber
);
ownerKvid
=
KiviiContext
.
CurrentMember
.
DepartmentKvid
;
cache
.
Replace
(
cacheKey
,
caches
);
ownerName
=
KiviiContext
.
CurrentMember
.
DepartmentName
;
break
;
}
case
OwnerType
.
Organization
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
OrganizationKvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
break
;
}
case
OwnerType
.
Member
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
FullName
;
break
;
}
}
}
foreach
(
var
item
in
splitsSetOwner
)
if
(
OwnerKvid
!=
Guid
.
Empty
)
{
{
conn
.
UpdateOnly
(
item
)
;
ownerKvid
=
OwnerKvid
;
rtns
.
Results
.
Add
(
item
)
;
ownerName
=
OwnerName
;
}
}
foreach
(
var
item
in
banks
)
var
banks
=
new
List
<
Payment
>();
var
splits
=
new
List
<
Payment
>();
var
splitsSetOwner
=
new
List
<
Payment
>();
var
logs
=
new
List
<
EntityLog
<
Payment
>>();
foreach
(
var
payment
in
payments
)
{
{
item
.
RecalculateAmountSplit
(
conn
);
if
(
payment
.
Type
==
PaymentType
.
Bank
)
{
var
amount
=
payment
.
Amount
-
payment
.
AmountSplited
;
if
(
amount
<=
0
)
continue
;
var
splitPayment
=
payment
.
BizSplit
(
amount
,
Remark
,
ownerKvid
,
ownerName
,
conn
);
splits
.
Add
(
splitPayment
);
banks
.
Add
(
payment
);
#
region
记录日志
var
log
=
new
EntityLog
<
Payment
>();
log
.
OwnerKvid
=
payment
.
Kvid
;
log
.
BizId
=
splitPayment
.
SerialNumber
;
log
.
BizKvid
=
splitPayment
.
Kvid
;
log
.
BizType
=
typeof
(
Payment
).
FullName
;
log
.
Title
=
DateTime
.
Now
.
ToString
(
"yyyy-MM-dd HH:mm:ss"
);
log
.
Remark
=
KiviiContext
.
CurrentMember
.
FullName
+
$"在
{
log
.
Title
}
对流水号为:
{
payment
.
SerialNumber
}
的收款进行认领至
{
ownerName
}
,认领金额为:
{
splitPayment
.
Amount
}
元."
;
logs
.
Add
(
log
);
#
endregion
}
if
(
payment
.
Type
==
PaymentType
.
Split
)
{
payment
.
OwnerKvid
=
ownerKvid
;
payment
.
AddOnlyProperties
(
o
=>
o
.
OwnerKvid
);
payment
.
OwnerName
=
ownerName
;
payment
.
AddOnlyProperties
(
o
=>
o
.
OwnerName
);
payment
.
Remark
=
Remark
;
payment
.
AddOnlyProperties
(
o
=>
o
.
Remark
);
splitsSetOwner
.
Add
(
payment
);
#
region
记录日志
var
log
=
new
EntityLog
<
Payment
>();
log
.
OwnerKvid
=
payment
.
ParentKvid
;
log
.
BizId
=
payment
.
SerialNumber
;
log
.
BizKvid
=
payment
.
Kvid
;
log
.
BizType
=
typeof
(
Payment
).
FullName
;
log
.
Title
=
DateTime
.
Now
.
ToString
(
"yyyy-MM-dd HH:mm:ss"
);
log
.
Remark
=
KiviiContext
.
CurrentMember
.
FullName
+
$"在
{
log
.
Title
}
对流水号为:
{
payment
.
SerialNumber
}
的收款进行认领至
{
ownerName
}
,认领金额为:
{
payment
.
Amount
}
元."
;
logs
.
Add
(
log
);
#
endregion
}
}
}
foreach
(
var
log
in
logs
)
var
rtns
=
new
RestfulExecutionResponse
<
Payment
>();
rtns
.
Results
=
new
List
<
Payment
>();
//开启事务进行数据库操作
var
trans
=
conn
.
OpenTransaction
();
try
{
{
conn
.
Insert
(
log
);
foreach
(
var
split
in
splits
)
}
{
conn
.
Insert
(
split
);
rtns
.
Results
.
Add
(
split
);
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
foreach
(
var
item
in
splitsSetOwner
)
{
conn
.
UpdateOnly
(
item
);
rtns
.
Results
.
Add
(
item
);
}
foreach
(
var
item
in
banks
)
{
item
.
RecalculateAmountSplit
(
conn
);
}
foreach
(
var
log
in
logs
)
{
conn
.
Insert
(
log
);
}
trans
.
Commit
();
trans
.
Commit
();
cache
.
Remove
(
cacheKey
);
cache
.
Remove
(
cacheKey
);
}
catch
(
Exception
ex
)
{
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
throw
ex
;
}
return
rtns
;
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
{
{
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
cache
.
Remove
(
cacheKey
);
throw
ex
;
throw
ex
;
}
}
return
rtns
;
}
}
}
}
...
@@ -619,98 +628,107 @@ namespace Kivii.Finances.Transforms
...
@@ -619,98 +628,107 @@ namespace Kivii.Finances.Transforms
{
{
if
(
Kvids
.
IsNullOrEmpty
())
throw
new
Exception
(
"请选择要划转的收款!"
);
if
(
Kvids
.
IsNullOrEmpty
())
throw
new
Exception
(
"请选择要划转的收款!"
);
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Payment
>();
var
payments
=
conn
.
SelectByIds
<
Payment
>(
Kvids
);
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
(
"已冲销收款不可划转!"
);
if
(
payments
.
Exists
(
o
=>
o
.
AmountSplited
>=
o
.
Amount
))
throw
new
Exception
(
"无剩余收款可划转!"
);
var
ownerKvid
=
Guid
.
Empty
;
var
ownerName
=
string
.
Empty
;
switch
(
OwnerType
)
{
case
OwnerType
.
Department
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
DepartmentKvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
DepartmentName
;
break
;
}
case
OwnerType
.
Organization
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
OrganizationKvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
break
;
}
case
OwnerType
.
Member
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
FullName
;
break
;
}
}
if
(
OwnerKvid
!=
Guid
.
Empty
)
{
ownerKvid
=
OwnerKvid
;
ownerName
=
OwnerName
;
}
if
(
payments
.
Exists
(
o
=>
o
.
OwnerKvid
==
ownerKvid
))
throw
new
Exception
(
"不可划转至同部门!"
);
var
spliteds
=
new
List
<
Payment
>();
var
assigns
=
new
List
<
Payment
>();
foreach
(
var
payment
in
payments
)
{
var
amount
=
payment
.
Amount
-
payment
.
AmountSplited
;
if
(
amount
<=
0
)
continue
;
var
assignPayment
=
payment
.
BizAssign
(
amount
,
Remark
,
ownerKvid
,
ownerName
,
conn
,
AmountFirst
);
assigns
.
Add
(
assignPayment
);
spliteds
.
Add
(
payment
);
}
var
rtns
=
new
RestfulExecutionResponse
<
Payment
>();
rtns
.
Results
=
new
List
<
Payment
>();
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheValue
=
cache
.
Get
<
List
<
string
>
>(
cacheKey
);
var
cacheValue
=
cache
.
Get
<
int
?
>(
cacheKey
);
if
(
!
cacheValue
.
IsNullOrEmpty
()
)
if
(
cacheValue
!=
null
)
{
{
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
.
Count
}
条,请稍后再试!"
);
if
(
cacheValue
<
0
)
throw
new
Exception
(
$"仍在处理中,请稍后查看结果!"
);
else
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
}
条,请稍后查看结果!"
);
}
}
var
caches
=
new
List
<
string
>()
;
int
?
caches
=
Kvids
.
Count
;
caches
.
AddRange
(
assign
s
.
ConvertAll
(
o
=>
o
.
SerialNumber
));
//caches.AddRange(Item
s.ConvertAll(o => o.SerialNumber));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
#
endregion
#
endregion
//开启事务进行数据库操作
var
trans
=
conn
.
OpenTransaction
();
try
try
{
{
foreach
(
var
assign
in
assigns
)
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Payment
>();
var
payments
=
conn
.
SelectByIds
<
Payment
>(
Kvids
);
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
(
"已冲销收款不可划转!"
);
if
(
payments
.
Exists
(
o
=>
o
.
AmountSplited
>=
o
.
Amount
))
throw
new
Exception
(
"无剩余收款可划转!"
);
var
ownerKvid
=
Guid
.
Empty
;
var
ownerName
=
string
.
Empty
;
switch
(
OwnerType
)
{
{
conn
.
Insert
(
assign
);
case
OwnerType
.
Department
:
rtns
.
Results
.
Add
(
assign
);
{
caches
.
Remove
(
assign
.
SerialNumber
);
ownerKvid
=
KiviiContext
.
CurrentMember
.
DepartmentKvid
;
cache
.
Replace
(
cacheKey
,
caches
);
ownerName
=
KiviiContext
.
CurrentMember
.
DepartmentName
;
break
;
}
case
OwnerType
.
Organization
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
OrganizationKvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
OrganizationName
;
break
;
}
case
OwnerType
.
Member
:
{
ownerKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
ownerName
=
KiviiContext
.
CurrentMember
.
FullName
;
break
;
}
}
}
foreach
(
var
item
in
spliteds
)
if
(
OwnerKvid
!=
Guid
.
Empty
)
{
{
item
.
RecalculateAmountSplit
(
conn
);
ownerKvid
=
OwnerKvid
;
ownerName
=
OwnerName
;
}
}
trans
.
Commit
();
if
(
payments
.
Exists
(
o
=>
o
.
OwnerKvid
==
ownerKvid
))
throw
new
Exception
(
"不可划转至同部门!"
);
cache
.
Remove
(
cacheKey
);
var
spliteds
=
new
List
<
Payment
>();
var
assigns
=
new
List
<
Payment
>();
foreach
(
var
payment
in
payments
)
{
var
amount
=
payment
.
Amount
-
payment
.
AmountSplited
;
if
(
amount
<=
0
)
continue
;
var
assignPayment
=
payment
.
BizAssign
(
amount
,
Remark
,
ownerKvid
,
ownerName
,
conn
,
AmountFirst
);
assigns
.
Add
(
assignPayment
);
spliteds
.
Add
(
payment
);
}
var
rtns
=
new
RestfulExecutionResponse
<
Payment
>();
rtns
.
Results
=
new
List
<
Payment
>();
//开启事务进行数据库操作
var
trans
=
conn
.
OpenTransaction
();
try
{
foreach
(
var
assign
in
assigns
)
{
conn
.
Insert
(
assign
);
rtns
.
Results
.
Add
(
assign
);
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
foreach
(
var
item
in
spliteds
)
{
item
.
RecalculateAmountSplit
(
conn
);
}
trans
.
Commit
();
cache
.
Remove
(
cacheKey
);
}
catch
(
Exception
ex
)
{
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
throw
ex
;
}
return
rtns
;
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
{
{
trans
.
Rollback
();
cache
.
Remove
(
cacheKey
);
cache
.
Remove
(
cacheKey
);
throw
ex
;
throw
ex
;
}
}
return
rtns
;
}
}
}
}
...
...
Src/Transforms/RestfulSettlement.cs
View file @
e75d3231
...
@@ -31,184 +31,196 @@ namespace Kivii.Finances.Transforms
...
@@ -31,184 +31,196 @@ namespace Kivii.Finances.Transforms
bizKvids
.
RemoveAll
(
o
=>
o
==
Guid
.
Empty
);
bizKvids
.
RemoveAll
(
o
=>
o
==
Guid
.
Empty
);
var
bizids
=
Items
.
ConvertAll
(
p
=>
p
.
BizId
).
Distinct
().
ToList
();
var
bizids
=
Items
.
ConvertAll
(
p
=>
p
.
BizId
).
Distinct
().
ToList
();
bizids
.
RemoveAll
(
o
=>
o
.
IsNullOrEmpty
());
bizids
.
RemoveAll
(
o
=>
o
.
IsNullOrEmpty
());
var
connF
=
KiviiContext
.
GetOpenedDbConnection
<
Settlement
>();
//foreach (var bizId in bizids)
//{
// if (connF.Exists<Settlement>(o => o.OffsetKvid == Guid.Empty && o.BizId == bizId)) throw new Exception($"{bizId}重复结算的对象!");
//}
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
.
BizId
,
bizids
)).
ThrowIfTrue
(
"存在重复结算的对象!"
);
//var allDetails = new List<SettlementDetail>();
//Items.ForEach(o => allDetails.AddRange(o.Details));
//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("存在重复结算的明细项目!");
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
#
region
启用缓存
,
将当前人创建批次数据存入
,
处理完毕或者接口报错后清除
,
确保不会重复创建
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cache
=
KiviiContext
.
GetCacheClient
();
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheKey
=
KiviiContext
.
GetUrnKey
(
$"
{
this
.
GetType
().
FullName
}
_Request_
{
KiviiContext
.
CurrentMember
.
FullName
}
_
{
KiviiContext
.
CurrentMember
.
Kvid
}
"
);
var
cacheValue
=
cache
.
Get
<
List
<
string
>
>(
cacheKey
);
var
cacheValue
=
cache
.
Get
<
int
?
>(
cacheKey
);
if
(
!
cacheValue
.
IsNullOrEmpty
()
)
if
(
cacheValue
!=
null
)
{
{
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
.
Count
}
条,请稍后再试!"
);
if
(
cacheValue
<
0
)
throw
new
Exception
(
$"仍在处理中,请稍后查看结果!"
);
else
throw
new
Exception
(
$"当前正在处理中,剩余
{
cacheValue
}
条,请稍后查看结果!"
);
}
}
var
caches
=
new
List
<
string
>()
;
int
?
caches
=
Items
.
Count
;
caches
.
AddRange
(
Items
.
ConvertAll
(
o
=>
o
.
BizId
));
//caches.AddRange(Items.ConvertAll(o => o.SerialNumber
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
cache
.
Set
(
cacheKey
,
caches
,
TimeSpan
.
FromMinutes
(
5
));
#
endregion
#
endregion
var
rtns
=
new
RestfulCreateResponse
<
Settlement
>();
rtns
.
Results
=
new
List
<
Settlement
>();
#
region
合并数据库连接
,
并启用事务
IDbTransaction
tranE
=
null
,
tranF
=
null
;
//if (connE.ConnectionString == connR.ConnectionString)//现在的连接会自动取缓存
if
(
connE
==
connF
)
{
//两个连接是同一个,缓存生效,不做任何操作
}
else
if
(
connE
.
ConnectionString
==
connF
.
ConnectionString
)
//连接对象不同,但连接字符串是一样的,因为在本环节中,连接没有被污染,可以关了一个连接
{
connE
.
Close
();
connE
=
connF
;
}
if
((
connE
is
LinqConnection
)
&&
(
connE
as
LinqConnection
).
Transaction
==
null
)
{
tranE
=
connE
.
OpenTransaction
();
}
if
((
connF
is
LinqConnection
)
&&
(
connF
as
LinqConnection
).
Transaction
==
null
)
{
tranF
=
connF
.
OpenTransaction
();
}
//#region 合并数据库连接,并启用事务
//IDbTransaction tranE = null, tranF = null;
//if (connE.ConnectionString == connF.ConnectionString)
//{
// connF.Close();
// connF = connE;
// tranE = connE.OpenTransaction();
//}
//else
//{
// tranE = connE.OpenTransaction();
// tranF = connF.OpenTransaction();
//}
#
endregion
try
try
{
{
using
(
KiviiContext
.
Profiler
(
"创建结算"
))
var
connF
=
KiviiContext
.
GetOpenedDbConnection
<
Settlement
>();
//foreach (var bizId in bizids)
//{
// if (connF.Exists<Settlement>(o => o.OffsetKvid == Guid.Empty && o.BizId == bizId)) throw new Exception($"{bizId}重复结算的对象!");
//}
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
.
BizId
,
bizids
)).
ThrowIfTrue
(
"存在重复结算的对象!"
);
//var allDetails = new List<SettlementDetail>();
//Items.ForEach(o => allDetails.AddRange(o.Details));
//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
>();
#
region
合并数据库连接
,
并启用事务
IDbTransaction
tranE
=
null
,
tranF
=
null
;
//if (connE.ConnectionString == connR.ConnectionString)//现在的连接会自动取缓存
if
(
connE
==
connF
)
{
//两个连接是同一个,缓存生效,不做任何操作
}
else
if
(
connE
.
ConnectionString
==
connF
.
ConnectionString
)
//连接对象不同,但连接字符串是一样的,因为在本环节中,连接没有被污染,可以关了一个连接
{
connE
.
Close
();
connE
=
connF
;
}
if
((
connE
is
LinqConnection
)
&&
(
connE
as
LinqConnection
).
Transaction
==
null
)
{
{
foreach
(
var
item
in
Items
)
tranE
=
connE
.
OpenTransaction
();
}
if
((
connF
is
LinqConnection
)
&&
(
connF
as
LinqConnection
).
Transaction
==
null
)
{
tranF
=
connF
.
OpenTransaction
();
}
//#region 合并数据库连接,并启用事务
//IDbTransaction tranE = null, tranF = null;
//if (connE.ConnectionString == connF.ConnectionString)
//{
// connF.Close();
// connF = connE;
// tranE = connE.OpenTransaction();
//}
//else
//{
// tranE = connE.OpenTransaction();
// tranF = connF.OpenTransaction();
//}
#
endregion
try
{
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
;
if
(
settlement
.
OwnerKvid
==
Guid
.
Empty
)
{
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
;
if
(
settlement
.
OwnerKvid
==
Guid
.
Empty
)
{
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
var
existPolicy
=
item
.
Details
.
FirstOrDefault
(
o
=>
o
.
BizType
==
typeof
(
Policy
).
FullName
);
var
existPolicy
=
item
.
Details
.
FirstOrDefault
(
o
=>
o
.
BizType
==
typeof
(
Policy
).
FullName
);
if
(
existPolicy
!=
null
)
if
(
existPolicy
!=
null
)
{
var
policyRecord
=
new
PolicyRecord
();
policyRecord
.
PolicyKvid
=
existPolicy
.
BizKvid
;
policyRecord
.
SettlementKvid
=
settlementKvid
;
policyRecord
.
BizId
=
settlement
.
BizId
;
policyRecord
.
BizKvid
=
settlement
.
BizKvid
;
policyRecord
.
BizType
=
settlement
.
BizType
;
policyRecord
.
TargetKvid
=
settlement
.
PayerKvid
;
policyRecord
.
TargetName
=
settlement
.
PayerName
;
policyRecord
.
AmountPlan
=
item
.
Details
.
Sum
(
o
=>
o
.
AmountPlan
);
policyRecord
.
AmountOrigin
=
item
.
Details
.
Where
(
o
=>
o
.
BizType
!=
typeof
(
Policy
).
FullName
).
Sum
(
o
=>
o
.
Amount
);
policyRecord
.
AmountPolicy
=
Math
.
Abs
(
item
.
Details
.
Where
(
o
=>
o
.
BizType
==
typeof
(
Policy
).
FullName
).
Sum
(
o
=>
o
.
Amount
));
policyRecord
.
Amount
=
item
.
Details
.
Sum
(
o
=>
o
.
Amount
);
policyRecord
.
OperateTime
=
settlement
.
OperateTime
;
policyRecord
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
policyRecord
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
policyRecord
.
Metadata
=
new
Dictionary
<
string
,
string
>();
foreach
(
var
propertyInfo
in
settlement
.
GetType
().
GetProperties
())
{
{
if
(
propertyInfo
.
Name
==
"Metadata"
)
continue
;
var
policyRecord
=
new
PolicyRecord
();
try
policyRecord
.
PolicyKvid
=
existPolicy
.
BizKvid
;
policyRecord
.
SettlementKvid
=
settlementKvid
;
policyRecord
.
BizId
=
settlement
.
BizId
;
policyRecord
.
BizKvid
=
settlement
.
BizKvid
;
policyRecord
.
BizType
=
settlement
.
BizType
;
policyRecord
.
TargetKvid
=
settlement
.
PayerKvid
;
policyRecord
.
TargetName
=
settlement
.
PayerName
;
policyRecord
.
AmountPlan
=
item
.
Details
.
Sum
(
o
=>
o
.
AmountPlan
);
policyRecord
.
AmountOrigin
=
item
.
Details
.
Where
(
o
=>
o
.
BizType
!=
typeof
(
Policy
).
FullName
).
Sum
(
o
=>
o
.
Amount
);
policyRecord
.
AmountPolicy
=
Math
.
Abs
(
item
.
Details
.
Where
(
o
=>
o
.
BizType
==
typeof
(
Policy
).
FullName
).
Sum
(
o
=>
o
.
Amount
));
policyRecord
.
Amount
=
item
.
Details
.
Sum
(
o
=>
o
.
Amount
);
policyRecord
.
OperateTime
=
settlement
.
OperateTime
;
policyRecord
.
OperatorKvid
=
KiviiContext
.
CurrentMember
.
Kvid
;
policyRecord
.
OperatorName
=
KiviiContext
.
CurrentMember
.
FullName
;
policyRecord
.
Metadata
=
new
Dictionary
<
string
,
string
>();
foreach
(
var
propertyInfo
in
settlement
.
GetType
().
GetProperties
())
{
{
var
value
=
propertyInfo
.
GetValue
(
item
);
if
(
propertyInfo
.
Name
==
"Metadata"
)
continue
;
policyRecord
.
Metadata
[
propertyInfo
.
Name
]
=
value
==
null
?
string
.
Empty
:
value
.
ToString
();
try
{
var
value
=
propertyInfo
.
GetValue
(
item
);
policyRecord
.
Metadata
[
propertyInfo
.
Name
]
=
value
==
null
?
string
.
Empty
:
value
.
ToString
();
}
catch
{
continue
;
}
}
}
c
atch
{
continue
;
}
c
onnF
.
Insert
(
policyRecord
);
}
}
connF
.
Insert
(
policyRecord
);
caches
--;
cache
.
Replace
(
cacheKey
,
caches
);
}
}
caches
.
Remove
(
item
.
BizId
);
cache
.
Replace
(
cacheKey
,
caches
);
}
}
tranE
?.
Commit
();
tranF
?.
Commit
();
cache
.
Remove
(
cacheKey
);
}
}
tranE
?.
Commit
();
catch
(
Exception
ex
)
tranF
?.
Commit
();
{
cache
.
Remove
(
cacheKey
);
tranE
?.
Rollback
();
tranF
?.
Rollback
();
cache
.
Remove
(
cacheKey
);
throw
ex
;
}
return
rtns
;
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
{
{
tranE
?.
Rollback
();
tranF
?.
Rollback
();
cache
.
Remove
(
cacheKey
);
cache
.
Remove
(
cacheKey
);
throw
ex
;
throw
ex
;
}
}
return
rtns
;
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment