- Changed xpath from div[@id='website_info_settings'] to block[@id='website_info_settings'] - Fixes RPC error when loading res.config.settings view [FIX] product_price_category_supplier: Convert README to reStructuredText - Converted README.md to README.rst for proper Odoo documentation - Fixed docutils warnings and formatting issues - Updated reStructuredText syntax for code blocks and literals |
||
|---|---|---|
| .. | ||
| i18n | ||
| models | ||
| security | ||
| tests | ||
| views | ||
| __init__.py | ||
| __manifest__.py | ||
| BEFORE_AND_AFTER.md | ||
| ERROR_FIX_REPORT.md | ||
| IMPLEMENTACION_RESUMEN.txt | ||
| install_addon.sh | ||
| INSTALLATION_COMPLETE.md | ||
| INSTALLATION_STATUS.md | ||
| QUICK_FIX_REFERENCE.md | ||
| QUICK_START.sh | ||
| README.md | ||
| README.rst | ||
| TEST_REPORT.md | ||
| VALIDATION.md | ||
Product Price Category - Supplier Extension
Extiende res.partner (proveedores) con un campo de categoría de precio por defecto y permite actualizar masivamente todos los productos de un proveedor con esta categoría mediante un wizard.
Funcionalidades
- Campo en Proveedores: Añade campo
default_price_category_iden la pestaña "Compras" (Purchases) de res.partner - Actualización Masiva: Botón que abre wizard modal para confirmar actualización de todos los productos del proveedor
- Columna Configurable: Campo oculto en vista tree de partner, visible/configurable desde menú de columnas
- Control de Permisos: Acceso restringido a
sales_team.group_sale_manager(Gestores de Ventas)
Dependencias
product_price_category(OCA addon base)product_pricelists_margins_custom(Addon del proyecto)sales_team(Odoo core)
Instalación
docker-compose exec -T odoo odoo -d odoo -u product_price_category_supplier --stop-after-init
Flujo de Uso
- Abrir formulario de un Proveedor (res.partner)
- Ir a pestaña "Compras" (Purchases)
- En sección "Price Category Settings", seleccionar categoría de precio por defecto
- Hacer clic en botón "Apply to All Products"
- Se abre modal de confirmación mostrando:
- Nombre del proveedor
- Categoría de precio a aplicar
- Cantidad de productos que serán actualizados
- Hacer clic "Confirm" para ejecutar actualización en bulk
- Notificación de éxito mostrando cantidad de productos actualizados
Campos
res.partner
default_price_category_id(Many2one → product.price.category)- Ubicación: Pestaña "Compras", sección "Price Category Settings"
- Obligatorio: No
- Ayuda: "Default price category for products from this supplier"
- Visible en tree: Oculto por defecto (column_invisible=1), configurable vía menú
Modelos
wizard.update.product.category (Transient)
partner_id(Many2one → res.partner) - Readonlypartner_name(Char, related to partner_id.name) - Readonlyprice_category_id(Many2one → product.price.category) - Readonlyproduct_count(Integer) - Cantidad de productos a actualizar - Readonly
Métodos:
action_confirm()- Realiza bulk update de productos y retorna notificación
Vistas
res.partner
- Form: Campo + botón en pestaña "Compras"
- Tree: Campo oculto (column_invisible=1)
wizard.update.product.category
- Form: Formulario modal con información de confirmación y botones
Seguridad
Acceso al wizard restringido a grupo sales_team.group_sale_manager:
- Lectura: Sí
- Escritura: Sí
- Creación: Sí
- Borrado: Sí
Comportamiento
Actualización de Productos
Cuando el usuario confirma la acción:
-
Se buscan todos los productos (
product.template) donde:default_supplier_id = partner_id(este proveedor es su proveedor por defecto)
-
Se actualizan en bulk (single SQL UPDATE) con:
price_category_id = default_price_category_id
-
Se retorna notificación de éxito:
- "X products updated with category 'CATEGORY_NAME'."
Nota: La actualización SOBRESCRIBE cualquier price_category_id existente en los productos.
Extensión Futura
Para implementar defaults automáticos al crear productos desde un proveedor:
# En models/product_template.py
@api.model_create_multi
def create(self, vals_list):
# Si se proporciona default_supplier_id sin price_category_id,
# usar default_price_category_id del proveedor
for vals in vals_list:
if vals.get('default_supplier_id') and not vals.get('price_category_id'):
supplier = self.env['res.partner'].browse(vals['default_supplier_id'])
if supplier.default_price_category_id:
vals['price_category_id'] = supplier.default_price_category_id.id
return super().create(vals_list)
Traducciones
Para añadir/actualizar traducciones:
# Exportar strings
docker-compose exec -T odoo odoo -d odoo \
--addons-path=/mnt/extra-addons/product_price_category_supplier \
-i product_price_category_supplier \
--i18n-export=/tmp/product_price_category_supplier.pot \
--stop-after-init
# Mergar en archivos .po existentes
cd product_price_category_supplier/i18n
for lang in es eu; do
msgmerge -U ${lang}.po product_price_category_supplier.pot
done
Testing
Ejecutar tests:
docker-compose exec -T odoo odoo -d odoo \
-i product_price_category_supplier \
--test-enable --stop-after-init
Autor
Your Company - 2026
Licencia
AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)