RemiFr82
1 year ago
13 changed files with 435 additions and 0 deletions
-
2purchase_discount_without_stock/__init__.py
-
26purchase_discount_without_stock/__manifest__.py
-
92purchase_discount_without_stock/i18n/fr.po
-
3purchase_discount_without_stock/models/__init__.py
-
38purchase_discount_without_stock/models/product_supplierinfo.py
-
118purchase_discount_without_stock/models/purchase_order.py
-
17purchase_discount_without_stock/models/res_partner.py
-
1purchase_discount_without_stock/report/__init__.py
-
34purchase_discount_without_stock/report/purchase_report.py
-
20purchase_discount_without_stock/views/product_supplierinfo_view.xml
-
42purchase_discount_without_stock/views/purchase_discount_view.xml
-
16purchase_discount_without_stock/views/report_purchaseorder.xml
-
26purchase_discount_without_stock/views/res_partner_view.xml
@ -0,0 +1,2 @@ |
|||
from . import models |
|||
from . import report |
@ -0,0 +1,26 @@ |
|||
# © 2004-2009 Tiny SPRL (<http://tiny.be>). |
|||
# © 2014-2017 Tecnativa - Pedro M. Baeza |
|||
# © 2016 ACSONE SA/NV (<http://acsone.eu>) |
|||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html |
|||
{ |
|||
"name": "Purchase order lines with discounts", |
|||
"author": "Tiny, " |
|||
"Acysos S.L., " |
|||
"Tecnativa, " |
|||
"ACSONE SA/NV," |
|||
"GRAP," |
|||
"Odoo Community Association (OCA)," |
|||
"RemiFr82", |
|||
"version": "14.0.1.1.3", |
|||
"category": "Purchase Management", |
|||
"website": "https://remifr82.me", |
|||
"depends": ["purchase"], |
|||
"data": [ |
|||
"views/purchase_discount_view.xml", |
|||
"views/report_purchaseorder.xml", |
|||
"views/product_supplierinfo_view.xml", |
|||
"views/res_partner_view.xml", |
|||
], |
|||
"license": "AGPL-3", |
|||
"installable": True, |
|||
} |
@ -0,0 +1,92 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * purchase_discount_whithout_stock |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2018 |
|||
# Quentin THEURET <odoo@kerpeo.com>, 2018 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 11.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2018-02-23 17:50+0000\n" |
|||
"PO-Revision-Date: 2020-07-22 12:19+0000\n" |
|||
"Last-Translator: c2cdidier <didier.donze@camptocamp.com>\n" |
|||
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" |
|||
"Language: fr\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 3.10\n" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model_terms:ir.ui.view,arch_db:purchase_discount_whithout_stock.report_purchaseorder_document |
|||
msgid "<strong>Disc. (%)</strong>" |
|||
msgstr "<strong>Remise (%)</strong>" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model,name:purchase_discount_whithout_stock.model_res_partner |
|||
msgid "Contact" |
|||
msgstr "Contact" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model.fields,field_description:purchase_discount_whithout_stock.field_res_partner__default_supplierinfo_discount |
|||
#: model:ir.model.fields,field_description:purchase_discount_whithout_stock.field_res_users__default_supplierinfo_discount |
|||
msgid "Default Supplier Discount (%)" |
|||
msgstr "Remise fournisseur par défaut (%)" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model.fields,field_description:purchase_discount_whithout_stock.field_product_supplierinfo__discount |
|||
#: model:ir.model.fields,field_description:purchase_discount_whithout_stock.field_purchase_order_line__discount |
|||
#: model:ir.model.fields,field_description:purchase_discount_whithout_stock.field_purchase_report__discount |
|||
msgid "Discount (%)" |
|||
msgstr "Remise (%)" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model.constraint,message:purchase_discount_whithout_stock.constraint_purchase_order_line_discount_limit |
|||
msgid "Discount must be lower than 100%." |
|||
msgstr "La remise doit être inférieure à 100%." |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model_terms:ir.ui.view,arch_db:purchase_discount_whithout_stock.res_partner_form_view |
|||
msgid "Discount-related settings are managed on" |
|||
msgstr "Paramètres des remises sont gérés sur" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model,name:purchase_discount_whithout_stock.model_purchase_order |
|||
msgid "Purchase Order" |
|||
msgstr "Commandes d'achat" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model,name:purchase_discount_whithout_stock.model_purchase_order_line |
|||
msgid "Purchase Order Line" |
|||
msgstr "Ligne de commande d'achat" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model,name:purchase_discount_whithout_stock.model_purchase_report |
|||
msgid "Purchase Report" |
|||
msgstr "Rapport des commandes" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model,name:purchase_discount_whithout_stock.model_product_supplierinfo |
|||
msgid "Supplier Pricelist" |
|||
msgstr "Liste de prix fournisseur" |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model:ir.model.fields,help:purchase_discount_whithout_stock.field_res_partner__default_supplierinfo_discount |
|||
#: model:ir.model.fields,help:purchase_discount_whithout_stock.field_res_users__default_supplierinfo_discount |
|||
msgid "" |
|||
"This value will be used as the default one, for each new supplierinfo line " |
|||
"depending on that supplier." |
|||
msgstr "" |
|||
"Cette valeur sera utilisée comme valeur par défaut pour chaque nouvelle " |
|||
"information fournisseur de ce fournisseur." |
|||
|
|||
#. module: purchase_discount_whithout_stock |
|||
#: model_terms:ir.ui.view,arch_db:purchase_discount_whithout_stock.res_partner_form_view |
|||
msgid "the parent company" |
|||
msgstr "Société parente" |
|||
|
|||
#~ msgid "Invoice" |
|||
#~ msgstr "Facture" |
@ -0,0 +1,3 @@ |
|||
from . import purchase_order |
|||
from . import product_supplierinfo |
|||
from . import res_partner |
@ -0,0 +1,38 @@ |
|||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>) |
|||
# Copyright 2014-2019 Tecnativa - Pedro M. Baeza |
|||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html |
|||
|
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class ProductSupplierInfo(models.Model): |
|||
_inherit = "product.supplierinfo" |
|||
|
|||
discount = fields.Float(string="Discount (%)", digits="Discount") |
|||
|
|||
@api.onchange("name") |
|||
def onchange_name(self): |
|||
"""Apply the default supplier discount of the selected supplier""" |
|||
for supplierinfo in self.filtered("name"): |
|||
supplierinfo.discount = supplierinfo.name.default_supplierinfo_discount |
|||
|
|||
@api.model |
|||
def _get_po_to_supplierinfo_synced_fields(self): |
|||
"""Overwrite this method for adding other fields to be synchronized |
|||
with product.supplierinfo. |
|||
""" |
|||
return ["discount"] |
|||
|
|||
@api.model_create_multi |
|||
def create(self, vals_list): |
|||
"""Insert discount (or others) from context from purchase.order's |
|||
_add_supplier_to_product method""" |
|||
for vals in vals_list: |
|||
product_tmpl_id = vals.get("product_tmpl_id") |
|||
po_line_map = self.env.context.get("po_line_map", {}) |
|||
if product_tmpl_id in po_line_map: |
|||
po_line = po_line_map[product_tmpl_id] |
|||
for field in self._get_po_to_supplierinfo_synced_fields(): |
|||
if not vals.get(field): |
|||
vals[field] = po_line[field] |
|||
return super().create(vals_list) |
@ -0,0 +1,118 @@ |
|||
# Copyright 2004-2009 Tiny SPRL (<http://tiny.be>). |
|||
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>) |
|||
# Copyright 2015-2019 Tecnativa - Pedro M. Baeza |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
|
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class PurchaseOrder(models.Model): |
|||
_inherit = "purchase.order" |
|||
|
|||
def _add_supplier_to_product(self): |
|||
"""Insert a mapping of products to PO lines to be picked up |
|||
in supplierinfo's create()""" |
|||
self.ensure_one() |
|||
po_line_map = { |
|||
line.product_id.product_tmpl_id.id: line for line in self.order_line |
|||
} |
|||
return super( |
|||
PurchaseOrder, self.with_context(po_line_map=po_line_map) |
|||
)._add_supplier_to_product() |
|||
|
|||
|
|||
class PurchaseOrderLine(models.Model): |
|||
_inherit = "purchase.order.line" |
|||
|
|||
# adding discount to depends |
|||
@api.depends("discount") |
|||
def _compute_amount(self): |
|||
return super()._compute_amount() |
|||
|
|||
def _prepare_compute_all_values(self): |
|||
vals = super()._prepare_compute_all_values() |
|||
vals.update({"price_unit": self._get_discounted_price_unit()}) |
|||
return vals |
|||
|
|||
discount = fields.Float(string="Discount (%)", digits="Discount") |
|||
|
|||
_sql_constraints = [ |
|||
( |
|||
"discount_limit", |
|||
"CHECK (discount <= 100.0)", |
|||
"Discount must be lower than 100%.", |
|||
) |
|||
] |
|||
|
|||
def _get_discounted_price_unit(self): |
|||
"""Inheritable method for getting the unit price after applying |
|||
discount(s). |
|||
|
|||
:rtype: float |
|||
:return: Unit price after discount(s). |
|||
""" |
|||
self.ensure_one() |
|||
if self.discount: |
|||
return self.price_unit * (1 - self.discount / 100) |
|||
return self.price_unit |
|||
|
|||
@api.onchange("product_qty", "product_uom") |
|||
def _onchange_quantity(self): |
|||
""" |
|||
Check if a discount is defined into the supplier info and if so then |
|||
apply it to the current purchase order line |
|||
""" |
|||
res = super()._onchange_quantity() |
|||
if self.product_id: |
|||
date = None |
|||
if self.order_id.date_order: |
|||
date = self.order_id.date_order.date() |
|||
seller = self.product_id._select_seller( |
|||
partner_id=self.partner_id, |
|||
quantity=self.product_qty, |
|||
date=date, |
|||
uom_id=self.product_uom, |
|||
) |
|||
self._apply_value_from_seller(seller) |
|||
return res |
|||
|
|||
@api.model |
|||
def _apply_value_from_seller(self, seller): |
|||
"""Overload this function to prepare other data from seller, |
|||
like in purchase_triple_discount module""" |
|||
if not seller: |
|||
return |
|||
self.discount = seller.discount |
|||
|
|||
def _prepare_account_move_line(self, move=False): |
|||
vals = super(PurchaseOrderLine, self)._prepare_account_move_line(move) |
|||
vals["discount"] = self.discount |
|||
return vals |
|||
|
|||
@api.model |
|||
def _prepare_purchase_order_line( |
|||
self, product_id, product_qty, product_uom, company_id, supplier, po |
|||
): |
|||
"""Apply the discount to the created purchase order""" |
|||
res = super()._prepare_purchase_order_line( |
|||
product_id, product_qty, product_uom, company_id, supplier, po |
|||
) |
|||
partner = supplier.name |
|||
uom_po_qty = product_uom._compute_quantity(product_qty, product_id.uom_po_id) |
|||
seller = product_id.with_company(company_id)._select_seller( |
|||
partner_id=partner, |
|||
quantity=uom_po_qty, |
|||
date=po.date_order and po.date_order.date(), |
|||
uom_id=product_id.uom_po_id, |
|||
) |
|||
res.update(self._prepare_purchase_order_line_from_seller(seller)) |
|||
return res |
|||
|
|||
@api.model |
|||
def _prepare_purchase_order_line_from_seller(self, seller): |
|||
"""Overload this function to prepare other data from seller, |
|||
like in purchase_triple_discount module""" |
|||
if not seller: |
|||
return {} |
|||
return {"discount": seller.discount} |
@ -0,0 +1,17 @@ |
|||
# Copyright 2016 GRAP (http://www.grap.coop) |
|||
# Sylvain LE GAL (https://twitter.com/legalsylvain) |
|||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html |
|||
|
|||
from odoo import fields, models |
|||
|
|||
|
|||
class ResPartner(models.Model): |
|||
_inherit = "res.partner" |
|||
|
|||
default_supplierinfo_discount = fields.Float( |
|||
string="Default Supplier Discount (%)", |
|||
digits="Discount", |
|||
help="This value will be used as the default one, for each new" |
|||
" supplierinfo line depending on that supplier.", |
|||
tracking=True, |
|||
) |
@ -0,0 +1 @@ |
|||
from . import purchase_report |
@ -0,0 +1,34 @@ |
|||
# Copyright 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
|||
# Copyright 2017-2019 Tecnativa - Pedro M. Baeza |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from odoo import fields, models |
|||
|
|||
|
|||
class PurchaseReport(models.Model): |
|||
_inherit = "purchase.report" |
|||
|
|||
discount = fields.Float( |
|||
string="Discount (%)", digits="Discount", group_operator="avg" |
|||
) |
|||
|
|||
def _select(self): |
|||
res = super()._select() |
|||
# There are 3 matches |
|||
res = res.replace("l.price_unit", self._get_discounted_price_unit_exp()) |
|||
res += ", l.discount AS discount" |
|||
return res |
|||
|
|||
def _group_by(self): |
|||
res = super()._group_by() |
|||
res += ", l.discount" |
|||
return res |
|||
|
|||
def _get_discounted_price_unit_exp(self): |
|||
"""Inheritable method for getting the SQL expression used for |
|||
calculating the unit price with discount(s). |
|||
|
|||
:rtype: str |
|||
:return: SQL expression for discounted unit price. |
|||
""" |
|||
return "(1.0 - COALESCE(l.discount, 0.0) / 100.0) * l.price_unit" |
@ -0,0 +1,20 @@ |
|||
<odoo> |
|||
<record model="ir.ui.view" id="product_supplierinfo_form_view"> |
|||
<field name="model">product.supplierinfo</field> |
|||
<field name="inherit_id" ref="product.product_supplierinfo_form_view" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//div[field[@name='price']]" position="after"> |
|||
<field name="discount" /> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
<record model="ir.ui.view" id="product_supplierinfo_tree_view"> |
|||
<field name="model">product.supplierinfo</field> |
|||
<field name="inherit_id" ref="product.product_supplierinfo_tree_view" /> |
|||
<field name="arch" type="xml"> |
|||
<field name="price" position="after"> |
|||
<field name="discount" /> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,42 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<odoo> |
|||
<record model="ir.ui.view" id="purchase_order_line_form2"> |
|||
<field name="name">purchase_discount.order.line.form2</field> |
|||
<field name="model">purchase.order.line</field> |
|||
<field name="inherit_id" ref="purchase.purchase_order_line_form2" /> |
|||
<field name="arch" type="xml"> |
|||
<field name="price_unit" position="after"> |
|||
<field name="discount" /> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
<record model="ir.ui.view" id="purchase_order_line_tree"> |
|||
<field name="name">purchase_discount.order.line.tree</field> |
|||
<field name="model">purchase.order.line</field> |
|||
<field name="inherit_id" ref="purchase.purchase_order_line_tree" /> |
|||
<field name="arch" type="xml"> |
|||
<field name="price_unit" position="after"> |
|||
<field name="discount" /> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
<record model="ir.ui.view" id="purchase_order_form"> |
|||
<field name="name">purchase_discount.purchase.order.form</field> |
|||
<field name="model">purchase.order</field> |
|||
<field name="inherit_id" ref="purchase.purchase_order_form" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath |
|||
expr="//field[@name='order_line']/tree/field[@name='price_unit']" |
|||
position="after" |
|||
> |
|||
<field name="discount" /> |
|||
</xpath> |
|||
<xpath |
|||
expr="//field[@name='order_line']/form//field[@name='price_unit']" |
|||
position="after" |
|||
> |
|||
<field name="discount" /> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,16 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<odoo> |
|||
<template |
|||
id="report_purchaseorder_document" |
|||
inherit_id="purchase.report_purchaseorder_document" |
|||
> |
|||
<xpath expr="//table[1]/thead/tr//th[last()]" position="before"> |
|||
<th name="th_discount" class="text-right"><strong>Disc. (%)</strong></th> |
|||
</xpath> |
|||
<xpath expr="//td[span[@t-field='line.price_subtotal']]" position="before"> |
|||
<td name="td_discount" class="text-right"> |
|||
<span t-field="line.discount" /> |
|||
</td> |
|||
</xpath> |
|||
</template> |
|||
</odoo> |
@ -0,0 +1,26 @@ |
|||
<odoo> |
|||
<record model="ir.ui.view" id="res_partner_form_view"> |
|||
<field name="model">res.partner</field> |
|||
<field name="inherit_id" ref="base.view_partner_form" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//group[@name='purchase']" position="inside"> |
|||
<field |
|||
name="default_supplierinfo_discount" |
|||
attrs="{'invisible': [('is_company', '=', False), ('parent_id', '!=', False)]}" |
|||
/> |
|||
<div |
|||
name="supplierinfo_discount_disabled" |
|||
colspan="2" |
|||
attrs="{'invisible': ['|',('is_company', '=', True), ('parent_id', '=', False)]}" |
|||
> |
|||
<p>Discount-related settings are managed on <button |
|||
name="open_commercial_entity" |
|||
type="object" |
|||
string="the parent company" |
|||
class="oe_link" |
|||
/></p> |
|||
</div> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue