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
- Add CatalogueImage model with FK to Product
- Add image resize service (strict/non-strict modes with configurable dimensions)
- Add CRUD API endpoints with admin-only write permissions
- Add catalogue_images field to product listing/detail endpoints
- Serve media files in development via static()
- 28 TDD tests covering model, API, permissions, resize, and product listing
- Include external_id field in CatalogSaleSerializer response
- Allows API clients to see if catalog sale has been synced to Tryton
- Maintains consistency with SaleSerializer which already includes external_id
- Backward compatible change (field is nullable)
- Add external_id field to CatalogSale model for tracking synced sales
- Create migration 0047 for external_id field
- Add TrytonCatalogSale and TrytonCatalogSaleLine classes for Tryton RPC format
- Add send_catalog_sales_to_tryton() method to SaleTrytonService
- Create CatalogSalesToTrytonView API endpoint (POST)
- Register endpoint at /don_confiao/api/enviar_catalog_sales_a_tryton
- Add test for external_id field functionality
- Catalog sales sync to same Tryton model as Sale (model.sale.sale.create)
- Differentiated by reference 'don_confiao_catalog X' and description 'Venta de catálogo'
- Filters only catalog sales without external_id to avoid duplicates
- Add CatalogSaleSummarySerializer and CatalogSummarySaleLineSerializer
- Add CatalogSaleSummary API view for GET requests
- Register endpoint at /don_confiao/resumen_compra_catalogo_json/<id>
- Add comprehensive test for catalog sale summary
- Include nested customer and product details in response
- Endpoint returns id, date, customer, and lines with products
Agrega documentación completa sobre la refactorización realizada:
- Estructura de directorios detallada
- Detalles por dominio (Products, Customers, Sales, Payments, Admin)
- Beneficios y principios aplicados
- Ejemplos de uso
- Métricas y verificaciones de calidad
Refactoriza la estructura del proyecto siguiendo principios de Domain-Driven Design,
organizando serializers, API views y servicios por dominios de negocio.
Cambios principales:
## Serializers (serializers/)
- Dividido serializers.py en módulos por dominio:
* products.py: ProductSerializer, ListProductSerializer
* customers.py: CustomerSerializer, ListCustomerSerializer
* sales.py: SaleSerializer, SaleLineSerializer, CatalogSaleSerializer, etc.
* payments.py: ReconciliationJarSerializer, PaymentMethodSerializer
* __init__.py: Exporta todos los serializers para mantener compatibilidad
## API Views (api/)
- Dividido api_views.py en módulos por dominio:
* products.py: ProductView, ProductsFromTrytonView
* customers.py: CustomerView, CustomersFromTrytonView
* sales.py: SaleView, CatalogSaleView, SaleSummary, SalesForTrytonView, SalesToTrytonView
* payments.py: ReconciliateJarView, ReconciliateJarModelView, PaymentMethodView, SalesForReconciliationView
* admin.py: AdminCodeValidateView
* __init__.py: Exporta todas las vistas para facilitar importaciones
## Services Layer (services/tryton/)
- Nueva capa de servicios para lógica de negocio Tryton:
* client.py: get_tryton_client(), TrytonSale, TrytonLineSale, configuración
* products.py: ProductTrytonService - sincronización de productos
* customers.py: CustomerTrytonService - sincronización de clientes
* sales.py: SaleTrytonService - sincronización de ventas
* __init__.py: Exporta servicios y utilidades
## Actualización de URLs
- Actualizado urls.py para importar desde nuevos módulos
- Mantiene todas las rutas existentes sin cambios
## Eliminación de archivos antiguos
- Eliminado serializers.py (refactorizado a serializers/)
- Eliminado api_views.py (refactorizado a api/)
## Beneficios
✅ Cohesión: Código organizado por dominio de negocio
✅ Separación de responsabilidades: API, Serializers y Services separados
✅ Mantenibilidad: Archivos más pequeños y enfocados
✅ Escalabilidad: Fácil agregar nuevos dominios
✅ Testabilidad: Mejor organización para pruebas por dominio
✅ Reutilización: Servicios Tryton pueden usarse desde cualquier vista
## Estructura final:
- models/ (ya existía organizado por dominio)
- serializers/ (nuevo, organizado por dominio)
- api/ (nuevo, organizado por dominio)
- services/tryton/ (nuevo, capa de servicios)
Tests: 46 tests pasando ✓