jashdoshi77 commited on
Commit
f2e427c
Β·
1 Parent(s): 3d9e2c3

fix: add component cost rules - always multiply per_unit by quantity from pricing table

Browse files
Files changed (1) hide show
  1. 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. USE PRE-COMPUTED TOTALS β€” NEVER RECONSTRUCT THEM:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- 4. CORRECT FORMULAS:
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
- 5. DATE FILTERING (order_date is TEXT 'YYYY-MM-DD'):
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
- 6. SIMPLICITY:
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