@things-factory/sales 10.1.226 → 10.1.228

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 (58) hide show
  1. package/dist-client/index.d.ts +1 -0
  2. package/dist-client/index.js +1 -0
  3. package/dist-client/index.js.map +1 -1
  4. package/dist-client/pages/quotation-editor.d.ts +50 -6
  5. package/dist-client/pages/quotation-editor.js +303 -33
  6. package/dist-client/pages/quotation-editor.js.map +1 -1
  7. package/dist-client/pages/sales-product-list.d.ts +54 -0
  8. package/dist-client/pages/sales-product-list.js +202 -0
  9. package/dist-client/pages/sales-product-list.js.map +1 -0
  10. package/dist-client/route.d.ts +1 -1
  11. package/dist-client/route.js +3 -0
  12. package/dist-client/route.js.map +1 -1
  13. package/dist-client/sales-product-pick.d.ts +51 -0
  14. package/dist-client/sales-product-pick.js +210 -0
  15. package/dist-client/sales-product-pick.js.map +1 -0
  16. package/dist-client/sales-product-words.d.ts +2 -0
  17. package/dist-client/sales-product-words.js +8 -0
  18. package/dist-client/sales-product-words.js.map +1 -0
  19. package/dist-client/tsconfig.tsbuildinfo +1 -1
  20. package/dist-server/service/index.d.ts +6 -2
  21. package/dist-server/service/index.js +8 -3
  22. package/dist-server/service/index.js.map +1 -1
  23. package/dist-server/service/quotation/quotation-query.d.ts +3 -0
  24. package/dist-server/service/quotation/quotation-query.js +36 -0
  25. package/dist-server/service/quotation/quotation-query.js.map +1 -1
  26. package/dist-server/service/quotation/quotation-service.d.ts +1 -0
  27. package/dist-server/service/quotation/quotation-service.js +5 -4
  28. package/dist-server/service/quotation/quotation-service.js.map +1 -1
  29. package/dist-server/service/sales-product/index.d.ts +6 -0
  30. package/dist-server/service/sales-product/index.js +10 -0
  31. package/dist-server/service/sales-product/index.js.map +1 -0
  32. package/dist-server/service/sales-product/sales-product-mutation.d.ts +6 -0
  33. package/dist-server/service/sales-product/sales-product-mutation.js +46 -0
  34. package/dist-server/service/sales-product/sales-product-mutation.js.map +1 -0
  35. package/dist-server/service/sales-product/sales-product-query.d.ts +11 -0
  36. package/dist-server/service/sales-product/sales-product-query.js +78 -0
  37. package/dist-server/service/sales-product/sales-product-query.js.map +1 -0
  38. package/dist-server/service/sales-product/sales-product-rules.d.ts +8 -0
  39. package/dist-server/service/sales-product/sales-product-rules.js +26 -0
  40. package/dist-server/service/sales-product/sales-product-rules.js.map +1 -0
  41. package/dist-server/service/sales-product/sales-product-service.d.ts +10 -0
  42. package/dist-server/service/sales-product/sales-product-service.js +86 -0
  43. package/dist-server/service/sales-product/sales-product-service.js.map +1 -0
  44. package/dist-server/service/sales-product/sales-product-type.d.ts +22 -0
  45. package/dist-server/service/sales-product/sales-product-type.js +81 -0
  46. package/dist-server/service/sales-product/sales-product-type.js.map +1 -0
  47. package/dist-server/service/sales-product/sales-product.d.ts +32 -0
  48. package/dist-server/service/sales-product/sales-product.js +126 -0
  49. package/dist-server/service/sales-product/sales-product.js.map +1 -0
  50. package/dist-server/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +7 -7
  52. package/things-factory.config.js +2 -1
  53. package/translations/en.json +33 -3
  54. package/translations/es.json +33 -3
  55. package/translations/ja.json +33 -3
  56. package/translations/ko.json +34 -4
  57. package/translations/ms.json +33 -3
  58. package/translations/zh.json +33 -3
