Files
grabowski 9ff5feef11
Deploy test site / deploy (push) Successful in 54s
Solar on every roof, BOI solar correction, open source section
Solar (user, 17 Oct 2026: "use as much roof space as possible")
- PV on every roof and canopy: ~640 kWp on the Payap scenario plot
  (factory roof ~523, canopies ~54, flat office roof ~65 kWp around the
  AC units); ~300 kWp on the Mueang Chi hall. Calculator: pvKWp 640,
  new pvSelf 85 % (zero export, hourly sketch), PV cost per kWp times the
  array, office-roof PV in the iso view, roofs drawn full.
- 12.8M to 16.6M THB at 20 to 26 THB/W; CSV baseline 34.37M to 56.34M;
  launch plant ~168M / 231M / 294M THB with contingency; Plan B ~216M
  (label ~215M), ~39M above Plan A; Plan A unchanged (it leases the
  array), its solar lever ~17.5M. PV payback ~4.2 to 5.9 years.
- Permits (rooftop solar no factory licence since 28 Dec 2024, ERC
  exemption under 1,000 kVA, PEA zero export) and PPA discounts sourced
  in sustainability.md.

BOI correction
- Announcement 3/2568 (in force 1 July 2025) ended BOI promotion for
  solar installations; only the battery may qualify (12M THB per MW cap).
  Removed the "BOI solar measure" from boi.md, total-investment,
  revenue-model, sustainability, site-candidates and both plan versions;
  Plan B's case for owning the array is the PPA bill it avoids
  (~0.07M USD a year).

Open source (user, 17 Oct 2026)
- digital-factory.md "Open source throughout, and working with other
  plants": everything we run and build is open source on NixOS, our code
  published (licence to decide), vendor firmware the stated exception;
  later the stack and factory-automation services for other pressing
  plants, not in the revenue.
- Business plan section 5.6 plus an executive-summary bullet, reading
  guide and not-modelled mentions; draft 0.3 rebuilt (A 60, B 61 pages),
  renders re-made with the roofs full.
2026-10-17 17:22:57 +07:00

47 lines
1.6 KiB
Python

"""Build the CNX Vinyl business plan .docx, in its two versions (October 2026).
python build_plan.py -> ../CNX-Vinyl-Business-Plan-A.docx and -B.docx
python build_plan.py A -> ../CNX-Vinyl-Business-Plan-A.docx
python build_plan.py B out.docx -> Plan B to a custom path
Plan A (~180M THB) and Plan B (~215M THB) share every chapter; the content modules
switch the plan-specific text with plan_variant.pick(). Images are resolved relative
to docs/ (the parent of business-plan/).
"""
from __future__ import annotations
import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
from plan_lib import Renderer # noqa: E402
import plan_variant # noqa: E402
import content_a, content_b, content_c # noqa: E402
DOCS = HERE.parent.parent # .../docs
VERSION = "draft 0.3, October 2026"
def out_path(plan: str) -> Path:
return HERE.parent / f"CNX-Vinyl-Business-Plan-{plan}.docx"
def main(plan: str = "A", out: Path | None = None) -> Path:
plan_variant.PLAN = plan
out = out or out_path(plan)
r = Renderer(DOCS, header_text=f"CNX Vinyl / Poy Records: Business plan, {plan_variant.label()}, {VERSION}",
footer_text="Confidential")
r.render(content_a.blocks() + content_b.blocks() + content_c.blocks())
r.save(out)
return out
if __name__ == "__main__":
args = sys.argv[1:]
plans = [args.pop(0).upper()] if args and args[0].upper() in ("A", "B") else ["A", "B"]
target = Path(args[0]) if args else None
for p in plans:
print(main(p, target if len(plans) == 1 else None))