From 2ee5a11d1a80e6bf1a1aa7af11d8c69c325fd64a Mon Sep 17 00:00:00 2001 From: "admin.suherdy" Date: Thu, 27 Nov 2025 10:08:15 +0700 Subject: [PATCH] remove files --- ARCHITECTURE.md | 402 ------------------------------------- DATE_FORMAT_FIX_SUMMARY.md | 287 -------------------------- 2 files changed, 689 deletions(-) delete mode 100644 ARCHITECTURE.md delete mode 100644 DATE_FORMAT_FIX_SUMMARY.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md deleted file mode 100644 index f60145c..0000000 --- a/ARCHITECTURE.md +++ /dev/null @@ -1,402 +0,0 @@ -# Architecture and Flow Diagrams - -## System Architecture - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Product Configuration │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ product.template │ │ -│ │ - lot_sequence_id (Many2one to ir.sequence) │ │ -│ │ - serial_prefix_format (Char, computed) │ │ -│ │ - next_serial (Char, computed) │ │ -│ └──────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Lot Generation Triggers │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ -│ │ Incoming │ │ Manufacturing│ │ Inventory │ │ -│ │ Receipts │ │ Orders │ │ Adjustments │ │ -│ │ (stock.move) │ │(mrp.production)│ │ (stock.quant) │ │ -│ └──────────────┘ └──────────────┘ └──────────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Optimization Layer │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ Smart Threshold Detection │ │ -│ │ if count > 10: │ │ -│ │ use batch optimization │ │ -│ │ else: │ │ -│ │ use standard generation │ │ -│ └──────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Batch Processing Engine │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ 1. Group lots by product │ │ -│ │ 2. Allocate sequences in batch (PostgreSQL) │ │ -│ │ 3. Format lot names │ │ -│ │ 4. Create lot records in batch │ │ -│ └──────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Database Layer │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ PostgreSQL │ │ -│ │ - ir_sequence (sequence numbers) │ │ -│ │ - stock_lot (lot records) │ │ -│ │ - generate_series() for batch allocation │ │ -│ └──────────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -## Batch Sequence Allocation Flow - -### Old Method (Slow) -``` -┌──────────────┐ -│ Need 500 lots│ -└──────┬───────┘ - │ - ▼ -┌──────────────────────────────────────┐ -│ Loop 500 times: │ -│ ┌────────────────────────────────┐ │ -│ │ 1. Call seq.next_by_id() │ │ ◄── 500 DB queries -│ │ 2. Wait for DB response │ │ -│ │ 3. Format lot name │ │ -│ │ 4. Create single lot record │ │ ◄── 500 DB inserts -│ └────────────────────────────────┘ │ -└──────────────────────────────────────┘ - │ - ▼ -┌──────────────┐ -│ 500 lots │ -│ Time: ~60s │ -└──────────────┘ -``` - -### New Method (Fast) -``` -┌──────────────┐ -│ Need 500 lots│ -└──────┬───────┘ - │ - ▼ -┌──────────────────────────────────────┐ -│ Batch Allocation: │ -│ ┌────────────────────────────────┐ │ -│ │ 1. Single DB query: │ │ ◄── 1 DB query -│ │ SELECT nextval(seq) │ │ -│ │ FROM generate_series(1,500) │ │ -│ │ 2. Format all 500 names │ │ -│ │ 3. Batch create 500 records │ │ ◄── 1 DB insert -│ └────────────────────────────────┘ │ -└──────────────────────────────────────┘ - │ - ▼ -┌──────────────┐ -│ 500 lots │ -│ Time: ~8s │ -└──────────────┘ -``` - -## Inventory Adjustment Flow - -### Without Auto-Generation (Old) -``` -┌─────────────────────┐ -│ User creates │ -│ inventory adjustment│ -│ for 100 units │ -└──────────┬──────────┘ - │ - ▼ -┌─────────────────────┐ -│ User must manually │ -│ create 100 lots: │ -│ - Enter each name │ -│ - One by one │ -│ - Time: ~10 min │ -└──────────┬──────────┘ - │ - ▼ -┌─────────────────────┐ -│ Apply inventory │ -└─────────────────────┘ -``` - -### With Auto-Generation (New) -``` -┌─────────────────────┐ -│ User creates │ -│ inventory adjustment│ -│ for 100 units │ -└──────────┬──────────┘ - │ - ▼ -┌─────────────────────┐ -│ System detects: │ -│ - Product tracked │ -│ - No lot assigned │ -│ - Custom sequence │ -└──────────┬──────────┘ - │ - ▼ -┌─────────────────────┐ -│ Auto-generate 100 │ -│ lots using batch │ -│ optimization │ -│ Time: ~3s │ -└──────────┬──────────┘ - │ - ▼ -┌─────────────────────┐ -│ Apply inventory │ -│ (lots already ready)│ -└─────────────────────┘ -``` - -## Code Flow Diagram - -### Incoming Receipt with 500 Serials - -``` -User clicks "Generate Serials" - │ - ▼ -stock.move.action_generate_lot_line_vals() - │ - ├─► Check: count > 10? ──► YES - │ │ - │ ▼ - │ _allocate_sequence_batch(seq, 500) - │ │ - │ ├─► Execute SQL: - │ │ SELECT nextval(seq) - │ │ FROM generate_series(1, 500) - │ │ - │ ├─► Format 500 lot names - │ │ (prefix + number + suffix) - │ │ - │ └─► Return 500 lot names - │ - ▼ -stock.move._create_lot_ids_from_move_line_vals() - │ - ├─► Group by product - │ - ├─► Prepare 500 lot values - │ [{'name': 'SN-0001', ...}, ...] - │ - ▼ -stock.lot.create([500 lot values]) - │ - ├─► Single batch insert - │ - └─► Return 500 lot records - │ - ▼ -Lots assigned to move lines - │ - ▼ -User validates receipt -``` - -## Performance Comparison - -### Database Operations - -#### Old Method (500 lots) -``` -┌─────────────────────────────────────┐ -│ Sequence Allocation │ -│ ┌─────┐ ┌─────┐ ┌─────┐ │ -│ │ Q1 │ │ Q2 │ ... │ Q500│ │ 500 queries -│ └─────┘ └─────┘ └─────┘ │ -│ │ -│ Lot Creation │ -│ ┌─────┐ ┌─────┐ ┌─────┐ │ -│ │ C1 │ │ C2 │ ... │ C500│ │ 500 creates -│ └─────┘ └─────┘ └─────┘ │ -│ │ -│ Total: 1000 DB operations │ -│ Time: ~60 seconds │ -└─────────────────────────────────────┘ -``` - -#### New Method (500 lots) -``` -┌─────────────────────────────────────┐ -│ Sequence Allocation │ -│ ┌───────────────────────────────┐ │ -│ │ Single Query (generate_series)│ │ 1 query -│ └───────────────────────────────┘ │ -│ │ -│ Lot Creation │ -│ ┌───────────────────────────────┐ │ -│ │ Batch Create (500 records) │ │ 1 create -│ └───────────────────────────────┘ │ -│ │ -│ Total: 2 DB operations │ -│ Time: ~8 seconds │ -└─────────────────────────────────────┘ -``` - -### Speedup Factor -``` -Old: 1000 operations / 60 seconds = 16.7 ops/sec -New: 2 operations / 8 seconds = 0.25 ops/sec - -But creates 500 lots in both cases: -Old: 500 lots / 60 sec = 8.3 lots/sec -New: 500 lots / 8 sec = 62.5 lots/sec - -Speedup: 62.5 / 8.3 = 7.5x faster -``` - -## Module Dependencies - -``` -┌─────────────────────────────────────────────────────────┐ -│ product_lot_sequence_per_product │ -│ │ -│ Depends on: │ -│ ┌──────────┐ ┌──────────┐ │ -│ │ stock │ │ mrp │ │ -│ │ (core) │ │ (core) │ │ -│ └────┬─────┘ └────┬─────┘ │ -│ │ │ │ -│ ├─► stock.move ├─► mrp.production │ -│ ├─► stock.move.line │ │ -│ ├─► stock.lot │ │ -│ ├─► stock.quant │ │ -│ └─► stock.picking │ │ -│ │ │ -└────────────────────────────┴───────────────────────────┘ -``` - -## Data Model - -``` -┌─────────────────────────────────────────────────────────┐ -│ product.template │ -│ ┌─────────────────────────────────────────────────────┐│ -│ │ id : Integer ││ -│ │ name : Char ││ -│ │ tracking : Selection (none/lot/serial) ││ -│ │ lot_sequence_id : Many2one(ir.sequence) ││ -│ │ serial_prefix_format : Char (computed) ││ -│ │ next_serial : Char (computed) ││ -│ └─────────────────────────────────────────────────────┘│ -└────────────────────┬────────────────────────────────────┘ - │ Many2one - ▼ -┌─────────────────────────────────────────────────────────┐ -│ ir.sequence │ -│ ┌─────────────────────────────────────────────────────┐│ -│ │ id : Integer ││ -│ │ name : Char ││ -│ │ code : Char ('stock.lot.serial') ││ -│ │ prefix : Char (e.g., 'SN-') ││ -│ │ suffix : Char ││ -│ │ padding : Integer (e.g., 7) ││ -│ │ number_next_actual: Integer ││ -│ └─────────────────────────────────────────────────────┘│ -└────────────────────┬────────────────────────────────────┘ - │ Used by - ▼ -┌─────────────────────────────────────────────────────────┐ -│ stock.lot │ -│ ┌─────────────────────────────────────────────────────┐│ -│ │ id : Integer ││ -│ │ name : Char (e.g., 'SN-0000001') ││ -│ │ product_id : Many2one(product.product) ││ -│ │ company_id : Many2one(res.company) ││ -│ └─────────────────────────────────────────────────────┘│ -└─────────────────────────────────────────────────────────┘ -``` - -## Optimization Decision Tree - -``` - ┌─────────────────┐ - │ Need to generate│ - │ N lot numbers │ - └────────┬────────┘ - │ - ▼ - ┌─────────────────┐ - │ Is N > 10? │ - └────────┬────────┘ - │ - ┌────────────┴────────────┐ - │ │ - YES NO - │ │ - ▼ ▼ - ┌───────────────────────┐ ┌──────────────────┐ - │ Use Batch Optimization│ │ Use Standard │ - │ │ │ Generation │ - │ - Single DB query │ │ │ - │ - generate_series() │ │ - Loop N times │ - │ - Batch create │ │ - seq.next_by_id()│ - │ │ │ - Individual │ - │ Time: O(1) │ │ creates │ - │ Fast for large N │ │ │ - └───────────────────────┘ │ Time: O(N) │ - │ Fine for small N │ - └──────────────────┘ -``` - -## Concurrency Handling - -``` -┌─────────────────────────────────────────────────────────┐ -│ Multiple Users Generating Lots Simultaneously │ -└─────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────┐ -│ PostgreSQL Sequence (ir_sequence_XXX) │ -│ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ User A │ │ User B │ │ User C │ │ -│ │ nextval()│ │ nextval()│ │ nextval()│ │ -│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ -│ │ │ │ │ -│ ├─────────────┼─────────────┤ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌────────────────────────────────────┐ │ -│ │ Atomic sequence increment │ │ -│ │ (Database-level locking) │ │ -│ └────────────────────────────────────┘ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ 1001 1002 1003 │ -│ │ -│ No conflicts - each gets unique number │ -└─────────────────────────────────────────────────────────┘ -``` - -## Summary - -The architecture provides: - -1. **Layered Design**: Clear separation between configuration, triggers, optimization, and database -2. **Smart Optimization**: Automatic detection and application of batch processing -3. **Scalability**: Handles from 1 to 500,000+ lots efficiently -4. **Concurrency Safety**: Database-level sequence management prevents conflicts -5. **Backward Compatibility**: Works with existing Odoo infrastructure -6. **Extensibility**: Easy to add new triggers or optimization strategies - -The key innovation is the **batch processing layer** that intercepts lot generation requests and optimizes them transparently, providing massive performance improvements without changing the user experience. diff --git a/DATE_FORMAT_FIX_SUMMARY.md b/DATE_FORMAT_FIX_SUMMARY.md deleted file mode 100644 index 9ab2623..0000000 --- a/DATE_FORMAT_FIX_SUMMARY.md +++ /dev/null @@ -1,287 +0,0 @@ -# Date Format Code Fix - Summary - -## Issue - -The batch sequence allocation optimization was not properly handling date format codes like `%(y)s`, `%(month)s`, `%(day)s` in the sequence prefix/suffix. This resulted in literal strings being used instead of actual date values. - -**Example Problem**: -- Configuration: `%(y)s%(month)s%(day)s` -- Expected: `2411200000001` (for Nov 20, 2024) -- Actual: `%(y)s%(month)s%(day)s0000001` (literal string) - -## Root Cause - -The `_allocate_sequence_batch()` method was directly using `sequence.prefix` and `sequence.suffix` without interpolating the date format codes. The standard `seq.next_by_id()` method handles this interpolation automatically, but our optimized batch method bypassed it. - -## Solution - -Updated three methods to properly handle date format codes: - -### 1. `stock_lot._allocate_sequence_batch()` -Added date interpolation logic before formatting lot names: - -```python -from datetime import datetime -now = datetime.now() - -# Build interpolation dictionary (same as Odoo's ir.sequence) -interpolation_dict = { - 'year': now.strftime('%Y'), - 'y': now.strftime('%y'), - 'month': now.strftime('%m'), - 'day': now.strftime('%d'), - 'doy': now.strftime('%j'), - 'woy': now.strftime('%W'), - 'weekday': now.strftime('%w'), - 'h24': now.strftime('%H'), - 'h12': now.strftime('%I'), - 'min': now.strftime('%M'), - 'sec': now.strftime('%S'), -} - -# Format prefix and suffix with date codes -prefix = (sequence.prefix or '') % interpolation_dict if sequence.prefix else '' -suffix = (sequence.suffix or '') % interpolation_dict if sequence.suffix else '' - -# Then format lot names with interpolated prefix/suffix -lot_name = '{}{:0{}d}{}'.format(prefix, seq_num, sequence.padding, suffix) -``` - -### 2. `stock_move._allocate_sequence_batch()` -Applied the same fix to the duplicate method in `stock_move.py`. - -### 3. `product_template._compute_next_serial()` -Updated to show correct preview of next lot number with date codes: - -```python -# Format prefix and suffix with date codes -prefix = (seq.prefix or '') % interpolation_dict if seq.prefix else '' -suffix = (seq.suffix or '') % interpolation_dict if seq.suffix else '' - -template.next_serial = '{}{:0{}d}{}'.format( - prefix, - seq.number_next_actual, - seq.padding, - suffix -) -``` - -## Files Modified - -1. **customaddons/product_lot_sequence_per_product/models/stock_lot.py** - - Enhanced `_allocate_sequence_batch()` with date interpolation - -2. **customaddons/product_lot_sequence_per_product/models/stock_move.py** - - Enhanced `_allocate_sequence_batch()` with date interpolation - -3. **customaddons/product_lot_sequence_per_product/models/product_template.py** - - Enhanced `_compute_next_serial()` with date interpolation - -4. **customaddons/product_lot_sequence_per_product/tests/test_date_format.py** (new) - - Comprehensive test suite for date format codes - -5. **customaddons/product_lot_sequence_per_product/DATE_FORMAT_GUIDE.md** (new) - - Complete guide for using date format codes - -6. **customaddons/product_lot_sequence_per_product/CHANGELOG.md** - - Added version 1.1.1 with fix details - -7. **customaddons/product_lot_sequence_per_product/__manifest__.py** - - Updated version to 1.1.1 - -## Supported Date Format Codes - -| Code | Description | Example | -|------|-------------|---------| -| `%(year)s` | Full year (4 digits) | 2024 | -| `%(y)s` | Short year (2 digits) | 24 | -| `%(month)s` | Month (2 digits) | 11 | -| `%(day)s` | Day of month (2 digits) | 20 | -| `%(doy)s` | Day of year (3 digits) | 325 | -| `%(woy)s` | Week of year (2 digits) | 47 | -| `%(weekday)s` | Day of week | 4 | -| `%(h24)s` | Hour (24-hour) | 14 | -| `%(h12)s` | Hour (12-hour) | 02 | -| `%(min)s` | Minute | 30 | -| `%(sec)s` | Second | 45 | - -## Testing - -### Test Suite Added - -**File**: `tests/test_date_format.py` - -**Tests**: -1. `test_date_format_year_month_day` - Tests `%(y)s%(month)s%(day)s` format -2. `test_date_format_full_year` - Tests `%(year)s` format -3. `test_date_format_batch_generation` - Tests batch generation with date codes -4. `test_date_format_complex` - Tests complex multi-code formats -5. `test_date_format_with_suffix` - Tests date codes with suffix -6. `test_date_format_inventory_adjustment` - Tests inventory adjustments -7. `test_date_format_all_codes` - Tests all available format codes - -### Running Tests - -```bash -# Run all date format tests -odoo-bin -c odoo.conf -d test_db --test-tags product_lot_sequence_per_product.test_date_format - -# Run all module tests -odoo-bin -c odoo.conf -d test_db --test-tags product_lot_sequence_per_product -``` - -## Usage Examples - -### Example 1: Year-Month-Day -**Configuration**: `%(y)s%(month)s%(day)s` -**Result**: `2411200000001` (for Nov 20, 2024) - -### Example 2: Full Date with Separators -**Configuration**: `LOT-%(year)s-%(month)s-%(day)s-` -**Result**: `LOT-2024-11-20-0000001` - -### Example 3: Week-Based -**Configuration**: `WK%(y)s%(woy)s-` -**Result**: `WK2447-0000001` (Week 47 of 2024) - -## Performance Impact - -**No performance degradation**: -- Date interpolation happens once per batch (not per lot) -- Adds ~0.001 seconds to batch generation -- Negligible compared to database operations -- Batch optimization still provides 8-10x speedup - -## Verification - -### Before Fix -``` -Configuration: %(y)s%(month)s%(day)s -Generated: %(y)s%(month)s%(day)s0000001 ❌ Wrong -``` - -### After Fix -``` -Configuration: %(y)s%(month)s%(day)s -Generated: 2411200000001 ✓ Correct -``` - -## Backward Compatibility - -✓ Fully backward compatible -✓ No breaking changes -✓ Existing sequences without date codes work as before -✓ Only affects sequences using date format codes - -## Upgrade Instructions - -### For Existing Installations - -1. **Backup database**: - ```bash - pg_dump your_database > backup_before_1.1.1.sql - ``` - -2. **Update module files**: - ```bash - cp -r product_lot_sequence_per_product /path/to/odoo/customaddons/ - ``` - -3. **Upgrade module**: - ```bash - odoo-bin -c odoo.conf -d your_database -u product_lot_sequence_per_product --stop-after-init - ``` - -4. **Verify**: - - Check a product with date format codes - - Verify "Next Number" field shows correct date - - Generate a test lot to confirm - -### For New Installations - -Simply install version 1.1.1 - date format codes work out of the box. - -## Documentation - -### New Documentation Added - -1. **DATE_FORMAT_GUIDE.md** - - Complete guide for date format codes - - Usage examples - - Best practices - - Troubleshooting - -2. **Test Suite** - - Comprehensive tests for all date codes - - Batch generation tests - - Integration tests - -3. **Updated CHANGELOG.md** - - Version 1.1.1 details - - Fix description - - Changed files list - -## Common Use Cases - -### Daily Production Batches -``` -Format: %(y)s%(month)s%(day)s -Result: 2411200000001, 2411200000002, ... -Next day: 2411210000001, 2411210000002, ... -``` - -### Monthly Inventory Cycles -``` -Format: LOT-%(year)s-%(month)s- -Result: LOT-2024-11-0000001, LOT-2024-11-0000002, ... -Next month: LOT-2024-12-0000001, ... -``` - -### Weekly Production Runs -``` -Format: WK%(woy)s-%(year)s- -Result: WK47-2024-0000001, WK47-2024-0000002, ... -Next week: WK48-2024-0000001, ... -``` - -## Troubleshooting - -### Issue: Still seeing literal `%(y)s` - -**Solution**: -1. Verify you're on version 1.1.1 or later -2. Restart Odoo after upgrade -3. Clear browser cache -4. Check sequence configuration - -### Issue: Wrong date values - -**Solution**: -1. Check server timezone -2. Verify Odoo timezone configuration -3. Check PostgreSQL timezone - -### Issue: Different dates in same batch - -**Explanation**: If batch generation crosses midnight, some lots may have different dates. This is expected behavior. - -**Solution**: Generate batches earlier in the day to avoid midnight crossover. - -## Summary - -The fix ensures that date format codes work correctly in all scenarios: - -✓ Single lot creation -✓ Batch generation (10+ lots) -✓ Very large batches (1000+ lots) -✓ Incoming receipts -✓ Manufacturing orders -✓ Inventory adjustments -✓ Manual lot creation - -All while maintaining the 8-10x performance improvement from batch optimization. - -**Version**: 1.1.1 -**Status**: Production Ready -**Testing**: Comprehensive test suite included -**Documentation**: Complete guide available