Saltar al contenido principal

Material Consumptions Module

Records material/product consumption events within a business — typically for production inputs, internal use, or service-related material usage. Each document captures line items with quantities, prices, and taxes, along with payment methods and auto-calculated inventory costs (WAC).

Architecture

apps/backend/src/material-consumptions/
├── material-consumptions.module.ts # NestJS module
├── domain/
│ └── material-consumptions-repository.domain.ts # Repository port
├── application/
│ ├── material-consumptions.service.ts # Use cases
│ └── events/
│ ├── on-create-material-consumption.event.ts
│ ├── on-update-material-consumption.event.ts
│ └── generate-material-consumption-link.dto.ts
├── infrastructure/
│ └── material-consumptions.repository.ts # Kysely adapter
└── interfaces/
├── material-consumptions.controller.ts # HTTP controller
├── dtos/
│ ├── create-material-consumption.dto.ts
│ └── update-material-consumption.dto.ts
└── query/
└── paginate-material-consumptions.query.ts

Layer responsibilities:

LayerResponsibility
DomainRepository interface (port). Framework-agnostic.
ApplicationOrchestrates creation, updates, PDF generation, public links. Emits domain events.
InfrastructureKysely queries against materialConsumption table. Filtering, pagination, transactions.
InterfacesHTTP controllers, DTOs, query objects. Thin — delegates to service.

Domain Concepts

Material Consumption Document

A document recording consumed materials with:

FieldDescription
documentNumberAuto-generated sequential number
statusdraftsubmittedreviewed
detailJSON with line items (products, quantities, prices, taxes)
paymentDetailJSON with payment method entries
costDetailAuto-calculated WAC (weighted average cost) from inventory
documentDateDate of the consumption event

Cost Calculation Flow

On creation, the service:

  1. Extracts items from detail
  2. Groups by location and product
  3. Fetches current inventory quantities and costs
  4. Calculates WAC per item
  5. Stores result in costDetail

Event-Driven Inventory Integration

  • materialConsumption.createInventoryOutboundHandler processes stock deduction
  • materialConsumption.update → Re-evaluates if status changed from draft to submitted/reviewed

API Endpoints

MethodPathDescription
POST/material-consumptionsCreate a new material consumption
GET/material-consumptionsList with pagination, filtering, search
GET/material-consumptions/:idGet by ID
PATCH/material-consumptions/:idUpdate (partial)
DELETE/material-consumptions/:idDelete
GET/material-consumptions/:id/pdfDownload as PDF
GET/material-consumptions/:id/pdf/contentGet PDF as base64 JSON
GET/material-consumptions/:id/printHTML print view
POST/material-consumptions/:id/public-linkGenerate signed public URL
GET/material-consumptions/:id/template-dataGet PDF template data

Query Parameters (List)

ParamTypeDescription
businessIdUUIDFilter by business
statusstringFilter by status (draft, submitted, reviewed)
documentNumberstringFilter by exact document number
serviceBookingIdUUIDFilter by linked service booking
createdAtFrom / createdAtToISO dateCreated date range
documentDateFrom / documentDateToISO dateDocument date range
searchstringSearch across taxId, taxName, taxAddress, locationName
size / pagenumberPagination
orderBy / orderstringSorting

PDF Options (Query Params)

ParamDefaultDescription
pageSizeA4Page size
marginTop/Right/Bottom/Left20Margins in pixels
printBackgroundtrueInclude background
timeout30000Render timeout (ms)
templateIdOverride template
locationIdLocation-specific template
useLocationTemplatefalseUse location template

Design Decisions

  1. Cost auto-calculation on create — The service calculates WAC from current inventory on document creation. This captures point-in-time costs without requiring the client to compute them.

  2. Event-driven inventory — Stock deductions are handled asynchronously via OnCreateMaterialConsumptionEvent / OnUpdateMaterialConsumptionEvent, keeping the module decoupled from inventory logic.

  3. Transaction scoping — Document creation (including document number generation, cost calculation, and insert) happens in a single database transaction for consistency.

  4. PDF template system — Supports system default, custom, and location-specific templates via the shared PdfModule infrastructure.

  5. Public link via GCP Cloud Storage — PDF is generated, uploaded to cloud storage, and a time-limited signed URL is returned. Link metadata is stored on the document record.