Compare commits
No commits in common. "4207afbc3fe435453df47108d797062c4cb934e4" and "2a480b74bbd6ab1f2a17e02c6ee029e8b2899c9e" have entirely different histories.
4207afbc3f
...
2a480b74bb
21 changed files with 483 additions and 2410 deletions
411
.github/copilot-instructions.md
vendored
411
.github/copilot-instructions.md
vendored
|
|
@ -1,411 +0,0 @@
|
||||||
# GitHub Copilot Instructions - Kidekoop Addons Custom
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
Este repositorio contiene addons personalizados y modificados de Odoo 18.0. El proyecto combina:
|
|
||||||
|
|
||||||
- **OCB (Odoo Community Backports)**: Base de Odoo 18.0 community en `/ocb`
|
|
||||||
- **Addons OCA**: Módulos de la comunidad OCA de los que heredan nuestros addons, modificados para adaptarse a nuestras necesidades
|
|
||||||
- **Addons Custom**: Módulos desarrollados por este proyecto
|
|
||||||
|
|
||||||
## Architecture & Stack
|
|
||||||
|
|
||||||
- **Odoo Version**: 18.0 (OCB)
|
|
||||||
- **Python Version**: 3.10+
|
|
||||||
- **Framework**: Odoo ORM
|
|
||||||
- **Deployment**: Docker Compose
|
|
||||||
- **DB**: PostgreSQL
|
|
||||||
- **Languages**: Python, XML, JavaScript, QWeb
|
|
||||||
|
|
||||||
## Code Standards
|
|
||||||
|
|
||||||
### Python Style
|
|
||||||
|
|
||||||
- Seguir **OCA guidelines** estrictamente
|
|
||||||
- Usar **black** para formateo (configurado en `pyproject.toml`)
|
|
||||||
- **isort** para ordenar imports (perfil black)
|
|
||||||
- **flake8** para linting
|
|
||||||
- **pylint** con pylint-odoo para verificaciones específicas de Odoo
|
|
||||||
- Pre-commit hooks activos (ver `.pre-commit-config.yaml`)
|
|
||||||
|
|
||||||
### Odoo Conventions
|
|
||||||
|
|
||||||
- **Model names**: snake_case con punto (`product.price.category`)
|
|
||||||
- **Class names**: PascalCase (`ProductPriceCategory`)
|
|
||||||
- **File names**: snake_case (`product_price_category.py`)
|
|
||||||
- **XML IDs**: módulo.nombre_descriptivo (`product_price_category.view_form`)
|
|
||||||
- **Manifest**: Siempre `__manifest__.py`, nunca `__openerp__.py`
|
|
||||||
|
|
||||||
### XML/View Standards
|
|
||||||
|
|
||||||
- **Indent**: 4 espacios (no tabs)
|
|
||||||
- **XPath**: Usar `position` explícito (`before`, `after`, `inside`, `replace`, `attributes`)
|
|
||||||
- **Groups**: Referenciar grupos con módulo.xml_id (`sales_team.group_sale_manager`)
|
|
||||||
- **Sequence**: Usar `sequence` attribute para ordenar campos en vistas
|
|
||||||
|
|
||||||
### Translation System
|
|
||||||
|
|
||||||
**IMPORTANTE**: El sistema de traducciones está funcionando correctamente. Seguir estas reglas:
|
|
||||||
|
|
||||||
1. **Estructura de carpeta i18n/**:
|
|
||||||
|
|
||||||
```
|
|
||||||
addon_name/
|
|
||||||
├── i18n/
|
|
||||||
│ ├── es.po # Español (obligatorio)
|
|
||||||
│ ├── eu.po # Euskera (obligatorio)
|
|
||||||
│ └── addon_name.pot # Template (generado)
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **NO usar `_()` en definiciones de campos a nivel de módulo**:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# ❌ INCORRECTO - causa warnings
|
|
||||||
from odoo import _
|
|
||||||
name = fields.Char(string=_("Name"))
|
|
||||||
|
|
||||||
# ✅ CORRECTO - traducción se maneja por .po files
|
|
||||||
name = fields.Char(string="Name")
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Usar `_()` solo en métodos y código ejecutable**:
|
|
||||||
|
|
||||||
```python
|
|
||||||
def action_confirm(self):
|
|
||||||
message = _("Confirmed successfully")
|
|
||||||
return {'warning': {'message': message}}
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Generar/actualizar traducciones**:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Exportar términos a traducir
|
|
||||||
Pedir al usuario generar a través de UI, no sabemos el método correcto para exportar SÓLO las cadenas del addon sin incluir todo el sistema.
|
|
||||||
```
|
|
||||||
|
|
||||||
Usar sólo polib para trataer los archivos .po, msmerge corrompe los archivos.
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Formato de archivos .po**:
|
|
||||||
- Encoding: UTF-8
|
|
||||||
- Content-Type: text/plain; charset=UTF-8
|
|
||||||
- Language codes: `es`, `eu`, `ca`, `gl`, `pt`, `fr`, `it`
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
addons-cm/
|
|
||||||
├── .github/ # GitHub configs
|
|
||||||
│ └── copilot-instructions.md # Este archivo
|
|
||||||
├── ocb/ # Odoo Community Backports (18.0)
|
|
||||||
│ └── addons/ # Addons core de Odoo
|
|
||||||
├── oca_dependencies.txt # Dependencias OCA
|
|
||||||
├── requirements.txt # Dependencias Python
|
|
||||||
├── docker-compose.yml # Configuración Docker
|
|
||||||
├── Makefile # Comandos útiles
|
|
||||||
│
|
|
||||||
├── # === ADDONS OCA NO MODIFICADOS ===
|
|
||||||
├── account_invoice_triple_discount/ # Triple descuento en facturas (OCA)
|
|
||||||
├── purchase_triple_discount/ # Triple descuento en compras (OCA)
|
|
||||||
├── product_origin/ # Origen del producto (OCA)
|
|
||||||
├── product_get_price_helper/ # Helper de precios (OCA)
|
|
||||||
├── product_main_seller/ # Proveedor principal (OCA)
|
|
||||||
├── product_price_category/ # Categorías de precio (OCA)
|
|
||||||
│
|
|
||||||
├── # === ADDONS CUSTOM ===
|
|
||||||
├── account_invoice_triple_discount_readonly/ # Fix para triple descuento
|
|
||||||
├── product_price_category_supplier/ # Extensión categorías precio
|
|
||||||
├── product_sale_price_from_pricelist/ # Auto-cálculo precio venta
|
|
||||||
└── website_sale_aplicoop/ # Sistema eskaera (compras grupo)
|
|
||||||
|
|
||||||
````
|
|
||||||
|
|
||||||
## Addon References
|
|
||||||
|
|
||||||
**Para arquitectura, detalles de implementación y uso específico de cada addon, consultar su `README.md` individual.**
|
|
||||||
|
|
||||||
### Addons OCA No Modificados
|
|
||||||
|
|
||||||
- [account_invoice_triple_discount](../account_invoice_triple_discount/README.rst)
|
|
||||||
- [purchase_triple_discount](../purchase_triple_discount/README.rst)
|
|
||||||
- [product_origin](../product_origin/README.rst)
|
|
||||||
- [product_get_price_helper](../product_get_price_helper/README.rst)
|
|
||||||
- [product_main_seller](../product_main_seller/README.rst)
|
|
||||||
- [product_price_category](../product_price_category/README.rst)
|
|
||||||
|
|
||||||
### Addons Custom Propios
|
|
||||||
|
|
||||||
- [account_invoice_triple_discount_readonly](../account_invoice_triple_discount_readonly/README.md) - Fix bug descuentos
|
|
||||||
- [product_price_category_supplier](../product_price_category_supplier/README.md) - Gestión categorías por proveedor
|
|
||||||
- [product_sale_price_from_pricelist](../product_sale_price_from_pricelist/README.md) - Auto-precio basado en compra
|
|
||||||
- [website_sale_aplicoop](../website_sale_aplicoop/README.md) - Sistema eskaera completo
|
|
||||||
|
|
||||||
## Development Workflow
|
|
||||||
|
|
||||||
### Local Development
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Iniciar entorno
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Actualizar addon
|
|
||||||
docker-compose exec odoo odoo -d odoo -u addon_name --stop-after-init
|
|
||||||
|
|
||||||
# Ver logs
|
|
||||||
docker-compose logs -f odoo
|
|
||||||
|
|
||||||
# Ejecutar tests
|
|
||||||
docker-compose exec odoo odoo -d odoo --test-enable --stop-after-init -u addon_name
|
|
||||||
````
|
|
||||||
|
|
||||||
### Quality Checks
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ejecutar todos los checks
|
|
||||||
pre-commit run --all-files
|
|
||||||
|
|
||||||
# O usar Makefile
|
|
||||||
make lint # Solo linting
|
|
||||||
make format # Formatear código
|
|
||||||
make check-addon # Verificar addon específico
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
- Tests en `tests/` de cada addon
|
|
||||||
- Naming: `test_*.py`
|
|
||||||
- Herencia: `odoo.tests.common.TransactionCase`
|
|
||||||
- Ejecutar: `--test-enable` flag
|
|
||||||
|
|
||||||
## Common Patterns
|
|
||||||
|
|
||||||
### Extending Models
|
|
||||||
|
|
||||||
```python
|
|
||||||
from odoo import models, fields, api
|
|
||||||
|
|
||||||
class ResPartner(models.Model):
|
|
||||||
_inherit = 'res.partner'
|
|
||||||
|
|
||||||
custom_field = fields.Char(string="Custom Field")
|
|
||||||
|
|
||||||
@api.depends('field1', 'field2')
|
|
||||||
def _compute_custom(self):
|
|
||||||
for record in self:
|
|
||||||
record.custom_computed = record.field1 + record.field2
|
|
||||||
```
|
|
||||||
|
|
||||||
### Creating Wizards (Transient Models)
|
|
||||||
|
|
||||||
```python
|
|
||||||
class WizardModel(models.TransientModel):
|
|
||||||
_name = 'wizard.model.name'
|
|
||||||
_description = "Wizard Description"
|
|
||||||
|
|
||||||
def action_confirm(self):
|
|
||||||
# Business logic
|
|
||||||
return {'type': 'ir.actions.act_window_close'}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bulk Updates
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Prefer SQL-level updates for performance
|
|
||||||
self.env['product.template'].search([
|
|
||||||
('default_supplier_id', '=', partner_id)
|
|
||||||
]).write({'price_category_id': category_id})
|
|
||||||
```
|
|
||||||
|
|
||||||
### Notifications
|
|
||||||
|
|
||||||
```python
|
|
||||||
return {
|
|
||||||
'type': 'ir.actions.client',
|
|
||||||
'tag': 'display_notification',
|
|
||||||
'params': {
|
|
||||||
'title': _('Success'),
|
|
||||||
'message': _('Operation completed'),
|
|
||||||
'type': 'success', # or 'warning', 'danger', 'info'
|
|
||||||
'sticky': False,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Dependencies Management
|
|
||||||
|
|
||||||
### OCA Dependencies (`oca_dependencies.txt`)
|
|
||||||
|
|
||||||
```
|
|
||||||
account-invoicing
|
|
||||||
product-attribute
|
|
||||||
purchase-workflow
|
|
||||||
sale-workflow
|
|
||||||
```
|
|
||||||
|
|
||||||
### Python Dependencies (`requirements.txt`)
|
|
||||||
|
|
||||||
- Versiones específicas para evitar breaking changes
|
|
||||||
- Incluir herramientas de desarrollo (linters, etc)
|
|
||||||
|
|
||||||
## Security & Access Rights
|
|
||||||
|
|
||||||
### Grupos Comunes
|
|
||||||
|
|
||||||
- `base.group_user` - Usuario interno
|
|
||||||
- `base.group_system` - Administrador
|
|
||||||
- `sales_team.group_sale_manager` - Manager de ventas
|
|
||||||
- `sales_team.group_sale_salesman` - Vendedor
|
|
||||||
- `purchase.group_purchase_manager` - Manager de compras
|
|
||||||
|
|
||||||
### Security Files
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<!-- security/ir.model.access.csv -->
|
|
||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
|
||||||
access_model_user,model.name.user,model_model_name,base.group_user,1,1,1,0
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Issues & Solutions
|
|
||||||
|
|
||||||
### Translation Warnings
|
|
||||||
|
|
||||||
**Problem**: `WARNING: _() called at import time at module...`
|
|
||||||
**Solution**: Remove `_()` from field definitions, use only in methods
|
|
||||||
|
|
||||||
### XPath Not Found
|
|
||||||
|
|
||||||
**Problem**: `Element ... not found in parent view`
|
|
||||||
**Solution**: Check view inheritance chain, verify XML IDs are correct
|
|
||||||
|
|
||||||
### Discount Reset Issue
|
|
||||||
|
|
||||||
**Problem**: Multiple discounts being accumulated in discount1
|
|
||||||
**Solution**: Use `account_invoice_triple_discount_readonly` addon
|
|
||||||
|
|
||||||
### Price Calculation
|
|
||||||
|
|
||||||
**Problem**: Prices not updating from pricelist
|
|
||||||
**Solution**: Use `product_sale_price_from_pricelist` with proper configuration
|
|
||||||
|
|
||||||
## Testing Guidelines
|
|
||||||
|
|
||||||
### Unit Tests
|
|
||||||
|
|
||||||
- Test business logic in isolation
|
|
||||||
- Mock external dependencies
|
|
||||||
- Use `TransactionCase` for DB tests
|
|
||||||
|
|
||||||
### Integration Tests
|
|
||||||
|
|
||||||
- Test workflow end-to-end
|
|
||||||
- Verify computed fields
|
|
||||||
- Check access rights
|
|
||||||
|
|
||||||
### UI Tests (Tours)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
odoo.define("module.tour", function (require) {
|
|
||||||
"use strict";
|
|
||||||
var tour = require("web_tour.tour");
|
|
||||||
tour.register(
|
|
||||||
"tour_name",
|
|
||||||
{
|
|
||||||
test: true,
|
|
||||||
url: "/web",
|
|
||||||
},
|
|
||||||
[
|
|
||||||
// Tour steps
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Debugging Tips
|
|
||||||
|
|
||||||
### Enable Developer Mode
|
|
||||||
|
|
||||||
```
|
|
||||||
Settings > Activate Developer Mode
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check Logs
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose logs -f odoo | grep ERROR
|
|
||||||
docker-compose logs -f odoo | grep addon_name
|
|
||||||
```
|
|
||||||
|
|
||||||
### Python Debugger
|
|
||||||
|
|
||||||
```python
|
|
||||||
import pdb; pdb.set_trace() # Set breakpoint
|
|
||||||
```
|
|
||||||
|
|
||||||
### Performance Profiling
|
|
||||||
|
|
||||||
```bash
|
|
||||||
--log-level=debug_sql # Show SQL queries
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation Standards
|
|
||||||
|
|
||||||
### README.md Structure
|
|
||||||
|
|
||||||
Cada addon debe tener un README.md con:
|
|
||||||
|
|
||||||
1. **Title & Summary**: Qué hace el addon
|
|
||||||
2. **Features**: Lista de funcionalidades
|
|
||||||
3. **Dependencies**: Addons requeridos
|
|
||||||
4. **Installation**: Comandos de instalación
|
|
||||||
5. **Configuration**: Settings necesarios
|
|
||||||
6. **Usage**: Flujo de trabajo típico
|
|
||||||
7. **Technical Details**: Modelos, campos, métodos
|
|
||||||
8. **Translations**: Estado de traducciones (si aplica)
|
|
||||||
|
|
||||||
### Code Comments
|
|
||||||
|
|
||||||
- Docstrings en clases y métodos públicos
|
|
||||||
- Comentarios inline para lógica compleja
|
|
||||||
- TODOs con contexto completo
|
|
||||||
|
|
||||||
## Version Control
|
|
||||||
|
|
||||||
### Commit Messages
|
|
||||||
|
|
||||||
```
|
|
||||||
[TAG] module: Brief description
|
|
||||||
|
|
||||||
Longer explanation if needed
|
|
||||||
```
|
|
||||||
|
|
||||||
Tags: `[ADD]`, `[FIX]`, `[IMP]`, `[REF]`, `[REM]`, `[I18N]`, `[DOC]`
|
|
||||||
|
|
||||||
### Branch Strategy
|
|
||||||
|
|
||||||
- `main` - Production ready
|
|
||||||
- `dev` - Development
|
|
||||||
- `feature/*` - New features
|
|
||||||
- `fix/*` - Bug fixes
|
|
||||||
|
|
||||||
## Performance Considerations
|
|
||||||
|
|
||||||
- Use `@api.depends` correctamente para computed fields
|
|
||||||
- Prefer `search()` + `write()` sobre loops con `write()`
|
|
||||||
- Use `create()` con lista de vals para bulk creates
|
|
||||||
- Indexes en campos frecuentemente buscados
|
|
||||||
- Avoid N+1 queries con `prefetch`
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
- **OCA Guidelines**: https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst
|
|
||||||
- **Odoo Documentation**: https://www.odoo.com/documentation/18.0/
|
|
||||||
- **OCB Repository**: https://github.com/OCA/OCB
|
|
||||||
- **OCA Repositories**: https://github.com/OCA/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Last Updated**: 2026-02-12
|
|
||||||
**Odoo Version**: 18.0
|
|
||||||
**Python Version**: 3.10+
|
|
||||||
|
|
@ -125,7 +125,7 @@ repos:
|
||||||
- "types-requests"
|
- "types-requests"
|
||||||
- "types-setuptools"
|
- "types-setuptools"
|
||||||
- repo: https://github.com/PyCQA/pylint
|
- repo: https://github.com/PyCQA/pylint
|
||||||
rev: v4.0.4
|
rev: v3.1.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: pylint
|
- id: pylint
|
||||||
name: pylint with optional checks
|
name: pylint with optional checks
|
||||||
|
|
@ -134,7 +134,7 @@ repos:
|
||||||
- --exit-zero
|
- --exit-zero
|
||||||
verbose: true
|
verbose: true
|
||||||
additional_dependencies: &pylint_deps
|
additional_dependencies: &pylint_deps
|
||||||
- pylint-odoo==10.0.0
|
- pylint-odoo==9.1.2
|
||||||
- id: pylint
|
- id: pylint
|
||||||
name: pylint with mandatory checks
|
name: pylint with mandatory checks
|
||||||
args:
|
args:
|
||||||
|
|
|
||||||
89
.pylintrc
89
.pylintrc
|
|
@ -2,6 +2,14 @@
|
||||||
load-plugins=pylint_odoo
|
load-plugins=pylint_odoo
|
||||||
score=n
|
score=n
|
||||||
|
|
||||||
|
[ODOOLINT]
|
||||||
|
readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
|
||||||
|
manifest_required_authors=Odoo Community Association (OCA)
|
||||||
|
manifest_required_keys=license
|
||||||
|
manifest_deprecated_keys=description,active
|
||||||
|
license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3,Other OSI approved licence,Other proprietary
|
||||||
|
valid_odoo_versions=16.0,17.0,18.0
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
disable=all
|
disable=all
|
||||||
|
|
||||||
|
|
@ -14,76 +22,67 @@ disable=all
|
||||||
# checks.
|
# checks.
|
||||||
|
|
||||||
enable=anomalous-backslash-in-string,
|
enable=anomalous-backslash-in-string,
|
||||||
|
api-one-deprecated,
|
||||||
|
api-one-multi-together,
|
||||||
assignment-from-none,
|
assignment-from-none,
|
||||||
attribute-deprecated,
|
attribute-deprecated,
|
||||||
attribute-string-redundant,
|
class-camelcase,
|
||||||
bad-builtin-groupby,
|
|
||||||
category-allowed,
|
|
||||||
category-allowed-app,
|
|
||||||
consider-merging-classes-inherited,
|
|
||||||
context-overridden,
|
context-overridden,
|
||||||
|
copy-wo-api-one,
|
||||||
dangerous-default-value,
|
dangerous-default-value,
|
||||||
deprecated-name-get,
|
dangerous-view-replace-wo-priority,
|
||||||
deprecated-odoo-model-method,
|
|
||||||
development-status-allowed,
|
development-status-allowed,
|
||||||
|
duplicate-id-csv,
|
||||||
duplicate-key,
|
duplicate-key,
|
||||||
except-pass,
|
duplicate-xml-fields,
|
||||||
external-request-timeout,
|
duplicate-xml-record-id,
|
||||||
inheritable-method-lambda,
|
eval-referenced,
|
||||||
inheritable-method-string,
|
eval-used,
|
||||||
invalid-commit,
|
incoherent-interpreter-exec-perm,
|
||||||
invalid-email,
|
|
||||||
license-allowed,
|
license-allowed,
|
||||||
manifest-author-string,
|
manifest-author-string,
|
||||||
manifest-behind-migrations,
|
|
||||||
manifest-data-duplicated,
|
|
||||||
manifest-deprecated-key,
|
manifest-deprecated-key,
|
||||||
manifest-external-assets,
|
|
||||||
manifest-maintainers-list,
|
|
||||||
manifest-required-author,
|
manifest-required-author,
|
||||||
manifest-required-key,
|
manifest-required-key,
|
||||||
manifest-required-key-app,
|
|
||||||
manifest-superfluous-key,
|
|
||||||
manifest-version-format,
|
manifest-version-format,
|
||||||
method-compute,
|
method-compute,
|
||||||
method-inverse,
|
method-inverse,
|
||||||
method-required-super,
|
method-required-super,
|
||||||
method-search,
|
method-search,
|
||||||
missing-odoo-file,
|
missing-import-error,
|
||||||
missing-odoo-file-app,
|
missing-manifest-dependency,
|
||||||
missing-readme,
|
openerp-exception-warning,
|
||||||
missing-return,
|
|
||||||
no-raise-unlink,
|
|
||||||
no-search-all,
|
|
||||||
no-wizard-in-models,
|
|
||||||
no-write-in-compute,
|
|
||||||
odoo-addons-relative-import,
|
|
||||||
odoo-exception-warning,
|
|
||||||
pointless-statement,
|
pointless-statement,
|
||||||
pointless-string-statement,
|
pointless-string-statement,
|
||||||
prefer-env-translation,
|
|
||||||
print-used,
|
print-used,
|
||||||
prohibited-method-override,
|
|
||||||
redundant-keyword-arg,
|
redundant-keyword-arg,
|
||||||
renamed-field-parameter,
|
redundant-modulename-xml,
|
||||||
resource-not-exist,
|
reimported,
|
||||||
|
relative-import,
|
||||||
|
return-in-init,
|
||||||
|
rst-syntax-error,
|
||||||
sql-injection,
|
sql-injection,
|
||||||
super-method-mismatch,
|
|
||||||
test-folder-imported,
|
|
||||||
too-few-format-args,
|
too-few-format-args,
|
||||||
translation-contains-variable,
|
|
||||||
translation-field,
|
translation-field,
|
||||||
translation-format-interpolation,
|
|
||||||
translation-format-truncated,
|
|
||||||
translation-fstring-interpolation,
|
|
||||||
translation-not-lazy,
|
|
||||||
translation-positional-used,
|
|
||||||
translation-required,
|
translation-required,
|
||||||
translation-too-few-args,
|
unreachable,
|
||||||
translation-too-many-args,
|
|
||||||
translation-unsupported-format,
|
|
||||||
use-vim-comment,
|
use-vim-comment,
|
||||||
website-manifest-key-not-valid-uri
|
wrong-tabs-instead-of-spaces,
|
||||||
|
xml-syntax-error
|
||||||
|
# messages that do not cause the lint step to fail
|
||||||
|
consider-merging-classes-inherited,
|
||||||
|
create-user-wo-reset-password,
|
||||||
|
deprecated-module,
|
||||||
|
file-not-used,
|
||||||
|
invalid-commit,
|
||||||
|
missing-newline-extrafiles,
|
||||||
|
missing-readme,
|
||||||
|
no-utf8-coding-comment,
|
||||||
|
odoo-addons-relative-import,
|
||||||
|
old-api7-method-defined,
|
||||||
|
redefined-builtin,
|
||||||
|
too-complex,
|
||||||
|
unnecessary-utf8-coding-comment
|
||||||
|
|
||||||
[REPORTS]
|
[REPORTS]
|
||||||
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
|
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
|
||||||
|
|
|
||||||
|
|
@ -2,58 +2,65 @@
|
||||||
load-plugins=pylint_odoo
|
load-plugins=pylint_odoo
|
||||||
score=n
|
score=n
|
||||||
|
|
||||||
|
[ODOOLINT]
|
||||||
|
readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
|
||||||
|
manifest_required_authors=Odoo Community Association (OCA)
|
||||||
|
manifest_required_keys=license
|
||||||
|
manifest_deprecated_keys=description,active
|
||||||
|
license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3,Other OSI approved licence,Other proprietary
|
||||||
|
valid_odoo_versions=16.0,17.0,18.0
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
disable=all
|
disable=all
|
||||||
|
|
||||||
enable=anomalous-backslash-in-string,
|
enable=anomalous-backslash-in-string,
|
||||||
|
api-one-deprecated,
|
||||||
|
api-one-multi-together,
|
||||||
assignment-from-none,
|
assignment-from-none,
|
||||||
attribute-deprecated,
|
attribute-deprecated,
|
||||||
consider-merging-classes-inherited,
|
class-camelcase,
|
||||||
context-overridden,
|
context-overridden,
|
||||||
|
copy-wo-api-one,
|
||||||
dangerous-default-value,
|
dangerous-default-value,
|
||||||
deprecated-name-get,
|
dangerous-view-replace-wo-priority,
|
||||||
deprecated-odoo-model-method,
|
|
||||||
development-status-allowed,
|
development-status-allowed,
|
||||||
|
duplicate-id-csv,
|
||||||
duplicate-key,
|
duplicate-key,
|
||||||
except-pass,
|
duplicate-xml-fields,
|
||||||
external-request-timeout,
|
duplicate-xml-record-id,
|
||||||
inheritable-method-lambda,
|
eval-referenced,
|
||||||
inheritable-method-string,
|
eval-used,
|
||||||
invalid-commit,
|
incoherent-interpreter-exec-perm,
|
||||||
license-allowed,
|
license-allowed,
|
||||||
manifest-author-string,
|
manifest-author-string,
|
||||||
manifest-behind-migrations,
|
|
||||||
manifest-data-duplicated,
|
|
||||||
manifest-deprecated-key,
|
manifest-deprecated-key,
|
||||||
manifest-maintainers-list,
|
|
||||||
manifest-required-author,
|
manifest-required-author,
|
||||||
manifest-required-key,
|
manifest-required-key,
|
||||||
manifest-superfluous-key,
|
|
||||||
manifest-version-format,
|
manifest-version-format,
|
||||||
method-compute,
|
method-compute,
|
||||||
method-inverse,
|
method-inverse,
|
||||||
method-required-super,
|
method-required-super,
|
||||||
method-search,
|
method-search,
|
||||||
missing-readme,
|
missing-import-error,
|
||||||
missing-return,
|
missing-manifest-dependency,
|
||||||
no-raise-unlink,
|
openerp-exception-warning,
|
||||||
no-write-in-compute,
|
|
||||||
odoo-addons-relative-import,
|
|
||||||
odoo-exception-warning,
|
|
||||||
pointless-statement,
|
pointless-statement,
|
||||||
pointless-string-statement,
|
pointless-string-statement,
|
||||||
print-used,
|
print-used,
|
||||||
prohibited-method-override,
|
|
||||||
redundant-keyword-arg,
|
redundant-keyword-arg,
|
||||||
renamed-field-parameter,
|
redundant-modulename-xml,
|
||||||
resource-not-exist,
|
reimported,
|
||||||
|
relative-import,
|
||||||
|
return-in-init,
|
||||||
|
rst-syntax-error,
|
||||||
sql-injection,
|
sql-injection,
|
||||||
test-folder-imported,
|
|
||||||
too-few-format-args,
|
too-few-format-args,
|
||||||
translation-field,
|
translation-field,
|
||||||
translation-positional-used,
|
|
||||||
translation-required,
|
translation-required,
|
||||||
use-vim-comment
|
unreachable,
|
||||||
|
use-vim-comment,
|
||||||
|
wrong-tabs-instead-of-spaces,
|
||||||
|
xml-syntax-error
|
||||||
|
|
||||||
[REPORTS]
|
[REPORTS]
|
||||||
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
|
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
|
||||||
|
|
|
||||||
249
README.md
249
README.md
|
|
@ -1,249 +0,0 @@
|
||||||
# Kidekoop - Addons Custom para Odoo 18.0
|
|
||||||
|
|
||||||
Sistema de gestión de compras colaborativas (grupo de consumo) basado en Odoo 18.0 con módulos personalizados y modificados.
|
|
||||||
|
|
||||||
## 🎯 Descripción
|
|
||||||
|
|
||||||
Este repositorio contiene los addons personalizados para Kidekoop, un sistema completo de gestión de grupos de consumo que permite:
|
|
||||||
|
|
||||||
- **Gestión de compras colaborativas** (eskaera)
|
|
||||||
- **Sistema de precios multinivel** con categorías y descuentos múltiples
|
|
||||||
- **Integración con proveedores** y gestión de precios automática
|
|
||||||
- **Interfaz web moderna** para pedidos grupales
|
|
||||||
- **Multiidioma** (ES, EU, CA, GL, PT, FR, IT)
|
|
||||||
|
|
||||||
## 📦 Componentes del Proyecto
|
|
||||||
|
|
||||||
### 1. OCB - Odoo Community Backports
|
|
||||||
- **Ubicación**: `/ocb`
|
|
||||||
- **Versión**: 18.0
|
|
||||||
- **Descripción**: Base de Odoo Community Edition
|
|
||||||
- **Repositorio**: https://github.com/OCA/OCB
|
|
||||||
|
|
||||||
### 2. Addons OCA Modificados
|
|
||||||
|
|
||||||
| Addon | Propósito | Repositorio OCA |
|
|
||||||
|-------|-----------|-----------------|
|
|
||||||
| [account_invoice_triple_discount](account_invoice_triple_discount/) | Sistema de triple descuento en facturas | account-invoicing |
|
|
||||||
| [purchase_triple_discount](purchase_triple_discount/) | Sistema de triple descuento en compras | purchase-workflow |
|
|
||||||
| [product_origin](product_origin/) | Campo de origen del producto | product-attribute |
|
|
||||||
| [product_get_price_helper](product_get_price_helper/) | Helper para cálculo de precios | product-attribute |
|
|
||||||
| [product_main_seller](product_main_seller/) | Proveedor principal por producto | purchase-workflow |
|
|
||||||
| [product_price_category](product_price_category/) | Sistema de categorías de precio | product-attribute |
|
|
||||||
|
|
||||||
### 3. Addons Custom Propios
|
|
||||||
|
|
||||||
| Addon | Propósito | Estado |
|
|
||||||
|-------|-----------|--------|
|
|
||||||
| [account_invoice_triple_discount_readonly](account_invoice_triple_discount_readonly/) | Fix para bug de descuentos acumulados | ✅ Estable |
|
|
||||||
| [product_price_category_supplier](product_price_category_supplier/) | Gestión de categorías por proveedor | ✅ Estable |
|
|
||||||
| [product_sale_price_from_pricelist](product_sale_price_from_pricelist/) | Auto-cálculo precio venta desde compra | ✅ Estable |
|
|
||||||
| [website_sale_aplicoop](website_sale_aplicoop/) | Sistema completo de eskaera web | ✅ Estable |
|
|
||||||
|
|
||||||
## 🚀 Quick Start
|
|
||||||
|
|
||||||
### Requisitos
|
|
||||||
|
|
||||||
- Docker & Docker Compose
|
|
||||||
- Python 3.10+
|
|
||||||
- PostgreSQL 14+
|
|
||||||
|
|
||||||
### Instalación
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clonar repositorio
|
|
||||||
git clone [URL_REPO]
|
|
||||||
cd addons-cm
|
|
||||||
|
|
||||||
# Iniciar entorno
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Verificar logs
|
|
||||||
docker-compose logs -f odoo
|
|
||||||
```
|
|
||||||
|
|
||||||
### Instalar un addon
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose exec odoo odoo -d odoo -u addon_name --stop-after-init
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ Desarrollo
|
|
||||||
|
|
||||||
### Estructura de Carpetas
|
|
||||||
|
|
||||||
```
|
|
||||||
addons-cm/
|
|
||||||
├── .github/ # GitHub Copilot instructions
|
|
||||||
├── ocb/ # Odoo 18.0 base
|
|
||||||
├── account_invoice_*/ # Addons de facturación
|
|
||||||
├── purchase_*/ # Addons de compras
|
|
||||||
├── product_*/ # Addons de productos
|
|
||||||
├── website_sale_aplicoop/ # Sistema eskaera
|
|
||||||
├── docker-compose.yml # Configuración Docker
|
|
||||||
├── requirements.txt # Dependencias Python
|
|
||||||
├── oca_dependencies.txt # Dependencias OCA
|
|
||||||
├── Makefile # Comandos útiles
|
|
||||||
└── .pre-commit-config.yaml # Hooks de pre-commit
|
|
||||||
```
|
|
||||||
|
|
||||||
### Herramientas de Calidad
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ejecutar checks de código
|
|
||||||
make lint
|
|
||||||
|
|
||||||
# Formatear código
|
|
||||||
make format
|
|
||||||
|
|
||||||
# Ejecutar todos los pre-commit hooks
|
|
||||||
pre-commit run --all-files
|
|
||||||
|
|
||||||
# Verificar addon específico
|
|
||||||
./check_addon.sh addon_name
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ejecutar tests de un addon
|
|
||||||
docker-compose exec odoo odoo -d odoo --test-enable --stop-after-init -u addon_name
|
|
||||||
|
|
||||||
# Tests específicos con Python unittest
|
|
||||||
docker-compose exec odoo python -m pytest addons/addon_name/tests/
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🌍 Sistema de Traducciones
|
|
||||||
|
|
||||||
Todos los addons custom incluyen traducciones completas en:
|
|
||||||
|
|
||||||
- **Español** (es) - Obligatorio
|
|
||||||
- **Euskera** (eu) - Obligatorio
|
|
||||||
- **Catalán** (ca)
|
|
||||||
- **Gallego** (gl)
|
|
||||||
- **Portugués** (pt)
|
|
||||||
- **Francés** (fr)
|
|
||||||
- **Italiano** (it)
|
|
||||||
|
|
||||||
### Actualizar Traducciones
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Exportar términos traducibles
|
|
||||||
docker-compose exec odoo odoo \
|
|
||||||
--addons-path=/mnt/extra-addons \
|
|
||||||
--i18n-export=/tmp/addon_name.pot \
|
|
||||||
--modules=addon_name \
|
|
||||||
--db=odoo
|
|
||||||
|
|
||||||
# Actualizar archivos .po
|
|
||||||
cd addon_name/i18n
|
|
||||||
msgmerge --update es.po addon_name.pot
|
|
||||||
msgmerge --update eu.po addon_name.pot
|
|
||||||
```
|
|
||||||
|
|
||||||
**Importante**: No usar `_()` en definiciones de campos a nivel de módulo. Solo usar en métodos.
|
|
||||||
|
|
||||||
📖 **[Ver guía completa de traducciones](docs/TRANSLATIONS.md)**
|
|
||||||
|
|
||||||
## 📖 Documentación Adicional
|
|
||||||
|
|
||||||
Cada addon incluye su propio README.md con:
|
|
||||||
- Arquitectura y diseño
|
|
||||||
- Detalles de implementación
|
|
||||||
- Ejemplos de uso
|
|
||||||
- Casos de prueba
|
|
||||||
|
|
||||||
### Documentos Principales
|
|
||||||
|
|
||||||
- [GitHub Copilot Instructions](.github/copilot-instructions.md) - Guía para desarrollo con AI
|
|
||||||
- [Documentación Técnica](docs/) - Guías de instalación, linters, y troubleshooting
|
|
||||||
- [Makefile](Makefile) - Comandos disponibles
|
|
||||||
- [requirements.txt](requirements.txt) - Dependencias Python
|
|
||||||
- [oca_dependencies.txt](oca_dependencies.txt) - Repositorios OCA necesarios
|
|
||||||
|
|
||||||
## 🔧 Configuración
|
|
||||||
|
|
||||||
### Dependencias OCA
|
|
||||||
|
|
||||||
Este proyecto depende de los siguientes repositorios OCA:
|
|
||||||
|
|
||||||
- **account-invoicing**: Sistema de facturación extendido
|
|
||||||
- **product-attribute**: Gestión avanzada de productos
|
|
||||||
- **purchase-workflow**: Flujos de compra personalizados
|
|
||||||
- **sale-workflow**: Flujos de venta personalizados
|
|
||||||
|
|
||||||
### Configuración de Odoo
|
|
||||||
|
|
||||||
Archivo `odoo.conf` incluye:
|
|
||||||
- Configuración de addons path
|
|
||||||
- Parámetros de base de datos
|
|
||||||
- Configuración de workers y límites
|
|
||||||
|
|
||||||
## 🐛 Issues Conocidos y Soluciones
|
|
||||||
|
|
||||||
### Descuentos Acumulándose en discount1
|
|
||||||
|
|
||||||
**Problema**: Al usar triple descuento, todos los descuentos se acumulan en el primer campo.
|
|
||||||
|
|
||||||
**Solución**: Instalar `account_invoice_triple_discount_readonly`
|
|
||||||
|
|
||||||
### Precio de Venta No Actualiza
|
|
||||||
|
|
||||||
**Problema**: El precio de venta no se calcula automáticamente desde el precio de compra.
|
|
||||||
|
|
||||||
**Solución**: Configurar `product_sale_price_from_pricelist` correctamente.
|
|
||||||
|
|
||||||
### Warnings de Traducción
|
|
||||||
|
|
||||||
**Problema**: `WARNING: _() called at import time at module...`
|
|
||||||
|
|
||||||
**Solución**: No usar `_()` en definiciones de campos, solo en métodos ejecutables.
|
|
||||||
|
|
||||||
## 🤝 Contribuir
|
|
||||||
|
|
||||||
### Estándares de Código
|
|
||||||
|
|
||||||
- Seguir [OCA Guidelines](https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst)
|
|
||||||
- Usar **black** para formateo
|
|
||||||
- Usar **isort** para imports
|
|
||||||
- Pasar **flake8** y **pylint-odoo**
|
|
||||||
- Todos los commits deben pasar pre-commit hooks
|
|
||||||
|
|
||||||
### Estructura de Commits
|
|
||||||
|
|
||||||
```
|
|
||||||
[TAG] module_name: Brief description
|
|
||||||
|
|
||||||
Detailed explanation if needed
|
|
||||||
|
|
||||||
Tags: [ADD], [FIX], [IMP], [REF], [REM], [I18N], [DOC]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
Todos los nuevos features deben incluir:
|
|
||||||
- Tests unitarios
|
|
||||||
- Tests de integración (si aplica)
|
|
||||||
- Documentación actualizada
|
|
||||||
|
|
||||||
## 📝 License
|
|
||||||
|
|
||||||
AGPL-3.0 or later
|
|
||||||
|
|
||||||
## 👥 Autores
|
|
||||||
|
|
||||||
- **Criptomart** - Development
|
|
||||||
- **OCA Community** - Base addons
|
|
||||||
|
|
||||||
## 🔗 Enlaces
|
|
||||||
|
|
||||||
- **Odoo Documentation**: https://www.odoo.com/documentation/18.0/
|
|
||||||
- **OCA**: https://github.com/OCA
|
|
||||||
- **OCB**: https://github.com/OCA/OCB
|
|
||||||
- **OCA Guidelines**: https://github.com/OCA/odoo-community.org
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Versión Odoo**: 18.0
|
|
||||||
**Python**: 3.10+
|
|
||||||
**Última Actualización**: 2026-02-12
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
# Copyright 2025 - Today Criptomart
|
# Copyright 2025
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
{ # noqa: B018
|
{
|
||||||
"name": "Account Invoice Triple Discount Readonly",
|
"name": "Account Invoice Triple Discount Readonly",
|
||||||
"version": "18.0.1.0.0",
|
"version": "18.0.1.0.0",
|
||||||
"summary": "Make total discount readonly and fix discount2/discount3 write issue",
|
"summary": "Make total discount readonly and fix discount2/discount3 write issue",
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
"author": "Odoo Community Association (OCA), Criptomart",
|
"author": "Criptomart",
|
||||||
"website": "https://git.criptomart.net/criptomart/addons-cm",
|
"website": "https://github.com/OCA/account-invoicing",
|
||||||
"depends": ["account_invoice_triple_discount", "purchase_triple_discount"],
|
"depends": ["account_invoice_triple_discount", "purchase_triple_discount"],
|
||||||
|
"data": [],
|
||||||
|
"installable": True,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
from odoo import fields
|
from odoo import fields, models
|
||||||
from odoo import models
|
|
||||||
|
|
||||||
|
|
||||||
class TripleDiscountMixin(models.AbstractModel):
|
class TripleDiscountMixin(models.AbstractModel):
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
# Documentación Técnica
|
|
||||||
|
|
||||||
Esta carpeta contiene documentación técnica y de referencia del proyecto.
|
|
||||||
|
|
||||||
## Contenido
|
|
||||||
|
|
||||||
### Configuración y Desarrollo
|
|
||||||
|
|
||||||
- **[LINTERS_README.md](LINTERS_README.md)** - Guía de herramientas de calidad de código (black, isort, flake8, pylint)
|
|
||||||
- **[TRANSLATIONS.md](TRANSLATIONS.md)** - Guía completa del sistema de traducciones (IMPORTANTE)
|
|
||||||
- **[INSTALACION_COMPLETA.md](INSTALACION_COMPLETA.md)** - Documentación detallada del proceso de instalación
|
|
||||||
- **[RESUMEN_INSTALACION.md](RESUMEN_INSTALACION.md)** - Resumen ejecutivo de la instalación
|
|
||||||
|
|
||||||
### Resolución de Problemas
|
|
||||||
|
|
||||||
- **[CORRECCION_PRECIOS_IVA.md](CORRECCION_PRECIOS_IVA.md)** - Correcciones relacionadas con precios e IVA
|
|
||||||
- **[TEST_MANUAL.md](TEST_MANUAL.md)** - Guía de tests manuales
|
|
||||||
|
|
||||||
## Documentación Principal
|
|
||||||
|
|
||||||
Para información general del proyecto y cómo empezar, ver:
|
|
||||||
|
|
||||||
- **[README.md](../README.md)** - Documentación principal del repositorio
|
|
||||||
- **[.github/copilot-instructions.md](../.github/copilot-instructions.md)** - Instrucciones para GitHub Copilot
|
|
||||||
|
|
||||||
## Documentación por Addon
|
|
||||||
|
|
||||||
Cada addon tiene su propio README:
|
|
||||||
|
|
||||||
### Addons Custom
|
|
||||||
- [account_invoice_triple_discount_readonly](../account_invoice_triple_discount_readonly/README.md)
|
|
||||||
- [product_price_category_supplier](../product_price_category_supplier/README.md)
|
|
||||||
- [product_sale_price_from_pricelist](../product_sale_price_from_pricelist/README.md)
|
|
||||||
- [website_sale_aplicoop](../website_sale_aplicoop/README.md)
|
|
||||||
|
|
||||||
### Addons OCA Modificados
|
|
||||||
- [account_invoice_triple_discount](../account_invoice_triple_discount/README.rst)
|
|
||||||
- [purchase_triple_discount](../purchase_triple_discount/README.rst)
|
|
||||||
- [product_origin](../product_origin/README.md)
|
|
||||||
- [product_get_price_helper](../product_get_price_helper/README.md)
|
|
||||||
- [product_main_seller](../product_main_seller/README.md)
|
|
||||||
- [product_price_category](../product_price_category/README.rst)
|
|
||||||
|
|
@ -1,314 +0,0 @@
|
||||||
# Sistema de Traducciones - Guía Completa
|
|
||||||
|
|
||||||
## Estado Actual
|
|
||||||
|
|
||||||
✅ **El sistema de traducciones está funcionando correctamente**
|
|
||||||
|
|
||||||
Todos los addons custom incluyen traducciones para:
|
|
||||||
- **Español (es)** - Obligatorio
|
|
||||||
- **Euskera (eu)** - Obligatorio
|
|
||||||
- Catalán (ca), Gallego (gl), Portugués (pt), Francés (fr), Italiano (it) - Opcional
|
|
||||||
|
|
||||||
## Estructura de Archivos
|
|
||||||
|
|
||||||
Cada addon debe tener la siguiente estructura:
|
|
||||||
|
|
||||||
```
|
|
||||||
addon_name/
|
|
||||||
├── i18n/
|
|
||||||
│ ├── es.po # Español (obligatorio)
|
|
||||||
│ ├── eu.po # Euskera (obligatorio)
|
|
||||||
│ ├── ca.po # Catalán (opcional)
|
|
||||||
│ ├── gl.po # Gallego (opcional)
|
|
||||||
│ ├── pt.po # Portugués (opcional)
|
|
||||||
│ ├── fr.po # Francés (opcional)
|
|
||||||
│ ├── it.po # Italiano (opcional)
|
|
||||||
│ └── addon_name.pot # Template (generado automáticamente)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Reglas Importantes
|
|
||||||
|
|
||||||
### ❌ NO Hacer
|
|
||||||
|
|
||||||
**NUNCA usar `_()` en definiciones de campos a nivel de módulo:**
|
|
||||||
|
|
||||||
```python
|
|
||||||
# ❌ INCORRECTO - Causa warnings
|
|
||||||
from odoo import _
|
|
||||||
|
|
||||||
class MyModel(models.Model):
|
|
||||||
_name = 'my.model'
|
|
||||||
|
|
||||||
name = fields.Char(string=_("Name")) # ❌ MAL
|
|
||||||
description = fields.Text(string=_("Description")) # ❌ MAL
|
|
||||||
```
|
|
||||||
|
|
||||||
**Por qué está mal**: `_()` se ejecuta en tiempo de importación del módulo, antes de que el sistema de traducciones esté inicializado, causando warnings.
|
|
||||||
|
|
||||||
### ✅ Hacer
|
|
||||||
|
|
||||||
**Usar strings literales en definiciones de campos:**
|
|
||||||
|
|
||||||
```python
|
|
||||||
# ✅ CORRECTO
|
|
||||||
from odoo import models, fields
|
|
||||||
|
|
||||||
class MyModel(models.Model):
|
|
||||||
_name = 'my.model'
|
|
||||||
|
|
||||||
name = fields.Char(string="Name") # ✅ BIEN
|
|
||||||
description = fields.Text(string="Description") # ✅ BIEN
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usar `_()` solo en métodos y código ejecutable:**
|
|
||||||
|
|
||||||
```python
|
|
||||||
# ✅ CORRECTO
|
|
||||||
from odoo import _, models
|
|
||||||
|
|
||||||
class MyModel(models.Model):
|
|
||||||
_name = 'my.model'
|
|
||||||
|
|
||||||
def action_confirm(self):
|
|
||||||
message = _("Order confirmed successfully") # ✅ BIEN
|
|
||||||
return {
|
|
||||||
'type': 'ir.actions.client',
|
|
||||||
'tag': 'display_notification',
|
|
||||||
'params': {
|
|
||||||
'title': _('Success'), # ✅ BIEN
|
|
||||||
'message': message,
|
|
||||||
'type': 'success',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def _compute_display_name(self):
|
|
||||||
for record in self:
|
|
||||||
record.display_name = _("Order %s") % record.name # ✅ BIEN
|
|
||||||
```
|
|
||||||
|
|
||||||
## Cómo Generar/Actualizar Traducciones
|
|
||||||
|
|
||||||
### 1. Exportar Términos Traducibles
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Exportar términos del addon
|
|
||||||
docker-compose exec odoo odoo \
|
|
||||||
--addons-path=/mnt/extra-addons \
|
|
||||||
--i18n-export=/tmp/addon_name.pot \
|
|
||||||
--modules=addon_name \
|
|
||||||
--db=odoo \
|
|
||||||
--stop-after-init
|
|
||||||
|
|
||||||
# Copiar el archivo generado
|
|
||||||
docker-compose cp odoo:/tmp/addon_name.pot ./addon_name/i18n/
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Actualizar Archivos .po Existentes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd addon_name/i18n
|
|
||||||
|
|
||||||
# Actualizar español
|
|
||||||
msgmerge --update es.po addon_name.pot
|
|
||||||
|
|
||||||
# Actualizar euskera
|
|
||||||
msgmerge --update eu.po addon_name.pot
|
|
||||||
|
|
||||||
# Actualizar otros idiomas (si existen)
|
|
||||||
msgmerge --update ca.po addon_name.pot
|
|
||||||
msgmerge --update gl.po addon_name.pot
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Traducir Términos Nuevos
|
|
||||||
|
|
||||||
Editar los archivos `.po` y completar las traducciones:
|
|
||||||
|
|
||||||
```po
|
|
||||||
#: models/my_model.py:25
|
|
||||||
msgid "Order confirmed successfully"
|
|
||||||
msgstr "Pedido confirmado correctamente" # Español
|
|
||||||
|
|
||||||
#: models/my_model.py:30
|
|
||||||
msgid "Success"
|
|
||||||
msgstr "Éxito"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Cargar Traducciones en Odoo
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Actualizar addon con nuevas traducciones
|
|
||||||
docker-compose exec odoo odoo -d odoo -u addon_name --stop-after-init
|
|
||||||
|
|
||||||
# O reiniciar Odoo para que cargue los cambios
|
|
||||||
docker-compose restart odoo
|
|
||||||
```
|
|
||||||
|
|
||||||
## Formato de Archivos .po
|
|
||||||
|
|
||||||
### Cabecera Requerida
|
|
||||||
|
|
||||||
```po
|
|
||||||
# Translation of Odoo Server.
|
|
||||||
# This file contains the translation of the following modules:
|
|
||||||
# * addon_name
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: Odoo Server 18.0\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2026-02-12 10:00+0000\n"
|
|
||||||
"PO-Revision-Date: 2026-02-12 10:00+0000\n"
|
|
||||||
"Last-Translator: Your Name <your.email@example.com>\n"
|
|
||||||
"Language-Team: \n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Language: es\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Campos Traducibles
|
|
||||||
|
|
||||||
Odoo automáticamente detecta y exporta:
|
|
||||||
|
|
||||||
1. **String en definiciones de campos**: `fields.Char(string="Name")`
|
|
||||||
2. **Help text**: `fields.Char(help="Enter the product name")`
|
|
||||||
3. **Selection options**: `fields.Selection([('draft', 'Draft'), ('done', 'Done')])`
|
|
||||||
4. **Texto en vistas XML**: `<label string="Customer Name"/>`
|
|
||||||
5. **Botones en vistas**: `<button string="Confirm"/>`
|
|
||||||
6. **Mensajes en código**: `_("Message text")`
|
|
||||||
7. **Excepciones**: `raise ValidationError(_("Invalid value"))`
|
|
||||||
|
|
||||||
## Verificación
|
|
||||||
|
|
||||||
### Comprobar que las Traducciones Funcionan
|
|
||||||
|
|
||||||
1. **Activar el idioma en Odoo**:
|
|
||||||
- Settings > Translations > Load a Translation
|
|
||||||
- Seleccionar el idioma (ej: Español)
|
|
||||||
|
|
||||||
2. **Cambiar idioma de usuario**:
|
|
||||||
- Settings > Users > [Usuario]
|
|
||||||
- Language: Español
|
|
||||||
|
|
||||||
3. **Verificar en la interfaz**:
|
|
||||||
- Abrir el módulo
|
|
||||||
- Verificar que los textos aparecen traducidos
|
|
||||||
|
|
||||||
### Logs de Carga
|
|
||||||
|
|
||||||
Al actualizar el módulo, verificar en logs:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose logs odoo | grep "loading translation"
|
|
||||||
```
|
|
||||||
|
|
||||||
Debe mostrar:
|
|
||||||
|
|
||||||
```
|
|
||||||
odoo.modules.loading: loading translation file for language 'es': addon_name/i18n/es.po
|
|
||||||
odoo.modules.loading: loading translation file for language 'eu': addon_name/i18n/eu.po
|
|
||||||
```
|
|
||||||
|
|
||||||
## Addons con Traducciones Completas
|
|
||||||
|
|
||||||
### Addons Custom
|
|
||||||
|
|
||||||
| Addon | es | eu | Otros |
|
|
||||||
|-------|----|----|-------|
|
|
||||||
| account_invoice_triple_discount_readonly | ✅ | ✅ | - |
|
|
||||||
| product_price_category_supplier | ✅ | ✅ | - |
|
|
||||||
| product_sale_price_from_pricelist | ✅ | - | - |
|
|
||||||
| website_sale_aplicoop | ✅ | ✅ | ca, gl, pt, fr, it |
|
|
||||||
|
|
||||||
### Addons OCA
|
|
||||||
|
|
||||||
Los addons OCA ya incluyen traducciones en múltiples idiomas.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Warning: "_() called at import time"
|
|
||||||
|
|
||||||
**Síntoma**:
|
|
||||||
```
|
|
||||||
WARNING: _() called at import time at module.path:line
|
|
||||||
```
|
|
||||||
|
|
||||||
**Causa**: `_()` usado en definición de campo a nivel de módulo
|
|
||||||
|
|
||||||
**Solución**: Eliminar `_()` de la definición del campo:
|
|
||||||
```python
|
|
||||||
# Cambiar:
|
|
||||||
name = fields.Char(string=_("Name"))
|
|
||||||
# Por:
|
|
||||||
name = fields.Char(string="Name")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Traducciones No Aparecen
|
|
||||||
|
|
||||||
**Posibles causas**:
|
|
||||||
|
|
||||||
1. **Archivo .po mal formado**: Verificar encoding UTF-8
|
|
||||||
2. **Módulo no actualizado**: `docker-compose exec odoo odoo -d odoo -u addon_name --stop-after-init`
|
|
||||||
3. **Idioma no activado**: Settings > Translations > Load Translation
|
|
||||||
4. **Usuario con idioma incorrecto**: Verificar preferencias de usuario
|
|
||||||
5. **Cache**: Reiniciar Odoo: `docker-compose restart odoo`
|
|
||||||
|
|
||||||
### Caracteres Especiales
|
|
||||||
|
|
||||||
Usar escape correcto en .po:
|
|
||||||
|
|
||||||
```po
|
|
||||||
# Comillas
|
|
||||||
msgstr "Haga clic en \"Confirmar\""
|
|
||||||
|
|
||||||
# Saltos de línea
|
|
||||||
msgstr "Primera línea\n"
|
|
||||||
"Segunda línea"
|
|
||||||
|
|
||||||
# Caracteres especiales (á, é, í, ó, ú, ñ, ç)
|
|
||||||
# Usar directamente, el archivo debe ser UTF-8
|
|
||||||
msgstr "Configuración"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Herramientas Útiles
|
|
||||||
|
|
||||||
### Editores de .po
|
|
||||||
|
|
||||||
- **Poedit**: https://poedit.net/ (GUI, recomendado)
|
|
||||||
- **VS Code**: Con extensión "gettext" para syntax highlighting
|
|
||||||
- **Lokalize**: Editor KDE para traducciones
|
|
||||||
|
|
||||||
### Comandos Útiles
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Verificar formato de archivo .po
|
|
||||||
msgfmt -c -v -o /dev/null addon_name/i18n/es.po
|
|
||||||
|
|
||||||
# Estadísticas de traducción
|
|
||||||
msgfmt --statistics addon_name/i18n/es.po
|
|
||||||
|
|
||||||
# Extraer solo términos sin traducir
|
|
||||||
msgattrib --untranslated addon_name/i18n/es.po
|
|
||||||
```
|
|
||||||
|
|
||||||
## Mejores Prácticas
|
|
||||||
|
|
||||||
1. ✅ Mantener es.po y eu.po siempre actualizados
|
|
||||||
2. ✅ Usar términos consistentes en todo el proyecto
|
|
||||||
3. ✅ Incluir contexto en comentarios cuando sea necesario
|
|
||||||
4. ✅ Verificar traducciones antes de commit
|
|
||||||
5. ✅ Nunca usar `_()` en definiciones de campos
|
|
||||||
6. ✅ Usar encoding UTF-8 en todos los archivos .po
|
|
||||||
7. ✅ Generar .pot después de cambios importantes
|
|
||||||
8. ✅ Documentar términos técnicos específicos del dominio
|
|
||||||
|
|
||||||
## Referencias
|
|
||||||
|
|
||||||
- **Odoo Translation Guidelines**: https://www.odoo.com/documentation/18.0/developer/reference/frontend/translations.html
|
|
||||||
- **GNU gettext Manual**: https://www.gnu.org/software/gettext/manual/
|
|
||||||
- **OCA Translation Guidelines**: https://github.com/OCA/maintainer-tools/wiki/Translations
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Última Actualización**: 2026-02-12
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
# Product Get Price Helper
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Provides a helper utility function to compute product prices with taxes, discounts, and unit of measure conversions.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Price Calculation Utility**: Helper method `get_product_price_for_pricelist`
|
|
||||||
- **Tax Handling**: Automatically computes prices with or without taxes
|
|
||||||
- **Discount Support**: Handles single and multiple discounts
|
|
||||||
- **UoM Conversion**: Converts prices between different units of measure
|
|
||||||
- **Reusable**: Can be used by other modules for price calculations
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Utility Function
|
|
||||||
|
|
||||||
Located in `utils.py`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
def get_product_price_for_pricelist(
|
|
||||||
product,
|
|
||||||
qty,
|
|
||||||
pricelist,
|
|
||||||
partner=None,
|
|
||||||
uom=None,
|
|
||||||
date=None,
|
|
||||||
include_tax=False
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Parameters**:
|
|
||||||
- `product`: Product record (product.product or product.template)
|
|
||||||
- `qty`: Quantity
|
|
||||||
- `pricelist`: Pricelist to use for calculation
|
|
||||||
- `partner`: Partner record (optional)
|
|
||||||
- `uom`: Unit of measure (optional, uses product default if not provided)
|
|
||||||
- `date`: Date for pricelist rules (optional, uses today if not provided)
|
|
||||||
- `include_tax`: Boolean, whether to include taxes in the result
|
|
||||||
|
|
||||||
**Returns**: Decimal price
|
|
||||||
|
|
||||||
### How It Works
|
|
||||||
|
|
||||||
1. Gets base price from pricelist
|
|
||||||
2. Applies any applicable discounts
|
|
||||||
3. Converts price if different UoM is specified
|
|
||||||
4. Adds taxes if `include_tax=True`
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- `account` (Odoo core)
|
|
||||||
- `product` (Odoo core)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose exec odoo odoo -d odoo -u product_get_price_helper --stop-after-init
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Example: Calculate Price with Tax
|
|
||||||
|
|
||||||
```python
|
|
||||||
from odoo.addons.product_get_price_helper.utils import get_product_price_for_pricelist
|
|
||||||
|
|
||||||
price = get_product_price_for_pricelist(
|
|
||||||
product=product_record,
|
|
||||||
qty=10,
|
|
||||||
pricelist=pricelist_record,
|
|
||||||
partner=partner_record,
|
|
||||||
include_tax=True
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example: Calculate Price with Different UoM
|
|
||||||
|
|
||||||
```python
|
|
||||||
price = get_product_price_for_pricelist(
|
|
||||||
product=product_record,
|
|
||||||
qty=1,
|
|
||||||
pricelist=pricelist_record,
|
|
||||||
uom=kg_uom, # Different from product's default UoM
|
|
||||||
include_tax=False
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## OCA Source
|
|
||||||
|
|
||||||
- **Repository**: [product-attribute](https://github.com/OCA/product-attribute)
|
|
||||||
- **Original Author**: ACSONE SA/NV
|
|
||||||
- **License**: AGPL-3
|
|
||||||
|
|
||||||
## Modifications for Kidekoop
|
|
||||||
|
|
||||||
None - Used as-is from OCA.
|
|
||||||
|
|
||||||
## Used By
|
|
||||||
|
|
||||||
This helper is used by other modules in the project:
|
|
||||||
- `product_sale_price_from_pricelist` - For automatic price calculations
|
|
||||||
- `product_price_category` - For category-based pricing
|
|
||||||
|
|
||||||
## Demo Data
|
|
||||||
|
|
||||||
Includes demo data with:
|
|
||||||
- Sample accounts
|
|
||||||
- Sample pricelists
|
|
||||||
|
|
||||||
Located in `demo/` directory.
|
|
||||||
|
|
||||||
## Translations
|
|
||||||
|
|
||||||
- ✅ Spanish (es)
|
|
||||||
- ✅ Euskera (eu)
|
|
||||||
|
|
||||||
Located in `i18n/` directory.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Version**: 18.0.1.1.0
|
|
||||||
**License**: AGPL-3
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
# Product Main Seller
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Adds a "Main Vendor" field to products that automatically tracks the primary supplier based on supplierinfo sequence.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Automatic Main Vendor**: Computed field showing the primary supplier
|
|
||||||
- **Based on Sequence**: Uses the supplierinfo with the lowest sequence number
|
|
||||||
- **Visible in Views**: Shows in product form and tree views
|
|
||||||
- **Searchable**: Can search and filter products by main vendor
|
|
||||||
- **Related Fields**: Access to vendor name and reference
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Models Extended
|
|
||||||
|
|
||||||
- `product.template`: Main product template
|
|
||||||
- `product.product`: Product variants
|
|
||||||
|
|
||||||
### Fields Added
|
|
||||||
|
|
||||||
- `default_supplier_id` (Many2one → res.partner, computed, stored)
|
|
||||||
- The main vendor for this product
|
|
||||||
- Computed from `seller_ids` with lowest sequence
|
|
||||||
- Stored for performance
|
|
||||||
- Searchable
|
|
||||||
|
|
||||||
- `default_supplier_ref` (Char, related to `default_supplier_id.ref`)
|
|
||||||
- The supplier's reference code
|
|
||||||
- Readonly
|
|
||||||
|
|
||||||
### Computation Logic
|
|
||||||
|
|
||||||
The main vendor is determined by:
|
|
||||||
1. Looking at all supplierinfo records (`seller_ids`)
|
|
||||||
2. Filtering for valid suppliers (not companies)
|
|
||||||
3. Selecting the one with the **lowest sequence** number
|
|
||||||
4. If no sequence, uses the first one
|
|
||||||
|
|
||||||
### Migration Hook
|
|
||||||
|
|
||||||
Includes `pre_init_hook` that:
|
|
||||||
- Populates `default_supplier_id` on existing products during installation
|
|
||||||
- Ensures data consistency from the start
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- `purchase` (Odoo core)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose exec odoo odoo -d odoo -u product_main_seller --stop-after-init
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Viewing Main Vendor
|
|
||||||
|
|
||||||
1. Open a product form (Products > Products > [Product])
|
|
||||||
2. See "Main Vendor" field (usually in Purchase tab)
|
|
||||||
3. Field is automatically computed from vendor list
|
|
||||||
|
|
||||||
### Changing Main Vendor
|
|
||||||
|
|
||||||
To change the main vendor:
|
|
||||||
1. Go to product form > Purchase tab
|
|
||||||
2. Edit the vendor list (`seller_ids`)
|
|
||||||
3. Change the sequence numbers (lower = more priority)
|
|
||||||
4. Save - the "Main Vendor" will update automatically
|
|
||||||
|
|
||||||
### Searching by Vendor
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Find all products from a specific vendor
|
|
||||||
products = self.env['product.template'].search([
|
|
||||||
('default_supplier_id', '=', vendor_id)
|
|
||||||
])
|
|
||||||
```
|
|
||||||
|
|
||||||
## OCA Source
|
|
||||||
|
|
||||||
- **Repository**: [purchase-workflow](https://github.com/OCA/purchase-workflow)
|
|
||||||
- **Original Author**: GRAP
|
|
||||||
- **Maintainers**: legalsylvain, quentinDupont
|
|
||||||
- **License**: AGPL-3
|
|
||||||
|
|
||||||
## Modifications for Kidekoop
|
|
||||||
|
|
||||||
None - Used as-is from OCA.
|
|
||||||
|
|
||||||
## Use Cases in Kidekoop
|
|
||||||
|
|
||||||
This module is critical for:
|
|
||||||
- `product_price_category_supplier`: Bulk updating products by main vendor
|
|
||||||
- Purchase order management
|
|
||||||
- Vendor performance analysis
|
|
||||||
- Inventory planning by supplier
|
|
||||||
|
|
||||||
## Views Modified
|
|
||||||
|
|
||||||
- Product Template Form View
|
|
||||||
- Product Template Tree View
|
|
||||||
- Product Variant Form View
|
|
||||||
|
|
||||||
## Translations
|
|
||||||
|
|
||||||
- ✅ Spanish (es)
|
|
||||||
- ✅ Euskera (eu)
|
|
||||||
|
|
||||||
Located in `i18n/` directory.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Version**: 18.0.1.0.0
|
|
||||||
**Category**: Purchase
|
|
||||||
**License**: AGPL-3
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# Product Origin
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Adds an origin field to products to track where they come from (geographic origin).
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Origin Field**: Adds a text field to store the product's origin
|
|
||||||
- **Visible in Views**: Shows in both product template and product variant forms
|
|
||||||
- **Simple Implementation**: Extends core product models
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Models Extended
|
|
||||||
|
|
||||||
- `product.template`: Main product template
|
|
||||||
- `product.product`: Product variants
|
|
||||||
|
|
||||||
### Fields Added
|
|
||||||
|
|
||||||
- `origin` (Char): Text field for product origin
|
|
||||||
|
|
||||||
### Views Modified
|
|
||||||
|
|
||||||
- Product Template Form
|
|
||||||
- Product Variant Form
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- `product` (Odoo core)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose exec odoo odoo -d odoo -u product_origin --stop-after-init
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
1. Open a product form (Products > Products > [Product])
|
|
||||||
2. Find the "Origin" field
|
|
||||||
3. Enter the geographic origin (e.g., "Spain", "France", "Local")
|
|
||||||
|
|
||||||
## OCA Source
|
|
||||||
|
|
||||||
- **Repository**: [product-attribute](https://github.com/OCA/product-attribute)
|
|
||||||
- **Original Authors**: ACSONE SA/NV, GRAP
|
|
||||||
- **License**: AGPL-3
|
|
||||||
|
|
||||||
## Modifications for Kidekoop
|
|
||||||
|
|
||||||
None - Used as-is from OCA.
|
|
||||||
|
|
||||||
## Translations
|
|
||||||
|
|
||||||
- ✅ Spanish (es)
|
|
||||||
- ✅ Euskera (eu)
|
|
||||||
|
|
||||||
Located in `i18n/` directory.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Version**: 18.0.1.0.0
|
|
||||||
**License**: AGPL-3
|
|
||||||
|
|
@ -1,22 +1,39 @@
|
||||||
# Copyright 2026 Criptomart
|
# Copyright 2026 Your Company
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
{ # noqa: B018
|
{
|
||||||
"name": "Product Price Category - Supplier Extension",
|
'name': 'Product Price Category - Supplier Extension',
|
||||||
"version": "18.0.1.0.0",
|
'version': '18.0.1.0.0',
|
||||||
"category": "Product",
|
'category': 'Product',
|
||||||
"summary": "Add default price category to suppliers and bulk update products",
|
'summary': 'Add default price category to suppliers and bulk update products',
|
||||||
"author": "Odoo Community Association (OCA), Criptomart",
|
'description': '''
|
||||||
"license": "AGPL-3",
|
Extends res.partner (suppliers) with a default price category field.
|
||||||
"depends": ["product_price_category", "sales_team", "product_main_seller"],
|
Allows bulk updating all products from a supplier with the default category
|
||||||
"data": [
|
via a wizard with confirmation dialog.
|
||||||
"security/ir.model.access.csv",
|
|
||||||
"views/res_partner_views.xml",
|
Features:
|
||||||
"views/wizard_update_product_category.xml",
|
- Add default price category to supplier partner
|
||||||
|
- Wizard to bulk update all supplier's products
|
||||||
|
- Column visibility toggle in partner tree view
|
||||||
|
- Access restricted to sales managers
|
||||||
|
''',
|
||||||
|
'author': 'Your Company',
|
||||||
|
'license': 'AGPL-3',
|
||||||
|
'depends': [
|
||||||
|
'product_price_category',
|
||||||
|
'sales_team',
|
||||||
|
'product_main_seller'
|
||||||
],
|
],
|
||||||
"i18n": [
|
'data': [
|
||||||
"i18n/product_price_category_supplier.pot",
|
'security/ir.model.access.csv',
|
||||||
"i18n/es.po",
|
'views/res_partner_views.xml',
|
||||||
"i18n/eu.po",
|
'views/wizard_update_product_category.xml',
|
||||||
],
|
],
|
||||||
|
'i18n': [
|
||||||
|
'i18n/product_price_category_supplier.pot',
|
||||||
|
'i18n/es.po',
|
||||||
|
'i18n/eu.po',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'auto_install': False,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
# Copyright 2025 - Today Criptomart
|
{
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
||||||
{ # noqa: B018
|
|
||||||
"name": "Product Sale Price from Pricelist",
|
"name": "Product Sale Price from Pricelist",
|
||||||
"version": "18.0.1.0.0",
|
"version": "18.0.1.0.0",
|
||||||
"category": "product",
|
"category": "product",
|
||||||
"summary": "Set sale price from pricelist based on last purchase price",
|
"summary": "Set sale price from pricelist based on last purchase price",
|
||||||
"author": "Odoo Community Association (OCA), Criptomart",
|
"description": """
|
||||||
"maintainers": ["Criptomart"],
|
Set sale price from pricelist based on last purchase price
|
||||||
"website": "https://git.criptomart.net/criptomart/addons-cm",
|
""",
|
||||||
|
"author": "Criptomart",
|
||||||
|
"website": "https://criptomart.net",
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
"depends": [
|
"depends": [
|
||||||
"product_get_price_helper",
|
"product_get_price_helper",
|
||||||
|
|
@ -21,4 +21,5 @@
|
||||||
"views/actions.xml",
|
"views/actions.xml",
|
||||||
"views/product_view.xml",
|
"views/product_view.xml",
|
||||||
],
|
],
|
||||||
|
"installable": True,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,82 @@
|
||||||
# Copyright 2025 - Today Criptomart
|
# Copyright 2025 Criptomart
|
||||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||||
|
|
||||||
{ # noqa: B018
|
{
|
||||||
"name": "Website Sale - Aplicoop",
|
'name': 'Website Sale - Aplicoop',
|
||||||
"version": "18.0.1.0.3",
|
'version': '18.0.1.0.2',
|
||||||
"category": "Website/Sale",
|
'category': 'Website/Sale',
|
||||||
"summary": "Modern replacement of legacy Aplicoop - Collaborative consumption group orders",
|
'summary': 'Modern replacement of legacy Aplicoop - Collaborative consumption group orders',
|
||||||
"author": "Odoo Community Association (OCA), Criptomart",
|
'description': '''
|
||||||
"maintainers": ["Criptomart"],
|
Website Sale - Aplicoop
|
||||||
"website": "https://git.criptomart.net/criptomart/addons-cm",
|
=======================
|
||||||
"license": "AGPL-3",
|
|
||||||
"depends": [
|
A modern Odoo 18 module that replaces the legacy Aplicoop application with
|
||||||
"website_sale",
|
a complete, scalable solution for managing collaborative consumption group
|
||||||
"product",
|
orders (eskaera in Basque).
|
||||||
"sale",
|
|
||||||
"account",
|
Features
|
||||||
"product_get_price_helper",
|
--------
|
||||||
"product_origin",
|
|
||||||
|
* Group Order Management: Create and manage group purchasing periods
|
||||||
|
* Separate Carts: Each user has an independent cart per group order
|
||||||
|
* Product Associations: Link products, suppliers, and categories to orders
|
||||||
|
* Web Interface: Responsive product catalog and checkout
|
||||||
|
* State Machine: Draft → Open → Closed/Cancelled workflow
|
||||||
|
* Sales Integration: Automatic conversion to Odoo sale.order
|
||||||
|
* Modern UI: AJAX-based cart without page reloads
|
||||||
|
* Security: Enterprise-ready with access control
|
||||||
|
|
||||||
|
Installation
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Add to Odoo addons directory and install via Apps menu.
|
||||||
|
See README.rst for detailed documentation.
|
||||||
|
''',
|
||||||
|
'author': 'Criptomart',
|
||||||
|
'maintainers': ['Criptomart'],
|
||||||
|
'website': 'https://criptomart.net',
|
||||||
|
'license': 'AGPL-3',
|
||||||
|
'depends': [
|
||||||
|
'website_sale',
|
||||||
|
'product',
|
||||||
|
'sale',
|
||||||
|
'account',
|
||||||
|
'product_get_price_helper',
|
||||||
],
|
],
|
||||||
"data": [
|
'data': [
|
||||||
# Datos: Grupos propios
|
# Datos: Grupos propios
|
||||||
"data/groups.xml",
|
'data/groups.xml',
|
||||||
# Vistas de seguridad
|
# Vistas de seguridad
|
||||||
"security/ir.model.access.csv",
|
'security/ir.model.access.csv',
|
||||||
"security/record_rules.xml",
|
'security/record_rules.xml',
|
||||||
# Vistas
|
# Vistas
|
||||||
"views/group_order_views.xml",
|
'views/group_order_views.xml',
|
||||||
"views/res_partner_views.xml",
|
'views/res_partner_views.xml',
|
||||||
"views/website_templates.xml",
|
'views/website_templates.xml',
|
||||||
"views/product_template_views.xml",
|
'views/product_template_views.xml',
|
||||||
"views/sale_order_views.xml",
|
'views/sale_order_views.xml',
|
||||||
"views/portal_templates.xml",
|
'views/portal_templates.xml',
|
||||||
"views/load_from_history_templates.xml",
|
'views/load_from_history_templates.xml',
|
||||||
],
|
],
|
||||||
"i18n": [
|
'i18n': [
|
||||||
"i18n/es.po",
|
'i18n/es.po',
|
||||||
"i18n/eu_ES.po",
|
'i18n/eu_ES.po',
|
||||||
],
|
],
|
||||||
"external_dependencies": {
|
'external_dependencies': {
|
||||||
"python": [],
|
'python': [],
|
||||||
},
|
},
|
||||||
"assets": {
|
'assets': {
|
||||||
"web.assets_frontend": [
|
'web.assets_frontend': [
|
||||||
"website_sale_aplicoop/static/src/css/website_sale.css",
|
'website_sale_aplicoop/static/src/css/website_sale.css',
|
||||||
],
|
],
|
||||||
"web.assets_tests": [
|
'web.assets_tests': [
|
||||||
"website_sale_aplicoop/static/tests/test_suite.js",
|
'website_sale_aplicoop/static/tests/test_suite.js',
|
||||||
"website_sale_aplicoop/static/tests/test_cart_functions.js",
|
'website_sale_aplicoop/static/tests/test_cart_functions.js',
|
||||||
"website_sale_aplicoop/static/tests/test_tooltips_labels.js",
|
'website_sale_aplicoop/static/tests/test_tooltips_labels.js',
|
||||||
"website_sale_aplicoop/static/tests/test_realtime_search.js",
|
'website_sale_aplicoop/static/tests/test_realtime_search.js',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"application": True,
|
'installable': True,
|
||||||
|
'auto_install': False,
|
||||||
|
'application': True,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue