Skip to content

Commit

Permalink
[16.0][FIX] sale_invoice_policy: compute qty to invoice
Browse files Browse the repository at this point in the history
  • Loading branch information
ACheung-FactorLibre authored and ioans73 committed Apr 30, 2024
1 parent 62c4c21 commit b09a9d2
Show file tree
Hide file tree
Showing 17 changed files with 121 additions and 253 deletions.
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
exclude: |
(?x)
# NOT INSTALLABLE ADDONS
^sale_invoice_policy/|
# END NOT INSTALLABLE ADDONS
# Files and folders generated by bots, to avoid loops
^setup/|/static/description/index\.html$|
Expand Down
4 changes: 3 additions & 1 deletion sale_invoice_policy/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Sale invoice Policy
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:3c1505e28f76dfda1fccdabb3cce63bab46df277823c4236d77da275a16a5a3c
!! source digest: sha256:f7cef4d695f93f0893a61a5db0dc5ea532311d04314a81189214b7a49d43faed
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down Expand Up @@ -70,6 +70,8 @@ Contributors
* Denis Roussel <denis.roussel@acsone.eu>
* Alexei Rivera <arivera@archeti.com>
* Luis J. Salvatierra <luis.salvatierra@factorlibre.com>
* Alejandro Ji Cheung <alejandro.jicheung@factorlibre.com>
* Ioan Galan <ioan@studio73.es>

Maintainers
~~~~~~~~~~~
Expand Down
1 change: 0 additions & 1 deletion sale_invoice_policy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
from . import models
from .post_init_hook import post_init_hook
3 changes: 0 additions & 3 deletions sale_invoice_policy/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
"license": "AGPL-3",
"depends": ["sale_stock"],
"data": [
"views/product_template_view.xml",
"views/res_config_settings_view.xml",
"views/sale_view.xml",
],
"installable": False,
"post_init_hook": "post_init_hook",
}
1 change: 0 additions & 1 deletion sale_invoice_policy/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from . import product_template
from . import res_config_settings
from . import sale_order
from . import sale_order_line
54 changes: 0 additions & 54 deletions sale_invoice_policy/models/product_template.py

This file was deleted.

10 changes: 0 additions & 10 deletions sale_invoice_policy/models/res_config_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

