add purchase_price_review_status

This commit is contained in:
Luis 2026-04-02 12:43:36 +02:00
parent d9a0eeb878
commit f586c99df9
10 changed files with 260 additions and 0 deletions

View 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).

View file

@ -0,0 +1 @@
from . import models

View 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,
}

View 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"

View file

@ -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 ""

View file

@ -0,0 +1,2 @@
from . import purchase_order
from . import stock_picking

View 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.",
)

View 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,
)

View 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>

View 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>