"""Generate docs/SOP_Roles_and_Responsibilities.docx — concise R&R reference
for the full S&OP process at Polleo. Designed for upload to a Claude project."""
from pathlib import Path
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH

OUT = Path(__file__).parent / "docs" / "SOP_Roles_and_Responsibilities.docx"
OUT.parent.mkdir(exist_ok=True)


def title(d, text, sub):
    t = d.add_paragraph()
    t.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r = t.add_run(text); r.bold = True; r.font.size = Pt(22)
    r.font.color.rgb = RGBColor(0x1F, 0x3A, 0x5F)
    s = d.add_paragraph()
    s.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r = s.add_run(sub); r.italic = True; r.font.size = Pt(12)
    r.font.color.rgb = RGBColor(0x55, 0x55, 0x55)
    d.add_paragraph()


def h(d, text, level=1):
    p = d.add_heading(text, level=level)
    color = RGBColor(0x1F, 0x3A, 0x5F) if level == 1 else RGBColor(0x2F, 0x54, 0x96)
    for r in p.runs:
        r.font.color.rgb = color


def p(d, text):
    d.add_paragraph(text)


def b(d, text):
    d.add_paragraph(text, style="List Bullet")


def n(d, text):
    d.add_paragraph(text, style="List Number")


def tbl(d, headers, rows):
    t = d.add_table(rows=1 + len(rows), cols=len(headers))
    t.style = "Light Grid Accent 1"
    for i, hh in enumerate(headers):
        c = t.rows[0].cells[i]
        c.text = hh
        for r in c.paragraphs[0].runs:
            r.bold = True
    for ri, row in enumerate(rows, start=1):
        for ci, val in enumerate(row):
            t.rows[ri].cells[ci].text = str(val)


# ============================================================
d = Document()
style = d.styles["Normal"]
style.font.name = "Calibri"
style.font.size = Pt(11)

title(d, "S&OP Process — Roles & Responsibilities",
      "Roles, responsibilities and meeting cadence across Demand Planning, "
      "Procurement, Wholesales, Retail and Finance")


# ============================================================
h(d, "1. Purpose")
p(d, "Sales & Operations Planning (S&OP) is the forum where Demand, Supply and "
     "Finance commit to a single forward-looking plan. It answers four "
     "executive questions: what will we sell, can we supply it, where will we "
     "miss, and what decisions need to be taken now.")
p(d, "S&OP does not replace day-to-day planning. It is the place where "
     "departments align on one number and where unresolved trade-offs are "
     "escalated to the CEO.")


# ============================================================
h(d, "2. Meeting cadence")
p(d, "Three meetings, escalating in scope:")
b(d, "Weekly S&OE (Sales & Operations Execution) — short operational sync. "
     "Demand Planning, Wholesales, Retail, Procurement. Resolves week-to-week "
     "issues. No CEO.")
b(d, "Monthly Pre-S&OP — full management decision forum. Demand Planning, "
     "Procurement, Wholesales, Retail, Finance. The intent is that all "
     "decisions are made here so the executive meeting is reporting, not "
     "deciding. No CEO.")
b(d, "Monthly S&OP — report-out to the CEO. The team presents the agreed "
     "plan, KPIs and a short list of items where Pre-S&OP could not reach "
     "consensus. The CEO makes the final call only on those open items.")


# ============================================================
h(d, "3. Tool ownership and data flow")
p(d, "The Polleo Demand tool is owned and maintained by the Demand Planning "
     "team. They run the forecast engine, manage the data files, fix bugs "
     "and define how reports are presented.")

p(d, "Demand Planning pulls the bulk of data automatically from ERP — sales "
     "history, prices, ERP promo calendar, cost prices, NPD codes once "
     "registered. Only four inputs come from outside the tool and the team:")
tbl(d,
    ["Input", "Provided by"],
    [
        ["VP commitments per buyer (Slack template)",
         "Wholesales (KAMs)"],
        ["MP commitments per category (Slack template)",
         "Retail (CMs)"],
        ["Open purchase orders (incoming_supply.csv)",
         "Procurement"],
        ["MOQ and logistics data (supply_master.csv)",
         "Procurement / Logistics"],
    ])
