ConusAI vendor v0.1.0-beta.114
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-beta.114
2026-11-14 09:56:45 +00:00
commit 1ce8d23c35
867 changed files with 122104 additions and 0 deletions
+171
View File
@@ -0,0 +1,171 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
import { businessRefusalNotices, businessServiceNotices } from "@conusai-kit/business/refusals"
import { type Container, notFound, serviceRefusal, type TransportCaller } from "@conusai-kit/core"
import type { I18n } from "@conusai-kit/i18n"
import { Decimal, Money } from "@conusai-kit/money"
import { Quantity } from "@conusai-kit/money/units"
import { type ProjectPage, projectPage } from "@conusai-kit/ui"
import { Can } from "@conusai-kit/ui/data"
import {
FactList,
Page,
PageHeader,
PageSection,
type ServiceNotice,
ServiceStatePage,
serviceNotice,
} from "@conusai-kit/ui/patterns"
import * as contracts from "../contract/index.js"
import { en } from "../i18n/en.js"
import { FiscalAction, InvoiceForm, Invoices, SeriesForm, UblDownload } from "./controls.js"
import type { Labels, Messages } from "./labels.js"
type Data = { labels: Labels } & (
| {
kind: "list"
invoices: { rows: contracts.InvoiceView[]; after?: string | undefined }
series: contracts.SeriesView[]
}
| {
kind: "invoice"
invoice: contracts.InvoiceView
series: contracts.SeriesView[]
/** The amounts, quantities and rates as the reader writes them, formatted on the server. */
shown: { payable: string; lines: string[] }
}
| { kind: "state"; notice: ServiceNotice }
)
export const invoicingPage: ProjectPage<TransportCaller, I18n, Container, Data> = projectPage({
async load({ slugs, segments, caller, i18n }) {
const messages = Object.fromEntries(
Object.keys(en).map((key) => [key, i18n.message(`invoicing.${key}`)]),
) as Messages
const labels: Labels = {
...messages,
locale: i18n.locale,
refusals: businessRefusalNotices(i18n.locale, {
conflict: messages.conflict,
revision_conflict: messages.conflict,
invalid: messages.invalid,
}),
}
const [id, ...rest] = segments
if (rest.length || (id !== undefined && !contracts.invoiceId.safeParse(id).success)) throw notFound()
try {
const allSeries: contracts.SeriesView[] = []
let after: string | undefined
const seen = new Set<string>()
let pages = 0
// Numbering choices are bounded; refusal is preferable to silently missing a series.
do {
if (pages++ >= 20) throw serviceRefusal("degraded")
const page = await caller.call(contracts.series, { org: slugs.org, ...(after ? { after } : {}) })
allSeries.push(...page.rows)
after = page.after
if (allSeries.length > 1000 || (after && seen.has(after))) throw serviceRefusal("degraded")
if (after) seen.add(after)
} while (after)
if (id === undefined)
return {
kind: "list",
labels,
invoices: await caller.call(contracts.invoices, { org: slugs.org }),
series: allSeries,
}
const invoice = await caller.call(contracts.invoice, { org: slugs.org, invoiceId: id })
return { kind: "invoice", labels, invoice, series: allSeries, shown: shownOf(invoice, labels, i18n) }
} catch (error) {
const notice = serviceNotice(error, businessServiceNotices(i18n.locale))
if (!notice) throw error
return { kind: "state", labels, notice }
}
},
View({ slugs, data }) {
const labels = data.labels
const href = `/${slugs.org}/${slugs.workspace}/${slugs.project}/invoicing`
if (data.kind === "state") return <ServiceStatePage title={labels.title} notice={data.notice} />
if (data.kind === "list")
return (
<Page>
<PageHeader title={labels.title} description={labels.intro} />
<p>{labels.fiscalNotice}</p>
<Invoices slugs={slugs} seed={data.invoices} href={href} labels={labels} />
<Can permission="invoicing.invoice.write">
<InvoiceForm slugs={slugs} labels={labels} series={data.series} href={href} />
</Can>
<Can permission="invoicing.series.manage">
<SeriesForm slugs={slugs} labels={labels} />
</Can>
</Page>
)
const invoice = data.invoice
return (
<Page>
<PageHeader
title={invoice.number ?? labels.draft}
description={`${labels[invoice.status]} · ${data.shown.payable}`}
/>
<a href={href}>{labels.back}</a>
<p>{labels.fiscalNotice}</p>
<PageSection title={labels.saved}>
<FactList
facts={[
{ label: labels.revision, value: invoice.revision },
{ label: labels.seller, value: invoice.data.seller.name },
{ label: labels.buyer, value: invoice.data.buyer.name },
{ label: labels.issueDate, value: invoice.data.issue_date },
{ label: labels.dueDate, value: invoice.data.due_date ?? "—" },
{ label: labels.currency, value: invoice.data.currency },
{ label: labels.buyerReference, value: invoice.data.buyer_reference },
...invoice.data.lines.map((line, index) => ({
label: line.item_name,
value: data.shown.lines[index] ?? "",
})),
{ label: labels.payable, value: data.shown.payable },
]}
/>
</PageSection>
{invoice.status === "draft" ? (
<>
<Can permission="invoicing.invoice.write">
<InvoiceForm slugs={slugs} invoice={invoice} labels={labels} series={data.series} href={href} />
</Can>
<Can permission="invoicing.invoice.issue">
<FiscalAction slugs={slugs} invoice={invoice} operation="issue" series={data.series} labels={labels} />
</Can>
</>
) : null}
{invoice.status === "issued" ? (
<>
<Can permission="invoicing.invoice.credit">
<FiscalAction slugs={slugs} invoice={invoice} operation="credit" series={data.series} labels={labels} />
</Can>
<Can permission="invoicing.invoice.void">
<FiscalAction slugs={slugs} invoice={invoice} operation="void" series={data.series} labels={labels} />
</Can>
</>
) : null}
{invoice.status !== "draft" ? (
<PageSection title={labels.download}>
<UblDownload slugs={slugs} invoice={invoice} labels={labels} />
</PageSection>
) : null}
</Page>
)
},
})
/** Exact values in the reader's form (`12,50 €`, `3 vnt.`, `21 %`), never through a float. */
function shownOf(invoice: contracts.InvoiceView, labels: Labels, i18n: I18n): { payable: string; lines: string[] } {
return {
payable: i18n.money(Money.parse(invoice.payable)),
lines: invoice.data.lines.map((line) =>
[
`${i18n.quantity(Quantity.of(line.quantity, line.unit))} × ${i18n.money(Money.parse(line.net_price))}`,
`${labels.vatCategory}: ${line.vat_category}`,
`${labels.vatRate}: ${line.vat_rate ? i18n.percent(Decimal.parse(line.vat_rate)) : "—"}`,
...(line.exemption_reason ? [line.exemption_reason] : []),
].join(" · "),
),
}
}