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
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
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
now = DateTime()
......@@ -20,10 +63,12 @@ tmp_sale_order = module.newContent(
temp_object=True,
trade_condition_type="deposit",
start_date=now,
source=first_subscription.getSource(),
source_section=first_subscription.getSourceSection(),
destination_value=source_section,
destination_section_value=source_section,
destination_decision_value=source_section,
ledger_value=portal.portal_categories.ledger.automated,
ledger=ledger_relative_url,
price_currency=currency_relative_url
)
tmp_sale_order.SaleOrder_applySaleTradeCondition(batch_mode=1, force=1)
......@@ -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())
#######################################################
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",
portal_type="Payment Transaction",
start_date=now,
stop_date=now,
specialise_value=tmp_sale_order.getSpecialiseValue(),
source=tmp_sale_order.getSource(),
source_section=tmp_sale_order.getSourceSection(),
......@@ -56,10 +108,10 @@ payment_transaction = portal.accounting_module.newContent(
destination_decision=tmp_sale_order.getDestinationDecision(),
destination_project=tmp_sale_order.getDestinationProject(),
payment_mode=payment_mode,
ledger_value=portal.portal_categories.ledger.automated,
ledger_value=ledger_relative_url,
resource=tmp_sale_order.getPriceCurrency(),
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
......@@ -70,7 +122,8 @@ payment_transaction.newContent(
portal_type='Accounting Transaction Line',
quantity=price,
source_value=getAccountForUse('asset_receivable_subscriber'),
destination_value=getAccountForUse('payable')
destination_value=getAccountForUse('payable'),
activate_kw=activate_kw
)
# bank
......@@ -80,7 +133,8 @@ payment_transaction.newContent(
portal_type='Accounting Transaction Line',
quantity=-price,
source_value=collection_account,
destination_value=collection_account
destination_value=collection_account,
activate_kw=activate_kw
)
if len(payment_transaction.checkConsistency()) != 0:
......@@ -88,4 +142,7 @@ if len(payment_transaction.checkConsistency()) != 0:
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
......@@ -50,11 +50,11 @@
</item>
<item>
<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>
<key> <string>id</string> </key>
<value> <string>Entity_addDepositPayment</string> </value>
<value> <string>Entity_createDepositPaymentTransaction</string> </value>
</item>
</dictionary>
</pickle>
......
portal = context.getPortalObject()
from Products.ERP5Type.Document import newTempBase
query_kw = {
"portal_type": "Subscription Request",
"simulation_state": "submitted"
}
if section_uid:
query_kw['source_section__uid'] = section_uid
if ledger_uid:
query_kw['ledger__uid'] = ledger_uid
......@@ -21,25 +23,14 @@ for subscription_request_brain in portal.portal_catalog(
subscription_request = subscription_request_brain.getObject()
subscription_request_total_price = subscription_request.getTotalPrice()
if 0 < subscription_request_total_price:
currency = subscription_request.getPriceCurrency()
currency_uid = subscription_request.getPriceCurrencyUid()
# 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:
object_dict[object_index] = dict(
causality_list=[],
uid=object_index,
price_currency=currency,
destination_section=subscription_request.getDestinationSection(),
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]))
object_dict[object_index] = [subscription_request, subscription_request_total_price]
else:
subscription_request_total_price += object_dict[object_index][1]
object_dict[object_index] = [object_dict[object_index][0],
subscription_request_total_price]
return object_list
return [s.asContext(total_price=price) for s, price in object_dict.values()]
......@@ -50,7 +50,7 @@
</item>
<item>
<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>
<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