feat(#49): add product provenance (suppliers, organizations, geography)
- 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
This commit is contained in:
64
tienda_ilusion/don_confiao/services/provenance.py
Normal file
64
tienda_ilusion/don_confiao/services/provenance.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from ..serializers.provenance import (
|
||||
CountryBriefSerializer,
|
||||
DepartmentBriefSerializer,
|
||||
MunicipalityBriefSerializer,
|
||||
OrganizationBriefSerializer,
|
||||
SupplierBriefSerializer,
|
||||
)
|
||||
from ..serializers.products import ListProductSerializer
|
||||
|
||||
|
||||
def build_product_provenance(products, request=None):
|
||||
"""Domain data for provenance charts.
|
||||
|
||||
Returns a list of products, each with its suppliers. Each supplier
|
||||
entry includes the linked organization and the territorial hierarchy
|
||||
(municipality -> department -> country) derived from the supplier's
|
||||
municipality.
|
||||
"""
|
||||
result = []
|
||||
for product in products:
|
||||
suppliers = []
|
||||
supplier_qs = product.suppliers.all().select_related(
|
||||
"organization", "municipality__department__country"
|
||||
)
|
||||
for supplier in supplier_qs:
|
||||
municipality = supplier.municipality
|
||||
entry = {
|
||||
"supplier": SupplierBriefSerializer(supplier).data,
|
||||
"organization": (
|
||||
OrganizationBriefSerializer(supplier.organization).data
|
||||
if supplier.organization
|
||||
else None
|
||||
),
|
||||
"municipality": (
|
||||
MunicipalityBriefSerializer(municipality).data
|
||||
if municipality
|
||||
else None
|
||||
),
|
||||
"department": (
|
||||
DepartmentBriefSerializer(
|
||||
municipality.department
|
||||
).data
|
||||
if municipality
|
||||
else None
|
||||
),
|
||||
"country": (
|
||||
CountryBriefSerializer(
|
||||
municipality.department.country
|
||||
).data
|
||||
if municipality
|
||||
else None
|
||||
),
|
||||
}
|
||||
suppliers.append(entry)
|
||||
|
||||
result.append(
|
||||
{
|
||||
"product": ListProductSerializer(
|
||||
product, context={"request": request}
|
||||
).data,
|
||||
"suppliers": suppliers,
|
||||
}
|
||||
)
|
||||
return result
|
||||
Reference in New Issue
Block a user