Extract ourdigital-estimate-engine; presales-seo now calls it
New skill 96-ourdigital-estimate-engine: method-aware quoting engine (effort / coaching / procurement) with universal rate_card + per-service catalog. Real catalogs: seo (effort), education (coaching); stubs: digital_ads, digital_branding. Validated to reproduce real quotes — SEO basic ₩10.5M / treatment ₩25.0M, SHR chain ₩29.5M, L'Escape basic ₩10.5M, GA4/GTM coaching ₩1,570,000, procurement +15%. Refactor 95-ourdigital-presales-seo: remove rate_card.yaml, sow_templates.yaml, estimate.py (migrated to engine); add findings_to_scope.py; Stage 5 now maps findings→scope.json and calls the engine CLI. build_deck/kg_query unchanged; end-to-end validated on SHR (29.5M) + deck renders engine estimate.json. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
"""Procurement method: cost = Σ(unit_cost × qty × (1 + markup)) for non-labor items."""
|
||||
|
||||
|
||||
def build(scope, rate, catalog):
|
||||
markup = rate.get("procurement_markup", 0.15)
|
||||
items, total = [], 0.0
|
||||
for it in scope.get("items", []):
|
||||
qty = it.get("qty", 1)
|
||||
amt = it["unit_cost"] * qty * (1 + markup)
|
||||
items.append({"label": it["label"], "unit_cost": it["unit_cost"], "qty": qty,
|
||||
"markup": markup, "amount": amt, "currency": it.get("currency", "KRW")})
|
||||
total += amt
|
||||
return {
|
||||
"kind": "procurement", "service": catalog.get("service", "procurement"),
|
||||
"label": "조달 항목 (Buying & Supplying)", "markup": markup,
|
||||
"items": items, "subtotal_sum": total, "proposal": int(round(total)),
|
||||
"stub": bool(catalog.get("_stub", False)),
|
||||
}
|
||||
Reference in New Issue
Block a user