p(d, "Everything else flows through ERP and into the tool without manual "
     "intervention.")


# ============================================================
h(d, "4. Department roles")

# DEMAND PLANNING
h(d, "4.1 Demand Planning", level=2)
p(d, "Owner of the demand number and of the tool itself.")
b(d, "Owns: statistical baseline forecast, FA tracking, consensus plan, "
     "S&OP slide deck, the Polleo Demand application.")
b(d, "Consumes: ERP sales export, ERP promo calendar, KAM/CM commitments, "
     "open POs and supply master from Procurement, NPD launch list.")
b(d, "Produces: Demand plan (xlsx), revenue & RUC projections, forecast "
     "accuracy report, NPD performance, exception list for Pre-S&OP.")
b(d, "Decisions: tier assignment, model selection, promo cleaning, "
     "planner-factor adjustments.")

# PROCUREMENT
h(d, "4.2 Procurement", level=2)
p(d, "Owner of the supply number and of inventory cash.")
b(d, "Owns: stock data (warehouse + stores), supplier master, lead times, "
     "MOQs, open POs, cost prices.")
b(d, "Consumes: demand plan from Demand Planning, supplier confirmations.")
b(d, "Produces: stock projection, coverage report, reorder plan, inventory "
     "health KPIs, supplier risk flags.")
b(d, "Decisions: order quantities within MOQ and target-coverage rules, "
     "supplier choice when alternatives exist, safety stock parameters.")

# WHOLESALES
h(d, "4.3 Wholesales (VP / KAM)", level=2)
p(d, "Owner of the wholesale (B2B) channel and per-buyer relationships.")
b(d, "Owns: wholesale revenue and margin targets, listing wins, promo "
     "negotiation with chains.")
b(d, "Consumes: forecast baseline, stock availability, pricing.")
b(d, "Produces: per-buyer VP commitments via Slack template, promo calendar "
     "inputs, wholesale FA tracking.")
b(d, "Decisions: per-buyer quantities, promo participation per chain.")

# RETAIL
h(d, "4.4 Retail (MP / CM)", level=2)
p(d, "Owner of direct retail and webshop channels.")
b(d, "Owns: retail and webshop revenue targets, in-store activation, "
     "webshop merchandising, direct promo plan.")
b(d, "Consumes: forecast baseline, stock availability, pricing rules.")
b(d, "Produces: per-category MP commitments via Slack template, retail "
     "promo calendar, retail FA tracking.")
b(d, "Decisions: per-category retail/webshop on-top, store-level promo "
     "participation.")

# FINANCE
h(d, "4.5 Finance", level=2)
p(d, "Owner of pricing and the financial reconciliation between operational "
     "plan and P&L.")
b(d, "Owns: revenue and margin targets, selling prices, pricing strategy, "
     "working capital targets.")
b(d, "Consumes: revenue & RUC projection from Demand, stock value and "
     "purchase plan from Procurement, promo and discount commitments from "
     "Wholesales/Retail.")
b(d, "Produces: approved selling prices, discount approvals, cash-flow "
     "projection from inventory roll-forward, P&L variance report.")
b(d, "Decisions: pricing within strategy bands, discount approvals, "
     "inventory write-offs, cash allocation between purchasing and other "
     "priorities.")