@@ -1 +1 @@
1
- {"version":3,"file":"quotation-editor.js","sourceRoot":"","sources":["../../client/pages/quotation-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 { navigate, PageView } from '@operato/shell'\nimport { ButtonStyles, CommonGristStyles, DocumentPageStyles, FormFieldStyles, ScrollbarStyles } from '@operato/styles'\nimport {\n documentHtml,\n DocumentFormStyles,\n documentLinesConfig,\n linesOf,\n printDocument,\n renderDocumentHead,\n renderDocumentTotals,\n type DocumentValue\n} from '@things-factory/invoice/dist-client'\n\nimport { quotationSection } from '../quotation-attach'\nimport { quotationStatusWord } from '../quotation-words'\n\nconst FIELDS = `\n id number version status validUntil outcomeReason opportunityId opportunity { id name } direction currency language supplierName supplierAddress supplierRegistrationNumber\n buyerName buyerAddress buyerRegistrationNumber issueDate purchaseOrder paymentTerms bankDetails notes sourceReference\n supplyAmount taxAmount totalAmount taxRounding currencyDigits\n items { position description quantity unitPrice discount taxKind taxRate supplyAmount }\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 'purchaseOrder',\n 'paymentTerms',\n 'bankDetails',\n 'notes',\n 'sourceReference',\n 'validUntil',\n 'opportunityId'\n]\n\nconst today = () => new Date().toLocaleDateString('en-CA')\n\n/**\n * 견적 편집 — the same head, lines and totals as an invoice, valid until a day.\n *\n * A draft is saved and sent; once sent its amounts are fixed, and the buyer's answer is recorded — accepted, or\n * declined with a reason. To change a sent quotation, revise it: the next version keeps the number.\n */\n@customElement('quotation-editor')\nexport class QuotationEditor 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() quotation: DocumentValue | null = null\n @state() form: DocumentValue = blank()\n @state() loading = false\n @state() error: unknown = null\n @state() busy = false\n @state() reason = ''\n @state() gristConfig: any\n /** The open opportunities a draft may answer, and the one it answers when that one is closed. */\n @state() opportunities: { id: string; name: string; counterparty?: { name: string } }[] = []\n\n @query('ox-grist') private grist?: DataGrist\n\n get editable() {\n return !this.quotation || this.quotation.status === 'DRAFT'\n }\n\n get context() {\n const status = this.quotation?.status\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.quotation-send'), icon: 'send', emphasis: { raised: true }, action: () => this.send() })\n }\n if (status === 'SENT') {\n if (this.quotation!.validUntil < today()) actions.push({ title: i18next.t('button.quotation-expire'), action: () => this.change('expireQuotation') })\n else actions.push({ title: i18next.t('button.quotation-accept'), emphasis: { raised: true }, action: () => this.change('acceptQuotation') })\n }\n if (['SENT', 'REJECTED', 'EXPIRED'].includes(status)) actions.push({ title: i18next.t('button.quotation-revise'), icon: 'edit_document', action: () => this.change('reviseQuotation') })\n if (this.quotation) actions.push({ title: i18next.t('button.quotation-print'), icon: 'print', action: () => this.print() })\n return {\n title: this.quotation ? `${i18next.t('title.quotation')} ${this.quotation.number} · v${this.quotation.version}` : i18next.t('title.quotation-new'),\n ...(this.quotation ? { description: quotationStatusWord(status) } : {}),\n frame: 'document',\n /* Opened from the quotation list; the menu marks it. */\n menu: 'quotation-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 (!this.opportunities.length) await this.readOpportunities()\n if (!id) {\n this.quotation = null\n /* Written from an opportunity, the draft answers it. */\n this.form = { ...blank(), opportunityId: lifecycle?.params?.opportunity ?? '' }\n this.configure()\n this.updateContext()\n return\n }\n if (id !== this.quotation?.id) await this.load(id)\n }\n\n render() {\n const attached = this.quotation ? quotationSection() : undefined\n const editable = this.editable && !this.busy\n return html`<ox-page-state .loading=${this.loading} .error=${this.error} @retry=${() => this.quotation && this.load(this.quotation.id)}>\n <div class=\"page\">\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.quotation-section-head')}</h3></header>\n ${renderDocumentHead(\n this.form,\n editable,\n patch => (this.form = { ...this.form, ...patch }),\n html`<label\n >${i18next.t('field.quotation-valid-until')}\n <input type=\"date\" .value=${this.form.validUntil ?? ''} ?disabled=${!editable} @input=${(e: any) => (this.form = { ...this.form, validUntil: e.target.value })}\n /></label>\n <label\n >${i18next.t('field.quotation-opportunity')}\n <select .value=${this.form.opportunityId ?? ''} ?disabled=${!editable} @change=${(e: any) => (this.form = { ...this.form, opportunityId: e.target.value })}>\n <option value=\"\"></option>\n ${this.opportunityChoices().map(\n one => html`<option value=${one.id} ?selected=${one.id === this.form.opportunityId}>${one.name}${one.counterparty?.name ? ` · ${one.counterparty.name}` : ''}</option>`\n )}\n </select>\n </label>`,\n 'field.quotation-number'\n )}\n </section>\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.quotation-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.quotation\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.quotation-section-totals')}</h3></header>\n ${renderDocumentTotals(this.quotation)}\n </section>`\n : nothing}\n ${this.quotation?.status === 'SENT' ? this.renderDecline() : nothing}\n ${this.quotation?.outcomeReason\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('field.quotation-outcome-reason')}</h3></header>\n <p>${this.quotation.outcomeReason}</p>\n </section>`\n : nothing}\n ${attached && this.quotation\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${attached.heading()}</h3></header>\n ${attached.render(this.quotation as any)}\n </section>`\n : nothing}\n </div>\n </ox-page-state>`\n }\n\n private renderDecline() {\n return html`<section class=\"page-section\">\n <header class=\"page-section-header\">\n <h3>${i18next.t('text.quotation-section-decline')}</h3>\n <div class=\"page-section-actions\">\n <button ?disabled=${this.busy || !this.reason.trim()} @click=${() => this.change('rejectQuotation', this.reason.trim())}>${i18next.t('button.quotation-reject')}</button>\n </div>\n </header>\n <div class=\"form\">\n <label class=\"wide\"\n >${i18next.t('field.quotation-outcome-reason')}\n <input .value=${this.reason} ?disabled=${this.busy} @input=${(e: any) => (this.reason = e.target.value)}\n /></label>\n </div>\n </section>`\n }\n\n private opportunityChoices() {\n const answered = this.quotation?.opportunity\n return answered && !this.opportunities.some(one => one.id === answered.id) ? [answered, ...this.opportunities] : this.opportunities\n }\n\n private async readOpportunities() {\n try {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n opportunities(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items { id name counterparty { name } }\n }\n }\n `,\n variables: {\n filters: [{ name: 'stage', operator: 'in', value: ['LEAD', 'PROPOSAL', 'QUOTED', 'NEGOTIATION'] }],\n pagination: { page: 1, limit: 500 },\n sortings: [{ name: 'name' }]\n },\n fetchPolicy: 'no-cache'\n })\n this.opportunities = response.data?.opportunities?.items ?? []\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error) })\n }\n }\n\n private configure() {\n this.gristConfig = documentLinesConfig({ editable: this.editable, 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!) { quotation(id: $id) { ${FIELDS} } }`), variables: { id }, fetchPolicy: 'no-cache' })\n if (response.errors?.length) throw response\n if (!response.data.quotation) throw new Error(i18next.t('text.quotation-not-found'))\n this.show(response.data.quotation)\n } catch (error) {\n this.error = error\n } finally {\n this.loading = false\n this.updateContext()\n }\n }\n\n private show(quotation: DocumentValue) {\n this.quotation = quotation\n this.form = { ...quotation, items: quotation.items.map((item: any) => ({ ...item })) }\n this.reason = ''\n this.configure()\n this.grist?.fetch()\n }\n\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.items = linesOf(this.grist).map(({ receivedTaxAmount, ...line }: any) => line)\n return input\n }\n\n private async save(): Promise<DocumentValue | undefined> {\n const id = this.quotation?.id\n const saved = await this.run(async () => {\n const response = await client.mutate({\n mutation: gql(\n id\n ? `mutation ($id: String!, $quotation: NewQuotation!) { quotation: updateQuotation(id: $id, quotation: $quotation) { ${FIELDS} } }`\n : `mutation ($quotation: NewQuotation!) { quotation: createQuotation(quotation: $quotation) { ${FIELDS} } }`\n ),\n variables: { ...(id ? { id } : {}), quotation: this.input() }\n })\n if (response.errors?.length) throw response\n return response.data.quotation as DocumentValue\n })\n if (!saved) return undefined\n this.show(saved)\n this.updateContext()\n if (!id) navigate(`quotation-editor?id=${saved.id}`)\n return saved\n }\n\n /** Save what is on screen, then send it — its amounts are fixed from here on. */\n private async send() {\n const saved = await this.save()\n if (saved) await this.change('sendQuotation')\n }\n\n private async change(mutation: string, reason?: string) {\n const changed = await this.run(async () => {\n const response = await client.mutate({\n mutation: gql(\n reason === undefined\n ? `mutation ($id: String!) { quotation: ${mutation}(id: $id) { ${FIELDS} } }`\n : `mutation ($id: String!, $reason: String!) { quotation: ${mutation}(id: $id, reason: $reason) { ${FIELDS} } }`\n ),\n variables: { id: this.quotation!.id, ...(reason === undefined ? {} : { reason }) }\n })\n if (response.errors?.length) throw response\n return response.data.quotation as DocumentValue\n })\n if (!changed) return\n if (changed.id !== this.quotation?.id) navigate(`quotation-editor?id=${changed.id}`)\n this.show(changed)\n this.updateContext()\n }\n\n private print() {\n const quotation = this.quotation!\n const lng = quotation.language === 'en' ? 'en' : 'ko'\n printDocument(\n documentHtml(quotation, {\n title: i18next.t('title.quotation-print', { lng }),\n numberLabel: 'field.quotation-number',\n terms: [\n { label: i18next.t('field.quotation-version', { lng }), value: `v${quotation.version}` },\n { label: i18next.t('field.quotation-valid-until', { lng }), value: quotation.validUntil }\n ]\n })\n )\n }\n}\n\nfunction blank(): DocumentValue {\n return { number: '', direction: 'SALES', currency: 'KRW', language: 'ko', supplierName: '', buyerName: '', issueDate: today(), validUntil: '', items: [] }\n}\n"]}
1
+ {"version":3,"file":"quotation-editor.js","sourceRoot":"","sources":["../../client/pages/quotation-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\nimport '@operato/list-state/ox-page-state.js'\nimport '@operato/input/ox-select.js'\nimport '@operato/popup/ox-popup-list.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'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client'\nimport {\n daysAfter,\n documentAmount,\n DocumentFormStyles,\n documentLinesConfig,\n linesOf,\n onLineChange,\n openDocumentPreview,\n reckonLines,\n renderDocumentHead,\n renderDocumentTotals,\n documentDefaults,\n headFromDefaults,\n nextInvoiceNumber,\n OUR_SIDE_FIELDS,\n oursFromLast,\n partyOfName,\n type DocumentDefaults,\n type DocumentFileFormat,\n type DocumentParty,\n type DocumentValue\n} from '@things-factory/invoice/dist-client'\n\nimport '@things-factory/invoice/dist-client/document/document-party.js'\n\nimport { quotationSection } from '../quotation-attach'\nimport '../sales-product-pick'\nimport { lineOfProduct, type PickedProduct } from '../sales-product-pick'\nimport { quotationStatusWord } from '../quotation-words'\n\nconst FIELDS = `\n id number version status validUntil outcomeReason opportunityId opportunity { id name } direction currency language supplierName supplierAddress supplierRegistrationNumber\n buyerName buyerAddress buyerRegistrationNumber issueDate purchaseOrder paymentTerms bankDetails notes sourceReference\n discountAmount lineSupplyAmount supplyAmount taxAmount totalAmount taxRounding currencyDigits\n items { position description quantity unit unitPrice discount taxKind taxRate supplyAmount }\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 'purchaseOrder',\n 'paymentTerms',\n 'bankDetails',\n 'notes',\n 'sourceReference',\n 'validUntil',\n 'opportunityId',\n 'discountAmount'\n]\n\nconst today = () => new Date().toLocaleDateString('en-CA')\n\n/** What an invoice made from a quotation takes of its head as it is. */\nconst INVOICE_HEAD = [\n 'direction',\n 'currency',\n 'language',\n 'supplierName',\n 'supplierAddress',\n 'supplierRegistrationNumber',\n 'buyerName',\n 'buyerAddress',\n 'buyerRegistrationNumber',\n 'paymentTerms',\n 'bankDetails',\n 'notes'\n]\n\n/** How long an offer holds unless the person writes another last day. */\nconst VALID_DAYS = 30\n\n/** Days an invoice made from a quotation is due unless the company says otherwise - the invoice editor's. */\nconst PAYMENT_DAYS = 30\n\n/** The next quotation number of a year after those given - 「Q2026-001」, 「Q2026-002」 … */\nexport function nextQuotationNumber(numbers: string[], year: number): string {\n const prefix = `Q${year}-`\n const last = Math.max(0, ...numbers.filter(one => one?.startsWith(prefix)).map(one => Number(one.slice(prefix.length)) || 0))\n return `${prefix}${String(last + 1).padStart(3, '0')}`\n}\n\n/**\n * 견적 편집 — the same head, lines and totals as an invoice, valid until a day.\n *\n * A draft is saved and sent; once sent its amounts are fixed, and the buyer's answer is recorded — accepted, or\n * declined with a reason. To change a sent quotation, revise it: the next version keeps the number.\n */\n@customElement('quotation-editor')\nexport class QuotationEditor 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 /* 상품에서 추가 sits over the lines, as wide as a head field. */\n .pick {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-small);\n max-width: 480px;\n margin-bottom: var(--spacing-medium);\n font-size: var(--ui-t-micro);\n color: var(--ui-muted);\n }\n `\n ]\n\n @state() quotation: DocumentValue | null = null\n @state() form: DocumentValue = blank()\n @state() loading = false\n @state() error: unknown = null\n @state() busy = false\n @state() reason = ''\n @state() gristConfig: any\n /** The open opportunities a draft may answer, and the one it answers when that one is closed. */\n @state() opportunities: { id: string; name: string; counterparty?: DocumentParty | null }[] = []\n /** The company's words a new quotation starts with, the terms it offers and how long an offer holds (ADR-0170). */\n @state() defaults: DocumentDefaults | null = null\n /** The counterparty the buyer was taken from on this screen - shown in the picker. */\n @state() party: DocumentParty | null = null\n /** The totals of the lines as typed - reckoned as the quotation will keep them, shown before it is saved. */\n @state() amounts: Partial<DocumentValue> = {}\n /** Whether this person may write invoices - an accepted quotation then makes one. */\n @state() invoiceWriter = false\n\n @query('ox-grist') private grist?: DataGrist\n\n get editable() {\n return !this.quotation || this.quotation.status === 'DRAFT'\n }\n\n get context() {\n const status = this.quotation?.status\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.quotation-send'), icon: 'send', emphasis: { raised: true }, action: () => this.send() })\n }\n if (status === 'SENT') {\n if (this.quotation!.validUntil < today()) actions.push({ title: i18next.t('button.quotation-expire'), action: () => this.change('expireQuotation') })\n else actions.push({ title: i18next.t('button.quotation-accept'), emphasis: { raised: true }, action: () => this.change('acceptQuotation') })\n }\n if (status === 'ACCEPTED' && this.invoiceWriter) actions.push({ title: i18next.t('button.quotation-make-invoice'), icon: 'receipt_long', emphasis: { raised: true }, action: () => this.makeInvoice() })\n if (['SENT', 'REJECTED', 'EXPIRED'].includes(status)) actions.push({ title: i18next.t('button.quotation-revise'), icon: 'edit_document', action: () => this.change('reviseQuotation') })\n if (this.quotation) actions.push({ title: i18next.t('button.preview'), icon: 'preview', action: () => this.preview() })\n return {\n title: this.quotation ? `${i18next.t('title.quotation')} ${this.quotation.number} · v${this.quotation.version}` : i18next.t('title.quotation-new'),\n ...(this.quotation ? { description: quotationStatusWord(status) } : {}),\n frame: 'document',\n /* Opened from the quotation list; the menu marks it. */\n menu: 'quotation-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 (!this.opportunities.length) await this.readOpportunities()\n if (!this.defaults) this.defaults = await documentDefaults()\n hasPrivilege({ category: 'invoice', privilege: 'mutation', domainOwnerGranted: true }).then(writer => {\n this.invoiceWriter = !!writer\n this.updateContext()\n })\n if (!id) {\n this.quotation = null\n /* Written from an opportunity, the draft answers it. */\n this.form = { ...blank(), opportunityId: lifecycle?.params?.opportunity ?? '' }\n this.amounts = {}\n this.party = null\n this.configure()\n await this.prefill()\n this.updateContext()\n return\n }\n if (id !== this.quotation?.id) await this.load(id)\n }\n\n render() {\n const attached = this.quotation ? quotationSection() : undefined\n const editable = this.editable && !this.busy\n return html`<ox-page-state .loading=${this.loading} .error=${this.error} @retry=${() => this.quotation && this.load(this.quotation.id)}>\n <div class=\"page\">\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.quotation-section-head')}</h3></header>\n ${renderDocumentHead(\n this.form,\n editable,\n patch => this.edit(patch),\n html`<label\n >${i18next.t('field.quotation-valid-until')}\n <input type=\"date\" .value=${this.form.validUntil ?? ''} ?disabled=${!editable} @input=${(e: any) => (this.form = { ...this.form, validUntil: e.target.value })}\n /></label>\n ${this.renderOpportunity(editable)}`,\n 'field.quotation-number',\n {\n terms: this.defaults?.paymentTerms,\n /* In the group it fills - the buyer's of a sale, the supplier's of a purchase. */\n party: html`<label\n >${i18next.t('field.counterparty')}\n <document-party-select .party=${this.party} ?disabled=${!editable} @party=${(e: CustomEvent) => this.takeParty(e.detail)}></document-party-select>\n </label>`\n }\n )}\n </section>\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.quotation-section-lines')}</h3></header>\n ${editable\n ? html`<label class=\"pick\"\n >${i18next.t('field.sales-product-pick')}\n <sales-product-pick .currency=${this.form.currency || 'KRW'} @product=${(e: CustomEvent) => this.addProduct(e.detail)}></sales-product-pick>\n </label>`\n : nothing}\n <ox-grist\n mode=\"GRID\"\n .config=${this.gristConfig}\n .fetchHandler=${() => ({ total: this.form.items.length, records: this.form.items })}\n @record-change=${(e: CustomEvent) => (this.amounts = onLineChange(this.grist, e, this.form.currency, false, this.form.discountAmount))}\n ></ox-grist>\n </section>\n <section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('text.quotation-section-totals')}</h3></header>\n ${renderDocumentTotals(\n { ...this.amounts, currency: this.form.currency },\n { value: this.form.discountAmount, editable, change: value => this.discount(value) }\n )}\n </section>\n ${this.quotation?.status === 'SENT' ? this.renderDecline() : nothing}\n ${this.quotation?.outcomeReason\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${i18next.t('field.quotation-outcome-reason')}</h3></header>\n <p>${this.quotation.outcomeReason}</p>\n </section>`\n : nothing}\n ${attached && this.quotation\n ? html`<section class=\"page-section\">\n <header class=\"page-section-header\"><h3>${attached.heading()}</h3></header>\n ${attached.render(this.quotation as any)}\n </section>`\n : nothing}\n </div>\n </ox-page-state>`\n }\n\n private renderDecline() {\n return html`<section class=\"page-section\">\n <header class=\"page-section-header\">\n <h3>${i18next.t('text.quotation-section-decline')}</h3>\n <div class=\"page-section-actions\">\n <button ?disabled=${this.busy || !this.reason.trim()} @click=${() => this.change('rejectQuotation', this.reason.trim())}>${i18next.t('button.quotation-reject')}</button>\n </div>\n </header>\n <div class=\"form\">\n <label class=\"wide\"\n >${i18next.t('field.quotation-outcome-reason')}\n <input .value=${this.reason} ?disabled=${this.busy} @input=${(e: any) => (this.reason = e.target.value)}\n /></label>\n </div>\n </section>`\n }\n\n /**\n * A line made from a product, after the lines there are - a copy the person then changes like any line (ADR-0171) -\n * and the totals reckoned with it.\n */\n private async addProduct(product: PickedProduct) {\n const grist = this.grist\n if (!grist || !product) return\n grist.addRecord(lineOfProduct(product))\n await grist.updateComplete\n this.amounts = reckonLines(grist, this.form.currency, false, this.form.discountAmount)\n grist.refresh()\n }\n\n /** The discount of the whole quotation as typed, and the totals after it. */\n private discount(value: string) {\n this.form = { ...this.form, discountAmount: value }\n this.amounts = reckonLines(this.grist, this.form.currency, false, value)\n }\n\n /** A change of the head; a new currency reckons the lines in its minor unit; the last day follows a moved issue day. */\n private edit(patch: DocumentValue) {\n const currency = this.form.currency\n const following = patch.issueDate && this.form.validUntil === daysAfter(this.form.issueDate, this.validDays)\n this.form = { ...this.form, ...patch, ...(following ? { validUntil: daysAfter(patch.issueDate, this.validDays) } : {}) }\n if (patch.currency && patch.currency !== currency) {\n this.configure()\n this.amounts = reckonLines(this.grist, this.form.currency, false, this.form.discountAmount)\n }\n }\n\n /** The opportunity it answers - found by typing; choosing one takes its counterparty as the buyer when none is written. */\n private renderOpportunity(editable: boolean) {\n const choices = this.opportunityChoices()\n const chosen = choices.find(one => one.id === this.form.opportunityId)\n const label = (one: { name: string; counterparty?: DocumentParty | null }) => `${one.name}${one.counterparty?.name ? ` · ${one.counterparty.name}` : ''}`\n return html`<label\n >${i18next.t('field.quotation-opportunity')}\n <ox-select\n .value=${this.form.opportunityId ?? ''}\n ?disabled=${!editable}\n aria-label=${i18next.t('field.quotation-opportunity')}\n @change=${(e: CustomEvent) => {\n const id = String(e.detail ?? '')\n if (id === (this.form.opportunityId ?? '')) return\n const opportunity = choices.find(one => one.id === id)\n this.form = { ...this.form, opportunityId: id }\n if (opportunity?.counterparty && !String(this.form.buyerName ?? '').trim()) this.takeParty(opportunity.counterparty)\n }}\n >\n <span slot=\"label\">${chosen ? label(chosen) : '—'}</span>\n <ox-popup-list align-left nowrap with-search>\n <div option value=\"\">—</div>\n ${choices.map(one => html`<div option value=${one.id}>${label(one)}</div>`)}\n </ox-popup-list>\n </ox-select>\n </label>`\n }\n\n /** A counterparty as the other side: the buyer of a sale, the supplier of a purchase. */\n private takeParty(party: DocumentParty | null) {\n this.party = party\n if (!party) return\n const side = this.form.direction === 'PURCHASE' ? 'supplier' : 'buyer'\n this.form = { ...this.form, [`${side}Name`]: party.name, [`${side}RegistrationNumber`]: party.businessNumber ?? this.form[`${side}RegistrationNumber`] ?? '' }\n }\n\n /**\n * What a new quotation starts with, so a person writes only what is new: the next number of the year, the last day an\n * offer holds, the company's own words (ADR-0170), and what they leave blank of our side as the last sales quotation\n * wrote it.\n */\n private async prefill() {\n try {\n const year = Number(this.form.issueDate.slice(0, 4))\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n numbered: quotations(filters: $filters, pagination: { page: 1, limit: 1000 }) { items { number } }\n last: quotations(pagination: $pagination, sortings: $sortings) { items { direction ${OUR_SIDE_FIELDS.join(' ')} } }\n }\n `,\n variables: { filters: [{ name: 'number', operator: 'like', value: `Q${year}-%` }], pagination: { page: 1, limit: 1 }, sortings: [{ name: 'createdAt', desc: true }] },\n fetchPolicy: 'no-cache'\n })\n const last = (response.data?.last?.items ?? []).find((one: any) => one.direction === 'SALES')\n this.form = { ...this.form, ...headFromDefaults(this.form, this.defaults) }\n this.form = {\n ...this.form,\n ...oursFromLast(this.form, last),\n number: this.form.number || nextQuotationNumber((response.data?.numbered?.items ?? []).map((one: any) => one.number), year),\n validUntil: this.form.validUntil || daysAfter(this.form.issueDate, this.validDays)\n }\n } catch {\n /* Nothing to start from - the person writes it, as before. */\n }\n const opportunity = this.opportunities.find(one => one.id === this.form.opportunityId)\n if (opportunity?.counterparty && !String(this.form.buyerName ?? '').trim()) this.takeParty(opportunity.counterparty)\n }\n\n /** Days an offer holds - the company's, or thirty. */\n private get validDays() {\n return this.defaults?.validDays || VALID_DAYS\n }\n\n private opportunityChoices() {\n const answered = this.quotation?.opportunity\n return answered && !this.opportunities.some(one => one.id === answered.id) ? [answered, ...this.opportunities] : this.opportunities\n }\n\n private async readOpportunities() {\n try {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n opportunities(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items { id name counterparty { id name businessNumber } }\n }\n }\n `,\n variables: {\n filters: [{ name: 'stage', operator: 'in', value: ['LEAD', 'PROPOSAL', 'QUOTED', 'NEGOTIATION'] }],\n pagination: { page: 1, limit: 500 },\n sortings: [{ name: 'name' }]\n },\n fetchPolicy: 'no-cache'\n })\n this.opportunities = response.data?.opportunities?.items ?? []\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error) })\n }\n }\n\n private configure() {\n this.gristConfig = documentLinesConfig({ editable: this.editable, 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!) { quotation(id: $id) { ${FIELDS} } }`), variables: { id }, fetchPolicy: 'no-cache' })\n if (response.errors?.length) throw response\n if (!response.data.quotation) throw new Error(i18next.t('text.quotation-not-found'))\n this.show(response.data.quotation)\n } catch (error) {\n this.error = error\n } finally {\n this.loading = false\n this.updateContext()\n }\n }\n\n private show(quotation: DocumentValue) {\n this.quotation = quotation\n this.form = { ...quotation, items: quotation.items.map((item: any) => ({ ...item })) }\n this.amounts = quotation\n this.reason = ''\n this.configure()\n this.grist?.fetch()\n }\n\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.items = linesOf(this.grist).map(({ receivedTaxAmount, ...line }: any) => line)\n input.discountAmount = input.discountAmount === null ? 0 : Number(input.discountAmount)\n return input\n }\n\n private async save(): Promise<DocumentValue | undefined> {\n const id = this.quotation?.id\n const saved = await this.run(async () => {\n const response = await client.mutate({\n mutation: gql(\n id\n ? `mutation ($id: String!, $quotation: NewQuotation!) { quotation: updateQuotation(id: $id, quotation: $quotation) { ${FIELDS} } }`\n : `mutation ($quotation: NewQuotation!) { quotation: createQuotation(quotation: $quotation) { ${FIELDS} } }`\n ),\n variables: { ...(id ? { id } : {}), quotation: this.input() }\n })\n if (response.errors?.length) throw response\n return response.data.quotation as DocumentValue\n })\n if (!saved) return undefined\n this.show(saved)\n this.updateContext()\n if (!id) navigate(`quotation-editor?id=${saved.id}`)\n return saved\n }\n\n /** Asked first - to whom and how much, fixed after - then save what is on screen and send it. */\n private async send() {\n const purchase = this.form.direction === 'PURCHASE'\n const words = {\n party: (purchase ? this.form.supplierName : this.form.buyerName) || '—',\n total: documentAmount(this.amounts.totalAmount ?? 0, this.form.currency || 'KRW')\n }\n const confirmed = await OxPrompt.open({\n title: i18next.t('button.quotation-send'),\n text: purchase ? i18next.t('text.quotation-send-confirm-purchase', words) : i18next.t('text.quotation-send-confirm', words),\n confirmButton: { text: i18next.t('button.quotation-send') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!confirmed) return\n const saved = await this.save()\n if (saved) await this.change('sendQuotation')\n }\n\n private async change(mutation: string, reason?: string) {\n const changed = await this.run(async () => {\n const response = await client.mutate({\n mutation: gql(\n reason === undefined\n ? `mutation ($id: String!) { quotation: ${mutation}(id: $id) { ${FIELDS} } }`\n : `mutation ($id: String!, $reason: String!) { quotation: ${mutation}(id: $id, reason: $reason) { ${FIELDS} } }`\n ),\n variables: { id: this.quotation!.id, ...(reason === undefined ? {} : { reason }) }\n })\n if (response.errors?.length) throw response\n return response.data.quotation as DocumentValue\n })\n if (!changed) return\n if (changed.id !== this.quotation?.id) navigate(`quotation-editor?id=${changed.id}`)\n this.show(changed)\n this.updateContext()\n }\n\n /**\n * An invoice draft of an accepted quotation (ADR-0170 decision 11): its parties, currency, language, terms, account,\n * notes, discount and lines as the quotation has them, issued today and due the company's days after, the quotation\n * named as its source - then opened to be checked and issued. The counterparty is the one of the other party's name,\n * as the invoice editor links it.\n */\n private async makeInvoice() {\n const quotation = this.quotation!\n const created = await this.run(async () => {\n const last = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n invoices(filters: $filters, pagination: $pagination, sortings: $sortings) { items { number } }\n }\n `,\n variables: { filters: [{ name: 'direction', operator: 'eq', value: 'SALES' }], pagination: { page: 1, limit: 1 }, sortings: [{ name: 'createdAt', desc: true }] },\n fetchPolicy: 'no-cache'\n })\n const issueDate = today()\n const party = await partyOfName(quotation.direction === 'PURCHASE' ? quotation.supplierName : quotation.buyerName)\n const response = await client.mutate({\n mutation: gql`\n mutation ($invoice: NewInvoice!) {\n createInvoice(invoice: $invoice) { id }\n }\n `,\n variables: {\n invoice: {\n number: nextInvoiceNumber(last.data?.invoices?.items?.[0]?.number, Number(issueDate.slice(0, 4))),\n counterpartyId: party?.id ?? null,\n ...Object.fromEntries(INVOICE_HEAD.map(key => [key, quotation[key] ?? null])),\n issueDate,\n dueDate: daysAfter(issueDate, this.defaults?.paymentDays ?? PAYMENT_DAYS),\n sourceReference: i18next.t('text.quotation-invoice-source', { number: quotation.number, version: quotation.version }),\n taxBasis: 'CALCULATED',\n discountAmount: Number(quotation.discountAmount ?? 0),\n items: quotation.items.map(({ description, quantity, unit, unitPrice, discount, taxKind, taxRate }: any) => ({\n description,\n quantity,\n unit: unit ?? null,\n unitPrice,\n discount,\n taxKind,\n taxRate\n }))\n }\n }\n })\n if (response.errors?.length) throw response\n return response.data.createInvoice as { id: string }\n })\n if (created) navigate(`invoice-editor?id=${created.id}`)\n }\n\n /**\n * The saved quotation as it goes out (ADR-0170 decision 10) - the server's page in the language chosen there, the\n * quotation's own first, to download as PDF or print. What is on screen and not saved is not in it.\n */\n private preview() {\n const { id, number, version, language } = this.quotation!\n openDocumentPreview(\n async (format: DocumentFileFormat, lng: string) => {\n const response = await client.query({\n query: gql`\n query ($id: String!, $format: DocumentFileFormat!, $language: String) {\n quotationDocumentFile(id: $id, format: $format, language: $language) { fileName mimeType content }\n }\n `,\n variables: { id, format, language: lng },\n fetchPolicy: 'no-cache'\n })\n if (!response.data?.quotationDocumentFile) throw response.errors?.[0] ?? new Error(i18next.t('text.quotation-not-found'))\n return response.data.quotationDocumentFile\n },\n language,\n `${i18next.t('title.preview')} · ${number} · v${version}`\n )\n }\n}\n\nfunction blank(): DocumentValue {\n return { number: '', direction: 'SALES', currency: 'KRW', language: 'ko', supplierName: '', buyerName: '', issueDate: today(), validUntil: '', discountAmount: 0, items: [] }\n}\n"]}
@@ -0,0 +1,54 @@
1
+ import '@operato/data-grist/ox-grist.js';
2
+ import '@operato/data-grist/ox-filters-form.js';
3
+ import { FetchOption } from '@operato/data-grist';
4
+ import { PageView } from '@operato/shell';
5
+ declare const SalesProductList_base: (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
6
+ /**
7
+ * 상품 — what the domain sells and the price it offers it at: goods, a service, or labor by the grade of the people
8
+ * (ADR-0171). Typed like a spreadsheet and saved together. A quotation line chosen from a product copies it at that
9
+ * moment; changing a price here changes no written quotation.
10
+ */
11
+ export declare class SalesProductList extends SalesProductList_base {
12
+ static styles: import("lit").CSSResult[];
13
+ gristConfig: any;
14
+ private grist;
15
+ get context(): {
16
+ title: string;
17
+ search: {
18
+ handler: (search: string) => void;
19
+ value: string;
20
+ };
21
+ filter: {
22
+ handler: () => void;
23
+ };
24
+ actions: ({
25
+ title: string;
26
+ icon: string;
27
+ action: () => void;
28
+ } | {
29
+ icon: string;
30
+ emphasis: {
31
+ raised: boolean;
32
+ outlined: boolean;
33
+ dense: boolean;
34
+ danger: boolean;
35
+ };
36
+ title: string;
37
+ action: () => Promise<void>;
38
+ })[];
39
+ exportable: {
40
+ name: string;
41
+ data: () => any[];
42
+ };
43
+ };
44
+ render(): import("lit-html").TemplateResult<1>;
45
+ pageInitialized(): Promise<void>;
46
+ fetchHandler({ page, limit, sortings, filters, search }: FetchOption): Promise<{
47
+ total: any;
48
+ records: any;
49
+ }>;
50
+ /** New, changed and deleted rows together; a refusal is said in the server's words and nothing is kept. */
51
+ private save;
52
+ private delete;
53
+ }
54
+ export {};
@@ -0,0 +1,202 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@operato/data-grist/ox-grist.js';
3
+ import '@operato/data-grist/ox-filters-form.js';
4
+ import gql from 'graphql-tag';
5
+ import { html } from 'lit';
6
+ import { customElement, query, state } from 'lit/decorators.js';
7
+ import { DataGrist } from '@operato/data-grist';
8
+ import { client } from '@operato/graphql';
9
+ import { i18next, localize } from '@operato/i18n';
10
+ import { notify } from '@operato/layout';
11
+ import { OxPrompt } from '@operato/popup/ox-prompt.js';
12
+ import { PageView } from '@operato/shell';
13
+ import { CommonButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
14
+ import { isMobileDevice } from '@operato/utils';
15
+ import { documentNumber } from '@things-factory/invoice/dist-client';
16
+ import { salesProductKindWord } from '../sales-product-words';
17
+ const KINDS = ['GOODS', 'SERVICE', 'LABOR'];
18
+ /** The fields a row writes - all of them for a new row, the changed ones otherwise. */
19
+ const FIELDS = ['code', 'name', 'kind', 'grade', 'spec', 'unit', 'unitPrice', 'currency', 'taxKind', 'active', 'description'];
20
+ /**
21
+ * 상품 — what the domain sells and the price it offers it at: goods, a service, or labor by the grade of the people
22
+ * (ADR-0171). Typed like a spreadsheet and saved together. A quotation line chosen from a product copies it at that
23
+ * moment; changing a price here changes no written quotation.
24
+ */
25
+ let SalesProductList = class SalesProductList extends localize(i18next)(PageView) {
26
+ static { this.styles = [WorkSurfacePageStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles]; }
27
+ get context() {
28
+ return {
29
+ title: i18next.t('title.sales-product-list'),
30
+ search: {
31
+ handler: (search) => {
32
+ this.grist.searchText = search;
33
+ },
34
+ value: this.grist?.searchText || ''
35
+ },
36
+ filter: {
37
+ handler: () => {
38
+ this.grist.toggleHeadroom();
39
+ }
40
+ },
41
+ actions: [
42
+ { title: i18next.t('button.add'), icon: 'add', action: () => this.grist.addRecordToTop({ kind: 'GOODS', currency: 'KRW', taxKind: 'TAXABLE', active: true }) },
43
+ { title: i18next.t('button.delete'), action: () => this.delete(), ...CommonButtonStyles.delete },
44
+ { title: i18next.t('button.save'), action: () => this.save(), ...CommonButtonStyles.save }
45
+ ],
46
+ exportable: { name: i18next.t('title.sales-product-list'), data: () => this.grist.exportRecords() }
47
+ };
48
+ }
49
+ render() {
50
+ return html `<ox-grist
51
+ class="page-fill"
52
+ search-mode="term"
53
+ .mode=${isMobileDevice() ? 'CARD' : 'GRID'}
54
+ .config=${this.gristConfig}
55
+ .fetchHandler=${this.fetchHandler.bind(this)}
56
+ >
57
+ <div slot="headroom" class="header">
58
+ <div class="filters">
59
+ <ox-filters-form without-search autofocus></ox-filters-form>
60
+ </div>
61
+ </div>
62
+ </ox-grist>`;
63
+ }
64
+ async pageInitialized() {
65
+ const text = (name, header, width, extra = {}) => ({ type: 'string', name, header, width, sortable: true, ...extra, record: { editable: true, ...extra.record } });
66
+ this.gristConfig = {
67
+ rows: { appendable: true, selectable: { multiple: true } },
68
+ pagination: { limit: 100, pages: [50, 100, 500] },
69
+ emptyNote: { title: i18next.t('text.sales-product-empty'), description: i18next.t('text.sales-product-empty-description') },
70
+ list: { fields: ['name', 'code'], details: ['kind', 'unit', 'unitPrice'] },
71
+ columns: [
72
+ { type: 'gutter', gutterName: 'sequence' },
73
+ { type: 'gutter', gutterName: 'row-selector', multiple: true },
74
+ text('code', i18next.t('field.sales-product-code'), 110, { record: { mandatory: true } }),
75
+ text('name', i18next.t('field.sales-product-name'), 200, { record: { mandatory: true } }),
76
+ {
77
+ type: 'select',
78
+ name: 'kind',
79
+ header: i18next.t('field.sales-product-kind'),
80
+ width: 80,
81
+ sortable: true,
82
+ record: { editable: true, options: KINDS.map(kind => ({ value: kind, display: salesProductKindWord(kind) })) },
83
+ filter: { type: 'select', operator: 'eq', options: [{ display: '', value: '' }, ...KINDS.map(kind => ({ display: salesProductKindWord(kind), value: kind }))] }
84
+ },
85
+ text('grade', i18next.t('field.sales-product-grade'), 110),
86
+ text('spec', i18next.t('field.sales-product-spec'), 160),
87
+ text('unit', i18next.t('field.sales-product-unit'), 70, { record: { align: 'center' } }),
88
+ {
89
+ type: 'float',
90
+ name: 'unitPrice',
91
+ header: i18next.t('field.sales-product-unit-price'),
92
+ width: 130,
93
+ sortable: true,
94
+ record: { editable: true, align: 'right', renderer: (value, _c, record) => documentNumber(value, record?.currency || 'KRW') }
95
+ },
96
+ text('currency', i18next.t('field.sales-product-currency'), 70, { record: { align: 'center' } }),
97
+ {
98
+ type: 'select',
99
+ name: 'taxKind',
100
+ header: i18next.t('field.sales-product-tax-kind'),
101
+ width: 80,
102
+ record: {
103
+ editable: true,
104
+ options: [
105
+ { value: 'TAXABLE', display: i18next.t('text.tax-kind-taxable') },
106
+ { value: 'ZERO_RATED', display: i18next.t('text.tax-kind-zero-rated') },
107
+ { value: 'EXEMPT', display: i18next.t('text.tax-kind-exempt') }
108
+ ]
109
+ }
110
+ },
111
+ { type: 'checkbox', name: 'active', header: i18next.t('field.sales-product-active'), width: 60, sortable: true, record: { editable: true } },
112
+ text('description', i18next.t('field.sales-product-description'), 220)
113
+ ],
114
+ sorters: [{ name: 'code' }]
115
+ };
116
+ }
117
+ async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [], search }) {
118
+ const response = await client.query({
119
+ query: gql `
120
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $search: String) {
121
+ responses: salesProducts(filters: $filters, pagination: $pagination, sortings: $sortings, search: $search) {
122
+ items { id code name kind grade spec unit unitPrice currency taxKind active description }
123
+ total
124
+ }
125
+ }
126
+ `,
127
+ variables: { filters, pagination: { page, limit }, sortings, search: search?.trim() || undefined },
128
+ fetchPolicy: 'network-only'
129
+ });
130
+ if (response.errors?.length)
131
+ throw response;
132
+ return { total: response.data.responses.total, records: response.data.responses.items };
133
+ }
134
+ /** New, changed and deleted rows together; a refusal is said in the server's words and nothing is kept. */
135
+ async save() {
136
+ const patches = this.grist.dirtyRecords.map((record) => {
137
+ const changed = record.__dirty__ === '+' ? FIELDS.filter(field => record[field] !== undefined) : Object.keys(record.__dirtyfields__ ?? {}).filter(field => FIELDS.includes(field));
138
+ return { ...(record.id ? { id: record.id } : {}), cuFlag: record.__dirty__, ...Object.fromEntries(changed.map(field => [field, record[field] === '' ? null : record[field]])) };
139
+ });
140
+ if (!patches.length)
141
+ return;
142
+ try {
143
+ const response = await client.mutate({
144
+ mutation: gql `
145
+ mutation ($patches: [SalesProductPatch!]!) {
146
+ updateMultipleSalesProduct(patches: $patches) { id }
147
+ }
148
+ `,
149
+ variables: { patches }
150
+ });
151
+ if (response.errors?.length)
152
+ throw response;
153
+ notify({ level: 'info', message: i18next.t('text.sales-product-saved') });
154
+ this.grist.fetch();
155
+ }
156
+ catch (error) {
157
+ notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.errors?.[0]?.message ?? error?.message ?? String(error) });
158
+ }
159
+ }
160
+ async delete() {
161
+ const ids = this.grist.selected.map((record) => record.id).filter(Boolean);
162
+ if (!ids.length)
163
+ return;
164
+ const confirmed = await OxPrompt.open({
165
+ title: i18next.t('button.delete'),
166
+ text: i18next.t('text.sales-product-delete-confirm', { count: ids.length }),
167
+ confirmButton: { text: i18next.t('button.delete'), destructive: true },
168
+ cancelButton: { text: i18next.t('button.cancel') }
169
+ });
170
+ if (!confirmed)
171
+ return;
172
+ try {
173
+ const response = await client.mutate({
174
+ mutation: gql `
175
+ mutation ($ids: [String!]!) {
176
+ deleteSalesProducts(ids: $ids)
177
+ }
178
+ `,
179
+ variables: { ids }
180
+ });
181
+ if (response.errors?.length)
182
+ throw response;
183
+ this.grist.fetch();
184
+ }
185
+ catch (error) {
186
+ notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.errors?.[0]?.message ?? error?.message ?? String(error) });
187
+ }
188
+ }
189
+ };
190
+ __decorate([
191
+ state(),
192
+ __metadata("design:type", Object)
193
+ ], SalesProductList.prototype, "gristConfig", void 0);
194
+ __decorate([
195
+ query('ox-grist'),
196
+ __metadata("design:type", DataGrist)
197
+ ], SalesProductList.prototype, "grist", void 0);
198
+ SalesProductList = __decorate([
199
+ customElement('sales-product-list')
200
+ ], SalesProductList);
201
+ export { SalesProductList };
202
+ //# sourceMappingURL=sales-product-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sales-product-list.js","sourceRoot":"","sources":["../../client/pages/sales-product-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist/ox-grist.js'\nimport '@operato/data-grist/ox-filters-form.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 { notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { PageView } from '@operato/shell'\nimport { CommonButtonStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { documentNumber } from '@things-factory/invoice/dist-client'\n\nimport { salesProductKindWord } from '../sales-product-words'\n\nconst KINDS = ['GOODS', 'SERVICE', 'LABOR']\n\n/** The fields a row writes - all of them for a new row, the changed ones otherwise. */\nconst FIELDS = ['code', 'name', 'kind', 'grade', 'spec', 'unit', 'unitPrice', 'currency', 'taxKind', 'active', 'description']\n\n/**\n * 상품 — what the domain sells and the price it offers it at: goods, a service, or labor by the grade of the people\n * (ADR-0171). Typed like a spreadsheet and saved together. A quotation line chosen from a product copies it at that\n * moment; changing a price here changes no written quotation.\n */\n@customElement('sales-product-list')\nexport class SalesProductList extends localize(i18next)(PageView) {\n static styles = [WorkSurfacePageStyles, CommonGristStyles, CommonHeaderStyles, ScrollbarStyles]\n\n @state() gristConfig: any\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('title.sales-product-list'),\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: {\n handler: () => {\n this.grist.toggleHeadroom()\n }\n },\n actions: [\n { title: i18next.t('button.add'), icon: 'add', action: () => this.grist.addRecordToTop({ kind: 'GOODS', currency: 'KRW', taxKind: 'TAXABLE', active: true }) },\n { title: i18next.t('button.delete'), action: () => this.delete(), ...CommonButtonStyles.delete },\n { title: i18next.t('button.save'), action: () => this.save(), ...CommonButtonStyles.save }\n ],\n exportable: { name: i18next.t('title.sales-product-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 >\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-filters-form without-search autofocus></ox-filters-form>\n </div>\n </div>\n </ox-grist>`\n }\n\n async pageInitialized() {\n const text = (name: string, header: string, width: number, extra: any = {}) => ({ type: 'string', name, header, width, sortable: true, ...extra, record: { editable: true, ...extra.record } })\n this.gristConfig = {\n rows: { appendable: true, selectable: { multiple: true } },\n pagination: { limit: 100, pages: [50, 100, 500] },\n emptyNote: { title: i18next.t('text.sales-product-empty'), description: i18next.t('text.sales-product-empty-description') },\n list: { fields: ['name', 'code'], details: ['kind', 'unit', 'unitPrice'] },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter', gutterName: 'row-selector', multiple: true },\n text('code', i18next.t('field.sales-product-code'), 110, { record: { mandatory: true } }),\n text('name', i18next.t('field.sales-product-name'), 200, { record: { mandatory: true } }),\n {\n type: 'select',\n name: 'kind',\n header: i18next.t('field.sales-product-kind'),\n width: 80,\n sortable: true,\n record: { editable: true, options: KINDS.map(kind => ({ value: kind, display: salesProductKindWord(kind) })) },\n filter: { type: 'select', operator: 'eq', options: [{ display: '', value: '' }, ...KINDS.map(kind => ({ display: salesProductKindWord(kind), value: kind }))] }\n },\n text('grade', i18next.t('field.sales-product-grade'), 110),\n text('spec', i18next.t('field.sales-product-spec'), 160),\n text('unit', i18next.t('field.sales-product-unit'), 70, { record: { align: 'center' } }),\n {\n type: 'float',\n name: 'unitPrice',\n header: i18next.t('field.sales-product-unit-price'),\n width: 130,\n sortable: true,\n record: { editable: true, align: 'right', renderer: (value: number, _c: any, record: any) => documentNumber(value, record?.currency || 'KRW') }\n },\n text('currency', i18next.t('field.sales-product-currency'), 70, { record: { align: 'center' } }),\n {\n type: 'select',\n name: 'taxKind',\n header: i18next.t('field.sales-product-tax-kind'),\n width: 80,\n record: {\n editable: true,\n options: [\n { value: 'TAXABLE', display: i18next.t('text.tax-kind-taxable') },\n { value: 'ZERO_RATED', display: i18next.t('text.tax-kind-zero-rated') },\n { value: 'EXEMPT', display: i18next.t('text.tax-kind-exempt') }\n ]\n }\n },\n { type: 'checkbox', name: 'active', header: i18next.t('field.sales-product-active'), width: 60, sortable: true, record: { editable: true } },\n text('description', i18next.t('field.sales-product-description'), 220)\n ],\n sorters: [{ name: 'code' }]\n }\n }\n\n async fetchHandler({ page = 1, limit = 100, 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: salesProducts(filters: $filters, pagination: $pagination, sortings: $sortings, search: $search) {\n items { id code name kind grade spec unit unitPrice currency taxKind active description }\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 /** New, changed and deleted rows together; a refusal is said in the server's words and nothing is kept. */\n private async save() {\n const patches = this.grist.dirtyRecords.map((record: any) => {\n const changed = record.__dirty__ === '+' ? FIELDS.filter(field => record[field] !== undefined) : Object.keys(record.__dirtyfields__ ?? {}).filter(field => FIELDS.includes(field))\n return { ...(record.id ? { id: record.id } : {}), cuFlag: record.__dirty__, ...Object.fromEntries(changed.map(field => [field, record[field] === '' ? null : record[field]])) }\n })\n if (!patches.length) return\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation ($patches: [SalesProductPatch!]!) {\n updateMultipleSalesProduct(patches: $patches) { id }\n }\n `,\n variables: { patches }\n })\n if (response.errors?.length) throw response\n notify({ level: 'info', message: i18next.t('text.sales-product-saved') })\n this.grist.fetch()\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.errors?.[0]?.message ?? error?.message ?? String(error) })\n }\n }\n\n private async delete() {\n const ids = this.grist.selected.map((record: any) => record.id).filter(Boolean)\n if (!ids.length) return\n const confirmed = await OxPrompt.open({\n title: i18next.t('button.delete'),\n text: i18next.t('text.sales-product-delete-confirm', { count: ids.length }),\n confirmButton: { text: i18next.t('button.delete'), destructive: true },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n if (!confirmed) return\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation ($ids: [String!]!) {\n deleteSalesProducts(ids: $ids)\n }\n `,\n variables: { ids }\n })\n if (response.errors?.length) throw response\n this.grist.fetch()\n } catch (error: any) {\n notify({ level: 'error', message: error?.graphQLErrors?.[0]?.message ?? error?.errors?.[0]?.message ?? error?.message ?? String(error) })\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- export default function route(page: string): "quotation-list" | "quotation-editor" | "opportunity-list" | "opportunity-editor" | undefined;
1
+ export default function route(page: string): "quotation-list" | "quotation-editor" | "opportunity-list" | "opportunity-editor" | "sales-product-list" | undefined;
@@ -12,6 +12,9 @@ export default function route(page) {
12
12
  case 'opportunity-editor':
13
13
  import('./pages/opportunity-editor');
14
14
  return page;
15
+ case 'sales-product-list':
16
+ import('./pages/sales-product-list');
17
+ return page;
15
18
  }
