Spaces:
Running
Running
Commit Β·
f2e427c
1
Parent(s): 3d9e2c3
fix: add component cost rules - always multiply per_unit by quantity from pricing table
Browse files- ai/signatures.py +43 -6
ai/signatures.py
CHANGED
|
@@ -56,6 +56,27 @@ class AnalyzeAndPlan(dspy.Signature):
|
|
| 56 |
β JOIN path: sales_order β sales_order_line β sales_order_line_pricing
|
| 57 |
β Still filter by sales_order.status = 'closed'.
|
| 58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
PURCHASE ORDER TOTALS:
|
| 60 |
β Use: purchase_orders_v6_purchase_order.total_amount
|
| 61 |
β For: "total amount of PO123", "PO value", "purchase order cost".
|
|
@@ -198,24 +219,40 @@ class SQLGeneration(dspy.Signature):
|
|
| 198 |
- Highest/biggest/top "purchase order" β purchase_orders_v6_purchase_order ORDER BY total_amount DESC
|
| 199 |
- Highest/biggest/top "order" or "sale" β sales_table_v2_sales_order ORDER BY total_amount DESC
|
| 200 |
|
| 201 |
-
3.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
- For order-level metrics (revenue, AOV): use sales_table_v2_sales_order.total_amount
|
| 203 |
- For PO totals: use purchase_orders_v6_purchase_order.total_amount
|
| 204 |
- NEVER add gold_amount + diamond_amount or any component columns β
|
| 205 |
that always gives the WRONG answer (misses labour, taxes, etc.)
|
| 206 |
|
| 207 |
-
|
| 208 |
- Revenue: SELECT SUM(total_amount) FROM sales_table_v2_sales_order WHERE status = 'closed'
|
| 209 |
- AOV: SELECT AVG(total_amount) FROM sales_table_v2_sales_order WHERE status = 'closed'
|
| 210 |
-
- Per-product revenue: SUM(line_total) FROM sales_order_line_pricing
|
| 211 |
-
JOIN sales_order_line JOIN sales_order WHERE status = 'closed'
|
| 212 |
|
| 213 |
-
|
| 214 |
- Use the EXACT year values from the [CONTEXT] block in the question.
|
| 215 |
- Use: order_date >= 'YYYY-01-01' AND order_date <= 'YYYY-12-31'
|
| 216 |
- Do NOT use EXTRACT() or CAST() on order_date.
|
| 217 |
|
| 218 |
-
|
| 219 |
- Single-record lookup = simple WHERE filter, no aggregation
|
| 220 |
- Only JOIN when needed, only aggregate when needed
|
| 221 |
|
|
|
|
| 56 |
β JOIN path: sales_order β sales_order_line β sales_order_line_pricing
|
| 57 |
β Still filter by sales_order.status = 'closed'.
|
| 58 |
|
| 59 |
+
COMPONENT COST BY PRODUCT (diamond cost, gold cost, making charges per product):
|
| 60 |
+
β The sales_table_v2_sales_order_line_pricing table has ALL component costs
|
| 61 |
+
and quantity in ONE place. Use it exclusively for cost analysis.
|
| 62 |
+
β Correct formula: SUM(component_amount_per_unit * quantity)
|
| 63 |
+
β Columns available:
|
| 64 |
+
diamond_amount_per_unit β total diamond cost = SUM(diamond_amount_per_unit * quantity)
|
| 65 |
+
gold_amount_per_unit β total gold cost = SUM(gold_amount_per_unit * quantity)
|
| 66 |
+
making_charges_per_unit β total making cost = SUM(making_charges_per_unit * quantity)
|
| 67 |
+
β GROUP BY product_id for "by product", GROUP BY variant_sku for "by variant/SKU".
|
| 68 |
+
β Example β top 10 products by diamond cost:
|
| 69 |
+
SELECT product_id, SUM(diamond_amount_per_unit * quantity) AS diamond_cost
|
| 70 |
+
FROM sales_table_v2_sales_order_line_pricing
|
| 71 |
+
GROUP BY product_id
|
| 72 |
+
ORDER BY diamond_cost DESC
|
| 73 |
+
LIMIT 10
|
| 74 |
+
β NEVER use sales_order_line_diamond or sales_order_line_gold tables for cost totals.
|
| 75 |
+
Those detail tables have diamond_amount_per_unit WITHOUT quantity β using SUM on them
|
| 76 |
+
directly gives WRONG results (undercounts because it ignores how many units were ordered).
|
| 77 |
+
Use them ONLY when the question asks about specific diamond/gold properties
|
| 78 |
+
(e.g. shape, quality, karat, size, carats) β NOT for cost or revenue calculations.
|
| 79 |
+
|
| 80 |
PURCHASE ORDER TOTALS:
|
| 81 |
β Use: purchase_orders_v6_purchase_order.total_amount
|
| 82 |
β For: "total amount of PO123", "PO value", "purchase order cost".
|
|
|
|
| 219 |
- Highest/biggest/top "purchase order" β purchase_orders_v6_purchase_order ORDER BY total_amount DESC
|
| 220 |
- Highest/biggest/top "order" or "sale" β sales_table_v2_sales_order ORDER BY total_amount DESC
|
| 221 |
|
| 222 |
+
3. COMPONENT COSTS (diamond/gold/making charges) β USE PRICING TABLE WITH QUANTITY:
|
| 223 |
+
- Correct table: sales_table_v2_sales_order_line_pricing
|
| 224 |
+
- Correct formula: SUM(diamond_amount_per_unit * quantity) for diamond cost
|
| 225 |
+
SUM(gold_amount_per_unit * quantity) for gold cost
|
| 226 |
+
SUM(making_charges_per_unit * quantity) for making charges
|
| 227 |
+
- NEVER use sales_order_line_diamond or sales_order_line_gold for cost aggregations.
|
| 228 |
+
Those tables lack quantity, so SUM(diamond_amount_per_unit) there is always WRONG.
|
| 229 |
+
- Examples:
|
| 230 |
+
Top products by diamond cost:
|
| 231 |
+
SELECT product_id, SUM(diamond_amount_per_unit * quantity) AS diamond_cost
|
| 232 |
+
FROM sales_table_v2_sales_order_line_pricing
|
| 233 |
+
GROUP BY product_id ORDER BY diamond_cost DESC LIMIT 10
|
| 234 |
+
Top SKUs by gold cost:
|
| 235 |
+
SELECT variant_sku, SUM(gold_amount_per_unit * quantity) AS gold_cost
|
| 236 |
+
FROM sales_table_v2_sales_order_line_pricing
|
| 237 |
+
GROUP BY variant_sku ORDER BY gold_cost DESC LIMIT 10
|
| 238 |
+
|
| 239 |
+
5. USE PRE-COMPUTED TOTALS β NEVER RECONSTRUCT THEM:
|
| 240 |
- For order-level metrics (revenue, AOV): use sales_table_v2_sales_order.total_amount
|
| 241 |
- For PO totals: use purchase_orders_v6_purchase_order.total_amount
|
| 242 |
- NEVER add gold_amount + diamond_amount or any component columns β
|
| 243 |
that always gives the WRONG answer (misses labour, taxes, etc.)
|
| 244 |
|
| 245 |
+
6. CORRECT FORMULAS:
|
| 246 |
- Revenue: SELECT SUM(total_amount) FROM sales_table_v2_sales_order WHERE status = 'closed'
|
| 247 |
- AOV: SELECT AVG(total_amount) FROM sales_table_v2_sales_order WHERE status = 'closed'
|
| 248 |
+
- Per-product revenue: SUM(line_total) FROM sales_order_line_pricing (no extra JOIN needed)
|
|
|
|
| 249 |
|
| 250 |
+
7. DATE FILTERING (order_date is TEXT 'YYYY-MM-DD'):
|
| 251 |
- Use the EXACT year values from the [CONTEXT] block in the question.
|
| 252 |
- Use: order_date >= 'YYYY-01-01' AND order_date <= 'YYYY-12-31'
|
| 253 |
- Do NOT use EXTRACT() or CAST() on order_date.
|
| 254 |
|
| 255 |
+
8. SIMPLICITY:
|
| 256 |
- Single-record lookup = simple WHERE filter, no aggregation
|
| 257 |
- Only JOIN when needed, only aggregate when needed
|
| 258 |
|