Commit 1b5f0fba authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_accounting: Rework creation of the Reversal Sale Invoice Transactions

  Unify and drop duplicated code present on slapos_payzen and slapos_wechat.
  Update and move tests related to the change
parent 25fd8d3a
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>text</string> </key> <key> <string>text</string> </key>
<value> <string>python: object.getSimulationState() in (\'stopped\', )</string> </value> <value> <string>python: object.getSimulationState() in (\'stopped\', ) and not object.SaleInvoiceTransaction_isLettered()</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
""" Create a reversal transaction from current wechat transaction. """ """ Create a reversal transaction from current transaction. """
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
portal = context.getPortalObject() portal = context.getPortalObject()
if not batch_mode and context.getPaymentMode() not in ["payzen", "wechat"]:
message = context.Base_translateString("The payment mode is unsupported.")
return context.Base_redirect(keep_items={'portal_status_message': message})
# Check that we are in state that we are waiting for user manual payment # Check that we are in state that we are waiting for user manual payment
assert context.getPortalType() == 'Sale Invoice Transaction' assert context.getPortalType() == 'Sale Invoice Transaction'
assert context.getPaymentMode() == 'wechat' assert context.getPaymentMode() in ('payzen', 'wechat')
assert context.getSimulationState() == 'stopped' assert context.getSimulationState() == 'stopped'
assert context.getTotalPrice() != 0 assert context.getTotalPrice() != 0
assert context.getSpecialise() in ("sale_trade_condition_module/slapos_aggregated_trade_condition", assert context.getSpecialise() in ("sale_trade_condition_module/slapos_aggregated_trade_condition",
"sale_trade_condition_module/slapos_aggregated_subscription_trade_condition") "sale_trade_condition_module/slapos_aggregated_subscription_trade_condition")
# Dont create if the invoice is already paied # Dont create if the invoice is already paied
assert not context.SaleInvoiceTransaction_isLettered() assert not context.SaleInvoiceTransaction_isLettered()
...@@ -21,9 +20,16 @@ payment = portal.portal_catalog.getResultValue( ...@@ -21,9 +20,16 @@ payment = portal.portal_catalog.getResultValue(
portal_type="Payment Transaction", portal_type="Payment Transaction",
simulation_state="started", simulation_state="started",
default_causality_uid=context.getUid(), default_causality_uid=context.getUid(),
default_payment_mode_uid=portal.portal_categories.payment_mode.wechat.getUid(), default_payment_mode_uid=[
portal.portal_categories.payment_mode.payzen.getUid(),
portal.portal_categories.payment_mode.wechat.getUid()],
) )
if payment is not None and payment.PaymentTransaction_getWechatId()[1] is None: if payment is not None:
payment_mode = payment.getPaymentMode()
if payment_mode == 'payzen' and payment.PaymentTransaction_getPayzenId()[1] is not None:
# The payment transaction will be cancelled by a proper alarm.
raise ValueError("Payment Transaction is waiting for External Payzen confirmation!")
elif payment_mode == 'wechat' and payment.PaymentTransaction_getWechatId()[1] is not None:
# The payment transaction will be cancelled by a proper alarm. # The payment transaction will be cancelled by a proper alarm.
raise ValueError("Payment Transaction is waiting for External Wechat confirmation!") raise ValueError("Payment Transaction is waiting for External Wechat confirmation!")
...@@ -44,4 +50,9 @@ for line in reversal_transaction.getMovementList(): ...@@ -44,4 +50,9 @@ for line in reversal_transaction.getMovementList():
reversal_transaction.confirm(comment="Automatic because of reversal creation") reversal_transaction.confirm(comment="Automatic because of reversal creation")
reversal_transaction.stop(comment="Automatic because of reversal creation") reversal_transaction.stop(comment="Automatic because of reversal creation")
return reversal_transaction if batch_mode:
return reversal_transaction
message = context.Base_translateString("Reversal Transaction created.")
return reversal_transaction.Base_redirect(
keep_items={'portal_status_message': message})
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value> <value> <string>batch_mode=False</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>SaleInvoiceTransaction_createReversalWechatTransaction</string> </value> <value> <string>SaleInvoiceTransaction_createReversalSaleInvoiceTransaction</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
if context.getPaymentMode() == "payzen":
reversal_payment = context.SaleInvoiceTransaction_createReversalPayzenTransaction()
elif context.getPaymentMode() == "wechat":
reversal_payment = context.SaleInvoiceTransaction_createReversalWechatTransaction()
else:
message = context.Base_translateString("The payment mode is unsupported.")
return context.Base_redirect(keep_items={'portal_status_message': message})
message = context.Base_translateString("Reversal Transaction created.")
return reversal_payment.Base_redirect(keep_items={'portal_status_message': message})
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleInvoiceTransaction_createSlapOSReversalTransaction</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -35,7 +35,11 @@ ...@@ -35,7 +35,11 @@
</item> </item>
<item> <item>
<key> <string>action</string> </key> <key> <string>action</string> </key>
<value> <string>SaleInvoiceTransaction_createSlapOSReversalTransaction</string> </value> <value> <string>SaleInvoiceTransaction_createReversalSaleInvoiceTransaction</string> </value>
</item>
<item>
<key> <string>action_title</string> </key>
<value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
# #
############################################################################## ##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, withAbort, simulate from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, withAbort
from zExceptions import Unauthorized from zExceptions import Unauthorized
from DateTime import DateTime from DateTime import DateTime
...@@ -50,6 +50,37 @@ class TestSlapOSAccounting(SlapOSTestCaseMixin): ...@@ -50,6 +50,37 @@ class TestSlapOSAccounting(SlapOSTestCaseMixin):
reference="TESTOSO-%s" % new_id, reference="TESTOSO-%s" % new_id,
) )
def createSaleInvoiceTransactionForReversal(self, destination_section=None, price=2, payment_mode="payzen"):
new_title = self.generateNewId()
new_reference = self.generateNewId()
new_source_reference = self.generateNewId()
new_destination_reference = self.generateNewId()
invoice = self.portal.accounting_module.newContent(
portal_type="Sale Invoice Transaction",
title=new_title,
start_date=DateTime(),
reference=new_reference,
source_reference=new_source_reference,
destination_reference=new_destination_reference,
destination_section=destination_section,
payment_mode=payment_mode,
specialise="sale_trade_condition_module/slapos_aggregated_trade_condition",
created_by_builder=1 # to prevent init script to create lines
)
self.portal.portal_workflow._jumpToStateFor(invoice, 'stopped')
invoice.newContent(
title="",
portal_type="Invoice Line",
quantity=-2,
price=price,
)
invoice.newContent(
portal_type="Sale Invoice Transaction Line",
source="account_module/receivable",
quantity=-3,
)
return invoice
@withAbort @withAbort
def test_IT_calculateSubscriptionStartDate_REQUEST_disallowed(self): def test_IT_calculateSubscriptionStartDate_REQUEST_disallowed(self):
item = self.createInstanceTree() item = self.createInstanceTree()
...@@ -209,43 +240,37 @@ class TestSlapOSAccounting(SlapOSTestCaseMixin): ...@@ -209,43 +240,37 @@ class TestSlapOSAccounting(SlapOSTestCaseMixin):
self.portal.OpenSaleOrder_reindexIfIndexedBeforeLine, self.portal.OpenSaleOrder_reindexIfIndexedBeforeLine,
REQUEST={}) REQUEST={})
def test_SaleInvoiceTransaction_createReversalSaleInvoiceTransaction_redirect_payzen(self):
sale_invoice_transaction = self.createSaleInvoiceTransactionForReversal(payment_mode='payzen')
self.tic()
@simulate("SaleInvoiceTransaction_createReversalPayzenTransaction", redirect = sale_invoice_transaction.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction()
"*args, **kwargs", """context.portal_workflow.doActionFor(context, action='edit_action', comment='Visited by SaleInvoiceTransaction_createReversalPayzenTransaction') self.assertTrue(
return context.getParentValue()""") redirect.endswith(
def test_SaleInvoiceTransaction_createSlapOSReversalTransaction_payzen(self): '?portal_status_message=Reversal%20Transaction%20created.'),
sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction") "%s doesn't end with expected response" % redirect)
sale_invoice_transaction.edit(payment_mode="payzen")
redirect = sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()
self.assertTrue(redirect.endswith('accounting_module?portal_status_message=Reversal%20Transaction%20created.'),
"%s doesn't end with sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()" % redirect)
self.assertEqual(
'Visited by SaleInvoiceTransaction_createReversalPayzenTransaction',
sale_invoice_transaction.workflow_history['edit_workflow'][-1]['comment'])
@simulate("SaleInvoiceTransaction_createReversalWechatTransaction", def test_SaleInvoiceTransaction_createReversalSaleInvoiceTransaction_redirect_wechat(self):
"*args, **kwargs", """context.portal_workflow.doActionFor(context, action='edit_action', comment='Visited by SaleInvoiceTransaction_createReversalWechatTransaction') sale_invoice_transaction = self.createSaleInvoiceTransactionForReversal(payment_mode='wechat')
return context.getParentValue()""") self.tic()
def test_SaleInvoiceTransaction_createSlapOSReversalTransaction_wechat(self):
sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction")
sale_invoice_transaction.edit(payment_mode="wechat")
redirect = sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction() redirect = sale_invoice_transaction.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction()
self.assertTrue(redirect.endswith('accounting_module?portal_status_message=Reversal%20Transaction%20created.'), self.assertTrue(
"%s doesn't end with sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction()" % redirect) redirect.endswith(
self.assertEqual( '?portal_status_message=Reversal%20Transaction%20created.'),
'Visited by SaleInvoiceTransaction_createReversalWechatTransaction', "%s doesn't end with expected response" % redirect)
sale_invoice_transaction.workflow_history['edit_workflow'][-1]['comment'])
def test_SaleInvoiceTransaction_createSlapOSReversalTransaction_unknown(self): def test_SaleInvoiceTransaction_createReversalSaleInvoiceTransaction_redirect_unknown(self):
sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction") sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction")
sale_invoice_transaction.edit(payment_mode="unknown") sale_invoice_transaction.edit(payment_mode="unknown")
redirect = sale_invoice_transaction.SaleInvoiceTransaction_createSlapOSReversalTransaction() redirect = sale_invoice_transaction.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction()
self.assertTrue(redirect.endswith('%s?portal_status_message=The%%20payment%%20mode%%20is%%20unsupported.' % sale_invoice_transaction.getRelativeUrl()), self.assertTrue(
"%s doesn't end with %s?portal_status_message=The%%20payment%%20mode%%20is%%20unsupported." % (redirect, sale_invoice_transaction.getRelativeUrl())) redirect.endswith(
'%s?portal_status_message=The%%20payment%%20mode%%20is%%20unsupported.' % sale_invoice_transaction.getRelativeUrl()),
"%s doesn't end with %s?portal_status_message=The%%20payment%%20mode%%20is%%20unsupported." % (
redirect, sale_invoice_transaction.getRelativeUrl()))
def test_SaleInvoiceTransaction_resetPaymentMode(self): def test_SaleInvoiceTransaction_resetPaymentMode(self):
sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction") sale_invoice_transaction = self.portal.accounting_module.newContent(portal_type="Sale Invoice Transaction")
...@@ -368,3 +393,243 @@ return context.getParentValue()""") ...@@ -368,3 +393,243 @@ return context.getParentValue()""")
self.assertEqual( self.assertEqual(
[i.getRelativeUrl() for i in unpaid_invoice_list], [i.getRelativeUrl() for i in unpaid_invoice_list],
[]) [])
@withAbort
def test_createReversalSaleInvoiceTransaction_bad_portal_type(self):
self.assertRaises(
AssertionError,
self.portal.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_bad_payment_mode(self):
invoice = self.createSaleInvoiceTransactionForReversal()
invoice.edit(payment_mode="cash")
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_bad_state(self, payment_mode='payzen'):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode=payment_mode)
self.portal.portal_workflow._jumpToStateFor(invoice, 'delivered')
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_zero_price(self, payment_mode='payzen'):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode=payment_mode)
invoice.manage_delObjects(invoice.contentIds())
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_wrong_trade_condition(self, payment_mode='payzen'):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode=payment_mode)
invoice.edit(specialise=None)
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_paid(self, payment_mode='payzen'):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode=payment_mode)
line = invoice.contentValues(portal_type="Sale Invoice Transaction Line")[0]
line.edit(grouping_reference="azerty")
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_registered_payment(self, payment_mode='payzen'):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode=payment_mode)
payment = self.portal.accounting_module.newContent(
portal_type="Payment Transaction",
payment_mode=payment_mode,
causality_value=invoice,
destination_section=invoice.getDestinationSection(),
created_by_builder=1 # to prevent init script to create lines
)
self.portal.portal_workflow._jumpToStateFor(payment, 'started')
self.tic()
payment.PaymentTransaction_generatePayzenId()
self.assertRaises(
ValueError,
invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_ok(self, payment_mode='payzen'):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode=payment_mode)
self.tic()
reversale_invoice = invoice.\
SaleInvoiceTransaction_createReversalSaleInvoiceTransaction(batch_mode=1)
self.assertEqual(invoice.getPaymentMode(""), "")
self.assertEqual(reversale_invoice.getTitle(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getDescription(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getCausality(),
invoice.getRelativeUrl())
self.assertEqual(reversale_invoice.getSimulationState(), "stopped")
self.assertEqual(invoice.getSimulationState(), "stopped")
invoice_line_id = invoice.contentValues(portal_type="Invoice Line")[0].getId()
transaction_line_id = invoice.contentValues(
portal_type="Sale Invoice Transaction Line")[0].getId()
self.assertEqual(invoice[invoice_line_id].getQuantity(),
-reversale_invoice[invoice_line_id].getQuantity())
self.assertEqual(reversale_invoice[invoice_line_id].getQuantity(), 2)
self.assertEqual(invoice[transaction_line_id].getQuantity(),
-reversale_invoice[transaction_line_id].getQuantity())
self.assertEqual(reversale_invoice[transaction_line_id].getQuantity(), 3)
self.assertEqual(len(invoice.getMovementList()), 2)
# Both invoice should have a grouping reference
self.assertNotEqual(invoice[transaction_line_id].getGroupingReference(""),
"")
self.assertEqual(
invoice[transaction_line_id].getGroupingReference("1"),
reversale_invoice[transaction_line_id].getGroupingReference("2"))
# All references should be regenerated
self.assertNotEqual(invoice.getReference(""),
reversale_invoice.getReference(""))
self.assertNotEqual(invoice.getSourceReference(""),
reversale_invoice.getSourceReference(""))
self.assertNotEqual(invoice.getDestinationReference(""),
reversale_invoice.getDestinationReference(""))
self.assertTrue(invoice.SaleInvoiceTransaction_isLettered())
self.assertTrue(reversale_invoice.SaleInvoiceTransaction_isLettered())
# Another trade condition
self.assertEqual(
reversale_invoice.getSpecialise(),
"sale_trade_condition_module/slapos_manual_accounting_trade_condition")
self.tic()
@withAbort
def test_createReversalSaleInvoiceTransaction_ok_dont_autocancel(self, payment_mode='payzen'):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode=payment_mode)
payment = self.portal.accounting_module.newContent(
portal_type="Payment Transaction",
payment_mode=payment_mode,
causality_value=invoice,
destination_section=invoice.getDestinationSection(),
created_by_builder=1 # to prevent init script to create lines
)
self.portal.portal_workflow._jumpToStateFor(payment, 'started')
self.tic()
reversale_invoice = invoice.\
SaleInvoiceTransaction_createReversalSaleInvoiceTransaction(batch_mode=1)
self.assertEqual(invoice.getPaymentMode(""), "")
# Related payment is cancelled by a proper alarm.
self.assertEqual(payment.getSimulationState(), "started")
self.assertEqual(reversale_invoice.getTitle(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getDescription(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getCausality(),
invoice.getRelativeUrl())
self.assertEqual(reversale_invoice.getSimulationState(), "stopped")
self.assertEqual(invoice.getSimulationState(), "stopped")
invoice_line_id = invoice.contentValues(portal_type="Invoice Line")[0].getId()
transaction_line_id = invoice.contentValues(
portal_type="Sale Invoice Transaction Line")[0].getId()
self.assertEqual(invoice[invoice_line_id].getQuantity(),
-reversale_invoice[invoice_line_id].getQuantity())
self.assertEqual(reversale_invoice[invoice_line_id].getQuantity(), 2)
self.assertEqual(invoice[transaction_line_id].getQuantity(),
-reversale_invoice[transaction_line_id].getQuantity())
self.assertEqual(reversale_invoice[transaction_line_id].getQuantity(), 3)
self.assertEqual(len(invoice.getMovementList()), 2)
# Both invoice should have a grouping reference
self.assertNotEqual(invoice[transaction_line_id].getGroupingReference(""),
"")
self.assertEqual(
invoice[transaction_line_id].getGroupingReference("1"),
reversale_invoice[transaction_line_id].getGroupingReference("2"))
# All references should be regenerated
self.assertNotEqual(invoice.getReference(""),
reversale_invoice.getReference(""))
self.assertNotEqual(invoice.getSourceReference(""),
reversale_invoice.getSourceReference(""))
self.assertNotEqual(invoice.getDestinationReference(""),
reversale_invoice.getDestinationReference(""))
self.assertTrue(invoice.SaleInvoiceTransaction_isLettered())
self.assertTrue(reversale_invoice.SaleInvoiceTransaction_isLettered())
# Another trade condition
self.assertEqual(
reversale_invoice.getSpecialise(),
"sale_trade_condition_module/slapos_manual_accounting_trade_condition")
self.tic()
@withAbort
def test_createReversalSaleInvoiceTransaction_wechat_bad_state(self):
self.test_createReversalSaleInvoiceTransaction_bad_state(payment_mode='wechat')
@withAbort
def test_createReversalSaleInvoiceTransaction_wechat_zero_price(self):
self.test_createReversalSaleInvoiceTransaction_zero_price(payment_mode='wechat')
@withAbort
def test_createReversalSaleInvoiceTransaction_wechat_wrong_trade_condition(self):
self.test_createReversalSaleInvoiceTransaction_wrong_trade_condition(payment_mode='wechat')
@withAbort
def test_createReversalSaleInvoiceTransaction_wechat_paid(self):
self.test_createReversalSaleInvoiceTransaction_paid(payment_mode='wechat')
@withAbort
def test_createReversalSaleInvoiceTransaction_wechat_registered_payment(self):
invoice = self.createSaleInvoiceTransactionForReversal(payment_mode='wechat')
payment = self.portal.accounting_module.newContent(
portal_type="Payment Transaction",
payment_mode='wechat',
causality_value=invoice,
destination_section=invoice.getDestinationSection(),
created_by_builder=1 # to prevent init script to create lines
)
self.portal.portal_workflow._jumpToStateFor(payment, 'started')
self.tic()
payment.PaymentTransaction_generateWechatId()
self.assertRaises(
ValueError,
invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction,
batch_mode=1)
@withAbort
def test_createReversalSaleInvoiceTransaction_wechat_ok(self):
self.test_createReversalSaleInvoiceTransaction_ok(payment_mode='wechat')
@withAbort
def test_createReversalSaleInvoiceTransaction_wechat_ok_dont_autocancel(self):
self.test_createReversalSaleInvoiceTransaction_ok_dont_autocancel(payment_mode='wechat')
\ No newline at end of file
...@@ -505,13 +505,10 @@ class TestSlapOSDefaultCRMEscalation(DefaultScenarioMixin): ...@@ -505,13 +505,10 @@ class TestSlapOSDefaultCRMEscalation(DefaultScenarioMixin):
# Manually cancel the users invoice # Manually cancel the users invoice
payment = self.portal.portal_catalog.getResultValue( invoice_list = person.Entity_getOutstandingAmountList()
portal_type="Payment Transaction", self.assertEqual(len(invoice_list), 1)
destination_section_uid=person.getUid(), sale_transaction_invoice = invoice_list[0].getObject()
simulation_state="started") sale_transaction_invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction(batch_mode=1)
invoice = payment.getCausalityValue(portal_type="Sale Invoice Transaction")
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction()
self.tic() self.tic()
......
""" Create a reversal transaction from current payzen transaction. """
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
portal = context.getPortalObject()
# Check that we are in state that we are waiting for user manual payment
assert context.getPortalType() == 'Sale Invoice Transaction'
assert context.getPaymentMode() == 'payzen'
assert context.getSimulationState() == 'stopped'
assert context.getTotalPrice() != 0
assert context.getSpecialise() in ("sale_trade_condition_module/slapos_aggregated_trade_condition",
"sale_trade_condition_module/slapos_aggregated_subscription_trade_condition")
# Dont create if the invoice is already paied
assert not context.SaleInvoiceTransaction_isLettered()
payment = portal.portal_catalog.getResultValue(
portal_type="Payment Transaction",
simulation_state="started",
default_causality_uid=context.getUid(),
default_payment_mode_uid=portal.portal_categories.payment_mode.payzen.getUid(),
)
if payment is not None and payment.PaymentTransaction_getPayzenId()[1] is None:
# The payment transaction will be cancelled by a proper alarm.
raise ValueError("Payment Transaction is waiting for External Payzen confirmation!")
# Should be safe now to fix everything
context.SaleInvoiceTransaction_resetPaymentMode()
reversal_transaction = context.Base_createCloneDocument(batch_mode=1)
reversal_transaction.edit(
title="Reversal Transaction for %s" % context.getTitle(),
causality_value=context,
description="Reversal Transaction for %s" % context.getTitle(),
specialise_value=portal.sale_trade_condition_module.slapos_manual_accounting_trade_condition,
)
for line in reversal_transaction.getMovementList():
line.edit(quantity=(-line.getQuantity()))
reversal_transaction.confirm(comment="Automatic because of reversal creation")
reversal_transaction.stop(comment="Automatic because of reversal creation")
return reversal_transaction
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleInvoiceTransaction_createReversalPayzenTransaction</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -713,7 +713,7 @@ class TestSlapOSPayzenAccountingTransaction_getPaymentState( ...@@ -713,7 +713,7 @@ class TestSlapOSPayzenAccountingTransaction_getPaymentState(
def test_AccountingTransaction_getPaymentState_reversed_payment(self): def test_AccountingTransaction_getPaymentState_reversed_payment(self):
invoice = self.createPayzenSaleInvoiceTransaction() invoice = self.createPayzenSaleInvoiceTransaction()
self.tic() self.tic()
reversal = invoice.SaleInvoiceTransaction_createReversalPayzenTransaction() reversal = invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction()
self.tic() self.tic()
self.assertEqual("Cancelled", invoice.AccountingTransaction_getPaymentState()) self.assertEqual("Cancelled", invoice.AccountingTransaction_getPaymentState())
self.assertEqual(0, invoice.getTotalPrice() + reversal.getTotalPrice()) self.assertEqual(0, invoice.getTotalPrice() + reversal.getTotalPrice())
...@@ -850,146 +850,3 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -850,146 +850,3 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
self.assertEqual("%s/already_registered" % payment.getRelativeUrl(), self.assertEqual("%s/already_registered" % payment.getRelativeUrl(),
redirect) redirect)
class TestSlapOSPayzenSaleInvoiceTransaction_createReversalPayzenTransaction(
SlapOSTestCaseMixinWithAbort):
def test_createReversalPayzenTransaction_REQUEST_disallowed(self):
self.assertRaises(
Unauthorized,
self.portal.SaleInvoiceTransaction_createReversalPayzenTransaction,
REQUEST={})
def test_createReversalPayzenTransaction_bad_portal_type(self):
self.assertRaises(
AssertionError,
self.portal.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_bad_payment_mode(self):
invoice = self.createPayzenSaleInvoiceTransaction()
invoice.edit(payment_mode="cash")
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_bad_state(self):
invoice = self.createPayzenSaleInvoiceTransaction()
self.portal.portal_workflow._jumpToStateFor(invoice, 'delivered')
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_zero_price(self):
invoice = self.createPayzenSaleInvoiceTransaction()
invoice.manage_delObjects(invoice.contentIds())
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_wrong_trade_condition(self):
invoice = self.createPayzenSaleInvoiceTransaction()
invoice.edit(specialise=None)
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_paid(self):
invoice = self.createPayzenSaleInvoiceTransaction()
line = invoice.contentValues(portal_type="Sale Invoice Transaction Line")[0]
line.edit(grouping_reference="azerty")
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_no_payment(self):
invoice = self.createPayzenSaleInvoiceTransaction()
# Do not reindex payment. portal_catalog will not find it.
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_no_payzen_payment(self):
invoice = self.createPayzenSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
payment.edit(payment_mode="cash")
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_no_payment_state(self):
invoice = self.createPayzenSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
self.portal.portal_workflow._jumpToStateFor(payment, 'cancelled')
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_registered_payment(self):
invoice = self.createPayzenSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
payment.PaymentTransaction_generatePayzenId()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction)
def test_createReversalPayzenTransaction_ok(self):
invoice = self.createPayzenSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
reversale_invoice = invoice.\
SaleInvoiceTransaction_createReversalPayzenTransaction()
self.assertEqual(invoice.getPaymentMode(""), "")
self.assertEqual(payment.getPaymentMode(""), "")
self.assertEqual(payment.getSimulationState(), "cancelled")
self.assertEqual(reversale_invoice.getTitle(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getDescription(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getCausality(),
invoice.getRelativeUrl())
self.assertEqual(reversale_invoice.getSimulationState(), "stopped")
self.assertEqual(invoice.getSimulationState(), "stopped")
invoice_line_id = invoice.contentValues(portal_type="Invoice Line")[0].getId()
transaction_line_id = invoice.contentValues(
portal_type="Sale Invoice Transaction Line")[0].getId()
self.assertEqual(invoice[invoice_line_id].getQuantity(),
-reversale_invoice[invoice_line_id].getQuantity())
self.assertEqual(reversale_invoice[invoice_line_id].getQuantity(), 2)
self.assertEqual(invoice[transaction_line_id].getQuantity(),
-reversale_invoice[transaction_line_id].getQuantity())
self.assertEqual(reversale_invoice[transaction_line_id].getQuantity(), 3)
self.assertEqual(len(invoice.getMovementList()), 2)
# Both invoice should have a grouping reference
self.assertNotEqual(invoice[transaction_line_id].getGroupingReference(""),
"")
self.assertEqual(
invoice[transaction_line_id].getGroupingReference("1"),
reversale_invoice[transaction_line_id].getGroupingReference("2"))
# All references should be regenerated
self.assertNotEqual(invoice.getReference(""),
reversale_invoice.getReference(""))
self.assertNotEqual(invoice.getSourceReference(""),
reversale_invoice.getSourceReference(""))
self.assertNotEqual(invoice.getDestinationReference(""),
reversale_invoice.getDestinationReference(""))
# Another trade condition
self.assertEqual(
reversale_invoice.getSpecialise(),
"sale_trade_condition_module/slapos_manual_accounting_trade_condition")
self.tic()
...@@ -381,7 +381,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -381,7 +381,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
self.logout() self.logout()
self.login() self.login()
sale_transaction_invoice.SaleInvoiceTransaction_createReversalPayzenTransaction() sale_transaction_invoice.SaleInvoiceTransaction_createReversalSaleInvoiceTransaction(batch_mode=1)
def checkSubscriptionRequestPayment(self, subscription_request, authAmount): def checkSubscriptionRequestPayment(self, subscription_request, authAmount):
......
portal = context.getPortalObject()
return portal.portal_catalog.getResultValue(
portal_type="Payment Transaction",
simulation_state="started",
default_causality_uid=context.getUid(),
default_payment_mode_uid=portal.portal_categories.payment_mode.wechat.getUid(),
)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleInvoiceTransaction_getWechatPaymentRelatedValue</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -741,165 +741,3 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -741,165 +741,3 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
self.assertEqual("%s/already_registered" % payment.getRelativeUrl(), self.assertEqual("%s/already_registered" % payment.getRelativeUrl(),
redirect) redirect)
class TestSlapOSWechatSaleInvoiceTransaction_getWechatPaymentRelatedValue(
SlapOSTestCaseMixinWithAbort):
def test_SaleInvoiceTransaction_getWechatPaymentRelatedValue(self):
invoice = self.createWechatSaleInvoiceTransaction()
self.tic()
payment = invoice.SaleInvoiceTransaction_getWechatPaymentRelatedValue()
self.assertNotEqual(None, payment)
self.assertEqual(payment.getSimulationState(), "started")
self.assertEqual(payment.getCausalityValue(), invoice)
self.assertEqual(payment.getPaymentModeUid(),
self.portal.portal_categories.payment_mode.wechat.getUid())
payment.setStartDate(DateTime())
payment.stop()
payment.immediateReindexObject()
payment = invoice.SaleInvoiceTransaction_getWechatPaymentRelatedValue()
self.assertEqual(None, payment)
class TestSlapOSWechatSaleInvoiceTransaction_createReversalWechatTransaction(
SlapOSTestCaseMixinWithAbort):
def test_createReversalWechatTransaction_REQUEST_disallowed(self):
self.assertRaises(
Unauthorized,
self.portal.SaleInvoiceTransaction_createReversalWechatTransaction,
REQUEST={})
def test_createReversalWechatTransaction_bad_portal_type(self):
self.assertRaises(
AssertionError,
self.portal.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_bad_payment_mode(self):
invoice = self.createWechatSaleInvoiceTransaction()
invoice.edit(payment_mode="cash")
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_bad_state(self):
invoice = self.createWechatSaleInvoiceTransaction()
self.portal.portal_workflow._jumpToStateFor(invoice, 'delivered')
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_zero_price(self):
invoice = self.createWechatSaleInvoiceTransaction()
invoice.manage_delObjects(invoice.contentIds())
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_wrong_trade_condition(self):
invoice = self.createWechatSaleInvoiceTransaction()
invoice.edit(specialise=None)
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_paid(self):
invoice = self.createWechatSaleInvoiceTransaction()
line = invoice.contentValues(portal_type="Sale Invoice Transaction Line")[0]
line.edit(grouping_reference="azerty")
self.tic()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_no_payment(self):
invoice = self.createWechatSaleInvoiceTransaction()
# Do not reindex payment. portal_catalog will not find it.
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_no_wechat_payment(self):
invoice = self.createWechatSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
payment.edit(payment_mode="cash")
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_no_payment_state(self):
invoice = self.createWechatSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
self.portal.portal_workflow._jumpToStateFor(payment, 'cancelled')
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_registered_payment(self):
invoice = self.createWechatSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
payment.PaymentTransaction_generateWechatId()
self.assertRaises(
AssertionError,
invoice.SaleInvoiceTransaction_createReversalWechatTransaction)
def test_createReversalWechatTransaction_ok(self):
invoice = self.createWechatSaleInvoiceTransaction()
self.tic()
payment = invoice.getCausalityRelatedValue()
reversale_invoice = invoice.\
SaleInvoiceTransaction_createReversalWechatTransaction()
self.assertEqual(invoice.getPaymentMode(""), "")
self.assertEqual(payment.getPaymentMode(""), "")
self.assertEqual(payment.getSimulationState(), "cancelled")
self.assertEqual(reversale_invoice.getTitle(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getDescription(),
"Reversal Transaction for %s" % invoice.getTitle())
self.assertEqual(reversale_invoice.getCausality(),
invoice.getRelativeUrl())
self.assertEqual(reversale_invoice.getSimulationState(), "stopped")
self.assertEqual(invoice.getSimulationState(), "stopped")
invoice_line_id = invoice.contentValues(portal_type="Invoice Line")[0].getId()
transaction_line_id = invoice.contentValues(
portal_type="Sale Invoice Transaction Line")[0].getId()
self.assertEqual(invoice[invoice_line_id].getQuantity(),
-reversale_invoice[invoice_line_id].getQuantity())
self.assertEqual(reversale_invoice[invoice_line_id].getQuantity(), 2)
self.assertEqual(invoice[transaction_line_id].getQuantity(),
-reversale_invoice[transaction_line_id].getQuantity())
self.assertEqual(reversale_invoice[transaction_line_id].getQuantity(), 3)
self.assertEqual(len(invoice.getMovementList()), 2)
# Both invoice should have a grouping reference
self.assertNotEqual(invoice[transaction_line_id].getGroupingReference(""),
"")
self.assertEqual(
invoice[transaction_line_id].getGroupingReference("1"),
reversale_invoice[transaction_line_id].getGroupingReference("2"))
# All references should be regenerated
self.assertNotEqual(invoice.getReference(""),
reversale_invoice.getReference(""))
self.assertNotEqual(invoice.getSourceReference(""),
reversale_invoice.getSourceReference(""))
self.assertNotEqual(invoice.getDestinationReference(""),
reversale_invoice.getDestinationReference(""))
# Another trade condition
self.assertEqual(
reversale_invoice.getSpecialise(),
"sale_trade_condition_module/slapos_manual_accounting_trade_condition")
self.tic()
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