======================================
Product Price Category - Supplier
======================================

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_id`` en 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
============

1. Abrir formulario de un **Proveedor** (res.partner)
2. Ir a pestaña **"Compras"** (Purchases)
3. En sección **"Price Category Settings"**, seleccionar **categoría de precio
   por defecto**
4. Hacer clic en botón **"Apply to All Products"**
5. Se abre modal de confirmación mostrando:

   - Nombre del proveedor
   - Categoría de precio a aplicar
   - Cantidad de productos que serán actualizados

6. Hacer clic **"Confirm"** para ejecutar actualización en bulk
7. Notificación de éxito mostrando cantidad de productos actualizados

Campos
======

res.partner - Campos añadidos
------------------------------

- ``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) - Readonly
- ``partner_name`` (Char, related to partner_id.name) - Readonly
- ``price_category_id`` (Many2one → product.price.category) - Readonly
- ``product_count`` (Integer) - Cantidad de productos a actualizar - Readonly

**Métodos**:

- ``action_confirm()`` - Realiza bulk update de productos y retorna notificación

Vistas
======

res.partner views
-----------------

- **Form**: Campo + botón en pestaña "Compras"
- **Tree**: Campo oculto (column_invisible=1)

wizard.update.product.category views
------------------------------------

- **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:

1. Se buscan todos los productos (``product.template``) donde:

   - ``default_supplier_id = partner_id`` (este proveedor es su proveedor por
     defecto)

2. Se actualizan en bulk (single SQL UPDATE) con:

   - ``price_category_id = default_price_category_id``

3. 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

Créditos
========

Autor
-----

Criptomart - 2026

Licencia
--------

AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
