Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association
=================
Receipts Journals
=================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4a249c844fc710ef3ce91a05fc2adff38e6dc9fb022b54d12112765c50997300
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github
:target: https://github.com/OCA/account-invoicing/tree/18.0/account_receipt_journal
:alt: OCA/account-invoicing
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-invoicing-18-0/account-invoicing-18-0-account_receipt_journal
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/account-invoicing&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
Define journals exclusive to receipts and automatically use them in sale
and purchase receipts A normal journal cannot be used in receipts if a
receipt journal has been created.
**Table of contents**
.. contents::
:local:
Known issues / Roadmap
======================
Dashboard Kanban View Pending Items Roadmap
=============================================
1. Drag & Drop Functionality
- Goal: Override the JS so that when files are uploaded a ``receipt`` is
created instead of a vendor bill.
- Reference: `bill_guide.js line
29 <https://github.com/odoo/odoo/blob/d26148acaee5b5c995155780ec3993c5ae7210e6/addons/account/static/src/components/bill_guide/bill_guide.js#L29>`__
2. "Try our Sample" Button
- Goal: Adapt the method to generate an editable ``receipt`` instead of
a vendor bill.
- Reference: `account_journal_dashboard.py line
922 <https://github.com/odoo/odoo/blob/d26148acaee5b5c995155780ec3993c5ae7210e6/addons/account/models/account_journal_dashboard.py#L922>`__
Changelog
=========
This module partially comes from module l10n_it_corrispettivi of
https://github.com/OCA/l10n-italy version 12.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-invoicing/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-invoicing/issues/new?body=module:%20account_receipt_journal%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* TAKOBI
Contributors
------------
- `TAKOBI <https://takobi.online>`__:
- Lorenzo Battistini
- `Moduon <https://www.moduon.team>`__:
- Eduardo de Miguel
- Rafael Blasco
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-eLBati| image:: https://github.com/eLBati.png?size=40px
:target: https://github.com/eLBati
:alt: eLBati
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-eLBati|
This module is part of the `OCA/account-invoicing <https://github.com/OCA/account-invoicing/tree/18.0/account_receipt_journal>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,17 @@
from . import models
from openupgradelib import openupgrade
def rename_old_italian_data(env):
if not openupgrade.is_module_installed(env.cr, "l10n_it_corrispettivi"):
return
openupgrade.rename_xmlids(
env.cr,
[
(
"l10n_it_corrispettivi.corrispettivi_journal",
"account_receipt_journal.sale_receipts_journal",
),
],
)

View File

@@ -0,0 +1,28 @@
# Copyright 2022 Lorenzo Battistini - TAKOBI
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
{
"name": "Receipts Journals",
"summary": "Define and use journals dedicated to receipts",
"version": "18.0.1.1.0",
"development_status": "Beta",
"category": "Accounting & Finance",
"website": "https://github.com/OCA/account-invoicing",
"author": "TAKOBI, Odoo Community Association (OCA)",
"maintainers": ["eLBati"],
"license": "LGPL-3",
"application": False,
"installable": True,
"preloadable": True,
"depends": [
"account",
],
"data": [
"views/account_journal_views.xml",
],
"pre_init_hook": "rename_old_italian_data",
"external_dependencies": {
"python": [
"openupgradelib",
],
},
}

View File

@@ -0,0 +1,100 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_receipt_journal
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_chart_template
msgid "Account Chart Template"
msgstr ""
#. module: account_receipt_journal
#: model:ir.model.fields,field_description:account_receipt_journal.field_account_journal__receipts
msgid "Exclusive to Receipts"
msgstr ""
#. module: account_receipt_journal
#: model:ir.model.fields,help:account_receipt_journal.field_account_journal__receipts
msgid ""
"If checked, this journal will be used by default for receipts and only can "
"be used for receipts."
msgstr ""
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_journal
msgid "Journal"
msgstr ""
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_move
msgid "Journal Entry"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "P-REC"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid ""
"Purchase Receipt must use a Receipt Journal because there is already a "
"Receipt Journal for Purchases"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "Purchase Receipts Journal"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid "Receipt Journal is restricted to Receipts"
msgstr ""
#. module: account_receipt_journal
#: model_terms:ir.ui.view,arch_db:account_receipt_journal.view_account_journal_form_receipts
msgid "Receipts"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "S-REC"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid ""
"Sale Receipt must use a Receipt Journal because there is already a Receipt "
"Journal for Sales"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "Sale Receipts Journal"
msgstr ""
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_journal.py:0
msgid ""
"The sequence of the journal '%s' must be higher than the sequence of the "
"other journals of the same type."
msgstr ""

View File

@@ -0,0 +1,112 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_receipt_journal
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-14 11:05+0000\n"
"PO-Revision-Date: 2025-10-14 13:31+0200\n"
"Last-Translator: Emilio Pascual <emilio@moduon.team>\n"
"Language-Team: none\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Poedit 3.5\n"
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_chart_template
msgid "Account Chart Template"
msgstr "Plantilla de plan contable"
#. module: account_receipt_journal
#: model:ir.model.fields,field_description:account_receipt_journal.field_account_journal__receipts
msgid "Exclusive to Receipts"
msgstr "Exclusivo para recibos"
#. module: account_receipt_journal
#: model:ir.model.fields,help:account_receipt_journal.field_account_journal__receipts
msgid ""
"If checked, this journal will be used by default for receipts and only can "
"be used for receipts."
msgstr ""
"Si se marca, este diario se utilizará por defecto para los recibos y sólo "
"podrá utilizarse para recibos."
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_journal
msgid "Journal"
msgstr "Diario"
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_move
msgid "Journal Entry"
msgstr "Entrada Diaria"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "P-REC"
msgstr "C-REC"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid ""
"Purchase Receipt must use a Receipt Journal because there is already a "
"Receipt Journal for Purchases"
msgstr ""
"El comprobante de compras debe utilizar un diario de comprobantes porque ya "
"existe un diario de comprobantes para las compras"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "Purchase Receipts Journal"
msgstr "Recibos de compra"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid "Receipt Journal is restricted to Receipts"
msgstr "El diario de Recibos se limita a los Recibos"
#. module: account_receipt_journal
#: model_terms:ir.ui.view,arch_db:account_receipt_journal.view_account_journal_form_receipts
msgid "Receipts"
msgstr "Recibos"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "S-REC"
msgstr "V-REC"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid ""
"Sale Receipt must use a Receipt Journal because there is already a Receipt "
"Journal for Sales"
msgstr ""
"El Comprobante de Venta debe utilizar un Diario de Comprobantes porque ya "
"existe un Diario de Comprobantes para Ventas"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "Sale Receipts Journal"
msgstr "Recibos de venta"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_journal.py:0
msgid ""
"The sequence of the journal '%s' must be higher than the sequence of the "
"other journals of the same type."
msgstr ""
"La secuencia del diario '%s' debe ser superior a la secuencia de los demás "
"diarios del mismo tipo."

View File

@@ -0,0 +1,111 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_receipt_journal
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-10-27 10:08+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_chart_template
msgid "Account Chart Template"
msgstr "Modello foglio conto"
#. module: account_receipt_journal
#: model:ir.model.fields,field_description:account_receipt_journal.field_account_journal__receipts
msgid "Exclusive to Receipts"
msgstr "Esclusivo per le ricevute"
#. module: account_receipt_journal
#: model:ir.model.fields,help:account_receipt_journal.field_account_journal__receipts
msgid ""
"If checked, this journal will be used by default for receipts and only can "
"be used for receipts."
msgstr ""
"Se selezionata, questo registro verrà utilizzato in modo predefinito e "
"solamente per le ricevute."
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_journal
msgid "Journal"
msgstr "Registro"
#. module: account_receipt_journal
#: model:ir.model,name:account_receipt_journal.model_account_move
msgid "Journal Entry"
msgstr "Registrazione contabile"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "P-REC"
msgstr "P-REC"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid ""
"Purchase Receipt must use a Receipt Journal because there is already a "
"Receipt Journal for Purchases"
msgstr ""
"La ricevuta di acquisto deve utilizzare il registro ricevute acquisti perchè "
"esiste già"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "Purchase Receipts Journal"
msgstr "Registro ricevute acquisto"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid "Receipt Journal is restricted to Receipts"
msgstr "Il registro ricevute è riservato alle ricevute"
#. module: account_receipt_journal
#: model_terms:ir.ui.view,arch_db:account_receipt_journal.view_account_journal_form_receipts
msgid "Receipts"
msgstr "Ricevute"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "S-REC"
msgstr "S-REC"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_move.py:0
msgid ""
"Sale Receipt must use a Receipt Journal because there is already a Receipt "
"Journal for Sales"
msgstr ""
"La ricevuta di vendita deve utilizzare un registro ricevuta vendite perché "
"esiste già"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_chart_template.py:0
msgid "Sale Receipts Journal"
msgstr "Registro ricevute vendite"
#. module: account_receipt_journal
#. odoo-python
#: code:addons/account_receipt_journal/models/account_journal.py:0
msgid ""
"The sequence of the journal '%s' must be higher than the sequence of the "
"other journals of the same type."
msgstr ""
"La sequenza del registro '%s' deve essere superiore della sequenza "
"dell'altro registro dello stesso tipo."

View File

@@ -0,0 +1,29 @@
# Copyright 2025 Moduon Team S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from openupgradelib import openupgrade
@openupgrade.migrate()
def migrate(env, version):
xml_spec = []
sale_journal_xmlid = "account_receipt_journal.sale_receipts_journal"
purchase_journal_xmlid = "account_receipt_journal.purchase_receipts_journal"
sale_journal = env.ref(sale_journal_xmlid, raise_if_not_found=False)
purchase_journal = env.ref(purchase_journal_xmlid, raise_if_not_found=False)
if sale_journal:
xml_spec.append(
(
sale_journal_xmlid,
f"account.{sale_journal.company_id.id}_sale_receipt_journal",
)
)
if purchase_journal:
xml_spec.append(
(
purchase_journal_xmlid,
f"account.{purchase_journal.company_id.id}_purchase_receipts_journal",
)
)
if xml_spec:
openupgrade.rename_xmlids(env.cr, xml_spec)

View File

@@ -0,0 +1,3 @@
from . import account_journal
from . import account_move
from . import account_chart_template

View File

@@ -0,0 +1,29 @@
# Copyright 2025 Moduon Team S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo import models
from odoo.addons.account.models.chart_template import template
class AccountChartTemplate(models.AbstractModel):
_inherit = "account.chart.template"
@template(model="account.journal")
def _get_account_receipt_journal(self, template_code):
return {
"sale_receipts": {
"name": self.env._("Sale Receipts Journal"),
"code": self.env._("S-REC"),
"type": "sale",
"sequence": 99,
"receipts": True,
},
"purchase_receipts": {
"name": self.env._("Purchase Receipts Journal"),
"code": self.env._("P-REC"),
"type": "purchase",
"sequence": 99,
"receipts": True,
},
}

View File

@@ -0,0 +1,66 @@
from odoo import _, api, exceptions, fields, models
class AccountJournal(models.Model):
_inherit = "account.journal"
receipts = fields.Boolean(
string="Exclusive to Receipts",
help="If checked, this journal will be used by default for receipts "
"and only can be used for receipts.",
)
def _get_move_action_context(self):
res = super()._get_move_action_context()
ctx = self._context.copy()
journal = self or self.browse(ctx["default_journal_id"])
if not journal or not journal.receipts:
return res
if journal.type == "sale":
res["default_move_type"] = "out_receipt"
elif journal.type == "purchase":
res["default_move_type"] = "in_receipt"
return res
def open_action(self):
"""Create a new Receipt from the Dashboard
Button link in name of journal
"""
res = super().open_action()
if not self.receipts:
return res
if self.type == "sale":
res["context"]["default_move_type"] = "out_receipt"
res["domain"] = [("move_type", "=", "out_receipt")]
elif self.type == "purchase":
res["context"]["default_move_type"] = "in_receipt"
res["domain"] = [("move_type", "=", "in_receipt")]
return res
@api.constrains("sequence", "type", "receipts", "company_id")
def _check_receipts_sequence(self):
"""Ensure that journals with receipts checked, are on a higher sequence
that the rest of journals of the same type"""
for receipt_journal in self.filtered("receipts"):
journals = self.search(
[
("type", "=", receipt_journal.type),
("receipts", "=", False),
# ("sequence", "<", journal.sequence),
("id", "!=", receipt_journal.id),
("company_id", "=", receipt_journal.company_id.id),
]
)
if not journals:
continue
previous_sequence_journals = journals.filtered(
lambda j, r=receipt_journal: j.sequence < r.sequence
)
if not previous_sequence_journals:
raise exceptions.ValidationError(
_(
"The sequence of the journal '%s' must be higher than "
"the sequence of the other journals of the same type."
)
% receipt_journal.name
)

View File

@@ -0,0 +1,119 @@
from odoo import _, api, exceptions, models
class AccountMove(models.Model):
_inherit = "account.move"
@api.depends("company_id", "invoice_filter_type_domain")
def _compute_suitable_journal_ids(self):
res = super()._compute_suitable_journal_ids()
for move in self:
if move.move_type in {"in_receipt", "out_receipt"}:
move.suitable_journal_ids = move.suitable_journal_ids.filtered(
"receipts"
)
continue
move.suitable_journal_ids = move.suitable_journal_ids.filtered(
lambda x: not x.receipts
)
return res
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
def _search_default_journal(self):
journal = super()._search_default_journal()
# We can assume that if move_type is not in receipts, a journal without
# receipts it's coming because of the Journal constraint
if self.move_type not in {"in_receipt", "out_receipt"} or journal.receipts:
return journal
journal_types = self._get_valid_journal_types()
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"
)
)

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,5 @@
- [TAKOBI](https://takobi.online):
- Lorenzo Battistini
- [Moduon](https://www.moduon.team):
- Eduardo de Miguel
- Rafael Blasco

View File

@@ -0,0 +1,3 @@
Define journals exclusive to receipts and automatically use them in sale
and purchase receipts A normal journal cannot be used in receipts if a
receipt journal has been created.

View File

@@ -0,0 +1,2 @@
This module partially comes from module l10n_it_corrispettivi of
<https://github.com/OCA/l10n-italy> version 12.

View File

@@ -0,0 +1,11 @@
# Dashboard Kanban View Pending Items Roadmap
1. Drag & Drop Functionality
- Goal: Override the JS so that when files are uploaded a `receipt` is created instead of a vendor bill.
- Reference: [bill_guide.js line 29](https://github.com/odoo/odoo/blob/d26148acaee5b5c995155780ec3993c5ae7210e6/addons/account/static/src/components/bill_guide/bill_guide.js#L29)
2. "Try our Sample" Button
- Goal: Adapt the method to generate an editable `receipt` instead of a vendor bill.
- Reference: [account_journal_dashboard.py line 922](https://github.com/odoo/odoo/blob/d26148acaee5b5c995155780ec3993c5ae7210e6/addons/account/models/account_journal_dashboard.py#L922)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,473 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="receipts-journals">
<h1>Receipts Journals</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4a249c844fc710ef3ce91a05fc2adff38e6dc9fb022b54d12112765c50997300
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/license-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-invoicing/tree/18.0/account_receipt_journal"><img alt="OCA/account-invoicing" src="https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-invoicing-18-0/account-invoicing-18-0-account_receipt_journal"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-invoicing&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Define journals exclusive to receipts and automatically use them in sale
and purchase receipts A normal journal cannot be used in receipts if a
receipt journal has been created.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-1">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#dashboard-kanban-view-pending-items-roadmap" id="toc-entry-2">Dashboard Kanban View Pending Items Roadmap</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-3">Changelog</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="known-issues-roadmap">
<h2><a class="toc-backref" href="#toc-entry-1">Known issues / Roadmap</a></h2>
</div>
<div class="section" id="dashboard-kanban-view-pending-items-roadmap">
<h2><a class="toc-backref" href="#toc-entry-2">Dashboard Kanban View Pending Items Roadmap</a></h2>
<ol class="arabic simple">
<li>Drag &amp; Drop Functionality</li>
</ol>
<ul class="simple">
<li>Goal: Override the JS so that when files are uploaded a <tt class="docutils literal">receipt</tt> is
created instead of a vendor bill.</li>
<li>Reference: <a class="reference external" href="https://github.com/odoo/odoo/blob/d26148acaee5b5c995155780ec3993c5ae7210e6/addons/account/static/src/components/bill_guide/bill_guide.js#L29">bill_guide.js line
29</a></li>
</ul>
<ol class="arabic simple" start="2">
<li>“Try our Sample” Button</li>
</ol>
<ul class="simple">
<li>Goal: Adapt the method to generate an editable <tt class="docutils literal">receipt</tt> instead of
a vendor bill.</li>
<li>Reference: <a class="reference external" href="https://github.com/odoo/odoo/blob/d26148acaee5b5c995155780ec3993c5ae7210e6/addons/account/models/account_journal_dashboard.py#L922">account_journal_dashboard.py line
922</a></li>
</ul>
</div>
<div class="section" id="changelog">
<h2><a class="toc-backref" href="#toc-entry-3">Changelog</a></h2>
<p>This module partially comes from module l10n_it_corrispettivi of
<a class="reference external" href="https://github.com/OCA/l10n-italy">https://github.com/OCA/l10n-italy</a> version 12.</p>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-invoicing/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-invoicing/issues/new?body=module:%20account_receipt_journal%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-5">Credits</a></h2>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-6">Authors</a></h3>
<ul class="simple">
<li>TAKOBI</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
<ul class="simple">
<li><a class="reference external" href="https://takobi.online">TAKOBI</a>:<ul>
<li>Lorenzo Battistini</li>
</ul>
</li>
<li><a class="reference external" href="https://www.moduon.team">Moduon</a>:<ul>
<li>Eduardo de Miguel</li>
<li>Rafael Blasco</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/eLBati"><img alt="eLBati" src="https://github.com/eLBati.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-invoicing/tree/18.0/account_receipt_journal">OCA/account-invoicing</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
from . import test_receipts

View File

@@ -0,0 +1,74 @@
from odoo.exceptions import ValidationError
from odoo.tests import tagged
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
@tagged("post_install", "-at_install")
class TestReceipts(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.out_receipt_journal = cls.env["account.journal"].create(
{
"name": "Sale Receipts Journal",
"code": "SREC",
"type": "sale",
"receipts": True,
"sequence": 99,
}
)
cls.in_receipt_journal = cls.env["account.journal"].create(
{
"name": "Purchase Receipts Journal",
"code": "PREC",
"type": "purchase",
"receipts": True,
"sequence": 99,
}
)
def test_receipt_journal_sequence(self):
with self.assertRaises(ValidationError):
self.out_receipt_journal.write({"sequence": 1})
with self.assertRaises(ValidationError):
self.in_receipt_journal.write({"sequence": 1})
def test_receipt_default_journal(self):
"""Test default values for receipt."""
for move_type in {"out_receipt", "in_receipt"}:
with self.subTest(move_type=move_type):
receipt = self.init_invoice(
move_type, products=self.product_a + self.product_b
)
self.assertTrue(receipt.journal_id.receipts)
def test_receipt_exclusive_journal(self):
"""Test exclusivity constraint for receipt journals."""
for move_type in {"out_receipt", "in_receipt"}:
with self.subTest(move_type=move_type):
receipt = self.init_invoice(
move_type, products=self.product_a + self.product_b
)
non_receipt_journals = self.env["account.journal"].search(
[
("type", "=", receipt.journal_id.type),
("company_id", "=", receipt.journal_id.company_id.id),
("receipts", "=", False),
]
)
with self.assertRaises(ValidationError):
receipt.write({"journal_id": non_receipt_journals.ids[0]})
def test_action_open_dashboard(self):
"""Test action_create_new and open_action"""
action = self.out_receipt_journal.action_create_new()
self.assertEqual(action["context"]["default_move_type"], "out_receipt")
action = self.in_receipt_journal.action_create_new()
self.assertEqual(action["context"]["default_move_type"], "in_receipt")
action = self.out_receipt_journal.open_action()
self.assertEqual(action["context"]["default_move_type"], "out_receipt")
self.assertEqual(action["domain"], [("move_type", "=", "out_receipt")])
action = self.in_receipt_journal.open_action()
self.assertEqual(action["context"]["default_move_type"], "in_receipt")
self.assertEqual(action["domain"], [("move_type", "=", "in_receipt")])

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_account_journal_form_receipts" model="ir.ui.view">
<field name="name">account.journal.form.receipts</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_journal_form" />
<field name="arch" type="xml">
<xpath expr="//page[@name='advanced_settings']/group" position="inside">
<group
name="receipts"
string="Receipts"
invisible="type not in ('sale', 'purchase')"
>
<field name="receipts" />
</group>
</xpath>
</field>
</record>
</odoo>