@things-factory/invoice 10.1.256 → 10.1.258
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.
- package/dist-client/document/document-defaults.d.ts +11 -2
- package/dist-client/document/document-defaults.js +7 -15
- package/dist-client/document/document-defaults.js.map +1 -1
- package/dist-client/document/document-party.d.ts +5 -2
- package/dist-client/document/document-party.js +21 -21
- package/dist-client/document/document-party.js.map +1 -1
- package/dist-client/entity360/invoice-360.d.ts +3 -4
- package/dist-client/entity360/invoice-360.js +17 -38
- package/dist-client/entity360/invoice-360.js.map +1 -1
- package/dist-client/index.d.ts +1 -1
- package/dist-client/index.js +1 -1
- package/dist-client/index.js.map +1 -1
- package/dist-client/invoice-files.d.ts +4 -10
- package/dist-client/invoice-files.js +19 -58
- package/dist-client/invoice-files.js.map +1 -1
- package/dist-client/pages/invoice-editor.d.ts +42 -19
- package/dist-client/pages/invoice-editor.js +150 -179
- package/dist-client/pages/invoice-editor.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/document-defaults-setting-let.d.ts +7 -2
- package/dist-client/viewparts/document-defaults-setting-let.js +30 -35
- package/dist-client/viewparts/document-defaults-setting-let.js.map +1 -1
- package/package.json +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice-files.js","sourceRoot":"","sources":["../client/invoice-files.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n/* The tile is not a subpath of its own; the package root registers it. */\nimport '@operato/attachment'\nimport '@operato/input/ox-input-file.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { client, uploadContext } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\n\nimport { invoice360Query } from './invoice-attach'\n\ntype InvoiceFile = { id: string; name: string; mimetype?: string; fullpath: string }\n\n/** The phone's camera is offered where a finger taps - on a desktop the file button is the only way in. */\nconst touch = () => window.matchMedia('(pointer: coarse)').matches\n\n/**\n * The files an invoice keeps - the signed copy, the order, the delivery note. Each opens in its own tab. Whoever may\n * change invoices attaches (a photo taken on the spot, or any file) and takes one off; it is saved at once.\n */\n@customElement('invoice-files')\nexport class InvoiceFiles extends localize(i18next)(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-medium, 8px);\n color: var(--ui-ink);\n }\n .tiles {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-medium, 8px);\n padding-top: 6px;\n }\n .tile {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 72px;\n gap: var(--spacing-tiny, 2px);\n }\n .tile a {\n display: block;\n width: 100%;\n aspect-ratio: 1;\n border-radius: var(--ui-r-small, 6px);\n border: 1px solid var(--ui-line);\n background: var(--ui-panel-2);\n overflow: hidden;\n }\n .tile ox-attachment-tile,\n .tile img {\n width: 100%;\n height: 100%;\n }\n .tile img {\n object-fit: cover;\n }\n .name {\n font-size: var(--ui-t-small, 11.5px);\n color: var(--ui-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .tile button {\n position: absolute;\n top: -6px;\n right: -6px;\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: 1px solid var(--ui-line);\n border-radius: 50%;\n background: var(--ui-panel);\n color: var(--ui-muted);\n cursor: pointer;\n }\n .tile button md-icon {\n --md-icon-size: 14px;\n }\n .pickers {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-small, 4px);\n }\n .none {\n font-size: var(--ui-t-small, 11.5px);\n color: var(--ui-muted);\n }\n `\n ]\n\n @property() invoiceId?: string\n @state() files: InvoiceFile[] = []\n @state() mayChange = false\n @state() busy = false\n @state() progress?: number\n\n connectedCallback() {\n super.connectedCallback()\n hasPrivilege({ privilege: 'mutation', category: 'invoice', domainOwnerGranted: true }).then(may => (this.mayChange = !!may))\n }\n\n updated(changed: Map<string, unknown>) {\n if (changed.has('invoiceId')) this.load()\n }\n\n render() {\n const editable = this.mayChange && !this.busy\n return html`\n ${this.files.length\n ? html`<div class=\"tiles\">${this.files.map(one => this.tile(one, editable))}</div>`\n : html`<span class=\"none\">${i18next.t('text.invoice-files-none')}</span>`}\n ${this.mayChange\n ? html`<div class=\"pickers\">\n ${touch()\n ? html`<ox-input-file\n quiet\n hide-filelist\n accept=\"image/*\"\n capture=\"environment\"\n icon=\"photo_camera\"\n .label=${i18next.t('button.invoice-file-photo')}\n ?disabled=${!editable}\n .progress=${this.progress}\n @change=${(e: CustomEvent) => this.pick(e)}\n ></ox-input-file>`\n : nothing}\n <ox-input-file\n quiet\n hide-filelist\n multiple\n icon=\"attach_file\"\n .label=${i18next.t('button.invoice-file-attach')}\n ?disabled=${!editable}\n .progress=${touch() ? undefined : this.progress}\n @change=${(e: CustomEvent) => this.pick(e)}\n ></ox-input-file>\n </div>`\n : nothing}\n `\n }\n\n private tile(one: InvoiceFile, editable: boolean) {\n return html`<span class=\"tile\">\n <a href=${one.fullpath} target=\"_blank\" rel=\"noopener\" title=${one.name}\n >${one.mimetype?.startsWith('image/')\n ? html`<img src=${one.fullpath} alt=${one.name} />`\n : html`<ox-attachment-tile .src=${one.fullpath} .path=${one.name} .mimetype=${one.mimetype ?? ''}></ox-attachment-tile>`}</a\n >\n <span class=\"name\">${one.name}</span>\n ${this.mayChange\n ? html`<button type=\"button\" ?disabled=${!editable} title=${i18next.t('button.invoice-file-remove')} aria-label=${i18next.t('button.invoice-file-remove')} @click=${() => this.takeOff(one)}>\n <md-icon>close</md-icon>\n </button>`\n : nothing}\n </span>`\n }\n\n private async load() {\n const id = this.invoiceId\n this.files = []\n if (!id) return\n try {\n const response = await client.query({\n query: gql(`query ($id: String!) { invoice: ${invoice360Query()}(id: $id) { id files { id name mimetype fullpath } } }`),\n variables: { id },\n fetchPolicy: 'no-cache'\n })\n if (this.invoiceId === id) this.files = response.data?.invoice?.files ?? []\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error) })\n }\n }\n\n private async pick(e: CustomEvent) {\n const picked = [...((e.detail as File[]) ?? [])]\n /* The picker's own reset says `change` again, with nothing - that one is let go. */\n if (!picked.length) return\n ;(e.target as any).reset?.()\n await this.change({ attach: picked })\n }\n\n private async takeOff(one: InvoiceFile) {\n const sure = await OxPrompt.open({\n title: i18next.t('button.invoice-file-remove'),\n text: i18next.t('text.invoice-file-remove-confirm', { name: one.name }),\n confirmButton: { text: i18next.t('button.invoice-file-remove'), destructive: true } as any,\n cancelButton: { text: i18next.t('button.cancel') }\n } as any)\n if (sure) await this.change({ remove: [one.id] })\n }\n\n private async change({ attach = [], remove = [] }: { attach?: File[]; remove?: string[] }) {\n if (!this.invoiceId || this.busy) return\n this.busy = true\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $attach: [Upload!], $remove: [String!]) {\n changeInvoiceFiles(id: $id, attach: $attach, remove: $remove) {\n id\n }\n }\n `,\n variables: { id: this.invoiceId, attach, remove },\n context: attach.length ? uploadContext(fraction => (this.progress = fraction)) : {}\n })\n if (response.errors?.length) throw new Error(response.errors.map(one => one.message).join(' · '))\n await this.load()\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error) })\n } finally {\n this.busy = false\n this.progress = undefined\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"invoice-files.js","sourceRoot":"","sources":["../client/invoice-files.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n/* The tile is not a subpath of its own; the package root registers it. */\nimport '@operato/attachment'\nimport '@operato/input/ox-input-file.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { MutationController, QueryController, uploadContext } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\n\nimport { invoice360Query } from './invoice-attach'\n\ntype InvoiceFile = { id: string; name: string; mimetype?: string; fullpath: string }\n\n/** The phone's camera is offered where a finger taps - on a desktop the file button is the only way in. */\nconst touch = () => window.matchMedia('(pointer: coarse)').matches\n\n/**\n * The files an invoice keeps - the signed copy, the order, the delivery note. Each opens in its own tab. Whoever may\n * change invoices attaches (a photo taken on the spot, or any file) and takes one off; it is saved at once.\n */\n@customElement('invoice-files')\nexport class InvoiceFiles extends localize(i18next)(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-medium, 8px);\n color: var(--ui-ink);\n }\n .tiles {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-medium, 8px);\n padding-top: 6px;\n }\n .tile {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 72px;\n gap: var(--spacing-tiny, 2px);\n }\n .tile a {\n display: block;\n width: 100%;\n aspect-ratio: 1;\n border-radius: var(--ui-r-small, 6px);\n border: 1px solid var(--ui-line);\n background: var(--ui-panel-2);\n overflow: hidden;\n }\n .tile ox-attachment-tile,\n .tile img {\n width: 100%;\n height: 100%;\n }\n .tile img {\n object-fit: cover;\n }\n .name {\n font-size: var(--ui-t-small, 11.5px);\n color: var(--ui-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .tile button {\n position: absolute;\n top: -6px;\n right: -6px;\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: 1px solid var(--ui-line);\n border-radius: 50%;\n background: var(--ui-panel);\n color: var(--ui-muted);\n cursor: pointer;\n }\n .tile button md-icon {\n --md-icon-size: 14px;\n }\n .pickers {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-small, 4px);\n }\n .none {\n font-size: var(--ui-t-small, 11.5px);\n color: var(--ui-muted);\n }\n `\n ]\n\n @property() invoiceId?: string\n @state() mayChange = false\n @state() progress?: number\n\n /* The files of the invoice named (ADR-0190). */\n private filesRead = new QueryController(\n this,\n gql(`query ($id: String!) { invoice: ${invoice360Query()}(id: $id) { id files { id name mimetype fullpath } } }`),\n { variables: () => (this.invoiceId ? { id: this.invoiceId } : undefined) }\n )\n\n /* Attaching or taking off reads the files again. */\n private changing = new MutationController(\n this,\n gql`\n mutation ($id: String!, $attach: [Upload!], $remove: [String!]) {\n changeInvoiceFiles(id: $id, attach: $attach, remove: $remove) {\n id\n }\n }\n `,\n { refetch: () => [this.filesRead] }\n )\n\n private get files(): InvoiceFile[] {\n return this.filesRead.data?.invoice?.files ?? []\n }\n\n private get busy() {\n return this.changing.pending\n }\n\n connectedCallback() {\n super.connectedCallback()\n hasPrivilege({ privilege: 'mutation', category: 'invoice', domainOwnerGranted: true }).then(may => (this.mayChange = !!may))\n }\n\n render() {\n const editable = this.mayChange && !this.busy\n return html`\n ${this.files.length\n ? html`<div class=\"tiles\">${this.files.map(one => this.tile(one, editable))}</div>`\n : html`<span class=\"none\">${i18next.t('text.invoice-files-none')}</span>`}\n ${this.mayChange\n ? html`<div class=\"pickers\">\n ${touch()\n ? html`<ox-input-file\n quiet\n hide-filelist\n accept=\"image/*\"\n capture=\"environment\"\n icon=\"photo_camera\"\n .label=${i18next.t('button.invoice-file-photo')}\n ?disabled=${!editable}\n .progress=${this.progress}\n @change=${(e: CustomEvent) => this.pick(e)}\n ></ox-input-file>`\n : nothing}\n <ox-input-file\n quiet\n hide-filelist\n multiple\n icon=\"attach_file\"\n .label=${i18next.t('button.invoice-file-attach')}\n ?disabled=${!editable}\n .progress=${touch() ? undefined : this.progress}\n @change=${(e: CustomEvent) => this.pick(e)}\n ></ox-input-file>\n </div>`\n : nothing}\n `\n }\n\n private tile(one: InvoiceFile, editable: boolean) {\n return html`<span class=\"tile\">\n <a href=${one.fullpath} target=\"_blank\" rel=\"noopener\" title=${one.name}\n >${one.mimetype?.startsWith('image/')\n ? html`<img src=${one.fullpath} alt=${one.name} />`\n : html`<ox-attachment-tile .src=${one.fullpath} .path=${one.name} .mimetype=${one.mimetype ?? ''}></ox-attachment-tile>`}</a\n >\n <span class=\"name\">${one.name}</span>\n ${this.mayChange\n ? html`<button type=\"button\" ?disabled=${!editable} title=${i18next.t('button.invoice-file-remove')} aria-label=${i18next.t('button.invoice-file-remove')} @click=${() => this.takeOff(one)}>\n <md-icon>close</md-icon>\n </button>`\n : nothing}\n </span>`\n }\n\n private async pick(e: CustomEvent) {\n const picked = [...((e.detail as File[]) ?? [])]\n /* The picker's own reset says `change` again, with nothing - that one is let go. */\n if (!picked.length) return\n ;(e.target as any).reset?.()\n await this.change({ attach: picked })\n }\n\n private async takeOff(one: InvoiceFile) {\n const sure = await OxPrompt.open({\n title: i18next.t('button.invoice-file-remove'),\n text: i18next.t('text.invoice-file-remove-confirm', { name: one.name }),\n confirmButton: { text: i18next.t('button.invoice-file-remove'), destructive: true } as any,\n cancelButton: { text: i18next.t('button.cancel') }\n } as any)\n if (sure) await this.change({ remove: [one.id] })\n }\n\n private async change({ attach = [], remove = [] }: { attach?: File[]; remove?: string[] }) {\n if (!this.invoiceId || this.busy) return\n await this.changing.run({ id: this.invoiceId, attach, remove }, { context: attach.length ? uploadContext(fraction => (this.progress = fraction)) : {} })\n this.progress = undefined\n }\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '@operato/data-grist/ox-grist.js';
|
|
2
2
|
import '@operato/list-state/ox-page-state.js';
|
|
3
|
+
import type { PropertyValues } from 'lit';
|
|
3
4
|
import { PageView } from '@operato/shell';
|
|
4
5
|
import { type DocumentValue } from '../document/document-form';
|
|
5
6
|
import { type DocumentDefaults } from '../document/document-defaults';
|
|
@@ -13,19 +14,36 @@ declare const InvoiceEditor_base: (new (...args: any[]) => import("lit").LitElem
|
|
|
13
14
|
*/
|
|
14
15
|
export declare class InvoiceEditor extends InvoiceEditor_base {
|
|
15
16
|
static styles: import("lit").CSSResult[];
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
loading: boolean;
|
|
19
|
-
error: unknown;
|
|
20
|
-
busy: boolean;
|
|
21
|
-
voidReason: string;
|
|
17
|
+
/** What the address opens: an invoice by id, or a new one. */
|
|
18
|
+
private address?;
|
|
22
19
|
gristConfig: any;
|
|
23
20
|
/** The totals of the lines as typed - reckoned as the invoice will keep them, shown before it is saved. */
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
private typedAmounts;
|
|
22
|
+
/** Whether this person may read the company's words - unknown, and nothing read, until asked. */
|
|
23
|
+
private defaultsReadable;
|
|
24
|
+
private companyDefaults;
|
|
25
|
+
private record;
|
|
26
|
+
private last;
|
|
27
|
+
private draft;
|
|
28
|
+
private voiding;
|
|
29
|
+
private saves;
|
|
30
|
+
private saving;
|
|
31
|
+
private get invoiceId();
|
|
32
|
+
/** The company's words a new invoice starts with, and the payment terms it offers (ADR-0170) - none until read. */
|
|
33
|
+
get defaults(): DocumentDefaults | null;
|
|
34
|
+
get invoice(): DocumentValue | null;
|
|
35
|
+
/** What the form shows unedited: the invoice read, or what a new one starts with. */
|
|
36
|
+
private get formRead();
|
|
37
|
+
/** The form as it shows: each field's edit, else what was read. */
|
|
38
|
+
get form(): DocumentValue;
|
|
39
|
+
/** The totals of the lines as typed, else as the invoice keeps them. */
|
|
40
|
+
get amounts(): Partial<DocumentValue>;
|
|
41
|
+
get voidReason(): string;
|
|
42
|
+
/** A failed read, or an invoice the address names that is not there. */
|
|
43
|
+
get error(): unknown;
|
|
44
|
+
get loading(): boolean;
|
|
45
|
+
/** Runs one request at a time. */
|
|
46
|
+
get busy(): boolean;
|
|
29
47
|
private grist?;
|
|
30
48
|
private get received();
|
|
31
49
|
get editable(): boolean;
|
|
@@ -36,7 +54,11 @@ export declare class InvoiceEditor extends InvoiceEditor_base {
|
|
|
36
54
|
description?: string;
|
|
37
55
|
title: string;
|
|
38
56
|
};
|
|
39
|
-
pageUpdated(changes: any, lifecycle: any):
|
|
57
|
+
pageUpdated(changes: any, lifecycle: any): void;
|
|
58
|
+
private lined?;
|
|
59
|
+
private relined;
|
|
60
|
+
willUpdate(changes: PropertyValues): void;
|
|
61
|
+
updated(changes: PropertyValues): void;
|
|
40
62
|
render(): import("lit-html").TemplateResult<1>;
|
|
41
63
|
private renderTerms;
|
|
42
64
|
/**
|
|
@@ -47,7 +69,8 @@ export declare class InvoiceEditor extends InvoiceEditor_base {
|
|
|
47
69
|
private renderParty;
|
|
48
70
|
/**
|
|
49
71
|
* A party typed by name and not picked is the counterparty of that name when exactly one is - case and spaces aside;
|
|
50
|
-
* otherwise it stays unlinked and the editor says so.
|
|
72
|
+
* otherwise it stays unlinked and the editor says so. Looked up for the save and shown nowhere: the invoice read after
|
|
73
|
+
* it shows the link.
|
|
51
74
|
*/
|
|
52
75
|
private linkByName;
|
|
53
76
|
/**
|
|
@@ -55,10 +78,14 @@ export declare class InvoiceEditor extends InvoiceEditor_base {
|
|
|
55
78
|
* due date the company's days after the issue, the company's own words (ADR-0170 decision 6), and what they leave
|
|
56
79
|
* blank of our side as the last sales invoice wrote it.
|
|
57
80
|
*/
|
|
58
|
-
private
|
|
81
|
+
private get start();
|
|
82
|
+
/** The number a new invoice is offered once the last one is read - it follows the direction while the person leaves it. */
|
|
83
|
+
private get suggestedNumber();
|
|
59
84
|
/** Days an invoice is due - the company's, or thirty. */
|
|
60
85
|
private get paymentDays();
|
|
61
86
|
private chooseParty;
|
|
87
|
+
/** Edits of several fields at once. */
|
|
88
|
+
private put;
|
|
62
89
|
private renderVoid;
|
|
63
90
|
private changeTaxBasis;
|
|
64
91
|
/** The discount of the whole invoice as typed, and the totals after it. */
|
|
@@ -70,16 +97,12 @@ export declare class InvoiceEditor extends InvoiceEditor_base {
|
|
|
70
97
|
*/
|
|
71
98
|
private edit;
|
|
72
99
|
private configure;
|
|
73
|
-
private load;
|
|
74
|
-
private show;
|
|
75
|
-
/** Runs one request at a time; a refusal is said in the server's words. */
|
|
76
|
-
private run;
|
|
77
100
|
private input;
|
|
101
|
+
/** A new one is opened once it is made; the edits sent are cleared once the save answered. Answers the invoice's id. */
|
|
78
102
|
private save;
|
|
79
103
|
/** Asked first - to whom and how much, fixed after - then save what is on screen and issue it. */
|
|
80
104
|
private issue;
|
|
81
105
|
private void;
|
|
82
|
-
private mutate;
|
|
83
106
|
/**
|
|
84
107
|
* The saved invoice as it goes out (ADR-0170 decision 10) - the server's page in the language chosen there, the
|
|
85
108
|
* invoice's own first, to download as PDF or print. What is on screen and not saved is not in it.
|