Deploy test site / deploy (push) Successful in 52s
- One build makes both documents: plan_variant.py switches the plan-specific text (pick / is_a / label); build_plan.py writes CNX-Vinyl-Business-Plan-A and -B (docx), export_pdf.py exports both PDFs with the table of contents filled in. Draft 0.2 (single launch-plant plan with contingency) is removed; it stays in the history. - Plan A: the launch plant with every machine and six cost levers, ~177M THB with the ramp-up reserve, no contingency. Plan B: the second Duplex at launch, five presses, ~224M THB on the same basis. Each version reads as a complete plan with one table comparing it with the other; the 216M investor-question text is gone, Pheenix is priced at OMS's reference plus 20 %. - Calculator renders in both documents, each from its own preset: the plant at a glance (Figure 4), the budget check (Figure 5) and ten years of cash (Figure 6), in docs/renders/calculator/. - Calculator budget card: the verdict and third KPI now name the tightest budget the midpoint fits (Plan A: 3.3M to spare under 180M; Plan B: 0.8M under 225M) instead of always 225M. - Fixes: CD replication cross-references point to section 4.10; the blended price in section 3.3 and roadmap item 1 is 3.76 to 5.27 USD at 60 % specials (3.50 to 4.60 at a standard-heavy mix).
37 lines
977 B
Python
37 lines
977 B
Python
"""Which version of the business plan is being built (October 2026).
|
|
|
|
Plan A, ~180M THB: the launch plant (1 Duplex system + 1 Classic, every machine) with six cost levers.
|
|
Plan B, ~225M THB: five presses (the second Duplex system at launch), everything in.
|
|
Both are priced without contingency and with the ramp-up reserve
|
|
(docs/finance/total-investment.md, "Two plans").
|
|
|
|
build_plan.py sets PLAN before it calls the content modules' blocks(); call pick() and the
|
|
helpers inside blocks(), never at import time.
|
|
"""
|
|
PLAN = "A"
|
|
|
|
NAME = {"A": "Plan A", "B": "Plan B"}
|
|
PRICE = {"A": "~180M THB", "B": "~225M THB"}
|
|
|
|
|
|
def is_a() -> bool:
|
|
return PLAN == "A"
|
|
|
|
|
|
def is_b() -> bool:
|
|
return PLAN == "B"
|
|
|
|
|
|
def pick(a, b):
|
|
"""The Plan A or the Plan B variant of a value, text or list of blocks."""
|
|
return a if PLAN == "A" else b
|
|
|
|
|
|
def name() -> str:
|
|
return NAME[PLAN]
|
|
|
|
|
|
def label() -> str:
|
|
"""e.g. 'Plan A (~180M THB)'."""
|
|
return f"{NAME[PLAN]} ({PRICE[PLAN]})"
|