Commit 7f79b8a7 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_accounting: Implement Entity_createDepositPaymentTransaction

  Reimplement Entity_addDeposity by creating deposit from a list of subscription

  Ensure will transfer deposit to the proper organisation/person, ledger
  and currency.

  Payment Transaction must preserve website context otherwise it will
  fail over redirections later on.
parent 5ce08b4f
...@@ -7,9 +7,52 @@ from Products.ERP5Type.Message import translateString ...@@ -7,9 +7,52 @@ from Products.ERP5Type.Message import translateString
portal = context.getPortalObject() portal = context.getPortalObject()
if not subscription_list:
raise ValueError('You need to provide at least one Invoice transaction')
payment_tag = 'Entity_addDepositPayment_%s' % context.getUid()
if context.REQUEST.get(payment_tag, None) is not None:
raise ValueError('This script was already called twice on the same transaction ')
activate_kw = {
'tag': payment_tag
}
# Ensure all invoice use the same arrow and resource
first_subscription = subscription_list[0]
identical_dict = {
'getSource': first_subscription.getSource(),
'getSourceSection': first_subscription.getSourceSection(),
'getDestinationSection': first_subscription.getDestinationSection(),
'getPriceCurrency': first_subscription.getPriceCurrency(),
'getLedger': first_subscription.getLedger(),
}
price = 0
for subscription in subscription_list:
for method_id, method_value in identical_dict.items():
if getattr(subscription, method_id)() != method_value:
raise ValueError('Subscription Requests do not match on method: %s' % method_id)
if subscription.total_price:
price += subscription.total_price
# Simulation state
if not subscription.isTempObject() and subscription.getSimulationState() != "submitted":
raise ValueError('Not on submitted state')
if subscription.getPortalType() != "Subscription Request":
raise ValueError('Not an Subscription Request')
if not price:
raise ValueError("No price to to pay")
if first_subscription.getDestinationSection() != context.getRelativeUrl():
raise ValueError("Subscription not related to the context")
###################################################### ######################################################
# Find Sale Trade Condition # Find Sale Trade Condition
source_section = context source_section = context
currency_relative_url = first_subscription.getPriceCurrency()
ledger_relative_url = first_subscription.getLedger()
# Create a temp Sale Order to calculate the real price and find the trade condition # Create a temp Sale Order to calculate the real price and find the trade condition
now = DateTime() now = DateTime()
...@@ -20,10 +63,12 @@ tmp_sale_order = module.newContent( ...@@ -20,10 +63,12 @@ tmp_sale_order = module.newContent(
temp_object=True, temp_object=True,
trade_condition_type="deposit", trade_condition_type="deposit",
start_date=now, start_date=now,
source=first_subscription.getSource(),
source_section=first_subscription.getSourceSection(),
destination_value=source_section, destination_value=source_section,
destination_section_value=source_section, destination_section_value=source_section,
destination_decision_value=source_section, destination_decision_value=source_section,
ledger_value=portal.portal_categories.ledger.automated, ledger=ledger_relative_url,
price_currency=currency_relative_url price_currency=currency_relative_url
) )
tmp_sale_order.SaleOrder_applySaleTradeCondition(batch_mode=1, force=1) tmp_sale_order.SaleOrder_applySaleTradeCondition(batch_mode=1, force=1)
...@@ -40,12 +85,19 @@ if (tmp_sale_order.getSourceSection(None) == tmp_sale_order.getDestinationSectio ...@@ -40,12 +85,19 @@ if (tmp_sale_order.getSourceSection(None) == tmp_sale_order.getDestinationSectio
raise AssertionError('The trade condition does not generate accounting: %s' % tmp_sale_order.getSpecialise()) raise AssertionError('The trade condition does not generate accounting: %s' % tmp_sale_order.getSpecialise())
####################################################### #######################################################
payment_transaction = portal.accounting_module.newContent( # The payment needs to be returned on web site context, to proper handle acquisition later on
# otherwise, payment redirections would fail on multiple occasions whenever website isn't in
# the context acquisition.
web_site = context.getWebSiteValue()
if web_site is None:
web_site = portal
# preserve the capability to call payment_transaction.getWebSiteValue() and get the current website back.
payment_transaction = web_site.accounting_module.newContent(
title="reservation payment", title="reservation payment",
portal_type="Payment Transaction", portal_type="Payment Transaction",
start_date=now, start_date=now,
stop_date=now, stop_date=now,
specialise_value=tmp_sale_order.getSpecialiseValue(), specialise_value=tmp_sale_order.getSpecialiseValue(),
source=tmp_sale_order.getSource(), source=tmp_sale_order.getSource(),
source_section=tmp_sale_order.getSourceSection(), source_section=tmp_sale_order.getSourceSection(),
...@@ -56,10 +108,10 @@ payment_transaction = portal.accounting_module.newContent( ...@@ -56,10 +108,10 @@ payment_transaction = portal.accounting_module.newContent(
destination_decision=tmp_sale_order.getDestinationDecision(), destination_decision=tmp_sale_order.getDestinationDecision(),
destination_project=tmp_sale_order.getDestinationProject(), destination_project=tmp_sale_order.getDestinationProject(),
payment_mode=payment_mode, payment_mode=payment_mode,
ledger_value=portal.portal_categories.ledger.automated, ledger_value=ledger_relative_url,
resource=tmp_sale_order.getPriceCurrency(), resource=tmp_sale_order.getPriceCurrency(),
created_by_builder=1, # XXX this prevent init script from creating lines. created_by_builder=1, # XXX this prevent init script from creating lines.
activate_kw={'tag':'%s_init' % context.getRelativeUrl()} activate_kw=activate_kw
) )
getAccountForUse = context.Base_getAccountForUse getAccountForUse = context.Base_getAccountForUse
...@@ -70,7 +122,8 @@ payment_transaction.newContent( ...@@ -70,7 +122,8 @@ payment_transaction.newContent(
portal_type='Accounting Transaction Line', portal_type='Accounting Transaction Line',
quantity=price, quantity=price,
source_value=getAccountForUse('asset_receivable_subscriber'), source_value=getAccountForUse('asset_receivable_subscriber'),
destination_value=getAccountForUse('payable') destination_value=getAccountForUse('payable'),
activate_kw=activate_kw
) )
# bank # bank
...@@ -80,7 +133,8 @@ payment_transaction.newContent( ...@@ -80,7 +133,8 @@ payment_transaction.newContent(
portal_type='Accounting Transaction Line', portal_type='Accounting Transaction Line',
quantity=-price, quantity=-price,
source_value=collection_account, source_value=collection_account,
destination_value=collection_account destination_value=collection_account,
activate_kw=activate_kw
) )
if len(payment_transaction.checkConsistency()) != 0: if len(payment_transaction.checkConsistency()) != 0:
...@@ -88,4 +142,7 @@ if len(payment_transaction.checkConsistency()) != 0: ...@@ -88,4 +142,7 @@ if len(payment_transaction.checkConsistency()) != 0:
payment_transaction.start(comment=translateString("Deposit payment.")) payment_transaction.start(comment=translateString("Deposit payment."))
# Set a flag on the request for prevent 2 calls on the same transaction
context.REQUEST.set(payment_tag, 1)
return payment_transaction return payment_transaction
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>price, currency_relative_url, payment_mode=None, REQUEST=None</string> </value> <value> <string>subscription_list, payment_mode=None, REQUEST=None</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Entity_addDepositPayment</string> </value> <value> <string>Entity_createDepositPaymentTransaction</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
portal = context.getPortalObject() portal = context.getPortalObject()
from Products.ERP5Type.Document import newTempBase
query_kw = { query_kw = {
"portal_type": "Subscription Request", "portal_type": "Subscription Request",
"simulation_state": "submitted" "simulation_state": "submitted"
} }
if section_uid:
query_kw['source_section__uid'] = section_uid
if ledger_uid: if ledger_uid:
query_kw['ledger__uid'] = ledger_uid query_kw['ledger__uid'] = ledger_uid
...@@ -21,25 +23,14 @@ for subscription_request_brain in portal.portal_catalog( ...@@ -21,25 +23,14 @@ for subscription_request_brain in portal.portal_catalog(
subscription_request = subscription_request_brain.getObject() subscription_request = subscription_request_brain.getObject()
subscription_request_total_price = subscription_request.getTotalPrice() subscription_request_total_price = subscription_request.getTotalPrice()
if 0 < subscription_request_total_price: if 0 < subscription_request_total_price:
currency = subscription_request.getPriceCurrency() currency_uid = subscription_request.getPriceCurrencyUid()
# Future proof in case we implement B2B payment # Future proof in case we implement B2B payment
object_index = "%s_%s" % (currency, subscription_request.getDestinationSection()) object_index = "%s_%s" % (currency_uid, subscription_request.getSourceSection())
if object_index not in object_dict: if object_index not in object_dict:
object_dict[object_index] = dict( object_dict[object_index] = [subscription_request, subscription_request_total_price]
causality_list=[], else:
uid=object_index, subscription_request_total_price += object_dict[object_index][1]
price_currency=currency, object_dict[object_index] = [object_dict[object_index][0],
destination_section=subscription_request.getDestinationSection(), subscription_request_total_price]
total_price = 0)
object_dict[object_index]['total_price'] = \
object_dict[object_index]['total_price'] + subscription_request_total_price
object_dict[object_index]['causality_list'].append(subscription_request.getRelativeUrl())
object_list = []
for key in object_dict:
object_list.append(newTempBase(
portal, object_dict[key]['causality_list'][0], **object_dict[key]))
return object_list return [s.asContext(total_price=price) for s, price in object_dict.values()]
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>resource_uid=None, ledger_uid=None,**kw</string> </value> <value> <string>resource_uid=None, section_uid=None, ledger_uid=None,**kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
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