Compare commits
3 commits
d9a0eeb878
...
524e3d643c
| Author | SHA1 | Date | |
|---|---|---|---|
| 524e3d643c | |||
| 91971ae56b | |||
| f586c99df9 |
24 changed files with 661 additions and 4 deletions
|
|
@ -17,6 +17,33 @@ msgstr ""
|
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step
|
||||
msgid "Sale Price Rounding Step"
|
||||
msgstr "Redondeo del precio de venta"
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step
|
||||
msgid "Round the theoretical sale price (after taxes) to the nearest multiple of this value. Set to 0.00 to disable rounding (e.g. 0.05 rounds to the nearest 5 cents)."
|
||||
msgstr "Redondea el precio de venta teórico (con impuestos) al múltiplo más cercano de este valor. Pon 0,00 para desactivar el redondeo (p. ej. 0,05 redondea al céntimo más cercano de 5)."
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_product__configured_sale_margin
|
||||
#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_template__configured_sale_margin
|
||||
msgid "Configured sale margin (%)"
|
||||
msgstr "Margen de venta configurado (%)"
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_product__configured_sale_margin
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_template__configured_sale_margin
|
||||
msgid "Effective margin configured by the automatic pricelist chain for this product. It reflects tariff configuration, not the current manual sale price."
|
||||
msgstr "Margen efectivo configurado por la cadena de tarifas automáticas para este producto. Refleja la configuración de tarifas, no el precio de venta manual actual."
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model_terms:ir.ui.view,arch_db:product_sale_price_from_pricelist.product_pricelist_view_price_rounding
|
||||
msgid "Sale Price Rounding"
|
||||
msgstr "Redondeo del precio de venta"
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist_item__base
|
||||
msgid ""
|
||||
|
|
|
|||
|
|
@ -15,6 +15,33 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step
|
||||
msgid "Sale Price Rounding Step"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step
|
||||
msgid "Round the theoretical sale price (after taxes) to the nearest multiple of this value. Set to 0.00 to disable rounding (e.g. 0.05 rounds to the nearest 5 cents)."
|
||||
msgstr ""
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_product__configured_sale_margin
|
||||
#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_template__configured_sale_margin
|
||||
msgid "Configured sale margin (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_product__configured_sale_margin
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_template__configured_sale_margin
|
||||
msgid "Effective margin configured by the automatic pricelist chain for this product. It reflects tariff configuration, not the current manual sale price."
|
||||
msgstr ""
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model_terms:ir.ui.view,arch_db:product_sale_price_from_pricelist.product_pricelist_view_price_rounding
|
||||
msgid "Sale Price Rounding"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_sale_price_from_pricelist
|
||||
#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist_item__base
|
||||
msgid ""
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
# import logging
|
||||
|
||||
from odoo import api, models
|
||||
from odoo import api, fields, models
|
||||
|
||||
# _logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -12,6 +12,14 @@ from odoo import api, models
|
|||
class ProductPricelist(models.Model):
|
||||
_inherit = "product.pricelist"
|
||||
|
||||
price_rounding_step = fields.Float(
|
||||
string="Sale Price Rounding Step",
|
||||
digits=(12, 2),
|
||||
default=0.0,
|
||||
help="Round the theoretical sale price (after taxes) to the nearest multiple of this value. "
|
||||
"Set to 0.00 to disable rounding (e.g. 0.05 rounds to the nearest 5 cents).",
|
||||
)
|
||||
|
||||
def _compute_price_rule(self, products, qty, uom=None, date=False, **kwargs):
|
||||
ProductPricelistItem = self.env["product.pricelist.item"]
|
||||
ProductProduct = self.env["product.product"]
|
||||
|
|
|
|||
|
|
@ -45,6 +45,51 @@ class ProductTemplate(models.Model):
|
|||
required=True,
|
||||
company_dependent=True,
|
||||
)
|
||||
configured_sale_margin = fields.Float(
|
||||
string="Configured sale margin (%)",
|
||||
digits="Discount",
|
||||
compute="_compute_configured_sale_margin",
|
||||
help="Effective margin configured by the automatic pricelist chain for "
|
||||
"this product. It reflects tariff configuration, not the current "
|
||||
"manual sale price.",
|
||||
)
|
||||
|
||||
def _compute_configured_sale_margin(self):
|
||||
pricelist_id = (
|
||||
self.env["ir.config_parameter"]
|
||||
.sudo()
|
||||
.get_param("product_sale_price_from_pricelist.product_pricelist_automatic")
|
||||
or False
|
||||
)
|
||||
if not pricelist_id:
|
||||
for template in self:
|
||||
template.configured_sale_margin = 0.0
|
||||
return
|
||||
|
||||
pricelist = self.env["product.pricelist"].browse(int(pricelist_id))
|
||||
for template in self:
|
||||
template.configured_sale_margin = 0.0
|
||||
if (
|
||||
not template.product_variant_id
|
||||
or template.last_purchase_price_compute_type == "manual_update"
|
||||
or not template.last_purchase_price_received
|
||||
):
|
||||
continue
|
||||
|
||||
# Get the final untaxed price after all chained pricelists are applied.
|
||||
final_price = template.product_variant_id._get_price(
|
||||
qty=1,
|
||||
pricelist=pricelist,
|
||||
)
|
||||
untaxed_price = final_price.get(template.product_variant_id.id, {}).get(
|
||||
"value"
|
||||
)
|
||||
if untaxed_price is None:
|
||||
continue
|
||||
|
||||
template.configured_sale_margin = (
|
||||
(untaxed_price / template.last_purchase_price_received) - 1.0
|
||||
) * 100.0
|
||||
|
||||
def _compute_theoritical_price(self):
|
||||
pricelist_obj = self.env["product.pricelist"]
|
||||
|
|
@ -82,9 +127,10 @@ class ProductTemplate(models.Model):
|
|||
tax_price["taxes"][0]["amount"]
|
||||
+ partial_price[template.product_variant_id.id]["value"]
|
||||
)
|
||||
# Round to 0.05
|
||||
if round(price_with_taxes % 0.05, 2) != 0:
|
||||
price_with_taxes = round(price_with_taxes * 20) / 20
|
||||
# Round to configurable step (defined on the pricelist)
|
||||
step = pricelist.price_rounding_step
|
||||
if step:
|
||||
price_with_taxes = math.ceil(price_with_taxes / step) * step
|
||||
|
||||
template.write(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
readonly="1"
|
||||
/>
|
||||
<field name="list_price_theoritical" readonly="1" />
|
||||
<field name="configured_sale_margin" readonly="1" />
|
||||
<field name="last_purchase_price_updated" readonly="1" />
|
||||
</field>
|
||||
</field>
|
||||
|
|
@ -40,6 +41,19 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_pricelist_view_price_rounding" model="ir.ui.view">
|
||||
<field name="name">product.pricelist.view.price.rounding</field>
|
||||
<field name="model">product.pricelist</field>
|
||||
<field name="inherit_id" ref="product.product_pricelist_view" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='pricelist_config']//group[@name='pricelist_availability']" position="after">
|
||||
<group name="pricelist_rounding" string="Sale Price Rounding">
|
||||
<field name="price_rounding_step" />
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form_pricelists" model="ir.ui.view">
|
||||
<field name="name">product.print.supermarket.res.config.settings.form</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# Purchase Order Supplierinfo Update Triple Discount
|
||||
|
||||
This module extends `purchase_order_supplierinfo_update` to optionally update triple discount fields in supplierinfo when confirming purchase orders.
|
||||
|
||||
## Features
|
||||
|
||||
- Adds three Purchase settings to enable/disable synchronization for each field independently.
|
||||
- Keeps original behavior for supplier price update.
|
||||
- Updates `discount1`, `discount2` and `discount3` from purchase order lines to supplierinfo only for the enabled fields.
|
||||
|
|
@ -0,0 +1 @@
|
|||
from . import models
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Copyright 2026 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
{
|
||||
"name": "Purchase Order Supplierinfo Update Triple Discount",
|
||||
"version": "16.0.1.0.0",
|
||||
"summary": "Optionally sync triple discounts to supplierinfo on purchase confirmation",
|
||||
"license": "AGPL-3",
|
||||
"author": "Criptomart",
|
||||
"website": "https://criptomart.net",
|
||||
"depends": [
|
||||
"purchase_order_supplierinfo_update",
|
||||
"purchase_triple_discount",
|
||||
],
|
||||
"data": [
|
||||
"views/res_config_settings_views.xml",
|
||||
],
|
||||
"installable": True,
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * purchase_order_supplierinfo_update_triple_discount
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-02 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-04-02 00:00+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \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"
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1
|
||||
msgid "Update Supplierinfo Discount 1"
|
||||
msgstr "Actualizar Descuento 1 en Info de Proveedor"
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2
|
||||
msgid "Update Supplierinfo Discount 2"
|
||||
msgstr "Actualizar Descuento 2 en Info de Proveedor"
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3
|
||||
msgid "Update Supplierinfo Discount 3"
|
||||
msgstr "Actualizar Descuento 3 en Info de Proveedor"
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1
|
||||
msgid "If enabled, confirming a purchase order will update discount1."
|
||||
msgstr "Si está habilitado, al confirmar una orden de compra se actualizará el descuento1."
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2
|
||||
msgid "If enabled, confirming a purchase order will update discount2."
|
||||
msgstr "Si está habilitado, al confirmar una orden de compra se actualizará el descuento2."
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3
|
||||
msgid "If enabled, confirming a purchase order will update discount3."
|
||||
msgstr "Si está habilitado, al confirmar una orden de compra se actualizará el descuento3."
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount
|
||||
msgid "Update discount1 from purchase lines into supplierinfo"
|
||||
msgstr "Actualizar descuento1 de las líneas de compra en la info del proveedor"
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount
|
||||
msgid "Update discount2 from purchase lines into supplierinfo"
|
||||
msgstr "Actualizar descuento2 de las líneas de compra en la info del proveedor"
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount
|
||||
msgid "Update discount3 from purchase lines into supplierinfo"
|
||||
msgstr "Actualizar descuento3 de las líneas de compra en la info del proveedor"
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * purchase_order_supplierinfo_update_triple_discount
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-02 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-04-02 00:00+0000\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: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1
|
||||
msgid "Update Supplierinfo Discount 1"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2
|
||||
msgid "Update Supplierinfo Discount 2"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3
|
||||
msgid "Update Supplierinfo Discount 3"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1
|
||||
msgid "If enabled, confirming a purchase order will update discount1."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2
|
||||
msgid "If enabled, confirming a purchase order will update discount2."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3
|
||||
msgid "If enabled, confirming a purchase order will update discount3."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount
|
||||
msgid "Update discount1 from purchase lines into supplierinfo"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount
|
||||
msgid "Update discount2 from purchase lines into supplierinfo"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_supplierinfo_update_triple_discount
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount
|
||||
msgid "Update discount3 from purchase lines into supplierinfo"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
from . import purchase_order_line
|
||||
from . import res_config_settings
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
from odoo import models
|
||||
from odoo.tools.misc import str2bool
|
||||
|
||||
|
||||
class PurchaseOrderLine(models.Model):
|
||||
_inherit = "purchase.order.line"
|
||||
|
||||
_SUPPLIERINFO_DISCOUNT_CONFIG = {
|
||||
"discount1": (
|
||||
"purchase_order_supplierinfo_update_triple_discount"
|
||||
".update_supplierinfo_discount1"
|
||||
),
|
||||
"discount2": (
|
||||
"purchase_order_supplierinfo_update_triple_discount"
|
||||
".update_supplierinfo_discount2"
|
||||
),
|
||||
"discount3": (
|
||||
"purchase_order_supplierinfo_update_triple_discount"
|
||||
".update_supplierinfo_discount3"
|
||||
),
|
||||
}
|
||||
|
||||
def _update_supplierinfo(self, seller):
|
||||
"""Extend supplierinfo update to optionally sync each discount field."""
|
||||
self.ensure_one()
|
||||
super()._update_supplierinfo(seller)
|
||||
if not seller:
|
||||
return
|
||||
|
||||
config = self.env["ir.config_parameter"].sudo()
|
||||
values = {}
|
||||
for field_name, parameter_name in self._SUPPLIERINFO_DISCOUNT_CONFIG.items():
|
||||
if field_name not in self._fields or field_name not in seller._fields:
|
||||
continue
|
||||
should_update = str2bool(
|
||||
config.get_param(parameter_name, default=False),
|
||||
default=False,
|
||||
)
|
||||
if should_update:
|
||||
values[field_name] = self[field_name]
|
||||
|
||||
if values:
|
||||
seller.sudo().write(values)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
update_supplierinfo_discount1 = fields.Boolean(
|
||||
string="Update Supplierinfo Discount 1",
|
||||
config_parameter=(
|
||||
"purchase_order_supplierinfo_update_triple_discount"
|
||||
".update_supplierinfo_discount1"
|
||||
),
|
||||
help="If enabled, confirming a purchase order will update discount1.",
|
||||
)
|
||||
|
||||
update_supplierinfo_discount2 = fields.Boolean(
|
||||
string="Update Supplierinfo Discount 2",
|
||||
config_parameter=(
|
||||
"purchase_order_supplierinfo_update_triple_discount"
|
||||
".update_supplierinfo_discount2"
|
||||
),
|
||||
help="If enabled, confirming a purchase order will update discount2.",
|
||||
)
|
||||
|
||||
update_supplierinfo_discount3 = fields.Boolean(
|
||||
string="Update Supplierinfo Discount 3",
|
||||
config_parameter=(
|
||||
"purchase_order_supplierinfo_update_triple_discount"
|
||||
".update_supplierinfo_discount3"
|
||||
),
|
||||
help="If enabled, confirming a purchase order will update discount3.",
|
||||
)
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="res_config_settings_view_form_purchase_supplierinfo_triple_discount" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.purchase.supplierinfo.triple.discount</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="purchase.res_config_settings_view_form_purchase" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='auto_receipt_reminder']" position="after">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="update_supplierinfo_triple_discount">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="update_supplierinfo_discount1" />
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="update_supplierinfo_discount1" />
|
||||
<div class="text-muted">
|
||||
Update discount1 from purchase lines into supplierinfo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="update_supplierinfo_discount2">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="update_supplierinfo_discount2" />
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="update_supplierinfo_discount2" />
|
||||
<div class="text-muted">
|
||||
Update discount2 from purchase lines into supplierinfo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="update_supplierinfo_discount3">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="update_supplierinfo_discount3" />
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="update_supplierinfo_discount3" />
|
||||
<div class="text-muted">
|
||||
Update discount3 from purchase lines into supplierinfo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
9
purchase_price_review_status/README.md
Normal file
9
purchase_price_review_status/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Purchase Price Review Status
|
||||
|
||||
Adds a boolean field on purchase orders to indicate whether purchase prices were reviewed against receipts.
|
||||
|
||||
It decorates list views according to these rules:
|
||||
|
||||
- Green: not fully received and prices reviewed.
|
||||
- Red: not fully received and prices not reviewed.
|
||||
- Default color: fully received (unchanged behavior).
|
||||
1
purchase_price_review_status/__init__.py
Normal file
1
purchase_price_review_status/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from . import models
|
||||
16
purchase_price_review_status/__manifest__.py
Normal file
16
purchase_price_review_status/__manifest__.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Copyright 2026 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
{
|
||||
"name": "Purchase Price Review Status",
|
||||
"version": "16.0.1.0.0",
|
||||
"summary": "Track if purchase prices were reviewed and color PO/receipt lists",
|
||||
"license": "AGPL-3",
|
||||
"author": "Criptomart",
|
||||
"website": "https://criptomart.net",
|
||||
"depends": ["purchase_stock"],
|
||||
"data": [
|
||||
"views/purchase_order_views.xml",
|
||||
"views/stock_picking_views.xml",
|
||||
],
|
||||
"installable": True,
|
||||
}
|
||||
39
purchase_price_review_status/i18n/es.po
Normal file
39
purchase_price_review_status/i18n/es.po
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * purchase_price_review_status
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-02 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-04-02 00:00+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \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"
|
||||
|
||||
#. module: purchase_price_review_status
|
||||
#: model:ir.model.fields,field_description:purchase_price_review_status.field_purchase_order__prices_reviewed
|
||||
#: model:ir.model.fields,field_description:purchase_price_review_status.field_stock_picking__purchase_prices_reviewed
|
||||
msgid "Purchase Prices Reviewed"
|
||||
msgstr "Precios de Compra Revisados"
|
||||
|
||||
#. module: purchase_price_review_status
|
||||
#: model:ir.model.fields,help:purchase_price_review_status.field_purchase_order__prices_reviewed
|
||||
msgid "Indicates whether purchase prices were reviewed against the receipt."
|
||||
msgstr "Indica si los precios de compra fueron revisados con la recepción."
|
||||
|
||||
#. module: purchase_price_review_status
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_purchase_order_filter_price_review
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.purchase_order_view_search_price_review
|
||||
msgid "Prices Not Reviewed"
|
||||
msgstr "Precios No Revisados"
|
||||
|
||||
#. module: purchase_price_review_status
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_picking_internal_search_price_review
|
||||
msgid "Purchase Prices Not Reviewed"
|
||||
msgstr "Precios de Compra No Revisados"
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * purchase_price_review_status
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-02 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-04-02 00:00+0000\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: purchase_price_review_status
|
||||
#: model:ir.model.fields,field_description:purchase_price_review_status.field_purchase_order__prices_reviewed
|
||||
#: model:ir.model.fields,field_description:purchase_price_review_status.field_stock_picking__purchase_prices_reviewed
|
||||
msgid "Purchase Prices Reviewed"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_price_review_status
|
||||
#: model:ir.model.fields,help:purchase_price_review_status.field_purchase_order__prices_reviewed
|
||||
msgid "Indicates whether purchase prices were reviewed against the receipt."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_price_review_status
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_purchase_order_filter_price_review
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.purchase_order_view_search_price_review
|
||||
msgid "Prices Not Reviewed"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_price_review_status
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_picking_internal_search_price_review
|
||||
msgid "Purchase Prices Not Reviewed"
|
||||
msgstr ""
|
||||
2
purchase_price_review_status/models/__init__.py
Normal file
2
purchase_price_review_status/models/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from . import purchase_order
|
||||
from . import stock_picking
|
||||
11
purchase_price_review_status/models/purchase_order.py
Normal file
11
purchase_price_review_status/models/purchase_order.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from odoo import fields, models
|
||||
|
||||
|
||||
class PurchaseOrder(models.Model):
|
||||
_inherit = "purchase.order"
|
||||
|
||||
prices_reviewed = fields.Boolean(
|
||||
string="Purchase Prices Reviewed",
|
||||
default=False,
|
||||
help="Indicates whether purchase prices were reviewed against the receipt.",
|
||||
)
|
||||
12
purchase_price_review_status/models/stock_picking.py
Normal file
12
purchase_price_review_status/models/stock_picking.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from odoo import fields, models
|
||||
|
||||
|
||||
class StockPicking(models.Model):
|
||||
_inherit = "stock.picking"
|
||||
|
||||
purchase_prices_reviewed = fields.Boolean(
|
||||
related="purchase_id.prices_reviewed",
|
||||
string="Purchase Prices Reviewed",
|
||||
readonly=True,
|
||||
store=False,
|
||||
)
|
||||
93
purchase_price_review_status/views/purchase_order_views.xml
Normal file
93
purchase_price_review_status/views/purchase_order_views.xml
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="purchase_order_form_price_review" model="ir.ui.view">
|
||||
<field name="name">purchase.order.form.price.review</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='partner_ref']" position="after">
|
||||
<field name="prices_reviewed" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="purchase_order_view_tree_price_review" model="ir.ui.view">
|
||||
<field name="name">purchase.order.view.tree.price.review</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="decoration-success">receipt_status != 'full' and prices_reviewed</attribute>
|
||||
<attribute name="decoration-danger">receipt_status != 'full' and not prices_reviewed</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='name']" position="before">
|
||||
<field name="prices_reviewed" optional="hide" />
|
||||
<field name="receipt_status" invisible="1" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="purchase_order_tree_price_review" model="ir.ui.view">
|
||||
<field name="name">purchase.order.tree.price.review</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="decoration-success">receipt_status != 'full' and prices_reviewed</attribute>
|
||||
<attribute name="decoration-danger">receipt_status != 'full' and not prices_reviewed</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='name']" position="before">
|
||||
<field name="prices_reviewed" optional="hide" />
|
||||
<field name="receipt_status" invisible="1" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="purchase_order_kpis_tree_price_review" model="ir.ui.view">
|
||||
<field name="name">purchase.order.kpis.tree.price.review</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_kpis_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="decoration-success">receipt_status != 'full' and prices_reviewed</attribute>
|
||||
<attribute name="decoration-danger">receipt_status != 'full' and not prices_reviewed</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='name']" position="before">
|
||||
<field name="prices_reviewed" optional="hide" />
|
||||
<field name="receipt_status" invisible="1" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_purchase_order_filter_price_review" model="ir.ui.view">
|
||||
<field name="name">purchase.order.filter.price.review</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.view_purchase_order_filter" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='starred']" position="after">
|
||||
<filter
|
||||
name="prices_not_reviewed"
|
||||
string="Prices Not Reviewed"
|
||||
domain="[('prices_reviewed', '=', False)]"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="purchase_order_view_search_price_review" model="ir.ui.view">
|
||||
<field name="name">purchase.order.view.search.price.review</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_view_search" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='starred']" position="after">
|
||||
<filter
|
||||
name="prices_not_reviewed"
|
||||
string="Prices Not Reviewed"
|
||||
domain="[('prices_reviewed', '=', False)]"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
39
purchase_price_review_status/views/stock_picking_views.xml
Normal file
39
purchase_price_review_status/views/stock_picking_views.xml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="stock_picking_tree_price_review" model="ir.ui.view">
|
||||
<field name="name">stock.picking.tree.price.review</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.vpicktree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="decoration-success">picking_type_code == 'incoming' and state not in ('done', 'cancel') and purchase_id and purchase_prices_reviewed</attribute>
|
||||
<attribute name="decoration-danger">picking_type_code == 'incoming' and state not in ('done', 'cancel') and purchase_id and not purchase_prices_reviewed</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='name']" position="before">
|
||||
<field name="purchase_id" invisible="1" />
|
||||
<field name="purchase_prices_reviewed" optional="hide" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_picking_internal_search_price_review" model="ir.ui.view">
|
||||
<field name="name">stock.picking.internal.search.price.review</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_internal_search" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//filter[@name='starred']" position="after">
|
||||
<filter
|
||||
name="purchase_prices_not_reviewed"
|
||||
string="Purchase Prices Not Reviewed"
|
||||
domain="[
|
||||
('picking_type_code', '=', 'incoming'),
|
||||
('purchase_id', '!=', False),
|
||||
('purchase_id.prices_reviewed', '=', False)
|
||||
]"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue