@things-factory/accounting 10.1.205 → 10.1.208
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/activities/activity-expenditure.js +5 -2
- package/dist-server/activities/activity-expenditure.js.map +1 -1
- package/dist-server/service/account/account-mutation.js +5 -7
- package/dist-server/service/account/account-mutation.js.map +1 -1
- package/dist-server/service/account/account-service.d.ts +5 -0
- package/dist-server/service/account/account-service.js +17 -0
- package/dist-server/service/account/account-service.js.map +1 -0
- package/dist-server/service/bank-account/bank-account-service.d.ts +4 -1
- package/dist-server/service/bank-account/bank-account-service.js +5 -1
- package/dist-server/service/bank-account/bank-account-service.js.map +1 -1
- package/dist-server/service/expenditure-request/expenditure-request-item.d.ts +4 -3
- package/dist-server/service/expenditure-request/expenditure-request-item.js +6 -5
- package/dist-server/service/expenditure-request/expenditure-request-item.js.map +1 -1
- package/dist-server/service/expenditure-request/expenditure-request-mutation.d.ts +1 -1
- package/dist-server/service/expenditure-request/expenditure-request-mutation.js +8 -7
- package/dist-server/service/expenditure-request/expenditure-request-mutation.js.map +1 -1
- package/dist-server/service/expenditure-request/expenditure-request-query.d.ts +9 -2
- package/dist-server/service/expenditure-request/expenditure-request-query.js +28 -6
- package/dist-server/service/expenditure-request/expenditure-request-query.js.map +1 -1
- package/dist-server/service/expenditure-request/expenditure-request-service.d.ts +12 -4
- package/dist-server/service/expenditure-request/expenditure-request-service.js +30 -9
- package/dist-server/service/expenditure-request/expenditure-request-service.js.map +1 -1
- package/dist-server/service/expenditure-request/expenditure-request-type.d.ts +1 -1
- package/dist-server/service/expenditure-request/expenditure-request-type.js +3 -3
- package/dist-server/service/expenditure-request/expenditure-request-type.js.map +1 -1
- package/dist-server/service/expenditure-request/index.d.ts +2 -2
- package/dist-server/service/expenditure-request/receipt-reader.d.ts +18 -9
- package/dist-server/service/expenditure-request/receipt-reader.js +19 -10
- package/dist-server/service/expenditure-request/receipt-reader.js.map +1 -1
- package/dist-server/service/financial-statement/index.d.ts +1 -1
- package/dist-server/service/index.d.ts +2 -1
- package/dist-server/service/index.js +1 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/payment/index.js +3 -0
- package/dist-server/service/payment/index.js.map +1 -1
- package/dist-server/service/recurring-cash-item/recurring-cash-item-service.d.ts +4 -1
- package/dist-server/service/recurring-cash-item/recurring-cash-item-service.js +5 -1
- package/dist-server/service/recurring-cash-item/recurring-cash-item-service.js.map +1 -1
- package/dist-server/service/transaction/transaction-service.d.ts +3 -2
- package/dist-server/service/transaction/transaction-service.js +4 -4
- package/dist-server/service/transaction/transaction-service.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/translations/en.json +8 -1
- package/translations/es.json +8 -1
- package/translations/ja.json +7 -0
- package/translations/ko.json +9 -2
- package/translations/ms.json +7 -0
- package/translations/zh.json +7 -0
|
@@ -41,7 +41,8 @@ const MODEL = [
|
|
|
41
41
|
{ name: 'requester', description: 'Who requests', tag: 'requester', hidden: true, mandatory: true, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },
|
|
42
42
|
{ name: 'payee', description: 'Who is paid', tag: 'payee', hidden: true, mandatory: false, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },
|
|
43
43
|
{ name: 'paidTo', description: 'Who is paid, as a reference its 360 opens from', tag: 'paidTo', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} },
|
|
44
|
-
{ name: 'lines', description: 'The lines as the approver reads them', tag: 'lines', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} }
|
|
44
|
+
{ name: 'lines', description: 'The lines as the approver reads them', tag: 'lines', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} },
|
|
45
|
+
{ name: 'request', description: 'The request, as a reference its lines and files open from', tag: 'request', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} }
|
|
45
46
|
];
|
|
46
47
|
/*
|
|
47
48
|
* What the 업무 카탈로그 shows of how far these forms are (worklist `ActivityReadiness`). `lastRun` is written by
|
|
@@ -51,7 +52,7 @@ const MODEL = [
|
|
|
51
52
|
const READINESS = {
|
|
52
53
|
stage: 'working',
|
|
53
54
|
tests: ['packages/accounting/test/expenditure-requests.test.mjs'],
|
|
54
|
-
lastRun: { passed:
|
|
55
|
+
lastRun: { passed: 21, total: 21, at: '2026-10-23T15:39:22+09:00', command: 'npm run build:server && node --test test/expenditure-requests.test.mjs (packages/accounting)' }
|
|
55
56
|
};
|
|
56
57
|
const COMMON = {
|
|
57
58
|
release: '1.0.0',
|
|
@@ -91,6 +92,7 @@ exports.ActivityExpenditureRequest = {
|
|
|
91
92
|
{ role: 'headline', inputPath: 'headline', name: 'what is to be paid' },
|
|
92
93
|
{ role: 'subject', inputPath: 'paidTo', tKey: 'field.payee', name: 'who is paid' },
|
|
93
94
|
{ role: 'reason', inputPath: 'lines', tKey: 'field.expenditure-lines', name: 'what it pays for' },
|
|
95
|
+
{ role: 'evidence', inputPath: 'request', tKey: 'field.expenditure-files', name: 'the receipts and papers of the lines' },
|
|
94
96
|
{ role: 'consequence', inputPath: 'consequence', name: 'what approving does' }
|
|
95
97
|
]
|
|
96
98
|
};
|
|
@@ -115,6 +117,7 @@ exports.ActivityExpenseClaim = {
|
|
|
115
117
|
{ role: 'headline', inputPath: 'headline', name: 'what is claimed' },
|
|
116
118
|
{ role: 'subject', inputPath: 'paidTo', tKey: 'field.requester', name: 'who claims' },
|
|
117
119
|
{ role: 'reason', inputPath: 'lines', tKey: 'field.expenditure-lines', name: 'what was spent, on what' },
|
|
120
|
+
{ role: 'evidence', inputPath: 'request', tKey: 'field.expenditure-files', name: 'the receipts and papers of the lines' },
|
|
118
121
|
{ role: 'consequence', inputPath: 'consequence', name: 'what approving does' }
|
|
119
122
|
]
|
|
120
123
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity-expenditure.js","sourceRoot":"","sources":["../../server/activities/activity-expenditure.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActivityInstance, UpdateActivityInstanceStateAddendum } from '@things-factory/worklist'\nimport { speaksRefusals } from '@things-factory/shell'\n\nimport { ExpenditureRequest, ExpenditureRequestStatus } from '../service/expenditure-request/expenditure-request'\nimport { decisionOf, type RequestStatus } from '../service/expenditure-request/expenditure-request-rules'\nimport { EXPENDITURE_REQUEST_ACTIVITY, EXPENSE_CLAIM_ACTIVITY } from './expenditure-activity-names'\n\n/**\n * What an approver's decision does to the request.\n *\n * worklist calls this on every state change of the instance, in the same transaction, and more than once for one\n * change. `decisionOf` lets a decision land only on the request still waiting on this instance - so a repeat call, or\n * a call about an instance the requester already withdrew and replaced, changes nothing.\n *\n * A rejection does not end the instance; the rejected thread in `causedBy` is how it is known. The person deciding is\n * `context.state.user` - the approver, not the requester.\n */\nexport async function decideExpenditure(activityInstance: ActivityInstance, addendum: UpdateActivityInstanceStateAddendum, context: ResolverContext) {\n const { domain, user, tx } = context.state\n const requestId = (activityInstance.input as any)?.requestId\n if (!requestId) return\n\n const repo = tx.getRepository(ExpenditureRequest)\n const request = await repo.findOne({ where: { id: requestId, domain: { id: domain.id } } as any })\n if (!request) return\n\n const decision = decisionOf(\n { id: activityInstance.id, state: String(activityInstance.state) },\n (addendum?.causedBy ?? []).map(thread => ({ state: String(thread.state) })),\n { status: request.status as RequestStatus, activityInstanceId: request.activityInstanceId }\n )\n if (!decision) return\n\n request.status = ExpenditureRequestStatus[decision]\n if (decision !== 'WITHDRAWN') {\n request.decidedAt = new Date()\n request.decidedBy = user\n }\n await repo.save(request)\n}\n\nconst MODEL = [\n { name: 'requestId', description: 'The request this approval decides', tag: 'requestId', hidden: true, mandatory: true, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'month', description: 'Month, at the top level so the search key can index it', tag: 'month', hidden: true, mandatory: false, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'requester', description: 'Who requests', tag: 'requester', hidden: true, mandatory: true, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'payee', description: 'Who is paid', tag: 'payee', hidden: true, mandatory: false, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'paidTo', description: 'Who is paid, as a reference its 360 opens from', tag: 'paidTo', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'lines', description: 'The lines as the approver reads them', tag: 'lines', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} }\n]\n\n/*\n * What the 업무 카탈로그 shows of how far these forms are (worklist `ActivityReadiness`). `lastRun` is written by\n * hand: change the tests, and change this line with them - the screen shows the day it was measured, so a stale\n * count reads as stale.\n */\nconst READINESS = {\n stage: 'working',\n tests: ['packages/accounting/test/expenditure-requests.test.mjs'],\n lastRun: { passed: 18, total: 18, at: '2026-10-16T21:09:48+09:00', command: 'npm run build:server && node --test test/expenditure-requests.test.mjs (packages/accounting)' }\n}\n\nconst COMMON = {\n release: '1.0.0',\n provider: 'hatiolab.com',\n category: 'accounting',\n activityType: 'user',\n priority: 1,\n startingType: 'post',\n multiple: 'single',\n /* No screen of its own: the generic approval screen draws the decision keys. Set explicitly - leaving it out keeps an old value. */\n viewType: '',\n viewSource: '',\n model: MODEL,\n standardTime: 3 * 24 * 60 * 60,\n readiness: READINESS,\n /* Runs inside worklist's mutation, where no resolver's `SpeakRefusals` reaches. */\n callback: speaksRefusals(decideExpenditure)\n}\n\n/** 지출결의 - paying a counterparty. */\nexport const ActivityExpenditureRequest = {\n ...COMMON,\n name: EXPENDITURE_REQUEST_ACTIVITY,\n label: 'expenditure request',\n description: 'Approval of a payment to a counterparty before the money leaves',\n guide: [\n 'someone asks the company to pay a counterparty - an invoice, a service, a deposit - into an account of that counterparty.',\n 'approving puts it in the payment queue; finance pays it, and the payment is reconciled with the bank statement.',\n 'the account approvers see is the account paid; if it changes after the approval, finance is told before paying.',\n 'rejecting returns the request to its writer, who can correct it and submit again.',\n 'with no approver named for this domain a request cannot be submitted.'\n ],\n searchKeys: [\n { name: 'payee', description: 'Who is paid', inputKey: 'payee', tKey: 'field.payee' },\n { name: 'requester', description: 'Who requests', inputKey: 'requester', tKey: 'field.requester' }\n ],\n decisionKeys: [\n { role: 'headline', inputPath: 'headline', name: 'what is to be paid' },\n { role: 'subject', inputPath: 'paidTo', tKey: 'field.payee', name: 'who is paid' },\n { role: 'reason', inputPath: 'lines', tKey: 'field.expenditure-lines', name: 'what it pays for' },\n { role: 'consequence', inputPath: 'consequence', name: 'what approving does' }\n ]\n}\n\n/** 경비 청구 - paying an employee back what they spent for the company in a month. */\nexport const ActivityExpenseClaim = {\n ...COMMON,\n name: EXPENSE_CLAIM_ACTIVITY,\n label: 'expense claim',\n description: 'Approval of what an employee spent for the company in a month',\n guide: [\n 'an employee claims what they spent for the company - meals, travel, supplies.',\n 'approving puts it in the payment queue; finance pays the employee back, and the payment is reconciled with the bank statement.',\n 'lines paid with the corporate card are reviewed the same way but nothing is paid back for them.',\n 'rejecting returns the claim to the employee, who can correct it and submit again.',\n 'with no approver named for this domain a claim cannot be submitted.'\n ],\n searchKeys: [\n { name: 'month', description: 'Which month', inputKey: 'month', tKey: 'field.month' },\n { name: 'requester', description: 'Who claims', inputKey: 'requester', tKey: 'field.requester' }\n ],\n decisionKeys: [\n { role: 'headline', inputPath: 'headline', name: 'what is claimed' },\n { role: 'subject', inputPath: 'paidTo', tKey: 'field.requester', name: 'who claims' },\n { role: 'reason', inputPath: 'lines', tKey: 'field.expenditure-lines', name: 'what was spent, on what' },\n { role: 'consequence', inputPath: 'consequence', name: 'what approving does' }\n ]\n}\n\n/** The approvals of an expenditure request - an application that uses them installs these into its domains. */\nexport const EXPENDITURE_ACTIVITIES = [ActivityExpenditureRequest, ActivityExpenseClaim]\n"]}
|
|
1
|
+
{"version":3,"file":"activity-expenditure.js","sourceRoot":"","sources":["../../server/activities/activity-expenditure.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActivityInstance, UpdateActivityInstanceStateAddendum } from '@things-factory/worklist'\nimport { speaksRefusals } from '@things-factory/shell'\n\nimport { ExpenditureRequest, ExpenditureRequestStatus } from '../service/expenditure-request/expenditure-request'\nimport { decisionOf, type RequestStatus } from '../service/expenditure-request/expenditure-request-rules'\nimport { EXPENDITURE_REQUEST_ACTIVITY, EXPENSE_CLAIM_ACTIVITY } from './expenditure-activity-names'\n\n/**\n * What an approver's decision does to the request.\n *\n * worklist calls this on every state change of the instance, in the same transaction, and more than once for one\n * change. `decisionOf` lets a decision land only on the request still waiting on this instance - so a repeat call, or\n * a call about an instance the requester already withdrew and replaced, changes nothing.\n *\n * A rejection does not end the instance; the rejected thread in `causedBy` is how it is known. The person deciding is\n * `context.state.user` - the approver, not the requester.\n */\nexport async function decideExpenditure(activityInstance: ActivityInstance, addendum: UpdateActivityInstanceStateAddendum, context: ResolverContext) {\n const { domain, user, tx } = context.state\n const requestId = (activityInstance.input as any)?.requestId\n if (!requestId) return\n\n const repo = tx.getRepository(ExpenditureRequest)\n const request = await repo.findOne({ where: { id: requestId, domain: { id: domain.id } } as any })\n if (!request) return\n\n const decision = decisionOf(\n { id: activityInstance.id, state: String(activityInstance.state) },\n (addendum?.causedBy ?? []).map(thread => ({ state: String(thread.state) })),\n { status: request.status as RequestStatus, activityInstanceId: request.activityInstanceId }\n )\n if (!decision) return\n\n request.status = ExpenditureRequestStatus[decision]\n if (decision !== 'WITHDRAWN') {\n request.decidedAt = new Date()\n request.decidedBy = user\n }\n await repo.save(request)\n}\n\nconst MODEL = [\n { name: 'requestId', description: 'The request this approval decides', tag: 'requestId', hidden: true, mandatory: true, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'month', description: 'Month, at the top level so the search key can index it', tag: 'month', hidden: true, mandatory: false, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'requester', description: 'Who requests', tag: 'requester', hidden: true, mandatory: true, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'payee', description: 'Who is paid', tag: 'payee', hidden: true, mandatory: false, inout: 'in', type: 'string', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'paidTo', description: 'Who is paid, as a reference its 360 opens from', tag: 'paidTo', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'lines', description: 'The lines as the approver reads them', tag: 'lines', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} },\n { name: 'request', description: 'The request, as a reference its lines and files open from', tag: 'request', hidden: true, mandatory: false, inout: 'in', type: 'object', options: {}, unit: null, quantifier: [1], spec: {} }\n]\n\n/*\n * What the 업무 카탈로그 shows of how far these forms are (worklist `ActivityReadiness`). `lastRun` is written by\n * hand: change the tests, and change this line with them - the screen shows the day it was measured, so a stale\n * count reads as stale.\n */\nconst READINESS = {\n stage: 'working',\n tests: ['packages/accounting/test/expenditure-requests.test.mjs'],\n lastRun: { passed: 21, total: 21, at: '2026-10-23T15:39:22+09:00', command: 'npm run build:server && node --test test/expenditure-requests.test.mjs (packages/accounting)' }\n}\n\nconst COMMON = {\n release: '1.0.0',\n provider: 'hatiolab.com',\n category: 'accounting',\n activityType: 'user',\n priority: 1,\n startingType: 'post',\n multiple: 'single',\n /* No screen of its own: the generic approval screen draws the decision keys. Set explicitly - leaving it out keeps an old value. */\n viewType: '',\n viewSource: '',\n model: MODEL,\n standardTime: 3 * 24 * 60 * 60,\n readiness: READINESS,\n /* Runs inside worklist's mutation, where no resolver's `SpeakRefusals` reaches. */\n callback: speaksRefusals(decideExpenditure)\n}\n\n/** 지출결의 - paying a counterparty. */\nexport const ActivityExpenditureRequest = {\n ...COMMON,\n name: EXPENDITURE_REQUEST_ACTIVITY,\n label: 'expenditure request',\n description: 'Approval of a payment to a counterparty before the money leaves',\n guide: [\n 'someone asks the company to pay a counterparty - an invoice, a service, a deposit - into an account of that counterparty.',\n 'approving puts it in the payment queue; finance pays it, and the payment is reconciled with the bank statement.',\n 'the account approvers see is the account paid; if it changes after the approval, finance is told before paying.',\n 'rejecting returns the request to its writer, who can correct it and submit again.',\n 'with no approver named for this domain a request cannot be submitted.'\n ],\n searchKeys: [\n { name: 'payee', description: 'Who is paid', inputKey: 'payee', tKey: 'field.payee' },\n { name: 'requester', description: 'Who requests', inputKey: 'requester', tKey: 'field.requester' }\n ],\n decisionKeys: [\n { role: 'headline', inputPath: 'headline', name: 'what is to be paid' },\n { role: 'subject', inputPath: 'paidTo', tKey: 'field.payee', name: 'who is paid' },\n { role: 'reason', inputPath: 'lines', tKey: 'field.expenditure-lines', name: 'what it pays for' },\n { role: 'evidence', inputPath: 'request', tKey: 'field.expenditure-files', name: 'the receipts and papers of the lines' },\n { role: 'consequence', inputPath: 'consequence', name: 'what approving does' }\n ]\n}\n\n/** 경비 청구 - paying an employee back what they spent for the company in a month. */\nexport const ActivityExpenseClaim = {\n ...COMMON,\n name: EXPENSE_CLAIM_ACTIVITY,\n label: 'expense claim',\n description: 'Approval of what an employee spent for the company in a month',\n guide: [\n 'an employee claims what they spent for the company - meals, travel, supplies.',\n 'approving puts it in the payment queue; finance pays the employee back, and the payment is reconciled with the bank statement.',\n 'lines paid with the corporate card are reviewed the same way but nothing is paid back for them.',\n 'rejecting returns the claim to the employee, who can correct it and submit again.',\n 'with no approver named for this domain a claim cannot be submitted.'\n ],\n searchKeys: [\n { name: 'month', description: 'Which month', inputKey: 'month', tKey: 'field.month' },\n { name: 'requester', description: 'Who claims', inputKey: 'requester', tKey: 'field.requester' }\n ],\n decisionKeys: [\n { role: 'headline', inputPath: 'headline', name: 'what is claimed' },\n { role: 'subject', inputPath: 'paidTo', tKey: 'field.requester', name: 'who claims' },\n { role: 'reason', inputPath: 'lines', tKey: 'field.expenditure-lines', name: 'what was spent, on what' },\n { role: 'evidence', inputPath: 'request', tKey: 'field.expenditure-files', name: 'the receipts and papers of the lines' },\n { role: 'consequence', inputPath: 'consequence', name: 'what approving does' }\n ]\n}\n\n/** The approvals of an expenditure request - an application that uses them installs these into its domains. */\nexport const EXPENDITURE_ACTIVITIES = [ActivityExpenditureRequest, ActivityExpenseClaim]\n"]}
|
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AccountMutation = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const type_graphql_1 = require("type-graphql");
|
|
6
|
-
const typeorm_1 = require("typeorm");
|
|
7
6
|
const shell_1 = require("@things-factory/shell");
|
|
8
7
|
const account_1 = require("./account");
|
|
9
8
|
const account_type_1 = require("./account-type");
|
|
9
|
+
const account_service_1 = require("./account-service");
|
|
10
10
|
let AccountMutation = class AccountMutation {
|
|
11
11
|
async createAccount(account, context) {
|
|
12
12
|
const { domain, user, tx } = context.state;
|
|
@@ -70,15 +70,12 @@ let AccountMutation = class AccountMutation {
|
|
|
70
70
|
}
|
|
71
71
|
async deleteAccount(id, context) {
|
|
72
72
|
const { domain, tx } = context.state;
|
|
73
|
-
await (0,
|
|
73
|
+
await (0, account_service_1.deleteAccounts)(tx, domain, [id]);
|
|
74
74
|
return true;
|
|
75
75
|
}
|
|
76
76
|
async deleteAccounts(ids, context) {
|
|
77
77
|
const { domain, tx } = context.state;
|
|
78
|
-
await (0,
|
|
79
|
-
domain: { id: domain.id },
|
|
80
|
-
id: (0, typeorm_1.In)(ids)
|
|
81
|
-
});
|
|
78
|
+
await (0, account_service_1.deleteAccounts)(tx, domain, ids);
|
|
82
79
|
return true;
|
|
83
80
|
}
|
|
84
81
|
async importAccounts(accounts, context) {
|
|
@@ -152,6 +149,7 @@ tslib_1.__decorate([
|
|
|
152
149
|
tslib_1.__metadata("design:returntype", Promise)
|
|
153
150
|
], AccountMutation.prototype, "importAccounts", null);
|
|
154
151
|
exports.AccountMutation = AccountMutation = tslib_1.__decorate([
|
|
155
|
-
(0, type_graphql_1.Resolver)(account_1.Account)
|
|
152
|
+
(0, type_graphql_1.Resolver)(account_1.Account),
|
|
153
|
+
(0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
|
|
156
154
|
], AccountMutation);
|
|
157
155
|
//# sourceMappingURL=account-mutation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-mutation.js","sourceRoot":"","sources":["../../../server/service/account/account-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { Account } from './account'\nimport { NewAccount, AccountPatch } from './account-type'\n\n@Resolver(Account)\nexport class AccountMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Account, { description: 'To create new Account' })\n async createAccount(@Arg('account') account: NewAccount, @Ctx() context: ResolverContext): Promise<Account> {\n const { domain, user, tx } = context.state\n\n const result = await getRepository(Account, tx).save({\n ...account,\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Account, { description: 'To modify Account information' })\n async updateAccount(\n @Arg('id') id: string,\n @Arg('patch') patch: AccountPatch,\n @Ctx() context: ResolverContext\n ): Promise<Account> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(Account, tx)\n const account = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const result = await repository.save({\n ...account,\n ...patch,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Account], { description: \"To modify multiple Accounts' information\" })\n async updateMultipleAccount(\n @Arg('patches', type => [AccountPatch]) patches: AccountPatch[],\n @Ctx() context: ResolverContext\n ): Promise<Account[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const accountRepo = getRepository(Account, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await accountRepo.save({\n ...newRecord,\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const account = await accountRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!account) {\n throw new Error(`failed to find account to update: ${updateRecord.id}`)\n }\n\n const result = await accountRepo.save({\n ...account,\n ...updateRecord,\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete Account' })\n async deleteAccount(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(Account, tx).softDelete({ domain: { id: domain.id }, id })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple Accounts' })\n async deleteAccounts(@Arg('ids', type => [String]) ids: string[], @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(Account, tx).softDelete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import multiple Accounts' })\n async importAccounts(\n @Arg('accounts', type => [AccountPatch]) accounts: AccountPatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await Promise.all(\n accounts.map(async (account: AccountPatch) => {\n const createdAccount: Account = await getRepository(Account, tx).save({ domain, ...account })\n })\n )\n\n return true\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"account-mutation.js","sourceRoot":"","sources":["../../../server/service/account/account-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive, UseMiddleware } from 'type-graphql'\n\nimport { getRepository, SpeakRefusals } from '@things-factory/shell'\n\nimport { Account } from './account'\nimport { NewAccount, AccountPatch } from './account-type'\nimport { deleteAccounts } from './account-service'\n\n@Resolver(Account)\n@UseMiddleware(SpeakRefusals)\nexport class AccountMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Account, { description: 'To create new Account' })\n async createAccount(@Arg('account') account: NewAccount, @Ctx() context: ResolverContext): Promise<Account> {\n const { domain, user, tx } = context.state\n\n const result = await getRepository(Account, tx).save({\n ...account,\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Account, { description: 'To modify Account information' })\n async updateAccount(\n @Arg('id') id: string,\n @Arg('patch') patch: AccountPatch,\n @Ctx() context: ResolverContext\n ): Promise<Account> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(Account, tx)\n const account = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const result = await repository.save({\n ...account,\n ...patch,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Account], { description: \"To modify multiple Accounts' information\" })\n async updateMultipleAccount(\n @Arg('patches', type => [AccountPatch]) patches: AccountPatch[],\n @Ctx() context: ResolverContext\n ): Promise<Account[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const accountRepo = getRepository(Account, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await accountRepo.save({\n ...newRecord,\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const account = await accountRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!account) {\n throw new Error(`failed to find account to update: ${updateRecord.id}`)\n }\n\n const result = await accountRepo.save({\n ...account,\n ...updateRecord,\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete Account' })\n async deleteAccount(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await deleteAccounts(tx, domain, [id])\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple Accounts' })\n async deleteAccounts(@Arg('ids', type => [String]) ids: string[], @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await deleteAccounts(tx, domain, ids)\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import multiple Accounts' })\n async importAccounts(\n @Arg('accounts', type => [AccountPatch]) accounts: AccountPatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await Promise.all(\n accounts.map(async (account: AccountPatch) => {\n const createdAccount: Account = await getRepository(Account, tx).save({ domain, ...account })\n })\n )\n\n return true\n }\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteAccounts = deleteAccounts;
|
|
4
|
+
const typeorm_1 = require("typeorm");
|
|
5
|
+
const shell_1 = require("@things-factory/shell");
|
|
6
|
+
const account_1 = require("./account");
|
|
7
|
+
/** An account a line, a recurring item or another row still names is not deleted (§`refuseTiedRows`). */
|
|
8
|
+
async function deleteAccounts(tx, domain, ids) {
|
|
9
|
+
const unique = [...new Set(ids)];
|
|
10
|
+
const repo = tx.getRepository(account_1.Account);
|
|
11
|
+
const found = await repo.find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(unique) } });
|
|
12
|
+
if (found.length !== unique.length)
|
|
13
|
+
throw new shell_1.Refusal('account-not-found', {}, 'an account was not found - reload and try again');
|
|
14
|
+
await (0, shell_1.refuseTiedRows)(tx, account_1.Account, unique);
|
|
15
|
+
await repo.softRemove(found);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=account-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-service.js","sourceRoot":"","sources":["../../../server/service/account/account-service.ts"],"names":[],"mappings":";;AAOA,wCAOC;AAdD,qCAA2C;AAE3C,iDAA+D;AAE/D,uCAAmC;AAEnC,yGAAyG;AAClG,KAAK,UAAU,cAAc,CAAC,EAAiB,EAAE,MAAsB,EAAE,GAAa;IAC3F,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAChC,MAAM,IAAI,GAAG,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;IACvF,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,eAAO,CAAC,mBAAmB,EAAE,EAAE,EAAE,iDAAiD,CAAC,CAAA;IACjI,MAAM,IAAA,sBAAc,EAAC,EAAE,EAAE,iBAAO,EAAE,MAAM,CAAC,CAAA;IACzC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Refusal, refuseTiedRows } from '@things-factory/shell'\n\nimport { Account } from './account'\n\n/** An account a line, a recurring item or another row still names is not deleted (§`refuseTiedRows`). */\nexport async function deleteAccounts(tx: EntityManager, domain: { id: string }, ids: string[]): Promise<void> {\n const unique = [...new Set(ids)]\n const repo = tx.getRepository(Account)\n const found = await repo.find({ where: { domain: { id: domain.id }, id: In(unique) } })\n if (found.length !== unique.length) throw new Refusal('account-not-found', {}, 'an account was not found - reload and try again')\n await refuseTiedRows(tx, Account, unique)\n await repo.softRemove(found)\n}\n"]}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { EntityManager } from 'typeorm';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* An account that lines were written on is made inactive, not deleted - the lines keep pointing at it, deleted ones
|
|
4
|
+
* too, since a deleted financial row stays readable. Whatever else names it stops the delete (§`refuseTiedRows`).
|
|
5
|
+
*/
|
|
3
6
|
export declare function deleteBankAccounts(tx: EntityManager, domain: {
|
|
4
7
|
id: string;
|
|
5
8
|
}, ids: string[]): Promise<void>;
|
|
@@ -5,7 +5,10 @@ const typeorm_1 = require("typeorm");
|
|
|
5
5
|
const shell_1 = require("@things-factory/shell");
|
|
6
6
|
const transaction_1 = require("../transaction/transaction");
|
|
7
7
|
const bank_account_1 = require("./bank-account");
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* An account that lines were written on is made inactive, not deleted - the lines keep pointing at it, deleted ones
|
|
10
|
+
* too, since a deleted financial row stays readable. Whatever else names it stops the delete (§`refuseTiedRows`).
|
|
11
|
+
*/
|
|
9
12
|
async function deleteBankAccounts(tx, domain, ids) {
|
|
10
13
|
const repo = tx.getRepository(bank_account_1.BankAccount);
|
|
11
14
|
const found = await repo.find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(ids) } });
|
|
@@ -16,6 +19,7 @@ async function deleteBankAccounts(tx, domain, ids) {
|
|
|
16
19
|
.count({ where: { domain: { id: domain.id }, bankAccount: { id: (0, typeorm_1.In)(ids) } }, withDeleted: true });
|
|
17
20
|
if (used)
|
|
18
21
|
throw new shell_1.Refusal('bank-account-has-transactions', {}, 'transactions were written on the account - make it inactive instead');
|
|
22
|
+
await (0, shell_1.refuseTiedRows)(tx, bank_account_1.BankAccount, ids);
|
|
19
23
|
await repo.softRemove(found);
|
|
20
24
|
}
|
|
21
25
|
//# sourceMappingURL=bank-account-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bank-account-service.js","sourceRoot":"","sources":["../../../server/service/bank-account/bank-account-service.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"bank-account-service.js","sourceRoot":"","sources":["../../../server/service/bank-account/bank-account-service.ts"],"names":[],"mappings":";;AAWA,gDAgBC;AA3BD,qCAA2C;AAE3C,iDAA+D;AAE/D,4DAAwD;AACxD,iDAA4C;AAE5C;;;GAGG;AACI,KAAK,UAAU,kBAAkB,CAAC,EAAiB,EAAE,MAAsB,EAAE,GAAa;IAC/F,MAAM,IAAI,GAAG,EAAE,CAAC,aAAa,CAAC,0BAAW,CAAC,CAAA;IAC1C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;IACpF,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI;QACpC,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,qDAAqD,CAAC,CAAA;IACxG,MAAM,IAAI,GAAG,MAAM,EAAE;SAClB,aAAa,CAAC,yBAAW,CAAC;SAC1B,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,GAAG,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IACnG,IAAI,IAAI;QACN,MAAM,IAAI,eAAO,CACf,+BAA+B,EAC/B,EAAE,EACF,qEAAqE,CACtE,CAAA;IACH,MAAM,IAAA,sBAAc,EAAC,EAAE,EAAE,0BAAW,EAAE,GAAG,CAAC,CAAA;IAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Refusal, refuseTiedRows } from '@things-factory/shell'\n\nimport { Transaction } from '../transaction/transaction'\nimport { BankAccount } from './bank-account'\n\n/**\n * An account that lines were written on is made inactive, not deleted - the lines keep pointing at it, deleted ones\n * too, since a deleted financial row stays readable. Whatever else names it stops the delete (§`refuseTiedRows`).\n */\nexport async function deleteBankAccounts(tx: EntityManager, domain: { id: string }, ids: string[]): Promise<void> {\n const repo = tx.getRepository(BankAccount)\n const found = await repo.find({ where: { domain: { id: domain.id }, id: In(ids) } })\n if (found.length !== new Set(ids).size)\n throw new Refusal('bank-account-not-found', {}, 'a bank account was not found - reload and try again')\n const used = await tx\n .getRepository(Transaction)\n .count({ where: { domain: { id: domain.id }, bankAccount: { id: In(ids) } }, withDeleted: true })\n if (used)\n throw new Refusal(\n 'bank-account-has-transactions',\n {},\n 'transactions were written on the account - make it inactive instead'\n )\n await refuseTiedRows(tx, BankAccount, ids)\n await repo.softRemove(found)\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Domain } from '@things-factory/shell';
|
|
2
2
|
import { User } from '@things-factory/auth-base';
|
|
3
3
|
import { TaxInvoice } from '@things-factory/tax-invoice';
|
|
4
|
+
import { Attachment } from '@things-factory/attachment-base';
|
|
4
5
|
import { Account } from '../account/account';
|
|
5
6
|
import { ExpenditureRequest } from './expenditure-request';
|
|
6
7
|
export declare enum ExpenditurePaymentMethod {
|
|
@@ -10,8 +11,8 @@ export declare enum ExpenditurePaymentMethod {
|
|
|
10
11
|
TRANSFER = "TRANSFER"
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
|
-
* One thing a request pays for - a meal, a taxi, a supplier's invoice.
|
|
14
|
-
* tax invoice it pays is cited, and then the bank line pays that invoice (ADR-0135 §2-5).
|
|
14
|
+
* One thing a request pays for - a meal, a taxi, a supplier's invoice. Its receipts and papers are attached to it by
|
|
15
|
+
* id; a purchase tax invoice it pays is cited, and then the bank line pays that invoice (ADR-0135 §2-5).
|
|
15
16
|
*/
|
|
16
17
|
export declare class ExpenditureRequestItem {
|
|
17
18
|
readonly id: string;
|
|
@@ -30,7 +31,7 @@ export declare class ExpenditureRequestItem {
|
|
|
30
31
|
paymentMethod: ExpenditurePaymentMethod;
|
|
31
32
|
taxInvoice?: TaxInvoice;
|
|
32
33
|
taxInvoiceId?: string;
|
|
33
|
-
|
|
34
|
+
files?: Attachment[];
|
|
34
35
|
createdAt?: Date;
|
|
35
36
|
updatedAt?: Date;
|
|
36
37
|
deletedAt?: Date;
|
|
@@ -7,6 +7,7 @@ const type_graphql_1 = require("type-graphql");
|
|
|
7
7
|
const shell_1 = require("@things-factory/shell");
|
|
8
8
|
const auth_base_1 = require("@things-factory/auth-base");
|
|
9
9
|
const tax_invoice_1 = require("@things-factory/tax-invoice");
|
|
10
|
+
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
10
11
|
const account_1 = require("../account/account");
|
|
11
12
|
const expenditure_request_1 = require("./expenditure-request");
|
|
12
13
|
var ExpenditurePaymentMethod;
|
|
@@ -21,8 +22,8 @@ var ExpenditurePaymentMethod;
|
|
|
21
22
|
description: 'How a line was paid - the corporate card is reported and approved, but the company already paid it'
|
|
22
23
|
});
|
|
23
24
|
/**
|
|
24
|
-
* One thing a request pays for - a meal, a taxi, a supplier's invoice.
|
|
25
|
-
* tax invoice it pays is cited, and then the bank line pays that invoice (ADR-0135 §2-5).
|
|
25
|
+
* One thing a request pays for - a meal, a taxi, a supplier's invoice. Its receipts and papers are attached to it by
|
|
26
|
+
* id; a purchase tax invoice it pays is cited, and then the bank line pays that invoice (ADR-0135 §2-5).
|
|
26
27
|
*/
|
|
27
28
|
let ExpenditureRequestItem = class ExpenditureRequestItem {
|
|
28
29
|
};
|
|
@@ -105,9 +106,9 @@ tslib_1.__decorate([
|
|
|
105
106
|
tslib_1.__metadata("design:type", String)
|
|
106
107
|
], ExpenditureRequestItem.prototype, "taxInvoiceId", void 0);
|
|
107
108
|
tslib_1.__decorate([
|
|
108
|
-
(0, type_graphql_1.Field)({ nullable: true, description: '
|
|
109
|
-
tslib_1.__metadata("design:type",
|
|
110
|
-
], ExpenditureRequestItem.prototype, "
|
|
109
|
+
(0, type_graphql_1.Field)(type => [attachment_base_1.Attachment], { nullable: true, description: 'The receipts and papers the line is proven by, the first attached first' }),
|
|
110
|
+
tslib_1.__metadata("design:type", Array)
|
|
111
|
+
], ExpenditureRequestItem.prototype, "files", void 0);
|
|
111
112
|
tslib_1.__decorate([
|
|
112
113
|
(0, typeorm_1.CreateDateColumn)(),
|
|
113
114
|
(0, type_graphql_1.Field)({ nullable: true, description: 'When it was written' }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expenditure-request-item.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/expenditure-request-item.ts"],"names":[],"mappings":";;;;AAAA,qCAUgB;AAChB,+CAAwF;AAExF,iDAA2D;AAC3D,yDAAgD;AAChD,6DAAwD;
|
|
1
|
+
{"version":3,"file":"expenditure-request-item.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/expenditure-request-item.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Column,\n CreateDateColumn,\n DeleteDateColumn,\n Entity,\n Index,\n ManyToOne,\n PrimaryGeneratedColumn,\n RelationId,\n UpdateDateColumn\n} from 'typeorm'\nimport { Directive, Field, Float, ID, ObjectType, registerEnumType } from 'type-graphql'\n\nimport { Domain, moneyColumn } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { TaxInvoice } from '@things-factory/tax-invoice'\nimport { Attachment } from '@things-factory/attachment-base'\n\nimport { Account } from '../account/account'\nimport { ExpenditureRequest } from './expenditure-request'\n\nexport enum ExpenditurePaymentMethod {\n PERSONAL_CARD = 'PERSONAL_CARD',\n CORPORATE_CARD = 'CORPORATE_CARD',\n CASH = 'CASH',\n TRANSFER = 'TRANSFER'\n}\n\nregisterEnumType(ExpenditurePaymentMethod, {\n name: 'ExpenditurePaymentMethod',\n description: 'How a line was paid - the corporate card is reported and approved, but the company already paid it'\n})\n\n/**\n * One thing a request pays for - a meal, a taxi, a supplier's invoice. Its receipts and papers are attached to it by\n * id; a purchase tax invoice it pays is cited, and then the bank line pays that invoice (ADR-0135 §2-5).\n */\n@Entity()\n@Index('ix_expenditure_request_item_0', (item: ExpenditureRequestItem) => [item.domain, item.request])\n@Index('ix_expenditure_request_item_1', (item: ExpenditureRequestItem) => [item.domain, item.taxInvoice])\n@ObjectType({ description: 'One thing an expenditure request pays for' })\nexport class ExpenditureRequestItem {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain it belongs to' })\n domain?: Domain\n\n @RelationId((item: ExpenditureRequestItem) => item.domain)\n domainId?: string\n\n @ManyToOne(type => ExpenditureRequest, request => request.items, { nullable: false, onDelete: 'CASCADE' })\n @Field(type => ExpenditureRequest, { nullable: true, description: 'The request the line is on' })\n request?: ExpenditureRequest\n\n @RelationId((item: ExpenditureRequestItem) => item.request)\n requestId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'YYYY-MM-DD it was spent, or the day of the invoice' })\n spentDate?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: \"What the requester called it - '식대', '교통비' - until an account is chosen\" })\n category?: string\n\n @ManyToOne(type => Account, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => Account, { nullable: true, description: '계정과목' })\n account?: Account\n\n @RelationId((item: ExpenditureRequestItem) => item.account)\n accountId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Where - the shop or company on the receipt' })\n merchant?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'What for - the purpose an approver judges' })\n description?: string\n\n @Column(moneyColumn())\n @Field(type => Float, { description: 'Amount paid, VAT included' })\n amount: number\n\n @Column(moneyColumn({ nullable: true, default: null }))\n @Field(type => Float, { nullable: true, description: 'VAT in the amount, when the receipt shows it' })\n vatAmount?: number\n\n @Column({ default: ExpenditurePaymentMethod.PERSONAL_CARD })\n @Field(type => ExpenditurePaymentMethod, { description: 'How it was paid' })\n paymentMethod: ExpenditurePaymentMethod\n\n /* The tax-invoice ledger's row (ADR-0139): a requester without it sees the line, and FORBIDDEN on this path. */\n @ManyToOne(type => TaxInvoice, { nullable: true })\n @Directive('@privilege(category: \"tax-invoice\", privilege: \"query\", domainOwnerGranted: false)')\n @Field(type => TaxInvoice, { nullable: true, description: 'The purchase tax invoice this line pays' })\n taxInvoice?: TaxInvoice\n\n @RelationId((item: ExpenditureRequestItem) => item.taxInvoice)\n taxInvoiceId?: string\n\n @Field(type => [Attachment], { nullable: true, description: 'The receipts and papers the line is proven by, the first attached first' })\n files?: Attachment[]\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When it was written' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When it was last changed' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When it was deleted - financial rows are kept, not erased' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who wrote it' })\n creator?: User\n\n @RelationId((item: ExpenditureRequestItem) => item.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who changed it last' })\n updater?: User\n\n @RelationId((item: ExpenditureRequestItem) => item.updater)\n updaterId?: string\n}\n"]}
|
|
@@ -7,7 +7,7 @@ export declare class ExpenditureRequestMutation {
|
|
|
7
7
|
saveExpenditureRequest(request: ExpenditureRequestInput, items: ExpenditureRequestItemPatch[], context: ResolverContext): Promise<ExpenditureRequest>;
|
|
8
8
|
/** One line from the phone - it joins this month's editable reimbursement, or starts one. */
|
|
9
9
|
addExpenditureLine(line: NewExpenditureLine, context: ResolverContext): Promise<ExpenditureRequest>;
|
|
10
|
-
|
|
10
|
+
saveExpenditureLineFiles(itemId: string, attach: FileUpload[], remove: string[], context: ResolverContext): Promise<ExpenditureRequestItem>;
|
|
11
11
|
submitExpenditureRequest(id: string, context: ResolverContext): Promise<ExpenditureRequest>;
|
|
12
12
|
withdrawExpenditureRequest(id: string, context: ResolverContext): Promise<ExpenditureRequest>;
|
|
13
13
|
deleteExpenditureRequest(id: string, context: ResolverContext): Promise<boolean>;
|
|
@@ -22,9 +22,9 @@ let ExpenditureRequestMutation = class ExpenditureRequestMutation {
|
|
|
22
22
|
const { domain, user, tx } = context.state;
|
|
23
23
|
return await (0, expenditure_request_service_1.addLine)(tx, domain, user, line, context);
|
|
24
24
|
}
|
|
25
|
-
async
|
|
25
|
+
async saveExpenditureLineFiles(itemId, attach, remove, context) {
|
|
26
26
|
const { domain, user, tx } = context.state;
|
|
27
|
-
return await (0, expenditure_request_service_1.
|
|
27
|
+
return await (0, expenditure_request_service_1.saveLineFiles)(tx, domain, user, itemId, { attach: attach ?? [], remove: remove ?? [] }, context);
|
|
28
28
|
}
|
|
29
29
|
async submitExpenditureRequest(id, context) {
|
|
30
30
|
const { domain, user, tx } = context.state;
|
|
@@ -74,14 +74,15 @@ tslib_1.__decorate([
|
|
|
74
74
|
tslib_1.__decorate([
|
|
75
75
|
(0, type_graphql_1.Directive)('@transaction'),
|
|
76
76
|
(0, type_graphql_1.Directive)('@privilege(category: "accounting-self", privilege: "mutation", domainOwnerGranted: true)'),
|
|
77
|
-
(0, type_graphql_1.Mutation)(returns => expenditure_request_item_1.ExpenditureRequestItem, { description:
|
|
77
|
+
(0, type_graphql_1.Mutation)(returns => expenditure_request_item_1.ExpenditureRequestItem, { description: "Attach files to a line and take others off it - the line's receipts and papers" }),
|
|
78
78
|
tslib_1.__param(0, (0, type_graphql_1.Arg)('itemId')),
|
|
79
|
-
tslib_1.__param(1, (0, type_graphql_1.Arg)('
|
|
80
|
-
tslib_1.__param(2, (0, type_graphql_1.
|
|
79
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('attach', type => [GraphQLUpload_js_1.default], { nullable: true })),
|
|
80
|
+
tslib_1.__param(2, (0, type_graphql_1.Arg)('remove', type => [String], { nullable: true })),
|
|
81
|
+
tslib_1.__param(3, (0, type_graphql_1.Ctx)()),
|
|
81
82
|
tslib_1.__metadata("design:type", Function),
|
|
82
|
-
tslib_1.__metadata("design:paramtypes", [String,
|
|
83
|
+
tslib_1.__metadata("design:paramtypes", [String, Array, Array, Object]),
|
|
83
84
|
tslib_1.__metadata("design:returntype", Promise)
|
|
84
|
-
], ExpenditureRequestMutation.prototype, "
|
|
85
|
+
], ExpenditureRequestMutation.prototype, "saveExpenditureLineFiles", null);
|
|
85
86
|
tslib_1.__decorate([
|
|
86
87
|
(0, type_graphql_1.Directive)('@transaction'),
|
|
87
88
|
(0, type_graphql_1.Directive)('@privilege(category: "accounting-self", privilege: "mutation", domainOwnerGranted: true)'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expenditure-request-mutation.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/expenditure-request-mutation.ts"],"names":[],"mappings":";;;;AAAA,+CAA4F;AAG5F,+FAA2D;AAE3D,yDAA2D;AAC3D,iDAAqD;AAErD,+DAA0D;AAC1D,yEAAmE;AACnE,+EAA6J;AAC7J,yEAA8I;AAIvI,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IACrC,0HAA0H;IAIpH,AAAN,KAAK,CAAC,sBAAsB,CACuB,OAAgC,EACR,KAAoC,EACtG,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1E,MAAM,WAAW,GAAG,MAAM,IAAA,2BAAe,EAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAA;QACtJ,OAAO,MAAM,IAAA,yCAAW,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;IACnF,CAAC;IAED,6FAA6F;IAIvF,AAAN,KAAK,CAAC,kBAAkB,CAA0C,IAAwB,EAAS,OAAwB;QACzH,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,qCAAO,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACvD,CAAC;IAKK,AAAN,KAAK,CAAC,wBAAwB,CACb,MAAc,EACO,IAAgB,EAC7C,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,4CAAc,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACtE,CAAC;IAKK,AAAN,KAAK,CAAC,wBAAwB,CAAY,EAAU,EAAS,OAAwB;QACnF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,2CAAa,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;IAC3D,CAAC;IAKK,AAAN,KAAK,CAAC,0BAA0B,CAAY,EAAU,EAAS,OAAwB;QACrF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,6CAAe,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;IAC7D,CAAC;IAKK,AAAN,KAAK,CAAC,wBAAwB,CAAY,EAAU,EAAS,OAAwB;QACnF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,2CAAa,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,oHAAoH;IAI9G,AAAN,KAAK,CAAC,sBAAsB,CACI,GAAa,EACM,OAAgC,EAC1E,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,yCAAW,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IAC1D,CAAC;IAED,mGAAmG;IAI7F,AAAN,KAAK,CAAC,6BAA6B,CACtB,EAAU,EACC,aAAqB,EACO,MAAc,EACzD,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,yCAAW,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,CAAA;IACvE,CAAC;CACF,CAAA;AAtFY,gEAA0B;AAK/B;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;IAEnG,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,kDAAuB,CAAC,CAAA;IAC/C,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,sDAA2B,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IACvE,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAFoD,kDAAuB;;wEAOlF;AAMK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,kEAAkE,EAAE,CAAC;IACnG,mBAAA,IAAA,kBAAG,EAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,6CAAkB,CAAC,CAAA;IAA4B,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAA1B,6CAAkB;;oEAGzF;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,iDAAsB,EAAE,EAAE,WAAW,EAAE,wCAAwC,EAAE,CAAC;IAEpG,mBAAA,IAAA,kBAAG,EAAC,QAAQ,CAAC,CAAA;IACb,mBAAA,IAAA,kBAAG,EAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,0BAAa,CAAC,CAAA;IAClC,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0EAIP;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;IAC5E,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0EAG3D;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,uDAAuD,EAAE,CAAC;IAChF,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;4EAG7D;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC;IACtE,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0EAG3D;AAMK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,sFAAsF,CAAC;IACjG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,wCAAkB,CAAC,EAAE,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;IAE/G,mBAAA,IAAA,kBAAG,EAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,kDAAuB,CAAC,CAAA;IAC/C,mBAAA,IAAA,kBAAG,GAAE,CAAA;;oDADoD,kDAAuB;;wEAKlF;AAMK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,sFAAsF,CAAC;IACjG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,0EAA0E,EAAE,CAAC;IAElI,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IACT,mBAAA,IAAA,kBAAG,EAAC,eAAe,CAAC,CAAA;IACpB,mBAAA,IAAA,kBAAG,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAChD,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;+EAIP;qCArFU,0BAA0B;IAFtC,IAAA,4BAAa,EAAC,qBAAa,CAAC;IAC5B,IAAA,uBAAQ,EAAC,wCAAkB,CAAC;GAChB,0BAA0B,CAsFtC","sourcesContent":["import { Arg, Ctx, Directive, Float, Mutation, Resolver, UseMiddleware } from 'type-graphql'\n\nimport type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\n\nimport { checkPermission } from '@things-factory/auth-base'\nimport { SpeakRefusals } from '@things-factory/shell'\n\nimport { ExpenditureRequest } from './expenditure-request'\nimport { ExpenditureRequestItem } from './expenditure-request-item'\nimport { addLine, deleteRequest, payRequests, payWithLine, replaceReceipt, saveRequest, submitRequest, withdrawRequest } from './expenditure-request-service'\nimport { ExpenditurePaymentInput, ExpenditureRequestInput, ExpenditureRequestItemPatch, NewExpenditureLine } from './expenditure-request-type'\n\n@UseMiddleware(SpeakRefusals)\n@Resolver(ExpenditureRequest)\nexport class ExpenditureRequestMutation {\n /** Write a request and its lines. A new request is the caller's; an existing one only its requester's, while editable. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Save an expenditure request and its lines' })\n async saveExpenditureRequest(\n @Arg('request', type => ExpenditureRequestInput) request: ExpenditureRequestInput,\n @Arg('items', type => [ExpenditureRequestItemPatch], { nullable: true }) items: ExpenditureRequestItemPatch[],\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequest> {\n const { domain, user, tx, unsafeIP, prohibitedPrivileges } = context.state\n const taxInvoices = await checkPermission({ category: 'tax-invoice', privilege: 'query', owner: false }, user, domain, unsafeIP, prohibitedPrivileges)\n return await saveRequest(tx, domain, user, request, items ?? [], { taxInvoices })\n }\n\n /** One line from the phone - it joins this month's editable reimbursement, or starts one. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: \"Add one expense line to the caller's reimbursement of that month\" })\n async addExpenditureLine(@Arg('line', type => NewExpenditureLine) line: NewExpenditureLine, @Ctx() context: ResolverContext): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await addLine(tx, domain, user, line, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequestItem, { description: 'Put (or replace) the receipt of a line' })\n async attachExpenditureReceipt(\n @Arg('itemId') itemId: string,\n @Arg('file', type => GraphQLUpload) file: FileUpload,\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequestItem> {\n const { domain, user, tx } = context.state\n return await replaceReceipt(tx, domain, user, itemId, file, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Put an expenditure request up for approval (상신)' })\n async submitExpenditureRequest(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await submitRequest(tx, domain, user, id, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Take a submitted request back from its approvers (회수)' })\n async withdrawExpenditureRequest(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await withdrawRequest(tx, domain, user, id, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete an editable expenditure request of the caller' })\n async deleteExpenditureRequest(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, user, tx } = context.state\n return await deleteRequest(tx, domain, user, id)\n }\n\n /** Finance paid approved requests at the bank; each becomes a withdrawal that the next statement import matches. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"expenditure\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [ExpenditureRequest], { description: 'Record that approved expenditure requests were paid' })\n async payExpenditureRequests(\n @Arg('ids', type => [String]) ids: string[],\n @Arg('payment', type => ExpenditurePaymentInput) payment: ExpenditurePaymentInput,\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequest[]> {\n const { domain, user, tx } = context.state\n return await payRequests(tx, domain, user, ids, payment)\n }\n\n /** Pay a request with a withdrawal already in the books - a bank statement brought it in first. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"expenditure\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Put a withdrawal already in the books on an approved expenditure request' })\n async payExpenditureRequestWithLine(\n @Arg('id') id: string,\n @Arg('transactionId') transactionId: string,\n @Arg('amount', type => Float, { nullable: true }) amount: number,\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await payWithLine(tx, domain, user, id, transactionId, amount)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"expenditure-request-mutation.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/expenditure-request-mutation.ts"],"names":[],"mappings":";;;;AAAA,+CAA4F;AAG5F,+FAA2D;AAE3D,yDAA2D;AAC3D,iDAAqD;AAErD,+DAA0D;AAC1D,yEAAmE;AACnE,+EAA4J;AAC5J,yEAA8I;AAIvI,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IACrC,0HAA0H;IAIpH,AAAN,KAAK,CAAC,sBAAsB,CACuB,OAAgC,EACR,KAAoC,EACtG,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1E,MAAM,WAAW,GAAG,MAAM,IAAA,2BAAe,EAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAA;QACtJ,OAAO,MAAM,IAAA,yCAAW,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;IACnF,CAAC;IAED,6FAA6F;IAIvF,AAAN,KAAK,CAAC,kBAAkB,CAA0C,IAAwB,EAAS,OAAwB;QACzH,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,qCAAO,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACvD,CAAC;IAKK,AAAN,KAAK,CAAC,wBAAwB,CACb,MAAc,EAC+B,MAAoB,EAC3B,MAAgB,EAC9D,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,2CAAa,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;IAC/G,CAAC;IAKK,AAAN,KAAK,CAAC,wBAAwB,CAAY,EAAU,EAAS,OAAwB;QACnF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,2CAAa,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;IAC3D,CAAC;IAKK,AAAN,KAAK,CAAC,0BAA0B,CAAY,EAAU,EAAS,OAAwB;QACrF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,6CAAe,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;IAC7D,CAAC;IAKK,AAAN,KAAK,CAAC,wBAAwB,CAAY,EAAU,EAAS,OAAwB;QACnF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,2CAAa,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,oHAAoH;IAI9G,AAAN,KAAK,CAAC,sBAAsB,CACI,GAAa,EACM,OAAgC,EAC1E,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,yCAAW,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IAC1D,CAAC;IAED,mGAAmG;IAI7F,AAAN,KAAK,CAAC,6BAA6B,CACtB,EAAU,EACC,aAAqB,EACO,MAAc,EACzD,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,OAAO,MAAM,IAAA,yCAAW,EAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,CAAA;IACvE,CAAC;CACF,CAAA;AAvFY,gEAA0B;AAK/B;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;IAEnG,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,kDAAuB,CAAC,CAAA;IAC/C,mBAAA,IAAA,kBAAG,EAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,sDAA2B,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IACvE,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAFoD,kDAAuB;;wEAOlF;AAMK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,kEAAkE,EAAE,CAAC;IACnG,mBAAA,IAAA,kBAAG,EAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,6CAAkB,CAAC,CAAA;IAA4B,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAA1B,6CAAkB;;oEAGzF;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,iDAAsB,EAAE,EAAE,WAAW,EAAE,gFAAgF,EAAE,CAAC;IAE5I,mBAAA,IAAA,kBAAG,EAAC,QAAQ,CAAC,CAAA;IACb,mBAAA,IAAA,kBAAG,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,0BAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1D,mBAAA,IAAA,kBAAG,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0EAIP;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;IAC5E,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0EAG3D;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,uDAAuD,EAAE,CAAC;IAChF,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;4EAG7D;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,0FAA0F,CAAC;IACrG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC;IACtE,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0EAG3D;AAMK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,sFAAsF,CAAC;IACjG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,wCAAkB,CAAC,EAAE,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;IAE/G,mBAAA,IAAA,kBAAG,EAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,kDAAuB,CAAC,CAAA;IAC/C,mBAAA,IAAA,kBAAG,GAAE,CAAA;;oDADoD,kDAAuB;;wEAKlF;AAMK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,sFAAsF,CAAC;IACjG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,0EAA0E,EAAE,CAAC;IAElI,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IACT,mBAAA,IAAA,kBAAG,EAAC,eAAe,CAAC,CAAA;IACpB,mBAAA,IAAA,kBAAG,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAChD,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;+EAIP;qCAtFU,0BAA0B;IAFtC,IAAA,4BAAa,EAAC,qBAAa,CAAC;IAC5B,IAAA,uBAAQ,EAAC,wCAAkB,CAAC;GAChB,0BAA0B,CAuFtC","sourcesContent":["import { Arg, Ctx, Directive, Float, Mutation, Resolver, UseMiddleware } from 'type-graphql'\n\nimport type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\n\nimport { checkPermission } from '@things-factory/auth-base'\nimport { SpeakRefusals } from '@things-factory/shell'\n\nimport { ExpenditureRequest } from './expenditure-request'\nimport { ExpenditureRequestItem } from './expenditure-request-item'\nimport { addLine, deleteRequest, payRequests, payWithLine, saveLineFiles, saveRequest, submitRequest, withdrawRequest } from './expenditure-request-service'\nimport { ExpenditurePaymentInput, ExpenditureRequestInput, ExpenditureRequestItemPatch, NewExpenditureLine } from './expenditure-request-type'\n\n@UseMiddleware(SpeakRefusals)\n@Resolver(ExpenditureRequest)\nexport class ExpenditureRequestMutation {\n /** Write a request and its lines. A new request is the caller's; an existing one only its requester's, while editable. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Save an expenditure request and its lines' })\n async saveExpenditureRequest(\n @Arg('request', type => ExpenditureRequestInput) request: ExpenditureRequestInput,\n @Arg('items', type => [ExpenditureRequestItemPatch], { nullable: true }) items: ExpenditureRequestItemPatch[],\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequest> {\n const { domain, user, tx, unsafeIP, prohibitedPrivileges } = context.state\n const taxInvoices = await checkPermission({ category: 'tax-invoice', privilege: 'query', owner: false }, user, domain, unsafeIP, prohibitedPrivileges)\n return await saveRequest(tx, domain, user, request, items ?? [], { taxInvoices })\n }\n\n /** One line from the phone - it joins this month's editable reimbursement, or starts one. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: \"Add one expense line to the caller's reimbursement of that month\" })\n async addExpenditureLine(@Arg('line', type => NewExpenditureLine) line: NewExpenditureLine, @Ctx() context: ResolverContext): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await addLine(tx, domain, user, line, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequestItem, { description: \"Attach files to a line and take others off it - the line's receipts and papers\" })\n async saveExpenditureLineFiles(\n @Arg('itemId') itemId: string,\n @Arg('attach', type => [GraphQLUpload], { nullable: true }) attach: FileUpload[],\n @Arg('remove', type => [String], { nullable: true }) remove: string[],\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequestItem> {\n const { domain, user, tx } = context.state\n return await saveLineFiles(tx, domain, user, itemId, { attach: attach ?? [], remove: remove ?? [] }, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Put an expenditure request up for approval (상신)' })\n async submitExpenditureRequest(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await submitRequest(tx, domain, user, id, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Take a submitted request back from its approvers (회수)' })\n async withdrawExpenditureRequest(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await withdrawRequest(tx, domain, user, id, context)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"accounting-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'Delete an editable expenditure request of the caller' })\n async deleteExpenditureRequest(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, user, tx } = context.state\n return await deleteRequest(tx, domain, user, id)\n }\n\n /** Finance paid approved requests at the bank; each becomes a withdrawal that the next statement import matches. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"expenditure\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [ExpenditureRequest], { description: 'Record that approved expenditure requests were paid' })\n async payExpenditureRequests(\n @Arg('ids', type => [String]) ids: string[],\n @Arg('payment', type => ExpenditurePaymentInput) payment: ExpenditurePaymentInput,\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequest[]> {\n const { domain, user, tx } = context.state\n return await payRequests(tx, domain, user, ids, payment)\n }\n\n /** Pay a request with a withdrawal already in the books - a bank statement brought it in first. */\n @Directive('@transaction')\n @Directive('@privilege(category: \"expenditure\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ExpenditureRequest, { description: 'Put a withdrawal already in the books on an approved expenditure request' })\n async payExpenditureRequestWithLine(\n @Arg('id') id: string,\n @Arg('transactionId') transactionId: string,\n @Arg('amount', type => Float, { nullable: true }) amount: number,\n @Ctx() context: ResolverContext\n ): Promise<ExpenditureRequest> {\n const { domain, user, tx } = context.state\n return await payWithLine(tx, domain, user, id, transactionId, amount)\n }\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Domain, ListParam } from '@things-factory/shell';
|
|
2
2
|
import { User } from '@things-factory/auth-base';
|
|
3
|
+
import { Attachment } from '@things-factory/attachment-base';
|
|
3
4
|
import { Counterparty, CounterpartyBankAccount } from '@things-factory/biz-base';
|
|
4
5
|
import { Department } from '@things-factory/organization';
|
|
5
6
|
import { TaxInvoice } from '@things-factory/tax-invoice';
|
|
@@ -17,6 +18,12 @@ export declare class ExpenditureRequestQuery {
|
|
|
17
18
|
/** Every request of the domain - what finance sees. */
|
|
18
19
|
expenditureRequests(params: ListParam, context: ResolverContext): Promise<ExpenditureRequestList>;
|
|
19
20
|
expenditureRequest(id: string, context: ResolverContext): Promise<ExpenditureRequest | null>;
|
|
21
|
+
/**
|
|
22
|
+
* One request as its approvers read it - the lines and their files. Open to whoever may open those files: its writer,
|
|
23
|
+
* whoever takes part in its approval, and the paying seat (§`receipt-reader.ts`). The approval card links to it.
|
|
24
|
+
* Anyone else is refused as the paying seat's door refuses them, so the 360 says 「볼 수 없음」, not 「없음」.
|
|
25
|
+
*/
|
|
26
|
+
expenditureRequestForReview(id: string, context: ResolverContext): Promise<ExpenditureRequest | null>;
|
|
20
27
|
/**
|
|
21
28
|
* The payment queue (지급 대기) - approved requests still to pay, by the day they are to be paid, and the paid ones
|
|
22
29
|
* whose bank line no statement has matched yet.
|
|
@@ -40,8 +47,8 @@ export declare class ExpenditureRequestItemQuery {
|
|
|
40
47
|
request(item: ExpenditureRequestItem): Promise<ExpenditureRequest | null>;
|
|
41
48
|
account(item: ExpenditureRequestItem): Promise<Account | null>;
|
|
42
49
|
taxInvoice(item: ExpenditureRequestItem): Promise<TaxInvoice | null>;
|
|
43
|
-
/**
|
|
44
|
-
|
|
50
|
+
/** The line's receipts and papers - so an approver sees what was spent. */
|
|
51
|
+
files(item: ExpenditureRequestItem): Promise<Attachment[]>;
|
|
45
52
|
domain(item: ExpenditureRequestItem): Promise<Domain>;
|
|
46
53
|
creator(item: ExpenditureRequestItem): Promise<User | null>;
|
|
47
54
|
updater(item: ExpenditureRequestItem): Promise<User | null>;
|
|
@@ -16,6 +16,7 @@ const expenditure_request_item_1 = require("./expenditure-request-item");
|
|
|
16
16
|
const expenditure_payment_state_1 = require("./expenditure-payment-state");
|
|
17
17
|
const expenditure_request_rules_1 = require("./expenditure-request-rules");
|
|
18
18
|
const expenditure_request_service_1 = require("./expenditure-request-service");
|
|
19
|
+
const receipt_reader_1 = require("./receipt-reader");
|
|
19
20
|
const expenditure_request_type_1 = require("./expenditure-request-type");
|
|
20
21
|
const byId = async (entity, id, withDeleted = false) => id ? (await (0, shell_1.getRepository)(entity).findOne({ where: { id }, withDeleted })) : null;
|
|
21
22
|
async function summaryOf(domain, year, month, requesterId) {
|
|
@@ -82,6 +83,19 @@ let ExpenditureRequestQuery = class ExpenditureRequestQuery {
|
|
|
82
83
|
async expenditureRequest(id, context) {
|
|
83
84
|
return await (0, shell_1.getRepository)(expenditure_request_1.ExpenditureRequest).findOne({ where: { id, domain: { id: context.state.domain.id } } });
|
|
84
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* One request as its approvers read it - the lines and their files. Open to whoever may open those files: its writer,
|
|
88
|
+
* whoever takes part in its approval, and the paying seat (§`receipt-reader.ts`). The approval card links to it.
|
|
89
|
+
* Anyone else is refused as the paying seat's door refuses them, so the 360 says 「볼 수 없음」, not 「없음」.
|
|
90
|
+
*/
|
|
91
|
+
async expenditureRequestForReview(id, context) {
|
|
92
|
+
const request = await (0, shell_1.getRepository)(expenditure_request_1.ExpenditureRequest).findOne({ where: { id, domain: { id: context.state.domain.id } } });
|
|
93
|
+
if (!request)
|
|
94
|
+
return null;
|
|
95
|
+
if (!(await (0, receipt_reader_1.mayReadRequest)(request, context, receipt_reader_1.REQUEST_READ_FACTS)))
|
|
96
|
+
throw (0, auth_base_1.privilegeRejection)(context, 'expenditure', 'query', 'role', 'query');
|
|
97
|
+
return request;
|
|
98
|
+
}
|
|
85
99
|
/**
|
|
86
100
|
* The payment queue (지급 대기) - approved requests still to pay, by the day they are to be paid, and the paid ones
|
|
87
101
|
* whose bank line no statement has matched yet.
|
|
@@ -197,6 +211,15 @@ tslib_1.__decorate([
|
|
|
197
211
|
tslib_1.__metadata("design:paramtypes", [String, Object]),
|
|
198
212
|
tslib_1.__metadata("design:returntype", Promise)
|
|
199
213
|
], ExpenditureRequestQuery.prototype, "expenditureRequest", null);
|
|
214
|
+
tslib_1.__decorate([
|
|
215
|
+
(0, type_graphql_1.Directive)('@privilege(category: "accounting-self", privilege: "query", domainOwnerGranted: true)'),
|
|
216
|
+
(0, type_graphql_1.Query)(returns => expenditure_request_1.ExpenditureRequest, { nullable: true, description: 'One expenditure request, for its writer, its approvers and the paying seat' }),
|
|
217
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
|
|
218
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
219
|
+
tslib_1.__metadata("design:type", Function),
|
|
220
|
+
tslib_1.__metadata("design:paramtypes", [String, Object]),
|
|
221
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
222
|
+
], ExpenditureRequestQuery.prototype, "expenditureRequestForReview", null);
|
|
200
223
|
tslib_1.__decorate([
|
|
201
224
|
(0, type_graphql_1.Directive)('@privilege(category: "expenditure", privilege: "query", domainOwnerGranted: true)'),
|
|
202
225
|
(0, type_graphql_1.Query)(returns => expenditure_request_type_1.ExpenditureQueue, { description: 'Approved requests still to pay, and paid ones not yet matched to the bank' }),
|
|
@@ -309,10 +332,9 @@ let ExpenditureRequestItemQuery = class ExpenditureRequestItemQuery {
|
|
|
309
332
|
async taxInvoice(item) {
|
|
310
333
|
return item.taxInvoice ?? (await byId(tax_invoice_1.TaxInvoice, item.taxInvoiceId, true));
|
|
311
334
|
}
|
|
312
|
-
/**
|
|
313
|
-
async
|
|
314
|
-
|
|
315
|
-
return attachment?.fullpath ?? null;
|
|
335
|
+
/** The line's receipts and papers - so an approver sees what was spent. */
|
|
336
|
+
async files(item) {
|
|
337
|
+
return await (0, shell_1.getRepository)(attachment_base_1.Attachment).find({ where: { domain: { id: item.domainId }, refType: expenditure_request_service_1.RECEIPT_REF_TYPE, refBy: item.id }, order: { createdAt: 'ASC' } });
|
|
316
338
|
}
|
|
317
339
|
async domain(item) {
|
|
318
340
|
return await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: item.domainId });
|
|
@@ -347,12 +369,12 @@ tslib_1.__decorate([
|
|
|
347
369
|
tslib_1.__metadata("design:returntype", Promise)
|
|
348
370
|
], ExpenditureRequestItemQuery.prototype, "taxInvoice", null);
|
|
349
371
|
tslib_1.__decorate([
|
|
350
|
-
(0, type_graphql_1.FieldResolver)(type =>
|
|
372
|
+
(0, type_graphql_1.FieldResolver)(type => [attachment_base_1.Attachment]),
|
|
351
373
|
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
352
374
|
tslib_1.__metadata("design:type", Function),
|
|
353
375
|
tslib_1.__metadata("design:paramtypes", [expenditure_request_item_1.ExpenditureRequestItem]),
|
|
354
376
|
tslib_1.__metadata("design:returntype", Promise)
|
|
355
|
-
], ExpenditureRequestItemQuery.prototype, "
|
|
377
|
+
], ExpenditureRequestItemQuery.prototype, "files", null);
|
|
356
378
|
tslib_1.__decorate([
|
|
357
379
|
(0, type_graphql_1.FieldResolver)(type => shell_1.Domain),
|
|
358
380
|
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|