Files
our-claude-skills/custom-skills/96-ourdigital-estimate-engine/scripts/methods/procurement.py
Andrew Yim c9bdbb57f7 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>
2026-05-28 01:54:11 +09:00

19 lines
827 B
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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)),
}