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
249172c7
Commit
249172c7
authored
Jan 17, 2022
by
陶然
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新增导入发票功能
parent
65f88acb
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
167 additions
and
10 deletions
+167
-10
Invoice.cs
Src/Entities/Invoice.cs
+2
-0
RestfulInvoice.cs
Src/Transforms/RestfulInvoice.cs
+160
-0
RestfulInvoiceApply.Apply.cs
Src/Transforms/RestfulInvoiceApply.Apply.cs
+5
-10
No files found.
Src/Entities/Invoice.cs
View file @
249172c7
...
...
@@ -253,5 +253,7 @@ namespace Kivii.Finances.Entities
#
endregion
[
Ignore
]
public
List
<
InvoiceDetail
>
Details
{
get
;
set
;
}
}
}
Src/Transforms/RestfulInvoice.cs
View file @
249172c7
...
...
@@ -91,4 +91,164 @@ namespace Kivii.Finances.Transforms
[
RequiresAnyRole
(
SystemRoles
.
Everyone
)]
public
class
InvoiceRead
:
RestfulRead
<
Invoice
>
{
}
[
Api
(
Description
=
"插入发票"
)]
[
RequiresAnyRole
(
SystemRoles
.
Everyone
)]
public
class
InvoiceAccept
:
RestfulExecution
<
Invoice
>
{
public
List
<
Invoice
>
Items
{
get
;
set
;
}
public
List
<
Payment
>
Payments
{
get
;
set
;
}
public
override
object
OnExecution
(
IRequest
req
,
IResponse
res
)
{
Items
.
ThrowIfNullOrEmpty
(
"开票结果内容不能为空!"
);
foreach
(
var
item
in
Items
)
{
(
item
.
OperateTime
==
DateTime
.
MinValue
||
item
.
OperateTime
==
DateTime
.
MaxValue
).
ThrowIfTrue
(
"缺少开票日期信息!"
);
item
.
SerialCode
.
ThrowIfNullOrEmpty
(
"缺少发票代码信息!"
);
item
.
SerialNumber
.
ThrowIfNullOrEmpty
(
"缺少发票号码信息!"
);
item
.
Type
.
ThrowIfNullOrEmpty
(
"缺少发票类型信息!"
);
(
item
.
TaxRate
<
0
||
item
.
TaxRate
>
1
).
ThrowIfTrue
(
"缺少发票税率信息!"
);
(
item
.
Amount
==
0
).
ThrowIfTrue
(
"缺少发票金额信息!"
);
item
.
Details
.
ThrowIfNullOrEmpty
(
"缺少发票明细信息!"
);
(
item
.
Amount
!=
item
.
Details
.
Sum
(
o
=>
o
.
Amount
)).
ThrowIfTrue
(
"明细金额和传入发票金额不一致!"
);
}
if
(!
Payments
.
IsNullOrEmpty
())
{
(
Payments
.
Exists
(
o
=>
o
.
Kvid
==
Guid
.
Empty
)).
ThrowIfTrue
(
"不存在的到账信息!"
);
(
Payments
.
Exists
(
o
=>
o
.
Amount
<=
0
)).
ThrowIfTrue
(
"未指定到账开票金额!"
);
(
Payments
.
Sum
(
o
=>
o
.
Amount
)
!=
Items
.
Sum
(
o
=>
o
.
Amount
)).
ThrowIfTrue
(
"到账开票金额和发票金额不一致!"
);
}
var
conn
=
KiviiContext
.
GetOpenedDbConnection
<
Invoice
>();
(
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
.
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
(
"指定的到账开票金额和发票金额不一致!"
);
}
foreach
(
var
info
in
Items
)
{
#
region
开票成功的情况处理
var
category
=
preCorrelatingPayments
.
IsNullOrEmpty
()
?
InvoiceApplyType
.
Debit
:
InvoiceApplyType
.
Payment
;
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
;
invoice
.
Currency
=
CurrencyUnit
.
CNY
;
invoice
.
Type
=
info
.
Type
;
invoice
.
Category
=
category
.
ToString
();
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
>();
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
.
QuantityUnitPriceUntaxed
=
Math
.
Round
(
detail
.
AmountUntaxed
/
detail
.
Quantity
,
2
);
insertInvoiceDetails
.
Add
(
detail
);
}
#
endregion
}
if
(!
preCorrelatingPayments
.
IsNullOrEmpty
())
{
var
correlatedInvoices
=
insertInvoices
.
Correlating
(
preCorrelatingPayments
);
insertInvoices
.
AddRange
(
correlatedInvoices
);
var
currentRootKvids
=
preCorrelatingPayments
.
Where
(
o
=>
o
.
Type
==
PaymentType
.
Split
).
ToList
().
ConvertAll
(
p
=>
p
.
RootKvid
);
if
(!
currentRootKvids
.
IsNullOrEmpty
())
parentPayments
=
conn
.
Select
<
Payment
>(
o
=>
o
.
OffsetKvid
==
Guid
.
Empty
&&
Sql
.
In
(
o
.
Kvid
,
currentRootKvids
));
}
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
);
}
}
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
();
return
rtns
;
}
catch
(
Exception
ex
)
{
trans
.
Rollback
();
throw
ex
;
}
}
}
}
Src/Transforms/RestfulInvoiceApply.Apply.cs
View file @
249172c7
...
...
@@ -533,18 +533,13 @@ namespace Kivii.Finances.Transforms
if
(
OperatorKvid
!=
Guid
.
Empty
)
query
.
And
(
o
=>
o
.
OperatorKvid
==
OperatorKvid
);
else
if
(
OwnerKvid
!=
Guid
.
Empty
)
query
.
And
(
o
=>
o
.
OwnerKvid
==
OwnerKvid
);
else
if
(
OrganizationKvid
!=
Guid
.
Empty
)
query
.
And
(
o
=>
o
.
OrganizationKvid
==
OrganizationKvid
);
var
apply
=
conn
.
Single
(
query
);
var
apply
s
=
conn
.
Select
(
query
);
var
rtns
=
new
RestfulQueryResponse
<
InvoiceApply
>();
rtns
.
Results
=
new
List
<
InvoiceApply
>();
if
(
apply
==
null
)
return
rtns
;
apply
.
Status
=
(
int
)
InvoiceApplyStatus
.
AutoExecuting
;
apply
.
AddOnlyProperties
(
o
=>
o
.
Status
);
conn
.
UpdateOnly
(
apply
);
apply
.
RemoveAllOnlyProperties
();
rtns
.
Results
.
Add
(
apply
);
if
(
applys
==
null
)
return
rtns
;
rtns
.
Results
.
AddRange
(
applys
);
rtns
.
Total
=
rtns
.
Results
.
Count
;
return
rtns
;
...
...
@@ -664,7 +659,7 @@ namespace Kivii.Finances.Transforms
invoice
.
OperateTime
=
time
;
invoice
.
SerialCode
=
code
;
invoice
.
SerialNumber
=
number
;
invoice
.
Status
=
1
;
//
invoice.Status = 1;
invoice
.
Amount
=
currentDetails
.
Sum
(
o
=>
o
.
Amount
);
invoice
.
AmountTax
=
currentDetails
.
Sum
(
o
=>
o
.
AmountTax
);
invoice
.
AmountUntaxed
=
currentDetails
.
Sum
(
o
=>
o
.
AmountUntaxed
);
...
...
@@ -855,7 +850,7 @@ namespace Kivii.Finances.Transforms
invoice
.
OperateTime
=
time
;
invoice
.
SerialCode
=
code
;
invoice
.
SerialNumber
=
number
;
invoice
.
Status
=
1
;
//
invoice.Status = 1;
invoice
.
Amount
=
currentAmount
;
invoice
.
AmountUntaxed
=
Math
.
Round
(
currentAmount
/
(
1
+
taxRate
),
2
);
invoice
.
AmountTax
=
currentAmount
-
invoice
.
AmountUntaxed
;
...
...
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