// contract-print.jsx — друкований бланк договору на розроблення проєктної документації. // Багатосторінковий A4: тіло (16 розділів) + Додатки 1–4. Перемикач Виконавця ТОВ/ФОП, // логіка ПДВ, підстановка даних договору/замовника, маркування ключових місць. // Потребує: contract-clauses.jsx, window.moneyInWords (invoice-template.jsx), window.COMPANY(_FOP). const CT_MONTHS = ["січня","лютого","березня","квітня","травня","червня","липня","серпня","вересня","жовтня","листопада","грудня"]; function ctLongDate(iso) { if (!iso) return "«___» ____________ 20___ р."; const d = new Date(iso + (iso.length <= 10 ? "T00:00:00" : "")); if (isNaN(d)) return iso; return `«${String(d.getDate()).padStart(2,"0")}» ${CT_MONTHS[d.getMonth()]} ${d.getFullYear()} р.`; } function ctEsc(s){ return String(s).replace(/&/g,"&").replace(//g,">"); } function ctHtml(text, tokens){ let s = ctEsc(text); s = s.replace(/\{\{(\w+)\}\}/g, (m,k) => { const v = (tokens[k] != null && tokens[k] !== "") ? tokens[k] : "________"; return `${ctEsc(v)}`; }); s = s.replace(/\[[^\]]+\]/g, (m) => `${m}`); return s; } function CtPara({ text, tokens, cls }) { return

