Documenta como hacer requests RPC de prueba contra Tryton con
sabatron-tryton-rpc-client:
- .opencode/skills/tryton-rpc-probe/SKILL.md: comando base con docker compose
dev (--no-deps), credenciales desde .env, como revelar estados HTTP
(401/403/429) que la libreria enmascara, convencion de agrupacion de campos
con punto ('template.' -> 'categories.') y sondas de ejemplo
- .opencode/agents/tryton-rpc-probe.md: subagente que obliga a cargar el skill
- AGENTS.md: referencia al skill para todos los agents del proyecto
Issue #51: discriminacion y administracion de categorias de productos.
- product.read ahora solicita template.categories.name; se elimina la
llamada separada model.product.category.read
- ProductTrytonService y CategoryTrytonService construyen el mapa
{id_tryton: nombre} desde 'template.categories.' de los productos leídos
- import_from_external pasa de 3 llamadas RPC a 2
Issue #51: discriminacion y administracion de categorias de productos.
- ProductCategoryAdmin con list_display/filtro por active
- doc/requests.org: GET/PATCH product_categories, import_from_external,
deactivate, activate
Issue #51: discriminacion y administracion de categorias de productos.
- Product.to_list() devuelve categorias como objetos
(id, name, alternative_name, active) en vez de solo nombres
Issue #51: discriminacion y administracion de categorias de productos.
- ProductCategoryView en /api/product_categories (list/retrieve IsNotPublico,
mutaciones admin): filtro ?active, PATCH de description/alternative_name/active
- POST deactivate/activate con body {ids} -> {deactivated|activated, failed}
(ignora ids inexistentes)
- POST import_from_external admin via CategoryTrytonService
- create/destroy deshabilitados (la fuente de categorias es Tryton)
Issue #51: discriminacion y administracion de categorias de productos.
- CategoryTrytonService.import_from_external: lee categorias asociadas a
productos salables, hace upsert por external_id (fallback nombre),
preserva description/alternative_name/active, reporta
checked/created/updated/untouched/failed
- upsert_category compartido y reutilizado por ProductTrytonService
Issue #51: discriminacion y administracion de categorias de productos.
- ProductCategorySerializer (name/external_id read_only)
- ProductCategoryBriefSerializer para el JSON de productos
- ProductSerializer.categories ahora devuelve objetos anidados
Issue #51: discriminacion y administracion de categorias de productos.
- _need_update compara las categorias (external_id) local vs Tryton
- _describe_changes reporta categorias agregadas (+Nombre) y removidas (-Nombre)
- Actualiza test que asumia asignacion de categorias sin marcar update
Issue #51: discriminacion y administracion de categorias de productos.
- ProductCategory.description (TextField blank)
- ProductCategory.alternative_name (CharField 100 nullable)
- ProductCategory.active (Boolean default True)
- Migracion 0056_productcategory_active_and_more
- Tests de modelo (campo don confiao y active por defecto)
- Campo external_id en ProductCategory para vincular con Tryton (migración 0055)
- Import/upsert de categorías usadas por los productos sincronizados
- Asignación M2M en productos creados, actualizados y sin cambios
- Respuesta del import incluye created_categories y updated_categories con detalle
- Fix: leer las categorías desde la clave agrupada "template." que devuelve el RPC de Tryton
Allowlist scripts/ in .gitignore (was caught by [Ss]cripts venv rule)
so seed_geography.py and colombia_municipios.csv can be committed.
This simplifies deployment since the files no longer need to be
copied separately to the server.
- Municipality model with optional latitude/longitude decimal fields
- Municipality and brief serializers expose lat/lng (also in product_provenance of public/authenticated summaries for the Leaflet map)
- seed_geography endpoint reads lat/lng and updates existing municipalities on reseed (idempotent)
- TDD tests for model, serializers, summaries and seed
- DepartmentSerializer adds country_detail (nested country object)
- MunicipalitySerializer adds department_detail and country_detail
- Writable FK id fields kept for create/update
- Move geography brief serializers to serializers/geography.py
- Country, Department, Municipality models (municipality unique per department)
- Organization and Supplier models, Supplier links to organization and municipality
- Product.suppliers M2M to link products to one or more suppliers
- Authenticated CRUD APIs for organizations, suppliers, countries, departments and municipalities (write only for administrators)
- product_provenance domain data embedded in sale/catalog summaries (public and authenticated)
- seed_geography endpoint (admin, idempotent) and scripts/seed_geography.py using pycountry + DANE municipalities CSV
- TDD tests for models, API permissions/CRUD and summary provenance data
- failed_products/failed_parties ahora incluyen {external_id, name, error} con causa legible (precio nulo, nombre duplicado, etc.)
- Los fallos de actualización de productos y clientes ya no abortan la sincronización
- created/updated/untouched/checked como objetos {id, name}; updated incluye detail con los cambios (Nombre/Precio/Unidad/Dirección)
- Ventas y catálogo: successful {id, code} y failed {id, code, error} (antes solo IDs, sin detalle)
- Added CatalogSale/CatalogSaleLine to setUp
- Added explicit assertion linking TrytonSale.build_tryton_comment()
to sale.description
- Rewrote test_send_catalog_sales_to_tryton with proper CatalogSale
data, validating comment format, description, reference and lines
- Added direct assertion of TrytonCatalogSale.build_tryton_comment()
- Restored test_exportar_ventas_para_tryton.py with full parameter
validation for client.call (method, context, sale fields, lines)
- Fixed TrytonSale.build_tryton_comment referencing self.catalog_sale
(nonexistent) instead of self.sale.description
- Crea modelo UserProfile (OneToOne con User) con user_type: publico/user/administrator
- Señal post_save que crea UserProfile automáticamente al crear User
- UserSerializer.get_role() lee desde profile.user_type
- Nuevos permisos: IsNotPublico, IsPublico y actualiza IsAdministrator
- IsNotPublico restringe acceso a vistas de gestión (productos, clientes, ventas)
- CatalogSaleView.create permite publico; otras acciones requieren IsNotPublico
- UserProfile inline en admin de Usuarios
- Data migration para backfill de usuarios existentes
- Cambia default global de IsAuthenticated a AllowAny en settings/base.py
- ProductView: AllowAny para GET, IsAuthenticated para POST/PUT/DELETE
- CatalogueImageViewSet: AllowAny para reads, IsAuthenticated+Admin para writes
- PaymentMethodView: AllowAny (público)
- SaleView, CatalogSaleView, SaleSummary, CatalogSaleSummary: IsAuthenticated
- CustomerView: IsAuthenticated
- Use PNG format instead of JPEG for transparency support
- Non-strict mode only resizes if image width > target width
- Replace CATALOGUE_BACKGROUND_IMAGES_COLOR with CATALOGUE_BACKGROUND_IMAGES_RGBA (tuple default (0,0,0,0))
- Move all inline imports to top of test file
- Add test_resize_non_strict_no_upscale test case
- Add comment explaining settings.DEBUG guard for media serving