# ============================================================
h(d, "5. Reports — what they show and who reads them")
tbl(d,
    ["Report", "What it shows", "Owner", "Read by"],
    [
        ["Dashboard",
         "Top-line KPIs across the portfolio",
         "Demand Planning", "All departments"],
        ["Demand planning view",
         "Per-SKU baseline vs run-rate, with VP/MP overlay",
         "Demand Planning", "Demand team daily"],
        ["Forecast Accuracy",
         "FA / FA-signed / BIAS by tier, with planner-factor toggle",
         "Demand Planning", "All depts; CEO at S&OP"],
        ["Top 30 Watchlist",
         "SKUs at biggest risk this week",
         "Demand Planning", "S&OE meeting"],
        ["Revenue & RUC",
         "13-week € projection by category, channel, with non-planned gross-up",
         "Demand Planning + Finance", "Finance, CEO"],
        ["Stock Projection",
         "13-week stock roll-forward in units and €",
         "Procurement", "Procurement, CEO"],
        ["Coverage table",
         "Weeks of cover per SKU",
         "Procurement", "Procurement"],
        ["Reorder alerts",
         "SKUs needing replenishment with proposed quantities",
         "Procurement", "Procurement"],
        ["Inventory Health",
         "Overstock and stockout flags",
         "Procurement", "Procurement, Finance"],
        ["S&OP Meeting view",
         "Executive one-screen with KPIs and exceptions",
         "Demand Planning", "Pre-S&OP, S&OP"],
        ["Promotions one-slider",
         "Biggest promotions per month — SKUs, units, revenue, RUC",
         "Demand Planning + Wholesales/Retail", "S&OP deck"],
        ["NPD list",
         "New product attainment vs projection",
         "Demand Planning + NPD", "S&OP, NPD"],
        ["Consensus plan snapshot",
         "Frozen plan signed off for the cycle",
         "Demand Planning", "All — variance reference"],
    ])


# ============================================================
h(d, "6. Decisions made in the S&OP process")
p(d, "These are the recurring calls. Pre-S&OP is the venue where the team "
     "agrees and locks them. S&OP is where the team reports the agreed plan "
     "and asks the CEO to settle anything still open.")
tbl(d,
    ["Decision", "Decided in", "Decision owner", "Inputs needed (from)"],
    [
        ["Approve the demand plan for the cycle",
         "Pre-S&OP", "Demand Planning",
         "Forecast (Demand), VP/MP commitments (Wholesales/Retail), FA history (Demand)"],
        ["Approve / adjust promo plan",
         "Pre-S&OP",
         "Wholesales + Retail jointly with Finance",
         "Promo plan with projected RUC (Wholesales/Retail), uplift assumption (Demand), margin band (Finance)"],
        ["Approve reorder cycle",
         "Pre-S&OP",
         "Procurement",
         "Demand plan (Demand), coverage and supplier status (Procurement), cash position (Finance)"],
        ["Pricing changes within strategy",
         "Pre-S&OP", "Finance",
         "Margin trend (Finance), competitor moves (Wholesales/Retail), cost trend (Procurement)"],
        ["Inventory write-off and slow-mover plan",
         "Pre-S&OP",
         "Finance + Procurement",
         "Inventory health (Procurement), tax impact (Finance)"],
        ["NPD launch readiness",
         "Pre-S&OP",
         "Cross-functional (Demand + Procurement + Wholesales/Retail + Finance)",
         "Projected sales (NPD), supply readiness (Procurement), pricing (Finance)"],
        ["SKU discontinuation",
         "Pre-S&OP",
         "Demand Planning",
         "Sales trend (Demand), residual stock (Procurement), KAM impact (Wholesales)"],
        ["Pricing strategy band change",
         "S&OP — CEO call",
         "CEO",
         "Margin & competitor analysis (Finance)"],
        ["Capital allocation (warehouse, supplier change, major CAPEX)",
         "S&OP — CEO call",
         "CEO",
         "Volume forecast (Demand), capacity & cost (Procurement), CAPEX impact (Finance)"],
        ["Items where Pre-S&OP could not agree",
         "S&OP — CEO call",
         "CEO",
         "Both positions presented by the responsible departments"],
    ])