; } function ctMoney(n){ return Number(n||0).toLocaleString("uk-UA", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } // Реквізити сторін (Розділ 16 / низ додатків) function CtReqs({ exec, client, withApprove }) { const edLabel = exec.edrpouLabel || "Код ЄДРПОУ"; return (

ВИКОНАВЕЦЬ:
{exec.fullNameUpper || exec.fullName}
{exec.address}
{edLabel} {exec.edrpou}
{exec.vatId &&
ІПН {exec.vatId}
} {!exec.vatPayer &&
{exec.taxNote || "не є платником ПДВ"}
}
IBAN {exec.iban}
в {exec.bank}{exec.mfo ? `, МФО ${exec.mfo}` : ""}
Тел.: {exec.phone}
E-mail: {exec.email}
{exec.directorRole}
{exec.directorSign || exec.directorFull}
М.П.
ЗАМОВНИК:
{client ? client.name : [НАЙМЕНУВАННЯ ЗАМОВНИКА]}
Юридична та фактична адреса: {client && client.address ? client.address : [_______]}
Код ЄДРПОУ {client && client.edrpou ? client.edrpou : [______]}
р/р UA[__________________]
в [найменування установи банку], МФО [____]
E-mail: {client && client.contact && client.contact.email ? client.contact.email : [____]}
Тел.: {client && client.contact && client.contact.phone ? client.contact.phone : [____]}
{client && client.contact ? client.contact.role : [посада керівника замовника]}
{client && client.contact ? client.contact.name : [Ім'я ПРІЗВИЩЕ]}
М.П.
); } function ContractSheet({ children, label }) { return (
{children}
{(window.COMPANY||{}).tmText}
{(window.COMPANY||{}).tmCert}
🇺🇦 Слава Україні · Героям слава
{label || ""}
); } function ContractPrintDoc({ contract, onClose }) { React.useEffect(() => { const onKey = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [onClose]); const [entity, setEntity] = React.useState(contract.execEntity || "tov"); const exec = window.execEntity(entity); const client = window.getClient(contract.client); const obj = window.getObject(contract.obj); // ── суми та ПДВ ── const base = Number(contract.total) || 0; // ціна без ПДВ (база для розрахунків) const vat = exec.vatPayer ? Math.round(base * 0.20 * 100) / 100 : 0; const price = base + vat; // договірна ціна (з ПДВ для ТОВ) const vatInline = exec.vatPayer ? `, у тому числі ПДВ 20 % — ${ctMoney(vat)} грн (${window.moneyInWords(vat)})` : `. ${exec.taxNote ? exec.taxNote.charAt(0).toUpperCase()+exec.taxNote.slice(1) : "Виконавець не є платником ПДВ"}`; const execRep = entity === "fop" ? exec.directorGen : `${(exec.directorRole||"директорки").toLowerCase()} ${exec.directorGen}`; const endDate = (contract.schedule && contract.schedule.length) ? ctLongDate(contract.schedule[contract.schedule.length-1].dueDate) : "«___» ____________ 20___ р."; const year = contract.date ? new Date(contract.date).getFullYear() : new Date().getFullYear(); const tokens = { OBJ: obj ? obj.name : "", OBJ_ADDR: obj && obj.address ? obj.address : "", CLIENT: client ? client.name : "[НАЙМЕНУВАННЯ ЗАМОВНИКА]", CLIENT_REP_ROLE: client && client.contact ? client.contact.role : "[посада керівника]", CLIENT_REP: client && client.contact ? window.declineFio(client.contact.name, "gen") : "[Прізвище Ім'я По батькові]", CLIENT_BASIS: "[статуту/положення/довіреності]", EXEC_FULL: exec.fullNameUpper || exec.fullName, EXEC_REP: execRep, EXEC_BASIS: exec.directorBasis, EDRPOU_LABEL: (exec.edrpouLabel || "ЄДРПОУ"), EDRPOU: exec.edrpou, SUM: ctMoney(price), SUM_W: window.moneyInWords(price), VAT_INLINE: vatInline, FUNDING: contract.funding || "Державний бюджет України (загальний фонд), КЕКВ 3132 «Капітальний ремонт інших об'єктів»", END_DATE: endDate, YEAR: String(year), }; const num = contract.number || "________"; const dateUA = ctLongDate(contract.date); const gip = contract.gip || "________"; const doPrint = () => window.print(); return (
Договір № {num}{obj ? ` · ${obj.name.slice(0,40)}${obj.name.length>40?"…":""}` : ""}
Виконавець:
{/* ───────── СТОРІНКА: ДОГОВІР ───────── */}

ДОГОВІР № {num}

про виконання робіт із розроблення проєктної документації та супроводу експертизи
по об'єкту: «{obj ? obj.name : "[найменування об'єкта]"}»
м. {exec.city || "Одеса"} {dateUA}
{window.CONTRACT_CLAUSES.map((sec) => (

{sec.n}. {sec.title}

{sec.paras.map((p, i) => )}
))}

16. РЕКВІЗИТИ СТОРІН

{/* ───────── ДОДАТОК 1 — ЗАВДАННЯ ───────── */}

ЗАВДАННЯ НА ПРОЄКТУВАННЯ

по об'єкту: «{obj ? obj.name : "[найменування об'єкта]"}»
(відповідно до Додатка Б ДБН А.2.2-3:2014 «Склад та зміст проєктної документації на будівництво»)
    {window.CONTRACT_TASK_POINTS.map((t, i) => (
  1. {t}
  2. ))}

Примітка 1. Завдання на проєктування затверджується замовником та погоджується проєктувальником.
Примітка 2. Склад завдання може змінюватися відповідно до особливостей об'єктів, що проєктуються.

{/* ───────── ДОДАТОК 2 — КАЛЕНДАРНИЙ ПЛАН ───────── */}

КАЛЕНДАРНИЙ ПЛАН

робіт із розроблення проєктної документації та супроводу експертизи
по об'єкту: «{obj ? obj.name : "[найменування об'єкта]"}»
{(contract.schedule && contract.schedule.length ? contract.schedule : [{stage:"Роботи з розроблення проєктної документації та супроводу експертизи"}]).map((s, i) => ( ))}
№ з/пНайменування робітПочатокЗакінчення
{i+1} {s.stage} {i===0 ? "дата підписання Договору" : ctLongDate(contract.schedule[i-1] && contract.schedule[i-1].dueDate)} {ctLongDate(s.dueDate) }
{/* ───────── ДОДАТОК 3 — ПРОТОКОЛ ЦІНИ ───────── */}

ПРОТОКОЛ ПОГОДЖЕННЯ ДОГОВІРНОЇ ЦІНИ

