Database Triggers Implementation: - Added automatic quantity calculation triggers for scanfg_orders - Added automatic quantity calculation triggers for scan1_orders (T1 phase) - Triggers calculate based on CP_base_code grouping (8 digits) - Quality code: 0 = approved, != 0 = rejected - Quantities set at insertion time (BEFORE INSERT trigger) - Added create_triggers() function to initialize_db.py Warehouse Inventory Enhancement: - Analyzed old app database quantity calculation logic - Created comprehensive trigger implementation guide - Added trigger verification and testing procedures - Documented data migration strategy Documentation Added: - APPROVED_REJECTED_QUANTITIES_ANALYSIS.md - Old app logic analysis - DATABASE_TRIGGERS_IMPLEMENTATION.md - v2 implementation guide - WAREHOUSE_INVENTORY_IMPLEMENTATION.md - Inventory view feature Files Modified: - initialize_db.py: Added create_triggers() function and call in main() - Documentation: 3 comprehensive guides for database and inventory management Quality Metrics: - Triggers maintain legacy compatibility - Automatic calculation ensures data consistency - Performance optimized at database level - Comprehensive testing documented
500 lines
14 KiB
Markdown
500 lines
14 KiB
Markdown
# 🏭 Warehouse Inventory - CP Articles View Implementation
|
|
|
|
**Date:** January 30, 2026
|
|
**Status:** ✅ Implemented and Deployed
|
|
**Feature:** CP Article Inventory with Box & Location Tracking
|
|
|
|
---
|
|
|
|
## 📋 Overview
|
|
|
|
Implemented a comprehensive warehouse inventory view that allows users to:
|
|
- View all CP articles scanned in the FG Scan module
|
|
- Track which boxes contain specific CP codes
|
|
- View warehouse locations for each box
|
|
- Search by CP code (8 digits or full 15-character code)
|
|
- Search by box number
|
|
- View detailed information for each CP code variation
|
|
- Filter and sort entries with latest entries displayed first
|
|
|
|
---
|
|
|
|
## 🗄️ Database Structure Understanding
|
|
|
|
### scanfg_orders Table (Extended Schema)
|
|
|
|
```sql
|
|
CREATE TABLE scanfg_orders (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
operator_code VARCHAR(50), -- Person who scanned (e.g., "OP01")
|
|
CP_full_code VARCHAR(50), -- Full CP code (e.g., "CP00000001-0001")
|
|
OC1_code VARCHAR(50), -- OC1 code
|
|
OC2_code VARCHAR(50), -- OC2 code
|
|
quality_code VARCHAR(10), -- Quality status (0=Rejected, 1=Approved)
|
|
date DATE, -- Scan date
|
|
time TIME, -- Scan time
|
|
approved_quantity INT, -- Approved count
|
|
rejected_quantity INT, -- Rejected count
|
|
box_id BIGINT, -- FK: Reference to boxes_crates table
|
|
location_id BIGINT, -- FK: Reference to warehouse_locations table
|
|
created_at TIMESTAMP,
|
|
|
|
-- Indexes for fast querying
|
|
INDEX idx_cp_code (CP_full_code),
|
|
INDEX idx_operator (operator_code),
|
|
INDEX idx_date (date),
|
|
INDEX idx_box_id (box_id),
|
|
INDEX idx_location_id (location_id),
|
|
|
|
-- Foreign Keys
|
|
FOREIGN KEY (box_id) REFERENCES boxes_crates(id) ON DELETE SET NULL,
|
|
FOREIGN KEY (location_id) REFERENCES warehouse_locations(id) ON DELETE SET NULL
|
|
);
|
|
```
|
|
|
|
### CP Code Structure
|
|
|
|
From the old application and current implementation:
|
|
|
|
- **CP Base (8 digits):** `CP00000001`
|
|
- Used to group related entries
|
|
- Represents the core product/order reference
|
|
|
|
- **CP Full Code (15 characters):** `CP00000001-0001`
|
|
- Includes 4-digit suffix after hyphen
|
|
- Can have multiple entries (e.g., `-0001`, `-0002`, `-0003`)
|
|
- Different suffixes can be in different boxes and locations
|
|
|
|
### Relationships
|
|
|
|
```
|
|
scanfg_orders (many)
|
|
├─→ boxes_crates (one)
|
|
│ └─→ warehouse_locations (one)
|
|
│
|
|
└─→ warehouse_locations (one) [Direct location assignment]
|
|
```
|
|
|
|
---
|
|
|
|
## ✨ Features Implemented
|
|
|
|
### 1. Backend Functions (warehouse.py)
|
|
|
|
#### `get_cp_inventory_list(limit=100, offset=0)`
|
|
- Returns all CP articles with aggregated data
|
|
- Groups by CP base code and box
|
|
- Shows latest entries first
|
|
- Returns: box_number, location_code, total_entries, total_approved, total_rejected, latest_date, latest_time
|
|
|
|
#### `search_cp_code(cp_code_search)`
|
|
- Searches by full CP code or CP base (8 digits)
|
|
- Handles hyphen-separated format
|
|
- Returns all matching entries with box and location info
|
|
|
|
#### `search_by_box_number(box_number_search)`
|
|
- Finds all CP codes in a specific box
|
|
- Shows operator, quality code, quantities
|
|
- Returns full details for each entry
|
|
|
|
#### `get_cp_details(cp_code)`
|
|
- Gets all variations of a CP code (all suffixes)
|
|
- Shows each entry's operator, quality status, box, location
|
|
- Useful for traceability and detailed audit trail
|
|
|
|
### 2. API Endpoints (routes.py)
|
|
|
|
#### `GET /warehouse/api/cp-inventory`
|
|
- List all CP inventory items
|
|
- Pagination support (limit, offset)
|
|
- Response includes count and metadata
|
|
|
|
**Example Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"inventory": [
|
|
{
|
|
"id": 1,
|
|
"CP_full_code": "CP00000001-0001",
|
|
"cp_base": "CP00000001",
|
|
"total_entries": 1,
|
|
"box_id": 5,
|
|
"box_number": "BOX001",
|
|
"location_code": "FG_INCOMING",
|
|
"total_approved": 10,
|
|
"total_rejected": 0,
|
|
"latest_date": "2026-01-30",
|
|
"latest_time": "14:30:15"
|
|
}
|
|
],
|
|
"count": 25,
|
|
"limit": 500,
|
|
"offset": 0
|
|
}
|
|
```
|
|
|
|
#### `POST /warehouse/api/search-cp`
|
|
- Search by CP code
|
|
- Accepts: `{ "cp_code": "CP00000001" }`
|
|
- Returns matching entries grouped by box
|
|
|
|
#### `POST /warehouse/api/search-cp-box`
|
|
- Search by box number
|
|
- Accepts: `{ "box_number": "BOX001" }`
|
|
- Returns all CP entries in that specific box
|
|
|
|
#### `GET /warehouse/api/cp-details/<cp_code>`
|
|
- Get detailed info for a CP code (8 digits)
|
|
- Shows all variations with different suffixes
|
|
- Returns all scans, locations, and box assignments
|
|
|
|
### 3. Frontend Interface (inventory.html)
|
|
|
|
#### Search Section
|
|
- **CP Code Search:** Enter full code or base code
|
|
- Example: "CP00000001" or "CP00000001-0001"
|
|
- Wildcard search for partial matches
|
|
|
|
- **Box Number Search:** Find all CP codes in a box
|
|
- Example: "BOX001"
|
|
- Shows all related entries
|
|
|
|
#### Results Table
|
|
Columns displayed (sorted by latest first):
|
|
- **CP Code (Base):** Base 8-digit CP code (badge)
|
|
- **CP Full Code:** Complete 15-character code with suffix
|
|
- **Box Number:** Which box contains this item
|
|
- **Location:** Warehouse location code
|
|
- **Total Entries:** How many variations exist
|
|
- **Approved Qty:** Total approved quantity
|
|
- **Rejected Qty:** Total rejected quantity
|
|
- **Latest Date:** Most recent scan date
|
|
- **Latest Time:** Most recent scan time
|
|
- **Actions:** View details button
|
|
|
|
#### Detail Modal
|
|
- Displays all variations of a CP code
|
|
- Shows detailed table with:
|
|
- CP Full Code
|
|
- Operator Code
|
|
- Quality status (Approved/Rejected)
|
|
- Box assignment
|
|
- Location
|
|
- Scan date and time
|
|
|
|
---
|
|
|
|
## 🔄 Data Flow
|
|
|
|
### 1. CP Code Entry Flow
|
|
```
|
|
FG Scan Module (/quality/fg-scan)
|
|
↓
|
|
User scans CP code (CP + 8 digits + hyphen + 4 digits)
|
|
↓
|
|
Scan saved to scanfg_orders table
|
|
↓
|
|
Optional: Assign to box (box_id)
|
|
↓
|
|
Optional: Update location (location_id)
|
|
```
|
|
|
|
### 2. Inventory Query Flow
|
|
```
|
|
User visits /warehouse/inventory
|
|
↓
|
|
loadInventory() called (JavaScript)
|
|
↓
|
|
Fetch /warehouse/api/cp-inventory
|
|
↓
|
|
Database aggregates all scanfg_orders entries
|
|
↓
|
|
Groups by CP base + box
|
|
↓
|
|
Returns sorted by latest date (DESC)
|
|
↓
|
|
Render in table with all details
|
|
```
|
|
|
|
### 3. Search Flow
|
|
```
|
|
User searches for CP code "CP00000001"
|
|
↓
|
|
JavaScript sends POST to /warehouse/api/search-cp
|
|
↓
|
|
Backend searches for REPLACE(CP_full_code, '-', '') LIKE 'CP00000001%'
|
|
↓
|
|
Returns all matching entries
|
|
↓
|
|
Frontend renders results table
|
|
↓
|
|
User can click "View Details" for each entry
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Query Examples
|
|
|
|
### Get all CP inventory grouped by base code and box
|
|
```sql
|
|
SELECT
|
|
s.CP_full_code,
|
|
SUBSTRING(s.CP_full_code, 1, 10) as cp_base,
|
|
COUNT(*) as total_entries,
|
|
s.box_id,
|
|
bc.box_number,
|
|
wl.location_code,
|
|
MAX(s.date) as latest_date,
|
|
MAX(s.time) as latest_time,
|
|
SUM(s.approved_quantity) as total_approved,
|
|
SUM(s.rejected_quantity) as total_rejected
|
|
FROM scanfg_orders s
|
|
LEFT JOIN boxes_crates bc ON s.box_id = bc.id
|
|
LEFT JOIN warehouse_locations wl ON s.location_id = wl.id
|
|
GROUP BY SUBSTRING(s.CP_full_code, 1, 10), s.box_id
|
|
ORDER BY MAX(s.created_at) DESC;
|
|
```
|
|
|
|
### Search for specific CP code
|
|
```sql
|
|
SELECT * FROM scanfg_orders
|
|
WHERE REPLACE(CP_full_code, '-', '') LIKE 'CP00000001%'
|
|
ORDER BY created_at DESC;
|
|
```
|
|
|
|
### Find all CP codes in a box
|
|
```sql
|
|
SELECT s.*, bc.box_number, wl.location_code
|
|
FROM scanfg_orders s
|
|
LEFT JOIN boxes_crates bc ON s.box_id = bc.id
|
|
LEFT JOIN warehouse_locations wl ON s.location_id = wl.id
|
|
WHERE bc.box_number LIKE '%BOX001%'
|
|
ORDER BY s.created_at DESC;
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Usage Guide
|
|
|
|
### Accessing the Inventory View
|
|
1. Navigate to Warehouse Module
|
|
2. Click "Inventory" option
|
|
3. Page loads with all CP articles (latest first)
|
|
|
|
### Searching by CP Code
|
|
1. Enter CP code in "Search by CP Code" field
|
|
- Can enter: "CP00000001" or "CP00000001-0001"
|
|
- Can enter partial: "CP000" for wildcard search
|
|
2. Click "Search CP" button
|
|
3. Results update in real-time
|
|
|
|
### Searching by Box Number
|
|
1. Enter box number in "Search by Box Number" field
|
|
- Example: "BOX001"
|
|
2. Click "Search Box" button
|
|
3. View all CP codes in that box
|
|
|
|
### Viewing CP Details
|
|
1. Click the "eye" icon in the Actions column
|
|
2. Modal opens showing:
|
|
- All variations of that CP code
|
|
- Operator who scanned each one
|
|
- Quality status for each
|
|
- Box and location assignments
|
|
- Detailed timestamp info
|
|
|
|
### Clearing Searches
|
|
1. Click "Clear" button next to search field
|
|
2. Returns to full inventory view
|
|
3. Shows all latest entries
|
|
|
|
---
|
|
|
|
## 📈 Performance Considerations
|
|
|
|
### Indexes Used
|
|
- `idx_cp_code` on CP_full_code
|
|
- `idx_box_id` for box lookups
|
|
- `idx_location_id` for location filtering
|
|
- `idx_date` for date-range queries
|
|
- `idx_operator` for operator tracking
|
|
|
|
### Query Optimization
|
|
- Group aggregation reduces result set size
|
|
- Indexes on foreign keys for fast joins
|
|
- Limit 500 default to prevent large transfers
|
|
- Latest entries first using created_at DESC
|
|
|
|
### Scalability
|
|
For large datasets (100,000+ records):
|
|
- Consider table partitioning by date
|
|
- Archive old scans to separate table
|
|
- Materialized views for common reports
|
|
- Consider caching for frequently searched CPs
|
|
|
|
---
|
|
|
|
## 🔐 Security & Permissions
|
|
|
|
### Access Control
|
|
- User must be logged in (session check)
|
|
- Returns 401 Unauthorized if not authenticated
|
|
- All routes check `if 'user_id' not in session`
|
|
|
|
### Data Validation
|
|
- CP code search minimum 2 characters
|
|
- Box number search requires non-empty string
|
|
- Pagination limits (max 1000 records)
|
|
- SQL injection prevented via parameterized queries
|
|
|
|
---
|
|
|
|
## 📋 Implementation Details
|
|
|
|
### Files Modified
|
|
1. **app/modules/warehouse/warehouse.py**
|
|
- Added 4 new functions for CP inventory operations
|
|
- Added pymysql import for cursor operations
|
|
|
|
2. **app/modules/warehouse/routes.py**
|
|
- Updated imports to include new warehouse functions
|
|
- Added 4 new API endpoints
|
|
- Integrated authentication checks
|
|
|
|
3. **app/templates/modules/warehouse/inventory.html**
|
|
- Complete rewrite with interactive interface
|
|
- Added JavaScript for real-time search
|
|
- Added detail modal for viewing CP variations
|
|
- Responsive design with Bootstrap styling
|
|
|
|
### Code Statistics
|
|
- **Backend Functions:** 4 new functions
|
|
- **API Endpoints:** 4 new routes
|
|
- **Frontend Lines:** 600+ lines (HTML + CSS + JS)
|
|
- **Total Code Added:** ~800 lines
|
|
|
|
---
|
|
|
|
## ✅ Testing Checklist
|
|
|
|
- [x] Backend functions execute without errors
|
|
- [x] API endpoints return proper JSON responses
|
|
- [x] Search by CP code works with full and partial codes
|
|
- [x] Search by box number finds all related CP entries
|
|
- [x] Latest entries display first (ORDER BY DESC)
|
|
- [x] CP details modal shows all variations
|
|
- [x] Pagination works with limit/offset
|
|
- [x] Error messages display properly
|
|
- [x] Loading indicators appear during API calls
|
|
- [x] Authentication checks work
|
|
- [x] Database joins with boxes_crates and warehouse_locations
|
|
- [x] Status messages show search results count
|
|
|
|
---
|
|
|
|
## 🔄 Integration Points
|
|
|
|
### With FG Scan Module
|
|
- Reads scanfg_orders entries created by FG Scan
|
|
- Shows CP codes as they are scanned
|
|
- Tracks box assignments from assign_cp_to_box feature
|
|
|
|
### With Warehouse Module
|
|
- Uses warehouse_locations for location display
|
|
- Uses boxes_crates for box information
|
|
- Part of warehouse management workflow
|
|
|
|
### With Quality Module
|
|
- Shows quality_code status (approved/rejected)
|
|
- Tracks operator who scanned each item
|
|
- Provides quality metrics
|
|
|
|
---
|
|
|
|
## 🚀 Future Enhancements
|
|
|
|
1. **Export/Download**
|
|
- Export search results to CSV/Excel
|
|
- Print inventory reports
|
|
|
|
2. **Advanced Filtering**
|
|
- Filter by date range
|
|
- Filter by quality status (approved/rejected)
|
|
- Filter by operator code
|
|
- Filter by location
|
|
|
|
3. **Analytics**
|
|
- Generate warehouse occupancy reports
|
|
- CP code aging (how long in warehouse)
|
|
- Location utilization statistics
|
|
|
|
4. **Real-Time Updates**
|
|
- WebSocket for live inventory updates
|
|
- Automatic refresh when new scans added
|
|
- Real-time location change notifications
|
|
|
|
5. **Barcode Generation**
|
|
- Generate barcodes for CP codes
|
|
- Generate warehouse location labels
|
|
- Print bulk labels for organization
|
|
|
|
6. **Mobile Interface**
|
|
- Responsive inventory lookup
|
|
- Mobile-optimized search
|
|
- QR code scanning support
|
|
|
|
---
|
|
|
|
## 📞 Support & Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Issue:** No results when searching
|
|
- **Solution:** Check CP code format (must include "CP")
|
|
- Ensure items exist in scanfg_orders table
|
|
- Try searching for partial CP code
|
|
|
|
**Issue:** Box shows as "No Box"
|
|
- **Solution:** Item may not be assigned to box yet
|
|
- Check box_id field in scanfg_orders
|
|
- Assign to box through FG Scan assign feature
|
|
|
|
**Issue:** Location shows as "No Location"
|
|
- **Solution:** Box may not have location assigned
|
|
- Assign location in warehouse locations module
|
|
- Update box location through inventory interface
|
|
|
|
**Issue:** Database errors
|
|
- **Solution:** Ensure boxes_crates table exists
|
|
- Ensure warehouse_locations table exists
|
|
- Check database connection parameters
|
|
|
|
---
|
|
|
|
## 📝 Documentation Files
|
|
|
|
Related documentation:
|
|
- [SCANFG_ORDERS_BOX_TRACKING.md](SCANFG_ORDERS_BOX_TRACKING.md) - Box tracking details
|
|
- [BOXES_IMPLEMENTATION_DETAILS.md](BOXES_IMPLEMENTATION_DETAILS.md) - Box feature docs
|
|
- [TRACEABILITY_WORKFLOW_ANALYSIS.md](TRACEABILITY_WORKFLOW_ANALYSIS.md) - CP traceability flow
|
|
|
|
---
|
|
|
|
## ✨ Summary
|
|
|
|
The Warehouse Inventory CP Articles view provides a complete solution for:
|
|
- **Viewing:** All CP articles scanned in FG module
|
|
- **Tracking:** Which boxes and locations contain each CP
|
|
- **Searching:** Quick lookup by CP code or box number
|
|
- **Analyzing:** Detailed information for traceability
|
|
- **Managing:** Latest entries displayed for efficient warehouse operations
|
|
|
|
This feature bridges the gap between FG Scanning and warehouse operations, enabling complete product traceability from scan to storage location.
|
|
|
|
---
|
|
|
|
**Last Updated:** January 30, 2026
|
|
**Version:** 1.0
|
|
**Status:** Production Ready ✅
|