Arbore/arbore#155 add supplier name to purchase order lines in a separate column

This commit is contained in:
Luis 2025-10-17 11:28:11 +02:00
parent 8049272620
commit fc3b037436
10 changed files with 338 additions and 0 deletions

View file

@ -0,0 +1,50 @@
# Product Supplier Name in Purchase
## Overview
This module extends purchase order lines by adding the supplier's product name field. This allows users to see how the supplier refers to each product and enables sorting and filtering purchase order lines by the supplier's product name.
## Features
- **Supplier Product Name Field**: Displays the product name as defined by the supplier in the product supplier info
- **Automatic Computation**: The field is automatically computed based on the selected partner and product
- **Search and Filter**: Enables searching and filtering purchase order lines by supplier product name
- **Sortable Column**: Allows sorting purchase order lines by supplier product name
- **Multi-language Support**: Includes translations for Spanish, Catalan, and Galician
## Installation
1. Copy the module to your Odoo addons directory
2. Update the apps list in Odoo
3. Install the module from the Apps menu
## Usage
1. Go to Purchase → Purchase Orders
2. Create or edit a purchase order
3. Add purchase order lines with products that have supplier info configured
4. The "Supplier Product Name" column will automatically show the supplier's name for each product
5. Use this column to sort or filter the lines as needed
## Configuration
Make sure your products have supplier information configured:
1. Go to Inventory → Products → Products
2. Select a product and go to the "Purchase" tab
3. Add vendor information with the supplier's product name
## Technical Details
- **Model Extended**: `purchase.order.line`
- **New Field**: `product_supplier_name` (computed, stored)
- **Dependencies**: `purchase`
- **Version**: 16.0.1.0.0
## Author
**Criptomart**
- Maintainer: Luis Nore
## License
AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)

View file

@ -0,0 +1,4 @@
# Copyright 2025 Criptomart
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import models

View file

@ -0,0 +1,18 @@
# Copyright 2025 Criptomart
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Product Supplier Name in Purchase",
"summary": """This module adds to the purchase order line the supplier
name defined in the product supplier info.""",
"version": "16.0.1.0.0",
"author": "Criptomart",
"maintainers": ["luisnore"],
"website": "https://github.com/criptomart",
"category": "Purchase Management",
"license": "AGPL-3",
"depends": ["purchase"],
"data": ["views/purchase_order_view.xml"],
"installable": True,
"development_status": "Beta",
}

View file

@ -0,0 +1,38 @@
# Catalan translation for product_supplier_name_purchase.
# Copyright (C) 2025 Criptomart
# This file is distributed under the same license as the product_supplier_name_purchase package.
# Luis Nore <luisnore@criptomart.com>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: product_supplier_name_purchase 16.0.1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-17 08:00+0000\n"
"PO-Revision-Date: 2025-10-17 08:00+0000\n"
"Last-Translator: Luis Nore <luisnore@criptomart.com>\n"
"Language-Team: Catalan\n"
"Language: ca\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: product_supplier_name_purchase
#: model:ir.model.fields,field_description:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Supplier Product Name"
msgstr "Nom del Producte del Proveïdor"
#. module: product_supplier_name_purchase
#: model:ir.model.fields,help:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Product name as defined by the supplier in the product supplier info."
msgstr "Nom del producte segons el defineix el proveïdor en la informació de proveïdors del producte."
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order
msgid "Purchase Order"
msgstr "Ordre de Compra"
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Línia d'Ordre de Compra"

View file

@ -0,0 +1,38 @@
# Spanish translation for product_supplier_name_purchase.
# Copyright (C) 2025 Criptomart
# This file is distributed under the same license as the product_supplier_name_purchase package.
# Luis Nore <luisnore@criptomart.com>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: product_supplier_name_purchase 16.0.1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-17 08:00+0000\n"
"PO-Revision-Date: 2025-10-17 08:00+0000\n"
"Last-Translator: Luis Nore <luisnore@criptomart.com>\n"
"Language-Team: Spanish\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: product_supplier_name_purchase
#: model:ir.model.fields,field_description:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Supplier Product Name"
msgstr "Nombre Producto del Proveedor"
#. module: product_supplier_name_purchase
#: model:ir.model.fields,help:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Product name as defined by the supplier in the product supplier info."
msgstr "Nombre del producto según lo define el proveedor en la información de proveedores del producto."
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order
msgid "Purchase Order"
msgstr "Orden de Compra"
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Línea de Orden de Compra"

View file