16
19
  }
17
20
  //# sourceMappingURL=route.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAY;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,gBAAgB;YACnB,MAAM,CAAC,wBAAwB,CAAC,CAAA;YAChC,OAAO,IAAI,CAAA;QAEb,KAAK,kBAAkB;YACrB,MAAM,CAAC,0BAA0B,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;QAEb,KAAK,kBAAkB;YACrB,MAAM,CAAC,0BAA0B,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;QAEb,KAAK,oBAAoB;YACvB,MAAM,CAAC,4BAA4B,CAAC,CAAA;YACpC,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["export default function route(page: string) {\n switch (page) {\n case 'quotation-list':\n import('./pages/quotation-list')\n return page\n\n case 'quotation-editor':\n import('./pages/quotation-editor')\n return page\n\n case 'opportunity-list':\n import('./pages/opportunity-list')\n return page\n\n case 'opportunity-editor':\n import('./pages/opportunity-editor')\n return page\n }\n}\n"]}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAY;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,gBAAgB;YACnB,MAAM,CAAC,wBAAwB,CAAC,CAAA;YAChC,OAAO,IAAI,CAAA;QAEb,KAAK,kBAAkB;YACrB,MAAM,CAAC,0BAA0B,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;QAEb,KAAK,kBAAkB;YACrB,MAAM,CAAC,0BAA0B,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;QAEb,KAAK,oBAAoB;YACvB,MAAM,CAAC,4BAA4B,CAAC,CAAA;YACpC,OAAO,IAAI,CAAA;QAEb,KAAK,oBAAoB;YACvB,MAAM,CAAC,4BAA4B,CAAC,CAAA;YACpC,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["export default function route(page: string) {\n switch (page) {\n case 'quotation-list':\n import('./pages/quotation-list')\n return page\n\n case 'quotation-editor':\n import('./pages/quotation-editor')\n return page\n\n case 'opportunity-list':\n import('./pages/opportunity-list')\n return page\n\n case 'opportunity-editor':\n import('./pages/opportunity-editor')\n return page\n\n case 'sales-product-list':\n import('./pages/sales-product-list')\n return page\n }\n}\n"]}