sale_default_invoice_policy = fields.Selection(
related="default_invoice_policy",
string="Default Sale Invoice Policy",
readonly=True,
)
sale_invoice_policy_required = fields.Boolean(
help="This makes Invoice Policy required on Sale Orders"
)
Expand All @@ -36,9 +31,4 @@ def set_values(self):
"sale_invoice_policy_required",
self.sale_invoice_policy_required,
)
ir_default_obj.set(
"res.config.settings",
"sale_default_invoice_policy",
self.sale_default_invoice_policy,
)
return True
16 changes: 11 additions & 5 deletions sale_invoice_policy/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,23 @@ class SaleOrder(models.Model):
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
default_sale_invoice_policy = self.env["ir.default"].get(
"res.config.settings", "sale_default_invoice_policy"
default_invoice_policy = (
self.env["res.config.settings"]
.sudo()
.default_get(["default_invoice_policy"])
.get("default_invoice_policy", False)
)
if "invoice_policy" not in res:
res.update({"invoice_policy": default_sale_invoice_policy})
res.update({"invoice_policy": default_invoice_policy})
return res

@api.depends("partner_id")
def _compute_invoice_policy_required(self):
invoice_policy_required = self.env["ir.default"].get(
"res.config.settings", "sale_invoice_policy_required"
invoice_policy_required = (
self.env["res.config.settings"]
.sudo()
.default_get(["sale_invoice_policy_required"])
.get("sale_invoice_policy_required", False)
)
for sale in self:
sale.invoice_policy_required = invoice_policy_required
122 changes: 78 additions & 44 deletions sale_invoice_policy/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,102 @@
# Copyright 2017 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import api, models
from odoo import api, fields, models


class SaleOrderLine(models.Model):

_inherit = "sale.order.line"

@api.depends(
"qty_invoiced",
"qty_delivered",
"product_uom_qty",
"order_id.state",
"state",
"order_id.invoice_policy",
)
def _compute_qty_to_invoice(self):
invoice_policies = set(self.mapped("order_id.invoice_policy"))
line_by_id = {line.id: line for line in self}
done_lines = self.env["sale.order.line"].browse()
for invoice_policy in invoice_policies:
so_lines = (
self.with_context(invoice_policy=invoice_policy)
.filtered(lambda x, p=invoice_policy: x.order_id.invoice_policy == p)
.with_prefetch()
)
if so_lines:
done_lines |= so_lines
super(SaleOrderLine, so_lines)._compute_qty_to_invoice()
for line in so_lines:
# due to the change of context in compute methods,
# assign the value in the modified context to self
line_by_id[line.id].qty_to_invoice = line.qty_to_invoice
# Not to break function if (it could not happen) some records
# were not in so_lines
super(SaleOrderLine, self - done_lines)._compute_qty_to_invoice()
other_lines = self.filtered(
lambda l: l.product_id.type == "service"
or not l.order_id.invoice_policy
or not l.order_id.invoice_policy_required
)
super(SaleOrderLine, other_lines)._compute_qty_to_invoice()
for line in self - other_lines:
invoice_policy = line.order_id.invoice_policy
if invoice_policy == "order":
line.qty_to_invoice = line.product_uom_qty - line.qty_invoiced
else:
line.qty_to_invoice = line.qty_delivered - line.qty_invoiced
return True

@api.depends(
"state",
"product_uom_qty",
"price_reduce",
"product_id",
"untaxed_amount_invoiced",
"qty_delivered",
"qty_to_invoice",
"qty_invoiced",
"product_uom_qty",
"order_id.invoice_policy",
)
def _compute_invoice_status(self):
invoice_policies = set(self.mapped("order_id.invoice_policy"))
line_by_id = {line.id: line for line in self}
done_lines = self.env["sale.order.line"].browse()
for invoice_policy in invoice_policies:
so_lines = (
self.with_context(invoice_policy=invoice_policy)
.filtered(lambda x, p=invoice_policy: x.order_id.invoice_policy == p)
.with_prefetch()
def _compute_untaxed_amount_to_invoice(self):
other_lines = self.filtered(
lambda line: line.product_id.type == "service"
or not line.order_id.invoice_policy
or line.order_id.invoice_policy == line.product_id.invoice_policy
or line.state not in ["sale", "done"]
or not line.order_id.invoice_policy_required
)
super(SaleOrderLine, other_lines)._compute_untaxed_amount_to_invoice()
for line in self - other_lines:
invoice_policy = line.order_id.invoice_policy
amount_to_invoice = 0.0
price_subtotal = 0.0
uom_qty_to_consider = (
line.qty_delivered
if invoice_policy == "delivery"
else line.product_uom_qty
)
done_lines |= so_lines
if so_lines:
super(SaleOrderLine, so_lines)._compute_invoice_status()
for line in so_lines:
# due to the change of context in compute methods,
# assign the value in the modified context to self
line_by_id[line.id].invoice_status = line.invoice_status
# Not to break function if (it could not happen) some records
# were not in so_lines
super(SaleOrderLine, self - done_lines)._compute_invoice_status()
price_reduce = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
price_subtotal = price_reduce * uom_qty_to_consider
if len(line.tax_id.filtered(lambda tax: tax.price_include)) > 0:
price_subtotal = line.tax_id.compute_all(
price_reduce,
currency=line.currency_id,
quantity=uom_qty_to_consider,
product=line.product_id,
partner=line.order_id.partner_shipping_id,
)["total_excluded"]
inv_lines = line._get_invoice_lines()
if any(inv_lines.mapped(lambda l: l.discount != line.discount)):
amount = 0
for inv_line in inv_lines:
if (
len(inv_line.tax_ids.filtered(lambda tax: tax.price_include))
> 0
):
amount += inv_line.tax_ids.compute_all(
inv_line.currency_id._convert(
inv_line.price_unit,
line.currency_id,
line.company_id,
inv_line.date or fields.Date.today(),
round=False,
)
* inv_line.quantity
)["total_excluded"]
else:
amount += (
inv_line.currency_id._convert(
inv_line.price_unit,
line.currency_id,
line.company_id,
inv_line.date or fields.Date.today(),
round=False,
)
* inv_line.quantity
)
amount_to_invoice = max(price_subtotal - amount, 0)
else:
amount_to_invoice = price_subtotal - line.untaxed_amount_invoiced
line.untaxed_amount_to_invoice = amount_to_invoice
return True
15 changes: 0 additions & 15 deletions sale_invoice_policy/post_init_hook.py

This file was deleted.

2 changes: 2 additions & 0 deletions sale_invoice_policy/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
* Denis Roussel <denis.roussel@acsone.eu>
* Alexei Rivera <arivera@archeti.com>
* Luis J. Salvatierra <luis.salvatierra@factorlibre.com>
* Alejandro Ji Cheung <alejandro.jicheung@factorlibre.com>
* Ioan Galan <ioan@studio73.es>
5 changes: 3 additions & 2 deletions sale_invoice_policy/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!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>
Expand Down Expand Up @@ -367,7 +366,7 @@ <h1 class="title">Sale invoice Policy</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:3c1505e28f76dfda1fccdabb3cce63bab46df277823c4236d77da275a16a5a3c
!! source digest: sha256:f7cef4d695f93f0893a61a5db0dc5ea532311d04314a81189214b7a49d43faed
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sale-workflow/tree/16.0/sale_invoice_policy"><img alt="OCA/sale-workflow" src="https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sale-workflow-16-0/sale-workflow-16-0-sale_invoice_policy"><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/sale-workflow&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This modules helps to get Invoicing Policy on Sale Order Level without
Expand Down Expand Up @@ -418,6 +417,8 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<li>Denis Roussel &lt;<a class="reference external" href="mailto:denis.roussel&#64;acsone.eu">denis.roussel&#64;acsone.eu</a>&gt;</li>
<li>Alexei Rivera &lt;<a class="reference external" href="mailto:arivera&#64;archeti.com">arivera&#64;archeti.com</a>&gt;</li>
<li>Luis J. Salvatierra &lt;<a class="reference external" href="mailto:luis.salvatierra&#64;factorlibre.com">luis.salvatierra&#64;factorlibre.com</a>&gt;</li>
<li>Alejandro Ji Cheung &lt;<a class="reference external" href="mailto:alejandro.jicheung&#64;factorlibre.com">alejandro.jicheung&#64;factorlibre.com</a>&gt;</li>
<li>Ioan Galan &lt;<a class="reference external" href="mailto:ioan&#64;studio73.es">ioan&#64;studio73.es</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down

0 comments on commit b09a9d2

Please sign in to comment.