diff --git a/pms/models/__init__.py b/pms/models/__init__.py index 30a479e42..8ee809acd 100644 --- a/pms/models/__init__.py +++ b/pms/models/__init__.py @@ -29,7 +29,6 @@ from . import product_pricelist from . import product_pricelist_item from . import res_partner from . import pms_sale_channel - from . import mail_compose_message from . import pms_room_type_class from . import pms_room_closure_reason diff --git a/pms/models/account_move.py b/pms/models/account_move.py index df9a1d02e..b92f77a42 100644 --- a/pms/models/account_move.py +++ b/pms/models/account_move.py @@ -95,7 +95,6 @@ class AccountMove(models.Model): else: domain.append(("balance", ">", 0.0)) payments_widget_vals["title"] = _("Outstanding debits") - for line in self.env["account.move.line"].search(domain): if line.currency_id == move.currency_id: @@ -134,23 +133,6 @@ class AccountMove(models.Model): ) move.invoice_has_outstanding = True - def action_folio_payments(self): - self.ensure_one() - sales = self.mapped("invoice_line_ids.sale_line_ids.order_id") - folios = self.env["pms.folio"].search([("order_id.id", "in", sales.ids)]) - payments_obj = self.env["account.payment"] - payments = payments_obj.search([("folio_id", "in", folios.ids)]) - payment_ids = payments.mapped("id") - return { - "name": _("Payments"), - "view_type": "form", - "view_mode": "tree,form", - "res_model": "account.payment", - "target": "new", - "type": "ir.actions.act_window", - "domain": [("id", "in", payment_ids)], - } - def _search_default_journal(self, journal_types): """ Search for the default journal based on the journal type and property, @@ -183,3 +165,41 @@ class AccountMove(models.Model): ) raise UserError(error_msg) return journal + + def _autoreconcile_folio_payments(self): + """ + Reconcile payments with the invoice + """ + # TODO: Add setting option to enable automatic payment reconciliation + for move in self.filtered(lambda m: m.state == "posted"): + if move.is_invoice(include_receipts=True) and move.folio_ids: + to_reconcile_payments_widget_vals = json.loads( + move.invoice_outstanding_credits_debits_widget + ) + if not to_reconcile_payments_widget_vals: + continue + current_amounts = { + vals["move_id"]: vals["amount"] + for vals in to_reconcile_payments_widget_vals["content"] + } + pay_term_lines = move.line_ids.filtered( + lambda line: line.account_id.user_type_id.type + in ("receivable", "payable") + ) + to_reconcile = ( + self.env["account.move"] + .browse(list(current_amounts.keys())) + .line_ids.filtered( + lambda line: line.account_id == pay_term_lines.account_id + and line.folio_ids in move.folio_ids + ) + ) + (pay_term_lines + to_reconcile).reconcile() + + def _post(self, soft=True): + """ + Overwrite the original method to add the folio_ids to the invoice + """ + res = super(AccountMove, self)._post(soft) + self._autoreconcile_folio_payments() + return res diff --git a/pms/models/account_move_line.py b/pms/models/account_move_line.py index 36eca2ad6..d917e5f68 100644 --- a/pms/models/account_move_line.py +++ b/pms/models/account_move_line.py @@ -12,7 +12,7 @@ class AccountMoveLine(models.Model): folio_line_ids = fields.Many2many( string="Folio Lines", help="The folio lines in the account move lines", - copy=False, + copy=True, comodel_name="folio.sale.line", relation="folio_sale_line_invoice_rel", column1="invoice_line_id", @@ -91,7 +91,3 @@ class AccountMoveLine(models.Model): # qty=record.quantity) # record.with_context(auto_name=True) # ._compute_name_changed_by_user() - - def _copy_data_extend_business_fields(self, values): - super(AccountMoveLine, self)._copy_data_extend_business_fields(values) - values["folio_line_ids"] = [(6, None, self.folio_line_ids.ids)] diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 1fb0d1b7e..3a7d16d22 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -1004,7 +1004,15 @@ class PmsFolio(models.Model): total = total - sum(record.service_ids.mapped("price_total")) # Compute 'payment_state'. payment_state = "not_paid" - if mls: + if ( + mls + and float_compare( + amount_residual, + total, + precision_rounding=record.currency_id.rounding, + ) + != 0 + ): has_due_amount = float_compare( amount_residual, 0.0, @@ -1689,6 +1697,11 @@ class PmsFolio(models.Model): pay = self.env["account.payment"].create(vals) pay.action_post() + # Review: force to autoreconcile payment with invoices already created + pay.flush() + for move in folio.move_ids: + move._autoreconcile_folio_payments() + # Automatic register payment in cash register if pay_type == "cash": line = self._get_statement_line_vals( diff --git a/pms/views/pms_folio_views.xml b/pms/views/pms_folio_views.xml index 7f0d489bb..cf6f4e163 100644 --- a/pms/views/pms_folio_views.xml +++ b/pms/views/pms_folio_views.xml @@ -538,7 +538,9 @@ + +