Stock Cut Stock Documentation¶
Overview¶
The Stock Cut Stock module (stock.cut.stock) represents available stock materials that can be used in cutting operations. Each record defines a stock width, available quantity, and whether it's a jumbo-sized piece.
Model Information¶
Model Name: stock.cut.stock
Display Name: (Not explicitly defined)
Key Fields: None (no unique constraint defined)
Features¶
- ❌ Audit logging enabled (
_audit_log) - ❌ Multi-company support (
company_id) - ❌ Full-text content search (
_content_search) - ❌ Unique key constraint
Field Reference¶
Header Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
cut_id |
Many2One | ✅ | Parent cutting operation (on_delete="cascade") |
width |
Decimal | ✅ | Width of the stock material |
qty |
Integer | ✅ | Number of stock pieces available |
jumbo |
Boolean | ❌ | Flag indicating jumbo-sized stock (special handling) |
pat_qty |
Integer | ❌ | Computed field showing how many pieces will be cut |
Understanding Jumbo Stock¶
The jumbo flag indicates whether a stock piece is jumbo-sized, which may have special handling requirements in the cutting operation or solver logic.
Potential uses: - Stock requiring special equipment to cut - Stock with different handling costs - Stock prioritization in optimization - Stock that should be used only when necessary
Field Reference¶
Relationship Fields¶
| Field | Type | Description |
|---|---|---|
cut_id |
Many2One | Links to stock.cut - Parent cutting operation |
Computed Fields¶
| Field | Type | Description |
|---|---|---|
pat_qty |
Integer | Number of stock pieces that will be cut based on patterns |
Computed Fields Functions¶
get_pat_qty(ids, context)¶
Calculates how many pieces of each stock width will be used based on generated cutting patterns.
Logic:
1. Retrieves the parent cutting operation
2. Iterates through all patterns
3. Sums the repeat count (num) for each stock width
4. Matches totals to each stock record by width
Returns: Dictionary mapping stock ID to quantity that will be cut
Example:
# Pattern 1: Stock width 300, num=10
# Pattern 2: Stock width 300, num=5
# Pattern 3: Stock width 250, num=8
# Stock record (width=300):
# pat_qty = 10 + 5 = 15 pieces will be cut
# Stock record (width=250):
# pat_qty = 8 pieces will be cut
API Methods¶
1. Create Stock Record¶
Method: create(vals, context)
Creates a new stock material record.
Parameters:
vals = {
"cut_id": 1, # Required: parent cutting operation
"width": 300.0, # Required: stock width
"qty": 25, # Required: available quantity
"jumbo": False # Optional: jumbo flag
}
Returns: int - New stock ID
Example:
# Create stock as part of cutting operation
cut_id = get_model("stock.cut").create({
"date": "2025-10-27",
"stock": [
("create", {
"width": 300.0,
"qty": 20,
"jumbo": False
}),
("create", {
"width": 400.0,
"qty": 10,
"jumbo": True # Special handling for large pieces
}),
("create", {
"width": 250.0,
"qty": 30,
"jumbo": False
})
],
"orders": [...]
})
Related Models¶
| Model | Relationship | Description |
|---|---|---|
stock.cut |
Many2One | Parent cutting operation |
stock.cut.pattern |
Related | Patterns that use this stock width |
Common Use Cases¶
Use Case 1: Check Stock Utilization¶
# After solving, verify stock usage
cut = get_model("stock.cut").browse(cut_id)
print("Stock Utilization:")
for stock in cut.stock:
utilization = (stock.pat_qty / stock.qty * 100) if stock.qty else 0
remaining = stock.qty - (stock.pat_qty or 0)
jumbo_flag = " [JUMBO]" if stock.jumbo else ""
print(f"Width {stock.width}mm{jumbo_flag}:")
print(f" Available: {stock.qty}")
print(f" Used: {stock.pat_qty}")
print(f" Remaining: {remaining}")
print(f" Utilization: {utilization:.1f}%")
print()
Use Case 2: Validate Stock Availability¶
# Before solving, ensure sufficient stock
def validate_stock_availability(cut_id):
cut = get_model("stock.cut").browse(cut_id)
# Rough estimate: check if total stock can fulfill orders
total_order_demand = sum(
order.width * order.qty
for order in cut.orders
)
total_stock_available = sum(
stock.width * stock.qty
for stock in cut.stock
)
if total_stock_available < total_order_demand:
shortfall = total_order_demand - total_stock_available
raise Exception(
f"Insufficient stock. Need {shortfall} more material units"
)
return True
# Validate before solving
validate_stock_availability(cut_id)
get_model("stock.cut").solve([cut_id])
Use Case 3: Prioritize Non-Jumbo Stock¶
# When multiple stock widths are available, prioritize standard sizes
def optimize_stock_usage(cut_id):
cut = get_model("stock.cut").browse(cut_id)
# Separate jumbo from standard stock
standard_stock = [s for s in cut.stock if not s.jumbo]
jumbo_stock = [s for s in cut.stock if s.jumbo]
print("Standard Stock:")
for s in standard_stock:
print(f" {s.width}mm × {s.qty}")
print("\nJumbo Stock (use if necessary):")
for s in jumbo_stock:
print(f" {s.width}mm × {s.qty}")
# After solving, check if jumbo was used
for s in jumbo_stock:
if s.pat_qty and s.pat_qty > 0:
print(f"⚠ Warning: Jumbo stock {s.width}mm was used ({s.pat_qty} pieces)")
Use Case 4: Identify Unused Stock¶
# Find stock that wasn't used in the cutting solution
cut = get_model("stock.cut").browse(cut_id)
unused_stock = []
for stock in cut.stock:
if not stock.pat_qty or stock.pat_qty == 0:
unused_stock.append(stock)
if unused_stock:
print("Unused Stock (consider removing from operation):")
for s in unused_stock:
jumbo_flag = " [JUMBO]" if s.jumbo else ""
print(f" {s.width}mm × {s.qty}{jumbo_flag}")
Use Case 5: Calculate Stock Value¶
# If stock has associated costs, calculate total value
def calculate_stock_value(cut_id, unit_prices):
"""
unit_prices: dict mapping width to price per unit
e.g., {300.0: 25.50, 250.0: 20.00}
"""
cut = get_model("stock.cut").browse(cut_id)
total_value = 0
for stock in cut.stock:
unit_price = unit_prices.get(stock.width, 0)
stock_value = stock.qty * unit_price
total_value += stock_value
print(f"Stock {stock.width}mm: {stock.qty} × ${unit_price} = ${stock_value}")
print(f"\nTotal Stock Value: ${total_value}")
return total_value
# Calculate value
unit_prices = {300.0: 25.50, 250.0: 20.00, 400.0: 35.00}
calculate_stock_value(cut_id, unit_prices)
Understanding Stock-Pattern Relationship¶
Each stock width is matched to patterns that use that width:
Stock (width=300, qty=20)
↓
Used in Pattern 1: num=10
↓
Used in Pattern 2: num=5
↓
Total pat_qty = 10 + 5 = 15 pieces
Utilization = 15/20 = 75%
Remaining = 20 - 15 = 5 pieces
Best Practices¶
1. Provide Adequate Stock Variety¶
# Good: Multiple stock widths give solver flexibility
stock_configs = [
{"width": 250.0, "qty": 30},
{"width": 300.0, "qty": 25},
{"width": 350.0, "qty": 20},
{"width": 400.0, "qty": 15},
]
# Bad: Single stock width limits optimization
stock_configs = [
{"width": 300.0, "qty": 100}, # Only one option
]
2. Balance Stock Quantities¶
# Provide reasonable quantities relative to orders
orders_total = sum(order.qty for order in cut.orders)
stock_total = sum(stock.qty for stock in cut.stock)
# Rule of thumb: stock should be 20-50% more than orders
recommended_ratio = orders_total * 1.3
if stock_total < orders_total:
print("⚠ Warning: Insufficient stock quantity")
elif stock_total > orders_total * 2:
print("⚠ Warning: Excessive stock (may not be fully utilized)")
3. Document Jumbo Stock Handling¶
# Clearly document why stock is marked as jumbo
stock_with_notes = {
"width": 400.0,
"qty": 10,
"jumbo": True,
# In practice, add notes/comments explaining:
# - Requires crane for handling
# - Higher cutting costs
# - Limited cutting stations
}
Performance Tips¶
1. Minimize Stock Varieties¶
More stock widths increase solver complexity. Use only necessary widths.
# Good: Essential widths only
stock = [
{"width": 300.0, "qty": 30},
{"width": 250.0, "qty": 25},
]
# Bad: Too many similar widths
stock = [
{"width": 290.0, "qty": 10},
{"width": 295.0, "qty": 10},
{"width": 300.0, "qty": 10},
{"width": 305.0, "qty": 10},
{"width": 310.0, "qty": 10},
]
2. Pre-filter Stock by Compatibility¶
# Remove stock that cannot fulfill any orders
def filter_compatible_stock(orders, stock_items):
min_order_width = min(order.width for order in orders)
compatible = [
s for s in stock_items
if s.width >= min_order_width
]
return compatible
Troubleshooting¶
"Stock not being used (pat_qty is 0)"¶
Cause: Stock width is too small for any orders, or solver found better alternatives
Solution:
- Verify stock width is larger than order widths
- Check if other stock widths are more efficient
- Consider removing unused stock from operation
"Insufficient stock error"¶
Cause: Total available stock cannot fulfill order requirements
Solution:
- Increase stock quantities
- Add additional stock widths
- Reduce order quantities or adjust order requirements
"All stock used but orders not fulfilled"¶
Cause: Stock widths or quantities don't match order needs
Solution:
- Review order widths for compatibility with stock
- Add intermediate stock sizes
- Increase stock quantities for heavily used widths
"Jumbo stock being used unnecessarily"¶
Cause: Solver selecting jumbo stock despite standard alternatives
Solution:
- Verify sufficient standard stock is available
- Check solver prioritization logic
- Consider removing jumbo from operation if not needed
Integration with Solver¶
The solver receives stock data in this format:
stock_for_solver = [
{
"width": 300.0,
"qty": 25,
"jumbo": False
},
{
"width": 400.0,
"qty": 10,
"jumbo": True
}
]
The jumbo flag may influence solver optimization strategies, potentially deprioritizing jumbo stock in pattern generation.
Version History¶
Last Updated: October 2025
Model Version: stock_cut_stock.py
Framework: Netforce
Additional Resources¶
- Stock Cut Documentation:
stock.cut - Stock Cut Order Documentation:
stock.cut.order - Stock Cut Pattern Documentation:
stock.cut.pattern
This documentation is generated for developer onboarding and reference purposes.