changeset 5158:5a01f3ef2acd

health_services: Fix bug #62596: Traceback if there is no Account Receivable defined neither on party or default acct config
author Luis Falcon <falcon@gnuhealth.org>
date Wed, 08 Jun 2022 12:51:49 +0100
parents 91632c9719bc
children d35dc2652483
files tryton/health_services/data/messages/messages.xml tryton/health_services/exceptions.py tryton/health_services/wizard/wizard_health_services.py
diffstat 3 files changed, 40 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/tryton/health_services/data/messages/messages.xml
+++ b/tryton/health_services/data/messages/messages.xml
@@ -18,5 +18,8 @@
         <record model="ir.message" id="msg_no_payment_term">
             <field name="text">Need a user payment term</field>
         </record>
+        <record model="ir.message" id="msg_no_account_receivable">
+            <field name="text">No Account Receivable defined in party or in default configuration</field>
+        </record>
     </data>
 </tryton>
--- a/tryton/health_services/exceptions.py
+++ b/tryton/health_services/exceptions.py
@@ -18,3 +18,6 @@
 
 class NoPaymentTerm(UserError):
     pass
+
+class NoAccountReceivable(UserError):
+    pass
--- a/tryton/health_services/wizard/wizard_health_services.py
+++ b/tryton/health_services/wizard/wizard_health_services.py
@@ -1,5 +1,4 @@
-# -*- coding: utf-8 -*-
-##############################################################################
+#############################################################################
 #
 #    GNU Health: The Free Health and Hospital Information System
 #    Copyright (C) 2008-2022 Luis Falcon <lfalcon@gnusolidario.org>
@@ -26,10 +25,16 @@
 from trytond.wizard import Wizard, StateTransition, StateView, Button
 from trytond.transaction import Transaction
 from trytond.pool import Pool
+from trytond.i18n import gettext
 
 
 __all__ = ['CreateServiceInvoiceInit', 'CreateServiceInvoice']
 
+from ..exceptions import (
+    ServiceAlreadyInvoiced, NoInvoiceAddress,
+    NoPaymentTerm, NoAccountReceivable
+    )
+
 
 class CreateServiceInvoiceInit(ModelView):
     'Create Service Invoice Init'
@@ -40,21 +45,23 @@
     'Create Service Invoice'
     __name__ = 'gnuhealth.service.invoice.create'
 
-    start = StateView('gnuhealth.service.invoice.init',
+    start = StateView(
+        'gnuhealth.service.invoice.init',
         'health_services.view_health_service_invoice', [
             Button('Cancel', 'end', 'tryton-cancel'),
-            Button('Create Invoice', 'create_service_invoice', 'tryton-ok',
-                True),
+            Button('Create Invoice', 'create_service_invoice',
+                   'tryton-ok', True),
             ])
     create_service_invoice = StateTransition()
 
-
     def transition_create_service_invoice(self):
         pool = Pool()
         HealthService = pool.get('gnuhealth.health_service')
         Invoice = pool.get('account.invoice')
         Party = pool.get('party.party')
         Journal = pool.get('account.journal')
+        AcctConfig = pool.get('account.configuration')
+        acct_config = AcctConfig(1)
 
         currency_id = Transaction().context.get('currency')
 
@@ -62,7 +69,7 @@
             'active_ids'))
         invoices = []
 
-        #Invoice Header
+        # Invoice Header
         for service in services:
             if service.state == 'invoiced':
                 raise ServiceAlreadyInvoiced(
@@ -77,9 +84,22 @@
             invoice_data['party'] = party.id
             invoice_data['type'] = 'out'
             invoice_data['invoice_date'] = datetime.date.today()
-            invoice_data['account'] = party.account_receivable.id
             invoice_data['company'] = service.company.id
 
+            """ Look for the AR account in the following order:
+                * Party
+                * Default AR in accounting config
+                * Raise an error if there is no AR account
+            """
+            if (party.account_receivable):
+                invoice_data['account'] = party.account_receivable.id
+            elif (acct_config.default_account_receivable):
+                invoice_data['account'] = \
+                    acct_config.default_account_receivable.id
+            else:
+                raise NoAccountReceivable(
+                    gettext('health_services.msg_no_account_receivable'))
+
             ctx = {}
             sale_price_list = None
             if hasattr(party, 'sale_price_list'):
@@ -115,7 +135,7 @@
 
             invoice_data['payment_term'] = party.customer_payment_term.id
 
-            #Invoice Lines
+            # Invoice Lines
             seq = 0
             invoice_lines = []
             for line in service.service_line:
@@ -124,7 +144,8 @@
 
                 if sale_price_list:
                     with Transaction().set_context(ctx):
-                        unit_price = sale_price_list.compute(party,
+                        unit_price = sale_price_list.compute(
+                            party,
                             line.product, line.product.list_price,
                             line.qty, line.product.default_uom)
                 else:
@@ -132,10 +153,10 @@
 
                 if line.to_invoice:
                     taxes = []
-                    #Include taxes related to the product on the invoice line
+                    # Include taxes related to the product on the invoice line
                     for product_tax_line in line.product.customer_taxes_used:
                         taxes.append(product_tax_line.id)
-                        
+
                     invoice_lines.append(('create', [{
                             'origin': str(line),
                             'product': line.product.id,
@@ -145,7 +166,7 @@
                             'unit': line.product.default_uom.id,
                             'unit_price': unit_price,
                             'sequence': seq,
-                            'taxes': [('add',taxes)],
+                            'taxes': [('add', taxes)],
                         }]))
                 invoice_data['lines'] = invoice_lines