diff --git a/README.md b/README.md index cfafcfc..0a1fd0d 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,8 @@ The detail lives in dedicated documents: electricity and steam, labour from base salaries with social security, on-costs and health care for all staff, overheads, EBITDA, depreciation and payback, with the revenue model's adverse, central and favourable - cases and USD, THB or EUR; every assumption is editable, with its + cases, BOI promotion on or off (machinery import duty and import VAT, + PVC duty relief) and USD, THB or EUR; every assumption is editable, with its source, and a scenario can be shared by link - [Test site](site/README.md): `site/` builds https://cnxvinyl.lol/, the internal test site with demo pages from `docs/` (the plant operation diff --git a/docs/boi.md b/docs/boi.md index e3f596a..0a38b13 100644 --- a/docs/boi.md +++ b/docs/boi.md @@ -39,7 +39,22 @@ not on "we press plastic discs." ## What Group B still delivers (the core value) - **Machinery import duty exemption**: significant with the entire equipment - list imported (Germany, Sweden, USA, Japan) + list imported (Germany, Sweden, USA, Japan). **Import VAT goes with it:** + machinery or raw material imported with the duty exemption is exempt + from VAT at import as well (Revenue Department answer on the + [BOI OSOS FAQ](https://osos.boi.go.th/One-Stop/faq-group/205/FAQ-about-VAT--BOI), + checked October 2026); otherwise a BOI company is treated like any other + for VAT. What it is worth: the capex blocks in + [total investment](finance/total-investment.md) are vendor prices + without duty or VAT, so they already assume promotion. Without it, the + ~2.75M USD of imported machinery at the start fleet (presses, galvanics, + Sibert, lathe system, metrology; block midpoints) would carry import duty, + roughly 5 % (Thailand's MFN averages 4.1 % on HS 8477 plastics + machinery, 0 to 10 % across HS 84; estimate until the HS codes are set), + ~0.14M USD, and 7 % import VAT, ~0.2M USD paid at the border and only + recovered later as input tax, mostly as a refund claim because exports + are zero-rated. The [press fleet calculator](fleet-calculator.html) + shows both cases. - **100% foreign ownership** of the promoted manufacturing company, overriding Foreign Business Act restrictions for the promoted activity - **Land ownership** for the promoted operation despite foreign diff --git a/docs/finance/total-investment.md b/docs/finance/total-investment.md index f67b539..2227fa0 100644 --- a/docs/finance/total-investment.md +++ b/docs/finance/total-investment.md @@ -75,7 +75,10 @@ exactly this reason. - **BOI**: machinery duty exemption applies across most of the equipment blocks, and the solar and automation spend converts into CIT-exemption headroom; the application precedes every purchase order (see - [boi.md](../boi.md)) + [boi.md](../boi.md)). The blocks are vendor prices without Thai duty or + import VAT, so the headline assumes promotion: without it, ~0.14M USD of + duty and ~0.2M USD of import VAT (reclaimable later) come on top at the + start fleet (estimate) - **Buy vs lease** on land and building swings roughly **1.0M to 2.1M USD (~34M to 69M THB)** of upfront capital, and also moves the launch date by about three quarters — see diff --git a/docs/fleet-calculator.html b/docs/fleet-calculator.html index 8150abc..54290d0 100644 --- a/docs/fleet-calculator.html +++ b/docs/fleet-calculator.html @@ -236,6 +236,12 @@ document.documentElement.setAttribute("data-theme",t);})();
+BOI. The capex blocks in total-investment.md are vendor prices without Thai import duty or + VAT, so they already assume BOI promotion: machinery imported under it pays no duty (Investment + Promotion Act section 28) and, with the duty, no import VAT (Revenue Department, BOI OSOS FAQ). + "Not promoted" adds the duty on the imported machinery to the capex and shows the import VAT as cash + paid at the border, reclaimable as input tax. Raw material: no duty on compound for exported + records, 90 % off for domestic sales. Revenue is net of VAT (exports zero-rated, 7 % on domestic + sales passed on). Corporate income tax and BOI's CIT exemptions (solar, automation, R&D) are not + modelled.
Labour. Base salaries per role (revenue-model.md, its loaded rates divided by 1.3; the cutting engineer a team figure), plus the employer's 5 % social security up to the 17,500 THB ceiling, 25 % for overtime, bonus and PPE, and the company's health care for every member of staff, office @@ -355,7 +370,7 @@ document.documentElement.setAttribute("data-theme",t);})(); const S0 = { mode: "target", target: 1000000, spec: 20, grow: "classic", dMin: 2, cMin: 1, dFleet: 2, cFleet: 1, shifts: 2, hrs: 8, days: 300, eff: 65, rateD: 3, rateC: 2, specF: 100, - priceStd: 3.8, premSpec: 1.15, titleFee: 1155, cur: "USD", + priceStd: 3.8, premSpec: 1.15, titleFee: 1155, cur: "USD", boi: "on", exportShare: 70, }; // [group, id, label, value, unit, kind, source] const AS = []; @@ -433,6 +448,14 @@ grp("Money", [ ["capexC", "Capex per Classic beyond one", 375000, "USD", "doc", "total-investment.md: ~290 to 460k, no Newbilt price on file"], ["deprYears", "Depreciation period", 12.5, "years", "doc", "revenue-model.md: 10 to 15 years"], ]); +grp("BOI and imports", [ + ["impMach", "Imported machinery in the start-fleet capex", 2750000, "USD", "doc", "total-investment.md block midpoints at vendor prices: presses 1.0M, galvanics 485k, Sibert 250k, lathe system 435k, metrology 580k; added presses count as imported"], + ["dutyMach", "Import duty on that machinery without BOI", 5, "%", "est", "Estimate: Thai MFN averages 4.1 % on HS 8477 plastics machinery (customs-compliance.ai, March 2026), 0 to 10 % across HS 84; set per line once the HS codes are known"], + ["vatRate", "VAT", 7, "%", "doc", "Thai VAT; with BOI duty exemption the import VAT is exempt too (Revenue Department, BOI OSOS FAQ; boi.md)"], + ["pvcImp", "Share of PVC compound imported", 100, "%", "est", "Estimate: record-grade compound from the specialist suppliers"], + ["dutyPVC", "Import duty on PVC compound without BOI", 5, "%", "est", "Estimate; no Thai tariff line checked for record compound yet"], + ["boiRawRed", "BOI duty reduction on raw material for domestic sales", 90, "%", "doc", "boi.md: exempt for export production (section 36(1)), up to 90 % off for domestic sales (section 30)"], +]); grp("Materials and packaging", [ ["pvcPrice", "PVC compound", 2.3, "USD/kg", "doc", "revenue-model.md: 1.75 to 2.90 USD/kg record grade"], ["labelCost", "Labels, a pair", 0.06, "USD", "doc", "revenue-model.md: 0.03 to 0.09"], @@ -597,13 +620,19 @@ function headsOf(r) { }; } // Money a year in USD. Lines: [group, label, USD, basis]. -function econ(r, b) { +function econ(r, b, boiOn = S.boi !== "off") { const fx = A.thbUsd > 0 ? A.thbUsd : 33, t2u = v => v / fx; const X = r.X, pressed = X * (1 + A.reject / 100), st = X - r.sp, L = []; const add = (g, l, v, s) => L.push([g, l, v, s]); const revStd = st * S.priceStd, revSpec = r.sp * (S.priceStd + S.premSpec), revTitle = r.titles * S.titleFee; const rev = revStd + revSpec + revTitle; add("mat", "PVC compound", r.compound * 1000 * A.pvcPrice, `${f0(r.compound)} t at ${f2(A.pvcPrice)} USD/kg incl. rejects; trim back as regrind`); + const expSh = Math.min(100, Math.max(0, S.exportShare)) / 100; + const pvcImported = r.compound * 1000 * A.pvcPrice * A.pvcImp / 100; + const pvcDuty = pvcImported * A.dutyPVC / 100 * (boiOn ? (1 - expSh) * (1 - A.boiRawRed / 100) : 1); + add("mat", "Import duty on PVC compound", pvcDuty, boiOn + ? `BOI: none on the ${pct(expSh)} exported, ${f0(A.boiRawRed)} % off the rest` + : `${f1(A.dutyPVC)} % on ${pct(A.pvcImp / 100)} imported compound, no BOI`); add("mat", "Labels", pressed * A.labelCost, "a printed pair per pressed record"); add("pack", "Inner sleeves", X * A.sleeveCost, ""); add("pack", "Jackets (printed cartons)", X * A.jacketCost, "local carton partners"); @@ -638,9 +667,12 @@ function econ(r, b) { `yearly for everyone, plus risk-factor tests for ${ppl(h.exposed)} on the press floor, in galvanics and maintenance`); const sum = gs => L.filter(l => gs.includes(l[0])).reduce((a, l) => a + l[2], 0); const direct = L.reduce((a, l) => a + l[2], 0), contrib = rev - direct, ebitda = contrib - A.overheads; - const capex = A.capexBase + (r.D - 2) * A.capexD + (r.C - 1) * A.capexC, depr = capex / Math.max(1, A.deprYears); + const fleetDelta = (r.D - 2) * A.capexD + (r.C - 1) * A.capexC; + const imp = Math.max(0, A.impMach + fleetDelta); + const dutyM = boiOn ? 0 : imp * A.dutyMach / 100, vatM = boiOn ? 0 : (imp + dutyM) * A.vatRate / 100; + const capex = A.capexBase + fleetDelta + dutyM, depr = capex / Math.max(1, A.deprYears); return { rev, revStd, revSpec, revTitle, L, sum, direct, contrib, ebitda, capex, depr, op: ebitda - depr, - payback: ebitda > 0 ? capex / ebitda : Infinity, heads: h }; + payback: ebitda > 0 ? capex / ebitda : Infinity, heads: h, imp, dutyM, vatM, pvcDuty, boiOn }; } function scenario() { const b = basis(S); @@ -680,7 +712,7 @@ function render() { $("specV").textContent = S.spec + " %"; $("targetBox").hidden = S.mode !== "target"; $("fleetBox").hidden = S.mode !== "fleet"; - for (const g of ["mode", "grow", "cur"]) for (const bt of $(g).children) bt.classList.toggle("on", bt.dataset.v === S[g]); + for (const g of ["mode", "grow", "cur", "boi"]) for (const bt of $(g).children) bt.classList.toggle("on", bt.dataset.v === S[g]); const cs = caseNow(); for (const bt of $("case").children) bt.classList.toggle("on", bt.dataset.v === cs); @@ -738,6 +770,11 @@ function render() { kpi(money(e.op), "operating profit after depreciation") + kpi(perRec(e.direct), "direct cost per record") + kpi(isFinite(e.payback) ? f1(e.payback) + " years" : "never", `payback on ${money(e.capex)} capex`); + const eOn = econ(r, b, true), eOff = econ(r, b, false); + const pb = x => isFinite(x.payback) ? f1(x.payback) + " years" : "none"; + $("boiNote").innerHTML = e.boiOn + ? `