@@ -0,0 +1,51 @@
1
+ import { LitElement } from 'lit';
2
+ /** A product as a quotation line takes it - what it is called and sold in, its price and taxation (ADR-0171). */
3
+ export type PickedProduct = {
4
+ id: string;
5
+ code: string;
6
+ name: string;
7
+ kind: string;
8
+ grade?: string | null;
9
+ spec?: string | null;
10
+ unit: string;
11
+ unitPrice: number;
12
+ currency: string;
13
+ taxKind: string;
14
+ };
15
+ /**
16
+ * The line a product makes: its name (and specification), one of its unit at its price, taxed as it is. A copy - the
17
+ * line keeps no tie to the product, so the person changes its price or anything else, and a later price of the
18
+ * product never reaches a written quotation (the user, 2026-10-28).
19
+ */
20
+ export declare function lineOfProduct(product: PickedProduct): {
21
+ description: string;
22
+ quantity: number;
23
+ unit: string;
24
+ unitPrice: number;
25
+ discount: number;
26
+ taxKind: string;
27
+ taxRate: number;
28
+ };
29
+ declare const SalesProductPick_base: (new (...args: any[]) => LitElement) & typeof LitElement;
30
+ /**
31
+ * 상품에서 추가 — one field that finds the domain's products still offered, in the document's currency, as it is typed;
32
+ * a click takes one and fires `product` with it. The editor makes a line of it - a copy, which the person then changes
33
+ * like any line. The interaction is the counterparty picker's (invoice `document-party-select`).
34
+ */
35
+ export declare class SalesProductPick extends SalesProductPick_base {
36
+ static styles: import("lit").CSSResult;
37
+ /** The document's currency - only products priced in it are offered. */
38
+ currency: string;
39
+ disabled: boolean;
40
+ private search;
41
+ private found;
42
+ private active;
43
+ private timer?;
44
+ private asked;
45
+ render(): import("lit-html").TemplateResult<1>;
46
+ private findSoon;
47
+ private find;
48
+ private key;
49
+ private choose;
50
+ }
51
+ export {};