From 761928889231eabf4df479d00f530360fd1f689d Mon Sep 17 00:00:00 2001 From: Miguel Padin Date: Sun, 7 Mar 2021 15:23:29 +0100 Subject: [PATCH] [IMP] allow invoicing several partners from folio (#64) field partner_invoice_id (m2o)->partner_invoice_ids(m2m) --- pms/models/pms_folio.py | 46 ++++++++++++------- pms/report/pms_folio_templates.xml | 6 ++- pms/tests/test_pms_folio_invoice.py | 46 +++++++++++++++++++ pms/views/pms_folio_views.xml | 6 +-- pms/wizards/folio_make_invoice_advance.py | 21 ++++++++- .../folio_make_invoice_advance_views.xml | 1 + 6 files changed, 103 insertions(+), 23 deletions(-) diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index c1578b37d..eff7eca71 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -212,18 +212,22 @@ class PmsFolio(models.Model): tracking=True, compute="_compute_amount", ) - partner_invoice_id = fields.Many2one( - "res.partner", - string="Invoice Address", - compute="_compute_partner_invoice_id", + partner_invoice_ids = fields.Many2many( + string="Billing addresses", + comodel_name="res.partner", + relation="pms_folio_partner_rel", + column1="folio", + column2="partner", + compute="_compute_partner_invoice_ids", store=True, readonly=False, help="Invoice address for current group.", ) - partner_invoice_state_id = fields.Many2one(related="partner_invoice_id.state_id") - partner_invoice_country_id = fields.Many2one( - related="partner_invoice_id.country_id" - ) + # REVIEW THIS + # partner_invoice_state_id = fields.Many2one(related="partner_invoice_id.state_id") + # partner_invoice_country_id = fields.Many2one( + # related="partner_invoice_id.country_id" + # ) fiscal_position_id = fields.Many2one( "account.fiscal.position", string="Fiscal Position" ) @@ -477,11 +481,12 @@ class PmsFolio(models.Model): folio.user_id = (folio.partner_id.user_id.id or self.env.uid,) @api.depends("partner_id") - def _compute_partner_invoice_id(self): - self.partner_invoice_id = False + def _compute_partner_invoice_ids(self): for folio in self: + folio.partner_invoice_ids = False addr = folio.partner_id.address_get(["invoice"]) - folio.partner_invoice_id = addr["invoice"] + if not addr["invoice"] in folio.partner_invoice_ids.ids: + folio.partner_invoice_ids = [(4, addr["invoice"])] @api.depends("partner_id") def _compute_payment_term_id(self): @@ -885,7 +890,7 @@ class PmsFolio(models.Model): ) record.checkin_partner_pending_count = sum(mapped_checkin_partner_count) - def _prepare_invoice(self): + def _prepare_invoice(self, partner_invoice_id=False): """ Prepare the dict of values to create the new invoice for a folio. This method may be overridden to implement custom invoice generation @@ -912,7 +917,9 @@ class PmsFolio(models.Model): # 'medium_id': self.medium_id.id, # 'source_id': self.source_id.id, "invoice_user_id": self.user_id and self.user_id.id, - "partner_id": self.partner_invoice_id.id, + "partner_id": partner_invoice_id + if partner_invoice_id + else self.partner_invoice_ids[0], "partner_bank_id": self.company_id.partner_id.bank_ids[:1].id, "journal_id": journal.id, # company comes from the journal "invoice_origin": self.name, @@ -986,12 +993,13 @@ class PmsFolio(models.Model): final=False, date=None, lines_to_invoice=False, + partner_invoice_id=False, ): """ Create the invoice associated to the Folio. :param grouped: if True, invoices are grouped by Folio id. If False, invoices are grouped by - (partner_invoice_id, currency) + (partner_invoice_ids, currency) :param final: if True, refunds will be generated if necessary :param lines_to_invoice: invoice specific lines dict(key=id, value=qty). if False, invoice all @@ -1011,7 +1019,9 @@ class PmsFolio(models.Model): 0 if line.display_type else line.qty_to_invoice ) invoice_vals_list = self.get_invoice_vals_list( - final=final, lines_to_invoice=lines_to_invoice + final=final, + lines_to_invoice=lines_to_invoice, + partner_invoice_id=partner_invoice_id, ) if not invoice_vals_list: @@ -1118,7 +1128,9 @@ class PmsFolio(models.Model): ) return moves - def get_invoice_vals_list(self, final=False, lines_to_invoice=False): + def get_invoice_vals_list( + self, final=False, lines_to_invoice=False, partner_invoice_id=False + ): precision = self.env["decimal.precision"].precision_get( "Product Unit of Measure" ) @@ -1130,7 +1142,7 @@ class PmsFolio(models.Model): down_payments = order.env["folio.sale.line"] # Invoice values. - invoice_vals = order._prepare_invoice() + invoice_vals = order._prepare_invoice(partner_invoice_id=partner_invoice_id) # Invoice line values (keep only necessary sections). invoice_lines_vals = [] diff --git a/pms/report/pms_folio_templates.xml b/pms/report/pms_folio_templates.xml index 23e163bab..e110e8955 100644 --- a/pms/report/pms_folio_templates.xml +++ b/pms/report/pms_folio_templates.xml @@ -6,9 +6,11 @@
- +
diff --git a/pms/tests/test_pms_folio_invoice.py b/pms/tests/test_pms_folio_invoice.py index d5e3f6f01..6fbc69207 100644 --- a/pms/tests/test_pms_folio_invoice.py +++ b/pms/tests/test_pms_folio_invoice.py @@ -132,6 +132,52 @@ class TestPmsFolioInvoice(TestHotel): "The status after an invoicing is not correct", ) + def test_invoice_partial_folio_diferent_partners(self): + # ARRANGE + self.create_common_scenario() + r1 = self.env["pms.reservation"].create( + { + "pms_property_id": self.property.id, + "checkin": datetime.datetime.now(), + "checkout": datetime.datetime.now() + datetime.timedelta(days=3), + "adults": 2, + "room_type_id": self.room_type_double.id, + "partner_id": self.env.ref("base.res_partner_12").id, + } + ) + dict_lines = dict() + # qty to 1 to 1st folio sale line + dict_lines[ + r1.folio_id.sale_line_ids.filtered(lambda l: not l.display_type)[0].id + ] = 1 + r1.folio_id._create_invoices( + lines_to_invoice=dict_lines, + partner_invoice_id=self.env.ref("base.res_partner_1"), + ) + + # test does not work without invalidating cache + self.env["account.move"].invalidate_cache() + + self.assertNotEqual( + "invoiced", + r1.folio_id.invoice_status, + "The status after a partial invoicing is not correct", + ) + + # qty to 2 to 1st folio sale line + dict_lines[ + r1.folio_id.sale_line_ids.filtered(lambda l: not l.display_type)[0].id + ] = 2 + r1.folio_id._create_invoices( + lines_to_invoice=dict_lines, + partner_invoice_id=self.env.ref("base.res_partner_12"), + ) + self.assertNotEqual( + r1.folio_id.move_ids.mapped("partner_id")[0], + r1.folio_id.move_ids.mapped("partner_id")[1], + "The status after an invoicing is not correct", + ) + def test_invoice_partial_folio_wrong_qtys(self): # ARRANGE self.create_common_scenario() diff --git a/pms/views/pms_folio_views.xml b/pms/views/pms_folio_views.xml index d68cfd691..f6e12ad30 100644 --- a/pms/views/pms_folio_views.xml +++ b/pms/views/pms_folio_views.xml @@ -381,7 +381,7 @@
@@ -484,7 +484,7 @@ - + +