feat: add partial shipment support (Phase 3)
- Add shipped_quantity field to OrderItem for tracking partial fulfillment
- Add partially_shipped order status for orders with partial shipments
- Add fulfill_item method for shipping individual items with quantities
- Add get_shipment_status method for detailed shipment tracking
- Add vendor API endpoints for partial shipment operations:
- GET /orders/{id}/shipment-status - Get item-level shipment status
- POST /orders/{id}/items/{item_id}/ship - Ship specific item quantity
- Automatic status updates: partially_shipped when some items shipped,
shipped when all items fully shipped
- Migration to add shipped_quantity column with upgrade for existing data
- Update documentation with partial shipment usage examples
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -242,9 +242,130 @@ recent = db.query(InventoryTransaction).filter(
|
||||
).order_by(InventoryTransaction.created_at.desc()).limit(10).all()
|
||||
```
|
||||
|
||||
## Partial Shipments (Phase 3)
|
||||
|
||||
Orders can be partially shipped, allowing vendors to ship items as they become available.
|
||||
|
||||
### Status Flow
|
||||
|
||||
```
|
||||
pending → processing → partially_shipped → shipped → delivered
|
||||
↘ ↗
|
||||
→ shipped (if all items shipped at once)
|
||||
```
|
||||
|
||||
### OrderItem Tracking
|
||||
|
||||
Each order item has a `shipped_quantity` field:
|
||||
|
||||
```python
|
||||
class OrderItem:
|
||||
quantity: int # Total ordered
|
||||
shipped_quantity: int # Units shipped so far
|
||||
|
||||
@property
|
||||
def remaining_quantity(self):
|
||||
return self.quantity - self.shipped_quantity
|
||||
|
||||
@property
|
||||
def is_fully_shipped(self):
|
||||
return self.shipped_quantity >= self.quantity
|
||||
```
|
||||
|
||||
### API Endpoints
|
||||
|
||||
#### Get Shipment Status
|
||||
|
||||
```http
|
||||
GET /api/v1/vendor/orders/{order_id}/shipment-status
|
||||
```
|
||||
|
||||
Returns item-level shipment status:
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"order_number": "ORD-1-20260101-ABC123",
|
||||
"order_status": "partially_shipped",
|
||||
"is_fully_shipped": false,
|
||||
"is_partially_shipped": true,
|
||||
"shipped_item_count": 1,
|
||||
"total_item_count": 3,
|
||||
"total_shipped_units": 2,
|
||||
"total_ordered_units": 5,
|
||||
"items": [
|
||||
{
|
||||
"item_id": 1,
|
||||
"product_name": "Widget A",
|
||||
"quantity": 2,
|
||||
"shipped_quantity": 2,
|
||||
"remaining_quantity": 0,
|
||||
"is_fully_shipped": true
|
||||
},
|
||||
{
|
||||
"item_id": 2,
|
||||
"product_name": "Widget B",
|
||||
"quantity": 3,
|
||||
"shipped_quantity": 0,
|
||||
"remaining_quantity": 3,
|
||||
"is_fully_shipped": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Ship Individual Item
|
||||
|
||||
```http
|
||||
POST /api/v1/vendor/orders/{order_id}/items/{item_id}/ship
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"quantity": 2 // Optional - defaults to remaining quantity
|
||||
}
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"item_id": 1,
|
||||
"fulfilled_quantity": 2,
|
||||
"shipped_quantity": 2,
|
||||
"remaining_quantity": 0,
|
||||
"is_fully_shipped": true
|
||||
}
|
||||
```
|
||||
|
||||
### Automatic Status Updates
|
||||
|
||||
When shipping items:
|
||||
1. If some items are shipped → status becomes `partially_shipped`
|
||||
2. If all items are fully shipped → status becomes `shipped`
|
||||
|
||||
### Service Usage
|
||||
|
||||
```python
|
||||
from app.services.order_inventory_service import order_inventory_service
|
||||
|
||||
# Ship partial quantity of an item
|
||||
result = order_inventory_service.fulfill_item(
|
||||
db=db,
|
||||
vendor_id=vendor_id,
|
||||
order_id=order_id,
|
||||
item_id=item_id,
|
||||
quantity=2, # Ship 2 units
|
||||
)
|
||||
|
||||
# Get shipment status
|
||||
status = order_inventory_service.get_shipment_status(
|
||||
db=db,
|
||||
vendor_id=vendor_id,
|
||||
order_id=order_id,
|
||||
)
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Multi-Location Selection** - Choose which location to draw from
|
||||
2. **Backorder Support** - Handle orders when stock is insufficient
|
||||
3. **Return Processing** - Increase stock when orders are returned
|
||||
4. **Transaction API** - Endpoint to view inventory history
|
||||
|
||||
Reference in New Issue
Block a user