@things-factory/invoice 10.1.206 → 10.1.209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist-client/document/document-form.d.ts +2 -1
  2. package/dist-client/document/document-form.js +3 -2
  3. package/dist-client/document/document-form.js.map +1 -1
  4. package/dist-client/document/document-print.d.ts +2 -1
  5. package/dist-client/document/document-print.js +2 -2
  6. package/dist-client/document/document-print.js.map +1 -1
  7. package/dist-client/entity360/invoice-360.d.ts +8 -0
  8. package/dist-client/entity360/invoice-360.js +12 -2
  9. package/dist-client/entity360/invoice-360.js.map +1 -1
  10. package/dist-client/invoice-files.d.ts +32 -0
  11. package/dist-client/invoice-files.js +249 -0
  12. package/dist-client/invoice-files.js.map +1 -0
  13. package/dist-client/pages/invoice-editor.d.ts +16 -0
  14. package/dist-client/pages/invoice-editor.js +88 -3
  15. package/dist-client/pages/invoice-editor.js.map +1 -1
  16. package/dist-client/pages/invoice-list.js +8 -4
  17. package/dist-client/pages/invoice-list.js.map +1 -1
  18. package/dist-client/tsconfig.tsbuildinfo +1 -1
  19. package/dist-server/service/index.d.ts +1 -0
  20. package/dist-server/service/index.js +1 -0
  21. package/dist-server/service/index.js.map +1 -1
  22. package/dist-server/service/invoice/invoice-files.d.ts +14 -0
  23. package/dist-server/service/invoice/invoice-files.js +43 -0
  24. package/dist-server/service/invoice/invoice-files.js.map +1 -0
  25. package/dist-server/service/invoice/invoice-mutation.d.ts +2 -0
  26. package/dist-server/service/invoice/invoice-mutation.js +18 -0
  27. package/dist-server/service/invoice/invoice-mutation.js.map +1 -1
  28. package/dist-server/service/invoice/invoice-query.d.ts +4 -0
  29. package/dist-server/service/invoice/invoice-query.js +23 -0
  30. package/dist-server/service/invoice/invoice-query.js.map +1 -1
  31. package/dist-server/service/invoice/invoice-service.js +5 -0
  32. package/dist-server/service/invoice/invoice-service.js.map +1 -1
  33. package/dist-server/service/invoice/invoice-type.d.ts +1 -0
  34. package/dist-server/service/invoice/invoice-type.js +4 -0
  35. package/dist-server/service/invoice/invoice-type.js.map +1 -1
  36. package/dist-server/service/invoice/invoice.d.ts +3 -0
  37. package/dist-server/service/invoice/invoice.js +11 -0
  38. package/dist-server/service/invoice/invoice.js.map +1 -1
  39. package/dist-server/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +9 -4
  41. package/translations/en.json +13 -1
  42. package/translations/es.json +13 -1
  43. package/translations/ja.json +13 -1
  44. package/translations/ko.json +13 -1
  45. package/translations/ms.json +13 -1
  46. package/translations/zh.json +13 -1
@@ -2,6 +2,12 @@ import '@operato/data-grist/ox-grist.js';
2
2
  import '@operato/list-state/ox-page-state.js';
3
3
  import { PageView } from '@operato/shell';
4
4
  import { type DocumentValue } from '../document/document-form';
5
+ import '../invoice-files';
6
+ type Party = {
7
+ id: string;
8
+ name: string;
9
+ businessNumber?: string | null;
10
+ };
5
11
  declare const InvoiceEditor_base: (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
6
12
  /**
7
13
  * 청구서 편집 — the head, the lines, the totals by tax kind and rate, and what an application links it to.
@@ -17,6 +23,9 @@ export declare class InvoiceEditor extends InvoiceEditor_base {
17
23
  error: unknown;
18
24
  busy: boolean;
19
25
  voidReason: string;
26
+ /** The counterparty search: what was typed, and what it found when more than one. */
27
+ partySearch: string;
28
+ partiesFound: Party[];
20
29
  gristConfig: any;
21
30
  private grist?;
22
31
  get editable(): boolean;
@@ -30,6 +39,13 @@ export declare class InvoiceEditor extends InvoiceEditor_base {
30
39
  pageUpdated(changes: any, lifecycle: any): Promise<void>;
31
40
  render(): import("lit-html").TemplateResult<1>;
32
41
  private renderTerms;
42
+ /**
43
+ * Who the other party is among the domain's counterparties - the buyer of a sale, the supplier of a purchase. Found by
44
+ * name or business number; choosing one writes its name and number onto the printed side, which stays editable.
45
+ */
46
+ private renderParty;
47
+ private chooseParty;
48
+ private findParties;
33
49
  private renderVoid;
34
50
  private changeTaxBasis;
35
51
  private configure;
@@ -16,8 +16,9 @@ import { documentLinesConfig, linesOf } from '../document/document-lines';
16
16
  import { documentHtml, printDocument } from '../document/document-print';
17
17
  import { invoiceStatusWord } from '../entity360/invoice-360';
18
18
  import { invoiceLinkSection } from '../invoice-attach';
19
+ import '../invoice-files';
19
20
  const FIELDS = `
20
- id number status direction currency language supplierName supplierAddress supplierRegistrationNumber buyerName buyerAddress
21
+ id number status direction currency language counterpartyId counterparty { id name } supplierName supplierAddress supplierRegistrationNumber buyerName buyerAddress
21
22
  buyerRegistrationNumber issueDate dueDate purchaseOrder paymentTerms bankDetails notes sourceReference taxBasis voidReason
22
23
  supplyAmount taxAmount totalAmount taxRounding currencyDigits
23
24
  items { position description quantity unitPrice discount taxKind taxRate supplyAmount receivedTaxAmount }
@@ -25,6 +26,7 @@ const FIELDS = `
25
26
  `;
26
27
  const HEAD = [
27
28
  'number',
29
+ 'counterpartyId',
28
30
  'direction',
29
31
  'currency',
30
32
  'language',
@@ -59,6 +61,9 @@ let InvoiceEditor = class InvoiceEditor extends localize(i18next)(PageView) {
59
61
  this.error = null;
60
62
  this.busy = false;
61
63
  this.voidReason = '';
64
+ /** The counterparty search: what was typed, and what it found when more than one. */
65
+ this.partySearch = '';
66
+ this.partiesFound = [];
62
67
  }
63
68
  static { this.styles = [
64
69
  FormFieldStyles,
@@ -71,6 +76,14 @@ let InvoiceEditor = class InvoiceEditor extends localize(i18next)(PageView) {
71
76
  ox-grist {
72
77
  height: calc(var(--form-element-height-medium) * 10);
73
78
  }
79
+ .party {
80
+ display: flex;
81
+ gap: var(--spacing-small);
82
+ align-items: center;
83
+ }
84
+ .party input {
85
+ flex: 1;
86
+ }
74
87
  `
75
88
  ]; }
76
89
  get editable() {
@@ -113,7 +126,7 @@ let InvoiceEditor = class InvoiceEditor extends localize(i18next)(PageView) {
113
126
  <div class="page">
114
127
  <section class="page-section">
115
128
  <header class="page-section-header"><h3>${i18next.t('text.invoice-section-head')}</h3></header>
116
- ${renderDocumentHead(this.form, this.editable && !this.busy, patch => (this.form = { ...this.form, ...patch }), this.renderTerms())}
129
+ ${renderDocumentHead(this.form, this.editable && !this.busy, patch => (this.form = { ...this.form, ...patch }), this.renderTerms(), 'field.invoice-number')}
117
130
  </section>
118
131
  <section class="page-section">
119
132
  <header class="page-section-header"><h3>${i18next.t('text.invoice-section-lines')}</h3></header>
@@ -123,6 +136,10 @@ let InvoiceEditor = class InvoiceEditor extends localize(i18next)(PageView) {
123
136
  ? html `<section class="page-section">
124
137
  <header class="page-section-header"><h3>${i18next.t('text.invoice-section-totals')}</h3></header>
125
138
  ${renderDocumentTotals(this.invoice)}
139
+ </section>
140
+ <section class="page-section">
141
+ <header class="page-section-header"><h3>${i18next.t('text.invoice-section-files')}</h3></header>
142
+ <invoice-files .invoiceId=${this.invoice.id}></invoice-files>
126
143
  </section>`
127
144
  : nothing}
128
145
  ${links && this.invoice
@@ -137,7 +154,7 @@ let InvoiceEditor = class InvoiceEditor extends localize(i18next)(PageView) {
137
154
  }
138
155
  renderTerms() {
139
156
  const editable = this.editable && !this.busy;
140
- return html `<label
157
+ return html `${this.renderParty(editable)}<label
141
158
  >${i18next.t('field.invoice-due-date')}
142
159
  <input type="date" .value=${this.form.dueDate ?? ''} ?disabled=${!editable} @input=${(e) => (this.form = { ...this.form, dueDate: e.target.value })}
143
160
  /></label>
@@ -151,6 +168,66 @@ let InvoiceEditor = class InvoiceEditor extends localize(i18next)(PageView) {
151
168
  >`
152
169
  : nothing}`;
153
170
  }
171
+ /**
172
+ * Who the other party is among the domain's counterparties - the buyer of a sale, the supplier of a purchase. Found by
173
+ * name or business number; choosing one writes its name and number onto the printed side, which stays editable.
174
+ */
175
+ renderParty(editable) {
176
+ const chosen = this.form.counterparty;
177
+ return html `<label
178
+ >${i18next.t('field.invoice-counterparty')}
179
+ <span class="party">
180
+ <input
181
+ .value=${this.partySearch}
182
+ placeholder=${chosen?.name ?? i18next.t('text.invoice-counterparty-search')}
183
+ ?disabled=${!editable}
184
+ @input=${(e) => (this.partySearch = e.target.value)}
185
+ @keydown=${(e) => e.key === 'Enter' && this.findParties()}
186
+ />
187
+ <button ?disabled=${!editable} @click=${() => this.findParties()}>${i18next.t('button.invoice-counterparty-find')}</button>
188
+ ${chosen ? html `<button ?disabled=${!editable} @click=${() => this.chooseParty(null)}>${i18next.t('button.invoice-counterparty-clear')}</button>` : nothing}
189
+ </span>
190
+ ${this.partiesFound.length
191
+ ? html `<select ?disabled=${!editable} @change=${(e) => this.chooseParty(this.partiesFound.find(one => one.id === e.target.value) ?? null)}>
192
+ <option value="">${chosen?.name ?? ''}</option>
193
+ ${this.partiesFound.map(one => html `<option value=${one.id}>${one.name}${one.businessNumber ? ` (${one.businessNumber})` : ''}</option>`)}
194
+ </select>`
195
+ : nothing}
196
+ </label>`;
197
+ }
198
+ chooseParty(party) {
199
+ const side = this.form.direction === 'PURCHASE' ? 'supplier' : 'buyer';
200
+ this.form = {
201
+ ...this.form,
202
+ counterpartyId: party?.id ?? null,
203
+ counterparty: party,
204
+ ...(party ? { [`${side}Name`]: party.name, [`${side}RegistrationNumber`]: party.businessNumber ?? this.form[`${side}RegistrationNumber`] } : {})
205
+ };
206
+ this.partySearch = '';
207
+ this.partiesFound = [];
208
+ }
209
+ async findParties() {
210
+ await this.run(async () => {
211
+ const response = await client.query({
212
+ query: gql `
213
+ query ($search: String, $pagination: Pagination) {
214
+ counterparties: counterpartyChoices(search: $search, pagination: $pagination) {
215
+ items { id name businessNumber }
216
+ }
217
+ }
218
+ `,
219
+ variables: { search: this.partySearch.trim() || undefined, pagination: { page: 1, limit: 30 } },
220
+ fetchPolicy: 'no-cache'
221
+ });
222
+ if (response.errors?.length)
223
+ throw response;
224
+ const found = response.data.counterparties.items ?? [];
225
+ if (found.length === 1)
226
+ this.chooseParty(found[0]);
227
+ else
228
+ this.partiesFound = found;
229
+ });
230
+ }
154
231
  renderVoid() {
155
232
  return html `<section class="page-section">
156
233
  <header class="page-section-header">
@@ -312,6 +389,14 @@ __decorate([
312
389
  state(),
313
390
  __metadata("design:type", Object)
314
391
  ], InvoiceEditor.prototype, "voidReason", void 0);
392
+ __decorate([
393
+ state(),
394
+ __metadata("design:type", Object)
395
+ ], InvoiceEditor.prototype, "partySearch", void 0);
396
+ __decorate([
397
+ state(),
398
+ __metadata("design:type", Array)
399
+ ], InvoiceEditor.prototype, "partiesFound", void 0);
315
400
  __decorate([
316
401
  state(),
317
402
  __metadata("design:type", Object)
@@ -1 +1 @@
1
- {"version":3,"file":"invoice-editor.js","sourceRoot":"","sources":["../../client/pages/invoice-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\nimport '@operato/list-state/ox-page-state.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { navigate, PageView } from '@operato/shell'\nimport { ButtonStyles, CommonGristStyles, DocumentPageStyles, FormFieldStyles, ScrollbarStyles } from '@operato/styles'\n\nimport { DocumentFormStyles, renderDocumentHead, renderDocumentTotals, type DocumentValue } from '../document/document-form'\nimport { documentLinesConfig, linesOf } from '../document/document-lines'\nimport { documentHtml, printDocument } from '../document/document-print'\nimport { invoiceStatusWord } from '../entity360/invoice-360'\nimport { invoiceLinkSection } from '../invoice-attach'\n\nconst FIELDS = `\n id number status direction currency language supplierName supplierAddress supplierRegistrationNumber buyerName buyerAddress\n buyerRegistrationNumber issueDate dueDate purchaseOrder paymentTerms bankDetails notes sourceReference taxBasis voidReason\n supplyAmount taxAmount totalAmount taxRounding currencyDigits\n items { position description quantity unitPrice discount taxKind taxRate supplyAmount receivedTaxAmount }\n taxGroups { taxKind taxRate supplyAmount taxAmount }\n`\n\nconst HEAD = [\n 'number',\n 'direction',\n 'currency',\n 'language',\n 'supplierName',\n 'supplierAddress',\n 'supplierRegistrationNumber',\n 'buyerName',\n 'buyerAddress',\n 'buyerRegistrationNumber',\n 'issueDate',\n 'dueDate',\n 'purchaseOrder',\n 'paymentTerms',\n 'bankDetails',\n 'notes',\n 'sourceReference',\n 'taxBasis'\n]\n\nconst today = () => new Date().toLocaleDateString('en-CA')\n\n/**\n * 청구서 편집 — the head, the lines, the totals by tax kind and rate, and what an application links it to.\n *\n * A draft is written and saved; 「발행」 saves what is on screen and issues it, after which its amounts never change.\n * An issued invoice is voided with a reason, in its own section. While a request runs only the inputs wait.\n */\n@customElement('invoice-editor')\nexport class InvoiceEditor extends localize(i18next)(PageView) {\n static styles = [\n FormFieldStyles,\n ButtonStyles,\n DocumentPageStyles,\n CommonGristStyles,\n ScrollbarStyles,\n DocumentFormStyles,\n css`\n ox-grist {\n height: calc(var(--form-element-height-medium) * 10);\n }\n `\n ]\n\n @state() invoice: DocumentValue | null = null\n @state() form: DocumentValue = blank()\n @state() loading = false\n @state() error: unknown = null\n @state() busy = false\n @state() voidReason = ''\n @state() gristConfig: any\n\n @query('ox-grist') private grist?: DataGrist\n\n get editable() {\n return !this.invoice || this.invoice.status === 'DRAFT'\n }\n\n get context() {\n const actions: any[] = []\n if (this.editable) {\n actions.push({ title: i18next.t('button.save'), icon: 'save', action: () => this.save() })\n actions.push({ title: i18next.t('button.invoice-issue'), icon: 'send', emphasis: { raised: true }, action: () => this.issue() })\n }\n if (this.invoice) actions.push({ title: i18next.t('button.invoice-print'), icon: 'print', action: () => this.print() })\n return {\n title: this.invoice ? `${i18next.t('title.invoice')} ${this.invoice.number}` : i18next.t('title.invoice-new'),\n ...(this.invoice ? { description: invoiceStatusWord(this.invoice.status) } : {}),\n frame: 'document',\n /* Opened from the invoice list; the menu marks it. */\n menu: 'invoice-list',\n actions: this.error ? [] : actions\n }\n }\n\n async pageUpdated(changes: any, lifecycle: any) {\n if (!this.active || !(changes.active || changes.params)) return\n const id = lifecycle?.params?.id\n if (!id) {\n this.invoice = null\n this.form = blank()\n this.configure()\n this.updateContext()\n return\n }\n if (id !== this.invoice?.id) await this.load(id)\n }\n\n render() {\n const links = this.invoice ? invoiceLinkSection() : undefined\n return html`<ox-page-state .loading=${this.loading} .error=${this.error} @retry=${() => this.invoice && this.load(this.invoice.id)}>\n <div class=\"page\">\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.invoice-section-head')}</h3></header>\n ${renderDocumentHead(this.form, this.editable && !this.busy, patch => (this.form = { ...this.form, ...patch }), this.renderTerms())}\n </section>\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.invoice-section-lines')}</h3></header>\n <ox-grist mode=\"GRID\" .config=${this.gristConfig} .fetchHandler=${() => ({ total: this.form.items.length, records: this.form.items })}></ox-grist>\n </section>\n ${this.invoice\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.invoice-section-totals')}</h3></header>\n ${renderDocumentTotals(this.invoice)}\n </section>`\n : nothing}\n ${links && this.invoice\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${links.heading()}</h3></header>\n ${links.render(this.invoice as any)}\n </section>`\n : nothing}\n ${this.invoice?.status === 'ISSUED' ? this.renderVoid() : nothing}\n </div>\n </ox-page-state>`\n }\n\n private renderTerms() {\n const editable = this.editable && !this.busy\n return html`<label\n >${i18next.t('field.invoice-due-date')}\n <input type=\"date\" .value=${this.form.dueDate ?? ''} ?disabled=${!editable} @input=${(e: any) => (this.form = { ...this.form, dueDate: e.target.value })}\n /></label>\n ${this.form.direction === 'PURCHASE'\n ? html`<label\n >${i18next.t('field.invoice-tax-basis')}\n <select ?disabled=${!editable} @change=${(e: any) => this.changeTaxBasis(e.target.value)}>\n <option value=\"CALCULATED\" ?selected=${this.form.taxBasis !== 'RECEIVED'}>${i18next.t('text.invoice-tax-basis-calculated')}</option>\n <option value=\"RECEIVED\" ?selected=${this.form.taxBasis === 'RECEIVED'}>${i18next.t('text.invoice-tax-basis-received')}</option>\n </select></label\n >`\n : nothing}`\n }\n\n private renderVoid() {\n return html`<section class=\"page-section\">\n <header class=\"page-section-header\">\n <h3>${i18next.t('text.invoice-section-void')}</h3>\n <div class=\"page-section-actions\">\n <button danger ?disabled=${this.busy || !this.voidReason.trim()} @click=${() => this.void()}>${i18next.t('button.invoice-void')}</button>\n </div>\n </header>\n <div class=\"form\">\n <label class=\"wide\"\n >${i18next.t('field.invoice-void-reason')}\n <input .value=${this.voidReason} ?disabled=${this.busy} @input=${(e: any) => (this.voidReason = e.target.value)}\n /></label>\n </div>\n </section>`\n }\n\n private changeTaxBasis(taxBasis: string) {\n this.form = { ...this.form, items: linesOf(this.grist), taxBasis }\n this.configure()\n }\n\n private configure() {\n this.gristConfig = documentLinesConfig({ editable: this.editable, received: this.form.taxBasis === 'RECEIVED', currency: this.form.currency || 'KRW' })\n }\n\n private async load(id: string) {\n this.loading = true\n this.error = null\n try {\n const response = await client.query({ query: gql(`query ($id: String!) { invoice(id: $id) { ${FIELDS} } }`), variables: { id }, fetchPolicy: 'no-cache' })\n if (response.errors?.length) throw response\n if (!response.data.invoice) throw new Error(i18next.t('text.invoice-not-found'))\n this.show(response.data.invoice)\n } catch (error) {\n this.error = error\n } finally {\n this.loading = false\n this.updateContext()\n }\n }\n\n private show(invoice: DocumentValue) {\n this.invoice = invoice\n this.form = { ...invoice, items: invoice.items.map((item: any) => ({ ...item })) }\n this.voidReason = ''\n this.configure()\n this.grist?.fetch()\n }\n\n /** Runs one request at a time; a refusal is said in the server's words. */\n private async run<T>(work: () => Promise<T>): Promise<T | undefined> {\n if (this.busy) return undefined\n this.busy = true\n try {\n return await work()\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.errors?.[0]?.message ?? error?.message ?? String(error) })\n return undefined\n } finally {\n this.busy = false\n }\n }\n\n private input() {\n const input: DocumentValue = Object.fromEntries(HEAD.map(key => [key, this.form[key] === '' ? null : this.form[key] ?? null]))\n input.taxBasis = input.direction === 'PURCHASE' ? input.taxBasis || 'CALCULATED' : 'CALCULATED'\n input.items = linesOf(this.grist)\n return input\n }\n\n private async save(): Promise<DocumentValue | undefined> {\n const id = this.invoice?.id\n const saved = await this.run(async () => {\n const response = await client.mutate({\n mutation: gql(\n id\n ? `mutation ($id: String!, $invoice: NewInvoice!) { invoice: updateInvoice(id: $id, invoice: $invoice) { ${FIELDS} } }`\n : `mutation ($invoice: NewInvoice!) { invoice: createInvoice(invoice: $invoice) { ${FIELDS} } }`\n ),\n variables: { ...(id ? { id } : {}), invoice: this.input() }\n })\n if (response.errors?.length) throw response\n return response.data.invoice as DocumentValue\n })\n if (!saved) return undefined\n this.show(saved)\n this.updateContext()\n if (!id) navigate(`invoice-editor?id=${saved.id}`)\n return saved\n }\n\n /** Save what is on screen, then issue it — its amounts are fixed from here on. */\n private async issue() {\n const saved = await this.save()\n if (!saved) return\n const issued = await this.mutate(`mutation ($id: String!) { invoice: issueInvoice(id: $id) { ${FIELDS} } }`, { id: saved.id })\n if (issued) notify({ level: 'info', message: i18next.t('text.invoice-issued') })\n }\n\n private async void() {\n const confirmed = await OxPrompt.open({\n title: i18next.t('button.invoice-void'),\n text: i18next.t('text.invoice-void-confirm'),\n confirmButton: { text: i18next.t('button.invoice-void'), destructive: true },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!confirmed) return\n await this.mutate(`mutation ($id: String!, $reason: String!) { invoice: voidInvoice(id: $id, reason: $reason) { ${FIELDS} } }`, {\n id: this.invoice!.id,\n reason: this.voidReason.trim()\n })\n }\n\n private async mutate(mutation: string, variables: any) {\n const changed = await this.run(async () => {\n const response = await client.mutate({ mutation: gql(mutation), variables })\n if (response.errors?.length) throw response\n return response.data.invoice as DocumentValue\n })\n if (changed) {\n this.show(changed)\n this.updateContext()\n }\n return changed\n }\n\n private print() {\n const invoice = this.invoice!\n const lng = invoice.language === 'en' ? 'en' : 'ko'\n printDocument(\n documentHtml(invoice, {\n title: i18next.t('title.invoice-print', { lng }),\n terms: [{ label: i18next.t('field.invoice-due-date', { lng }), value: invoice.dueDate }]\n })\n )\n }\n}\n\nfunction blank(): DocumentValue {\n return {\n number: '',\n direction: 'SALES',\n currency: 'KRW',\n language: 'ko',\n supplierName: '',\n buyerName: '',\n issueDate: today(),\n dueDate: '',\n taxBasis: 'CALCULATED',\n items: []\n }\n}\n"]}
1
+ {"version":3,"file":"invoice-editor.js","sourceRoot":"","sources":["../../client/pages/invoice-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\nimport '@operato/list-state/ox-page-state.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, nothing } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { navigate, PageView } from '@operato/shell'\nimport { ButtonStyles, CommonGristStyles, DocumentPageStyles, FormFieldStyles, ScrollbarStyles } from '@operato/styles'\n\nimport { DocumentFormStyles, renderDocumentHead, renderDocumentTotals, type DocumentValue } from '../document/document-form'\nimport { documentLinesConfig, linesOf } from '../document/document-lines'\nimport { documentHtml, printDocument } from '../document/document-print'\nimport { invoiceStatusWord } from '../entity360/invoice-360'\nimport { invoiceLinkSection } from '../invoice-attach'\nimport '../invoice-files'\n\nconst FIELDS = `\n id number status direction currency language counterpartyId counterparty { id name } supplierName supplierAddress supplierRegistrationNumber buyerName buyerAddress\n buyerRegistrationNumber issueDate dueDate purchaseOrder paymentTerms bankDetails notes sourceReference taxBasis voidReason\n supplyAmount taxAmount totalAmount taxRounding currencyDigits\n items { position description quantity unitPrice discount taxKind taxRate supplyAmount receivedTaxAmount }\n taxGroups { taxKind taxRate supplyAmount taxAmount }\n`\n\nconst HEAD = [\n 'number',\n 'counterpartyId',\n 'direction',\n 'currency',\n 'language',\n 'supplierName',\n 'supplierAddress',\n 'supplierRegistrationNumber',\n 'buyerName',\n 'buyerAddress',\n 'buyerRegistrationNumber',\n 'issueDate',\n 'dueDate',\n 'purchaseOrder',\n 'paymentTerms',\n 'bankDetails',\n 'notes',\n 'sourceReference',\n 'taxBasis'\n]\n\nconst today = () => new Date().toLocaleDateString('en-CA')\n\ntype Party = { id: string; name: string; businessNumber?: string | null }\n\n/**\n * 청구서 편집 — the head, the lines, the totals by tax kind and rate, and what an application links it to.\n *\n * A draft is written and saved; 「발행」 saves what is on screen and issues it, after which its amounts never change.\n * An issued invoice is voided with a reason, in its own section. While a request runs only the inputs wait.\n */\n@customElement('invoice-editor')\nexport class InvoiceEditor extends localize(i18next)(PageView) {\n static styles = [\n FormFieldStyles,\n ButtonStyles,\n DocumentPageStyles,\n CommonGristStyles,\n ScrollbarStyles,\n DocumentFormStyles,\n css`\n ox-grist {\n height: calc(var(--form-element-height-medium) * 10);\n }\n .party {\n display: flex;\n gap: var(--spacing-small);\n align-items: center;\n }\n .party input {\n flex: 1;\n }\n `\n ]\n\n @state() invoice: DocumentValue | null = null\n @state() form: DocumentValue = blank()\n @state() loading = false\n @state() error: unknown = null\n @state() busy = false\n @state() voidReason = ''\n /** The counterparty search: what was typed, and what it found when more than one. */\n @state() partySearch = ''\n @state() partiesFound: Party[] = []\n @state() gristConfig: any\n\n @query('ox-grist') private grist?: DataGrist\n\n get editable() {\n return !this.invoice || this.invoice.status === 'DRAFT'\n }\n\n get context() {\n const actions: any[] = []\n if (this.editable) {\n actions.push({ title: i18next.t('button.save'), icon: 'save', action: () => this.save() })\n actions.push({ title: i18next.t('button.invoice-issue'), icon: 'send', emphasis: { raised: true }, action: () => this.issue() })\n }\n if (this.invoice) actions.push({ title: i18next.t('button.invoice-print'), icon: 'print', action: () => this.print() })\n return {\n title: this.invoice ? `${i18next.t('title.invoice')} ${this.invoice.number}` : i18next.t('title.invoice-new'),\n ...(this.invoice ? { description: invoiceStatusWord(this.invoice.status) } : {}),\n frame: 'document',\n /* Opened from the invoice list; the menu marks it. */\n menu: 'invoice-list',\n actions: this.error ? [] : actions\n }\n }\n\n async pageUpdated(changes: any, lifecycle: any) {\n if (!this.active || !(changes.active || changes.params)) return\n const id = lifecycle?.params?.id\n if (!id) {\n this.invoice = null\n this.form = blank()\n this.configure()\n this.updateContext()\n return\n }\n if (id !== this.invoice?.id) await this.load(id)\n }\n\n render() {\n const links = this.invoice ? invoiceLinkSection() : undefined\n return html`<ox-page-state .loading=${this.loading} .error=${this.error} @retry=${() => this.invoice && this.load(this.invoice.id)}>\n <div class=\"page\">\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.invoice-section-head')}</h3></header>\n ${renderDocumentHead(this.form, this.editable && !this.busy, patch => (this.form = { ...this.form, ...patch }), this.renderTerms(), 'field.invoice-number')}\n </section>\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.invoice-section-lines')}</h3></header>\n <ox-grist mode=\"GRID\" .config=${this.gristConfig} .fetchHandler=${() => ({ total: this.form.items.length, records: this.form.items })}></ox-grist>\n </section>\n ${this.invoice\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.invoice-section-totals')}</h3></header>\n ${renderDocumentTotals(this.invoice)}\n </section>\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.invoice-section-files')}</h3></header>\n <invoice-files .invoiceId=${this.invoice.id}></invoice-files>\n </section>`\n : nothing}\n ${links && this.invoice\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${links.heading()}</h3></header>\n ${links.render(this.invoice as any)}\n </section>`\n : nothing}\n ${this.invoice?.status === 'ISSUED' ? this.renderVoid() : nothing}\n </div>\n </ox-page-state>`\n }\n\n private renderTerms() {\n const editable = this.editable && !this.busy\n return html`${this.renderParty(editable)}<label\n >${i18next.t('field.invoice-due-date')}\n <input type=\"date\" .value=${this.form.dueDate ?? ''} ?disabled=${!editable} @input=${(e: any) => (this.form = { ...this.form, dueDate: e.target.value })}\n /></label>\n ${this.form.direction === 'PURCHASE'\n ? html`<label\n >${i18next.t('field.invoice-tax-basis')}\n <select ?disabled=${!editable} @change=${(e: any) => this.changeTaxBasis(e.target.value)}>\n <option value=\"CALCULATED\" ?selected=${this.form.taxBasis !== 'RECEIVED'}>${i18next.t('text.invoice-tax-basis-calculated')}</option>\n <option value=\"RECEIVED\" ?selected=${this.form.taxBasis === 'RECEIVED'}>${i18next.t('text.invoice-tax-basis-received')}</option>\n </select></label\n >`\n : nothing}`\n }\n\n /**\n * Who the other party is among the domain's counterparties - the buyer of a sale, the supplier of a purchase. Found by\n * name or business number; choosing one writes its name and number onto the printed side, which stays editable.\n */\n private renderParty(editable: boolean) {\n const chosen = this.form.counterparty as Party | null | undefined\n return html`<label\n >${i18next.t('field.invoice-counterparty')}\n <span class=\"party\">\n <input\n .value=${this.partySearch}\n placeholder=${chosen?.name ?? i18next.t('text.invoice-counterparty-search')}\n ?disabled=${!editable}\n @input=${(e: any) => (this.partySearch = e.target.value)}\n @keydown=${(e: KeyboardEvent) => e.key === 'Enter' && this.findParties()}\n />\n <button ?disabled=${!editable} @click=${() => this.findParties()}>${i18next.t('button.invoice-counterparty-find')}</button>\n ${chosen ? html`<button ?disabled=${!editable} @click=${() => this.chooseParty(null)}>${i18next.t('button.invoice-counterparty-clear')}</button>` : nothing}\n </span>\n ${this.partiesFound.length\n ? html`<select ?disabled=${!editable} @change=${(e: any) => this.chooseParty(this.partiesFound.find(one => one.id === e.target.value) ?? null)}>\n <option value=\"\">${chosen?.name ?? ''}</option>\n ${this.partiesFound.map(one => html`<option value=${one.id}>${one.name}${one.businessNumber ? ` (${one.businessNumber})` : ''}</option>`)}\n </select>`\n : nothing}\n </label>`\n }\n\n private chooseParty(party: Party | null) {\n const side = this.form.direction === 'PURCHASE' ? 'supplier' : 'buyer'\n this.form = {\n ...this.form,\n counterpartyId: party?.id ?? null,\n counterparty: party,\n ...(party ? { [`${side}Name`]: party.name, [`${side}RegistrationNumber`]: party.businessNumber ?? this.form[`${side}RegistrationNumber`] } : {})\n }\n this.partySearch = ''\n this.partiesFound = []\n }\n\n private async findParties() {\n await this.run(async () => {\n const response = await client.query({\n query: gql`\n query ($search: String, $pagination: Pagination) {\n counterparties: counterpartyChoices(search: $search, pagination: $pagination) {\n items { id name businessNumber }\n }\n }\n `,\n variables: { search: this.partySearch.trim() || undefined, pagination: { page: 1, limit: 30 } },\n fetchPolicy: 'no-cache'\n })\n if (response.errors?.length) throw response\n const found: Party[] = response.data.counterparties.items ?? []\n if (found.length === 1) this.chooseParty(found[0])\n else this.partiesFound = found\n })\n }\n\n private renderVoid() {\n return html`<section class=\"page-section\">\n <header class=\"page-section-header\">\n <h3>${i18next.t('text.invoice-section-void')}</h3>\n <div class=\"page-section-actions\">\n <button danger ?disabled=${this.busy || !this.voidReason.trim()} @click=${() => this.void()}>${i18next.t('button.invoice-void')}</button>\n </div>\n </header>\n <div class=\"form\">\n <label class=\"wide\"\n >${i18next.t('field.invoice-void-reason')}\n <input .value=${this.voidReason} ?disabled=${this.busy} @input=${(e: any) => (this.voidReason = e.target.value)}\n /></label>\n </div>\n </section>`\n }\n\n private changeTaxBasis(taxBasis: string) {\n this.form = { ...this.form, items: linesOf(this.grist), taxBasis }\n this.configure()\n }\n\n private configure() {\n this.gristConfig = documentLinesConfig({ editable: this.editable, received: this.form.taxBasis === 'RECEIVED', currency: this.form.currency || 'KRW' })\n }\n\n private async load(id: string) {\n this.loading = true\n this.error = null\n try {\n const response = await client.query({ query: gql(`query ($id: String!) { invoice(id: $id) { ${FIELDS} } }`), variables: { id }, fetchPolicy: 'no-cache' })\n if (response.errors?.length) throw response\n if (!response.data.invoice) throw new Error(i18next.t('text.invoice-not-found'))\n this.show(response.data.invoice)\n } catch (error) {\n this.error = error\n } finally {\n this.loading = false\n this.updateContext()\n }\n }\n\n private show(invoice: DocumentValue) {\n this.invoice = invoice\n this.form = { ...invoice, items: invoice.items.map((item: any) => ({ ...item })) }\n this.voidReason = ''\n this.configure()\n this.grist?.fetch()\n }\n\n /** Runs one request at a time; a refusal is said in the server's words. */\n private async run<T>(work: () => Promise<T>): Promise<T | undefined> {\n if (this.busy) return undefined\n this.busy = true\n try {\n return await work()\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.errors?.[0]?.message ?? error?.message ?? String(error) })\n return undefined\n } finally {\n this.busy = false\n }\n }\n\n private input() {\n const input: DocumentValue = Object.fromEntries(HEAD.map(key => [key, this.form[key] === '' ? null : this.form[key] ?? null]))\n input.taxBasis = input.direction === 'PURCHASE' ? input.taxBasis || 'CALCULATED' : 'CALCULATED'\n input.items = linesOf(this.grist)\n return input\n }\n\n private async save(): Promise<DocumentValue | undefined> {\n const id = this.invoice?.id\n const saved = await this.run(async () => {\n const response = await client.mutate({\n mutation: gql(\n id\n ? `mutation ($id: String!, $invoice: NewInvoice!) { invoice: updateInvoice(id: $id, invoice: $invoice) { ${FIELDS} } }`\n : `mutation ($invoice: NewInvoice!) { invoice: createInvoice(invoice: $invoice) { ${FIELDS} } }`\n ),\n variables: { ...(id ? { id } : {}), invoice: this.input() }\n })\n if (response.errors?.length) throw response\n return response.data.invoice as DocumentValue\n })\n if (!saved) return undefined\n this.show(saved)\n this.updateContext()\n if (!id) navigate(`invoice-editor?id=${saved.id}`)\n return saved\n }\n\n /** Save what is on screen, then issue it — its amounts are fixed from here on. */\n private async issue() {\n const saved = await this.save()\n if (!saved) return\n const issued = await this.mutate(`mutation ($id: String!) { invoice: issueInvoice(id: $id) { ${FIELDS} } }`, { id: saved.id })\n if (issued) notify({ level: 'info', message: i18next.t('text.invoice-issued') })\n }\n\n private async void() {\n const confirmed = await OxPrompt.open({\n title: i18next.t('button.invoice-void'),\n text: i18next.t('text.invoice-void-confirm'),\n confirmButton: { text: i18next.t('button.invoice-void'), destructive: true },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!confirmed) return\n await this.mutate(`mutation ($id: String!, $reason: String!) { invoice: voidInvoice(id: $id, reason: $reason) { ${FIELDS} } }`, {\n id: this.invoice!.id,\n reason: this.voidReason.trim()\n })\n }\n\n private async mutate(mutation: string, variables: any) {\n const changed = await this.run(async () => {\n const response = await client.mutate({ mutation: gql(mutation), variables })\n if (response.errors?.length) throw response\n return response.data.invoice as DocumentValue\n })\n if (changed) {\n this.show(changed)\n this.updateContext()\n }\n return changed\n }\n\n private print() {\n const invoice = this.invoice!\n const lng = invoice.language === 'en' ? 'en' : 'ko'\n printDocument(\n documentHtml(invoice, {\n title: i18next.t('title.invoice-print', { lng }),\n terms: [{ label: i18next.t('field.invoice-due-date', { lng }), value: invoice.dueDate }]\n })\n )\n }\n}\n\nfunction blank(): DocumentValue {\n return {\n number: '',\n direction: 'SALES',\n currency: 'KRW',\n language: 'ko',\n supplierName: '',\n buyerName: '',\n issueDate: today(),\n dueDate: '',\n taxBasis: 'CALCULATED',\n items: []\n }\n}\n"]}
@@ -11,7 +11,7 @@ import { navigate, PageView } from '@operato/shell';
11
11
  import { CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
12
12
  import { isMobileDevice } from '@operato/utils';
13
13
  import { documentAmount } from '../document/document-amount';
14
- import { counterpartOf, invoiceStatusWord } from '../entity360/invoice-360';
14
+ import { counterpartCell, invoiceStatusWord } from '../entity360/invoice-360';
15
15
  /**
16
16
  * 청구서 — every invoice the domain sent or received. The other party's name opens the invoice's 360; the edit gutter
17
17
  * opens the editor. Search is the server's: number, parties, purchase order and notes.
@@ -54,7 +54,7 @@ let InvoiceList = class InvoiceList extends localize(i18next)(PageView) {
54
54
  rows: { appendable: false, selectable: false },
55
55
  pagination: { limit: 50, pages: [50, 100, 500] },
56
56
  emptyNote: { title: i18next.t('text.invoice-empty'), description: i18next.t('text.invoice-empty-description') },
57
- list: { fields: ['counterpart', 'number'], details: ['status', 'dueDate', 'totalAmount'] },
57
+ list: { fields: ['number', 'counterpart'], details: ['status', 'dueDate', 'totalAmount'] },
58
58
  columns: [
59
59
  { type: 'gutter', gutterName: 'sequence' },
60
60
  {
@@ -63,11 +63,14 @@ let InvoiceList = class InvoiceList extends localize(i18next)(PageView) {
63
63
  icon: 'edit_note',
64
64
  handlers: { click: (_columns, _data, _column, record) => record?.id && navigate(`invoice-editor?id=${record.id}`) }
65
65
  },
66
+ /* The number is the invoice's own name and opens its 360; the other party opens the counterparty's (ADR-0067 decision 1). */
67
+ readonly('string', 'number', i18next.t('field.invoice-number'), 140, {
68
+ record: { renderer: (value, _column, record) => (record?.id ? entity360Name({ __typename: 'Invoice', ...record }, value) : value) }
69
+ }),
66
70
  readonly('string', 'counterpart', i18next.t('field.invoice-counterpart'), 200, {
67
71
  sortable: false,
68
- record: { renderer: (_value, _column, record) => (record?.id ? entity360Name({ __typename: 'Invoice', ...record }, counterpartOf(record)) : '') }
72
+ record: { renderer: (_value, _column, record) => counterpartCell(record) }
69
73
  }),
70
- readonly('string', 'number', i18next.t('field.invoice-number'), 140),
71
74
  readonly('string', 'status', i18next.t('field.invoice-status'), 80, { record: { renderer: (value) => invoiceStatusWord(value) } }),
72
75
  readonly('string', 'direction', i18next.t('field.invoice-direction'), 80, {
73
76
  record: { renderer: (value) => (value === 'PURCHASE' ? i18next.t('text.invoice-direction-purchase') : i18next.t('text.invoice-direction-sales')) }
@@ -92,6 +95,7 @@ let InvoiceList = class InvoiceList extends localize(i18next)(PageView) {
92
95
  status
93
96
  direction
94
97
  currency
98
+ counterpartyId
95
99
  supplierName
96
100
  buyerName
97
101
  issueDate
@@ -1 +1 @@
1
- {"version":3,"file":"invoice-list.js","sourceRoot":"","sources":["../../client/pages/invoice-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\n\nimport gql from 'graphql-tag'\nimport { html } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { entity360Name } from '@operato/layout'\nimport { navigate, PageView } from '@operato/shell'\nimport { CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\n\nimport { documentAmount } from '../document/document-amount'\nimport { counterpartOf, invoiceStatusWord } from '../entity360/invoice-360'\n\n/**\n * 청구서 — every invoice the domain sent or received. The other party's name opens the invoice's 360; the edit gutter\n * opens the editor. Search is the server's: number, parties, purchase order and notes.\n */\n@customElement('invoice-list')\nexport class InvoiceList extends localize(i18next)(PageView) {\n static styles = [WorkSurfacePageStyles, CommonGristStyles, ScrollbarStyles]\n\n @state() gristConfig: any\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('title.invoice-list'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n actions: [{ title: i18next.t('button.invoice-new'), icon: 'add', emphasis: { raised: true }, action: () => navigate('invoice-editor') }],\n exportable: { name: i18next.t('title.invoice-list'), data: () => this.grist.exportRecords() }\n }\n }\n\n render() {\n return html`<ox-grist\n class=\"page-fill\"\n search-mode=\"term\"\n .mode=${isMobileDevice() ? 'CARD' : 'GRID'}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n ></ox-grist>`\n }\n\n async pageInitialized() {\n const readonly = (type: string, name: string, header: string, width: number, extra: any = {}) => ({\n type,\n name,\n header,\n width,\n sortable: true,\n ...extra,\n record: { editable: false, ...extra.record }\n })\n this.gristConfig = {\n rows: { appendable: false, selectable: false },\n pagination: { limit: 50, pages: [50, 100, 500] },\n emptyNote: { title: i18next.t('text.invoice-empty'), description: i18next.t('text.invoice-empty-description') },\n list: { fields: ['counterpart', 'number'], details: ['status', 'dueDate', 'totalAmount'] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'gutter',\n gutterName: 'button',\n icon: 'edit_note',\n handlers: { click: (_columns: any, _data: any, _column: any, record: any) => record?.id && navigate(`invoice-editor?id=${record.id}`) }\n },\n readonly('string', 'counterpart', i18next.t('field.invoice-counterpart'), 200, {\n sortable: false,\n record: { renderer: (_value: any, _column: any, record: any) => (record?.id ? entity360Name({ __typename: 'Invoice', ...record }, counterpartOf(record)) : '') }\n }),\n readonly('string', 'number', i18next.t('field.invoice-number'), 140),\n readonly('string', 'status', i18next.t('field.invoice-status'), 80, { record: { renderer: (value: string) => invoiceStatusWord(value) } }),\n readonly('string', 'direction', i18next.t('field.invoice-direction'), 80, {\n record: { renderer: (value: string) => (value === 'PURCHASE' ? i18next.t('text.invoice-direction-purchase') : i18next.t('text.invoice-direction-sales')) }\n }),\n readonly('string', 'issueDate', i18next.t('field.invoice-issue-date'), 110),\n readonly('string', 'dueDate', i18next.t('field.invoice-due-date'), 110),\n readonly('float', 'totalAmount', i18next.t('field.invoice-total-amount'), 160, {\n record: { align: 'right', renderer: (value: number, _column: any, record: any) => documentAmount(value, record?.currency || 'KRW') }\n })\n ],\n sorters: [{ name: 'issueDate', desc: true }]\n }\n }\n\n async fetchHandler({ page = 1, limit = 50, sortings = [], filters = [], search }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $search: String) {\n responses: invoices(filters: $filters, pagination: $pagination, sortings: $sortings, search: $search) {\n items {\n id\n number\n status\n direction\n currency\n supplierName\n buyerName\n issueDate\n dueDate\n totalAmount\n }\n total\n }\n }\n `,\n variables: { filters, pagination: { page, limit }, sortings, search: search?.trim() || undefined },\n fetchPolicy: 'network-only'\n })\n if (response.errors?.length) throw response\n return { total: response.data.responses.total, records: response.data.responses.items }\n }\n}\n"]}
1
+ {"version":3,"file":"invoice-list.js","sourceRoot":"","sources":["../../client/pages/invoice-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\n\nimport gql from 'graphql-tag'\nimport { html } from 'lit'\nimport { customElement, query, state } from 'lit/decorators.js'\n\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { entity360Name } from '@operato/layout'\nimport { navigate, PageView } from '@operato/shell'\nimport { CommonGristStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\n\nimport { documentAmount } from '../document/document-amount'\nimport { counterpartCell, invoiceStatusWord } from '../entity360/invoice-360'\n\n/**\n * 청구서 — every invoice the domain sent or received. The other party's name opens the invoice's 360; the edit gutter\n * opens the editor. Search is the server's: number, parties, purchase order and notes.\n */\n@customElement('invoice-list')\nexport class InvoiceList extends localize(i18next)(PageView) {\n static styles = [WorkSurfacePageStyles, CommonGristStyles, ScrollbarStyles]\n\n @state() gristConfig: any\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('title.invoice-list'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n actions: [{ title: i18next.t('button.invoice-new'), icon: 'add', emphasis: { raised: true }, action: () => navigate('invoice-editor') }],\n exportable: { name: i18next.t('title.invoice-list'), data: () => this.grist.exportRecords() }\n }\n }\n\n render() {\n return html`<ox-grist\n class=\"page-fill\"\n search-mode=\"term\"\n .mode=${isMobileDevice() ? 'CARD' : 'GRID'}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n ></ox-grist>`\n }\n\n async pageInitialized() {\n const readonly = (type: string, name: string, header: string, width: number, extra: any = {}) => ({\n type,\n name,\n header,\n width,\n sortable: true,\n ...extra,\n record: { editable: false, ...extra.record }\n })\n this.gristConfig = {\n rows: { appendable: false, selectable: false },\n pagination: { limit: 50, pages: [50, 100, 500] },\n emptyNote: { title: i18next.t('text.invoice-empty'), description: i18next.t('text.invoice-empty-description') },\n list: { fields: ['number', 'counterpart'], details: ['status', 'dueDate', 'totalAmount'] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'gutter',\n gutterName: 'button',\n icon: 'edit_note',\n handlers: { click: (_columns: any, _data: any, _column: any, record: any) => record?.id && navigate(`invoice-editor?id=${record.id}`) }\n },\n /* The number is the invoice's own name and opens its 360; the other party opens the counterparty's (ADR-0067 decision 1). */\n readonly('string', 'number', i18next.t('field.invoice-number'), 140, {\n record: { renderer: (value: string, _column: any, record: any) => (record?.id ? entity360Name({ __typename: 'Invoice', ...record }, value) : value) }\n }),\n readonly('string', 'counterpart', i18next.t('field.invoice-counterpart'), 200, {\n sortable: false,\n record: { renderer: (_value: any, _column: any, record: any) => counterpartCell(record) }\n }),\n readonly('string', 'status', i18next.t('field.invoice-status'), 80, { record: { renderer: (value: string) => invoiceStatusWord(value) } }),\n readonly('string', 'direction', i18next.t('field.invoice-direction'), 80, {\n record: { renderer: (value: string) => (value === 'PURCHASE' ? i18next.t('text.invoice-direction-purchase') : i18next.t('text.invoice-direction-sales')) }\n }),\n readonly('string', 'issueDate', i18next.t('field.invoice-issue-date'), 110),\n readonly('string', 'dueDate', i18next.t('field.invoice-due-date'), 110),\n readonly('float', 'totalAmount', i18next.t('field.invoice-total-amount'), 160, {\n record: { align: 'right', renderer: (value: number, _column: any, record: any) => documentAmount(value, record?.currency || 'KRW') }\n })\n ],\n sorters: [{ name: 'issueDate', desc: true }]\n }\n }\n\n async fetchHandler({ page = 1, limit = 50, sortings = [], filters = [], search }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $search: String) {\n responses: invoices(filters: $filters, pagination: $pagination, sortings: $sortings, search: $search) {\n items {\n id\n number\n status\n direction\n currency\n counterpartyId\n supplierName\n buyerName\n issueDate\n dueDate\n totalAmount\n }\n total\n }\n }\n `,\n variables: { filters, pagination: { page, limit }, sortings, search: search?.trim() || undefined },\n fetchPolicy: 'network-only'\n })\n if (response.errors?.length) throw response\n return { total: response.data.responses.total, records: response.data.responses.items }\n }\n}\n"]}