Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5_fork
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eteri
erp5_fork
Commits
88f60f5c
Commit
88f60f5c
authored
Apr 26, 2022
by
Xiaowu Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_accounting: round also asset price
parent
11077f97
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
80 additions
and
61 deletions
+80
-61
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_roundDebitCredit.py
...erp5_accounting/AccountingTransaction_roundDebitCredit.py
+80
-61
No files found.
bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_roundDebitCredit.py
View file @
88f60f5c
""" Rounds debit and credit lines on generated transactions, according to
precision of this transaction's resource.
precision of this transaction's resource.
What is expected with this script:
...
...
@@ -9,21 +9,9 @@ What is expected with this script:
- In reality we probably also want that amount on vat line match invoice vat
amount, but we have ignored this.
"""
precision
=
context
.
getQuantityPrecisionFromResource
(
context
.
getResource
())
resource
=
context
.
getResourceValue
()
line
=
None
total_quantity
=
0.0
line_list
=
context
.
getMovementList
(
portal_type
=
context
.
getPortalAccountingMovementTypeList
())
for
line
in
line_list
:
line_quantity
=
round
(
line
.
getQuantity
(),
precision
)
line
.
setQuantity
(
line_quantity
)
total_quantity
+=
line_quantity
# If no "line" found (eg no SIT line), then do nothing. This is in the case where a SIT
# has only Invoice Line and no SIT Line. Otherwise account_type_dict will be empty =>
# asset_line = None => the assert below will fail because getTotalPrice() will returns the
...
...
@@ -31,28 +19,26 @@ for line in line_list:
if
not
line_list
:
return
abs_total_quantity
=
abs
(
round
(
total_quantity
,
precision
))
# The total quantity should be zero with a little error, if simulation has been
# completely applied, because the debit and the credit must be balanced. However,
# this is not the case, if the delivery is divergent, as the builder does not
# adopt prevision automatically, when a conflict happens between the simulation
# and user-entered values.
if
abs_total_quantity
>
2
*
resource
.
getBaseUnitQuantity
():
return
total_price
=
round
(
context
.
getTotalPrice
(),
precision
)
account_type_dict
=
{}
source_exchange_ratio
=
None
destination_exchange_ratio
=
None
for
line
in
line_list
:
if
not
destination_exchange_ratio
and
line
.
getDestinationTotalAssetPrice
():
destination_exchange_ratio
=
line
.
getDestinationTotalAssetPrice
()
/
line
.
getQuantity
()
if
not
source_exchange_ratio
and
line
.
getSourceTotalAssetPrice
():
source_exchange_ratio
=
line
.
getSourceTotalAssetPrice
()
/
line
.
getQuantity
()
for
account
in
(
line
.
getSourceValue
(
portal_type
=
'Account'
),
line
.
getDestinationValue
(
portal_type
=
'Account'
),):
account_type_dict
.
setdefault
(
line
,
set
()).
add
(
account
is
not
None
and
account
.
getAccountTypeValue
()
or
None
)
# find asset line which will be used later
account_type
=
context
.
getPortalObject
().
portal_categories
.
account_type
receivable_type
=
account_type
.
asset
.
receivable
payable_type
=
account_type
.
liability
.
payable
line_to_adjust
=
None
asset_line
=
None
for
line
,
account_type_list
in
account_type_dict
.
iteritems
():
...
...
@@ -62,41 +48,74 @@ for line, account_type_list in account_type_dict.iteritems():
asset_line
=
line
break
if
not
asset_line
:
assert
total_price
==
0.0
and
total_quantity
==
0.0
,
\
'receivable or payable line not found.'
return
def
roundLine
(
resource
,
get_method
,
set_method
,
exchange_ratio
):
precision
=
context
.
getQuantityPrecisionFromResource
(
resource
)
total_quantity
=
0.0
for
line
in
line_list
:
line_quantity
=
round
(
getattr
(
line
,
get_method
)(),
precision
)
getattr
(
line
,
set_method
)(
line_quantity
)
total_quantity
+=
line_quantity
abs_total_quantity
=
abs
(
round
(
total_quantity
,
precision
))
# The total quantity should be zero with a little error, if simulation has been
# completely applied, because the debit and the credit must be balanced. However,
# this is not the case, if the delivery is divergent, as the builder does not
# adopt prevision automatically, when a conflict happens between the simulation
# and user-entered values.
if
abs_total_quantity
>
2
*
context
.
restrictedTraverse
(
resource
).
getBaseUnitQuantity
():
return
total_price
=
round
(
context
.
getTotalPrice
()
*
exchange_ratio
,
precision
)
if
not
asset_line
:
assert
total_price
==
0.0
and
total_quantity
==
0.0
,
\
'receivable or payable line not found.'
return
# If we have a difference between total credit and total debit, one line is
# chosen to add or remove this difference. The payable or receivable is chosen
# only if this line is not matching with invoice total price, because total price
# comes from all invoice lines (quantity * price) and it is what should be payed.
# And payable or receivable line is the record in the accounting of what has
# to be payed. Then, we must not touch it when it already matches.
# If is not a payable or receivable, vat or other line (ie. income) is used.
line_to_adjust
=
None
if
abs_total_quantity
!=
0
:
if
round
(
abs
(
getattr
(
asset_line
,
get_method
)()),
precision
)
!=
round
(
abs
(
context
.
getTotalPrice
())
*
exchange_ratio
,
precision
):
# adjust payable or receivable
for
line
in
line_list
:
if
receivable_type
in
account_type_dict
[
line
]
or
\
payable_type
in
account_type_dict
[
line
]:
line_to_adjust
=
line
break
if
line_to_adjust
is
None
:
# VAT
for
line
in
line_list
:
if
receivable_type
.
refundable_vat
in
account_type_dict
[
line
]
or
\
payable_type
.
collected_vat
in
account_type_dict
[
line
]:
line_to_adjust
=
line
break
if
line_to_adjust
is
None
:
# adjust anything except payable or receivable
for
line
in
line_list
:
if
receivable_type
not
in
account_type_dict
[
line
]
and
\
payable_type
not
in
account_type_dict
[
line
]:
line_to_adjust
=
line
break
if
line_to_adjust
is
not
None
:
getattr
(
line_to_adjust
,
set_method
)(
round
(
getattr
(
line_to_adjust
,
get_method
)()
-
total_quantity
,
precision
))
# If we have a difference between total credit and total debit, one line is
# chosen to add or remove this difference. The payable or receivable is chosen
# only if this line is not matching with invoice total price, because total price
# comes from all invoice lines (quantity * price) and it is what should be payed.
# And payable or receivable line is the record in the accounting of what has
# to be payed. Then, we must not touch it when it already matches.
# If is not a payable or receivable, vat or other line (ie. income) is used.
if
abs_total_quantity
!=
0
:
if
round
(
abs
(
asset_line
.
getQuantity
()),
precision
)
!=
round
(
abs
(
context
.
getTotalPrice
()),
precision
):
# adjust payable or receivable
for
line
in
line_list
:
if
receivable_type
in
account_type_dict
[
line
]
or
\
payable_type
in
account_type_dict
[
line
]:
line_to_adjust
=
line
break
if
line_to_adjust
is
None
:
# VAT
for
line
in
line_list
:
if
receivable_type
.
refundable_vat
in
account_type_dict
[
line
]
or
\
payable_type
.
collected_vat
in
account_type_dict
[
line
]:
line_to_adjust
=
line
break
if
line_to_adjust
is
None
:
# adjust anything except payable or receivable
for
line
in
line_list
:
if
receivable_type
not
in
account_type_dict
[
line
]
and
\
payable_type
not
in
account_type_dict
[
line
]:
line_to_adjust
=
line
break
if
line_to_adjust
is
not
None
:
line_to_adjust
.
setQuantity
(
round
(
line_to_adjust
.
getQuantity
()
-
total_quantity
,
precision
))
resource
=
context
.
getResource
()
# Round Debit/credit
roundLine
(
resource
,
'getQuantity'
,
'setQuantity'
,
1
)
# Round source asset price
if
source_exchange_ratio
:
source_section_price_currency
=
context
.
getSourceSectionValue
().
getPriceCurrency
()
roundLine
(
source_section_price_currency
,
'getSourceTotalAssetPrice'
,
'setSourceTotalAssetPrice'
,
source_exchange_ratio
)
# Round destination asset price
if
destination_exchange_ratio
:
destination_section_price_currency
=
context
.
getDestinationSectionValue
().
getPriceCurrency
()
roundLine
(
destination_section_price_currency
,
'getDestinationTotalAssetPrice'
,
'setDestinationTotalAssetPrice'
,
destination_exchange_ratio
)
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