Add POI feature and imporve the overall backend implementation

This commit is contained in:
Urtzi Alfaro
2025-11-12 15:34:10 +01:00
parent e8096cd979
commit 5783c7ed05
173 changed files with 16862 additions and 9078 deletions

View File

@@ -30,6 +30,17 @@ The **Procurement Service** automates ingredient purchasing by analyzing product
- **Performance Tracking** - Monitor on-time delivery and quality
- **Supplier Scorecards** - Data-driven supplier evaluation
### Purchase Order Workflow & Tracking (🆕)
- **Dashboard-Integrated Approval** - Approve/reject POs directly from dashboard action queue
- **Progressive Disclosure** - View PO details inline without navigation
- **Automatic Supplier Notifications** - Professional HTML emails sent on approval
- **Delivery Date Tracking** - Auto-calculate estimated delivery based on supplier lead time
- **Color-Coded Status Indicators** - Visual delivery tracking (green/yellow/red)
- **Overdue Detection** - Hourly background job detects late deliveries
- **Severity Levels** - Low (1d), Medium (2-3d), High (4-7d), Critical (7+ days overdue)
- **Delivery Receipt Modal** - Comprehensive delivery recording with batch/expiry tracking
- **Automatic Stock Updates** - Inventory updated automatically via events when deliveries recorded
### Stock Optimization
- **Reorder Point Calculation** - When to order based on consumption rate
- **Economic Order Quantity (EOQ)** - Optimal order size calculation
@@ -103,9 +114,19 @@ The **Procurement Service** automates ingredient purchasing by analyzing product
- `POST /api/v1/procurement/purchase-orders` - Create purchase order
- `GET /api/v1/procurement/purchase-orders/{po_id}` - Get PO details
- `PUT /api/v1/procurement/purchase-orders/{po_id}` - Update PO
- `POST /api/v1/procurement/purchase-orders/{po_id}/approve` - Approve PO (triggers email)
- `POST /api/v1/procurement/purchase-orders/{po_id}/reject` - Reject PO with reason
- `POST /api/v1/procurement/purchase-orders/{po_id}/send` - Send PO to supplier
- `POST /api/v1/procurement/purchase-orders/{po_id}/receive` - Mark PO received
- `POST /api/v1/procurement/purchase-orders/{po_id}/cancel` - Cancel PO
- `GET /api/v1/procurement/purchase-orders/overdue` - Get overdue POs (🆕)
- `GET /api/v1/procurement/purchase-orders/{po_id}/overdue-status` - Check if PO is overdue (🆕)
### Deliveries (🆕)
- `POST /api/v1/procurement/purchase-orders/{po_id}/deliveries` - Record delivery receipt
- `GET /api/v1/procurement/purchase-orders/{po_id}/deliveries` - List deliveries for PO
- `GET /api/v1/procurement/purchase-orders/{po_id}/deliveries/{delivery_id}` - Get delivery details
- `PATCH /api/v1/procurement/purchase-orders/{po_id}/deliveries/{delivery_id}/status` - Update delivery status
### Purchase Order Items
- `GET /api/v1/procurement/purchase-orders/{po_id}/items` - List PO items
@@ -690,8 +711,110 @@ async def recommend_supplier(
### Published Events (RabbitMQ)
**Exchange**: `procurement.events`
**Routing Keys**: `po.approved`, `po.rejected`, `po.sent_to_supplier`, `delivery.received`, `procurement.needs_calculated`, `procurement.po_created`, `procurement.stockout_risk`
### Purchase Order Lifecycle Events (🆕)
**PO Approved Event** - Published when a PO is approved
- **Routing Key**: `po.approved`
- **Consumed By**: Notification service (sends email to supplier)
- **Trigger**: User approves PO in dashboard or via API
```json
{
"event_id": "uuid",
"event_type": "po.approved",
"service_name": "procurement",
"timestamp": "2025-11-12T10:30:00Z",
"data": {
"tenant_id": "uuid",
"po_id": "uuid",
"po_number": "PO-2025-1112-001",
"supplier_id": "uuid",
"supplier_name": "Harinas García",
"supplier_email": "pedidos@harinasgarcia.es",
"supplier_phone": "+34612345678",
"total_amount": 850.00,
"currency": "EUR",
"required_delivery_date": "2025-11-19",
"items": [
{
"product_name": "Harina de Trigo T-55",
"ordered_quantity": 100.0,
"unit_of_measure": "kg",
"unit_price": 0.85,
"line_total": 85.00
}
],
"approved_by": "uuid",
"approved_at": "2025-11-12T10:30:00Z"
}
}
```
**PO Rejected Event** - Published when a PO is rejected
- **Routing Key**: `po.rejected`
- **Consumed By**: Notification service (notifies stakeholders)
- **Trigger**: User rejects PO with reason
```json
{
"event_id": "uuid",
"event_type": "po.rejected",
"service_name": "procurement",
"timestamp": "2025-11-12T10:30:00Z",
"data": {
"tenant_id": "uuid",
"po_id": "uuid",
"po_number": "PO-2025-1112-001",
"supplier_id": "uuid",
"supplier_name": "Harinas García",
"rejection_reason": "Price too high compared to market rate",
"rejected_by": "uuid",
"rejected_at": "2025-11-12T10:30:00Z"
}
}
```
**Delivery Received Event** - Published when a delivery is recorded
- **Routing Key**: `delivery.received`
- **Consumed By**: Inventory service (automatically updates stock)
- **Trigger**: User records delivery receipt in `DeliveryReceiptModal`
```json
{
"event_id": "uuid",
"event_type": "delivery.received",
"service_name": "procurement",
"timestamp": "2025-11-12T10:30:00Z",
"data": {
"tenant_id": "uuid",
"delivery_id": "uuid",
"po_id": "uuid",
"received_by": "uuid",
"received_at": "2025-11-12T10:30:00Z",
"items": [
{
"inventory_product_id": "uuid",
"product_name": "Harina de Trigo T-55",
"ordered_quantity": 100.0,
"delivered_quantity": 98.0,
"accepted_quantity": 95.0,
"rejected_quantity": 3.0,
"batch_lot_number": "LOT-2025-1112",
"expiry_date": "2025-12-12",
"rejection_reason": "3 damaged bags"
}
]
}
}
```
### Legacy/Other Events
**Exchange**: `procurement`
**Routing Keys**: `procurement.needs_calculated`, `procurement.po_created`, `procurement.po_received`, `procurement.stockout_risk`
**Routing Keys**: `procurement.needs_calculated`, `procurement.po_created`, `procurement.stockout_risk`
**Procurement Needs Calculated Event**
```json