# ============================================================
h(d, "7. Cross-department handoffs — who needs what from whom")
tbl(d,
    ["From", "To", "What"],
    [
        ["ERP", "Demand Planning",
         "Weekly sales export, prices, ERP promo calendar, cost prices"],
        ["Wholesales", "Demand Planning",
         "Filled VP templates per buyer (Slack)"],
        ["Retail", "Demand Planning",
         "Filled MP templates per category (Slack)"],
        ["Procurement", "Demand Planning",
         "Open POs, MOQs, lead times, logistics data"],
        ["NPD", "Demand Planning",
         "New SKU codes, names, launch week, projected retail/wholesale per week"],
        ["Demand Planning", "Procurement",
         "Demand plan and forecast bridge file"],
        ["Demand Planning", "Finance",
         "Revenue & RUC projection by category and channel"],
        ["Demand Planning", "NPD",
         "NPD attainment vs projection"],
        ["Procurement", "Finance",
         "Stock value and projected purchases for cash-flow"],
        ["Wholesales / Retail", "Finance",
         "Promo plans with depth and margin impact"],
        ["CEO (S&OP)", "All departments",
         "Decisions log from the executive meeting"],
    ])


# ============================================================
h(d, "8. KPIs each department is measured on")
tbl(d,
    ["Department", "Primary", "Secondary"],
    [
        ["Demand Planning",
         "Forecast accuracy by tier, BIAS direction",
         "On-time forecast delivery, FA improvement trend"],
        ["Procurement",
         "Service level, inventory turnover",
         "Overstock €, supplier on-time delivery"],
        ["Wholesales",
         "Sell-in revenue vs target, FA on own commitments",
         "Listing wins, promo execution rate"],
        ["Retail",
         "Sell-out revenue vs target, same-store growth",
         "Promo ROI, webshop conversion, CM commitment FA"],
        ["Finance",
         "Gross margin, working capital, P&L variance to plan",
         "Pricing realisation, write-off €"],
    ])


# ============================================================
h(d, "9. Common dysfunctions to watch for")
b(d, "KAMs over-committing on input call to look good — caught by FA-signed "
     "drifting consistently above 100%.")
b(d, "Procurement smoothing demand spikes by ordering early — visible as "
     "overstock building, then write-offs at quarter-end.")
b(d, "Finance approving promos on aggregate margin — Gold-level RUC tells "
     "the truth.")
b(d, "Demand Planning over-using planner factors to chase weekly noise — "
     "backtest accuracy should not deteriorate.")
b(d, "S&OP meeting becoming a status update with no decisions — the "
     "exception list should be short. If it is long, Pre-S&OP did not do "
     "its job.")


# ============================================================
h(d, "10. CEO checklist for the S&OP meeting")
n(d, "What is forecast accuracy on Gold? Is it improving?")
n(d, "Where will we miss in the next short horizon, and why?")
n(d, "Is cash tied up in inventory at target or above?")
n(d, "Any Gold-tier stockout risk in the horizon?")
n(d, "Promo plan margin impact — within band?")
n(d, "Variance vs last cycle's plan — explained?")
n(d, "What items did Pre-S&OP not resolve, and who is asking me to decide?")


# ============================================================
h(d, "11. Glossary")
tbl(d,
    ["Term", "Meaning"],
    [
        ["S&OE", "Sales & Operations Execution — the weekly operational sync"],
        ["Pre-S&OP", "Monthly management decision forum, no CEO"],
        ["S&OP", "Monthly executive review with the CEO"],
        ["FA", "Forecast Accuracy, capped 0–100%"],
        ["FA signed", "Forecast / actual ratio (can exceed 100%)"],
        ["BIAS", "(Forecast − actual) / actual; sign matters"],
        ["VP", "Wholesale (Veleprodaja)"],
        ["MP", "Retail / marketing (Maloprodaja)"],
        ["KAM", "Key Account Manager (wholesales)"],
        ["CM", "Category Manager (retail)"],
        ["NPD", "New Product Development"],
        ["RUC", "Razlika u cijeni — gross margin in €"],
        ["Oznaka", "ABC tier (Gold / Silver / Bronze)"],
        ["XYZ", "Demand-volatility class (X stable, Z volatile)"],
        ["Coverage", "Weeks of stock at current run rate"],
        ["MOQ", "Minimum Order Quantity"],
        ["Long-tail", "SKUs not in the forecast portfolio"],
    ])


# ============================================================
d.save(OUT)
print(f"Generated: {OUT}  ({OUT.stat().st_size // 1024} KB)")
