Initial commit
This commit is contained in:
commit
41d230d524
163 files changed
+11500
No files matched your search
@@ -0,0 +1,205 @@
|
||||
// ==========================================
|
||||
// PROFILE: ДОГОВОР
|
||||
// ==========================================
|
||||
#import "../../domain/document.typ": document-profile, fail
|
||||
#import "../../domain/attachments.typ": attachment-set
|
||||
#import "../../domain/parties.typ": validate-parties, signer
|
||||
#import "../../shared/numbering.typ": attachment_numbering
|
||||
#import "../foundation.typ": apply-foundation
|
||||
#import "../components.typ": appendix-heading, multi-party-signing, requisites-table
|
||||
|
||||
#let contract-section(
|
||||
id,
|
||||
title,
|
||||
body,
|
||||
number: auto,
|
||||
level: 1,
|
||||
) = {
|
||||
if type(id) != str or id.trim() == "" {
|
||||
fail("contract-section.id", "нужна непустая строка")
|
||||
}
|
||||
if type(title) not in (str, content) {
|
||||
fail("contract-section.title", "ожидались str или content")
|
||||
}
|
||||
if type(body) not in (content, function) {
|
||||
fail("contract-section.body", "ожидались content или function")
|
||||
}
|
||||
if type(level) != int or level < 1 {
|
||||
fail("contract-section.level", "ожидалось положительное целое число")
|
||||
}
|
||||
(
|
||||
kind: "contract-section",
|
||||
id: id,
|
||||
title: title,
|
||||
body: body,
|
||||
number: number,
|
||||
level: level,
|
||||
)
|
||||
}
|
||||
|
||||
#let validate-sections(sections) = {
|
||||
if type(sections) != array {
|
||||
fail("contract.sections", "ожидался array")
|
||||
}
|
||||
let seen = ()
|
||||
for section in sections {
|
||||
if type(section) != dictionary or section.at("kind", default: none) != "contract-section" {
|
||||
fail("contract.sections", "каждый элемент должен быть contract-section")
|
||||
}
|
||||
if section.id in seen { fail("contract.sections", "повторяющийся id " + repr(section.id)) }
|
||||
seen.push(section.id)
|
||||
}
|
||||
sections
|
||||
}
|
||||
|
||||
#let normalize-contract(metadata) = {
|
||||
if type(metadata.attachments) == array {
|
||||
metadata.insert("attachments", attachment-set(items: metadata.attachments))
|
||||
}
|
||||
metadata
|
||||
}
|
||||
|
||||
#let validate-contract(metadata) = {
|
||||
if type(metadata.title) not in (str, content) {
|
||||
fail("contract.title", "ожидались str или content")
|
||||
}
|
||||
if metadata.number == none {
|
||||
fail("contract.number", "номер договора обязателен")
|
||||
}
|
||||
let _ = validate-parties(metadata.parties, minimum: 2)
|
||||
let _ = validate-sections(metadata.sections)
|
||||
if type(metadata.attachments) != dictionary or metadata.attachments.at("kind", default: none) != "attachment-set" {
|
||||
fail("contract.attachments", "ожидался attachment-set")
|
||||
}
|
||||
metadata
|
||||
}
|
||||
|
||||
#let contract-preamble(data) = {
|
||||
if data.preamble == auto {
|
||||
[Стороны, указанные в разделе «Реквизиты и подписи сторон», заключили настоящий договор о нижеследующем.]
|
||||
} else {
|
||||
data.preamble
|
||||
}
|
||||
}
|
||||
|
||||
#let render-contract-sections(sections) = {
|
||||
for (index, section) in sections.enumerate() {
|
||||
let number = if section.number == auto { index + 1 } else { section.number }
|
||||
heading(level: section.level, numbering: none)[#number. #upper(section.title)]
|
||||
if type(section.body) == function { (section.body)() } else { section.body }
|
||||
}
|
||||
}
|
||||
|
||||
#let signing-parties(parties, include-media: true) = {
|
||||
parties.map(item => {
|
||||
if item.representative == none or include-media {
|
||||
item
|
||||
} else {
|
||||
let person = item.representative
|
||||
let clean-person = signer(
|
||||
person.name,
|
||||
person.title,
|
||||
basis: person.basis,
|
||||
signature: none,
|
||||
stamp: none,
|
||||
)
|
||||
let clean-item = item
|
||||
clean-item.insert("representative", clean-person)
|
||||
clean-item
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#let render-contract-attachments(attachments) = {
|
||||
for (index, item) in attachments.items.enumerate() {
|
||||
pagebreak()
|
||||
let source-number = if item.number == auto { index + attachments.start } else { item.number }
|
||||
let display-number = attachment_numbering(attachments.numbering, source-number)
|
||||
appendix-heading(item, display-number)
|
||||
v(0.5cm)
|
||||
if type(item.body) == function { (item.body)() } else { item.body }
|
||||
}
|
||||
}
|
||||
|
||||
#let render-contract(body, ctx) = {
|
||||
let data = ctx.metadata
|
||||
let include-media = ctx.options.mode == "final"
|
||||
let media-policy = if include-media { ctx.options.at("media-policy") } else { "reserve-space" }
|
||||
let signing = signing-parties(data.parties, include-media: include-media)
|
||||
let composed = [
|
||||
#set heading(numbering: "1.1")
|
||||
#show heading: it => {
|
||||
set text(font: "Times New Roman", size: 11pt, weight: "bold", hyphenate: false)
|
||||
set par(first-line-indent: 0pt, justify: false)
|
||||
v(1em, weak: true)
|
||||
block(sticky: true, width: 100%)[#it]
|
||||
v(0.5em)
|
||||
}
|
||||
|
||||
#align(center)[
|
||||
#text(weight: "bold", size: 14pt)[#upper(data.title)] \
|
||||
№ #data.number
|
||||
]
|
||||
#v(0.7cm)
|
||||
#grid(
|
||||
columns: (1fr, 1fr),
|
||||
[#data.place],
|
||||
align(right)[#data.date],
|
||||
)
|
||||
#v(0.8cm)
|
||||
#contract-preamble(data)
|
||||
#v(0.6cm)
|
||||
#if data.sections.len() > 0 { render-contract-sections(data.sections) }
|
||||
#body
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#heading(numbering: none)[РЕКВИЗИТЫ И ПОДПИСИ СТОРОН]
|
||||
#requisites-table(data.parties)
|
||||
#v(1cm)
|
||||
#multi-party-signing(signing, media_policy: media-policy)
|
||||
|
||||
#if data.attachments.items.len() > 0 {
|
||||
render-contract-attachments(data.attachments)
|
||||
}
|
||||
]
|
||||
|
||||
apply-foundation(
|
||||
composed,
|
||||
ctx: ctx,
|
||||
tokens: (
|
||||
text-font: "Times New Roman",
|
||||
text-size: 11pt,
|
||||
line-height: 1.15em,
|
||||
page-margin: (left: 2.5cm, right: 2cm, top: 2cm, bottom: 2cm),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#let contract-profile(
|
||||
number: none,
|
||||
date: none,
|
||||
place: "Екатеринбург",
|
||||
title: "Договор",
|
||||
parties: (),
|
||||
preamble: auto,
|
||||
sections: (),
|
||||
attachments: attachment-set(),
|
||||
) = {
|
||||
document-profile(
|
||||
"contract",
|
||||
render-contract,
|
||||
metadata: (
|
||||
number: number,
|
||||
date: date,
|
||||
place: place,
|
||||
title: title,
|
||||
parties: parties,
|
||||
preamble: preamble,
|
||||
sections: sections,
|
||||
attachments: attachments,
|
||||
bibliographies: (),
|
||||
),
|
||||
normalize: normalize-contract,
|
||||
validate: validate-contract,
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user