oca-financial/odoo-bringout-oca-account-invoicing-account_receipt_journal/account_receipt_journal/models/account_move.py
2025-08-29 15:43:04 +02:00

117 lines
5 KiB
Python

from odoo import _, api, exceptions, models
class AccountMove(models.Model):
_inherit = "account.move"
@api.depends("company_id", "invoice_filter_type_domain", "move_type")
def _compute_suitable_journal_ids(self):
res = super()._compute_suitable_journal_ids()
for m in self:
dedicated_journals = m.suitable_journal_ids.filtered(
lambda j: j.receipts == m.move_type in {"out_receipt", "in_receipt"}
)
# Suitable journals dedicated to receipts if exists
m.suitable_journal_ids = dedicated_journals or m.suitable_journal_ids
return res
@api.model
def _search_default_receipt_journal(self, journal_types):
company_id = self.env.context.get("default_company_id", self.env.company.id)
currency_id = self.env.context.get("default_currency_id")
domain = [
("company_id", "=", company_id),
("type", "in", journal_types),
("receipts", "=", True),
]
journal = None
if currency_id:
journal = self.env["account.journal"].search(
domain + [("currency_id", "=", currency_id)], limit=1
)
if not journal:
journal = self.env["account.journal"].search(domain, limit=1)
return journal
@api.model
def _search_default_journal(self):
journal = super()._search_default_journal()
move_type = self.env.context.get("default_move_type")
journal_types = self._get_journal_types(move_type)
# We can assume that if move_type is not in receipts, a journal without
# receipts it's coming because of the Journal constraint
if move_type not in {"in_receipt", "out_receipt"} or journal.receipts:
return journal
return self._search_default_receipt_journal(journal_types) or journal
def _get_journal_types(self, move_type):
if move_type in self.get_sale_types(include_receipts=True):
journal_types = ["sale"]
elif move_type in self.get_purchase_types(include_receipts=True):
journal_types = ["purchase"]
else:
journal_types = self.env.context.get(
"default_move_journal_types", ["general"]
)
return journal_types
@api.model
def _update_receipts_journal(self, vals_list):
"""
Update `vals_list` in place to set journal_id to the receipt journal
when move_type is receipt.
Model defaults are also considered it move_type or journal_id
are not in a `vals_list`.
"""
defaults = self.default_get(["journal_id", "move_type"])
default_journal = defaults.get("journal_id")
default_move_type = defaults.get("move_type")
for vals in vals_list:
move_type = vals.get("move_type", default_move_type)
if move_type in ("in_receipt", "out_receipt"):
selected_journal_id = vals.get("journal_id", default_journal)
selected_journal = self.env["account.journal"].browse(
selected_journal_id
)
if not selected_journal.receipts:
journal_types = self._get_journal_types(move_type)
receipt_journal = self._search_default_receipt_journal(
journal_types
)
if receipt_journal:
vals["journal_id"] = receipt_journal.id
@api.model_create_multi
def create(self, vals_list):
self._update_receipts_journal(vals_list)
return super().create(vals_list)
@api.constrains("move_type", "journal_id")
def _check_receipts_journal(self):
"""Ensure that Receipt Journal is only used in Receipts
if exists Receipt Journals for its type"""
aj_model = self.env["account.journal"]
receipt_domain = [("receipts", "=", True)]
has_in_rjournals = aj_model.search([("type", "=", "purchase")] + receipt_domain)
has_out_rjournals = aj_model.search([("type", "=", "sale")] + receipt_domain)
for move in self:
is_rj = move.journal_id.receipts
if move.move_type not in {"in_receipt", "out_receipt"} and is_rj:
raise exceptions.ValidationError(
_("Receipt Journal is restricted to Receipts")
)
elif move.move_type == "in_receipt" and not is_rj and has_in_rjournals:
raise exceptions.ValidationError(
_(
"Purchase Receipt must use a Receipt Journal because "
"there is already a Receipt Journal for Purchases"
)
)
elif move.move_type == "out_receipt" and not is_rj and has_out_rjournals:
raise exceptions.ValidationError(
_(
"Sale Receipt must use a Receipt Journal because "
"there is already a Receipt Journal for Sales"
)
)