@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expenditure-request-type.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/expenditure-request-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, Float, ID, InputType, Int, ObjectType } from 'type-graphql'\n\nimport type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\n\nimport { ObjectRef } from '@things-factory/shell'\n\nimport { ExpenditureKind, ExpenditureRequest } from './expenditure-request'\nimport { ExpenditurePaymentMethod } from './expenditure-request-item'\nimport { ExpenditurePaymentState } from './expenditure-payment-state'\n\n@InputType({ description: 'The head of an expenditure request - the lines are sent beside it' })\nexport class ExpenditureRequestInput {\n @Field(type => ID, { nullable: true, description: 'Empty for a new request' })\n id?: string\n\n @Field(type => ExpenditureKind, { nullable: true, description: 'Required for a new request; a request keeps its kind' })\n kind?: ExpenditureKind\n\n @Field({ nullable: true, description: \"Defaults to '<month> 경비', or '<counterparty> 지급'\" })\n title?: string\n\n @Field({ nullable: true, description: 'YYYY-MM a reimbursement belongs to' })\n month?: string\n\n @Field({ nullable: true, description: 'YYYY-MM-DD it is to be paid' })\n dueDate?: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Who is paid, for a counterparty payment' })\n counterparty?: ObjectRef\n\n @Field(type => ObjectRef, { nullable: true, description: \"The counterparty's account to pay into\" })\n payeeAccount?: ObjectRef\n\n @Field({ nullable: true, description: 'Notes' })\n notes?: string\n}\n\n@InputType({ description: 'A line of an expenditure request to add, change or delete' })\nexport class ExpenditureRequestItemPatch {\n @Field(type => ID, { nullable: true, description: 'The line to change or delete' })\n id?: string\n\n @Field({ nullable: true, description: 'YYYY-MM-DD' })\n spentDate?: string\n\n @Field({ nullable: true, description: \"What the requester calls it - '식대', '교통비'\" })\n category?: string\n\n @Field(type => ObjectRef, { nullable: true, description: '계정과목 - found from the category or description when not given' })\n account?: ObjectRef\n\n @Field({ nullable: true, description: 'Where - the shop or company on the receipt' })\n merchant?: string\n\n @Field({ nullable: true, description: 'What for' })\n description?: string\n\n @Field(type => Float, { nullable: true, description: 'Amount, VAT included' })\n amount?: number\n\n @Field(type => Float, { nullable: true, description: 'VAT in the amount' })\n vatAmount?: number\n\n @Field(type => ExpenditurePaymentMethod, { nullable: true, description: 'How it was paid' })\n paymentMethod?: ExpenditurePaymentMethod\n\n @Field(type => ObjectRef, { nullable: true, description: 'The purchase tax invoice this line pays' })\n taxInvoice?: ObjectRef\n\n @Field({ nullable: true, description: \"Grid batch flag: '+' add, 'M' modify, '-' delete\" })\n cuFlag?: string\n}\n\n@InputType({ description: 'One expense added on the go - it joins the month’s editable reimbursement' })\nexport class NewExpenditureLine {\n @Field({ description: 'YYYY-MM-DD; the month is taken from it unless month is given' })\n spentDate: string\n\n @Field({ nullable: true, description: 'YYYY-MM - to file a late receipt under another month' })\n month?: string\n\n @Field({ description: \"What it was - '식대', '교통비'\" })\n category: string\n\n @Field(type => Float, { description: 'Amount, VAT included' })\n amount: number\n\n @Field(type => ObjectRef, { nullable: true, description: '계정과목 - found from the category or description when not given' })\n account?: ObjectRef\n\n @Field({ nullable: true, description: 'Where' })\n merchant?: string\n\n @Field({ nullable: true, description: 'What for' })\n description?: string\n\n @Field(type => Float, { nullable: true, description: 'VAT in the amount' })\n vatAmount?: number\n\n @Field(type => ExpenditurePaymentMethod, { nullable: true, description: 'How it was paid' })\n paymentMethod?: ExpenditurePaymentMethod\n\n @Field(type => GraphQLUpload, { nullable: true, description: 'Photo of the receipt' })\n receipt?: FileUpload\n}\n\n@InputType({ description: 'How approved requests were paid at the bank' })\nexport class ExpenditurePaymentInput {\n @Field({ description: 'YYYY-MM-DD the money went out' })\n paidDate: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Our account it went out of' })\n bankAccount?: ObjectRef\n}\n\n@ObjectType({ description: 'A page of expenditure requests' })\nexport class ExpenditureRequestList {\n @Field(type => [ExpenditureRequest], { description: 'The requests on this page' })\n items: ExpenditureRequest[]\n\n @Field(type => Int, { description: 'How many there are in all' })\n total: number\n}\n\n@ObjectType({ description: 'How far an expenditure request is paid, read from the bank lines that paid it' })\nexport class ExpenditurePayment {\n @Field(type => ExpenditurePaymentState, { description: 'Nothing to pay, unpaid, partly or fully paid' })\n state: ExpenditurePaymentState\n\n @Field(type => Float, { description: 'What the company is to pay' })\n payable: number\n\n @Field(type => Float, { description: 'What bank lines paid of it' })\n paid: number\n\n @Field(type => Float, { description: 'What is still to pay' })\n outstanding: number\n\n @Field({ description: 'Every bank line that paid it was matched to the bank statement' })\n reconciled: boolean\n\n @Field(type => [String], { description: 'The bank lines that paid it' })\n transactionIds: string[]\n}\n\n@ObjectType({ description: 'An approved request in the payment queue' })\nexport class ExpenditureQueueRow {\n @Field(type => ExpenditureRequest, { description: 'The request' })\n request: ExpenditureRequest\n\n @Field(type => ExpenditurePayment, { description: 'How far it is paid' })\n payment: ExpenditurePayment\n\n @Field({ nullable: true, description: 'Who is paid - the counterparty, or the employee paid back' })\n payeeName?: string\n\n @Field({\n nullable: true,\n description: \"'gone' or 'changed' when the account approvers saw is no longer on file as it was, 'missing' when none was written\"\n })\n payeeAccountDrift?: string\n}\n\n@ObjectType({ description: 'The payment queue - what is approved and still to pay, and what was paid but not yet matched to the bank' })\nexport class ExpenditureQueue {\n @Field(type => [ExpenditureQueueRow], { description: 'Approved and not fully paid, by the day it is to be paid' })\n waiting: ExpenditureQueueRow[]\n\n @Field(type => [ExpenditureQueueRow], { description: 'Paid, with a bank line not yet matched to a statement' })\n unreconciled: ExpenditureQueueRow[]\n}\n\n@ObjectType({ description: 'Approved spending of one month, one requester, one category' })\nexport class ExpenditureSummaryRow {\n @Field({ description: 'YYYY-MM' })\n month: string\n\n @Field(type => ID, { description: 'Who requested' })\n requesterId: string\n\n @Field({ nullable: true, description: \"The requester's name\" })\n requesterName?: string\n\n @Field({ description: 'The category or account' })\n category: string\n\n @Field(type => Float, { description: 'Total of the lines' })\n total: number\n\n @Field(type => Float, { description: 'What the company pays of it' })\n payable: number\n\n @Field(type => Int, { description: 'How many lines' })\n count: number\n}\n\n@ObjectType({ description: 'How many requests stand in a status' })\nexport class ExpenditureStatusCount {\n @Field({ description: 'The status' })\n status: string\n\n @Field(type => Int, { description: 'How many' })\n count: number\n}\n\n@ObjectType({ description: 'Monthly summary of reimbursements' })\nexport class ExpenditureSummary {\n @Field(type => [ExpenditureSummaryRow], { description: 'Approved requests only' })\n rows: ExpenditureSummaryRow[]\n\n @Field(type => [ExpenditureStatusCount], { description: 'Every request of the period, by status - drafts and pending ones are counted, not summed' })\n statuses: ExpenditureStatusCount[]\n\n @Field(type => Float, { description: 'Approved in the period' })\n approvedTotal: number\n\n @Field(type => Float, { description: 'Approved but not yet paid' })\n unpaid: number\n}\n"]}
|
|
1
|
+
{"version":3,"file":"expenditure-request-type.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/expenditure-request-type.ts"],"names":[],"mappings":";;;;AAAA,+CAA2E;AAG3E,+FAA2D;AAE3D,iDAAiD;AAEjD,+DAA2E;AAC3E,yEAAqE;AACrE,2EAAqE;AAG9D,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;CAwBnC,CAAA;AAxBY,0DAAuB;AAElC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;;mDACnE;AAGX;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,qCAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC;;qDAClG;AAGtB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,kDAAkD,EAAE,CAAC;;sDAC7E;AAGd;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,oCAAoC,EAAE,CAAC;;sDAC/D;AAGd;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;;wDACtD;AAGhB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,yCAAyC,EAAE,CAAC;sCACtF,iBAAS;6DAAA;AAGxB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,wCAAwC,EAAE,CAAC;sCACrF,iBAAS;6DAAA;AAGxB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;;sDAClC;kCAvBH,uBAAuB;IADnC,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,mEAAmE,EAAE,CAAC;GACnF,uBAAuB,CAwBnC;AAGM,IAAM,2BAA2B,GAAjC,MAAM,2BAA2B;CAiCvC,CAAA;AAjCY,kEAA2B;AAEtC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8BAA8B,EAAE,CAAC;;uDACxE;AAGX;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;;8DACnC;AAGlB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;;6DACnE;AAGjB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC;sCAChH,iBAAS;4DAAA;AAGnB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,4CAA4C,EAAE,CAAC;;6DACpE;AAGjB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;;gEAC/B;AAGpB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;;2DAC/D;AAGf;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;;8DACzD;AAGlB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,mDAAwB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;;kEACpD;AAGxC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,yCAAyC,EAAE,CAAC;sCACxF,iBAAS;+DAAA;AAGtB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,kDAAkD,EAAE,CAAC;;2DAC5E;sCAhCJ,2BAA2B;IADvC,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,2DAA2D,EAAE,CAAC;GAC3E,2BAA2B,CAiCvC;AAGM,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;CA8B9B,CAAA;AA9BY,gDAAkB;AAE7B;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC;;qDACtE;AAGjB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC;;iDACjF;AAGd;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;;oDACpC;AAGhB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;;kDAChD;AAGd;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC;sCAChH,iBAAS;mDAAA;AAGnB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;;oDAC/B;AAGjB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;;uDAC/B;AAGpB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;;qDACzD;AAGlB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,mDAAwB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;;yDACpD;AAGxC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,0BAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,gDAAgD,EAAE,CAAC;;iDAC9F;6BA7BT,kBAAkB;IAD9B,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,2EAA2E,EAAE,CAAC;GAC3F,kBAAkB,CA8B9B;AAGM,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;CAMnC,CAAA;AANY,0DAAuB;AAElC;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC;;yDACxC;AAGhB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;sCAC1E,iBAAS;4DAAA;kCALZ,uBAAuB;IADnC,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;GAC7D,uBAAuB,CAMnC;AAGM,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;CAMlC,CAAA;AANY,wDAAsB;AAEjC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,wCAAkB,CAAC,EAAE,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;;qDACvD;AAG3B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAG,EAAE,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;;qDACpD;iCALF,sBAAsB;IADlC,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;GACjD,sBAAsB,CAMlC;AAGM,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;CAkB9B,CAAA;AAlBY,gDAAkB;AAE7B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,mDAAuB,EAAE,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;;iDAC1E;AAG9B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;;mDACrD;AAGf;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;;gDACxD;AAGZ;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;;uDAC3C;AAGnB;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,gEAAgE,EAAE,CAAC;;sDACtE;AAGnB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;;0DAChD;6BAjBb,kBAAkB;IAD9B,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,+EAA+E,EAAE,CAAC;GAChG,kBAAkB,CAkB9B;AAGM,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;CAe/B,CAAA;AAfY,kDAAmB;AAE9B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,wCAAkB,EAAE,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;sCACzD,wCAAkB;oDAAA;AAG3B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;sCAChE,kBAAkB;oDAAA;AAG3B;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2DAA2D,EAAE,CAAC;;sDAClF;AAMlB;IAJC,IAAA,oBAAK,EAAC;QACL,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,oHAAoH;KAClI,CAAC;;8DACwB;8BAdf,mBAAmB;IAD/B,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC;GAC3D,mBAAmB,CAe/B;AAGM,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAM5B,CAAA;AANY,4CAAgB;AAE3B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,WAAW,EAAE,0DAA0D,EAAE,CAAC;;iDACpF;AAG9B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,WAAW,EAAE,uDAAuD,EAAE,CAAC;;sDAC5E;2BALxB,gBAAgB;IAD5B,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,0GAA0G,EAAE,CAAC;GAC3H,gBAAgB,CAM5B;AAGM,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;CAqBjC,CAAA;AArBY,sDAAqB;AAEhC;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;;oDACrB;AAGb;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAE,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;;0DACjC;AAGnB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;;4DACzC;AAGtB;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;;uDAClC;AAGhB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;;oDAC/C;AAGb;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;;sDACtD;AAGf;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAG,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC;;oDACzC;gCApBF,qBAAqB;IADjC,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,6DAA6D,EAAE,CAAC;GAC9E,qBAAqB,CAqBjC;AAGM,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;CAMlC,CAAA;AANY,wDAAsB;AAEjC;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;;sDACvB;AAGd;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kBAAG,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;;qDACnC;iCALF,sBAAsB;IADlC,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;GACtD,sBAAsB,CAMlC;AAGM,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;CAY9B,CAAA;AAZY,gDAAkB;AAE7B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,qBAAqB,CAAC,EAAE,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;;gDACrD;AAG7B;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAAE,EAAE,WAAW,EAAE,0FAA0F,EAAE,CAAC;;oDACnH;AAGlC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;;yDAC3C;AAGrB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,oBAAK,EAAE,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;;kDACrD;6BAXH,kBAAkB;IAD9B,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;GACpD,kBAAkB,CAY9B","sourcesContent":["import { Field, Float, ID, InputType, Int, ObjectType } from 'type-graphql'\n\nimport type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\n\nimport { ObjectRef } from '@things-factory/shell'\n\nimport { ExpenditureKind, ExpenditureRequest } from './expenditure-request'\nimport { ExpenditurePaymentMethod } from './expenditure-request-item'\nimport { ExpenditurePaymentState } from './expenditure-payment-state'\n\n@InputType({ description: 'The head of an expenditure request - the lines are sent beside it' })\nexport class ExpenditureRequestInput {\n @Field(type => ID, { nullable: true, description: 'Empty for a new request' })\n id?: string\n\n @Field(type => ExpenditureKind, { nullable: true, description: 'Required for a new request; a request keeps its kind' })\n kind?: ExpenditureKind\n\n @Field({ nullable: true, description: \"Defaults to '<month> 경비', or '<counterparty> 지급'\" })\n title?: string\n\n @Field({ nullable: true, description: 'YYYY-MM a reimbursement belongs to' })\n month?: string\n\n @Field({ nullable: true, description: 'YYYY-MM-DD it is to be paid' })\n dueDate?: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Who is paid, for a counterparty payment' })\n counterparty?: ObjectRef\n\n @Field(type => ObjectRef, { nullable: true, description: \"The counterparty's account to pay into\" })\n payeeAccount?: ObjectRef\n\n @Field({ nullable: true, description: 'Notes' })\n notes?: string\n}\n\n@InputType({ description: 'A line of an expenditure request to add, change or delete' })\nexport class ExpenditureRequestItemPatch {\n @Field(type => ID, { nullable: true, description: 'The line to change or delete' })\n id?: string\n\n @Field({ nullable: true, description: 'YYYY-MM-DD' })\n spentDate?: string\n\n @Field({ nullable: true, description: \"What the requester calls it - '식대', '교통비'\" })\n category?: string\n\n @Field(type => ObjectRef, { nullable: true, description: '계정과목 - found from the category or description when not given' })\n account?: ObjectRef\n\n @Field({ nullable: true, description: 'Where - the shop or company on the receipt' })\n merchant?: string\n\n @Field({ nullable: true, description: 'What for' })\n description?: string\n\n @Field(type => Float, { nullable: true, description: 'Amount, VAT included' })\n amount?: number\n\n @Field(type => Float, { nullable: true, description: 'VAT in the amount' })\n vatAmount?: number\n\n @Field(type => ExpenditurePaymentMethod, { nullable: true, description: 'How it was paid' })\n paymentMethod?: ExpenditurePaymentMethod\n\n @Field(type => ObjectRef, { nullable: true, description: 'The purchase tax invoice this line pays' })\n taxInvoice?: ObjectRef\n\n @Field({ nullable: true, description: \"Grid batch flag: '+' add, 'M' modify, '-' delete\" })\n cuFlag?: string\n}\n\n@InputType({ description: 'One expense added on the go - it joins the month’s editable reimbursement' })\nexport class NewExpenditureLine {\n @Field({ description: 'YYYY-MM-DD; the month is taken from it unless month is given' })\n spentDate: string\n\n @Field({ nullable: true, description: 'YYYY-MM - to file a late receipt under another month' })\n month?: string\n\n @Field({ description: \"What it was - '식대', '교통비'\" })\n category: string\n\n @Field(type => Float, { description: 'Amount, VAT included' })\n amount: number\n\n @Field(type => ObjectRef, { nullable: true, description: '계정과목 - found from the category or description when not given' })\n account?: ObjectRef\n\n @Field({ nullable: true, description: 'Where' })\n merchant?: string\n\n @Field({ nullable: true, description: 'What for' })\n description?: string\n\n @Field(type => Float, { nullable: true, description: 'VAT in the amount' })\n vatAmount?: number\n\n @Field(type => ExpenditurePaymentMethod, { nullable: true, description: 'How it was paid' })\n paymentMethod?: ExpenditurePaymentMethod\n\n @Field(type => [GraphQLUpload], { nullable: true, description: 'Receipt photos and files the line is proven by' })\n files?: FileUpload[]\n}\n\n@InputType({ description: 'How approved requests were paid at the bank' })\nexport class ExpenditurePaymentInput {\n @Field({ description: 'YYYY-MM-DD the money went out' })\n paidDate: string\n\n @Field(type => ObjectRef, { nullable: true, description: 'Our account it went out of' })\n bankAccount?: ObjectRef\n}\n\n@ObjectType({ description: 'A page of expenditure requests' })\nexport class ExpenditureRequestList {\n @Field(type => [ExpenditureRequest], { description: 'The requests on this page' })\n items: ExpenditureRequest[]\n\n @Field(type => Int, { description: 'How many there are in all' })\n total: number\n}\n\n@ObjectType({ description: 'How far an expenditure request is paid, read from the bank lines that paid it' })\nexport class ExpenditurePayment {\n @Field(type => ExpenditurePaymentState, { description: 'Nothing to pay, unpaid, partly or fully paid' })\n state: ExpenditurePaymentState\n\n @Field(type => Float, { description: 'What the company is to pay' })\n payable: number\n\n @Field(type => Float, { description: 'What bank lines paid of it' })\n paid: number\n\n @Field(type => Float, { description: 'What is still to pay' })\n outstanding: number\n\n @Field({ description: 'Every bank line that paid it was matched to the bank statement' })\n reconciled: boolean\n\n @Field(type => [String], { description: 'The bank lines that paid it' })\n transactionIds: string[]\n}\n\n@ObjectType({ description: 'An approved request in the payment queue' })\nexport class ExpenditureQueueRow {\n @Field(type => ExpenditureRequest, { description: 'The request' })\n request: ExpenditureRequest\n\n @Field(type => ExpenditurePayment, { description: 'How far it is paid' })\n payment: ExpenditurePayment\n\n @Field({ nullable: true, description: 'Who is paid - the counterparty, or the employee paid back' })\n payeeName?: string\n\n @Field({\n nullable: true,\n description: \"'gone' or 'changed' when the account approvers saw is no longer on file as it was, 'missing' when none was written\"\n })\n payeeAccountDrift?: string\n}\n\n@ObjectType({ description: 'The payment queue - what is approved and still to pay, and what was paid but not yet matched to the bank' })\nexport class ExpenditureQueue {\n @Field(type => [ExpenditureQueueRow], { description: 'Approved and not fully paid, by the day it is to be paid' })\n waiting: ExpenditureQueueRow[]\n\n @Field(type => [ExpenditureQueueRow], { description: 'Paid, with a bank line not yet matched to a statement' })\n unreconciled: ExpenditureQueueRow[]\n}\n\n@ObjectType({ description: 'Approved spending of one month, one requester, one category' })\nexport class ExpenditureSummaryRow {\n @Field({ description: 'YYYY-MM' })\n month: string\n\n @Field(type => ID, { description: 'Who requested' })\n requesterId: string\n\n @Field({ nullable: true, description: \"The requester's name\" })\n requesterName?: string\n\n @Field({ description: 'The category or account' })\n category: string\n\n @Field(type => Float, { description: 'Total of the lines' })\n total: number\n\n @Field(type => Float, { description: 'What the company pays of it' })\n payable: number\n\n @Field(type => Int, { description: 'How many lines' })\n count: number\n}\n\n@ObjectType({ description: 'How many requests stand in a status' })\nexport class ExpenditureStatusCount {\n @Field({ description: 'The status' })\n status: string\n\n @Field(type => Int, { description: 'How many' })\n count: number\n}\n\n@ObjectType({ description: 'Monthly summary of reimbursements' })\nexport class ExpenditureSummary {\n @Field(type => [ExpenditureSummaryRow], { description: 'Approved requests only' })\n rows: ExpenditureSummaryRow[]\n\n @Field(type => [ExpenditureStatusCount], { description: 'Every request of the period, by status - drafts and pending ones are counted, not summed' })\n statuses: ExpenditureStatusCount[]\n\n @Field(type => Float, { description: 'Approved in the period' })\n approvedTotal: number\n\n @Field(type => Float, { description: 'Approved but not yet paid' })\n unpaid: number\n}\n"]}
|
|
@@ -3,6 +3,6 @@ import { ExpenditureRequestItem } from './expenditure-request-item';
|
|
|
3
3
|
import { ExpenditureRequestItemQuery, ExpenditureRequestQuery } from './expenditure-request-query';
|
|
4
4
|
import { ExpenditureRequestMutation } from './expenditure-request-mutation';
|
|
5
5
|
import './expenditure-target';
|
|
6
|
-
export declare const entities: (typeof
|
|
7
|
-
export declare const resolvers: (typeof
|
|
6
|
+
export declare const entities: (typeof ExpenditureRequest | typeof ExpenditureRequestItem)[];
|
|
7
|
+
export declare const resolvers: (typeof ExpenditureRequestMutation | typeof ExpenditureRequestQuery | typeof ExpenditureRequestItemQuery)[];
|
|
8
8
|
export declare const subscribers: any[];
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
/** What
|
|
2
|
-
export interface
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/** What a request's reader is - who wrote it, and the approval case it went up as. */
|
|
2
|
+
export interface ReadRequest {
|
|
3
|
+
requesterId?: string;
|
|
4
|
+
activityInstanceId?: string;
|
|
5
|
+
}
|
|
6
|
+
/** What the rule asks of the world - passed in so it is tested without a database. */
|
|
7
|
+
export interface RequestReadFacts {
|
|
8
8
|
/** Whether the caller reads every request - the paying seat (`expenditure:query`). */
|
|
9
9
|
readsEveryRequest(context: any): Promise<boolean>;
|
|
10
10
|
/** Whether the caller takes part in the approval case. */
|
|
11
11
|
takesPart(activityInstanceId: string, context: any): Promise<boolean>;
|
|
12
12
|
}
|
|
13
|
+
export interface ReceiptFacts extends RequestReadFacts {
|
|
14
|
+
/** The line's request. */
|
|
15
|
+
requestOf(itemId: string, domainId: string): Promise<ReadRequest | undefined>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Who may read one request, its lines and their files (ADR-0106 decision 2, ADR-0139): the employee who wrote it,
|
|
19
|
+
* whoever decides it in the worklist, and the paying seat, which reads every request (`expenditure`).
|
|
20
|
+
*/
|
|
21
|
+
export declare function mayReadRequest(request: ReadRequest, context: any, facts: RequestReadFacts): Promise<boolean>;
|
|
13
22
|
/**
|
|
14
|
-
* Who may open a
|
|
15
|
-
* decides it in the worklist, and the paying seat, which reads every request (`expenditure`). attachment-base has already checked the
|
|
23
|
+
* Who may open a line's file by its path - whoever may read its request. attachment-base has already checked the
|
|
16
24
|
* attachment is of the request's domain.
|
|
17
25
|
*/
|
|
18
26
|
export declare function receiptReader(attachment: {
|
|
19
27
|
refBy?: string;
|
|
20
28
|
}, context: any, facts: ReceiptFacts): Promise<boolean>;
|
|
29
|
+
export declare const REQUEST_READ_FACTS: ReceiptFacts;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.REQUEST_READ_FACTS = void 0;
|
|
4
|
+
exports.mayReadRequest = mayReadRequest;
|
|
3
5
|
exports.receiptReader = receiptReader;
|
|
4
6
|
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
5
7
|
const auth_base_1 = require("@things-factory/auth-base");
|
|
@@ -8,16 +10,12 @@ const worklist_1 = require("@things-factory/worklist");
|
|
|
8
10
|
const expenditure_request_item_1 = require("./expenditure-request-item");
|
|
9
11
|
const expenditure_request_service_1 = require("./expenditure-request-service");
|
|
10
12
|
/**
|
|
11
|
-
* Who may
|
|
12
|
-
* decides it in the worklist, and the paying seat, which reads every request (`expenditure`).
|
|
13
|
-
* attachment is of the request's domain.
|
|
13
|
+
* Who may read one request, its lines and their files (ADR-0106 decision 2, ADR-0139): the employee who wrote it,
|
|
14
|
+
* whoever decides it in the worklist, and the paying seat, which reads every request (`expenditure`).
|
|
14
15
|
*/
|
|
15
|
-
async function
|
|
16
|
+
async function mayReadRequest(request, context, facts) {
|
|
16
17
|
const { domain, user } = context?.state ?? {};
|
|
17
|
-
if (!domain || !user
|
|
18
|
-
return false;
|
|
19
|
-
const request = await facts.requestOf(attachment.refBy, domain.id);
|
|
20
|
-
if (!request)
|
|
18
|
+
if (!domain || !user)
|
|
21
19
|
return false;
|
|
22
20
|
if (request.requesterId === user.id)
|
|
23
21
|
return true;
|
|
@@ -25,7 +23,18 @@ async function receiptReader(attachment, context, facts) {
|
|
|
25
23
|
return true;
|
|
26
24
|
return !!request.activityInstanceId && (await facts.takesPart(request.activityInstanceId, context));
|
|
27
25
|
}
|
|
28
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Who may open a line's file by its path - whoever may read its request. attachment-base has already checked the
|
|
28
|
+
* attachment is of the request's domain.
|
|
29
|
+
*/
|
|
30
|
+
async function receiptReader(attachment, context, facts) {
|
|
31
|
+
const { domain, user } = context?.state ?? {};
|
|
32
|
+
if (!domain || !user || !attachment.refBy)
|
|
33
|
+
return false;
|
|
34
|
+
const request = await facts.requestOf(attachment.refBy, domain.id);
|
|
35
|
+
return !!request && (await mayReadRequest(request, context, facts));
|
|
36
|
+
}
|
|
37
|
+
exports.REQUEST_READ_FACTS = {
|
|
29
38
|
async requestOf(itemId, domainId) {
|
|
30
39
|
const item = await (0, shell_1.getRepository)(expenditure_request_item_1.ExpenditureRequestItem).findOne({ where: { id: itemId, domain: { id: domainId } }, relations: ['request'] });
|
|
31
40
|
return item?.request ? { requesterId: item.request.requesterId, activityInstanceId: item.request.activityInstanceId } : undefined;
|
|
@@ -39,5 +48,5 @@ const FACTS = {
|
|
|
39
48
|
return !!instance && (await (0, worklist_1.mayReadInstance)(instance, context));
|
|
40
49
|
}
|
|
41
50
|
};
|
|
42
|
-
(0, attachment_base_1.registerAttachmentReader)(expenditure_request_service_1.RECEIPT_REF_TYPE, (attachment, context) => receiptReader(attachment, context,
|
|
51
|
+
(0, attachment_base_1.registerAttachmentReader)(expenditure_request_service_1.RECEIPT_REF_TYPE, (attachment, context) => receiptReader(attachment, context, exports.REQUEST_READ_FACTS));
|
|
43
52
|
//# sourceMappingURL=receipt-reader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"receipt-reader.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/receipt-reader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"receipt-reader.js","sourceRoot":"","sources":["../../../server/service/expenditure-request/receipt-reader.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerAttachmentReader } from '@things-factory/attachment-base'\nimport { checkPermission } from '@things-factory/auth-base'\nimport { getRepository } from '@things-factory/shell'\nimport { ActivityInstance, mayReadInstance } from '@things-factory/worklist'\n\nimport { ExpenditureRequestItem } from './expenditure-request-item'\nimport { RECEIPT_REF_TYPE } from './expenditure-request-service'\n\n/** What a request's reader is - who wrote it, and the approval case it went up as. */\nexport interface ReadRequest {\n requesterId?: string\n activityInstanceId?: string\n}\n\n/** What the rule asks of the world - passed in so it is tested without a database. */\nexport interface RequestReadFacts {\n /** Whether the caller reads every request - the paying seat (`expenditure:query`). */\n readsEveryRequest(context: any): Promise<boolean>\n /** Whether the caller takes part in the approval case. */\n takesPart(activityInstanceId: string, context: any): Promise<boolean>\n}\n\nexport interface ReceiptFacts extends RequestReadFacts {\n /** The line's request. */\n requestOf(itemId: string, domainId: string): Promise<ReadRequest | undefined>\n}\n\n/**\n * Who may read one request, its lines and their files (ADR-0106 decision 2, ADR-0139): the employee who wrote it,\n * whoever decides it in the worklist, and the paying seat, which reads every request (`expenditure`).\n */\nexport async function mayReadRequest(request: ReadRequest, context: any, facts: RequestReadFacts): Promise<boolean> {\n const { domain, user } = context?.state ?? {}\n if (!domain || !user) return false\n if (request.requesterId === user.id) return true\n if (await facts.readsEveryRequest(context)) return true\n return !!request.activityInstanceId && (await facts.takesPart(request.activityInstanceId, context))\n}\n\n/**\n * Who may open a line's file by its path - whoever may read its request. attachment-base has already checked the\n * attachment is of the request's domain.\n */\nexport async function receiptReader(attachment: { refBy?: string }, context: any, facts: ReceiptFacts): Promise<boolean> {\n const { domain, user } = context?.state ?? {}\n if (!domain || !user || !attachment.refBy) return false\n const request = await facts.requestOf(attachment.refBy, domain.id)\n return !!request && (await mayReadRequest(request, context, facts))\n}\n\nexport const REQUEST_READ_FACTS: ReceiptFacts = {\n async requestOf(itemId, domainId) {\n const item = await getRepository(ExpenditureRequestItem).findOne({ where: { id: itemId, domain: { id: domainId } } as any, relations: ['request'] })\n return item?.request ? { requesterId: item.request.requesterId, activityInstanceId: item.request.activityInstanceId } : undefined\n },\n async readsEveryRequest(context) {\n const { domain, user, unsafeIP, prohibitedPrivileges } = context.state\n return !!(await checkPermission({ category: 'expenditure', privilege: 'query', owner: true }, user, domain, unsafeIP, prohibitedPrivileges))\n },\n async takesPart(activityInstanceId, context) {\n const instance = await getRepository(ActivityInstance).findOne({ where: { id: activityInstanceId, domain: { id: context.state.domain.id } } as any })\n return !!instance && (await mayReadInstance(instance, context))\n }\n}\n\nregisterAttachmentReader(RECEIPT_REF_TYPE, (attachment, context) => receiptReader(attachment, context, REQUEST_READ_FACTS))\n"]}
|
|
@@ -4,6 +4,6 @@ import { FinancialStatementHistory } from './financial-statement-history';
|
|
|
4
4
|
import { FinancialStatementLineQuery, FinancialStatementQuery } from './financial-statement-query';
|
|
5
5
|
import { FinancialStatementMutation } from './financial-statement-mutation';
|
|
6
6
|
import { FinancialStatementHistoryEntitySubscriber } from './event-subscriber';
|
|
7
|
-
export declare const entities: (typeof
|
|
7
|
+
export declare const entities: (typeof FinancialStatement | typeof FinancialStatementLine | typeof FinancialStatementHistory)[];
|
|
8
8
|
export declare const resolvers: (typeof FinancialStatementQuery | typeof FinancialStatementLineQuery | typeof FinancialStatementMutation)[];
|
|
9
9
|
export declare const subscribers: (typeof FinancialStatementHistoryEntitySubscriber)[];
|
|
@@ -28,6 +28,7 @@ export * from './recurring-cash-item/recurring-cash-item-service';
|
|
|
28
28
|
export * from './account/account-match';
|
|
29
29
|
export * from './account/default-accounts';
|
|
30
30
|
export * from './account/account-choice';
|
|
31
|
+
export * from './account/account-service';
|
|
31
32
|
export * from './bank-statement/bank-source';
|
|
32
33
|
export * from './bank-statement/bank-parser';
|
|
33
34
|
export * from './bank-statement/bank-reconcile';
|
|
@@ -41,5 +42,5 @@ export * from './expenditure-request/expenditure-request-service';
|
|
|
41
42
|
export declare const entities: any[];
|
|
42
43
|
export declare const subscribers: any[];
|
|
43
44
|
export declare const schema: {
|
|
44
|
-
resolverClasses: (typeof import("./financial-statement/financial-statement-query").FinancialStatementQuery | typeof import("./financial-statement/financial-statement-query").FinancialStatementLineQuery | typeof import("./financial-statement/financial-statement-mutation").FinancialStatementMutation | typeof import("./accounting-category/accounting-category-query").AccountingCategoryQuery | typeof import("./accounting-category/accounting-category-mutation").AccountingCategoryMutation | typeof import("./transaction/transaction-query").TransactionQuery | typeof import("./transaction/transaction-mutation").TransactionMutation | typeof import("./bank-account/bank-account-query").BankAccountQuery | typeof import("./bank-account/bank-account-mutation").BankAccountMutation | typeof import("./bank-statement/bank-statement-query").BankStatementQuery | typeof import("./bank-statement/bank-import-mutation").BankImportMutation | typeof import("./payment/payment-query").PaymentQuery | typeof import("./payment/payment-mutation").PaymentMutation | typeof import("./account/account-query").AccountQuery | typeof import("./account/account-mutation").AccountMutation | typeof import("./accounting-document/accounting-document-query").AccountingDocumentQuery | typeof import("./accounting-document/accounting-document-mutation").AccountingDocumentMutation | typeof import("./recurring-cash-item/recurring-cash-item-query").RecurringCashItemQuery | typeof import("./recurring-cash-item/recurring-cash-item-mutation").RecurringCashItemMutation | typeof import("./financial-institution/financial-institution-query").FinancialInstitutionQuery | typeof import("./financial-institution/financial-institution-mutation").FinancialInstitutionMutation | typeof import("./fiscal-month/fiscal-month-query").FiscalMonthQuery | typeof import("./fiscal-month/fiscal-month-mutation").FiscalMonthMutation | typeof import("./fiscal-quarter/fiscal-quarter-query").FiscalQuarterQuery | typeof import("./fiscal-quarter/fiscal-quarter-mutation").FiscalQuarterMutation | typeof import("./fiscal-year/fiscal-year-query").FiscalYearQuery | typeof import("./fiscal-year/fiscal-year-mutation").FiscalYearMutation | typeof import("./counterparty-account/counterparty-account-query").CounterpartyAccountQuery
|
|
45
|
+
resolverClasses: (typeof import("./expenditure-request/expenditure-request-mutation").ExpenditureRequestMutation | typeof import("./expenditure-request/expenditure-request-query").ExpenditureRequestQuery | typeof import("./expenditure-request/expenditure-request-query").ExpenditureRequestItemQuery | typeof import("./financial-statement/financial-statement-query").FinancialStatementQuery | typeof import("./financial-statement/financial-statement-query").FinancialStatementLineQuery | typeof import("./financial-statement/financial-statement-mutation").FinancialStatementMutation | typeof import("./accounting-category/accounting-category-query").AccountingCategoryQuery | typeof import("./accounting-category/accounting-category-mutation").AccountingCategoryMutation | typeof import("./transaction/transaction-query").TransactionQuery | typeof import("./transaction/transaction-mutation").TransactionMutation | typeof import("./bank-account/bank-account-query").BankAccountQuery | typeof import("./bank-account/bank-account-mutation").BankAccountMutation | typeof import("./bank-statement/bank-statement-query").BankStatementQuery | typeof import("./bank-statement/bank-import-mutation").BankImportMutation | typeof import("./payment/payment-query").PaymentQuery | typeof import("./payment/payment-mutation").PaymentMutation | typeof import("./account/account-query").AccountQuery | typeof import("./account/account-mutation").AccountMutation | typeof import("./accounting-document/accounting-document-query").AccountingDocumentQuery | typeof import("./accounting-document/accounting-document-mutation").AccountingDocumentMutation | typeof import("./recurring-cash-item/recurring-cash-item-query").RecurringCashItemQuery | typeof import("./recurring-cash-item/recurring-cash-item-mutation").RecurringCashItemMutation | typeof import("./financial-institution/financial-institution-query").FinancialInstitutionQuery | typeof import("./financial-institution/financial-institution-mutation").FinancialInstitutionMutation | typeof import("./fiscal-month/fiscal-month-query").FiscalMonthQuery | typeof import("./fiscal-month/fiscal-month-mutation").FiscalMonthMutation | typeof import("./fiscal-quarter/fiscal-quarter-query").FiscalQuarterQuery | typeof import("./fiscal-quarter/fiscal-quarter-mutation").FiscalQuarterMutation | typeof import("./fiscal-year/fiscal-year-query").FiscalYearQuery | typeof import("./fiscal-year/fiscal-year-mutation").FiscalYearMutation | typeof import("./counterparty-account/counterparty-account-query").CounterpartyAccountQuery)[];
|
|
45
46
|
};
|
|
@@ -34,6 +34,7 @@ tslib_1.__exportStar(require("./recurring-cash-item/recurring-cash-item-service"
|
|
|
34
34
|
tslib_1.__exportStar(require("./account/account-match"), exports);
|
|
35
35
|
tslib_1.__exportStar(require("./account/default-accounts"), exports);
|
|
36
36
|
tslib_1.__exportStar(require("./account/account-choice"), exports);
|
|
37
|
+
tslib_1.__exportStar(require("./account/account-service"), exports);
|
|
37
38
|
tslib_1.__exportStar(require("./bank-statement/bank-source"), exports);
|
|
38
39
|
tslib_1.__exportStar(require("./bank-statement/bank-parser"), exports);
|
|
39
40
|
tslib_1.__exportStar(require("./bank-statement/bank-reconcile"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,yBAAyB;AACzB,2DAAgC;AAChC,oFAAyD;AACzD,oFAAyD;AACzD,oEAAyC;AACzC,sEAA2C;AAC3C,0EAA+C;AAC/C,4DAAiC;AACjC,4DAAiC;AACjC,oFAAyD;AACzD,oFAAyD;AACzD,wFAA6D;AAC7D,sEAA2C;AAC3C,0EAA+C;AAC/C,oEAAyC;AACzC,oFAAyD;AACzD,yFAA8D;AAE9D,qBAAqB;AACrB,2EAAgD;AAChD,4EAAiD;AACjD,8EAAmD;AACnD,oEAAyC;AACzC,oEAAyC;AACzC,qEAA0C;AAC1C,qEAA0C;AAC1C,yFAA8D;AAC9D,4FAAiE;AACjE,mFAAwD;AACxD,4FAAiE;AACjE,kEAAuC;AACvC,qEAA0C;AAC1C,mEAAwC;AACxC,uEAA4C;AAC5C,uEAA4C;AAC5C,0EAA+C;AAC/C,4EAAiD;AACjD,uEAA4C;AAC5C,4FAAiE;AACjE,8FAAmE;AACnE,0FAA+D;AAC/D,0FAA+D;AAC/D,4FAAiE;AAEjE,mCAAmC;AACnC,+DAI8B;AAC9B,+DAI8B;AAC9B,+CAIsB;AACtB,iDAIuB;AACvB,qDAIyB;AACzB,uCAIkB;AAClB,uCAIkB;AAClB,+DAI8B;AAC9B,+DAI8B;AAC9B,mEAIgC;AAChC,iDAIuB;AACvB,qDAIyB;AACzB,+CAIsB;AACtB,iEAI+B;AAC/B,+DAI8B;AAEjB,QAAA,QAAQ,GAAG;IACtB,GAAG,8BAA0B;IAC7B,GAAG,8BAA0B;IAC7B,GAAG,sBAAmB;IACtB,GAAG,uBAAmB;IACtB,GAAG,yBAAqB;IACxB,GAAG,kBAAe;IAClB,GAAG,kBAAe;IAClB,GAAG,8BAA0B;IAC7B,GAAG,8BAAyB;IAC5B,GAAG,gCAA4B;IAC/B,GAAG,uBAAmB;IACtB,GAAG,yBAAqB;IACxB,GAAG,sBAAkB;IACrB,GAAG,+BAA2B;IAC9B,GAAG,8BAA0B;CAC9B,CAAA;AAEY,QAAA,WAAW,GAAG;IACzB,GAAG,iCAA6B;IAChC,GAAG,iCAA6B;IAChC,GAAG,yBAAsB;IACzB,GAAG,0BAAsB;IACzB,GAAG,4BAAwB;IAC3B,GAAG,qBAAkB;IACrB,GAAG,qBAAkB;IACrB,GAAG,iCAA6B;IAChC,GAAG,iCAA4B;IAC/B,GAAG,mCAA+B;IAClC,GAAG,0BAAsB;IACzB,GAAG,4BAAwB;IAC3B,GAAG,yBAAqB;IACxB,GAAG,kCAA8B;IACjC,GAAG,iCAA6B;CACjC,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,GAAG,+BAA2B;QAC9B,GAAG,+BAA2B;QAC9B,GAAG,uBAAoB;QACvB,GAAG,wBAAoB;QACvB,GAAG,0BAAsB;QACzB,GAAG,mBAAgB;QACnB,GAAG,mBAAgB;QACnB,GAAG,+BAA2B;QAC9B,GAAG,+BAA0B;QAC7B,GAAG,iCAA6B;QAChC,GAAG,wBAAoB;QACvB,GAAG,0BAAsB;QACzB,GAAG,uBAAmB;QACtB,GAAG,gCAA4B;QAC/B,GAAG,+BAA2B;KAC/B;CACF,CAAA","sourcesContent":["/* EXPORT ENTITY TYPES */\nexport * from './cash-flow-type'\nexport * from './financial-statement/financial-statement'\nexport * from './accounting-category/accounting-category'\nexport * from './transaction/transaction'\nexport * from './bank-account/bank-account'\nexport * from './bank-statement/bank-statement'\nexport * from './payment/payment'\nexport * from './account/account'\nexport * from './accounting-document/accounting-document'\nexport * from './recurring-cash-item/recurring-cash-item'\nexport * from './financial-institution/financial-institution'\nexport * from './fiscal-month/fiscal-month'\nexport * from './fiscal-quarter/fiscal-quarter'\nexport * from './fiscal-year/fiscal-year'\nexport * from './expenditure-request/expenditure-request'\nexport * from './expenditure-request/expenditure-request-item'\n\n/* EXPORT SERVICES */\nexport * from './transaction/transaction-period'\nexport * from './transaction/transaction-service'\nexport * from './bank-account/bank-account-service'\nexport * from './payment/payment-targets'\nexport * from './payment/payment-service'\nexport * from './payment/payment-currency'\nexport * from './payment/document-targets'\nexport * from './financial-statement/financial-statement-line'\nexport * from './financial-statement/financial-statement-service'\nexport * from './recurring-cash-item/recurring-schedule'\nexport * from './recurring-cash-item/recurring-cash-item-service'\nexport * from './account/account-match'\nexport * from './account/default-accounts'\nexport * from './account/account-choice'\nexport * from './bank-statement/bank-source'\nexport * from './bank-statement/bank-parser'\nexport * from './bank-statement/bank-reconcile'\nexport * from './bank-statement/bank-import-type'\nexport * from './bank-statement/bank-import'\nexport * from './counterparty-account/counterparty-account-rules'\nexport * from './counterparty-account/counterparty-account-service'\nexport * from './expenditure-request/expenditure-request-rules'\nexport * from './expenditure-request/expenditure-payment-state'\nexport * from './expenditure-request/expenditure-request-service'\n\n/* IMPORT ENTITIES AND RESOLVERS */\nimport {\n entities as FinancialStatementEntities,\n resolvers as FinancialStatementResolvers,\n subscribers as FinancialStatementSubscribers\n} from './financial-statement'\nimport {\n entities as AccountingCategoryEntities,\n resolvers as AccountingCategoryResolvers,\n subscribers as AccountingCategorySubscribers\n} from './accounting-category'\nimport {\n entities as TransactionEntities,\n resolvers as TransactionResolvers,\n subscribers as TransactionSubscribers\n} from './transaction'\nimport {\n entities as BankAccountEntities,\n resolvers as BankAccountResolvers,\n subscribers as BankAccountSubscribers\n} from './bank-account'\nimport {\n entities as BankStatementEntities,\n resolvers as BankStatementResolvers,\n subscribers as BankStatementSubscribers\n} from './bank-statement'\nimport {\n entities as PaymentEntities,\n resolvers as PaymentResolvers,\n subscribers as PaymentSubscribers\n} from './payment'\nimport {\n entities as AccountEntities,\n resolvers as AccountResolvers,\n subscribers as AccountSubscribers\n} from './account'\nimport {\n entities as AccountingDocumentEntities,\n resolvers as AccountingDocumentResolvers,\n subscribers as AccountingDocumentSubscribers\n} from './accounting-document'\nimport {\n entities as RecurringCashItemEntities,\n resolvers as RecurringCashItemResolvers,\n subscribers as RecurringCashItemSubscribers\n} from './recurring-cash-item'\nimport {\n entities as FinancialInstitutionEntities,\n resolvers as FinancialInstitutionResolvers,\n subscribers as FinancialInstitutionSubscribers\n} from './financial-institution'\nimport {\n entities as FiscalMonthEntities,\n resolvers as FiscalMonthResolvers,\n subscribers as FiscalMonthSubscribers\n} from './fiscal-month'\nimport {\n entities as FiscalQuarterEntities,\n resolvers as FiscalQuarterResolvers,\n subscribers as FiscalQuarterSubscribers\n} from './fiscal-quarter'\nimport {\n entities as FiscalYearEntities,\n resolvers as FiscalYearResolvers,\n subscribers as FiscalYearSubscribers\n} from './fiscal-year'\nimport {\n entities as CounterpartyAccountEntities,\n resolvers as CounterpartyAccountResolvers,\n subscribers as CounterpartyAccountSubscribers\n} from './counterparty-account'\nimport {\n entities as ExpenditureRequestEntities,\n resolvers as ExpenditureRequestResolvers,\n subscribers as ExpenditureRequestSubscribers\n} from './expenditure-request'\n\nexport const entities = [\n ...FinancialStatementEntities,\n ...AccountingCategoryEntities,\n ...TransactionEntities,\n ...BankAccountEntities,\n ...BankStatementEntities,\n ...PaymentEntities,\n ...AccountEntities,\n ...AccountingDocumentEntities,\n ...RecurringCashItemEntities,\n ...FinancialInstitutionEntities,\n ...FiscalMonthEntities,\n ...FiscalQuarterEntities,\n ...FiscalYearEntities,\n ...CounterpartyAccountEntities,\n ...ExpenditureRequestEntities\n]\n\nexport const subscribers = [\n ...FinancialStatementSubscribers,\n ...AccountingCategorySubscribers,\n ...TransactionSubscribers,\n ...BankAccountSubscribers,\n ...BankStatementSubscribers,\n ...PaymentSubscribers,\n ...AccountSubscribers,\n ...AccountingDocumentSubscribers,\n ...RecurringCashItemSubscribers,\n ...FinancialInstitutionSubscribers,\n ...FiscalMonthSubscribers,\n ...FiscalQuarterSubscribers,\n ...FiscalYearSubscribers,\n ...CounterpartyAccountSubscribers,\n ...ExpenditureRequestSubscribers\n]\n\nexport const schema = {\n resolverClasses: [\n ...FinancialStatementResolvers,\n ...AccountingCategoryResolvers,\n ...TransactionResolvers,\n ...BankAccountResolvers,\n ...BankStatementResolvers,\n ...PaymentResolvers,\n ...AccountResolvers,\n ...AccountingDocumentResolvers,\n ...RecurringCashItemResolvers,\n ...FinancialInstitutionResolvers,\n ...FiscalMonthResolvers,\n ...FiscalQuarterResolvers,\n ...FiscalYearResolvers,\n ...CounterpartyAccountResolvers,\n ...ExpenditureRequestResolvers\n ]\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,yBAAyB;AACzB,2DAAgC;AAChC,oFAAyD;AACzD,oFAAyD;AACzD,oEAAyC;AACzC,sEAA2C;AAC3C,0EAA+C;AAC/C,4DAAiC;AACjC,4DAAiC;AACjC,oFAAyD;AACzD,oFAAyD;AACzD,wFAA6D;AAC7D,sEAA2C;AAC3C,0EAA+C;AAC/C,oEAAyC;AACzC,oFAAyD;AACzD,yFAA8D;AAE9D,qBAAqB;AACrB,2EAAgD;AAChD,4EAAiD;AACjD,8EAAmD;AACnD,oEAAyC;AACzC,oEAAyC;AACzC,qEAA0C;AAC1C,qEAA0C;AAC1C,yFAA8D;AAC9D,4FAAiE;AACjE,mFAAwD;AACxD,4FAAiE;AACjE,kEAAuC;AACvC,qEAA0C;AAC1C,mEAAwC;AACxC,oEAAyC;AACzC,uEAA4C;AAC5C,uEAA4C;AAC5C,0EAA+C;AAC/C,4EAAiD;AACjD,uEAA4C;AAC5C,4FAAiE;AACjE,8FAAmE;AACnE,0FAA+D;AAC/D,0FAA+D;AAC/D,4FAAiE;AAEjE,mCAAmC;AACnC,+DAI8B;AAC9B,+DAI8B;AAC9B,+CAIsB;AACtB,iDAIuB;AACvB,qDAIyB;AACzB,uCAIkB;AAClB,uCAIkB;AAClB,+DAI8B;AAC9B,+DAI8B;AAC9B,mEAIgC;AAChC,iDAIuB;AACvB,qDAIyB;AACzB,+CAIsB;AACtB,iEAI+B;AAC/B,+DAI8B;AAEjB,QAAA,QAAQ,GAAG;IACtB,GAAG,8BAA0B;IAC7B,GAAG,8BAA0B;IAC7B,GAAG,sBAAmB;IACtB,GAAG,uBAAmB;IACtB,GAAG,yBAAqB;IACxB,GAAG,kBAAe;IAClB,GAAG,kBAAe;IAClB,GAAG,8BAA0B;IAC7B,GAAG,8BAAyB;IAC5B,GAAG,gCAA4B;IAC/B,GAAG,uBAAmB;IACtB,GAAG,yBAAqB;IACxB,GAAG,sBAAkB;IACrB,GAAG,+BAA2B;IAC9B,GAAG,8BAA0B;CAC9B,CAAA;AAEY,QAAA,WAAW,GAAG;IACzB,GAAG,iCAA6B;IAChC,GAAG,iCAA6B;IAChC,GAAG,yBAAsB;IACzB,GAAG,0BAAsB;IACzB,GAAG,4BAAwB;IAC3B,GAAG,qBAAkB;IACrB,GAAG,qBAAkB;IACrB,GAAG,iCAA6B;IAChC,GAAG,iCAA4B;IAC/B,GAAG,mCAA+B;IAClC,GAAG,0BAAsB;IACzB,GAAG,4BAAwB;IAC3B,GAAG,yBAAqB;IACxB,GAAG,kCAA8B;IACjC,GAAG,iCAA6B;CACjC,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,GAAG,+BAA2B;QAC9B,GAAG,+BAA2B;QAC9B,GAAG,uBAAoB;QACvB,GAAG,wBAAoB;QACvB,GAAG,0BAAsB;QACzB,GAAG,mBAAgB;QACnB,GAAG,mBAAgB;QACnB,GAAG,+BAA2B;QAC9B,GAAG,+BAA0B;QAC7B,GAAG,iCAA6B;QAChC,GAAG,wBAAoB;QACvB,GAAG,0BAAsB;QACzB,GAAG,uBAAmB;QACtB,GAAG,gCAA4B;QAC/B,GAAG,+BAA2B;KAC/B;CACF,CAAA","sourcesContent":["/* EXPORT ENTITY TYPES */\nexport * from './cash-flow-type'\nexport * from './financial-statement/financial-statement'\nexport * from './accounting-category/accounting-category'\nexport * from './transaction/transaction'\nexport * from './bank-account/bank-account'\nexport * from './bank-statement/bank-statement'\nexport * from './payment/payment'\nexport * from './account/account'\nexport * from './accounting-document/accounting-document'\nexport * from './recurring-cash-item/recurring-cash-item'\nexport * from './financial-institution/financial-institution'\nexport * from './fiscal-month/fiscal-month'\nexport * from './fiscal-quarter/fiscal-quarter'\nexport * from './fiscal-year/fiscal-year'\nexport * from './expenditure-request/expenditure-request'\nexport * from './expenditure-request/expenditure-request-item'\n\n/* EXPORT SERVICES */\nexport * from './transaction/transaction-period'\nexport * from './transaction/transaction-service'\nexport * from './bank-account/bank-account-service'\nexport * from './payment/payment-targets'\nexport * from './payment/payment-service'\nexport * from './payment/payment-currency'\nexport * from './payment/document-targets'\nexport * from './financial-statement/financial-statement-line'\nexport * from './financial-statement/financial-statement-service'\nexport * from './recurring-cash-item/recurring-schedule'\nexport * from './recurring-cash-item/recurring-cash-item-service'\nexport * from './account/account-match'\nexport * from './account/default-accounts'\nexport * from './account/account-choice'\nexport * from './account/account-service'\nexport * from './bank-statement/bank-source'\nexport * from './bank-statement/bank-parser'\nexport * from './bank-statement/bank-reconcile'\nexport * from './bank-statement/bank-import-type'\nexport * from './bank-statement/bank-import'\nexport * from './counterparty-account/counterparty-account-rules'\nexport * from './counterparty-account/counterparty-account-service'\nexport * from './expenditure-request/expenditure-request-rules'\nexport * from './expenditure-request/expenditure-payment-state'\nexport * from './expenditure-request/expenditure-request-service'\n\n/* IMPORT ENTITIES AND RESOLVERS */\nimport {\n entities as FinancialStatementEntities,\n resolvers as FinancialStatementResolvers,\n subscribers as FinancialStatementSubscribers\n} from './financial-statement'\nimport {\n entities as AccountingCategoryEntities,\n resolvers as AccountingCategoryResolvers,\n subscribers as AccountingCategorySubscribers\n} from './accounting-category'\nimport {\n entities as TransactionEntities,\n resolvers as TransactionResolvers,\n subscribers as TransactionSubscribers\n} from './transaction'\nimport {\n entities as BankAccountEntities,\n resolvers as BankAccountResolvers,\n subscribers as BankAccountSubscribers\n} from './bank-account'\nimport {\n entities as BankStatementEntities,\n resolvers as BankStatementResolvers,\n subscribers as BankStatementSubscribers\n} from './bank-statement'\nimport {\n entities as PaymentEntities,\n resolvers as PaymentResolvers,\n subscribers as PaymentSubscribers\n} from './payment'\nimport {\n entities as AccountEntities,\n resolvers as AccountResolvers,\n subscribers as AccountSubscribers\n} from './account'\nimport {\n entities as AccountingDocumentEntities,\n resolvers as AccountingDocumentResolvers,\n subscribers as AccountingDocumentSubscribers\n} from './accounting-document'\nimport {\n entities as RecurringCashItemEntities,\n resolvers as RecurringCashItemResolvers,\n subscribers as RecurringCashItemSubscribers\n} from './recurring-cash-item'\nimport {\n entities as FinancialInstitutionEntities,\n resolvers as FinancialInstitutionResolvers,\n subscribers as FinancialInstitutionSubscribers\n} from './financial-institution'\nimport {\n entities as FiscalMonthEntities,\n resolvers as FiscalMonthResolvers,\n subscribers as FiscalMonthSubscribers\n} from './fiscal-month'\nimport {\n entities as FiscalQuarterEntities,\n resolvers as FiscalQuarterResolvers,\n subscribers as FiscalQuarterSubscribers\n} from './fiscal-quarter'\nimport {\n entities as FiscalYearEntities,\n resolvers as FiscalYearResolvers,\n subscribers as FiscalYearSubscribers\n} from './fiscal-year'\nimport {\n entities as CounterpartyAccountEntities,\n resolvers as CounterpartyAccountResolvers,\n subscribers as CounterpartyAccountSubscribers\n} from './counterparty-account'\nimport {\n entities as ExpenditureRequestEntities,\n resolvers as ExpenditureRequestResolvers,\n subscribers as ExpenditureRequestSubscribers\n} from './expenditure-request'\n\nexport const entities = [\n ...FinancialStatementEntities,\n ...AccountingCategoryEntities,\n ...TransactionEntities,\n ...BankAccountEntities,\n ...BankStatementEntities,\n ...PaymentEntities,\n ...AccountEntities,\n ...AccountingDocumentEntities,\n ...RecurringCashItemEntities,\n ...FinancialInstitutionEntities,\n ...FiscalMonthEntities,\n ...FiscalQuarterEntities,\n ...FiscalYearEntities,\n ...CounterpartyAccountEntities,\n ...ExpenditureRequestEntities\n]\n\nexport const subscribers = [\n ...FinancialStatementSubscribers,\n ...AccountingCategorySubscribers,\n ...TransactionSubscribers,\n ...BankAccountSubscribers,\n ...BankStatementSubscribers,\n ...PaymentSubscribers,\n ...AccountSubscribers,\n ...AccountingDocumentSubscribers,\n ...RecurringCashItemSubscribers,\n ...FinancialInstitutionSubscribers,\n ...FiscalMonthSubscribers,\n ...FiscalQuarterSubscribers,\n ...FiscalYearSubscribers,\n ...CounterpartyAccountSubscribers,\n ...ExpenditureRequestSubscribers\n]\n\nexport const schema = {\n resolverClasses: [\n ...FinancialStatementResolvers,\n ...AccountingCategoryResolvers,\n ...TransactionResolvers,\n ...BankAccountResolvers,\n ...BankStatementResolvers,\n ...PaymentResolvers,\n ...AccountResolvers,\n ...AccountingDocumentResolvers,\n ...RecurringCashItemResolvers,\n ...FinancialInstitutionResolvers,\n ...FiscalMonthResolvers,\n ...FiscalQuarterResolvers,\n ...FiscalYearResolvers,\n ...CounterpartyAccountResolvers,\n ...ExpenditureRequestResolvers\n ]\n}\n"]}
|
|
@@ -7,6 +7,9 @@ const event_subscriber_1 = require("./event-subscriber");
|
|
|
7
7
|
const payment_query_1 = require("./payment-query");
|
|
8
8
|
const payment_mutation_1 = require("./payment-mutation");
|
|
9
9
|
require("./transfer-target");
|
|
10
|
+
const shell_1 = require("@things-factory/shell");
|
|
11
|
+
/* A payment names what it paid by kind and id (§`registerPaymentTarget`); what it pays is tied to it (§`refuseTiedRows`). */
|
|
12
|
+
(0, shell_1.registerKindTie)(payment_1.Payment, { kind: 'targetType', id: 'targetId' });
|
|
10
13
|
exports.entities = [payment_1.Payment, payment_history_1.PaymentHistory];
|
|
11
14
|
exports.resolvers = [payment_query_1.PaymentQuery, payment_mutation_1.PaymentMutation];
|
|
12
15
|
exports.subscribers = [event_subscriber_1.PaymentHistoryEntitySubscriber];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/payment/index.ts"],"names":[],"mappings":";;;AAAA,uCAAmC;AACnC,uDAAkD;AAClD,yDAAmE;AACnE,mDAA8C;AAC9C,yDAAoD;AACpD,6BAA0B;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/payment/index.ts"],"names":[],"mappings":";;;AAAA,uCAAmC;AACnC,uDAAkD;AAClD,yDAAmE;AACnE,mDAA8C;AAC9C,yDAAoD;AACpD,6BAA0B;AAE1B,iDAAuD;AAEvD,6HAA6H;AAC7H,IAAA,uBAAe,EAAC,iBAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAA;AAEnD,QAAA,QAAQ,GAAG,CAAC,iBAAO,EAAE,gCAAc,CAAC,CAAA;AACpC,QAAA,SAAS,GAAG,CAAC,4BAAY,EAAE,kCAAe,CAAC,CAAA;AAC3C,QAAA,WAAW,GAAG,CAAC,iDAA8B,CAAC,CAAA","sourcesContent":["import { Payment } from './payment'\nimport { PaymentHistory } from './payment-history'\nimport { PaymentHistoryEntitySubscriber } from './event-subscriber'\nimport { PaymentQuery } from './payment-query'\nimport { PaymentMutation } from './payment-mutation'\nimport './transfer-target'\n\nimport { registerKindTie } from '@things-factory/shell'\n\n/* A payment names what it paid by kind and id (§`registerPaymentTarget`); what it pays is tied to it (§`refuseTiedRows`). */\nregisterKindTie(Payment, { kind: 'targetType', id: 'targetId' })\n\nexport const entities = [Payment, PaymentHistory]\nexport const resolvers = [PaymentQuery, PaymentMutation]\nexport const subscribers = [PaymentHistoryEntitySubscriber]\n"]}
|
|
@@ -10,7 +10,10 @@ export type RecurringCashItemInput = Partial<Omit<RecurringCashItem, 'account' |
|
|
|
10
10
|
id: string;
|
|
11
11
|
} | null;
|
|
12
12
|
};
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Apply rows to a domain's recurring items: `+` (or no id) adds, `M` changes, `-` deletes (softly). An item its forecast
|
|
15
|
+
* lines were made from is not deleted while they are there (§`refuseTiedRows`).
|
|
16
|
+
*/
|
|
14
17
|
export declare function saveRecurringCashItems(tx: EntityManager, domain: {
|
|
15
18
|
id: string;
|
|
16
19
|
}, user: any, inputs: RecurringCashItemInput[]): Promise<RecurringCashItem[]>;
|
|
@@ -31,7 +31,10 @@ function rowOf(input, current) {
|
|
|
31
31
|
throw new shell_1.Refusal('recurring-amount-required', {}, 'amount: every month');
|
|
32
32
|
return row;
|
|
33
33
|
}
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Apply rows to a domain's recurring items: `+` (or no id) adds, `M` changes, `-` deletes (softly). An item its forecast
|
|
36
|
+
* lines were made from is not deleted while they are there (§`refuseTiedRows`).
|
|
37
|
+
*/
|
|
35
38
|
async function saveRecurringCashItems(tx, domain, user, inputs) {
|
|
36
39
|
const repo = tx.getRepository(recurring_cash_item_1.RecurringCashItem);
|
|
37
40
|
const deletes = [...new Set(inputs.filter(one => one.cuFlag === '-' && one.id).map(one => one.id))];
|
|
@@ -39,6 +42,7 @@ async function saveRecurringCashItems(tx, domain, user, inputs) {
|
|
|
39
42
|
const found = await repo.find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(deletes) } });
|
|
40
43
|
if (found.length !== deletes.length)
|
|
41
44
|
throw new shell_1.Refusal('recurring-not-found', {}, 'a recurring item was not found - reload and try again');
|
|
45
|
+
await (0, shell_1.refuseTiedRows)(tx, recurring_cash_item_1.RecurringCashItem, deletes);
|
|
42
46
|
await repo.softRemove(found);
|
|
43
47
|
}
|
|
44
48
|
const saved = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recurring-cash-item-service.js","sourceRoot":"","sources":["../../../server/service/recurring-cash-item/recurring-cash-item-service.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"recurring-cash-item-service.js","sourceRoot":"","sources":["../../../server/service/recurring-cash-item/recurring-cash-item-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Refusal, refuseTiedRows } from '@things-factory/shell'\n\nimport { ForecastStatus, Transaction, TransactionCategory } from '../transaction/transaction'\nimport { saveTransactions } from '../transaction/transaction-service'\nimport { RecurringCashItem } from './recurring-cash-item'\nimport { linesFor } from './recurring-schedule'\n\nconst MONTH = /^\\d{4}-(0[1-9]|1[0-2])$/\n\nexport type RecurringCashItemInput = Partial<Omit<RecurringCashItem, 'account' | 'counterparty'>> & {\n id?: string\n cuFlag?: string\n account?: { id: string } | null\n counterparty?: { id: string } | null\n}\n\nfunction rowOf(input: RecurringCashItemInput, current: RecurringCashItem | undefined): Record<string, any> {\n const { id, cuFlag, ...row } = input as Record<string, any>\n const merged = { ...current, ...row }\n if (!String(merged.name ?? '').trim()) throw new Refusal('recurring-name-required', {}, 'name: what it is')\n if (!merged.type) throw new Refusal('transaction-type-required', {}, 'type: money in or money out')\n if (!MONTH.test(String(merged.startMonth ?? '')))\n throw new Refusal('recurring-start-required', {}, 'startMonth: YYYY-MM')\n if (merged.endMonth && !MONTH.test(merged.endMonth))\n throw new Refusal('recurring-end-not-a-month', {}, 'endMonth: YYYY-MM')\n if (merged.endMonth && merged.endMonth < merged.startMonth)\n throw new Refusal('recurring-end-before-start', {}, 'endMonth: before startMonth')\n if (\n merged.dayOfMonth !== null &&\n merged.dayOfMonth !== undefined &&\n !(merged.dayOfMonth >= 1 && merged.dayOfMonth <= 31)\n ) {\n throw new Refusal('day-of-month-out-of-range', {}, 'dayOfMonth: must be 1 to 31')\n }\n if (!current && (row.amount === undefined || row.amount === null))\n throw new Refusal('recurring-amount-required', {}, 'amount: every month')\n return row\n}\n\n/**\n * Apply rows to a domain's recurring items: `+` (or no id) adds, `M` changes, `-` deletes (softly). An item its forecast\n * lines were made from is not deleted while they are there (§`refuseTiedRows`).\n */\nexport async function saveRecurringCashItems(\n tx: EntityManager,\n domain: { id: string },\n user: any,\n inputs: RecurringCashItemInput[]\n): Promise<RecurringCashItem[]> {\n const repo = tx.getRepository(RecurringCashItem)\n const deletes = [...new Set(inputs.filter(one => one.cuFlag === '-' && one.id).map(one => one.id!))]\n if (deletes.length) {\n const found = await repo.find({ where: { domain: { id: domain.id }, id: In(deletes) } })\n if (found.length !== deletes.length)\n throw new Refusal('recurring-not-found', {}, 'a recurring item was not found - reload and try again')\n await refuseTiedRows(tx, RecurringCashItem, deletes)\n await repo.softRemove(found)\n }\n\n const saved: RecurringCashItem[] = []\n for (const input of inputs.filter(one => one.cuFlag !== '-')) {\n const isNew = !input.id || input.cuFlag === '+'\n const current = isNew ? undefined : await repo.findOne({ where: { domain: { id: domain.id }, id: input.id } })\n if (!isNew && !current)\n throw new Refusal('recurring-not-found', {}, 'a recurring item was not found - reload and try again')\n saved.push(\n await repo.save({\n ...(current ?? { domain, creator: user }),\n ...rowOf(input, current),\n updater: user\n } as RecurringCashItem)\n )\n }\n return saved\n}\n\n/**\n * Make the month's forecasts from the recurring items. A forecast already made from an item for that month is not\n * made again, so running it twice changes nothing. Returns how many were made.\n */\nexport async function makeForecasts(\n tx: EntityManager,\n domain: { id: string },\n user: any,\n year: number,\n month: number\n): Promise<number> {\n if (!(month >= 1 && month <= 12)) throw new Refusal('month-out-of-range', { month }, 'month: must be 1 to 12')\n\n const items = await tx.getRepository(RecurringCashItem).find({ where: { domain: { id: domain.id } } })\n const made = await tx\n .getRepository(Transaction)\n .find({\n where: { domain: { id: domain.id }, category: TransactionCategory.FORECAST, year, month },\n relations: ['recurringItem']\n })\n const already = new Set(made.map(one => one.recurringItem?.id).filter(Boolean) as string[])\n\n const lines = linesFor(items, year, month, already)\n await saveTransactions(\n tx,\n domain,\n user,\n lines.map(line => {\n return {\n cuFlag: '+',\n category: TransactionCategory.FORECAST,\n type: line.type as any,\n year: line.year,\n month: line.month,\n description: line.name,\n amount: line.amount,\n currency: line.currency,\n timing: line.timing ?? undefined,\n status: ForecastStatus.PLANNED,\n recurringItem: { id: line.recurringItemId }\n }\n })\n )\n\n return lines.length\n}\n"]}
|
|
@@ -26,8 +26,9 @@ export declare function protectBankFacts(current: Partial<Transaction> & {
|
|
|
26
26
|
}, patch: Record<string, any>): void;
|
|
27
27
|
/**
|
|
28
28
|
* Apply rows to a domain's transactions: `+` (or no id) adds, `M` changes, `-` deletes (softly - a financial row
|
|
29
|
-
* that was deleted stays readable). A transaction that pays something,
|
|
30
|
-
* deleted; when its money changes, its payments are checked again - the general rule
|
|
29
|
+
* that was deleted stays readable). A transaction that pays something, is paid, or is named by another row is unlinked
|
|
30
|
+
* before it is deleted (§`refuseTiedRows`); when its money changes, its payments are checked again - the general rule
|
|
31
|
+
* and each target kind's own.
|
|
31
32
|
* A line from a bank statement keeps the statement's facts (§`protectBankFacts`).
|
|
32
33
|
*/
|
|
33
34
|
export declare function saveTransactions(tx: EntityManager, domain: {
|
|
@@ -105,8 +105,9 @@ async function paymentsOn(tx, domain, ids) {
|
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
107
|
* Apply rows to a domain's transactions: `+` (or no id) adds, `M` changes, `-` deletes (softly - a financial row
|
|
108
|
-
* that was deleted stays readable). A transaction that pays something,
|
|
109
|
-
* deleted; when its money changes, its payments are checked again - the general rule
|
|
108
|
+
* that was deleted stays readable). A transaction that pays something, is paid, or is named by another row is unlinked
|
|
109
|
+
* before it is deleted (§`refuseTiedRows`); when its money changes, its payments are checked again - the general rule
|
|
110
|
+
* and each target kind's own.
|
|
110
111
|
* A line from a bank statement keeps the statement's facts (§`protectBankFacts`).
|
|
111
112
|
*/
|
|
112
113
|
async function saveTransactions(tx, domain, user, inputs) {
|
|
@@ -116,8 +117,7 @@ async function saveTransactions(tx, domain, user, inputs) {
|
|
|
116
117
|
const found = await repo.find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(deletes) } });
|
|
117
118
|
if (found.length !== deletes.length)
|
|
118
119
|
throw new shell_1.Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again');
|
|
119
|
-
|
|
120
|
-
throw new shell_1.Refusal('transaction-has-payments', {}, 'unlink what the transaction paid before deleting it');
|
|
120
|
+
await (0, shell_1.refuseTiedRows)(tx, transaction_1.Transaction, deletes);
|
|
121
121
|
await repo.softRemove(found);
|
|
122
122
|
}
|
|
123
123
|
const saved = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-service.js","sourceRoot":"","sources":["../../../server/service/transaction/transaction-service.ts"],"names":[],"mappings":";;AAmCA,4CAYC;AAoFD,4CAoFC;AAvND,qCAA2C;AAE3C,iDAA+C;AAE/C,uDAAuD;AAEvD,gDAA4C;AAC5C,+DAA0D;AAC1D,qEAAgE;AAChE,oFAA8E;AAC9E,sDAAgD;AAChD,gDAA4C;AAC5C,kEAAoE;AACpE,gEAAgE;AAChE,gEAA0E;AAC1E,+CAAmG;AACnG,6DAA+D;AAe/D,uHAAuH;AACvH,MAAM,UAAU,GAAG,CAAC,iBAAiB,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,CAAU,CAAA;AAEvG,0FAA0F;AAC1F,SAAgB,gBAAgB,CAAC,OAA0D,EAAE,KAA0B;IACrH,IAAI,OAAO,CAAC,MAAM,KAAK,+BAAiB,CAAC,cAAc;QAAE,OAAM;IAC/D,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC;YAAE,SAAQ;QAC/B,MAAM,MAAM,GAAG,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAE,OAAe,CAAC,KAAK,CAAC,CAAA;QACnH,MAAM,KAAK,GAAG,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC5E,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YACjD,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5G,CAAC,CAAC,MAAM,KAAK,KAAK,CAAA;QACpB,IAAI,CAAC,KAAK;YACR,MAAM,IAAI,eAAO,CAAC,mBAAmB,EAAE,EAAE,EAAE,8EAA8E,CAAC,CAAA;IAC9H,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,GAA0B;IACxC,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,iBAAO,CAAC;IAC1B,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,uBAAY,CAAC;IACpC,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,uCAAiB,CAAC;IAC1C,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,8BAAa,CAAC;CACvC,CAAA;AAED,gHAAgH;AAChH,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,CAAU,CAAA;AAExE;;;GAGG;AACH,SAAS,KAAK,CAAC,KAAuB,EAAE,OAAgC;IACtE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,CAAA;IACvC,MAAM,GAAG,GAAwB,EAAE,GAAG,MAAM,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,EAAE,CAAA;IACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,iCAAmB,CAAC,SAAS,CAAA;IACjE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAEvB,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI;QAAE,MAAM,IAAI,eAAO,CAAC,2BAA2B,EAAE,EAAE,EAAE,6BAA6B,CAAC,CAAA;IAC5G,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,6BAAY,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAC3E,MAAM,IAAI,eAAO,CAAC,2BAA2B,EAAE,EAAE,EAAE,6BAA6B,CAAC,CAAA;IACnF,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC;QAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;IACjF,wFAAwF;IACxF,IAAI,UAAU,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAA;IAE5D,IAAI,QAAQ,KAAK,iCAAmB,CAAC,SAAS,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAA,gCAAW,EAAC,MAAM,CAAC,eAAe,CAAC,CAAA;QAClD,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,eAAO,CACf,2BAA2B,EAC3B,EAAE,KAAK,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE,EAAE,EACvC,6BAA6B,CAC9B,CAAA;QACH,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9C,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACjE,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,iCAAiC,CAAC,CAAA;QAC7F,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,eAAO,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,EAAE,wBAAwB,CAAC,CAAA;QAClG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;YAC1C,MAAM,IAAI,eAAO,CAAC,+BAA+B,EAAE,EAAE,EAAE,8BAA8B,CAAC,CAAA;QACxF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,eAAe,EAAE,IAAA,gCAAW,EAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC7F,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,GAAG,CAAC,MAAM,GAAG,4BAAc,CAAC,OAAO,CAAA;IACzD,CAAC;IAED,IACE,MAAM,CAAC,WAAW,KAAK,SAAS;QAChC,MAAM,CAAC,WAAW,KAAK,IAAI;QAC3B,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,IAAI,MAAM,CAAC,WAAW,IAAI,GAAG,CAAC,EACvD,CAAC;QACD,MAAM,IAAI,eAAO,CAAC,0BAA0B,EAAE,EAAE,EAAE,+BAA+B,CAAC,CAAA;IACpF,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,uFAAuF;AACvF,KAAK,UAAU,UAAU,CAAC,EAAiB,EAAE,MAAsB,EAAE,GAAa;IAChF,IAAI,CAAC,GAAG,CAAC,MAAM;QAAE,OAAO,EAAE,CAAA;IAC1B,MAAM,IAAI,GAAG,EAAE,CAAC,aAAa,CAAC,iBAAO,CAAC,CAAA;IACtC,OAAO;QACL,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC;YAClB,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;YAClE,SAAS,EAAE,CAAC,aAAa,CAAC;SAC3B,CAAC,CAAC;QACH,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC;YAClB,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAA,YAAE,EAAC,GAAG,CAAC,EAAE;YAClF,SAAS,EAAE,CAAC,aAAa,CAAC;SAC3B,CAAC,CAAC;KACJ,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,gBAAgB,CACpC,EAAiB,EACjB,MAAsB,EACtB,IAAS,EACT,MAA0B;IAE1B,MAAM,IAAI,GAAG,EAAE,CAAC,aAAa,CAAC,yBAAW,CAAC,CAAA;IAE1C,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAG,CAAC,CAAC,CAAC,CAAA;IACpG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,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,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;QACxF,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM;YACjC,MAAM,IAAI,eAAO,CAAC,uBAAuB,EAAE,EAAE,EAAE,oDAAoD,CAAC,CAAA;QACtG,IAAI,CAAC,MAAM,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM;YAChD,MAAM,IAAI,eAAO,CAAC,0BAA0B,EAAE,EAAE,EAAE,qDAAqD,CAAC,CAAA;QAC1G,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,KAAK,GAAkB,EAAE,CAAA;IAC/B,MAAM,YAAY,GAAa,EAAE,CAAA;IACjC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAA;QAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QAC9G,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO;YACpB,MAAM,IAAI,eAAO,CAAC,uBAAuB,EAAE,EAAE,EAAE,oDAAoD,CAAC,CAAA;QAEtG,IAAI,OAAO;YAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QACjC,IAAI,GAAG,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,MAAM,EAAE;iBACrB,aAAa,CAAC,0BAAW,CAAC;iBAC1B,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YAC5E,IAAI,CAAC,OAAO;gBACV,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,uDAAuD,CAAC,CAAA;YAC1G,IAAI,OAAO,CAAC,QAAQ;gBAAE,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QACvD,CAAC;QAED,6GAA6G;QAC7G,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,UAAU;YACtC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;gBACtJ,MAAM,IAAI,eAAO,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,uCAAuC,CAAC,CAAA;QAEpH,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;YAC/G,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,OAAO,EAAE,EAAE;gBACjC,MAAM,IAAI,eAAO,CACf,iBAAiB,EACjB,EAAE,GAAG,EAAE,IAAI,CAAC,eAAe,IAAI,EAAE,EAAE,EACnC,wCAAwC,CACzC,CAAA;QACL,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,IAAI,EAAiB,CAAC,CAAA;QACpH,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAM,OAAe,CAAC,KAAK,CAAC,CAAC;YACxF,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC/B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACrB,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,CAAA;QAC3D,MAAM,IAAA,qCAAmB,EACvB,EAAE,EACF,MAAM,EACN,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CACxC,CAAA;QACD,MAAM,IAAA,yCAAsB,EAC1B,EAAE,EACF,MAAM,EACN,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CACxC,CAAA;QACD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAA;QAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ;YAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;QAClH,MAAM,SAAS,GAAG,CAAC,MAAiB,EAAE,EAAE,CAAC,CAAC;YACxC,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;YACxD,cAAc,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;SACpE,CAAC,CAAA;QACF,KAAK,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,KAAK;YACtC,MAAM,IAAA,iCAAe,EAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;QAC9E,KAAK,MAAM,IAAI,IAAI,IAAA,8BAAY,GAAE;YAAE,MAAM,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACpI,KAAK,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,KAAK;YACtC,MAAM,IAAA,iCAAe,EAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/E,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Refusal } from '@things-factory/shell'\n\nimport { Counterparty } from '@things-factory/biz-base'\n\nimport { Account } from '../account/account'\nimport { BankAccount } from '../bank-account/bank-account'\nimport { BankStatement } from '../bank-statement/bank-statement'\nimport { RecurringCashItem } from '../recurring-cash-item/recurring-cash-item'\nimport { CashFlowType } from '../cash-flow-type'\nimport { Payment } from '../payment/payment'\nimport { checkPaymentCurrencies } from '../payment/payment-currency'\nimport { checkPaymentsWithin } from '../payment/payment-service'\nimport { paymentRules, paymentTargetOf } from '../payment/payment-targets'\nimport { ForecastStatus, Transaction, TransactionCategory, TransactionSource } from './transaction'\nimport { forecastDay, yearMonthOf } from './transaction-period'\n\n/** A transaction as a module writes it: what a person may write, and the facts a bank statement gives. */\nexport type TransactionInput = Partial<\n Omit<Transaction, 'bankAccount' | 'account' | 'counterparty' | 'recurringItem' | 'bankStatement'>\n> & {\n id?: string\n cuFlag?: string\n bankAccount?: { id: string } | null\n account?: { id: string } | null\n counterparty?: { id: string } | null\n recurringItem?: { id: string } | null\n bankStatement?: { id: string } | null\n}\n\n/** What a bank statement says of a line - changed only by a statement; what a person writes beside them stays open. */\nconst BANK_FACTS = ['transactionDate', 'type', 'amount', 'balance', 'currency', 'bankAccount'] as const\n\n/** A line that came from a bank statement keeps the statement's facts (§`BANK_FACTS`). */\nexport function protectBankFacts(current: Partial<Transaction> & { bankAccountId?: string }, patch: Record<string, any>): void {\n if (current.source !== TransactionSource.BANK_STATEMENT) return\n for (const field of BANK_FACTS) {\n if (!(field in patch)) continue\n const before = field === 'bankAccount' ? current.bankAccountId ?? current.bankAccount?.id : (current as any)[field]\n const after = field === 'bankAccount' ? patch.bankAccount?.id : patch[field]\n const equal = ['amount', 'balance'].includes(field)\n ? (before == null && after == null) || (before != null && after != null && Number(before) === Number(after))\n : before === after\n if (!equal)\n throw new Refusal('bank-facts-locked', {}, 'Bank facts can only be updated from a statement; annotations remain editable')\n }\n}\n\n/** The rows a transaction names besides its bank account, each of the caller's domain. */\nconst REFERENCES: [string, () => any][] = [\n ['account', () => Account],\n ['counterparty', () => Counterparty],\n ['recurringItem', () => RecurringCashItem],\n ['bankStatement', () => BankStatement]\n]\n\n/** What its payments depend on - they are checked again, and their owners follow, when one of these changes. */\nconst FACTS = ['amount', 'type', 'currency', 'transactionDate'] as const\n\n/**\n * The row a patch writes over the current one: a confirmed transaction has a day and takes its year and month from it;\n * a forecast has a year and a month, and the day its timing names.\n */\nfunction rowOf(input: TransactionInput, current: Transaction | undefined): Record<string, any> {\n const { id, cuFlag, ...fields } = input\n const row: Record<string, any> = { ...fields }\n const merged = { ...current, ...row }\n const category = merged.category ?? TransactionCategory.CONFIRMED\n row.category = category\n\n if (!current && !row.type) throw new Refusal('transaction-type-required', {}, 'type: money in or money out')\n if (row.type !== undefined && !Object.values(CashFlowType).includes(row.type))\n throw new Refusal('transaction-type-required', {}, 'type: money in or money out')\n if (!current && (row.amount === undefined || row.amount === null)) row.amount = 0\n /* An emptied currency is won, the column's own default - a row is never without one. */\n if ('currency' in row && !row.currency) row.currency = 'KRW'\n\n if (category === TransactionCategory.CONFIRMED) {\n const period = yearMonthOf(merged.transactionDate)\n if (!period)\n throw new Refusal(\n 'transaction-date-required',\n { value: merged.transactionDate ?? '' },\n 'transactionDate: YYYY-MM-DD'\n )\n Object.assign(row, period, { status: null })\n } else {\n const [year, month] = [Number(merged.year), Number(merged.month)]\n if (!year) throw new Refusal('forecast-year-required', {}, 'year: the year it is planned in')\n if (!(month >= 1 && month <= 12))\n throw new Refusal('month-out-of-range', { month: merged.month ?? '' }, 'month: must be 1 to 12')\n if (!String(merged.description ?? '').trim())\n throw new Refusal('forecast-description-required', {}, 'description: what is planned')\n Object.assign(row, { year, month, transactionDate: forecastDay(year, month, merged.timing) })\n if (!merged.status) row.status = ForecastStatus.PLANNED\n }\n\n if (\n merged.probability !== undefined &&\n merged.probability !== null &&\n !(merged.probability >= 0 && merged.probability <= 100)\n ) {\n throw new Refusal('probability-out-of-range', {}, 'probability: must be 0 to 100')\n }\n\n return row\n}\n\n/** The payments on these transactions, and the transfers into them, by target kind. */\nasync function paymentsOn(tx: EntityManager, domain: { id: string }, ids: string[]): Promise<Payment[]> {\n if (!ids.length) return []\n const repo = tx.getRepository(Payment)\n return [\n ...(await repo.find({\n where: { domain: { id: domain.id }, transaction: { id: In(ids) } },\n relations: ['transaction']\n })),\n ...(await repo.find({\n where: { domain: { id: domain.id }, targetType: 'Transaction', targetId: In(ids) },\n relations: ['transaction']\n }))\n ]\n}\n\n/**\n * Apply rows to a domain's transactions: `+` (or no id) adds, `M` changes, `-` deletes (softly - a financial row\n * that was deleted stays readable). A transaction that pays something, or is paid, is unlinked before it is\n * deleted; when its money changes, its payments are checked again - the general rule and each target kind's own.\n * A line from a bank statement keeps the statement's facts (§`protectBankFacts`).\n */\nexport async function saveTransactions(\n tx: EntityManager,\n domain: { id: string },\n user: any,\n inputs: TransactionInput[]\n): Promise<Transaction[]> {\n const repo = tx.getRepository(Transaction)\n\n const deletes = [...new Set(inputs.filter(one => one.cuFlag === '-' && one.id).map(one => one.id!))]\n if (deletes.length) {\n const found = await repo.find({ where: { domain: { id: domain.id }, id: In(deletes) } })\n if (found.length !== deletes.length)\n throw new Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again')\n if ((await paymentsOn(tx, domain, deletes)).length)\n throw new Refusal('transaction-has-payments', {}, 'unlink what the transaction paid before deleting it')\n await repo.softRemove(found)\n }\n\n const saved: Transaction[] = []\n const factsChanged: string[] = []\n for (const input of inputs.filter(one => one.cuFlag !== '-')) {\n const isNew = !input.id || input.cuFlag === '+'\n const current = isNew ? undefined : await repo.findOne({ where: { domain: { id: domain.id }, id: input.id } })\n if (!isNew && !current)\n throw new Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again')\n\n if (current) protectBankFacts(current, input)\n const row = rowOf(input, current)\n if (row.bankAccount?.id && !('currency' in input)) {\n const account = await tx\n .getRepository(BankAccount)\n .findOne({ where: { domain: { id: domain.id }, id: row.bankAccount.id } })\n if (!account)\n throw new Refusal('bank-account-not-found', {}, 'the bank account was not found - reload and try again')\n if (account.currency) row.currency = account.currency\n }\n\n /* What a row names is the caller's own - never another domain's account, counterparty, item or statement. */\n for (const [field, entity] of REFERENCES)\n if (row[field]?.id && !(await tx.getRepository(entity()).findOne({ where: { domain: { id: domain.id }, id: row[field].id } as any, withDeleted: true })))\n throw new Refusal('transaction-reference-not-found', { field }, `${field} was not found - reload and try again`)\n\n if (row.bankFingerprint) {\n const twin = await repo.findOne({ where: { domain: { id: domain.id }, bankFingerprint: row.bankFingerprint } })\n if (twin && twin.id !== current?.id)\n throw new Refusal(\n 'bank-line-twice',\n { day: twin.transactionDate ?? '' },\n 'this bank line is already in the books'\n )\n }\n\n const written = await repo.save({ ...(current ?? { domain, creator: user }), ...row, updater: user } as Transaction)\n if (current && FACTS.some(field => field in row && row[field] !== (current as any)[field]))\n factsChanged.push(current.id)\n saved.push(written)\n }\n\n if (factsChanged.length) {\n const payments = await paymentsOn(tx, domain, factsChanged)\n await checkPaymentsWithin(\n tx,\n domain,\n payments.map(one => one.transaction.id)\n )\n await checkPaymentCurrencies(\n tx,\n domain,\n payments.map(one => one.transaction.id)\n )\n const kinds = new Map<string, Payment[]>()\n for (const payment of payments) kinds.set(payment.targetType, [...(kinds.get(payment.targetType) ?? []), payment])\n const touchedOf = (ofKind: Payment[]) => ({\n targetIds: [...new Set(ofKind.map(one => one.targetId))],\n transactionIds: [...new Set(ofKind.map(one => one.transaction.id))]\n })\n for (const [targetType, ofKind] of kinds)\n await paymentTargetOf(targetType)?.validate?.(tx, domain, touchedOf(ofKind))\n for (const rule of paymentRules()) await rule(tx, domain, { transactionIds: [...new Set(payments.map(one => one.transaction.id))] })\n for (const [targetType, ofKind] of kinds)\n await paymentTargetOf(targetType)?.onSaved?.(tx, domain, touchedOf(ofKind))\n }\n\n return saved\n}\n"]}
|
|
1
|
+
{"version":3,"file":"transaction-service.js","sourceRoot":"","sources":["../../../server/service/transaction/transaction-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Refusal, refuseTiedRows } from '@things-factory/shell'\n\nimport { Counterparty } from '@things-factory/biz-base'\n\nimport { Account } from '../account/account'\nimport { BankAccount } from '../bank-account/bank-account'\nimport { BankStatement } from '../bank-statement/bank-statement'\nimport { RecurringCashItem } from '../recurring-cash-item/recurring-cash-item'\nimport { CashFlowType } from '../cash-flow-type'\nimport { Payment } from '../payment/payment'\nimport { checkPaymentCurrencies } from '../payment/payment-currency'\nimport { checkPaymentsWithin } from '../payment/payment-service'\nimport { paymentRules, paymentTargetOf } from '../payment/payment-targets'\nimport { ForecastStatus, Transaction, TransactionCategory, TransactionSource } from './transaction'\nimport { forecastDay, yearMonthOf } from './transaction-period'\n\n/** A transaction as a module writes it: what a person may write, and the facts a bank statement gives. */\nexport type TransactionInput = Partial<\n Omit<Transaction, 'bankAccount' | 'account' | 'counterparty' | 'recurringItem' | 'bankStatement'>\n> & {\n id?: string\n cuFlag?: string\n bankAccount?: { id: string } | null\n account?: { id: string } | null\n counterparty?: { id: string } | null\n recurringItem?: { id: string } | null\n bankStatement?: { id: string } | null\n}\n\n/** What a bank statement says of a line - changed only by a statement; what a person writes beside them stays open. */\nconst BANK_FACTS = ['transactionDate', 'type', 'amount', 'balance', 'currency', 'bankAccount'] as const\n\n/** A line that came from a bank statement keeps the statement's facts (§`BANK_FACTS`). */\nexport function protectBankFacts(current: Partial<Transaction> & { bankAccountId?: string }, patch: Record<string, any>): void {\n if (current.source !== TransactionSource.BANK_STATEMENT) return\n for (const field of BANK_FACTS) {\n if (!(field in patch)) continue\n const before = field === 'bankAccount' ? current.bankAccountId ?? current.bankAccount?.id : (current as any)[field]\n const after = field === 'bankAccount' ? patch.bankAccount?.id : patch[field]\n const equal = ['amount', 'balance'].includes(field)\n ? (before == null && after == null) || (before != null && after != null && Number(before) === Number(after))\n : before === after\n if (!equal)\n throw new Refusal('bank-facts-locked', {}, 'Bank facts can only be updated from a statement; annotations remain editable')\n }\n}\n\n/** The rows a transaction names besides its bank account, each of the caller's domain. */\nconst REFERENCES: [string, () => any][] = [\n ['account', () => Account],\n ['counterparty', () => Counterparty],\n ['recurringItem', () => RecurringCashItem],\n ['bankStatement', () => BankStatement]\n]\n\n/** What its payments depend on - they are checked again, and their owners follow, when one of these changes. */\nconst FACTS = ['amount', 'type', 'currency', 'transactionDate'] as const\n\n/**\n * The row a patch writes over the current one: a confirmed transaction has a day and takes its year and month from it;\n * a forecast has a year and a month, and the day its timing names.\n */\nfunction rowOf(input: TransactionInput, current: Transaction | undefined): Record<string, any> {\n const { id, cuFlag, ...fields } = input\n const row: Record<string, any> = { ...fields }\n const merged = { ...current, ...row }\n const category = merged.category ?? TransactionCategory.CONFIRMED\n row.category = category\n\n if (!current && !row.type) throw new Refusal('transaction-type-required', {}, 'type: money in or money out')\n if (row.type !== undefined && !Object.values(CashFlowType).includes(row.type))\n throw new Refusal('transaction-type-required', {}, 'type: money in or money out')\n if (!current && (row.amount === undefined || row.amount === null)) row.amount = 0\n /* An emptied currency is won, the column's own default - a row is never without one. */\n if ('currency' in row && !row.currency) row.currency = 'KRW'\n\n if (category === TransactionCategory.CONFIRMED) {\n const period = yearMonthOf(merged.transactionDate)\n if (!period)\n throw new Refusal(\n 'transaction-date-required',\n { value: merged.transactionDate ?? '' },\n 'transactionDate: YYYY-MM-DD'\n )\n Object.assign(row, period, { status: null })\n } else {\n const [year, month] = [Number(merged.year), Number(merged.month)]\n if (!year) throw new Refusal('forecast-year-required', {}, 'year: the year it is planned in')\n if (!(month >= 1 && month <= 12))\n throw new Refusal('month-out-of-range', { month: merged.month ?? '' }, 'month: must be 1 to 12')\n if (!String(merged.description ?? '').trim())\n throw new Refusal('forecast-description-required', {}, 'description: what is planned')\n Object.assign(row, { year, month, transactionDate: forecastDay(year, month, merged.timing) })\n if (!merged.status) row.status = ForecastStatus.PLANNED\n }\n\n if (\n merged.probability !== undefined &&\n merged.probability !== null &&\n !(merged.probability >= 0 && merged.probability <= 100)\n ) {\n throw new Refusal('probability-out-of-range', {}, 'probability: must be 0 to 100')\n }\n\n return row\n}\n\n/** The payments on these transactions, and the transfers into them, by target kind. */\nasync function paymentsOn(tx: EntityManager, domain: { id: string }, ids: string[]): Promise<Payment[]> {\n if (!ids.length) return []\n const repo = tx.getRepository(Payment)\n return [\n ...(await repo.find({\n where: { domain: { id: domain.id }, transaction: { id: In(ids) } },\n relations: ['transaction']\n })),\n ...(await repo.find({\n where: { domain: { id: domain.id }, targetType: 'Transaction', targetId: In(ids) },\n relations: ['transaction']\n }))\n ]\n}\n\n/**\n * Apply rows to a domain's transactions: `+` (or no id) adds, `M` changes, `-` deletes (softly - a financial row\n * that was deleted stays readable). A transaction that pays something, is paid, or is named by another row is unlinked\n * before it is deleted (§`refuseTiedRows`); when its money changes, its payments are checked again - the general rule\n * and each target kind's own.\n * A line from a bank statement keeps the statement's facts (§`protectBankFacts`).\n */\nexport async function saveTransactions(\n tx: EntityManager,\n domain: { id: string },\n user: any,\n inputs: TransactionInput[]\n): Promise<Transaction[]> {\n const repo = tx.getRepository(Transaction)\n\n const deletes = [...new Set(inputs.filter(one => one.cuFlag === '-' && one.id).map(one => one.id!))]\n if (deletes.length) {\n const found = await repo.find({ where: { domain: { id: domain.id }, id: In(deletes) } })\n if (found.length !== deletes.length)\n throw new Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again')\n await refuseTiedRows(tx, Transaction, deletes)\n await repo.softRemove(found)\n }\n\n const saved: Transaction[] = []\n const factsChanged: string[] = []\n for (const input of inputs.filter(one => one.cuFlag !== '-')) {\n const isNew = !input.id || input.cuFlag === '+'\n const current = isNew ? undefined : await repo.findOne({ where: { domain: { id: domain.id }, id: input.id } })\n if (!isNew && !current)\n throw new Refusal('transaction-not-found', {}, 'a transaction was not found - reload and try again')\n\n if (current) protectBankFacts(current, input)\n const row = rowOf(input, current)\n if (row.bankAccount?.id && !('currency' in input)) {\n const account = await tx\n .getRepository(BankAccount)\n .findOne({ where: { domain: { id: domain.id }, id: row.bankAccount.id } })\n if (!account)\n throw new Refusal('bank-account-not-found', {}, 'the bank account was not found - reload and try again')\n if (account.currency) row.currency = account.currency\n }\n\n /* What a row names is the caller's own - never another domain's account, counterparty, item or statement. */\n for (const [field, entity] of REFERENCES)\n if (row[field]?.id && !(await tx.getRepository(entity()).findOne({ where: { domain: { id: domain.id }, id: row[field].id } as any, withDeleted: true })))\n throw new Refusal('transaction-reference-not-found', { field }, `${field} was not found - reload and try again`)\n\n if (row.bankFingerprint) {\n const twin = await repo.findOne({ where: { domain: { id: domain.id }, bankFingerprint: row.bankFingerprint } })\n if (twin && twin.id !== current?.id)\n throw new Refusal(\n 'bank-line-twice',\n { day: twin.transactionDate ?? '' },\n 'this bank line is already in the books'\n )\n }\n\n const written = await repo.save({ ...(current ?? { domain, creator: user }), ...row, updater: user } as Transaction)\n if (current && FACTS.some(field => field in row && row[field] !== (current as any)[field]))\n factsChanged.push(current.id)\n saved.push(written)\n }\n\n if (factsChanged.length) {\n const payments = await paymentsOn(tx, domain, factsChanged)\n await checkPaymentsWithin(\n tx,\n domain,\n payments.map(one => one.transaction.id)\n )\n await checkPaymentCurrencies(\n tx,\n domain,\n payments.map(one => one.transaction.id)\n )\n const kinds = new Map<string, Payment[]>()\n for (const payment of payments) kinds.set(payment.targetType, [...(kinds.get(payment.targetType) ?? []), payment])\n const touchedOf = (ofKind: Payment[]) => ({\n targetIds: [...new Set(ofKind.map(one => one.targetId))],\n transactionIds: [...new Set(ofKind.map(one => one.transaction.id))]\n })\n for (const [targetType, ofKind] of kinds)\n await paymentTargetOf(targetType)?.validate?.(tx, domain, touchedOf(ofKind))\n for (const rule of paymentRules()) await rule(tx, domain, { transactionIds: [...new Set(payments.map(one => one.transaction.id))] })\n for (const [targetType, ofKind] of kinds)\n await paymentTargetOf(targetType)?.onSaved?.(tx, domain, touchedOf(ofKind))\n }\n\n return saved\n}\n"]}
|