-
-
Notifications
You must be signed in to change notification settings - Fork 687
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by sergiocorato
- Loading branch information
Showing
16 changed files
with
448 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
from . import models | ||
from . import wizard | ||
from odoo import api, SUPERUSER_ID | ||
from openupgradelib import openupgrade | ||
|
||
|
||
def rename_old_italian_module(cr): | ||
|
||
if not openupgrade.is_module_installed(cr, "l10n_it_corrispettivi"): | ||
return | ||
|
||
openupgrade.update_module_names( | ||
cr, | ||
[ | ||
("l10n_it_corrispettivi", "account_receipt_sale"), | ||
], | ||
merge_modules=True, | ||
) | ||
|
||
if openupgrade.column_exists( | ||
cr, "account_move", "old_invoice_id" | ||
) and openupgrade.column_exists(cr, "account_invoice", "corrispettivo"): | ||
# l10n_it_corrispettivi handled sale receipts only | ||
openupgrade.logged_query( | ||
cr, | ||
"UPDATE account_move m " | ||
"SET move_type = 'out_receipt' " | ||
"FROM account_invoice i " | ||
"WHERE i.corrispettivo = true AND i.id = m.old_invoice_id", | ||
) | ||
|
||
if openupgrade.column_exists(cr, "account_journal", "corrispettivi"): | ||
openupgrade.logged_query( | ||
cr, | ||
"UPDATE account_journal " | ||
"SET receipts = true " | ||
"WHERE corrispettivi = true", | ||
) | ||
|
||
if not openupgrade.is_module_installed(cr, "l10n_it_corrispettivi_sale"): | ||
return | ||
|
||
openupgrade.update_module_names( | ||
cr, | ||
[ | ||
("l10n_it_corrispettivi_sale", "account_receipt_sale"), | ||
], | ||
merge_modules=True, | ||
) | ||
|
||
|
||
def invert_receipt_refund_quantity(env): | ||
"""Receipt Refunds are the same as normal Receipts | ||
but with inverted Quantities.""" | ||
openupgrade.logged_query( | ||
env.cr, | ||
"UPDATE account_move_line l " | ||
"SET quantity = -quantity " | ||
"FROM account_move m " | ||
"WHERE m.id = l.move_id " | ||
"AND m.move_type IN ('out_receipt', 'in_receipt') " | ||
"AND m.amount_total_signed < 0 " | ||
"AND l.exclude_from_invoice_tab = false " | ||
"AND (l.display_type NOT IN ('line_section', 'line_note') " | ||
" OR display_type IS NULL) " | ||
"AND l.quantity > 0", | ||
) | ||
|
||
|
||
def migrate_corrispettivi_data(cr, registry): | ||
""" | ||
Populate the new columns with data from corrispettivi modules. | ||
""" | ||
if openupgrade.column_exists(cr, "sale_order", "corrispettivi"): | ||
openupgrade.logged_query( | ||
cr, | ||
"UPDATE sale_order " "SET receipts = true " "WHERE corrispettivi = true", | ||
) | ||
|
||
if openupgrade.column_exists(cr, "account_fiscal_position", "corrispettivi"): | ||
openupgrade.logged_query( | ||
cr, | ||
"UPDATE account_fiscal_position " | ||
"SET receipts = true " | ||
"WHERE corrispettivi = true", | ||
) | ||
|
||
if openupgrade.column_exists(cr, "res_partner", "use_corrispettivi"): | ||
openupgrade.logged_query( | ||
cr, | ||
"UPDATE res_partner " | ||
"SET use_receipts = true " | ||
"WHERE use_corrispettivi = true", | ||
) | ||
|
||
with api.Environment.manage(): | ||
env = api.Environment(cr, SUPERUSER_ID, {}) | ||
invert_receipt_refund_quantity(env) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Copyright 2016-2022 Lorenzo Battistini | ||
# Copyright 2018-2019 Simone Rubino | ||
# Copyright 2019 Sergio Zanchetta (Associazione PNLUG - Gruppo Odoo) | ||
# Copyright 2020 Giovanni Serra - GSLab.it | ||
# Copyright 2023 Simone Rubino - TAKOBI | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
{ | ||
"name": "Receipts from sales", | ||
"summary": "Generate receipts from sale orders", | ||
"version": "14.0.1.0.1", | ||
"development_status": "Beta", | ||
"category": "Sales/Sales", | ||
"website": "https://github.com/OCA/account-invoicing", | ||
"author": "TAKOBI, Agile Business Group, Odoo Community Association (OCA)", | ||
"maintainers": ["eLBati"], | ||
"license": "AGPL-3", | ||
"application": False, | ||
"installable": True, | ||
"preloadable": True, | ||
"depends": [ | ||
"account_receipt_base", | ||
"account_receipt_journal", | ||
"sale", | ||
], | ||
"data": [ | ||
"views/sale_views.xml", | ||
], | ||
"pre_init_hook": "rename_old_italian_module", | ||
"post_init_hook": "migrate_corrispettivi_data", | ||
"external_dependencies": { | ||
"python": [ | ||
"openupgradelib", | ||
], | ||
}, | ||
} |
11 changes: 11 additions & 0 deletions
11
account_receipt_sale/migrations/14.0.1.0.1/post-migrate.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Copyright 2023 Simone Rubino - TAKOBI | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
from openupgradelib import openupgrade | ||
|
||
from odoo.addons.account_receipt_sale import invert_receipt_refund_quantity | ||
|
||
|
||
@openupgrade.migrate() | ||
def migrate(env, version): | ||
invert_receipt_refund_quantity(env) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import sale |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
from odoo import api, fields, models | ||
|
||
|
||
class SaleOrder(models.Model): | ||
_inherit = "sale.order" | ||
receipts = fields.Boolean() | ||
receipt_ids = fields.Many2many( | ||
comodel_name="account.move", | ||
string="Receipts", | ||
compute="_compute_receipt_ids", | ||
readonly=True, | ||
copy=False, | ||
search="_search_receipt_ids", | ||
) | ||
receipt_count = fields.Integer( | ||
string="Receipt Count", | ||
compute="_compute_receipt_ids", | ||
readonly=True, | ||
) | ||
|
||
@api.depends( | ||
"order_line.invoice_lines", | ||
) | ||
def _compute_receipt_ids(self): | ||
for order in self: | ||
receipts = order.order_line.invoice_lines.move_id.filtered( | ||
lambda r: r.move_type == "out_receipt" | ||
) | ||
order.receipt_ids = receipts | ||
order.receipt_count = len(receipts) | ||
|
||
def _search_receipt_ids(self, operator, value): | ||
# Basically copied from _search_invoice_ids, | ||
# just using out_receipt instead of out_invoice and out_refund | ||
if operator == "in" and value: | ||
self.env.cr.execute( | ||
""" | ||
SELECT array_agg(so.id) | ||
FROM sale_order so | ||
JOIN sale_order_line sol ON sol.order_id = so.id | ||
JOIN sale_order_line_invoice_rel soli_rel ON soli_rel.order_line_id = sol.id | ||
JOIN account_move_line aml ON aml.id = soli_rel.invoice_line_id | ||
JOIN account_move am ON am.id = aml.move_id | ||
WHERE | ||
am.move_type = 'out_receipt' AND | ||
am.id = ANY(%s) | ||
""", | ||
(list(value),), | ||
) | ||
so_ids = self.env.cr.fetchone()[0] or [] | ||
return [("id", "in", so_ids)] | ||
elif operator == "=" and not value: | ||
order_ids = self._search( | ||
[ | ||
("order_line.invoice_lines.move_id.move_type", "=", "out_receipt"), | ||
] | ||
) | ||
return [("id", "not in", order_ids)] | ||
return [ | ||
"&", | ||
("order_line.invoice_lines.move_id.move_type", "=", "out_receipt"), | ||
("order_line.invoice_lines.move_id", operator, value), | ||
] | ||
|
||
def action_view_receipt(self): | ||
# Basically the same as what happens in action_view_invoice | ||
receipts = self.mapped("receipt_ids") | ||
action = self.env["ir.actions.actions"]._for_xml_id( | ||
"account.action_move_out_receipt_type" | ||
) | ||
if len(receipts) > 1: | ||
action["domain"] = [("id", "in", receipts.ids)] | ||
elif len(receipts) == 1: | ||
form_view = [(self.env.ref("account.view_move_form").id, "form")] | ||
if "views" in action: | ||
action["views"] = form_view + [ | ||
(state, view) for state, view in action["views"] if view != "form" | ||
] | ||
else: | ||
action["views"] = form_view | ||
action["res_id"] = receipts.id | ||
else: | ||
action = {"type": "ir.actions.act_window_close"} | ||
|
||
context = { | ||
"default_move_type": "out_receipt", | ||
} | ||
if len(self) == 1: | ||
context.update( | ||
{ | ||
"default_partner_id": self.partner_id.id, | ||
"default_partner_shipping_id": self.partner_shipping_id.id, | ||
"default_invoice_payment_term_id": self.payment_term_id.id | ||
or self.partner_id.property_payment_term_id.id | ||
or self.env["account.move"] | ||
.default_get(["invoice_payment_term_id"]) | ||
.get("invoice_payment_term_id"), | ||
"default_invoice_origin": self.name, | ||
"default_user_id": self.user_id.id, | ||
} | ||
) | ||
action["context"] = context | ||
return action | ||
|
||
@api.onchange("partner_id") | ||
def _onchange_partner_receipts_sale(self): | ||
self.receipts = self.partner_id.use_receipts | ||
|
||
@api.onchange("fiscal_position_id") | ||
def _onchange_fiscal_position_id_receipts(self): | ||
if self.fiscal_position_id: | ||
self.receipts = self.fiscal_position_id.receipts | ||
|
||
def _prepare_invoice(self): | ||
invoice_values = super()._prepare_invoice() | ||
if self.receipts: | ||
invoice_values["move_type"] = "out_receipt" | ||
self.env["account.move"]._update_receipts_journal([invoice_values]) | ||
return invoice_values | ||
|
||
@api.model | ||
def create(self, values): | ||
order = super().create(values) | ||
if "partner_id" in values and "receipts" not in values: | ||
order._onchange_partner_receipts_sale() | ||
if "fiscal_position_id" in values and "receipts" not in values: | ||
order._onchange_fiscal_position_id_receipts() | ||
return order | ||
|
||
def write(self, values): | ||
res = super().write(values) | ||
if "partner_id" in values and "receipts" not in values: | ||
for order in self: | ||
order._onchange_partner_receipts_sale() | ||
if "fiscal_position_id" in values and "receipts" not in values: | ||
for order in self: | ||
order._onchange_fiscal_position_id_receipts() | ||
return res | ||
|
||
|
||
class OrderLine(models.Model): | ||
_inherit = "sale.order.line" | ||
|
||
def _compute_untaxed_amount_invoiced(self): | ||
super()._compute_untaxed_amount_invoiced() | ||
for line in self: | ||
amount_receipt = 0.0 | ||
for invoice_line in line.invoice_lines: | ||
if invoice_line.move_id.state == "posted": | ||
invoice_date = ( | ||
invoice_line.move_id.invoice_date or fields.Date.today() | ||
) | ||
if invoice_line.move_id.move_type == "out_receipt": | ||
amount_receipt += invoice_line.currency_id._convert( | ||
invoice_line.price_subtotal, | ||
line.currency_id, | ||
line.company_id, | ||
invoice_date, | ||
) | ||
line.untaxed_amount_invoiced += amount_receipt | ||
|
||
def _get_invoice_qty(self): | ||
super()._get_invoice_qty() | ||
for line in self: | ||
qty_receipt = 0.0 | ||
for invoice_line in line.invoice_lines: | ||
if invoice_line.move_id.state != "cancel": | ||
if invoice_line.move_id.move_type == "out_receipt": | ||
qty_receipt += invoice_line.product_uom_id._compute_quantity( | ||
invoice_line.quantity, line.product_uom | ||
) | ||
line.qty_invoiced += qty_receipt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
- Add your users to "Sale Receipt" group | ||
- Go to Invoicing > Customers > Receipts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
* Lorenzo Battistini | ||
* Simone Rubino | ||
* Sergio Zanchetta <https://github.com/primes2h> | ||
* Giovanni Serra <[email protected]> | ||
* `TAKOBI <https://takobi.online>`_: | ||
|
||
* Simone Rubino <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Based on `account_receipt_journal`, this module allows to create receipts from sale orders. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This module comes from modules `l10n_it_corrispettivi` and `l10n_it_corrispettivi_sale` of https://github.com/OCA/l10n-italy version 12. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import test_receipts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Copyright 2018 Simone Rubino | ||
# Copyright 2022 Lorenzo Battistini | ||
# Copyright 2023 Simone Rubino - TAKOBI | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
|
||
from odoo.tests import tagged | ||
|
||
from odoo.addons.account_receipt_journal.tests.test_receipts import TestReceipts | ||
|
||
|
||
@tagged("post_install", "-at_install") | ||
class TestReceiptsSale(TestReceipts): | ||
def setUp(self): | ||
super(TestReceiptsSale, self).setUp() | ||
partner_model = self.env["res.partner"] | ||
self.fiscal_pos_model = self.env["account.fiscal.position"] | ||
self.sale_model = self.env["sale.order"] | ||
self.receipts_fiscal_position = self.fiscal_pos_model.create( | ||
{ | ||
"name": "receipts fiscal position", | ||
"receipts": True, | ||
"company_id": self.env.user.company_id.id, | ||
} | ||
) | ||
self.no_receipts_fiscal_position = self.fiscal_pos_model.create( | ||
{ | ||
"name": "no receipts fiscal position", | ||
"receipts": False, | ||
"company_id": self.env.user.company_id.id, | ||
} | ||
) | ||
self.no_receipts_partner = partner_model.create( | ||
{ | ||
"name": "No receipts partner", | ||
"use_receipts": False, | ||
"property_account_position_id": self.no_receipts_fiscal_position.id, | ||
} | ||
) | ||
|
||
def test_order_creation(self): | ||
order_no_receipts = self.sale_model.create( | ||
{ | ||
"partner_id": self.no_receipts_partner.id, | ||
"fiscal_position_id": self.no_receipts_fiscal_position.id, | ||
} | ||
) | ||
self.assertFalse(order_no_receipts.receipts) | ||
order_receipts = self.sale_model.create( | ||
{ | ||
"partner_id": self.no_receipts_partner.id, | ||
"fiscal_position_id": self.receipts_fiscal_position.id, | ||
} | ||
) | ||
self.assertTrue(order_receipts.receipts) | ||
|
||
# testing write | ||
order_no_receipts.fiscal_position_id = self.receipts_fiscal_position.id | ||
self.assertTrue(order_no_receipts.receipts) |
Oops, something went wrong.