Commit 7bdd936e authored by Jérome Perrin's avatar Jérome Perrin

Simplify workflow scripts, as validation is mostly done using constraints.

We still use workflow scripts for "transiant validation" : for example, validating that at the time we validate this transaction an accounting period is open, other parties are not invalidated.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@18382 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 626f45ac
......@@ -76,95 +76,90 @@ from Products.ERP5Type.Message import Message\n
transaction = state_change[\'object\']\n
N_ = lambda msg, **kw: Message(\'erp5_ui\', msg, **kw)\n
\n
# do we have to check transaction is in openned periods ? \n
# XXX manually default start date to stop date\n
if not transaction.getStartDate() and transaction.getStopDate():\n
transaction.setStartDate(transaction.getStopDate())\n
\n
# Check constraints\n
transaction.Base_checkConsistency()\n
\n
# Check that the transaction is in an open accounting period when we validate\n
# it.\n
skip_period_validation = state_change[\'kwargs\'].get(\n
\'skip_period_validation\', 0)\n
transition = state_change[\'transition\']\n
if transition.id in (\'plan_action\', \'confirm_action\') :\n
skip_period_validation = 1\n
\n
# Get sections and a currency.\n
source_section = transaction.getSourceSectionValue(\n
portal_type=[\'Organisation\', \'Person\'])\n
if source_section is None:\n
raise ValidationFailed(N_(\'Source Section is not Defined.\'))\n
\n
destination_section = transaction.getDestinationSectionValue(\n
portal_type=[\'Organisation\', \'Person\'])\n
# if it\'s not an invoice, then we can validate without destination\n
if destination_section is None and \\\n
transaction.getPortalType() in transaction.getPortalInvoiceTypeList():\n
raise ValidationFailed(N_(\'Destination Section is not Defined.\'))\n
portal_type=[\'Organisation\', \'Person\'])\n
\n
currency = transaction.getResource(portal_type = \'Currency\')\n
if not currency :\n
raise ValidationFailed(N_(\'Currency is not Defined.\'))\n
if source_section is None and destination_section is None:\n
raise ValidationFailed(N_(\'At Least One Section Must be Defined\'))\n
\n
# XXX manually default start date to stop date\n
if not transaction.getStartDate() and transaction.getStopDate():\n
transaction.setStartDate(transaction.getStopDate())\n
# check that no categories are used for section\n
if transaction.getSourceSectionValue(portal_type=\'Category\') is not None or\\\n
transaction.getDestinationSectionValue(portal_type=\'Category\') is not None:\n
raise ValidationFailed(N_(\'Using Category for Section is Invalid\'))\n
\n
\n
transaction_line_list = transaction.getMovementList(\n
portal_type=transaction.getPortalAccountingMovementTypeList())\n
if not transaction.getStartDate() :\n
raise ValidationFailed(N_(\'Date is not Defined\'))\n
else:\n
if not skip_period_validation :\n
# check the date is in an opened period\n
if source_section is not None:\n
# if we don\'t have any accounts on this side, we don\'t enforce date\n
# checks\n
valid_date = False\n
no_accounts = True\n
for line in transaction_line_list:\n
if line.getSource():\n
no_accounts = False\n
if no_accounts:\n
valid_date = True\n
transaction_date = transaction.getStartDate().earliestTime()\n
openned_accounting_period_list = source_section.searchFolder(\n
portal_type="Accounting Period",\n
# planned is for b/w compatibility\n
simulation_state=(\'planned\', \'started\'))\n
if not len(source_section.contentValues(\n
filter=dict(portal_type="Accounting Period"))):\n
# if the entity doesn\'t have any accounting period, we can\n
# consider that they do not want to use accounting periods or\n
# we do not account from their side.\n
valid_date = True\n
for apd in openned_accounting_period_list:\n
apd = apd.getObject()\n
if apd.getStartDate().Date() <= transaction_date.Date() <= apd.getStopDate().Date():\n
valid_date = True\n
if not valid_date:\n
raise ValidationFailed(N_("Date is not in an opened Accounting Period "\n
"for source section"))\n
# do the same for destination section \n
if destination_section is not None:\n
# if we don\'t have any accounts on this side, we don\'t enforce date\n
# checks\n
valid_date = False\n
no_accounts = True\n
for line in transaction_line_list:\n
if line.getDestination():\n
no_accounts = False\n
if no_accounts:\n
\n
if not skip_period_validation :\n
# check the date is in an opened period\n
if source_section is not None:\n
# if we don\'t have any accounts on this side, we don\'t enforce date checks\n
valid_date = False\n
no_accounts = True\n
for line in transaction_line_list:\n
if line.getSource():\n
no_accounts = False\n
if no_accounts:\n
valid_date = True\n
transaction_date = transaction.getStartDate().earliestTime()\n
openned_accounting_period_list = source_section.searchFolder(\n
portal_type="Accounting Period",\n
# planned is for b/w compatibility\n
simulation_state=(\'planned\', \'started\'))\n
if not len(source_section.contentValues(\n
filter=dict(portal_type="Accounting Period"))):\n
# if the entity doesn\'t have any accounting period, we can\n
# consider that they do not want to use accounting periods or\n
# we do not account from their side.\n
valid_date = True\n
for apd in openned_accounting_period_list:\n
apd = apd.getObject()\n
if apd.getStartDate().Date() <= transaction_date.Date() <= apd.getStopDate().Date():\n
valid_date = True\n
transaction_date = transaction.getStopDate().earliestTime()\n
openned_accounting_period_list = destination_section.searchFolder(\n
portal_type = "Accounting Period",\n
simulation_state=(\'planned\', \'started\'))\n
if not len(destination_section.contentValues(\n
filter=dict(portal_type="Accounting Period"))):\n
if not valid_date:\n
raise ValidationFailed(N_("Date is not in an opened Accounting Period "\n
"for source section"))\n
# do the same for destination section \n
if destination_section is not None:\n
# if we don\'t have any accounts on this side, we don\'t enforce date checks\n
valid_date = False\n
no_accounts = True\n
for line in transaction_line_list:\n
if line.getDestination():\n
no_accounts = False\n
if no_accounts:\n
valid_date = True\n
transaction_date = transaction.getStopDate().earliestTime()\n
openned_accounting_period_list = destination_section.searchFolder(\n
portal_type = "Accounting Period",\n
simulation_state=(\'planned\', \'started\'))\n
if not len(destination_section.contentValues(\n
filter=dict(portal_type="Accounting Period"))):\n
valid_date = True\n
for apd in openned_accounting_period_list:\n
apd = apd.getObject()\n
if apd.getStartDate().Date() <= transaction_date.Date() <= apd.getStopDate().Date():\n
valid_date = True\n
for apd in openned_accounting_period_list:\n
apd = apd.getObject()\n
if apd.getStartDate().Date() <= transaction_date.Date() <= apd.getStopDate().Date():\n
valid_date = True\n
if not valid_date:\n
raise ValidationFailed(N_("Date is not in an opened Accounting Period "\n
"for destination section"))\n
if not valid_date:\n
raise ValidationFailed(N_("Date is not in an opened Accounting Period "\n
"for destination section"))\n
]]></string> </value>
......@@ -239,9 +234,8 @@ else:\n
<string>skip_period_validation</string>
<string>transition</string>
<string>source_section</string>
<string>None</string>
<string>destination_section</string>
<string>currency</string>
<string>None</string>
<string>transaction_line_list</string>
<string>False</string>
<string>valid_date</string>
......
......@@ -71,176 +71,66 @@
from Products.DCWorkflow.DCWorkflow import ValidationFailed\n
from Products.ERP5Type.Message import Message\n
\n
SOURCE, DESTINATION = (\'source\', \'destination\')\n
transaction = state_change[\'object\']\n
portal = transaction.getPortalObject()\n
valid_section_portal_type_list = [\'Person\', \'Organisation\']\n
bank_account_portal_type = portal.getPortalPaymentNodeTypeList()\n
section_portal_type_list = [\'Person\', \'Organisation\']\n
invalid_state_list = [\'invalidated\', \'deleted\']\n
\n
N_ = lambda msg, **kw: Message(\'erp5_ui\', msg, **kw)\n
\n
# first of all, validate the transaction itself\n
container.validateTransaction(state_change)\n
\n
# Get sections.\n
source_section = transaction.getSourceSectionValue(\n
portal_type=valid_section_portal_type_list)\n
destination_section = transaction.getDestinationSectionValue(\n
portal_type=valid_section_portal_type_list)\n
\n
# do we want to check validity for destination as well?\n
check_for_destination = 0\n
if source_section is not None and destination_section is not None:\n
source_section_group = source_section.getGroup(\'\').lstrip(\'group/\').split(\'/\')\n
destination_section_group = destination_section\\\n
.getGroup(\'\').lstrip(\'group/\').split(\'/\')\n
if destination_section_group and source_section_group and \\\n
destination_section_group[0] == source_section_group[0] \\\n
and destination_section.getPortalType() != \'Person\':\n
check_for_destination = 1\n
\n
source_sum = 0\n
destination_sum = 0\n
# Check that all lines uses open accounts, and doesn\'t use invalid third\n
# parties or bank accounts\n
for line in transaction.contentValues(filter=dict(\n
portal_type=transaction.getPortalAccountingMovementTypeList())):\n
\n
# Check transaction lines\n
if transaction.getPortalType() not in (\'Balance Transaction\',) :\n
accounting_transaction_line_list = transaction.contentValues(\n
filter={ \'portal_type\':\n
transaction.getPortalAccountingMovementTypeList()})\n
for transaction_line in accounting_transaction_line_list:\n
# XXX would source_section != destination_section work here ?\n
if source_section is not None and destination_section is not None and\\\n
source_section.getUid() != destination_section.getUid():\n
source_quantity = transaction_line\\\n
.getSourceInventoriatedTotalAssetPrice() or 0\n
destination_quantity = transaction_line\\\n
.getDestinationInventoriatedTotalAssetPrice() or 0\n
else:\n
destination_quantity = source_quantity = ((transaction_line\\\n
.getSourceInventoriatedTotalAssetPrice() or 0) + \\\n
(transaction_line.getDestinationInventoriatedTotalAssetPrice() or 0))\n
for account, third_party, bank_account in (\n
( line.getSourceValue(portal_type=\'Account\'),\n
line.getSourcePaymentValue(portal_type=bank_account_portal_type),\n
line.getDestinationSectionValue(portal_type=section_portal_type_list),),\n
( line.getDestinationValue(portal_type=\'Account\'),\n
line.getDestinationPaymentValue(portal_type=bank_account_portal_type),\n
line.getSourceSectionValue(portal_type=section_portal_type_list),), ):\n
\n
source_sum += source_quantity\n
destination_sum += destination_quantity\n
\n
if transaction_line.getSource( portal_type = \'Account\') is None and \\\n
transaction_line.getDestination(portal_type = \'Account\') is None and \\\n
transaction_line.getQuantity() != 0:\n
if account is not None and account.getValidationState() != \'validated\':\n
raise ValidationFailed, N_(\n
"Action failed: no account defined for line \'${line_id}\'.",\n
mapping = {\'line_id\': transaction_line.getId()} )\n
\n
for side in (SOURCE, DESTINATION) :\n
if side == SOURCE:\n
account = transaction_line.getSourceValue(portal_type=\'Account\')\n
payment = transaction_line.getSourcePaymentValue(\n
portal_type=portal.getPortalPaymentNodeTypeList())\n
third_party = transaction_line.getDestinationSectionValue(\n
portal_type=valid_section_portal_type_list)\n
else:\n
account = transaction_line.getDestinationValue(portal_type=\'Account\')\n
payment = transaction_line.getDestinationPaymentValue(\n
portal_type=portal.getPortalPaymentNodeTypeList())\n
third_party = transaction_line.getSourceSectionValue(\n
portal_type=valid_section_portal_type_list)\n
\n
if account is None:\n
continue\n
\n
if account.getValidationState() != \'validated\':\n
raise ValidationFailed, N_(\n
"Action failed: account \'${account_title}\' is not opened.",\n
mapping = {\'account_title\':\n
unicode(account.getTranslatedTitle(), \'utf8\')})\n
\n
# Test third party related-data\n
if account.getAccountTypeId() in ("receivable", "payable"):\n
# Test existence\n
if third_party is None:\n
raise ValidationFailed, N_(\n
"Action failed: no third party defined for line \'${line}\'.",\n
mapping = {\'line\': transaction_line.getId()} )\n
if third_party is not None and third_party.getPortalType() \\\n
in [\'Person\', \'Organisation\']:\n
# Test state :(\n
if third_party.getValidationState() != \'validated\':\n
raise ValidationFailed, N_(\n
"Action failed: third party \'${third_party_name}\' is not "\n
"validated.",\n
mapping = {\'third_party_name\':\n
unicode(third_party.getTranslatedTitle(), \'utf8\')} )\n
# Test region\n
# Note: This test is normally handle by the entity workflow which\n
# don\'t allow validation of entity until region is set. So if the\n
# previous condition is not verified, the previous test catch it. We\n
# add this redundent test for easy upgrade of previous ERP5\n
# accounting system.\n
if not third_party.getRegion():\n
raise ValidationFailed, N_(\n
"Action failed: third party \'${third_party_name}\' has no "\n
"region.",\n
mapping = {\'third_party_name\':\n
unicode(third_party.getTranslatedTitle(), \'utf8\')})\n
\n
if (side == SOURCE) and account.isMemberOf(\n
"account_type/asset/cash/bank"):\n
# XXX we must check for source only if we are intersted in the\n
# accounting for source. Today, payment transaction cannot be validated\n
# if they do not have a source, so this check is not needed yet.\n
if payment is None:\n
raise ValidationFailed, N_(\n
"Action failed: no source bank account defined for line \'${line}\'.",\n
mapping = {\'line\': transaction_line.getId()} )\n
else:\n
bank_account_currency = payment.getProperty(\'price_currency\')\n
if bank_account_currency is not None and \\\n
bank_account_currency != transaction_line.getResource():\n
raise ValidationFailed, N_(\n
"Action failed: source bank account for line \'${line}\' "\\\n
"uses ${bank_account_currency} as default currency.",\n
mapping = { \'line\' : transaction_line.getId(),\n
\'bank_account_currency\':\n
unicode(payment.getPriceCurrencyReference(), \'utf8\')})\n
"Account ${account_title} is not opened",\n
mapping=dict(account_title=unicode(\n
account.Account_getFormattedTitle(), \'utf8\')))\n
\n
if (side == DESTINATION) and account.isMemberOf(\n
"account_type/asset/cash/bank"):\n
# we check account for destination section only if we are interested in\n
# the accounting for this entity.\n
if not check_for_destination:\n
continue\n
if payment is None:\n
raise ValidationFailed, N_(\n
"Action failed: no destination bank account defined for"\n
" line \'${line}\'.",\n
mapping = {\'line\': transaction_line.getId()} )\n
else:\n
bank_account_currency = payment.getProperty(\'price_currency\')\n
if bank_account_currency is not None and \\\n
bank_account_currency != transaction_line.getResource():\n
raise ValidationFailed, N_(\n
"Action failed: bank account for line \'${line}\' "\\\n
"uses ${bank_account_currency} as default currency.",\n
mapping = { \'line\' : transaction_line.getId(),\n
\'bank_account_currency\':\n
unicode(payment.getPriceCurrencyReference(), \'utf8\')})\n
\n
source_precision = destination_precision = 2\n
if source_section is not None and\\\n
source_section.getPortalType() == \'Organisation\':\n
source_currency = source_section.getPriceCurrencyValue()\n
if source_currency is not None:\n
source_precision = source_currency.getQuantityPrecision()\n
if round(source_sum, source_precision) != 0:\n
raise ValidationFailed, N_(\n
\'Action failed: transaction is not balanced for source section.\')\n
if third_party is not None and\\\n
third_party.getValidationState() in invalid_state_list:\n
raise ValidationFailed, N_(\n
"Third Party ${third_party_name} is invalid",\n
mapping=dict(third_party_name=unicode(\n
third_party.getTitle(), \'utf8\')))\n
\n
if bank_account is not None and\\\n
bank_account.getValidationState() in invalid_state_list:\n
raise ValidationFailed, N_(\n
"Bank Account ${bank_account_reference} is invalid",\n
mapping=dict(bank_account_reference=unicode(\n
bank_account.getReference(), \'utf8\')))\n
\n
if destination_section is not None and\\\n
destination_section.getPortalType() == \'Organisation\':\n
destination_currency = destination_section.getPriceCurrencyValue()\n
if destination_currency is not None:\n
destination_precision = destination_currency.getQuantityPrecision()\n
if round(destination_sum, destination_precision) != 0:\n
raise ValidationFailed, N_(\n
\'Action failed: transaction is not balanced for destination section.\')\n
if account is not None:\n
# also check that currencies are consistent if we use this quantity for\n
# accounting.\n
bank_account_currency = bank_account.getProperty(\'price_currency\')\n
if bank_account_currency is not None and \\\n
bank_account_currency != transaction_line.getResource():\n
raise ValidationFailed, N_(\n
"Bank Account ${bank_account_reference} "\n
"uses ${bank_account_currency} as default currency",\n
mapping=dict(\n
bank_account_reference=unicode(\n
bank_account.getReference(), \'utf8\'),\n
bank_account_currency=unicode(\n
bank_account.getPriceCurrencyReference(), \'utf8\')))\n
\n
# Delete empty lines\n
transaction.AccountingTransaction_deleteEmptyLines(redirect=0)\n
</string> </value>
</item>
......@@ -307,40 +197,25 @@ transaction.AccountingTransaction_deleteEmptyLines(redirect=0)\n
<string>ValidationFailed</string>
<string>Products.ERP5Type.Message</string>
<string>Message</string>
<string>_getiter_</string>
<string>SOURCE</string>
<string>DESTINATION</string>
<string>_getitem_</string>
<string>transaction</string>
<string>_getattr_</string>
<string>portal</string>
<string>valid_section_portal_type_list</string>
<string>bank_account_portal_type</string>
<string>section_portal_type_list</string>
<string>invalid_state_list</string>
<string>N_</string>
<string>container</string>
<string>source_section</string>
<string>destination_section</string>
<string>check_for_destination</string>
<string>None</string>
<string>source_section_group</string>
<string>destination_section_group</string>
<string>source_sum</string>
<string>destination_sum</string>
<string>accounting_transaction_line_list</string>
<string>transaction_line</string>
<string>source_quantity</string>
<string>destination_quantity</string>
<string>_inplacevar_</string>
<string>side</string>
<string>_getiter_</string>
<string>dict</string>
<string>line</string>
<string>account</string>
<string>payment</string>
<string>third_party</string>
<string>bank_account</string>
<string>None</string>
<string>unicode</string>
<string>bank_account_currency</string>
<string>source_precision</string>
<string>destination_precision</string>
<string>source_currency</string>
<string>round</string>
<string>destination_currency</string>
<string>transaction_line</string>
</tuple>
</value>
</item>
......
526
\ No newline at end of file
531
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment