@things-factory/saas 10.1.240 → 10.1.241

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 (76) hide show
  1. package/README.md +11 -11
  2. package/dist-client/entity360/saas-account-360.d.ts +0 -1
  3. package/dist-client/entity360/saas-account-360.js +18 -71
  4. package/dist-client/entity360/saas-account-360.js.map +1 -1
  5. package/dist-client/index.d.ts +0 -3
  6. package/dist-client/index.js +0 -3
  7. package/dist-client/index.js.map +1 -1
  8. package/dist-client/pages/saas-account-list.d.ts +1 -1
  9. package/dist-client/pages/saas-account-list.js +5 -14
  10. package/dist-client/pages/saas-account-list.js.map +1 -1
  11. package/dist-client/pages/saas-account-page.d.ts +3 -5
  12. package/dist-client/pages/saas-account-page.js +30 -55
  13. package/dist-client/pages/saas-account-page.js.map +1 -1
  14. package/dist-client/route.d.ts +1 -1
  15. package/dist-client/route.js +0 -3
  16. package/dist-client/route.js.map +1 -1
  17. package/dist-client/tsconfig.tsbuildinfo +1 -1
  18. package/dist-client/words.d.ts +0 -13
  19. package/dist-client/words.js +0 -17
  20. package/dist-client/words.js.map +1 -1
  21. package/dist-server/service/checks.d.ts +1 -9
  22. package/dist-server/service/checks.js +2 -18
  23. package/dist-server/service/checks.js.map +1 -1
  24. package/dist-server/service/index.d.ts +1 -6
  25. package/dist-server/service/index.js +1 -9
  26. package/dist-server/service/index.js.map +1 -1
  27. package/dist-server/service/saas-account.d.ts +0 -4
  28. package/dist-server/service/saas-account.js +1 -16
  29. package/dist-server/service/saas-account.js.map +1 -1
  30. package/dist-server/service/saas-mutation.d.ts +1 -10
  31. package/dist-server/service/saas-mutation.js +1 -86
  32. package/dist-server/service/saas-mutation.js.map +1 -1
  33. package/dist-server/service/saas-query.d.ts +2 -51
  34. package/dist-server/service/saas-query.js +2 -65
  35. package/dist-server/service/saas-query.js.map +1 -1
  36. package/dist-server/service/saas-rules.d.ts +3 -141
  37. package/dist-server/service/saas-rules.js +10 -213
  38. package/dist-server/service/saas-rules.js.map +1 -1
  39. package/dist-server/service/saas-service.d.ts +2 -125
  40. package/dist-server/service/saas-service.js +50 -438
  41. package/dist-server/service/saas-service.js.map +1 -1
  42. package/dist-server/service/saas-subscription.d.ts +4 -5
  43. package/dist-server/service/saas-subscription.js +11 -21
  44. package/dist-server/service/saas-subscription.js.map +1 -1
  45. package/dist-server/service/saas-sync.d.ts +0 -35
  46. package/dist-server/service/saas-sync.js +0 -60
  47. package/dist-server/service/saas-sync.js.map +1 -1
  48. package/dist-server/service/saas-type.d.ts +0 -93
  49. package/dist-server/service/saas-type.js +3 -351
  50. package/dist-server/service/saas-type.js.map +1 -1
  51. package/dist-server/tsconfig.tsbuildinfo +1 -1
  52. package/package.json +10 -10
  53. package/translations/en.json +3 -81
  54. package/translations/es.json +3 -81
  55. package/translations/ja.json +3 -81
  56. package/translations/ko.json +3 -81
  57. package/translations/ms.json +3 -81
  58. package/translations/zh.json +3 -81
  59. package/dist-client/components/saas-bill-editor.d.ts +0 -59
  60. package/dist-client/components/saas-bill-editor.js +0 -211
  61. package/dist-client/components/saas-bill-editor.js.map +0 -1
  62. package/dist-client/components/saas-candidates.d.ts +0 -33
  63. package/dist-client/components/saas-candidates.js +0 -157
  64. package/dist-client/components/saas-candidates.js.map +0 -1
  65. package/dist-client/pages/saas-cost-trend.d.ts +0 -23
  66. package/dist-client/pages/saas-cost-trend.js +0 -219
  67. package/dist-client/pages/saas-cost-trend.js.map +0 -1
  68. package/dist-server/service/saas-bill.d.ts +0 -42
  69. package/dist-server/service/saas-bill.js +0 -165
  70. package/dist-server/service/saas-bill.js.map +0 -1
  71. package/dist-server/service/saas-hidden-vendor.d.ts +0 -19
  72. package/dist-server/service/saas-hidden-vendor.js +0 -53
  73. package/dist-server/service/saas-hidden-vendor.js.map +0 -1
  74. package/dist-server/service/saas-trend-type.d.ts +0 -9
  75. package/dist-server/service/saas-trend-type.js +0 -37
  76. package/dist-server/service/saas-trend-type.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"saas-service.js","sourceRoot":"","sources":["../../server/service/saas-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BankAccount, CashFlowType, linkLinesByName, RecurringCashItem, Transaction, TransactionCategory } from '@things-factory/accounting'\nimport { Asset } from '@things-factory/asset'\n/* The register grids' save, the asset module's - this module saves its grids the same way (one implementation). */\nimport { amountOf, applyPatches, dayOf, Patch, textOf, touched } from '@things-factory/asset/dist-server/service/patches.js'\nimport { Counterparty, CounterpartyKind, looksLikePersonName, nameKey, partyNamed, saveCounterparties } from '@things-factory/biz-base'\nimport { fieldChanges, readFactChanges, recordFactChanges } from '@things-factory/fact-change'\nimport { Department, Employee } from '@things-factory/organization'\nimport { Domain, Refusal } from '@things-factory/shell'\nimport { EntityManager, In } from 'typeorm'\n\nimport { accountIn, SaasScope } from './saas-access'\nimport { SaasAccount } from './saas-account'\nimport { SaasBill, SaasBillLine } from './saas-bill'\nimport { SaasHiddenVendor } from './saas-hidden-vendor'\nimport {\n alertsOf,\n BillFacts,\n billTotal,\n candidatesOf,\n expectedOfMonth,\n MONTH,\n monthsFrom,\n SaasAccountStatus,\n SaasBilling,\n CandidateFacts,\n SaasSubscriptionStatus,\n seatHeld,\n shiftMonth,\n trendOf\n} from './saas-rules'\nimport { SaasSeat } from './saas-seat'\nimport { SaasSubscription } from './saas-subscription'\nimport { SaasTrend } from './saas-trend-type'\n\nconst currencyOf = (value: any, fallback: string | null) => {\n const text = String(value ?? '').trim().toUpperCase()\n if (!text) return fallback\n if (!/^[A-Z]{3}$/.test(text)) throw new Refusal('saas-currency-invalid', { value: text }, `'${text}' is not a currency code (KRW, USD)`)\n return text\n}\n\nconst intOf = (value: any, code: string, min: number, max: number): number | null => {\n if (value === null || value === undefined || value === '') return null\n const number = Number(value)\n if (!Number.isInteger(number) || number < min || number > max) throw new Refusal(code, { min, max }, `Give a whole number from ${min} to ${max}`)\n return number\n}\n\nasync function oneOf<T>(tx: EntityManager, target: any, domain: Domain, id: string | null | undefined, code: string): Promise<T | null> {\n if (!id) return null\n const found = await tx.getRepository(target).findOne({ where: { domain: { id: domain.id }, id } as any })\n if (!found) throw new Refusal(code, {}, 'What it points at was not found')\n return found as T\n}\n\nconst field = (patch: Patch, name: string, old?: any) => (patch[name] !== undefined ? patch[name] : old?.[name])\n\n/*\n * What moved on an account or a subscription, field by field (ADR-0177 decision 11) - the fact-change module keeps it.\n * A row's relations are told by their id; a new row has no history yet.\n */\nexport const SAAS_ACCOUNT_FACT = 'saas-account'\nexport const SAAS_SUBSCRIPTION_FACT = 'saas-subscription'\nconst ACCOUNT_TRACKED = ['name', 'counterpartyId', 'identifier', 'parentId', 'paymentAccountId', 'currency', 'billingDay', 'increaseAlertRate', 'status', 'closedOn'] as const\nconst SUBSCRIPTION_TRACKED = ['name', 'billing', 'vendorKey', 'trial', 'quantity', 'unitPrice', 'amount', 'budget', 'everyMonths', 'startOn', 'renewalOn', 'autoRenew', 'noticeDays', 'departmentId', 'assetId', 'status', 'endedOn'] as const\nconst idsOf = (row: Record<string, any>) =>\n Object.fromEntries(Object.entries(row).map(([key, value]) => (value && typeof value === 'object' && 'id' in value ? [`${key}Id`, value.id] : value === null && ['counterparty', 'parent', 'paymentAccount', 'department', 'asset'].includes(key) ? [`${key}Id`, null] : [key, value])))\n\nasync function recordChanges(tx: EntityManager, domain: Domain, user: any, factKind: string, old: any, row: Record<string, any>, fields: readonly string[]) {\n if (!old) return\n const after = { ...old, ...idsOf(row) }\n await recordFactChanges(tx, domain, { factKind, factName: old.id, changes: fieldChanges(old, after, fields as any) }, { user, source: 'saas' })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Accounts (decision 2) - kept by `saas` keepers only */\n\nexport async function saveSaasAccounts(tx: EntityManager, domain: Domain, user: any, patches: Patch[]) {\n const saved = await applyPatches(\n tx,\n SaasAccount,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = {}\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-account-name-required', {}, 'Name the service')\n row.name = name\n for (const one of ['identifier', 'purpose', 'billingEmail', 'secretLocation', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (touched(patch, 'currency', old)) row.currency = currencyOf(patch.currency, 'KRW')\n if (touched(patch, 'billingDay', old)) row.billingDay = intOf(patch.billingDay, 'saas-billing-day-invalid', 1, 31)\n if (touched(patch, 'increaseAlertRate', old)) {\n const rate = amountOf(patch.increaseAlertRate, 'saas-alert-rate-invalid')\n if (rate !== null && rate > 10) throw new Refusal('saas-alert-rate-invalid', {}, 'Give the rate as a part - 0.2 for 20%')\n row.increaseAlertRate = rate\n }\n if (touched(patch, 'counterpartyId', old)) row.counterparty = await oneOf(tx, Counterparty, domain, patch.counterpartyId, 'saas-counterparty-not-found')\n if (touched(patch, 'paymentAccountId', old)) row.paymentAccount = await oneOf(tx, BankAccount, domain, patch.paymentAccountId, 'saas-payment-account-not-found')\n if (touched(patch, 'parentId', old)) {\n const parent = await oneOf<SaasAccount>(tx, SaasAccount, domain, patch.parentId, 'saas-parent-not-found')\n if (parent && (parent.id === old?.id || (await tx.getRepository(SaasAccount).findOne({ where: { id: parent.id }, relations: ['parent'] }))?.parent))\n throw new Refusal('saas-parent-invalid', {}, 'An account is under a top account only, and not under itself')\n if (parent && old && (await tx.getRepository(SaasSubscription).count({ where: { account: { id: old.id } } as any })))\n throw new Refusal('saas-parent-has-subscriptions', {}, 'An account with subscriptions is billed itself - it cannot go under another')\n row.parent = parent\n }\n if (touched(patch, 'adminIds', old)) {\n const ids: string[] = [...new Set<string>((patch.adminIds ?? []).filter(Boolean))]\n const admins = ids.length ? await tx.getRepository(Employee).find({ where: { id: In(ids), domain: { id: domain.id } } as any }) : []\n if (admins.length !== ids.length) throw new Refusal('saas-admin-not-found', {}, 'An admin is no employee of this domain')\n row.admins = admins\n }\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasAccountStatus.ACTIVE\n if (touched(patch, 'closedOn', old)) row.closedOn = dayOf(patch.closedOn, 'saas-day-invalid')\n if ((row.status ?? old?.status) === SaasAccountStatus.CLOSED && !(row.closedOn !== undefined ? row.closedOn : old?.closedOn))\n throw new Refusal('saas-closed-on-required', {}, 'Give the day it was closed')\n await recordChanges(tx, domain, user, SAAS_ACCOUNT_FACT, old, row, ACCOUNT_TRACKED)\n return row\n },\n 'saas-account-not-found'\n )\n /* The vendor's lines written with its name and not linked yet are the account's months (개정 1). */\n const vendors = patches.filter(one => one.cuFlag !== '-' && one.counterpartyId).map(one => one.counterpartyId as string)\n if (vendors.length) await linkLinesByName(tx, domain, user, vendors)\n return saved\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Subscriptions (decision 3) - by keepers, and by the account's admins */\n\nexport async function saveSaasSubscriptions(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, accountId: string, patches: Patch[]) {\n const account = await accountIn(tx, domain, scope, accountId)\n if (account.parentId && patches.some(one => one.cuFlag !== '-'))\n throw new Refusal('saas-subscription-on-sub-account', {}, 'An account under another is billed by its parent - subscribe there')\n return applyPatches(\n tx,\n SaasSubscription,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { account }\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-subscription-name-required', {}, 'Name the product or plan')\n row.name = name\n const billing = (field(patch, 'billing', old) ?? SaasBilling.FIXED) as SaasBilling\n if (!Object.values(SaasBilling).includes(billing)) throw new Refusal('saas-billing-invalid', {}, 'Say how it is paid for')\n row.billing = billing\n for (const one of ['quantity', 'unitPrice', 'amount', 'budget']) if (touched(patch, one, old)) row[one] = amountOf(patch[one], 'saas-amount-invalid')\n /* `vendorKey` and `trial` are a sync's (개정 2) - the GraphQL patch does not carry them. */\n if (touched(patch, 'vendorKey', old)) row.vendorKey = textOf(patch.vendorKey)\n if (touched(patch, 'trial', old)) row.trial = patch.trial === true\n const value = (name: string) => (row[name] !== undefined ? row[name] : old?.[name])\n /* A plan read from the vendor's tenant may wait for its price (개정 2) - it is expected at nothing until then. */\n const priced = value('unitPrice') !== null && value('unitPrice') !== undefined\n if (billing === SaasBilling.SEAT && !(Number(value('quantity')) > 0 && (priced || value('vendorKey'))))\n throw new Refusal('saas-seat-price-required', {}, 'A seat plan takes its seats and the price of one')\n if ((billing === SaasBilling.FIXED || billing === SaasBilling.COMMITMENT) && (value('amount') === null || value('amount') === undefined))\n throw new Refusal('saas-amount-required', {}, 'Give what one billing costs')\n if (touched(patch, 'everyMonths', old)) row.everyMonths = intOf(patch.everyMonths, 'saas-every-months-invalid', 1, 120) ?? 1\n row.startOn = touched(patch, 'startOn', old) ? dayOf(patch.startOn, 'saas-start-on-invalid', true) : old!.startOn\n if (touched(patch, 'renewalOn', old)) row.renewalOn = dayOf(patch.renewalOn, 'saas-day-invalid')\n if (touched(patch, 'endedOn', old)) row.endedOn = dayOf(patch.endedOn, 'saas-day-invalid')\n if (touched(patch, 'autoRenew', old)) row.autoRenew = patch.autoRenew !== false\n if (touched(patch, 'noticeDays', old)) row.noticeDays = intOf(patch.noticeDays, 'saas-notice-days-invalid', 0, 365)\n if (touched(patch, 'description', old)) row.description = textOf(patch.description)\n if (touched(patch, 'departmentId', old)) row.department = await oneOf(tx, Department, domain, patch.departmentId, 'saas-department-not-found')\n if (touched(patch, 'assetId', old)) row.asset = await oneOf(tx, Asset, domain, patch.assetId, 'saas-asset-not-found')\n if (billing === SaasBilling.OWNED && !(row.asset !== undefined ? row.asset : old?.assetId))\n throw new Refusal('saas-owned-asset-required', {}, 'A license owned points at its asset in the register - its cost is there')\n if (billing === SaasBilling.COMMITMENT && !value('renewalOn')) throw new Refusal('saas-term-end-required', {}, 'A commitment takes the day its term ends')\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasSubscriptionStatus.ACTIVE\n const status = row.status ?? old?.status ?? SaasSubscriptionStatus.ACTIVE\n if (status === SaasSubscriptionStatus.CANCELLED && !value('endedOn')) throw new Refusal('saas-ended-on-required', {}, 'Give the day it ended')\n if (status === SaasSubscriptionStatus.CANCELLING && !value('renewalOn')) throw new Refusal('saas-renewal-on-required', {}, 'Not renewing needs the day it would renew')\n if (value('endedOn') && value('endedOn') < row.startOn) throw new Refusal('saas-ended-before-start', {}, 'It ended before it started')\n await recordChanges(tx, domain, user, SAAS_SUBSCRIPTION_FACT, old, row, SUBSCRIPTION_TRACKED)\n return row\n },\n 'saas-subscription-not-found',\n { account: { id: account.id } }\n )\n}\n\n/** The subscriptions of an account, with the seats held today. */\nexport async function saasSubscriptionsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string, today: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, relations: ['department', 'asset'], order: { name: 'ASC' } as any })\n const seats = subs.length ? await tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: In(subs.map(one => one.id)) } } as any }) : []\n for (const sub of subs) sub.seatsHeld = seats.filter(seat => seat.subscriptionId === sub.id && seatHeld(seat, today)).length\n return subs\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Seats (decision 6) */\n\nasync function subscriptionIn(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = subscriptionId ? await tx.getRepository(SaasSubscription).findOne({ where: { domain: { id: domain.id }, id: subscriptionId } as any }) : null\n if (!sub || (scope !== 'all' && !scope.has(sub.accountId!))) throw new Refusal('saas-subscription-not-found', {}, 'The subscription was not found - reload and try again')\n return sub\n}\n\nexport async function saveSaasSeats(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, subscriptionId: string, patches: Patch[]) {\n const subscription = await subscriptionIn(tx, domain, scope, subscriptionId)\n return applyPatches(\n tx,\n SaasSeat,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { subscription }\n if (touched(patch, 'employeeId', old)) row.employee = await oneOf(tx, Employee, domain, patch.employeeId, 'saas-seat-employee-not-found')\n /* `login` is a sync's (개정 2) - the GraphQL patch does not carry it. */\n for (const one of ['holder', 'login', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (!(row.employee !== undefined ? row.employee : old?.employeeId) && !(row.holder !== undefined ? row.holder : old?.holder))\n throw new Refusal('saas-seat-holder-required', {}, 'Say who holds the seat - an employee, or a name')\n if (touched(patch, 'fromOn', old)) row.fromOn = dayOf(patch.fromOn, 'saas-day-invalid')\n if (touched(patch, 'untilOn', old)) row.untilOn = dayOf(patch.untilOn, 'saas-day-invalid')\n const from = row.fromOn !== undefined ? row.fromOn : old?.fromOn\n const until = row.untilOn !== undefined ? row.untilOn : old?.untilOn\n if (from && until && until < from) throw new Refusal('saas-seat-until-before-from', {}, 'It was taken back before it was given')\n return row\n },\n 'saas-seat-not-found',\n { subscription: { id: subscription.id } }\n )\n}\n\nexport async function saasSeatsOf(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = await subscriptionIn(tx, domain, scope, subscriptionId)\n return tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: sub.id } } as any, relations: ['employee'], order: { fromOn: 'DESC' } as any })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Bills (decisions 5, 9) - one an account a month, its lines replaced whole */\n\nexport interface SaasBillFields {\n id?: string | null\n month: string\n billedOn?: string | null\n description?: string | null\n lines: { subscriptionId?: string | null; label?: string | null; amount: number }[]\n}\n\nexport async function saveSaasBill(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, accountId: string, input: SaasBillFields) {\n const account = await accountIn(tx, domain, scope, accountId)\n if (account.parentId) throw new Refusal('saas-bill-on-sub-account', {}, 'An account under another is billed by its parent')\n const month = String(input.month ?? '').trim()\n if (!MONTH.test(month)) throw new Refusal('saas-month-invalid', { value: month }, 'Write the month as YYYY-MM')\n const bills = tx.getRepository(SaasBill)\n const old = input.id ? await bills.findOne({ where: { domain: { id: domain.id }, id: input.id, account: { id: account.id } } as any }) : null\n if (input.id && !old) throw new Refusal('saas-bill-not-found', {}, 'The bill was not found - reload and try again')\n const twin = await bills.findOne({ where: { domain: { id: domain.id }, account: { id: account.id }, month } as any })\n if (twin && twin.id !== old?.id) throw new Refusal('saas-bill-month-taken', { month }, `The account already has a bill for ${month} - change that one`)\n const lines = (input.lines ?? []).filter(line => line && (line.subscriptionId || textOf(line.label) || Number(line.amount)))\n if (!lines.length) throw new Refusal('saas-bill-lines-required', {}, 'A bill takes at least one line')\n const subIds = [...new Set(lines.map(line => line.subscriptionId).filter(Boolean))] as string[]\n if (subIds.length) {\n const found = await tx.getRepository(SaasSubscription).count({ where: { domain: { id: domain.id }, account: { id: account.id }, id: In(subIds) } as any })\n if (found !== subIds.length) throw new Refusal('saas-bill-subscription-not-found', {}, 'A line names a subscription not of this account')\n }\n for (const line of lines) if (!Number.isFinite(Number(line.amount))) throw new Refusal('saas-amount-invalid', {}, 'Give the amount as a number')\n const bill = await bills.save({\n ...(old ?? { domain, account, creator: user, currency: account.currency }),\n month,\n billedOn: dayOf(input.billedOn, 'saas-day-invalid'),\n description: textOf(input.description),\n /* Whoever writes it owns it: a person's save keeps a later sync off it (a sync marks its own, 개정 3). */\n synced: false,\n updater: user\n } as any)\n await tx.getRepository(SaasBillLine).delete({ bill: { id: bill.id } } as any)\n await tx.getRepository(SaasBillLine).save(\n lines.map(line => ({ domain, bill: { id: bill.id }, subscription: line.subscriptionId ? { id: line.subscriptionId } : null, label: textOf(line.label), amount: Number(line.amount) })) as any\n )\n return billsOf(tx, domain, [account.id]).then(all => all.find(one => one.id === bill.id)!)\n}\n\nexport async function deleteSaasBill(tx: EntityManager, domain: Domain, scope: SaasScope, id: string): Promise<boolean> {\n const bill = await tx.getRepository(SaasBill).findOne({ where: { domain: { id: domain.id }, id } as any })\n if (!bill || (scope !== 'all' && !scope.has(bill.accountId!))) throw new Refusal('saas-bill-not-found', {}, 'The bill was not found - reload and try again')\n await tx.getRepository(SaasBill).softDelete({ id })\n return true\n}\n\n/** The bills of some accounts (all when none named) from a month on, with their lines and totals, latest first. */\nexport async function billsOf(tx: EntityManager, domain: Domain, accountIds?: string[], from?: string, to?: string): Promise<SaasBill[]> {\n const query = tx\n .getRepository(SaasBill)\n .createQueryBuilder('bill')\n .leftJoinAndSelect('bill.lines', 'line')\n .leftJoinAndSelect('line.subscription', 'subscription')\n .where('bill.domain = :domain', { domain: domain.id })\n if (accountIds) {\n if (!accountIds.length) return []\n query.andWhere('bill.account IN (:...accounts)', { accounts: accountIds })\n }\n if (from) query.andWhere('bill.month >= :from', { from })\n if (to) query.andWhere('bill.month <= :to', { to })\n const bills = await query.orderBy('bill.month', 'DESC').getMany()\n for (const bill of bills) bill.total = billTotal(bill.lines ?? [])\n return bills\n}\n\nexport async function saasBillsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n return billsOf(tx, domain, [account.id])\n}\n\nconst factsOf = (bill: SaasBill): BillFacts => ({\n accountId: bill.accountId!,\n month: bill.month,\n currency: bill.currency,\n lines: (bill.lines ?? []).map(line => ({ subscriptionId: line.subscriptionId ?? null, amount: Number(line.amount) }))\n})\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* What is still to come (decision 4) - read by an application's expected cash */\n\nexport interface SaasExpectedRow {\n accountId: string\n accountName: string\n counterpartyId?: string | null\n paymentAccountId?: string | null\n month: string\n day: string | null\n amount: number\n currency: string\n /** A bill is written for the month: the amount is the bill's, not an estimate. */\n billed: boolean\n}\n\n/**\n * What each account is expected to be billed, month by month from `from` to `to`: the bill when one is written for the\n * month, else what its subscriptions say (usage at the average of its latest bills).\n */\nexport async function saasExpected(tx: EntityManager, domain: Domain, from: string, to: string): Promise<SaasExpectedRow[]> {\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id }, status: SaasAccountStatus.ACTIVE } as any })\n const top = accounts.filter(one => !one.parentId)\n if (!top.length) return []\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: In(top.map(one => one.id)) } } as any })\n const bills = await billsOf(tx, domain, top.map(one => one.id), shiftMonth(from, -12), to)\n const billed = new Map<string, { month: string; amount: number }[]>()\n for (const bill of bills)\n if (bill.month < from)\n for (const line of bill.lines ?? []) if (line.subscriptionId) billed.set(line.subscriptionId, [...(billed.get(line.subscriptionId) ?? []), { month: bill.month, amount: Number(line.amount) }])\n const rows: SaasExpectedRow[] = []\n for (const account of top) {\n const own = subs.filter(one => one.accountId === account.id)\n for (const month of monthsFrom(from, to)) {\n const [year, m] = month.split('-').map(Number)\n const bill = bills.find(one => one.accountId === account.id && one.month === month)\n const expected = expectedOfMonth(account, own, billed, year, m)\n if (!bill && !expected) continue\n rows.push({\n accountId: account.id,\n accountName: account.name,\n counterpartyId: account.counterpartyId ?? null,\n paymentAccountId: account.paymentAccountId ?? null,\n month,\n day: bill?.billedOn ?? expected?.day ?? null,\n amount: bill ? bill.total! : expected!.amount,\n currency: account.currency,\n billed: !!bill\n })\n }\n }\n return rows\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* The cost trend (decision 9) */\n\n/** Whose department each employee is in. */\nasync function departmentsOfEmployees(tx: EntityManager, domain: Domain, ids: string[]): Promise<Map<string, { id: string; name: string }>> {\n if (!ids.length) return new Map()\n const employees = await tx.getRepository(Employee).find({ where: { domain: { id: domain.id }, id: In(ids) } as any, relations: ['department'] })\n return new Map(employees.filter(one => one.department).map(one => [one.id, { id: one.department!.id, name: one.department!.name }]))\n}\n\n/**\n * The bills of the months from `from` to `to` as series - all, an account, a subscription - and a department series: a\n * line of a seat plan split by the seats held at the month's end by department, any other line its subscription's\n * department. Plus what the latest month's bills are worth telling.\n */\nexport async function saasCostTrend(tx: EntityManager, domain: Domain, from: string, to: string) {\n if (!MONTH.test(from) || !MONTH.test(to) || from > to) throw new Refusal('saas-month-invalid', {}, 'Give the months as YYYY-MM, the first before the last')\n if (monthsFrom(from, to).length > 60) throw new Refusal('saas-trend-too-long', { max: 60 }, 'Up to 60 months at once')\n const bills = await billsOf(tx, domain, undefined, shiftMonth(from, -1), to)\n const facts = bills.map(factsOf)\n const trend = trendOf(facts, from, to)\n\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id } } as any, withDeleted: true })\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id } } as any, relations: ['department'], withDeleted: true })\n const seats = subs.length ? await tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: In(subs.map(one => one.id)) } } as any }) : []\n const departmentOf = await departmentsOfEmployees(tx, domain, [...new Set(seats.map(one => one.employeeId).filter(Boolean))] as string[])\n\n const months = trend.months\n const departments = new Map<string, { key: string; departmentId: string | null; name: string | null; currency: string; amounts: number[] }>()\n const addTo = (id: string | null, name: string | null, currency: string, at: number, amount: number) => {\n const key = `${id ?? ''}|${currency}`\n let one = departments.get(key)\n if (!one) departments.set(key, (one = { key, departmentId: id, name, currency, amounts: months.map(() => 0) }))\n one.amounts[at] += amount\n }\n for (const bill of facts) {\n const at = months.indexOf(bill.month)\n if (at < 0) continue\n const monthEnd = `${bill.month}-31`\n for (const line of bill.lines) {\n const sub = subs.find(one => one.id === line.subscriptionId)\n const held = sub?.billing === SaasBilling.SEAT ? seats.filter(seat => seat.subscriptionId === sub.id && seatHeld(seat, monthEnd) && (!seat.fromOn || seat.fromOn <= monthEnd)) : []\n if (held.length) {\n for (const seat of held) {\n const department = seat.employeeId ? departmentOf.get(seat.employeeId) : undefined\n addTo(department?.id ?? sub?.department?.id ?? null, department?.name ?? sub?.department?.name ?? null, bill.currency, at, line.amount / held.length)\n }\n } else addTo(sub?.department?.id ?? null, sub?.department?.name ?? null, bill.currency, at, line.amount)\n }\n }\n\n const latest = facts.filter(one => one.month <= to).map(one => one.month).sort().pop()\n const alerts = latest\n ? facts\n .filter(one => one.month === latest)\n .flatMap(bill => {\n const account = accounts.find(one => one.id === bill.accountId)\n if (!account) return []\n const previous = facts.find(one => one.accountId === bill.accountId && one.month === shiftMonth(bill.month, -1))\n return alertsOf(account, subs.filter(one => one.accountId === account.id), bill, previous).map(alert => ({ ...alert, accountId: account.id, month: bill.month }))\n })\n : []\n\n const name = (id?: string | null) => accounts.find(one => one.id === id)?.name ?? null\n const subName = (id?: string | null) => subs.find(one => one.id === id)?.name ?? null\n return {\n months,\n all: trend.all,\n accounts: trend.accounts.map(one => ({ ...one, name: name(one.accountId) })),\n subscriptions: trend.subscriptions.map(one => ({ ...one, name: subName(one.subscriptionId), accountName: name(one.accountId) })),\n departments: [...departments.values()].map(one => ({ ...one, total: one.amounts.reduce((sum, amount) => sum + amount, 0) })).sort((a, b) => b.total - a.total),\n alerts: alerts.map(alert => ({ ...alert, accountName: name(alert.accountId), subscriptionName: subName(alert.subscriptionId) }))\n }\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* A row's months for the list and the 360 (decision 10) and what moved on it (decision 11) */\n\n/**\n * What went out to an account's vendor (ADR-0177 decision 10, the user 2026-10-30: 「이테크 입금 이력이 있을텐데」;\n * 개정 1) - the bank withdrawals and the card charges (accounting, CONFIRMED and CARD) to the account's counterparty,\n * newest first. A line takes its counterparty when it lands (accounting `saveTransactions`), so a vendor's lines are\n * its linked ones. Only lines in the account's currency count toward its months.\n */\nexport async function vendorLinesOf(tx: EntityManager, domain: Domain, counterpartyIds: string[], from?: string, to?: string): Promise<Transaction[]> {\n if (!counterpartyIds.length) return []\n const query = tx\n .getRepository(Transaction)\n .createQueryBuilder('line')\n .leftJoinAndSelect('line.bankAccount', 'bankAccount')\n .where('line.domain = :domain', { domain: domain.id })\n .andWhere('line.category IN (:...categories)', { categories: [TransactionCategory.CONFIRMED, TransactionCategory.CARD] })\n .andWhere('line.type = :type', { type: CashFlowType.EXPENSE })\n .andWhere('line.counterparty IN (:...parties)', { parties: counterpartyIds })\n if (from) query.andWhere('line.transactionDate >= :from', { from })\n if (to) query.andWhere('line.transactionDate <= :to', { to })\n return query.orderBy('line.transactionDate', 'DESC').addOrderBy('line.amount', 'DESC').getMany()\n}\n\n/** The bank and card lines that paid an account's vendor, every one - for its 360. */\nexport async function saasPaymentsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n return account.counterpartyId ? vendorLinesOf(tx, domain, [account.counterpartyId]) : []\n}\n\n/**\n * Each account's last twelve months before this one and the next three expected (`saasExpected`). A month is its bill\n * when one is written; else, for a reader of the bank lines (`withBank`), what went out to its vendor that month from\n * the bank or a card (decision 10, 개정 1); else empty. One read for all the accounts of a list.\n */\nexport async function saasTrendsOf(tx: EntityManager, domain: Domain, accounts: SaasAccount[], today: string, withBank = false): Promise<Map<string, SaasTrend>> {\n const trends = new Map<string, SaasTrend>()\n if (!accounts.length) return trends\n const now = today.slice(0, 7)\n const months = monthsFrom(shiftMonth(now, -12), shiftMonth(now, -1))\n const nextMonths = monthsFrom(now, shiftMonth(now, 2))\n const bills = await billsOf(tx, domain, accounts.map(one => one.id), months[0], months[months.length - 1])\n const expected = await saasExpected(tx, domain, nextMonths[0], nextMonths[nextMonths.length - 1])\n const parties = [...new Set(accounts.map(one => one.counterpartyId).filter(Boolean))] as string[]\n const paid = withBank ? await vendorLinesOf(tx, domain, parties, `${months[0]}-01`, `${months[months.length - 1]}-31`) : []\n for (const account of accounts) {\n const own = bills.filter(one => one.accountId === account.id)\n const lines = paid.filter(line => line.counterpartyId === account.counterpartyId && (line.currency || 'KRW') === account.currency)\n const banked = (month: string) => {\n const of = lines.filter(line => line.transactionDate?.slice(0, 7) === month)\n return of.length ? of.reduce((sum, line) => sum + Number(line.amount), 0) : null\n }\n const values = months.map(month => own.find(one => one.month === month)?.total ?? banked(month))\n trends.set(account.id, {\n months,\n values,\n sources: months.map((month, i) =>\n own.some(one => one.month === month)\n ? 'bill'\n : values[i] === null\n ? null\n : lines.some(line => line.transactionDate?.slice(0, 7) === month && line.category === TransactionCategory.CONFIRMED)\n ? 'bank'\n : 'card'\n ),\n nextMonths,\n expected: nextMonths.map(month => expected.find(one => one.accountId === account.id && one.month === month)?.amount ?? null),\n currency: account.currency\n })\n }\n return trends\n}\n\n/** What moved on an account and on each of its subscriptions, newest first. */\nexport async function saasChangesOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, withDeleted: true })\n const rows = [\n ...(await readFactChanges(tx, domain, SAAS_ACCOUNT_FACT, account.id)).map(one => Object.assign(one, { subject: account.name })),\n ...(await Promise.all(subs.map(async sub => (await readFactChanges(tx, domain, SAAS_SUBSCRIPTION_FACT, sub.id)).map(one => Object.assign(one, { subject: sub.name }))))).flat()\n ]\n return rows.sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime())\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* What the books already say is subscribed to (개정 1) */\n\n/** A candidate with its vendor's name, for the list. */\nexport type SaasCandidateRow = CandidateFacts & { counterpartyName: string; hidden: boolean }\n\n\n/**\n * Whom the bank and card lines of the last twelve months show paid month after month that is no account yet and no\n * recurring item - what a keeper may make an account of with one press. A line on a subject outside profit and loss\n * (a card bill, a tax, a transfer, a loan) pays no vendor, and a person (salary, expenses) is no vendor. With `hidden`,\n * the ones a keeper hid instead.\n */\nexport async function saasCandidatesOf(tx: EntityManager, domain: Domain, today: string, hidden = false): Promise<SaasCandidateRow[]> {\n const now = today.slice(0, 7)\n const from = `${shiftMonth(now, -12)}-01`\n const lines = await tx\n .getRepository(Transaction)\n .createQueryBuilder('line')\n .leftJoinAndSelect('line.account', 'subject')\n .where('line.domain = :domain', { domain: domain.id })\n .andWhere('line.category IN (:...categories)', { categories: [TransactionCategory.CONFIRMED, TransactionCategory.CARD] })\n .andWhere('line.type = :type', { type: CashFlowType.EXPENSE })\n .andWhere('line.transactionDate >= :from', { from })\n .getMany()\n const accounts = await tx.getRepository(SaasAccount).find({ where: { domain: { id: domain.id } } as any })\n const recurring = await tx.getRepository(RecurringCashItem).find({ where: { domain: { id: domain.id } } as any })\n const hiddenKeys = new Set((await tx.getRepository(SaasHiddenVendor).find({ where: { domain: { id: domain.id } } as any })).map(one => one.counterpartyId ?? `name:${one.nameKey}`))\n const skip = new Set([...accounts.map(one => one.counterpartyId), ...recurring.map(one => one.counterpartyId), ...(hidden ? [] : hiddenKeys)].filter(Boolean) as string[])\n const parties = await tx.getRepository(Counterparty).find({ where: { domain: { id: domain.id } } as any, select: ['id', 'name', 'aliases', 'kind'] })\n const named = partyNamed(parties)\n const people = new Set(parties.filter(one => one.kind === CounterpartyKind.PERSON).map(one => one.id))\n /* Whom a line paid: its counterparty, else the one its written name is (the rule a line is linked by), else the name. */\n const vendorOf = (line: Transaction) => {\n const id = line.counterpartyId ?? named(line.counterpartyName)?.id\n if (id) return people.has(id) ? null : { key: id, counterpartyId: id }\n const key = nameKey(line.counterpartyName)\n return key && !looksLikePersonName(line.counterpartyName!) ? { key: `name:${key}`, counterpartyId: null } : null\n }\n const found = candidatesOf(\n lines\n .filter(line => line.account?.profitAndLoss !== false)\n .flatMap(line => {\n const vendor = vendorOf(line)\n return vendor ? [{ ...vendor, name: line.counterpartyName, transactionDate: line.transactionDate!, amount: Number(line.amount), currency: line.currency, bankAccountId: line.bankAccountId }] : []\n }),\n skip\n ).filter(one => hiddenKeys.has(one.key) === hidden)\n return found.map(one => ({ ...one, counterpartyName: parties.find(party => party.id === one.counterpartyId)?.name ?? one.name ?? '', hidden }))\n}\n\n/**\n * Make an account of each candidate - named after the vendor, paid from where it was paid most, on the day it was paid\n * most - with one usage subscription budgeted at the monthly average, so the months to come are expected at it until\n * bills say otherwise. A vendor the lines only name is registered as a counterparty first; the lines written with its\n * name are linked to it (accounting `linkLinesByName`). One that is no candidate any more is refused.\n */\nexport async function createSaasAccountsFromCandidates(tx: EntityManager, domain: Domain, user: any, keys: string[], today: string): Promise<SaasAccount[]> {\n const candidates = await saasCandidatesOf(tx, domain, today)\n const made: SaasAccount[] = []\n for (const key of [...new Set(keys)]) {\n const one = candidates.find(candidate => candidate.key === key)\n if (!one) throw new Refusal('saas-candidate-not-found', {}, 'It is no candidate any more - reload and try again')\n const counterpartyId = one.counterpartyId ?? (await saveCounterparties(tx, domain, user, [{ cuFlag: '+', name: one.counterpartyName, kind: CounterpartyKind.COMPANY }]))[0].id\n /* Its lines written with its name and not linked yet are its months. */\n await linkLinesByName(tx, domain, user, [counterpartyId])\n const [account] = await saveSaasAccounts(tx, domain, user, [\n { cuFlag: '+', name: one.counterpartyName, counterpartyId, paymentAccountId: one.paymentAccountId, currency: one.currency, billingDay: one.billingDay, status: SaasAccountStatus.ACTIVE }\n ])\n await saveSaasSubscriptions(tx, domain, user, 'all', account.id, [\n { cuFlag: '+', name: one.counterpartyName, billing: SaasBilling.USAGE, budget: one.average, startOn: one.firstDate, status: SaasSubscriptionStatus.ACTIVE }\n ])\n made.push(account)\n }\n return made\n}\n\n/** Hide candidates - by their keys - or show them again. */\nexport async function hideSaasCandidates(tx: EntityManager, domain: Domain, user: any, keys: string[], hide: boolean): Promise<boolean> {\n const repo = tx.getRepository(SaasHiddenVendor)\n const wanted = [...new Set(keys)].filter(Boolean)\n const names = wanted.filter(key => key.startsWith('name:')).map(key => key.slice(5))\n const ids = wanted.filter(key => !key.startsWith('name:'))\n const parties = ids.length ? await tx.getRepository(Counterparty).find({ where: { domain: { id: domain.id }, id: In(ids) } as any }) : []\n if (parties.length !== ids.length) throw new Refusal('saas-counterparty-not-found', {}, 'The vendor was not found - reload and try again')\n const rows = await repo.find({ where: { domain: { id: domain.id } } as any })\n const held = (row: SaasHiddenVendor) => (row.counterpartyId ? ids.includes(row.counterpartyId) : names.includes(row.nameKey!))\n if (!hide) {\n const gone = rows.filter(held)\n if (gone.length) await repo.remove(gone)\n return true\n }\n for (const party of parties) if (!rows.some(row => row.counterpartyId === party.id)) await repo.save({ domain, counterparty: party, creator: user })\n for (const key of names) if (!rows.some(row => !row.counterpartyId && row.nameKey === key)) await repo.save({ domain, nameKey: key, creator: user })\n return true\n}\n"]}
1
+ {"version":3,"file":"saas-service.js","sourceRoot":"","sources":["../../server/service/saas-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BankAccount } from '@things-factory/accounting'\n/* The register grids' save, the asset module's - this module saves its grids the same way (one implementation). */\nimport { amountOf, applyPatches, Asset, dayOf, Patch, textOf, touched } from '@things-factory/asset'\nimport { Counterparty } from '@things-factory/biz-base'\nimport { fieldChanges, readFactChanges, recordFactChanges } from '@things-factory/fact-change'\nimport { Department, Employee } from '@things-factory/organization'\nimport { Domain, Refusal } from '@things-factory/shell'\nimport { EntityManager, In } from 'typeorm'\n\nimport { accountIn, SaasScope } from './saas-access'\nimport { SaasAccount } from './saas-account'\nimport { referenceAmountOf, SaasAccountStatus, SaasBilling, SaasSubscriptionStatus, seatHeld } from './saas-rules'\nimport { SaasSeat } from './saas-seat'\nimport { SaasSubscription } from './saas-subscription'\n\nconst currencyOf = (value: any, fallback: string | null) => {\n const text = String(value ?? '').trim().toUpperCase()\n if (!text) return fallback\n if (!/^[A-Z]{3}$/.test(text)) throw new Refusal('saas-currency-invalid', { value: text }, `'${text}' is not a currency code (KRW, USD)`)\n return text\n}\n\nconst intOf = (value: any, code: string, min: number, max: number): number | null => {\n if (value === null || value === undefined || value === '') return null\n const number = Number(value)\n if (!Number.isInteger(number) || number < min || number > max) throw new Refusal(code, { min, max }, `Give a whole number from ${min} to ${max}`)\n return number\n}\n\nasync function oneOf<T>(tx: EntityManager, target: any, domain: Domain, id: string | null | undefined, code: string): Promise<T | null> {\n if (!id) return null\n const found = await tx.getRepository(target).findOne({ where: { domain: { id: domain.id }, id } as any })\n if (!found) throw new Refusal(code, {}, 'What it points at was not found')\n return found as T\n}\n\nconst field = (patch: Patch, name: string, old?: any) => (patch[name] !== undefined ? patch[name] : old?.[name])\n\n/*\n * What moved on an account or a subscription, field by field (ADR-0177 decision 11) - the fact-change module keeps it.\n * A row's relations are told by their id; a new row has no history yet.\n */\nexport const SAAS_ACCOUNT_FACT = 'saas-account'\nexport const SAAS_SUBSCRIPTION_FACT = 'saas-subscription'\nconst ACCOUNT_TRACKED = ['name', 'counterpartyId', 'identifier', 'parentId', 'paymentAccountId', 'currency', 'status', 'closedOn'] as const\nconst SUBSCRIPTION_TRACKED = ['name', 'billing', 'vendorKey', 'trial', 'quantity', 'unitPrice', 'startOn', 'renewalOn', 'autoRenew', 'noticeDays', 'departmentId', 'assetId', 'status', 'endedOn'] as const\nconst idsOf = (row: Record<string, any>) =>\n Object.fromEntries(Object.entries(row).map(([key, value]) => (value && typeof value === 'object' && 'id' in value ? [`${key}Id`, value.id] : value === null && ['counterparty', 'parent', 'paymentAccount', 'department', 'asset'].includes(key) ? [`${key}Id`, null] : [key, value])))\n\nasync function recordChanges(tx: EntityManager, domain: Domain, user: any, factKind: string, old: any, row: Record<string, any>, fields: readonly string[]) {\n if (!old) return\n const after = { ...old, ...idsOf(row) }\n await recordFactChanges(tx, domain, { factKind, factName: old.id, changes: fieldChanges(old, after, fields as any) }, { user, source: 'saas' })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Accounts (decision 2) - kept by `saas` keepers only */\n\nexport async function saveSaasAccounts(tx: EntityManager, domain: Domain, user: any, patches: Patch[]) {\n const saved = await applyPatches(\n tx,\n SaasAccount,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = {}\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-account-name-required', {}, 'Name the service')\n row.name = name\n for (const one of ['identifier', 'purpose', 'billingEmail', 'secretLocation', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (touched(patch, 'currency', old)) row.currency = currencyOf(patch.currency, 'KRW')\n if (touched(patch, 'counterpartyId', old)) row.counterparty = await oneOf(tx, Counterparty, domain, patch.counterpartyId, 'saas-counterparty-not-found')\n if (touched(patch, 'paymentAccountId', old)) row.paymentAccount = await oneOf(tx, BankAccount, domain, patch.paymentAccountId, 'saas-payment-account-not-found')\n if (touched(patch, 'parentId', old)) {\n const parent = await oneOf<SaasAccount>(tx, SaasAccount, domain, patch.parentId, 'saas-parent-not-found')\n if (parent && (parent.id === old?.id || (await tx.getRepository(SaasAccount).findOne({ where: { id: parent.id }, relations: ['parent'] }))?.parent))\n throw new Refusal('saas-parent-invalid', {}, 'An account is under a top account only, and not under itself')\n if (parent && old && (await tx.getRepository(SaasSubscription).count({ where: { account: { id: old.id } } as any })))\n throw new Refusal('saas-parent-has-subscriptions', {}, 'An account with subscriptions is billed itself - it cannot go under another')\n row.parent = parent\n }\n if (touched(patch, 'adminIds', old)) {\n const ids: string[] = [...new Set<string>((patch.adminIds ?? []).filter(Boolean))]\n const admins = ids.length ? await tx.getRepository(Employee).find({ where: { id: In(ids), domain: { id: domain.id } } as any }) : []\n if (admins.length !== ids.length) throw new Refusal('saas-admin-not-found', {}, 'An admin is no employee of this domain')\n row.admins = admins\n }\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasAccountStatus.ACTIVE\n if (touched(patch, 'closedOn', old)) row.closedOn = dayOf(patch.closedOn, 'saas-day-invalid')\n if ((row.status ?? old?.status) === SaasAccountStatus.CLOSED && !(row.closedOn !== undefined ? row.closedOn : old?.closedOn))\n throw new Refusal('saas-closed-on-required', {}, 'Give the day it was closed')\n await recordChanges(tx, domain, user, SAAS_ACCOUNT_FACT, old, row, ACCOUNT_TRACKED)\n return row\n },\n 'saas-account-not-found'\n )\n return saved\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Subscriptions (decision 3) - by keepers, and by the account's admins */\n\nexport async function saveSaasSubscriptions(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, accountId: string, patches: Patch[]) {\n const account = await accountIn(tx, domain, scope, accountId)\n if (account.parentId && patches.some(one => one.cuFlag !== '-'))\n throw new Refusal('saas-subscription-on-sub-account', {}, 'An account under another is billed by its parent - subscribe there')\n return applyPatches(\n tx,\n SaasSubscription,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { account }\n const name = touched(patch, 'name', old) ? textOf(patch.name) : old!.name\n if (!name) throw new Refusal('saas-subscription-name-required', {}, 'Name the product or plan')\n row.name = name\n const billing = (field(patch, 'billing', old) ?? SaasBilling.FIXED) as SaasBilling\n if (!Object.values(SaasBilling).includes(billing)) throw new Refusal('saas-billing-invalid', {}, 'Say how it is paid for')\n row.billing = billing\n /* Reference only - the money is the recurring item's (개정 7-3). */\n for (const one of ['quantity', 'unitPrice']) if (touched(patch, one, old)) row[one] = amountOf(patch[one], 'saas-amount-invalid')\n /* `vendorKey` and `trial` are a sync's (개정 2) - the GraphQL patch does not carry them. */\n if (touched(patch, 'vendorKey', old)) row.vendorKey = textOf(patch.vendorKey)\n if (touched(patch, 'trial', old)) row.trial = patch.trial === true\n const value = (name: string) => (row[name] !== undefined ? row[name] : old?.[name])\n row.startOn = touched(patch, 'startOn', old) ? dayOf(patch.startOn, 'saas-start-on-invalid', true) : old!.startOn\n if (touched(patch, 'renewalOn', old)) row.renewalOn = dayOf(patch.renewalOn, 'saas-day-invalid')\n if (touched(patch, 'endedOn', old)) row.endedOn = dayOf(patch.endedOn, 'saas-day-invalid')\n if (touched(patch, 'autoRenew', old)) row.autoRenew = patch.autoRenew !== false\n if (touched(patch, 'noticeDays', old)) row.noticeDays = intOf(patch.noticeDays, 'saas-notice-days-invalid', 0, 365)\n if (touched(patch, 'description', old)) row.description = textOf(patch.description)\n if (touched(patch, 'departmentId', old)) row.department = await oneOf(tx, Department, domain, patch.departmentId, 'saas-department-not-found')\n if (touched(patch, 'assetId', old)) row.asset = await oneOf(tx, Asset, domain, patch.assetId, 'saas-asset-not-found')\n if (billing === SaasBilling.OWNED && !(row.asset !== undefined ? row.asset : old?.assetId))\n throw new Refusal('saas-owned-asset-required', {}, 'A license owned points at its asset in the register')\n if (billing === SaasBilling.COMMITMENT && !value('renewalOn')) throw new Refusal('saas-term-end-required', {}, 'A commitment takes the day its term ends')\n if (touched(patch, 'status', old)) row.status = patch.status ?? SaasSubscriptionStatus.ACTIVE\n const status = row.status ?? old?.status ?? SaasSubscriptionStatus.ACTIVE\n if (status === SaasSubscriptionStatus.CANCELLED && !value('endedOn')) throw new Refusal('saas-ended-on-required', {}, 'Give the day it ended')\n if (status === SaasSubscriptionStatus.CANCELLING && !value('renewalOn')) throw new Refusal('saas-renewal-on-required', {}, 'Not renewing needs the day it would renew')\n if (value('endedOn') && value('endedOn') < row.startOn) throw new Refusal('saas-ended-before-start', {}, 'It ended before it started')\n await recordChanges(tx, domain, user, SAAS_SUBSCRIPTION_FACT, old, row, SUBSCRIPTION_TRACKED)\n return row\n },\n 'saas-subscription-not-found',\n { account: { id: account.id } }\n )\n}\n\n/** The subscriptions of an account, with the seats held today and the reference each makes. */\nexport async function saasSubscriptionsOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string, today: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, relations: ['department', 'asset'], order: { name: 'ASC' } as any })\n const seats = subs.length ? await tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: In(subs.map(one => one.id)) } } as any }) : []\n for (const sub of subs) {\n sub.seatsHeld = seats.filter(seat => seat.subscriptionId === sub.id && seatHeld(seat, today)).length\n sub.referenceAmount = referenceAmountOf(sub)\n }\n return subs\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* Seats (decision 6) */\n\nasync function subscriptionIn(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = subscriptionId ? await tx.getRepository(SaasSubscription).findOne({ where: { domain: { id: domain.id }, id: subscriptionId } as any }) : null\n if (!sub || (scope !== 'all' && !scope.has(sub.accountId!))) throw new Refusal('saas-subscription-not-found', {}, 'The subscription was not found - reload and try again')\n return sub\n}\n\nexport async function saveSaasSeats(tx: EntityManager, domain: Domain, user: any, scope: SaasScope, subscriptionId: string, patches: Patch[]) {\n const subscription = await subscriptionIn(tx, domain, scope, subscriptionId)\n return applyPatches(\n tx,\n SaasSeat,\n domain,\n user,\n patches,\n async (patch, old) => {\n const row: Record<string, any> = old ? {} : { subscription }\n if (touched(patch, 'employeeId', old)) row.employee = await oneOf(tx, Employee, domain, patch.employeeId, 'saas-seat-employee-not-found')\n /* `login` is a sync's (개정 2) - the GraphQL patch does not carry it. */\n for (const one of ['holder', 'login', 'description']) if (touched(patch, one, old)) row[one] = textOf(patch[one])\n if (!(row.employee !== undefined ? row.employee : old?.employeeId) && !(row.holder !== undefined ? row.holder : old?.holder))\n throw new Refusal('saas-seat-holder-required', {}, 'Say who holds the seat - an employee, or a name')\n if (touched(patch, 'fromOn', old)) row.fromOn = dayOf(patch.fromOn, 'saas-day-invalid')\n if (touched(patch, 'untilOn', old)) row.untilOn = dayOf(patch.untilOn, 'saas-day-invalid')\n const from = row.fromOn !== undefined ? row.fromOn : old?.fromOn\n const until = row.untilOn !== undefined ? row.untilOn : old?.untilOn\n if (from && until && until < from) throw new Refusal('saas-seat-until-before-from', {}, 'It was taken back before it was given')\n return row\n },\n 'saas-seat-not-found',\n { subscription: { id: subscription.id } }\n )\n}\n\nexport async function saasSeatsOf(tx: EntityManager, domain: Domain, scope: SaasScope, subscriptionId: string) {\n const sub = await subscriptionIn(tx, domain, scope, subscriptionId)\n return tx.getRepository(SaasSeat).find({ where: { domain: { id: domain.id }, subscription: { id: sub.id } } as any, relations: ['employee'], order: { fromOn: 'DESC' } as any })\n}\n\n/* ----------------------------------------------------------------------------------------------------------------- */\n/* What moved on a row (decision 11) */\n\n/** What moved on an account and on each of its subscriptions, newest first. */\nexport async function saasChangesOf(tx: EntityManager, domain: Domain, scope: SaasScope, accountId: string) {\n const account = await accountIn(tx, domain, scope, accountId)\n const subs = await tx.getRepository(SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } as any, withDeleted: true })\n const rows = [\n ...(await readFactChanges(tx, domain, SAAS_ACCOUNT_FACT, account.id)).map(one => Object.assign(one, { subject: account.name })),\n ...(await Promise.all(subs.map(async sub => (await readFactChanges(tx, domain, SAAS_SUBSCRIPTION_FACT, sub.id)).map(one => Object.assign(one, { subject: sub.name }))))).flat()\n ]\n return rows.sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime())\n}\n"]}
@@ -6,8 +6,9 @@ import { SaasAccount } from './saas-account';
6
6
  import { SaasBilling, SaasSubscriptionStatus } from './saas-rules';
7
7
  /**
8
8
  * One thing under an account the domain decides on and can cancel (ADR-0177 decisions 1, 3): a plan with seats, a fixed
9
- * fee, metered usage with a monthly budget, a commitment for a term, or a license owned - which points at the asset
10
- * register and carries no amount. It is billed in the account's currency, every so many months from the month it started.
9
+ * fee, metered usage, a commitment for a term, or a license owned - which points at the asset register. Its quantity and
10
+ * unit price are for reference only: the money is the recurring item's (accounting), which a person compares it with
11
+ * (개정 7).
11
12
  */
12
13
  export declare class SaasSubscription {
13
14
  readonly id: string;
@@ -21,9 +22,6 @@ export declare class SaasSubscription {
21
22
  trial: boolean;
22
23
  quantity?: number;
23
24
  unitPrice?: number;
24
- amount?: number;
25
- budget?: number;
26
- everyMonths: number;
27
25
  startOn: string;
28
26
  renewalOn?: string;
29
27
  autoRenew: boolean;
@@ -36,6 +34,7 @@ export declare class SaasSubscription {
36
34
  endedOn?: string;
37
35
  description?: string;
38
36
  seatsHeld?: number;
37
+ referenceAmount?: number | null;
39
38
  createdAt?: Date;
40
39
  updatedAt?: Date;
41
40
  deletedAt?: Date;
@@ -12,8 +12,9 @@ const saas_account_1 = require("./saas-account");
12
12
  const saas_rules_1 = require("./saas-rules");
13
13
  /**
14
14
  * One thing under an account the domain decides on and can cancel (ADR-0177 decisions 1, 3): a plan with seats, a fixed
15
- * fee, metered usage with a monthly budget, a commitment for a term, or a license owned - which points at the asset
16
- * register and carries no amount. It is billed in the account's currency, every so many months from the month it started.
15
+ * fee, metered usage, a commitment for a term, or a license owned - which points at the asset register. Its quantity and
16
+ * unit price are for reference only: the money is the recurring item's (accounting), which a person compares it with
17
+ * (개정 7).
17
18
  */
18
19
  let SaasSubscription = class SaasSubscription {
19
20
  };
@@ -62,33 +63,18 @@ tslib_1.__decorate([
62
63
  tslib_1.__metadata("design:type", Boolean)
63
64
  ], SaasSubscription.prototype, "trial", void 0);
64
65
  tslib_1.__decorate([
65
- (0, typeorm_1.Column)({ type: 'float', nullable: true }),
66
- (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'Seats or units - for a seat plan' }),
66
+ (0, typeorm_1.Column)((0, shell_1.quantityColumn)({ nullable: true })),
67
+ (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'Seats or units' }),
67
68
  tslib_1.__metadata("design:type", Number)
68
69
  ], SaasSubscription.prototype, "quantity", void 0);
69
70
  tslib_1.__decorate([
70
71
  (0, typeorm_1.Column)({ ...(0, shell_1.moneyColumn)(), nullable: true }),
71
- (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'The price of one seat for one billing - for a seat plan' }),
72
+ (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'The price of one seat or unit, or the fee - for reference only' }),
72
73
  tslib_1.__metadata("design:type", Number)
73
74
  ], SaasSubscription.prototype, "unitPrice", void 0);
74
- tslib_1.__decorate([
75
- (0, typeorm_1.Column)({ ...(0, shell_1.moneyColumn)(), nullable: true }),
76
- (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'What one billing costs - for a fixed fee or a commitment' }),
77
- tslib_1.__metadata("design:type", Number)
78
- ], SaasSubscription.prototype, "amount", void 0);
79
- tslib_1.__decorate([
80
- (0, typeorm_1.Column)({ ...(0, shell_1.moneyColumn)(), nullable: true }),
81
- (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'What a month of metered usage may cost - told when a bill is over it' }),
82
- tslib_1.__metadata("design:type", Number)
83
- ], SaasSubscription.prototype, "budget", void 0);
84
- tslib_1.__decorate([
85
- (0, typeorm_1.Column)({ type: 'int', default: 1 }),
86
- (0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Billed every so many months - 1 monthly, 12 yearly' }),
87
- tslib_1.__metadata("design:type", Number)
88
- ], SaasSubscription.prototype, "everyMonths", void 0);
89
75
  tslib_1.__decorate([
90
76
  (0, typeorm_1.Column)(),
91
- (0, type_graphql_1.Field)({ description: 'The day it started - YYYY-MM-DD; billings count from its month' }),
77
+ (0, type_graphql_1.Field)({ description: 'The day it started - YYYY-MM-DD' }),
92
78
  tslib_1.__metadata("design:type", String)
93
79
  ], SaasSubscription.prototype, "startOn", void 0);
94
80
  tslib_1.__decorate([
@@ -143,6 +129,10 @@ tslib_1.__decorate([
143
129
  (0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'How many seats are held today - filled by the list query' }),
144
130
  tslib_1.__metadata("design:type", Number)
145
131
  ], SaasSubscription.prototype, "seatsHeld", void 0);
132
+ tslib_1.__decorate([
133
+ (0, type_graphql_1.Field)(type => type_graphql_1.Float, { nullable: true, description: 'What its quantity and unit price make - for reference against the recurring item; filled by the query' }),
134
+ tslib_1.__metadata("design:type", Number)
135
+ ], SaasSubscription.prototype, "referenceAmount", void 0);
146
136
  tslib_1.__decorate([
147
137
  (0, typeorm_1.CreateDateColumn)(),
148
138
  (0, type_graphql_1.Field)({ nullable: true, description: 'When the subscription was registered' }),
@@ -1 +1 @@
1
- {"version":3,"file":"saas-subscription.js","sourceRoot":"","sources":["../../server/service/saas-subscription.ts"],"names":[],"mappings":"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","sourcesContent":["import { Asset } from '@things-factory/asset'\nimport { User } from '@things-factory/auth-base'\nimport { Department } from '@things-factory/organization'\nimport { Domain, moneyColumn } from '@things-factory/shell'\nimport { Field, Float, ID, Int, ObjectType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { SaasAccount } from './saas-account'\nimport { SaasBilling, SaasSubscriptionStatus } from './saas-rules'\n\n/**\n * One thing under an account the domain decides on and can cancel (ADR-0177 decisions 1, 3): a plan with seats, a fixed\n * fee, metered usage with a monthly budget, a commitment for a term, or a license owned - which points at the asset\n * register and carries no amount. It is billed in the account's currency, every so many months from the month it started.\n */\n@Entity()\n@Index('ix_saas_subscription_0', (sub: SaasSubscription) => [sub.domain, sub.account])\n@ObjectType({ description: 'Entity for SaasSubscription — a plan, fee, usage, commitment or owned license under an account' })\nexport class SaasSubscription {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier of the subscription' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain the subscription belongs to' })\n domain?: Domain\n\n @RelationId((sub: SaasSubscription) => sub.domain)\n domainId?: string\n\n @ManyToOne(type => SaasAccount, { onDelete: 'CASCADE' })\n @Field(type => SaasAccount, { nullable: true, description: 'The account it is under' })\n account?: SaasAccount\n\n @RelationId((sub: SaasSubscription) => sub.account)\n accountId?: string\n\n @Column()\n @Field({ description: 'The product and plan - Microsoft 365 Business Standard, AWS usage, Savings Plan 1 year, example.com' })\n name: string\n\n @Column({ default: SaasBilling.FIXED })\n @Field(type => SaasBilling, { description: 'How it is paid for' })\n billing: SaasBilling\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: \"The vendor's id for the plan - a Microsoft 365 SKU id; set by a sync, which keeps its seats and quantity\" })\n vendorKey?: string\n\n @Column({ default: false })\n @Field({ description: 'A trial the vendor hands out - it ends on its renewal day unless bought; set by a sync' })\n trial: boolean\n\n @Column({ type: 'float', nullable: true })\n @Field(type => Float, { nullable: true, description: 'Seats or units - for a seat plan' })\n quantity?: number\n\n @Column({ ...moneyColumn(), nullable: true })\n @Field(type => Float, { nullable: true, description: 'The price of one seat for one billing - for a seat plan' })\n unitPrice?: number\n\n @Column({ ...moneyColumn(), nullable: true })\n @Field(type => Float, { nullable: true, description: 'What one billing costs - for a fixed fee or a commitment' })\n amount?: number\n\n @Column({ ...moneyColumn(), nullable: true })\n @Field(type => Float, { nullable: true, description: 'What a month of metered usage may cost - told when a bill is over it' })\n budget?: number\n\n @Column({ type: 'int', default: 1 })\n @Field(type => Int, { description: 'Billed every so many months - 1 monthly, 12 yearly' })\n everyMonths: number\n\n @Column()\n @Field({ description: 'The day it started - YYYY-MM-DD; billings count from its month' })\n startOn: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The day it renews or its term ends - YYYY-MM-DD; a domain’s expiry' })\n renewalOn?: string\n\n @Column({ default: true })\n @Field({ description: 'Whether the vendor renews it unless cancelled' })\n autoRenew: boolean\n\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'How many days before renewal it must be cancelled - told from then' })\n noticeDays?: number\n\n @ManyToOne(type => Department, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => Department, { nullable: true, description: 'The department it is for - its cost when no seat says whose' })\n department?: Department\n\n @RelationId((sub: SaasSubscription) => sub.department)\n departmentId?: string\n\n @ManyToOne(type => Asset, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => Asset, { nullable: true, description: 'For a license owned: the asset of the register that carries its cost' })\n asset?: Asset\n\n @RelationId((sub: SaasSubscription) => sub.asset)\n assetId?: string\n\n @Column({ default: SaasSubscriptionStatus.ACTIVE })\n @Field(type => SaasSubscriptionStatus, { description: 'In use, not to be renewed, or ended' })\n status: SaasSubscriptionStatus\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The day it ended - YYYY-MM-DD' })\n endedOn?: string\n\n @Column({ type: 'text', nullable: true })\n @Field({ nullable: true, description: 'Notes' })\n description?: string\n\n @Field(type => Int, { nullable: true, description: 'How many seats are held today - filled by the list query' })\n seatsHeld?: number\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the subscription was registered' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the subscription last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the subscription was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who registered it' })\n creator?: User\n\n @RelationId((sub: SaasSubscription) => sub.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who last changed it' })\n updater?: User\n\n @RelationId((sub: SaasSubscription) => sub.updater)\n updaterId?: string\n}\n"]}
1
+ {"version":3,"file":"saas-subscription.js","sourceRoot":"","sources":["../../server/service/saas-subscription.ts"],"names":[],"mappings":"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","sourcesContent":["import { Asset } from '@things-factory/asset'\nimport { User } from '@things-factory/auth-base'\nimport { Department } from '@things-factory/organization'\nimport { Domain, moneyColumn, quantityColumn } from '@things-factory/shell'\nimport { Field, Float, ID, Int, ObjectType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { SaasAccount } from './saas-account'\nimport { SaasBilling, SaasSubscriptionStatus } from './saas-rules'\n\n/**\n * One thing under an account the domain decides on and can cancel (ADR-0177 decisions 1, 3): a plan with seats, a fixed\n * fee, metered usage, a commitment for a term, or a license owned - which points at the asset register. Its quantity and\n * unit price are for reference only: the money is the recurring item's (accounting), which a person compares it with\n * (개정 7).\n */\n@Entity()\n@Index('ix_saas_subscription_0', (sub: SaasSubscription) => [sub.domain, sub.account])\n@ObjectType({ description: 'Entity for SaasSubscription — a plan, fee, usage, commitment or owned license under an account' })\nexport class SaasSubscription {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier of the subscription' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain the subscription belongs to' })\n domain?: Domain\n\n @RelationId((sub: SaasSubscription) => sub.domain)\n domainId?: string\n\n @ManyToOne(type => SaasAccount, { onDelete: 'CASCADE' })\n @Field(type => SaasAccount, { nullable: true, description: 'The account it is under' })\n account?: SaasAccount\n\n @RelationId((sub: SaasSubscription) => sub.account)\n accountId?: string\n\n @Column()\n @Field({ description: 'The product and plan - Microsoft 365 Business Standard, AWS usage, Savings Plan 1 year, example.com' })\n name: string\n\n @Column({ default: SaasBilling.FIXED })\n @Field(type => SaasBilling, { description: 'How it is paid for' })\n billing: SaasBilling\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: \"The vendor's id for the plan - a Microsoft 365 SKU id; set by a sync, which keeps its seats and quantity\" })\n vendorKey?: string\n\n @Column({ default: false })\n @Field({ description: 'A trial the vendor hands out - it ends on its renewal day unless bought; set by a sync' })\n trial: boolean\n\n @Column(quantityColumn({ nullable: true }))\n @Field(type => Float, { nullable: true, description: 'Seats or units' })\n quantity?: number\n\n @Column({ ...moneyColumn(), nullable: true })\n @Field(type => Float, { nullable: true, description: 'The price of one seat or unit, or the fee - for reference only' })\n unitPrice?: number\n\n @Column()\n @Field({ description: 'The day it started - YYYY-MM-DD' })\n startOn: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The day it renews or its term ends - YYYY-MM-DD; a domain’s expiry' })\n renewalOn?: string\n\n @Column({ default: true })\n @Field({ description: 'Whether the vendor renews it unless cancelled' })\n autoRenew: boolean\n\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'How many days before renewal it must be cancelled - told from then' })\n noticeDays?: number\n\n @ManyToOne(type => Department, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => Department, { nullable: true, description: 'The department it is for - its cost when no seat says whose' })\n department?: Department\n\n @RelationId((sub: SaasSubscription) => sub.department)\n departmentId?: string\n\n @ManyToOne(type => Asset, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => Asset, { nullable: true, description: 'For a license owned: the asset of the register that carries its cost' })\n asset?: Asset\n\n @RelationId((sub: SaasSubscription) => sub.asset)\n assetId?: string\n\n @Column({ default: SaasSubscriptionStatus.ACTIVE })\n @Field(type => SaasSubscriptionStatus, { description: 'In use, not to be renewed, or ended' })\n status: SaasSubscriptionStatus\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The day it ended - YYYY-MM-DD' })\n endedOn?: string\n\n @Column({ type: 'text', nullable: true })\n @Field({ nullable: true, description: 'Notes' })\n description?: string\n\n @Field(type => Int, { nullable: true, description: 'How many seats are held today - filled by the list query' })\n seatsHeld?: number\n\n @Field(type => Float, { nullable: true, description: 'What its quantity and unit price make - for reference against the recurring item; filled by the query' })\n referenceAmount?: number | null\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the subscription was registered' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the subscription last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the subscription was deleted' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who registered it' })\n creator?: User\n\n @RelationId((sub: SaasSubscription) => sub.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who last changed it' })\n updater?: User\n\n @RelationId((sub: SaasSubscription) => sub.updater)\n updaterId?: string\n}\n"]}
@@ -32,38 +32,3 @@ export interface LicenseSyncResult {
32
32
  unmatched: string[];
33
33
  }
34
34
  export declare function syncSaasLicenses(tx: EntityManager, domain: Domain, user: any, facts: LicenseFacts, today: string): Promise<LicenseSyncResult>;
35
- export interface CostFacts {
36
- /** The vendor's id for the account - an Anthropic organization id. */
37
- vendorAccount: string;
38
- vendorName?: string | null;
39
- currency: string;
40
- months: {
41
- month: string;
42
- lines: {
43
- label: string;
44
- amount: number;
45
- }[];
46
- }[];
47
- }
48
- export interface CostSyncResult {
49
- accountId: string;
50
- accountName: string;
51
- written: number;
52
- /** Months a person wrote the bill of - left as they are. */
53
- kept: string[];
54
- }
55
- /**
56
- * Write each closed month's bill from the vendor's cost report, a line a model, all on the account's usage subscription
57
- * for the vendor (made when there is none: usage, `vendorKey` the vendor account). A month whose bill a person wrote is
58
- * kept; one a sync wrote is rewritten. The report's currency must be the account's.
59
- */
60
- export declare function syncSaasCosts(tx: EntityManager, domain: Domain, user: any, facts: CostFacts, today: string): Promise<CostSyncResult>;
61
- /**
62
- * Several accounts' cost reports at once - an AWS organization gives one an account. A vendor account no subscription
63
- * account names is passed over and told (an organization holds accounts the domain does not keep); any other refusal
64
- * stops the sync.
65
- */
66
- export declare function syncSaasCostsOf(tx: EntityManager, domain: Domain, user: any, reports: CostFacts[], today: string): Promise<{
67
- results: CostSyncResult[];
68
- unmatched: string[];
69
- }>;
@@ -1,12 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.syncSaasLicenses = syncSaasLicenses;
4
- exports.syncSaasCosts = syncSaasCosts;
5
- exports.syncSaasCostsOf = syncSaasCostsOf;
6
4
  const organization_1 = require("@things-factory/organization");
7
5
  const shell_1 = require("@things-factory/shell");
8
6
  const saas_account_1 = require("./saas-account");
9
- const saas_bill_1 = require("./saas-bill");
10
7
  const saas_rules_1 = require("./saas-rules");
11
8
  const saas_seat_1 = require("./saas-seat");
12
9
  const saas_service_1 = require("./saas-service");
@@ -106,61 +103,4 @@ async function syncSaasLicenses(tx, domain, user, facts, today) {
106
103
  result.unmatched = [...new Set(result.unmatched)];
107
104
  return result;
108
105
  }
109
- /**
110
- * Write each closed month's bill from the vendor's cost report, a line a model, all on the account's usage subscription
111
- * for the vendor (made when there is none: usage, `vendorKey` the vendor account). A month whose bill a person wrote is
112
- * kept; one a sync wrote is rewritten. The report's currency must be the account's.
113
- */
114
- async function syncSaasCosts(tx, domain, user, facts, today) {
115
- const account = await accountOfVendor(tx, domain, [facts.vendorAccount]);
116
- if (account.parentId)
117
- throw new shell_1.Refusal('saas-bill-on-sub-account', {}, 'An account under another is billed by its parent');
118
- if (String(facts.currency).toUpperCase() !== account.currency)
119
- throw new shell_1.Refusal('saas-sync-currency-differs', { currency: facts.currency, account: account.currency }, `The vendor bills in ${facts.currency}; the account is in ${account.currency} - set the account's currency`);
120
- const months = facts.months.filter(one => one.month < today.slice(0, 7) && one.lines.some(line => Number(line.amount)));
121
- const result = { accountId: account.id, accountName: account.name, written: 0, kept: [] };
122
- if (!months.length)
123
- return result;
124
- const subs = await tx.getRepository(saas_subscription_1.SaasSubscription).find({ where: { domain: { id: domain.id }, account: { id: account.id } } });
125
- let usage = subs.find(one => one.vendorKey === facts.vendorAccount);
126
- if (!usage)
127
- [usage] = await (0, saas_service_1.saveSaasSubscriptions)(tx, domain, user, 'all', account.id, [
128
- { cuFlag: '+', name: `${facts.vendorName || account.name} API`, billing: saas_rules_1.SaasBilling.USAGE, vendorKey: facts.vendorAccount, startOn: `${months[0].month}-01`, status: saas_rules_1.SaasSubscriptionStatus.ACTIVE }
129
- ]);
130
- const bills = await tx.getRepository(saas_bill_1.SaasBill).find({ where: { domain: { id: domain.id }, account: { id: account.id } } });
131
- for (const one of months) {
132
- const bill = bills.find(old => old.month === one.month);
133
- if (bill && !bill.synced) {
134
- result.kept.push(one.month);
135
- continue;
136
- }
137
- const saved = await (0, saas_service_1.saveSaasBill)(tx, domain, user, 'all', account.id, {
138
- id: bill?.id ?? null,
139
- month: one.month,
140
- lines: one.lines.filter(line => Number(line.amount)).map(line => ({ subscriptionId: usage.id, label: line.label, amount: Number(line.amount) }))
141
- });
142
- await tx.getRepository(saas_bill_1.SaasBill).update({ id: saved.id }, { synced: true });
143
- result.written++;
144
- }
145
- return result;
146
- }
147
- /**
148
- * Several accounts' cost reports at once - an AWS organization gives one an account. A vendor account no subscription
149
- * account names is passed over and told (an organization holds accounts the domain does not keep); any other refusal
150
- * stops the sync.
151
- */
152
- async function syncSaasCostsOf(tx, domain, user, reports, today) {
153
- const results = [];
154
- const unmatched = [];
155
- for (const facts of reports)
156
- try {
157
- results.push(await syncSaasCosts(tx, domain, user, facts, today));
158
- }
159
- catch (error) {
160
- if (error?.code !== 'saas-sync-account-not-found')
161
- throw error;
162
- unmatched.push(facts.vendorAccount);
163
- }
164
- return { results, unmatched };
165
- }
166
106
  //# sourceMappingURL=saas-sync.js.map