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 25, 2024
1 parent 9a9eaa2 commit 3aa5173
Show file tree
Hide file tree
Showing 16 changed files with 63 additions and 249 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
3 changes: 2 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,7 @@ 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>

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",
}
54 changes: 9 additions & 45 deletions sale_invoice_policy/models/product_template.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,18 @@
# 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, fields, models
from odoo import fields, models


class ProductTemplate(models.Model):
_inherit = "product.template"

default_invoice_policy = fields.Selection(
[("order", "Ordered quantities"), ("delivery", "Delivered quantities")],
string="Default Invoicing Policy",
help="Ordered Quantity: Invoice based on the quantity the customer "
"ordered.\n"
"Delivered Quantity: Invoiced based on the quantity the vendor "
"delivered (time or deliveries).",
default=lambda self: self.env["ir.default"].get(
"res.config.settings", "default_invoice_policy"
),
)
def _default_invoice_policy(self):
return (
self.env["res.config.settings"]
.sudo()
.default_get(["default_invoice_policy"])
.get("default_invoice_policy", False)
)

invoice_policy = fields.Selection(
compute="_compute_invoice_policy",
store=False,
readonly=True,
search="_search_invoice_policy",
inverse="_inverse_invoice_policy",
precompute=False,
)

def _inverse_invoice_policy(self):
for template in self.filtered("invoice_policy"):
template.default_invoice_policy = template.invoice_policy

@api.depends("detailed_type", "default_invoice_policy")
@api.depends_context("invoice_policy")
def _compute_invoice_policy(self):
"""
Apply the invoice_policy given by context (if exist) otherwise use the
default invoice policy given by the field with this same name.
If the product is type = 'service', we don't have to apply the invoice
policy given by the context.
:return:
"""
invoice_policy = self.env.context.get("invoice_policy")
for tmpl in self:
if tmpl.type != "service" and invoice_policy:
tmpl.invoice_policy = invoice_policy
else:
tmpl.invoice_policy = tmpl.default_invoice_policy

@api.model
def _search_invoice_policy(self, operator, value):
return [("default_invoice_policy", operator, value)]
invoice_policy = fields.Selection(default=_default_invoice_policy)
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
63 changes: 12 additions & 51 deletions sale_invoice_policy/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,25 @@


class SaleOrderLine(models.Model):

_inherit = "sale.order.line"

@api.depends(
"qty_invoiced",
"qty_delivered",
"product_uom_qty",
"order_id.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()
return True

@api.depends(
"state",
"product_uom_qty",
"qty_delivered",
"qty_to_invoice",
"qty_invoiced",
"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()
)
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()
def _compute_qty_to_invoice(self):
other_lines = self.env["sale.order.line"]
for line in self:
if line.product_id.type == "service" or not line.order_id.invoice_policy:
other_lines |= line
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
15 changes: 0 additions & 15 deletions sale_invoice_policy/post_init_hook.py

This file was deleted.

1 change: 1 addition & 0 deletions sale_invoice_policy/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
* 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>
3 changes: 2 additions & 1 deletion sale_invoice_policy/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,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 +418,7 @@ <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>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down

0 comments on commit 3aa5173

Please sign in to comment.