@ -0,0 +1,38 @@
# Galician translation for product_supplier_name_purchase.
# Copyright (C) 2025 Criptomart
# This file is distributed under the same license as the product_supplier_name_purchase package.
# Luis Nore <luisnore@criptomart.com>, 2025.
#
msgid ""
msgstr ""
"Project-Id-Version: product_supplier_name_purchase 16.0.1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-17 08:00+0000\n"
"PO-Revision-Date: 2025-10-17 08:00+0000\n"
"Last-Translator: Luis Nore <luisnore@criptomart.com>\n"
"Language-Team: Galician\n"
"Language: gl\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: product_supplier_name_purchase
#: model:ir.model.fields,field_description:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Supplier Product Name"
msgstr "Nome do Produto do Provedor"
#. module: product_supplier_name_purchase
#: model:ir.model.fields,help:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Product name as defined by the supplier in the product supplier info."
msgstr "Nome do produto segundo o define o provedor na información de provedores do produto."
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order
msgid "Purchase Order"
msgstr "Orde de Compra"
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Liña de Orde de Compra"

View file

@ -0,0 +1,37 @@
# Translation template for product_supplier_name_purchase.
# Copyright (C) 2025 Criptomart
# This file is distributed under the same license as the product_supplier_name_purchase package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: product_supplier_name_purchase 16.0.1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-17 08:00+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#. module: product_supplier_name_purchase
#: model:ir.model.fields,field_description:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Supplier Product Name"
msgstr ""
#. module: product_supplier_name_purchase
#: model:ir.model.fields,help:product_supplier_name_purchase.field_purchase_order_line__product_supplier_name
msgid "Product name as defined by the supplier in the product supplier info."
msgstr ""
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order
msgid "Purchase Order"
msgstr ""
#. module: product_supplier_name_purchase
#: model:ir.model,name:product_supplier_name_purchase.model_purchase_order_line
msgid "Purchase Order Line"
msgstr ""

View file

@ -0,0 +1,4 @@
# Copyright 2025 Criptomart
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import purchase_order

View file

@ -0,0 +1,71 @@
# Copyright 2025 Criptomart
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
from odoo.exceptions import AccessError
class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"
product_supplier_name = fields.Char(
string="Supplier Product Name",
compute="_compute_product_supplier_name",
store=True,
help="Product name as defined by the supplier in the product supplier info.",
)
@api.depends("partner_id", "product_id")
def _compute_product_supplier_name(self):
for line in self:
name = ""
if line.product_id and line.partner_id:
# First try to find exact product match
supplier_info = line.product_id.seller_ids.filtered(
lambda s: (
s.product_id == line.product_id
and s.partner_id == line.partner_id
)
)
if supplier_info:
name = supplier_info[0].product_name or ""
else:
# If no exact match, try product template
supplier_info = line.product_id.seller_ids.filtered(
lambda s: (
s.product_tmpl_id == line.product_id.product_tmpl_id
and s.partner_id == line.partner_id
)
)
if supplier_info:
name = supplier_info[0].product_name or ""
line.product_supplier_name = name
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
def _add_supplier_to_product(self):
"""Override to also update supplier product name when adding supplier."""
res = super()._add_supplier_to_product()
for line in self.order_line:
partner = (
self.partner_id
if not self.partner_id.parent_id
else self.partner_id.parent_id
)
if partner in line.product_id.seller_ids.mapped("partner_id"):
seller = line.product_id._select_seller(
partner_id=line.partner_id,
quantity=line.product_qty,
date=line.order_id.date_order and line.order_id.date_order.date(),
uom_id=line.product_uom,
)
if seller and hasattr(line, "product_supplier_name"):
try:
# Update supplier info with the current product name
if line.product_supplier_name:
seller.write({"product_name": line.product_supplier_name})
except AccessError:
break
return res

View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="purchase_order_form_supplier_name" model="ir.ui.view">
<field name="name">purchase.order.form.supplier.name</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='product_id']"
position="after"
>
<field name="product_supplier_name" optional="hide" />
</xpath>
</field>
</record>
<record id="purchase_order_line_tree_supplier_name" model="ir.ui.view">
<field name="name">purchase.order.line.tree.supplier.name</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="product_id" position="after">
<field name="product_supplier_name" optional="show" />
</field>
</field>
</record>
<record id="purchase_order_line_search_supplier_name" model="ir.ui.view">
<field name="name">purchase.order.line.search.supplier.name</field>
<field name="model">purchase.order.line</field>
<field name="inherit_id" ref="purchase.purchase_order_line_search" />
<field name="arch" type="xml">
<field name="product_id" position="after">
<field name="product_supplier_name" />
</field>
</field>
</record>
</odoo>