робіт із розроблення проєктної документації та супроводу експертизи
по об'єкту: «{obj ? obj.name : "[найменування об'єкта]"}»

Ціна Договору (договірна ціна) є твердою і становить {ctMoney(price)} грн ({window.moneyInWords(price)}).

{/* ───────── ДОДАТОК 4 — КОШТОРИСИ ───────── */}

КОШТОРИСИ

на роботи з розроблення проєктної документації та супроводу експертизи
по об'єкту: «{obj ? obj.name : "[найменування об'єкта]"}»
Замовник: {client ? client.name : "________"}
Виконавець: {exec.fullName}
Клас наслідків: {contract.consequenceClass ? {contract.consequenceClass} : СС1}
Стадія проєктування: {contract.stage ? {contract.stage} : Робочий проєкт (РП)}
Склад Додатка № 4:
  • Кошторис № 1 — Зведений кошторис на проєктні, науково-проєктні, вишукувальні роботи (форма 1-П)
  • Кошторис № 2 — Кошторис на виконання робіт «Проєктні роботи» (форма 3-П)
  • Кошторис № 3 — Кошторис на виконання робіт «Реєстрація проєктної документації в ЄДЕССБ» (форма 3-П)
  • Кошторис № 4 — Кошторис на проєктні, науково-проєктні, вишукувальні роботи «Експертиза» (форма 2-П)
  • Розрахунок показника кошторисної вартості в розрахунку на 1 людино-день (коефіцієнт зміни рівня заробітної плати)

ЗВЕДЕНИЙ КОШТОРИС № 1 · Форма № 1-П

{(contract.kosht && contract.kosht.length ? contract.kosht : null) ? contract.kosht.map((k, i) => ( )) : ( )}
Ч.ч.Стадія / перелік робітФормаВартість робіт, грн
{i+1}{k.name}{k.form}{ctMoney(k.sum)}
1Технічне обстеження3-П_____
2Проєктні роботи3-П_____
3Реєстрація проєктної документації в ЄДЕССБ3-П_____
4Експертиза проєктної документації2-П_____
Разом{ctMoney(contract.kosht && contract.kosht.length ? window.doksKoshtTotal(contract.kosht) : base)}

{contract.doksKey ? <>Кошторис підтягнуто з Робочого простору (Докс), проєкт {contract.doksKey}. Детальні форми 1-П, 2-П, 3-П та розрахунок коефіцієнта додаються окремими аркушами. : <>Детальні кошториси (форми 1-П, 2-П, 3-П) та розрахунок коефіцієнта зміни рівня заробітної плати додаються окремими аркушами відповідно до Настанови (наказ Мінрегіону № 281 від 01.11.2021). Значення вартості заповнюються за результатами кошторисного розрахунку по об'єкту.}

Всього за зведеним кошторисом — {ctMoney(price)} грн ({window.moneyInWords(price)})

Керівник проєктної організації{exec.directorSign || exec.directorFull}
Головний інженер проєкту (ГАП){gip}
Кошторис склала, провідна інженерка з ПКРАліса АПОТОВСЬКА
М.П.
); } // Шапка додатка з блоками ПОГОДЖЕНО/ЗАТВЕРДЖУЮ (Додаток 1) function CtAppendixHead({ n, num, dateUA, exec, client }) { return (
Додаток № {n}
до Договору № {num}
від {dateUA}
ПОГОДЖЕНО:
Виконавець · {exec.directorRole}
{exec.fullNameUpper || exec.fullName}
{exec.directorSign}
М.П. «___» __________ 20__ р.
ЗАТВЕРДЖУЮ:
Замовник · {client && client.contact ? client.contact.role : [посада]}
{client ? client.name : [НАЙМЕНУВАННЯ ЗАМОВНИКА]}
{client && client.contact ? client.contact.name : [Ім'я ПРІЗВИЩЕ]}
М.П. «___» __________ 20__ р.
); } function CtAppendixSimpleHead({ n, num, dateUA }) { return
Додаток № {n}
до Договору № {num}
від {dateUA}
; } function ContractPrintStyles() { return ( ); } window.ContractPrintDoc = ContractPrintDoc;