diff --git a/account_payment_order/models/account_move_line.py b/account_payment_order/models/account_move_line.py index 40b5ba2309c..dfa7dbcb2fa 100644 --- a/account_payment_order/models/account_move_line.py +++ b/account_payment_order/models/account_move_line.py @@ -29,7 +29,7 @@ class AccountMoveLine(models.Model): def _compute_partner_bank_id(self): for ml in self: if ( - ml.move_id.move_type in ("in_invoice", "in_refund") + ml.move_id.move_type in ("in_invoice", "in_receipt", "in_refund") and not ml.reconciled and ml.payment_mode_id.payment_order_ok and ml.account_id.account_type diff --git a/account_payment_order/models/account_payment_line.py b/account_payment_order/models/account_payment_line.py index 866b8570a01..9429970ba29 100644 --- a/account_payment_order/models/account_payment_line.py +++ b/account_payment_order/models/account_payment_line.py @@ -221,9 +221,9 @@ def _prepare_account_payment_vals(self): vals["payment_method_line_id"] = line.id # Determine partner_type move_type = self[:1].move_line_id.move_id.move_type - if move_type in {"out_invoice", "out_refund"}: + if move_type in {"out_invoice", "out_receipt", "out_refund"}: vals["partner_type"] = "customer" - elif move_type in {"in_invoice", "in_refund"}: + elif move_type in {"in_invoice", "in_receipt", "in_refund"}: vals["partner_type"] = "supplier" else: p_type = "customer" if vals["payment_type"] == "inbound" else "supplier" diff --git a/account_payment_order/tests/test_payment_order_inbound.py b/account_payment_order/tests/test_payment_order_inbound.py index 496b50a6d11..ed639182477 100644 --- a/account_payment_order/tests/test_payment_order_inbound.py +++ b/account_payment_order/tests/test_payment_order_inbound.py @@ -59,14 +59,17 @@ def setUpClass(cls): # Open invoice cls.invoice = cls._create_customer_invoice(cls) cls.invoice.action_post() + # Open receipt + cls.receipt = cls._create_customer_invoice(cls, move_type="out_receipt") + cls.receipt.action_post() # Add to payment order using the wizard cls.env["account.invoice.payment.line.multi"].with_context( active_model="account.move", active_ids=cls.invoice.ids ).create({}).run() - def _create_customer_invoice(self): + def _create_customer_invoice(self, move_type="out_invoice"): with Form( - self.env["account.move"].with_context(default_move_type="out_invoice") + self.env["account.move"].with_context(default_move_type=move_type) ) as invoice_form: invoice_form.partner_id = self.partner with invoice_form.invoice_line_ids.new() as invoice_line_form: @@ -134,6 +137,35 @@ def test_creation(self): payment_order.unlink() self.assertEqual(len(self.payment_order_obj.search(self.domain)), 0) + def test_creation_out_receipt(self): + # Make sure no others orders are present + self.payment_order_obj.search(self.domain).unlink() + # Add to payment order using the wizard + self.env["account.invoice.payment.line.multi"].with_context( + active_model="account.move", active_ids=self.receipt.ids + ).create({}).run() + payment_order = self.payment_order_obj.search(self.domain) + self.assertEqual(len(payment_order.ids), 1) + payment_order.write({"journal_id": self.journal.id}) + self.assertEqual(len(payment_order.payment_line_ids), 1) + self.assertFalse(payment_order.payment_ids) + # Open payment order + payment_order.draft2open() + self.assertEqual(payment_order.payment_count, 1) + # Generate and upload + payment_order.open2generated() + payment_order.generated2uploaded() + self.assertEqual(payment_order.state, "uploaded") + self.assertEqual(self.receipt.payment_state, "in_payment") + with self.assertRaises(UserError): + payment_order.unlink() + # Cancel order + payment_order.action_uploaded_cancel() + self.assertEqual(payment_order.state, "cancel") + payment_order.cancel2draft() + payment_order.unlink() + self.assertEqual(len(self.payment_order_obj.search(self.domain)), 0) + @freeze_time("2024-04-01") def test_creation_transfer_move_date_01(self): self.inbound_order.date_prefered = "fixed" diff --git a/account_payment_order/tests/test_payment_order_outbound.py b/account_payment_order/tests/test_payment_order_outbound.py index 64d2fa2377a..72f7aed27b6 100644 --- a/account_payment_order/tests/test_payment_order_outbound.py +++ b/account_payment_order/tests/test_payment_order_outbound.py @@ -58,6 +58,7 @@ def setUpClass(cls): ) cls.invoice = cls._create_supplier_invoice(cls, "F1242") cls.invoice_02 = cls._create_supplier_invoice(cls, "F1243") + cls.receipt = cls._create_supplier_invoice(cls, "F1244", "in_receipt") cls.bank_journal = cls.company_data["default_journal_bank"] # Make sure no other payment orders are in the DB cls.domain = [ @@ -67,7 +68,7 @@ def setUpClass(cls): ] cls.env["account.payment.order"].search(cls.domain).unlink() - def _create_supplier_invoice(self, ref): + def _create_supplier_invoice(self, ref, move_type="in_invoice"): invoice = self.env["account.move"].create( { "partner_id": self.partner.id, @@ -249,6 +250,37 @@ def test_cancel_payment_order(self): payment_order.unlink() self.assertEqual(len(self.env["account.payment.order"].search(self.domain)), 0) + def test_creation_in_receipt(self): + self.receipt.action_post() + # Make sure no others orders are present + payment_order_obj = self.env["account.payment.order"] + payment_order_obj.search(self.domain).unlink() + # Add to payment order using the wizard + self.env["account.invoice.payment.line.multi"].with_context( + active_model="account.move", active_ids=self.receipt.ids + ).create({}).run() + payment_order = payment_order_obj.search(self.domain) + self.assertEqual(len(payment_order.ids), 1) + payment_order.write({"journal_id": self.bank_journal.id}) + self.assertEqual(len(payment_order.payment_line_ids), 1) + self.assertFalse(payment_order.payment_ids) + # Open payment order + payment_order.draft2open() + self.assertEqual(payment_order.payment_count, 1) + # Generate and upload + payment_order.open2generated() + payment_order.generated2uploaded() + self.assertEqual(payment_order.state, "uploaded") + self.assertEqual(self.receipt.payment_state, "in_payment") + with self.assertRaises(UserError): + payment_order.unlink() + # Cancel order + payment_order.action_uploaded_cancel() + self.assertEqual(payment_order.state, "cancel") + payment_order.cancel2draft() + payment_order.unlink() + self.assertEqual(len(payment_order_obj.search(self.domain)), 0) + def test_constrains(self): outbound_order = self.env["account.payment.order"].create( { diff --git a/account_payment_order/views/account_invoice_view.xml b/account_payment_order/views/account_invoice_view.xml index f3a5b20d193..c48a6d18ad2 100644 --- a/account_payment_order/views/account_invoice_view.xml +++ b/account_payment_order/views/account_invoice_view.xml @@ -21,14 +21,14 @@ type="object" string="Add to Debit Order" groups="account_payment_order.group_account_payment" - invisible="not payment_order_ok or state != 'posted' or move_type not in ('out_invoice', 'out_refund')" + invisible="not payment_order_ok or state != 'posted' or move_type not in ('out_invoice', 'out_receipt', 'out_refund')" />
@@ -55,8 +55,8 @@
@@ -88,7 +88,7 @@ type="action" string="Add to Payment/Debit Order" groups="account_payment_order.group_account_payment" - invisible="context.get('default_move_type') not in ('out_invoice', 'out_refund', 'in_invoice', 'in_refund')" + invisible="context.get('default_move_type') not in ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'in_receipt', 'out_receipt')" /> diff --git a/account_payment_partner/models/account_move.py b/account_payment_partner/models/account_move.py index 984221ae2a7..214497c55db 100644 --- a/account_payment_partner/models/account_move.py +++ b/account_payment_partner/models/account_move.py @@ -36,9 +36,9 @@ class AccountMove(models.Model): @api.depends("move_type") def _compute_payment_mode_filter_type_domain(self): for move in self: - if move.move_type in ("out_invoice", "in_refund"): + if move.move_type in ("out_invoice", "out_receipt", "in_refund"): move.payment_mode_filter_type_domain = "inbound" - elif move.move_type in ("in_invoice", "out_refund"): + elif move.move_type in ("in_invoice", "in_receipt", "out_refund"): move.payment_mode_filter_type_domain = "outbound" else: move.payment_mode_filter_type_domain = False @@ -46,9 +46,9 @@ def _compute_payment_mode_filter_type_domain(self): @api.depends("partner_id", "move_type") def _compute_partner_bank_filter_type_domain(self): for move in self: - if move.move_type in ("out_invoice", "in_refund"): + if move.move_type in ("out_invoice", "out_receipt", "in_refund"): move.partner_bank_filter_type_domain = move.bank_partner_id - elif move.move_type in ("in_invoice", "out_refund"): + elif move.move_type in ("in_invoice", "in_receipt", "out_refund"): move.partner_bank_filter_type_domain = move.commercial_partner_id else: move.partner_bank_filter_type_domain = False @@ -60,10 +60,14 @@ def _compute_payment_mode_id(self): move.payment_mode_id = False if move.partner_id: partner = move.with_company(move.company_id.id).partner_id - if move.move_type == "in_invoice" and partner.supplier_payment_mode_id: + if ( + move.move_type in ["in_invoice", "in_receipt"] + and partner.supplier_payment_mode_id + ): move.payment_mode_id = partner.supplier_payment_mode_id elif ( - move.move_type == "out_invoice" and partner.customer_payment_mode_id + move.move_type in ["out_invoice", "out_receipt"] + and partner.customer_payment_mode_id ): move.payment_mode_id = partner.customer_payment_mode_id elif ( @@ -97,13 +101,13 @@ def _compute_partner_bank_id(self): payment_mode = move.payment_mode_id if payment_mode: if ( - move.move_type == "in_invoice" + move.move_type in ["in_invoice", "in_receipt"] and payment_mode.payment_type == "outbound" and not payment_mode.payment_method_id.bank_account_required ): move.partner_bank_id = False continue - elif move.move_type == "out_invoice": + elif move.move_type in ["out_invoice", "out_receipt"]: if payment_mode.payment_method_id.bank_account_required: if ( payment_mode.bank_account_link == "fixed" diff --git a/account_payment_partner/models/account_move_line.py b/account_payment_partner/models/account_move_line.py index 0fb81d6177e..fff669059fc 100644 --- a/account_payment_partner/models/account_move_line.py +++ b/account_payment_partner/models/account_move_line.py @@ -19,7 +19,7 @@ class AccountMoveLine(models.Model): @api.depends("move_id", "move_id.payment_mode_id") def _compute_payment_mode(self): for line in self: - if line.move_id.is_invoice() and line.account_type in ( + if line.move_id.is_invoice(include_receipts=True) and line.account_type in ( "asset_receivable", "liability_payable", ): @@ -35,9 +35,8 @@ def write(self, vals): self.env["account.move"].browse(vals.get("move_id", 0)) or record.move_id ) - if ( - move.payment_mode_id.id != vals["payment_mode_id"] - and move.is_invoice() - ): + if move.payment_mode_id.id != vals[ + "payment_mode_id" + ] and move.is_invoice(include_receipts=True): move.payment_mode_id = vals["payment_mode_id"] return super().write(vals) diff --git a/account_payment_partner/tests/test_account_payment_partner.py b/account_payment_partner/tests/test_account_payment_partner.py index 6db7ed4e898..6c3f5faafd5 100644 --- a/account_payment_partner/tests/test_account_payment_partner.py +++ b/account_payment_partner/tests/test_account_payment_partner.py @@ -303,6 +303,42 @@ def test_invoice_create_in_refund(self): self.supplier.supplier_payment_mode_id.refund_payment_mode_id, ) + def test_invoice_create_in_receipt(self): + invoice = self._create_invoice( + default_move_type="in_receipt", partner=self.supplier + ) + invoice.action_post() + aml = invoice.line_ids.filtered( + lambda x: x.account_id.account_type == "liability_payable" + ) + self.assertEqual(invoice.payment_mode_id, aml[0].payment_mode_id) + # Test payment mode change on aml + mode = self.supplier_payment_mode.copy() + aml.payment_mode_id = mode + self.assertEqual(invoice.payment_mode_id, mode) + # Test payment mode editability on account move + self.assertFalse(invoice.has_reconciled_items) + invoice.payment_mode_id = self.supplier_payment_mode + self.assertEqual(aml.payment_mode_id, self.supplier_payment_mode) + + def test_invoice_create_out_receipt(self): + invoice = self._create_invoice( + default_move_type="out_receipt", partner=self.supplier + ) + invoice.action_post() + aml = invoice.line_ids.filtered( + lambda x: x.account_id.account_type == "asset_receivable" + ) + self.assertEqual(invoice.payment_mode_id, aml[0].payment_mode_id) + # Test payment mode change on aml + mode = self.supplier_payment_mode.copy() + aml.payment_mode_id = mode + self.assertEqual(invoice.payment_mode_id, mode) + # Test payment mode editability on account move + self.assertFalse(invoice.has_reconciled_items) + invoice.payment_mode_id = self.supplier_payment_mode + self.assertEqual(aml.payment_mode_id, self.supplier_payment_mode) + def test_invoice_constrains(self): with self.assertRaises(UserError): self.move_model.create( @@ -446,6 +482,12 @@ def test_partner_onchange(self): vals = {"partner_id": self.supplier.id, "move_type": "in_refund"} invoice = self.move_model.new(vals) self.assertEqual(invoice.payment_mode_id, self.customer_payment_mode) + vals = {"partner_id": self.supplier.id, "move_type": "in_receipt"} + invoice = self.move_model.new(vals) + self.assertEqual(invoice.payment_mode_id, self.supplier_payment_mode) + vals = {"partner_id": self.customer.id, "move_type": "out_receipt"} + invoice = self.move_model.new(vals) + self.assertEqual(invoice.payment_mode_id, self.customer_payment_mode) vals = {"partner_id": False, "move_type": "out_invoice"} invoice = self.move_model.new(vals) self.assertFalse(invoice.payment_mode_id) @@ -532,6 +574,28 @@ def test_filter_type_domain(self): self.assertEqual( out_invoice.partner_bank_filter_type_domain, out_invoice.bank_partner_id ) + in_receipt = self.move_model.create( + { + "partner_id": self.supplier.id, + "move_type": "in_receipt", + "journal_id": self.journal_purchase.id, + } + ) + self.assertEqual(in_receipt.payment_mode_filter_type_domain, "outbound") + self.assertEqual( + in_receipt.partner_bank_filter_type_domain, in_receipt.bank_partner_id + ) + out_receipt = self.move_model.create( + { + "partner_id": self.customer.id, + "move_type": "out_receipt", + "journal_id": self.journal_sale.id, + } + ) + self.assertEqual(out_receipt.payment_mode_filter_type_domain, "inbound") + self.assertEqual( + out_receipt.partner_bank_filter_type_domain, out_receipt.bank_partner_id + ) def test_account_move_payment_mode_id_default(self): payment_mode = self.env["account.payment.mode"].create( diff --git a/account_payment_partner/views/account_move_view.xml b/account_payment_partner/views/account_move_view.xml index 23c1d5e4685..0aced78ffa7 100644 --- a/account_payment_partner/views/account_move_view.xml +++ b/account_payment_partner/views/account_move_view.xml @@ -29,7 +29,7 @@ domain="[('payment_type', '=', payment_mode_filter_type_domain), ('company_id', '=', company_id)]" widget="selection" readonly="has_reconciled_items" - invisible="move_type not in ['out_invoice','out_refund','in_invoice','in_refund']" + invisible="move_type not in ['out_invoice','out_refund','in_invoice','in_refund', 'out_receipt', 'in_receipt']" />