Compare commits

...

5 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
93841af533 chore: configure gitpod 2023-11-04 15:32:50 +02:00
Ahmed Bouhuolia
121d992b68 chore: updating CONTRIBUTING.md 2023-11-02 22:57:41 +02:00
Ahmed Bouhuolia
078a7ea51c fix: change Dockerfile files with new pnpm (#278) 2023-10-28 01:57:31 +02:00
Ahmed Bouhuolia
e070ac72dd feat: Computed Net Income under Equity in Balance Sheet report. (#271) 2023-10-26 18:59:09 +02:00
allcontributors[bot]
08ac5f4b01 docs: add kochie as a contributor for code (#277)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-10-25 22:14:38 +02:00
34 changed files with 1533 additions and 274 deletions

View File

@@ -60,6 +60,15 @@
"contributions": [
"bug"
]
},
{
"login": "kochie",
"name": "Robert Koch",
"avatar_url": "https://avatars.githubusercontent.com/u/10809884?v=4",
"profile": "https://me.kochie.io",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

15
.gitpod.yml Normal file
View File

@@ -0,0 +1,15 @@
tasks:
- name: Init
init: pnpm install && docker-compose pull
command: cp .env.example .env && && docker-compose up -d && pnpm run dev
ports:
- port: 4000
visibility: public
onOpen: open-browser
- port: 3000
visibility: public
onOpen: ignore
- port: 3306
visibility: public
onOpen: ignore

View File

@@ -33,7 +33,8 @@ Contributions via pull requests are much appreciated. Once the approach is agree
---
## Local Setup Prerequisites
- The application currently supports **Node.js v14.x**. Please ensure that you are using this version of Node.js when developing. (use [nvm](https://github.com/nvm-sh/nvm#installing-and-updating) to switch between node versions)
- The application currently supports **Node.js v18.x**.
- `pnpm` packages manager, (from pnpm [guide](https://pnpm.io/installation) pick any installation method).
## Contribute to Backend
@@ -44,11 +45,10 @@ Contributions via pull requests are much appreciated. Once the approach is agree
cp .env.example .env
```
- Install all npm dependencies of the monorepo, you don't have to change directory to the `backend` package. just hit these command on root directory and it will install dependencies of all packages.
- Install all npm dependencies of the monorepo, you don't have to change directory to the `backend` package. just hit the command on root directory and it will install dependencies of all packages.
```
npm install
npm run bootstrap
pnpm install
```
- Run all required docker containers in the development, we already configured all containers under `docker-compose.yml`.
@@ -69,7 +69,7 @@ cefa73fe2881 bigcapital-redis "docker-entrypoint.s…" 7 seconds ago Up
- There're some CLI commands we should run before running the server like databaase migration, so we need to build the `server` app first.
```
npm run build:server
pnpm run build:server
```
- Run the database migration for system database.
@@ -87,7 +87,7 @@ Batch 1 run: 6 migrations
- Next, start the webapp application.
```
npm run dev:server
pnpm run dev:server
```
**[`^top^`](#)**
@@ -105,14 +105,13 @@ git clone https://github.com/bigcapital/bigcapital.git && cd bigcaptial
- Install all npm dependencies of the monorepo, you don't have to change directory to the `frontend` package. just hit that command and will install all packages across all application.
```
npm install
npm run bootstrap
pnpm install
```
- Next, start the webapp application.
```
npm run dev:webapp
pnpm run dev:webapp
```
**[`^top^`](#)**

View File

@@ -80,6 +80,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://scheibling.se"><img src="https://avatars.githubusercontent.com/u/24367830?v=4?s=100" width="100px;" alt="Lars Scheibling"/><br /><sub><b>Lars Scheibling</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Ascheibling" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/suhaibaffan"><img src="https://avatars.githubusercontent.com/u/18115937?v=4?s=100" width="100px;" alt="Suhaib Affan"/><br /><sub><b>Suhaib Affan</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=suhaibaffan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KalliopiPliogka"><img src="https://avatars.githubusercontent.com/u/81677549?v=4?s=100" width="100px;" alt="Kalliopi Pliogka"/><br /><sub><b>Kalliopi Pliogka</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3AKalliopiPliogka" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://me.kochie.io"><img src="https://avatars.githubusercontent.com/u/10809884?v=4?s=100" width="100px;" alt="Robert Koch"/><br /><sub><b>Robert Koch</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=kochie" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -1,4 +1,4 @@
FROM node:14.20-alpine as build
FROM node:18.16.0-alpine as build
USER root
@@ -83,15 +83,25 @@ WORKDIR /app
RUN chown node:node /
# Install pnpm
RUN npm install -g pnpm
# Copy application dependency manifests to the container image.
COPY ./package*.json ./
COPY ./pnpm-lock.yaml ./pnpm-lock.yaml
COPY ./pnpm-workspace.yaml ./pnpm-workspace.yaml
COPY ./lerna.json ./lerna.json
COPY ./packages/server/package*.json ./packages/server/
COPY ./lerna.json ./lerna.json
# Install application dependencies
RUN apk update
RUN apk add python3 build-base chromium
# Install app dependencies for production.
RUN npm install
RUN npm run bootstrap
# Set PYHTON env
ENV PYTHON=/usr/bin/python3
# Install packages dependencies for production.
RUN pnpm install
COPY --chown=node:node ./packages/server ./packages/server

View File

@@ -43,7 +43,7 @@
"crypto-random-string": "^3.2.0",
"csurf": "^1.10.0",
"deep-map": "^2.0.0",
"deepdash": "^5.3.7",
"deepdash": "^5.3.9",
"dotenv": "^8.1.0",
"errorhandler": "^1.5.1",
"es6-weak-map": "^2.0.3",
@@ -95,6 +95,7 @@
"rate-limiter-flexible": "^2.1.14",
"reflect-metadata": "^0.1.13",
"rtl-detect": "^1.0.4",
"source-map-loader": "^4.0.1",
"ts-transformer-keys": "^0.4.2",
"tsyringe": "^4.3.0",
"typedi": "^0.8.0",

View File

@@ -587,6 +587,7 @@
"balance_sheet.long_term_liabilities": "Long-Term Liabilities",
"balance_sheet.non_current_liabilities": "Non-Current Liabilities",
"balance_sheet.equity": "Equity",
"balance_sheet.net_income": "Net Income",
"balance_sheet.account_name": "Account name",
"balance_sheet.total": "Total",

View File

@@ -9,6 +9,7 @@ export enum BALANCE_SHEET_SCHEMA_NODE_TYPE {
AGGREGATE = 'AGGREGATE',
ACCOUNTS = 'ACCOUNTS',
ACCOUNT = 'ACCOUNT',
NET_INCOME = 'NET_INCOME',
}
export enum BALANCE_SHEET_NODE_TYPE {
@@ -33,6 +34,7 @@ export enum BALANCE_SHEET_SCHEMA_NODE_ID {
LOGN_TERM_LIABILITY = 'LOGN_TERM_LIABILITY',
NON_CURRENT_LIABILITY = 'NON_CURRENT_LIABILITY',
EQUITY = 'EQUITY',
NET_INCOME = 'NET_INCOME',
}
// Balance sheet query.
@@ -87,7 +89,6 @@ export interface IBalanceSheetDOO {
meta: IBalanceSheetMeta;
}
export interface IBalanceSheetCommonNode {
total: IBalanceSheetTotal;
horizontalTotals?: IBalanceSheetTotal[];
@@ -108,7 +109,7 @@ export interface IBalanceSheetAggregateNode extends IBalanceSheetCommonNode {
id: string;
name: string;
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE;
children?: (IBalanceSheetAggregateNode | IBalanceSheetAccountNode)[];
children?: IBalanceSheetDataNode[];
}
export interface IBalanceSheetTotal {
@@ -118,6 +119,13 @@ export interface IBalanceSheetTotal {
date?: string | Date;
}
export interface IBalanceSheetAccountsNode extends IBalanceSheetCommonNode {
id: number | string;
name: string;
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS;
children: IBalanceSheetAccountNode[];
}
export interface IBalanceSheetAccountNode extends IBalanceSheetCommonNode {
id: number;
index: number;
@@ -128,7 +136,17 @@ export interface IBalanceSheetAccountNode extends IBalanceSheetCommonNode {
children?: IBalanceSheetAccountNode[];
}
export type IBalanceSheetDataNode = IBalanceSheetAggregateNode;
export interface IBalanceSheetNetIncomeNode extends IBalanceSheetCommonNode {
id: number;
name: string;
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME;
}
export type IBalanceSheetDataNode =
| IBalanceSheetAggregateNode
| IBalanceSheetAccountNode
| IBalanceSheetAccountsNode
| IBalanceSheetNetIncomeNode;
export interface IBalanceSheetPercentageAmount {
amount: number;
@@ -150,9 +168,16 @@ export interface IBalanceSheetSchemaAccountNode {
accountsTypes: string[];
}
export interface IBalanceSheetSchemaNetIncomeNode {
id: string;
name: string;
type: BALANCE_SHEET_SCHEMA_NODE_TYPE;
}
export type IBalanceSheetSchemaNode =
| IBalanceSheetSchemaAccountNode
| IBalanceSheetSchemaAggregateNode;
| IBalanceSheetSchemaAggregateNode
| IBalanceSheetSchemaNetIncomeNode;
export interface IBalanceSheetDatePeriods {
assocAccountNodeDatePeriods(node): any;

View File

@@ -7,12 +7,14 @@ export interface ILedger {
filter(cb: (entry: ILedgerEntry) => boolean): ILedger;
whereAccountId(accountId: number): ILedger;
whereAccountsIds(accountsIds: number[]): ILedger;
whereContactId(contactId: number): ILedger;
whereFromDate(fromDate: Date | string): ILedger;
whereToDate(toDate: Date | string): ILedger;
whereCurrencyCode(currencyCode: string): ILedger;
whereBranch(branchId: number): ILedger;
whereItem(itemId: number): ILedger;
whereProject(projectId: number): ILedger;
getClosingBalance(): number;
getForeignClosingBalance(): number;
@@ -21,6 +23,9 @@ export interface ILedger {
getContactsIds(): number[];
getAccountsIds(): number[];
reverse(): ILedger;
isEmpty(): boolean;
}
export interface ILedgerEntry {

View File

@@ -587,6 +587,7 @@
"balance_sheet.long_term_liabilities": "Long-Term Liabilities",
"balance_sheet.non_current_liabilities": "Non-Current Liabilities",
"balance_sheet.equity": "Equity",
"balance_sheet.net_income": "Net Income",
"balance_sheet.account_name": "Account name",
"balance_sheet.total": "Total",

View File

@@ -51,11 +51,11 @@ export default class Ledger implements ILedger {
/**
* Filters entries by the given accounts ids then returns a new ledger.
* @param {number[]} accountsIds - Accounts ids.
* @param {number[]} accountIds
* @returns {ILedger}
*/
public whereAccountsIds(accountsIds: number[]): ILedger {
return this.filter((entry) => accountsIds.indexOf(entry.accountId) !== -1);
public whereAccountsIds(accountIds: number[]): ILedger {
return this.filter((entry) => accountIds.indexOf(entry.accountId) !== -1);
}
/**

View File

@@ -1,18 +1,10 @@
import * as R from 'ramda';
import { defaultTo, isEmpty, sumBy } from 'lodash';
import FinancialSheet from '../FinancialSheet';
import {
IBalanceSheetAggregateNode,
IBalanceSheetAccountNode,
BALANCE_SHEET_SCHEMA_NODE_TYPE,
IBalanceSheetQuery,
INumberFormatQuery,
IAccount,
IBalanceSheetSchemaNode,
IBalanceSheetSchemaAggregateNode,
IBalanceSheetDataNode,
IBalanceSheetSchemaAccountNode,
IBalanceSheetCommonNode,
} from '../../../interfaces';
import { BalanceSheetSchema } from './BalanceSheetSchema';
import { BalanceSheetPercentage } from './BalanceSheetPercentage';
@@ -24,8 +16,14 @@ import { FinancialSheetStructure } from '../FinancialSheetStructure';
import BalanceSheetRepository from './BalanceSheetRepository';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import { BalanceSheetFiltering } from './BalanceSheetFiltering';
import { BalanceSheetNetIncome } from './BalanceSheetNetIncome';
import { BalanceSheetAggregators } from './BalanceSheetAggregators';
import { BalanceSheetAccounts } from './BalanceSheetAccounts';
export default class BalanceSheet extends R.compose(
BalanceSheetAggregators,
BalanceSheetAccounts,
BalanceSheetNetIncome,
BalanceSheetFiltering,
BalanceSheetDatePeriods,
BalanceSheetComparsionPreviousPeriod,
@@ -53,6 +51,9 @@ export default class BalanceSheet extends R.compose(
*/
readonly baseCurrency: string;
/**
* Localization.
*/
readonly i18n: any;
/**
@@ -77,216 +78,18 @@ export default class BalanceSheet extends R.compose(
}
/**
* Retrieve the accounts node of accounts types.
* @param {string} accountsTypes
* @returns {IAccount[]}
* Parses report schema nodes.
* @param {IBalanceSheetSchemaNode[]} schema
* @returns {IBalanceSheetDataNode[]}
*/
private getAccountsByAccountTypes = (accountsTypes: string[]): IAccount[] => {
const mapAccountsByTypes = R.map((accountType) =>
defaultTo(this.repository.accountsByType.get(accountType), [])
);
return R.compose(R.flatten, mapAccountsByTypes)(accountsTypes);
};
/**
* Mappes the aggregate schema node type.
* @param {IBalanceSheetSchemaAggregateNode} node - Schema node.
* @return {IBalanceSheetAggregateNode}
*/
private reportSchemaAggregateNodeMapper = (
node: IBalanceSheetSchemaAggregateNode
): IBalanceSheetAggregateNode => {
const total = this.getTotalOfNodes(node.children);
return {
name: this.i18n.__(node.name),
id: node.id,
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE,
total: this.getTotalAmountMeta(total),
children: node.children,
};
};
/**
* Compose shema aggregate node of balance sheet schema.
* @param {IBalanceSheetSchemaAggregateNode} node
* @returns {IBalanceSheetSchemaAggregateNode}
*/
private schemaAggregateNodeCompose = (
node: IBalanceSheetSchemaAggregateNode
) => {
return R.compose(
this.aggregateNodeTotalMapper,
this.reportSchemaAggregateNodeMapper
)(node);
};
/**
* Mappes the account model to report account node.
* @param {IAccount} account
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountNodeMapper = (
account: IAccount
): IBalanceSheetAccountNode => {
const total = this.repository.totalAccountsLedger
.whereAccountId(account.id)
.getClosingBalance();
return {
id: account.id,
index: account.index,
name: account.name,
code: account.code,
total: this.getAmountMeta(total),
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNT,
};
};
/**
*
* @param {IAccount} account
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountNodeComposer = (
account: IAccount
): IBalanceSheetAccountNode => {
return R.compose(
R.when(
this.query.isPreviousYearActive,
this.previousYearAccountNodeComposer
),
R.when(
this.query.isPreviousPeriodActive,
this.previousPeriodAccountNodeComposer
),
R.when(
this.query.isDatePeriodsColumnsType,
this.assocAccountNodeDatePeriods
),
this.reportSchemaAccountNodeMapper
)(account);
};
/**
* Retrieve the total of the given nodes.
* @param {IBalanceSheetCommonNode[]} nodes
* @returns {number}
*/
private getTotalOfNodes = (nodes: IBalanceSheetCommonNode[]) => {
return sumBy(nodes, 'total.amount');
};
/**
* Retrieve the report accounts node by the given accounts types.
* @param {string[]} accountsTypes
* @returns {}
*/
private getAccountsNodesByAccountTypes = (accountsTypes: string[]) => {
const accounts = this.getAccountsByAccountTypes(accountsTypes);
return R.compose(R.map(this.reportSchemaAccountNodeComposer))(accounts);
};
/**
* Mappes the accounts schema node type.
* @param {IBalanceSheetSchemaNode} node - Schema node.
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountsNodeMapper = (
node: IBalanceSheetSchemaAccountNode
): IBalanceSheetAccountNode => {
const accounts = this.getAccountsNodesByAccountTypes(node.accountsTypes);
const total = this.getTotalOfNodes(accounts);
return {
id: node.id,
name: this.i18n.__(node.name),
type: node.type,
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS,
children: accounts,
total: this.getTotalAmountMeta(total),
};
};
/**
* Compose account schema node to report node.
* @param {IBalanceSheetSchemaAccountNode} node
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountsNodeComposer = (
node: IBalanceSheetSchemaAccountNode
): IBalanceSheetAccountNode => {
return R.compose(
R.when(
this.query.isPreviousYearActive,
this.previousYearAggregateNodeComposer
),
R.when(
this.query.isPreviousPeriodActive,
this.previousPeriodAggregateNodeComposer
),
R.when(
this.query.isDatePeriodsColumnsType,
this.assocAccountsNodeDatePeriods
),
this.reportSchemaAccountsNodeMapper
)(node);
};
/**
* Mappes the given report schema node.
* @param {IBalanceSheetSchemaNode} node - Schema node.
* @return {IBalanceSheetDataNode}
*/
private reportSchemaNodeMapper = (
schemaNode: IBalanceSheetSchemaNode
): IBalanceSheetDataNode => {
return R.compose(
R.when(
this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE),
this.schemaAggregateNodeCompose
),
R.when(
this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS),
this.reportSchemaAccountsNodeComposer
)
)(schemaNode);
};
/**
* Mappes the report schema nodes.
* @param {IBalanceSheetSchemaNode[]} nodes -
* @return {IBalanceSheetStructureSection[]}
*/
private reportSchemaAccountNodesMapper = (
schemaNodes: IBalanceSheetSchemaNode[]
public parseSchemaNodes = (
schema: IBalanceSheetSchemaNode[]
): IBalanceSheetDataNode[] => {
return this.mapNodesDeepReverse(schemaNodes, this.reportSchemaNodeMapper);
};
/**
* Sets total amount that calculated from node children.
* @param {IBalanceSheetSection} node
* @returns {IBalanceSheetDataNode}
*/
private aggregateNodeTotalMapper = (
node: IBalanceSheetDataNode
): IBalanceSheetDataNode => {
return R.compose(
R.when(
this.query.isPreviousYearActive,
this.previousYearAggregateNodeComposer
),
R.when(
this.query.isPreviousPeriodActive,
this.previousPeriodAggregateNodeComposer
),
R.when(
this.query.isDatePeriodsColumnsType,
this.assocAggregateNodeDatePeriods
)
)(node);
this.aggregatesSchemaParser,
this.netIncomeSchemaParser,
this.accountsSchemaParser
)(schema) as IBalanceSheetDataNode[];
};
/**
@@ -299,7 +102,7 @@ export default class BalanceSheet extends R.compose(
return R.compose(
this.reportFilterPlugin,
this.reportPercentageCompose,
this.reportSchemaAccountNodesMapper
this.parseSchemaNodes
)(balanceSheetSchema);
};
}

View File

@@ -0,0 +1,182 @@
import * as R from 'ramda';
import { defaultTo, toArray } from 'lodash';
import { FinancialSheetStructure } from '../FinancialSheetStructure';
import {
BALANCE_SHEET_SCHEMA_NODE_TYPE,
IAccount,
IBalanceSheetAccountNode,
IBalanceSheetAccountsNode,
IBalanceSheetDataNode,
IBalanceSheetSchemaAccountNode,
IBalanceSheetSchemaNode,
INumberFormatQuery,
} from '@/interfaces';
import { BalanceSheetNetIncome } from './BalanceSheetNetIncome';
import { BalanceSheetFiltering } from './BalanceSheetFiltering';
import { BalanceSheetDatePeriods } from './BalanceSheetDatePeriods';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
import { BalanceSheetPercentage } from './BalanceSheetPercentage';
import { BalanceSheetSchema } from './BalanceSheetSchema';
import { BalanceSheetBase } from './BalanceSheetBase';
import { BalanceSheetQuery } from './BalanceSheetQuery';
export const BalanceSheetAccounts = (Base: any) =>
class extends R.compose(
BalanceSheetNetIncome,
BalanceSheetFiltering,
BalanceSheetDatePeriods,
BalanceSheetComparsionPreviousPeriod,
BalanceSheetComparsionPreviousYear,
BalanceSheetPercentage,
BalanceSheetSchema,
BalanceSheetBase,
FinancialSheetStructure
)(Base) {
/**
* Balance sheet query.
* @param {BalanceSheetQuery}
*/
readonly query: BalanceSheetQuery;
/**
* Balance sheet number format query.
* @param {INumberFormatQuery}
*/
readonly numberFormat: INumberFormatQuery;
/**
* Base currency of the organization.
* @param {string}
*/
readonly baseCurrency: string;
/**
* Localization.
*/
readonly i18n: any;
/**
* Retrieve the accounts node of accounts types.
* @param {string} accountsTypes
* @returns {IAccount[]}
*/
private getAccountsByAccountTypes = (
accountsTypes: string[]
): IAccount[] => {
const mapAccountsByTypes = R.map((accountType) =>
defaultTo(this.repository.accountsByType.get(accountType), [])
);
return R.compose(R.flatten, mapAccountsByTypes)(accountsTypes);
};
/**
* Mappes the account model to report account node.
* @param {IAccount} account
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountNodeMapper = (
account: IAccount
): IBalanceSheetAccountNode => {
const total = this.repository.totalAccountsLedger
.whereAccountId(account.id)
.getClosingBalance();
return {
id: account.id,
index: account.index,
name: account.name,
code: account.code,
total: this.getAmountMeta(total),
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNT,
};
};
/**
* Mappes the given account model to the balance sheet account node.
* @param {IAccount} account
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountNodeComposer = (
account: IAccount
): IBalanceSheetAccountNode => {
return R.compose(
R.when(
this.query.isPreviousYearActive,
this.previousYearAccountNodeComposer
),
R.when(
this.query.isPreviousPeriodActive,
this.previousPeriodAccountNodeComposer
),
R.when(
this.query.isDatePeriodsColumnsType,
this.assocAccountNodeDatePeriods
),
this.reportSchemaAccountNodeMapper
)(account);
};
// -----------------------------
// - Accounts Node Praser
// -----------------------------
/**
* Retrieve the report accounts node by the given accounts types.
* @param {string[]} accountsTypes
* @returns {IBalanceSheetAccountNode[]}
*/
private getAccountsNodesByAccountTypes = (
accountsTypes: string[]
): IBalanceSheetAccountNode[] => {
const accounts = this.getAccountsByAccountTypes(accountsTypes);
return R.map(this.reportSchemaAccountNodeComposer, accounts);
};
/**
* Mappes the accounts schema node type.
* @param {IBalanceSheetSchemaNode} node - Schema node.
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountsNodeMapper = (
node: IBalanceSheetSchemaAccountNode
): IBalanceSheetAccountsNode => {
const accounts = this.getAccountsNodesByAccountTypes(node.accountsTypes);
const children = toArray(node?.children);
return {
id: node.id,
name: this.i18n.__(node.name),
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS,
type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS,
children: [...accounts, ...children],
total: this.getTotalAmountMeta(0),
};
};
/**
* Mappes the given report schema node.
* @param {IBalanceSheetSchemaNode | IBalanceSheetDataNode} node - Schema node.
* @return {IBalanceSheetSchemaNode | IBalanceSheetDataNode}
*/
private reportAccountSchemaParser = (
node: IBalanceSheetSchemaNode | IBalanceSheetDataNode
): IBalanceSheetSchemaNode | IBalanceSheetDataNode => {
return R.compose(
R.when(
this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS),
this.reportSchemaAccountsNodeMapper
)
)(node);
};
/**
* Parses the report accounts schema nodes.
* @param {IBalanceSheetSchemaNode[]} nodes -
* @return {IBalanceSheetStructureSection[]}
*/
public accountsSchemaParser = (
nodes: (IBalanceSheetSchemaNode | IBalanceSheetDataNode)[]
): (IBalanceSheetDataNode | IBalanceSheetSchemaNode)[] => {
return this.mapNodesDeepReverse(nodes, this.reportAccountSchemaParser);
};
};

View File

@@ -0,0 +1,142 @@
import * as R from 'ramda';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';
import { FinancialSheetStructure } from '../FinancialSheetStructure';
import {
BALANCE_SHEET_SCHEMA_NODE_TYPE,
IBalanceSheetAggregateNode,
IBalanceSheetDataNode,
IBalanceSheetSchemaAggregateNode,
IBalanceSheetSchemaNode,
INumberFormatQuery,
} from '@/interfaces';
import { BalanceSheetDatePeriods } from './BalanceSheetDatePeriods';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
import { BalanceSheetPercentage } from './BalanceSheetPercentage';
import { BalanceSheetSchema } from './BalanceSheetSchema';
import { BalanceSheetBase } from './BalanceSheetBase';
import { BalanceSheetQuery } from './BalanceSheetQuery';
export const BalanceSheetAggregators = (Base: any) =>
class extends R.compose(
BalanceSheetDatePeriods,
BalanceSheetComparsionPreviousPeriod,
BalanceSheetComparsionPreviousYear,
BalanceSheetPercentage,
BalanceSheetSchema,
BalanceSheetBase,
FinancialSheetStructure
)(Base) {
/**
* Balance sheet query.
* @param {BalanceSheetQuery}
*/
readonly query: BalanceSheetQuery;
/**
* Balance sheet number format query.
* @param {INumberFormatQuery}
*/
readonly numberFormat: INumberFormatQuery;
/**
* Base currency of the organization.
* @param {string}
*/
readonly baseCurrency: string;
/**
* Localization.
*/
readonly i18n: any;
/**
* Sets total amount that calculated from node children.
* @param {IBalanceSheetSection} node
* @returns {IBalanceSheetDataNode}
*/
private aggregateNodeTotalMapper = (
node: IBalanceSheetDataNode
): IBalanceSheetDataNode => {
return R.compose(
R.when(
this.query.isPreviousYearActive,
this.previousYearAggregateNodeComposer
),
R.when(
this.query.isPreviousPeriodActive,
this.previousPeriodAggregateNodeComposer
),
R.when(
this.query.isDatePeriodsColumnsType,
this.assocAggregateNodeDatePeriods
)
)(node);
};
/**
* Mappes the aggregate schema node type.
* @param {IBalanceSheetSchemaAggregateNode} node - Schema node.
* @return {IBalanceSheetAggregateNode}
*/
private reportSchemaAggregateNodeMapper = (
node: IBalanceSheetSchemaAggregateNode
): IBalanceSheetAggregateNode => {
const total = this.getTotalOfNodes(node.children);
return {
name: this.i18n.__(node.name),
id: node.id,
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE,
type: BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE,
total: this.getTotalAmountMeta(total),
children: node.children,
};
};
/**
* Compose shema aggregate node of balance sheet schema.
* @param {IBalanceSheetSchemaAggregateNode} node
* @returns {IBalanceSheetSchemaAggregateNode}
*/
private schemaAggregateNodeCompose = (
node: IBalanceSheetSchemaAggregateNode
) => {
return R.compose(
this.aggregateNodeTotalMapper,
this.reportSchemaAggregateNodeMapper
)(node);
};
/**
* Mappes the given report schema node.
* @param {IBalanceSheetSchemaNode} node - Schema node.
* @return {IBalanceSheetDataNode}
*/
private reportAggregateSchemaParser = (
node: IBalanceSheetSchemaNode
): IBalanceSheetDataNode => {
return R.compose(
R.when(
this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.AGGREGATE),
this.schemaAggregateNodeCompose
),
R.when(
this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS),
this.schemaAggregateNodeCompose
)
)(node);
};
/**
* Mappes the report schema nodes.
* @param {IBalanceSheetSchemaNode[]} nodes -
* @return {IBalanceSheetStructureSection[]}
*/
public aggregatesSchemaParser = (
nodes: (IBalanceSheetSchemaNode | IBalanceSheetDataNode)[]
): (IBalanceSheetDataNode | IBalanceSheetSchemaNode)[] => {
return this.mapNodesDeepReverse(nodes, this.reportAggregateSchemaParser);
};
};

View File

@@ -6,6 +6,7 @@ import {
IBalanceSheetAggregateNode,
IBalanceSheetTotal,
IBalanceSheetCommonNode,
IBalanceSheetComparsions,
} from '@/interfaces';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';

View File

@@ -156,13 +156,14 @@ export const BalanceSheetComparsionPreviousYear = (Base: any) =>
* @param {IBalanceSheetCommonNode} node
* @returns {IBalanceSheetCommonNode}
*/
private assocPreviousYearAggregateHorizNode = (
public assocPreviousYearAggregateHorizNode = (
node: IBalanceSheetCommonNode
) => {
): IBalanceSheetCommonNode => {
const horizontalTotals = R.addIndex(R.map)(
this.previousYearAggregateHorizNodeComposer(node),
node.horizontalTotals
);
) as IBalanceSheetTotal[];
return R.assoc('horizontalTotals', horizontalTotals, node);
};
@@ -258,12 +259,11 @@ export const BalanceSheetComparsionPreviousYear = (Base: any) =>
// ------------------------------
// # Horizontal Nodes - Aggregate.
// ------------------------------
/**
* Detarmines whether the given node has horizontal totals.
* @param {IBalanceSheetCommonNode} node
* @returns {boolean}
*/
private isNodeHasHorizontalTotals = (node: IBalanceSheetCommonNode) =>
public isNodeHasHorizontalTotals = (node: IBalanceSheetCommonNode) =>
!isEmpty(node.horizontalTotals);
};

View File

@@ -107,9 +107,9 @@ export const BalanceSheetDatePeriods = (Base: FinancialSheet) =>
/**
*
* @param {IBalanceSheetAccountNode} node
* @param {Date} fromDate
* @param {Date} toDate
* @param {IBalanceSheetAccountNode} node
* @param {Date} fromDate
* @param {Date} toDate
* @returns {IBalanceSheetAccountNode}
*/
private getAccountNodeDatePeriod = (
@@ -201,7 +201,7 @@ export const BalanceSheetDatePeriods = (Base: FinancialSheet) =>
};
/**
*
*
* @param node
* @returns
*/

View File

@@ -0,0 +1,226 @@
import * as R from 'ramda';
import {
BALANCE_SHEET_SCHEMA_NODE_TYPE,
IBalanceSheetDataNode,
IBalanceSheetNetIncomeNode,
IBalanceSheetSchemaNetIncomeNode,
IBalanceSheetSchemaNode,
IBalanceSheetTotalPeriod,
} from '@/interfaces';
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';
import BalanceSheetRepository from './BalanceSheetRepository';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import { BalanceSheetNetIncomePP } from './BalanceSheetNetIncomePP';
import { BalanceSheetNetIncomePY } from './BalanceSheetNetIncomePY';
export const BalanceSheetNetIncome = (Base: any) =>
class extends R.compose(
BalanceSheetNetIncomePP,
BalanceSheetNetIncomePY,
BalanceSheetComparsionPreviousYear,
BalanceSheetComparsionPreviousPeriod,
FinancialPreviousPeriod,
FinancialHorizTotals
)(Base) {
private repository: BalanceSheetRepository;
private query: BalanceSheetQuery;
/**
* Retrieves the closing balance of income accounts.
* @returns {number}
*/
private getIncomeTotal = () => {
const closeingBalance = this.repository.incomeLedger.getClosingBalance();
return closeingBalance;
};
/**
* Retrieves the closing balance of expenses accounts.
* @returns {number}
*/
private getExpensesTotal = () => {
const closingBalance = this.repository.expensesLedger.getClosingBalance();
return closingBalance;
};
/**
* Retrieves the total net income.
* @returns {number}
*/
protected getNetIncomeTotal = () => {
const income = this.getIncomeTotal();
const expenses = this.getExpensesTotal();
return income - expenses;
};
/**
* Mappes the aggregate schema node type.
* @param {IBalanceSheetSchemaNetIncomeNode} node - Schema node.
* @return {IBalanceSheetAggregateNode}
*/
protected schemaNetIncomeNodeMapper = (
node: IBalanceSheetSchemaNetIncomeNode
): IBalanceSheetNetIncomeNode => {
const total = this.getNetIncomeTotal();
return {
id: node.id,
name: this.i18n.__(node.name),
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME,
total: this.getTotalAmountMeta(total),
};
};
/**
* Mapps the net income shcema node to report node.
* @param {IBalanceSheetSchemaNetIncomeNode} node
* @returns {IBalanceSheetNetIncomeNode}
*/
protected schemaNetIncomeNodeCompose = (
node: IBalanceSheetSchemaNetIncomeNode
): IBalanceSheetNetIncomeNode => {
return R.compose(
R.when(
this.query.isPreviousYearActive,
this.previousYearNetIncomeNodeCompose
),
R.when(
this.query.isPreviousPeriodActive,
this.previousPeriodNetIncomeNodeCompose
),
R.when(
this.query.isDatePeriodsColumnsType,
this.assocNetIncomeDatePeriodsNode
),
this.schemaNetIncomeNodeMapper
)(node);
};
// --------------------------------
// # Date Periods
// --------------------------------
/**
* Retreives total income of the given date period.
* @param {number} accountId -
* @param {Date} toDate -
* @returns {number}
*/
private getIncomeDatePeriodTotal = (toDate: Date): number => {
const periodTotalBetween = this.repository.incomePeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const periodOpening =
this.repository.incomePeriodsOpeningAccountsLedger.getClosingBalance();
return periodOpening + periodTotalBetween;
};
/**
* Retrieves total expense of the given date period.
* @param {number} accountId -
* @param {Date} toDate -
* @returns {number}
*/
private getExpensesDatePeriodTotal = (toDate: Date): number => {
const periodTotalBetween = this.repository.expensesPeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const periodOpening =
this.repository.expensesOpeningAccountLedger.getClosingBalance();
return periodOpening + periodTotalBetween;
};
/**
* Retrieve the given net income date period total.
* @param {number} accountId
* @param {Date} toDate
* @returns {number}
*/
private getNetIncomeDatePeriodTotal = (toDate: Date): number => {
const income = this.getIncomeDatePeriodTotal(toDate);
const expense = this.getExpensesDatePeriodTotal(toDate);
return income - expense;
};
/**
* Retrieves the net income date period node.
* @param {IBalanceSheetNetIncomeNode} node
* @param {Date} fromDate
* @param {Date} toDate
* @returns {IBalanceSheetNetIncomeNode}
*/
private getNetIncomeDatePeriodNode = (
node: IBalanceSheetNetIncomeNode,
fromDate: Date,
toDate: Date
): IBalanceSheetTotalPeriod => {
const periodTotal = this.getNetIncomeDatePeriodTotal(toDate);
return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate);
};
/**
* Retrieve total date periods of the given net income node.
* @param {IBalanceSheetNetIncomeNode} node
* @returns {IBalanceSheetNetIncomeNode}
*/
private getNetIncomeDatePeriodsNode = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetTotalPeriod[] => {
return this.getReportNodeDatePeriods(
node,
this.getNetIncomeDatePeriodNode
);
};
/**
* Assoc total date periods to net income node.
* @param {IBalanceSheetNetIncomeNode} node
* @returns {IBalanceSheetNetIncomeNode}
*/
public assocNetIncomeDatePeriodsNode = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetNetIncomeNode => {
const datePeriods = this.getNetIncomeDatePeriodsNode(node);
return R.assoc('horizontalTotals', datePeriods, node);
};
// -----------------------------
// - Net Income Nodes Praser
// -----------------------------
/**
* Mappes the given report schema node.
* @param {IBalanceSheetSchemaNode} node - Schema node.
* @return {IBalanceSheetDataNode}
*/
private reportNetIncomeNodeSchemaParser = (
schemaNode: IBalanceSheetSchemaNode
): IBalanceSheetDataNode => {
return R.compose(
R.when(
this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME),
this.schemaNetIncomeNodeCompose
)
)(schemaNode);
};
/**
* Parses the report net income schema nodes.
* @param {(IBalanceSheetSchemaNode | IBalanceSheetDataNode)[]} nodes -
* @return {IBalanceSheetDataNode[]}
*/
public netIncomeSchemaParser = (
nodes: (IBalanceSheetSchemaNode | IBalanceSheetDataNode)[]
): IBalanceSheetDataNode[] => {
return this.mapNodesDeep(nodes, this.reportNetIncomeNodeSchemaParser);
};
};

View File

@@ -0,0 +1,120 @@
import * as R from 'ramda';
import {
IBalanceSheetNetIncomeNode,
IBalanceSheetTotalPeriod,
} from '@/interfaces';
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';
import BalanceSheetRepository from './BalanceSheetRepository';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import { BalanceSheetNetIncomePP } from './BalanceSheetNetIncomePP';
import { BalanceSheetNetIncomePY } from './BalanceSheetNetIncomePY';
export const BalanceSheetNetIncomeDatePeriods = (Base: any) =>
class extends R.compose(
BalanceSheetNetIncomePP,
BalanceSheetNetIncomePY,
BalanceSheetComparsionPreviousYear,
BalanceSheetComparsionPreviousPeriod,
FinancialPreviousPeriod,
FinancialHorizTotals
)(Base) {
private repository: BalanceSheetRepository;
private query: BalanceSheetQuery;
// --------------------------------
// # Date Periods
// --------------------------------
/**
* Retreives total income of the given date period.
* @param {number} accountId -
* @param {Date} toDate -
* @returns {number}
*/
private getIncomeDatePeriodTotal = (toDate: Date): number => {
const periodTotalBetween = this.repository.incomePeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const periodOpening =
this.repository.incomePeriodsOpeningAccountsLedger.getClosingBalance();
return periodOpening + periodTotalBetween;
};
/**
* Retrieves total expense of the given date period.
* @param {number} accountId -
* @param {Date} toDate -
* @returns {number}
*/
private getExpensesDatePeriodTotal = (toDate: Date): number => {
const periodTotalBetween = this.repository.expensesPeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const periodOpening =
this.repository.expensesOpeningAccountLedger.getClosingBalance();
return periodOpening + periodTotalBetween;
};
/**
* Retrieve the given net income date period total.
* @param {number} accountId
* @param {Date} toDate
* @returns {number}
*/
private getNetIncomeDatePeriodTotal = (toDate: Date): number => {
const income = this.getIncomeDatePeriodTotal(toDate);
const expense = this.getExpensesDatePeriodTotal(toDate);
return income - expense;
};
/**
* Retrieves the net income date period node.
* @param {IBalanceSheetNetIncomeNode} node
* @param {Date} fromDate
* @param {Date} toDate
* @returns {IBalanceSheetNetIncomeNode}
*/
private getNetIncomeDatePeriodNode = (
node: IBalanceSheetNetIncomeNode,
fromDate: Date,
toDate: Date
): IBalanceSheetTotalPeriod => {
const periodTotal = this.getNetIncomeDatePeriodTotal(toDate);
return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate);
};
/**
* Retrieve total date periods of the given net income node.
* @param {IBalanceSheetNetIncomeNode} node
* @returns {IBalanceSheetNetIncomeNode}
*/
private getNetIncomeDatePeriodsNode = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetTotalPeriod[] => {
return this.getReportNodeDatePeriods(
node,
this.getNetIncomeDatePeriodNode
);
};
/**
* Assoc total date periods to net income node.
* @param {IBalanceSheetNetIncomeNode} node
* @returns {IBalanceSheetNetIncomeNode}
*/
public assocNetIncomeDatePeriodsNode = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetNetIncomeNode => {
const datePeriods = this.getNetIncomeDatePeriodsNode(node);
return R.assoc('horizontalTotals', datePeriods, node);
};
};

View File

@@ -0,0 +1,127 @@
import * as R from 'ramda';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';
import { IBalanceSheetNetIncomeNode, IBalanceSheetTotal } from '@/interfaces';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import BalanceSheetRepository from './BalanceSheetRepository';
export const BalanceSheetNetIncomeDatePeriodsPP = (Base: any) =>
class extends R.compose(
BalanceSheetComparsionPreviousPeriod,
FinancialPreviousPeriod,
FinancialHorizTotals
)(Base) {
query: BalanceSheetQuery;
repository: BalanceSheetRepository;
/**
* Retrieves the PY total income of the given date period.
* @param {number} accountId -
* @param {Date} toDate -
* @return {number}
*/
private getPPIncomeDatePeriodTotal = R.curry((toDate: Date) => {
const PYPeriodsTotal = this.repository.incomePPPeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const PYPeriodsOpeningTotal =
this.repository.incomePPPeriodsOpeningAccountLedger.getClosingBalance();
return PYPeriodsOpeningTotal + PYPeriodsTotal;
});
/**
* Retrieves the PY total expense of the given date period.
* @param {number} accountId -
* @param {Date} toDate -
* @returns {number}
*/
private getPPExpenseDatePeriodTotal = R.curry((toDate: Date) => {
const PYPeriodsTotal = this.repository.expensePPPeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const PYPeriodsOpeningTotal =
this.repository.expensePPPeriodsOpeningAccountLedger.getClosingBalance();
return PYPeriodsOpeningTotal + PYPeriodsTotal;
});
/**
* Retrieve the given net income total of the given period.
* @param {number} accountId - Account id.
* @param {Date} toDate - To date.
* @returns {number}
*/
private getPPNetIncomeDatePeriodTotal = R.curry((toDate: Date) => {
const income = this.getPPIncomeDatePeriodTotal(toDate);
const expense = this.getPPExpenseDatePeriodTotal(toDate);
return income - expense;
});
/**
* Assoc preivous period to account horizontal total node.
* @param {IBalanceSheetAccountNode} node
* @returns {}
*/
private assocPreviousPeriodNetIncomeHorizTotal = R.curry(
(node: IBalanceSheetNetIncomeNode, totalNode) => {
const total = this.getPPNetIncomeDatePeriodTotal(
totalNode.previousPeriodToDate.date
);
return R.assoc('previousPeriod', this.getAmountMeta(total), totalNode);
}
);
/**
* Compose previous period to aggregate horizontal nodes.
* @param {IBalanceSheetTotal} node
* @returns {IBalanceSheetTotal}
*/
private previousPeriodNetIncomeHorizNodeComposer = R.curry(
(
node: IBalanceSheetNetIncomeNode,
horiontalTotalNode: IBalanceSheetTotal
): IBalanceSheetTotal => {
return R.compose(
R.when(
this.query.isPreviousPeriodPercentageActive,
this.assocPreviousPeriodTotalPercentageNode
),
R.when(
this.query.isPreviousPeriodChangeActive,
this.assocPreviousPeriodTotalChangeNode
),
R.when(
this.query.isPreviousPeriodActive,
this.assocPreviousPeriodNetIncomeHorizTotal(node)
),
R.when(
this.query.isPreviousPeriodActive,
this.assocPreviousPeriodHorizNodeFromToDates(
this.query.displayColumnsBy
)
)
)(horiontalTotalNode);
}
);
/**
* Associate the PP to net income horizontal nodes.
* @param {IBalanceSheetCommonNode} node
* @returns {IBalanceSheetCommonNode}
*/
public assocPreviousPeriodNetIncomeHorizNode = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetNetIncomeNode => {
const horizontalTotals = R.addIndex(R.map)(
this.previousPeriodNetIncomeHorizNodeComposer(node),
node.horizontalTotals
) as IBalanceSheetTotal[];
return R.assoc('horizontalTotals', horizontalTotals, node);
};
};

View File

@@ -0,0 +1,122 @@
import * as R from 'ramda';
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';
import { IBalanceSheetNetIncomeNode, IBalanceSheetTotal } from '@/interfaces';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import BalanceSheetRepository from './BalanceSheetRepository';
export const BalanceSheetNetIncomeDatePeriodsPY = (Base: any) =>
class extends R.compose(
BalanceSheetComparsionPreviousYear,
FinancialPreviousPeriod,
FinancialHorizTotals
)(Base) {
query: BalanceSheetQuery;
repository: BalanceSheetRepository;
/**
* Retrieves the PY total income of the given date period.
* @param {Date} toDate -
* @return {number}
*/
private getPYIncomeDatePeriodTotal = R.curry((toDate: Date) => {
const PYPeriodsTotal = this.repository.incomePYPeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const PYPeriodsOpeningTotal =
this.repository.incomePYPeriodsOpeningAccountLedger.getClosingBalance();
return PYPeriodsOpeningTotal + PYPeriodsTotal;
});
/**
* Retrieves the PY total expense of the given date period.
* @param {Date} toDate -
* @returns {number}
*/
private getPYExpenseDatePeriodTotal = R.curry((toDate: Date) => {
const PYPeriodsTotal = this.repository.expensePYPeriodsAccountsLedger
.whereToDate(toDate)
.getClosingBalance();
const PYPeriodsOpeningTotal =
this.repository.expensePYPeriodsOpeningAccountLedger.getClosingBalance();
return PYPeriodsOpeningTotal + PYPeriodsTotal;
});
/**
* Retrieve the given net income total of the given period.
* @param {Date} toDate - To date.
* @returns {number}
*/
private getPYNetIncomeDatePeriodTotal = R.curry((toDate: Date) => {
const income = this.getPYIncomeDatePeriodTotal(toDate);
const expense = this.getPYExpenseDatePeriodTotal(toDate);
return income - expense;
});
/**
* Assoc preivous year to account horizontal total node.
* @param {IBalanceSheetAccountNode} node
* @returns {}
*/
private assocPreviousYearNetIncomeHorizTotal = R.curry(
(node: IBalanceSheetNetIncomeNode, totalNode) => {
const total = this.getPYNetIncomeDatePeriodTotal(
totalNode.previousYearToDate.date
);
return R.assoc('previousYear', this.getAmountMeta(total), totalNode);
}
);
/**
* Compose PY to net income horizontal nodes.
* @param {IBalanceSheetTotal} node
* @returns {IBalanceSheetTotal}
*/
private previousYearNetIncomeHorizNodeComposer = R.curry(
(
node: IBalanceSheetNetIncomeNode,
horiontalTotalNode: IBalanceSheetTotal
): IBalanceSheetTotal => {
return R.compose(
R.when(
this.query.isPreviousYearPercentageActive,
this.assocPreviousYearTotalPercentageNode
),
R.when(
this.query.isPreviousYearChangeActive,
this.assocPreviousYearTotalChangeNode
),
R.when(
this.query.isPreviousYearActive,
this.assocPreviousYearNetIncomeHorizTotal(node)
),
R.when(
this.query.isPreviousYearActive,
this.assocPreviousYearHorizNodeFromToDates
)
)(horiontalTotalNode);
}
);
/**
* Associate the PY to net income horizontal nodes.
* @param {IBalanceSheetCommonNode} node
* @returns {IBalanceSheetCommonNode}
*/
public assocPreviousYearNetIncomeHorizNode = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetNetIncomeNode => {
const horizontalTotals = R.addIndex(R.map)(
this.previousYearNetIncomeHorizNodeComposer(node),
node.horizontalTotals
) as IBalanceSheetTotal[];
return R.assoc('horizontalTotals', horizontalTotals, node);
};
};

View File

@@ -0,0 +1,75 @@
import * as R from 'ramda';
import {
IBalanceSheetDataNode,
IBalanceSheetNetIncomeNode,
} from '@/interfaces';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';
import BalanceSheetRepository from './BalanceSheetRepository';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import { BalanceSheetNetIncomeDatePeriodsPP } from './BalanceSheetNetIncomeDatePeriodsPP';
export const BalanceSheetNetIncomePP = (Base: any) =>
class extends R.compose(
BalanceSheetNetIncomeDatePeriodsPP,
BalanceSheetComparsionPreviousPeriod,
FinancialPreviousPeriod,
FinancialHorizTotals
)(Base) {
private repository: BalanceSheetRepository;
private query: BalanceSheetQuery;
// -------------------------------
// # Previous Period (PP)
// -------------------------------
/**
* Retrieves the PP net income.
* @returns {}
*/
protected getPreviousPeriodNetIncome = () => {
const income = this.repository.incomePPAccountsLedger.getClosingBalance();
const expense =
this.repository.expensePPAccountsLedger.getClosingBalance();
return income - expense;
};
/**
* Associates the previous period to account node.
* @param {IBalanceSheetDataNode} node
* @returns {IBalanceSheetDataNode}
*/
protected assocPreviousPeriodNetIncomeNode = (
node: IBalanceSheetDataNode
): IBalanceSheetDataNode => {
const total = this.getPreviousPeriodNetIncome();
return R.assoc('previousPeriod', this.getAmountMeta(total), node);
};
/**
* Previous period account node composer.
* @param {IBalanceSheetNetIncomeNode} node
* @returns {IBalanceSheetNetIncomeNode}
*/
protected previousPeriodNetIncomeNodeCompose = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetNetIncomeNode => {
return R.compose(
R.when(
this.isNodeHasHorizTotals,
this.assocPreviousPeriodNetIncomeHorizNode
),
R.when(
this.query.isPreviousPeriodPercentageActive,
this.assocPreviousPeriodPercentageNode
),
R.when(
this.query.isPreviousPeriodChangeActive,
this.assocPreviousPeriodChangeNode
),
this.assocPreviousPeriodNetIncomeNode
)(node);
};
};

View File

@@ -0,0 +1,79 @@
import * as R from 'ramda';
import {
IBalanceSheetDataNode,
IBalanceSheetNetIncomeNode,
} from '@/interfaces';
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { FinancialPreviousPeriod } from '../FinancialPreviousPeriod';
import { FinancialHorizTotals } from '../FinancialHorizTotals';
import BalanceSheetRepository from './BalanceSheetRepository';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import { BalanceSheetNetIncomeDatePeriodsPY } from './BalanceSheetNetIncomeDatePeriodsPY';
export const BalanceSheetNetIncomePY = (Base: any) =>
class extends R.compose(
BalanceSheetNetIncomeDatePeriodsPY,
BalanceSheetComparsionPreviousYear,
BalanceSheetComparsionPreviousPeriod,
FinancialPreviousPeriod,
FinancialHorizTotals
)(Base) {
private repository: BalanceSheetRepository;
private query: BalanceSheetQuery;
// ------------------------------
// # Previous Year (PY)
// ------------------------------
/**
* Retrieves the previous year (PY) net income.
* @returns {number}
*/
protected getPreviousYearNetIncome = () => {
const income =
this.repository.incomePYTotalAccountsLedger.getClosingBalance();
const expense =
this.repository.expensePYTotalAccountsLedger.getClosingBalance();
return income - expense;
};
/**
* Assoc previous year on aggregate node.
* @param {IBalanceSheetAccountNode} node
* @returns {IBalanceSheetAccountNode}
*/
protected assocPreviousYearNetIncomeNode = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetNetIncomeNode => {
const total = this.getPreviousYearNetIncome();
return R.assoc('previousYear', this.getTotalAmountMeta(total), node);
};
/**
* Assoc previous year attributes to aggregate node.
* @param {IBalanceSheetAccountNode} node
* @returns {IBalanceSheetAccountNode}
*/
protected previousYearNetIncomeNodeCompose = (
node: IBalanceSheetNetIncomeNode
): IBalanceSheetNetIncomeNode => {
return R.compose(
R.when(
this.query.isPreviousYearPercentageActive,
this.assocPreviousYearTotalPercentageNode
),
R.when(
this.query.isPreviousYearChangeActive,
this.assocPreviousYearTotalChangeNode
),
// Associate the PY to date periods horizontal nodes.
R.when(
this.isNodeHasHorizontalTotals,
this.assocPreviousYearNetIncomeHorizNode
),
this.assocPreviousYearNetIncomeNode
)(node);
};
};

View File

@@ -12,26 +12,31 @@ export class BalanceSheetQuery extends R.compose(FinancialDateRanges)(
* @param {IBalanceSheetQuery}
*/
public readonly query: IBalanceSheetQuery;
/**
* Previous year to date.
* @param {Date}
*/
public readonly PYToDate: Date;
/**
* Previous year from date.
* @param {Date}
*/
public readonly PYFromDate: Date;
/**
* Previous period to date.
* @param {Date}
*/
public readonly PPToDate: Date;
/**
* Previous period from date.
* @param {Date}
*/
public readonly PPFromDate: Date;
/**
* Constructor method
* @param {IBalanceSheetQuery} query

View File

@@ -3,6 +3,7 @@ import * as R from 'ramda';
import { Knex } from 'knex';
import { isEmpty } from 'lodash';
import {
IAccount,
IAccountTransactionsGroupBy,
IBalanceSheetQuery,
ILedger,
@@ -11,9 +12,12 @@ import { transformToMapBy } from 'utils';
import Ledger from '@/services/Accounting/Ledger';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import { FinancialDatePeriods } from '../FinancialDatePeriods';
import { ACCOUNT_PARENT_TYPE, ACCOUNT_TYPE } from '@/data/AccountTypes';
import { BalanceSheetRepositoryNetIncome } from './BalanceSheetRepositoryNetIncome';
@Service()
export default class BalanceSheetRepository extends R.compose(
BalanceSheetRepositoryNetIncome,
FinancialDatePeriods
)(class {}) {
/**
@@ -65,8 +69,22 @@ export default class BalanceSheetRepository extends R.compose(
*/
public readonly PPFromDate: Date;
/**
* Total closing accounts ledger.
* @param {Ledger}
*/
public totalAccountsLedger: Ledger;
/**
* Total income accounts ledger.
*/
public incomeLedger: Ledger;
/**
* Total expense accounts ledger.
*/
public expensesLedger: Ledger;
/**
* Transactions group type.
* @param {IAccountTransactionsGroupBy}
@@ -171,6 +189,8 @@ export default class BalanceSheetRepository extends R.compose(
) {
await this.initPeriodsPreviousPeriod();
}
//
await this.asyncInitializeNetIncome();
};
// ----------------------------
@@ -181,6 +201,7 @@ export default class BalanceSheetRepository extends R.compose(
this.accounts = accounts;
this.accountsByType = transformToMapBy(accounts, 'accountType');
this.accountsByParentType = transformToMapBy(accounts, 'accountParentType');
};
// ----------------------------
@@ -309,14 +330,15 @@ export default class BalanceSheetRepository extends R.compose(
/**
* Closing accounts date periods.
* @param openingDate
* @param datePeriodsType
* @param {Date} fromDate
* @param {Date} toDate
* @param {string} datePeriodsType
* @returns
*/
public accountsDatePeriods = async (
fromDate: Date,
toDate: Date,
datePeriodsType
datePeriodsType: string
) => {
const { AccountTransaction } = this.models;
@@ -336,6 +358,7 @@ export default class BalanceSheetRepository extends R.compose(
/**
* Retrieve the opening balance transactions of the report.
* @param {Date|string} openingDate -
*/
public closingAccountsTotal = async (openingDate: Date | string) => {
const { AccountTransaction } = this.models;

View File

@@ -0,0 +1,222 @@
import * as R from 'ramda';
import { IAccount, ILedger } from '@/interfaces';
import { FinancialDatePeriods } from '../FinancialDatePeriods';
import { ACCOUNT_PARENT_TYPE } from '@/data/AccountTypes';
export const BalanceSheetRepositoryNetIncome = (Base) =>
class extends R.compose(FinancialDatePeriods)(Base) {
// -----------------------
// # Net Income
// -----------------------
public incomeAccounts: IAccount[];
public incomeAccountsIds: number[];
public expenseAccounts: IAccount[];
public expenseAccountsIds: number[];
public incomePeriodsAccountsLedger: ILedger;
public incomePeriodsOpeningAccountsLedger: ILedger;
public expensesPeriodsAccountsLedger: ILedger;
public expensesOpeningAccountLedger: ILedger;
public incomePPAccountsLedger: ILedger;
public expensePPAccountsLedger: ILedger;
public incomePPPeriodsAccountsLedger: ILedger;
public incomePPPeriodsOpeningAccountLedger: ILedger;
public expensePPPeriodsAccountsLedger: ILedger;
public expensePPPeriodsOpeningAccountLedger: ILedger;
public incomePYTotalAccountsLedger: ILedger;
public expensePYTotalAccountsLedger: ILedger;
public incomePYPeriodsAccountsLedger: ILedger;
public incomePYPeriodsOpeningAccountLedger: ILedger;
public expensePYPeriodsAccountsLedger: ILedger;
public expensePYPeriodsOpeningAccountLedger: ILedger;
/**
* Async initialize.
* @returns {Promise<void>}
*/
public asyncInitializeNetIncome = async () => {
await this.initAccounts();
await this.initAccountsTotalLedger();
// Net Income
this.initIncomeAccounts();
this.initExpenseAccounts();
this.initIncomeTotalLedger();
this.initExpensesTotalLedger();
// Date periods
if (this.query.isDatePeriodsColumnsType()) {
this.initNetIncomeDatePeriods();
}
// Previous Year (PY).
if (this.query.isPreviousYearActive()) {
this.initNetIncomePreviousYear();
}
// Previous Period (PP).
if (this.query.isPreviousPeriodActive()) {
this.initNetIncomePreviousPeriod();
}
// Previous Year (PY) / Date Periods.
if (
this.query.isPreviousYearActive() &&
this.query.isDatePeriodsColumnsType()
) {
this.initNetIncomePeriodsPreviewYear();
}
// Previous Period (PP) / Date Periods.
if (
this.query.isPreviousPeriodActive() &&
this.query.isDatePeriodsColumnsType()
) {
this.initNetIncomePeriodsPreviousPeriod();
}
};
// ----------------------------
// # Net Income
// ----------------------------
/**
* Initialize income accounts.
*/
private initIncomeAccounts = () => {
const incomeAccounts = this.accountsByParentType.get(
ACCOUNT_PARENT_TYPE.INCOME
);
const incomeAccountsIds = incomeAccounts.map((a) => a.id);
this.incomeAccounts = incomeAccounts;
this.incomeAccountsIds = incomeAccountsIds;
};
/**
* Initialize expense accounts.
*/
private initExpenseAccounts = () => {
const expensesAccounts = this.accountsByParentType.get(
ACCOUNT_PARENT_TYPE.EXPENSE
);
const expensesAccountsIds = expensesAccounts.map((a) => a.id);
this.expenseAccounts = expensesAccounts;
this.expenseAccountsIds = expensesAccountsIds;
};
/**
* Initialize the income total ledger.
*/
private initIncomeTotalLedger = (): void => {
// Inject to the repository.
this.incomeLedger = this.totalAccountsLedger.whereAccountsIds(
this.incomeAccountsIds
);
};
/**
* Initialize the expenses total ledger.
*/
private initExpensesTotalLedger = (): void => {
this.expensesLedger = this.totalAccountsLedger.whereAccountsIds(
this.expenseAccountsIds
);
};
// ----------------------------
// # Net Income - Date Periods
// ----------------------------
/**
* Initialize the net income date periods.
*/
public initNetIncomeDatePeriods = () => {
this.incomePeriodsAccountsLedger =
this.periodsAccountsLedger.whereAccountsIds(this.incomeAccountsIds);
this.incomePeriodsOpeningAccountsLedger =
this.periodsOpeningAccountLedger.whereAccountsIds(
this.incomeAccountsIds
);
this.expensesPeriodsAccountsLedger =
this.periodsAccountsLedger.whereAccountsIds(this.expenseAccountsIds);
this.expensesOpeningAccountLedger =
this.periodsOpeningAccountLedger.whereAccountsIds(
this.expenseAccountsIds
);
};
// ----------------------------
// # Net Income - Previous Period
// ----------------------------
/**
* Initialize the total net income PP.
*/
public initNetIncomePreviousPeriod = () => {
this.incomePPAccountsLedger = this.PPTotalAccountsLedger.whereAccountsIds(
this.incomeAccountsIds
);
this.expensePPAccountsLedger =
this.PPTotalAccountsLedger.whereAccountsIds(this.expenseAccountsIds);
};
/**
* Initialize the net income periods of previous period.
*/
public initNetIncomePeriodsPreviousPeriod = () => {
this.incomePPPeriodsAccountsLedger =
this.PPPeriodsAccountsLedger.whereAccountsIds(this.incomeAccountsIds);
this.incomePPPeriodsOpeningAccountLedger =
this.PPPeriodsOpeningAccountLedger.whereAccountsIds(
this.incomeAccountsIds
);
this.expensePPPeriodsAccountsLedger =
this.PPPeriodsAccountsLedger.whereAccountsIds(this.expenseAccountsIds);
this.expensePPPeriodsOpeningAccountLedger =
this.PPPeriodsOpeningAccountLedger.whereAccountsIds(
this.expenseAccountsIds
);
};
// ----------------------------
// # Net Income - Previous Year
// ----------------------------
/**
* Initialize the net income PY total.
*/
public initNetIncomePreviousYear = () => {
this.incomePYTotalAccountsLedger =
this.PYTotalAccountsLedger.whereAccountsIds(this.incomeAccountsIds);
this.expensePYTotalAccountsLedger =
this.PYTotalAccountsLedger.whereAccountsIds(this.expenseAccountsIds);
};
/**
* Initialize the net income PY periods.
*/
public initNetIncomePeriodsPreviewYear = () => {
this.incomePYPeriodsAccountsLedger =
this.PYPeriodsAccountsLedger.whereAccountsIds(this.incomeAccountsIds);
this.incomePYPeriodsOpeningAccountLedger =
this.PYPeriodsOpeningAccountLedger.whereAccountsIds(
this.incomeAccountsIds
);
this.expensePYPeriodsAccountsLedger =
this.PYPeriodsAccountsLedger.whereAccountsIds(this.expenseAccountsIds);
this.expensePYPeriodsOpeningAccountLedger =
this.PYPeriodsOpeningAccountLedger.whereAccountsIds(
this.expenseAccountsIds
);
};
};

View File

@@ -7,12 +7,11 @@ import {
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
import { FinancialSchema } from '../FinancialSchema';
export const BalanceSheetSchema = (Base) =>
class extends R.compose(FinancialSchema)(Base) {
/**
* Retrieves the balance sheet schema.
* @returns
* @returns
*/
getSchema = () => {
return getBalanceSheetSchema();
@@ -115,6 +114,13 @@ export const getBalanceSheetSchema = () => [
id: BALANCE_SHEET_SCHEMA_NODE_ID.EQUITY,
type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS,
accountsTypes: [ACCOUNT_TYPE.EQUITY],
children: [
{
name: 'balance_sheet.net_income',
id: BALANCE_SHEET_SCHEMA_NODE_ID.NET_INCOME,
type: BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME,
},
],
},
],
alwaysShow: true,

View File

@@ -8,6 +8,10 @@ import {
BALANCE_SHEET_SCHEMA_NODE_TYPE,
IBalanceSheetDataNode,
IBalanceSheetSchemaNode,
IBalanceSheetNetIncomeNode,
IBalanceSheetAccountNode,
IBalanceSheetAccountsNode,
IBalanceSheetAggregateNode,
} from '@/interfaces';
import { tableRowMapper } from 'utils';
import FinancialSheet from '../FinancialSheet';
@@ -108,11 +112,13 @@ export default class BalanceSheetTable extends R.compose(
};
/**
*
* @param node
* Retrieves the table row from the given report aggregate node.
* @param {IBalanceSheetAggregateNode} node
* @returns {ITableRow}
*/
private aggregateNodeTableRowsMapper = (node): ITableRow => {
private aggregateNodeTableRowsMapper = (
node: IBalanceSheetAggregateNode
): ITableRow => {
const columns = this.commonColumnsAccessors();
const meta = {
rowTypes: [IROW_TYPE.AGGREGATE],
@@ -122,11 +128,13 @@ export default class BalanceSheetTable extends R.compose(
};
/**
*
* @param node
* Retrieves the table row from the given report accounts node.
* @param {IBalanceSheetAccountsNode} node
* @returns {ITableRow}
*/
private accountsNodeTableRowsMapper = (node): ITableRow => {
private accountsNodeTableRowsMapper = (
node: IBalanceSheetAccountsNode
): ITableRow => {
const columns = this.commonColumnsAccessors();
const meta = {
rowTypes: [IROW_TYPE.ACCOUNTS],
@@ -136,11 +144,13 @@ export default class BalanceSheetTable extends R.compose(
};
/**
*
* @param {} node
* Retrieves the table row from the given report account node.
* @param {IBalanceSheetAccountNode} node
* @returns {ITableRow}
*/
private accountNodeTableRowsMapper = (node): ITableRow => {
private accountNodeTableRowsMapper = (
node: IBalanceSheetAccountNode
): ITableRow => {
const columns = this.commonColumnsAccessors();
const meta = {
@@ -150,6 +160,22 @@ export default class BalanceSheetTable extends R.compose(
return tableRowMapper(node, columns, meta);
};
/**
* Retrieves the table row from the given report net income node.
* @param {IBalanceSheetNetIncomeNode} node
* @returns {ITableRow}
*/
private netIncomeNodeTableRowsMapper = (
node: IBalanceSheetNetIncomeNode
): ITableRow => {
const columns = this.commonColumnsAccessors();
const meta = {
rowTypes: [IROW_TYPE.NET_INCOME],
id: node.id,
};
return tableRowMapper(node, columns, meta);
};
/**
* Mappes the given report node to table rows.
* @param {IBalanceSheetDataNode} node -
@@ -169,6 +195,10 @@ export default class BalanceSheetTable extends R.compose(
this.isNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNT),
this.accountNodeTableRowsMapper,
],
[
this.isNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.NET_INCOME),
this.netIncomeNodeTableRowsMapper,
],
])(node);
};

View File

@@ -9,5 +9,6 @@ export enum IROW_TYPE {
AGGREGATE = 'AGGREGATE',
ACCOUNTS = 'ACCOUNTS',
ACCOUNT = 'ACCOUNT',
NET_INCOME = 'NET_INCOME',
TOTAL = 'TOTAL',
}

View File

@@ -41,10 +41,10 @@ const mapValuesDeepReverse = (nodes, callback, config?) => {
);
const mappedNode = callback(node, children);
_.set(clonedNodes, pathString, {
...mappedNode,
...(!_.isEmpty(children) ? { children } : {}),
});
if (!mappedNode.children && children) {
mappedNode.children = children;
}
_.set(clonedNodes, pathString, mappedNode);
});
return clonedNodes;
};

View File

@@ -1,17 +1,26 @@
FROM node:14.15.0 as build
FROM node:18.16.0-alpine as build
USER root
WORKDIR /app
# Install dependencies
COPY package*.json ./
COPY lerna.json ./
# Copy application dependency manifests to the container image.
COPY ./package*.json ./
COPY ./pnpm-lock.yaml ./pnpm-lock.yaml
COPY ./pnpm-workspace.yaml ./pnpm-workspace.yaml
COPY ./lerna.json ./lerna.json
COPY ./packages/webapp/package*.json ./packages/webapp/
COPY ./packages/webapp/package*.json /app/packages/webapp/
# Install application dependencies
RUN apk update
RUN apk add python3 build-base chromium
RUN npm install
RUN npm run bootstrap
# Set PYHTON env
ENV PYTHON=/usr/bin/python3
# Install pnpm packages dependencies
RUN npm install -g pnpm
RUN pnpm install
# Build webapp package
COPY ./packages/webapp /app/packages/webapp

View File

@@ -5,5 +5,10 @@ module.exports = {
alias: {
'@': path.resolve(__dirname, 'src'),
},
configure: {
resolve: {
fallback: { path: require.resolve('path-browserify') },
},
},
},
};

17
pnpm-lock.yaml generated
View File

@@ -102,7 +102,7 @@ importers:
specifier: ^2.0.0
version: 2.0.0
deepdash:
specifier: ^5.3.7
specifier: ^5.3.9
version: 5.3.9
dotenv:
specifier: ^8.1.0
@@ -257,6 +257,9 @@ importers:
rtl-detect:
specifier: ^1.0.4
version: 1.0.4
source-map-loader:
specifier: ^4.0.1
version: 4.0.1(webpack@5.76.0)
ts-transformer-keys:
specifier: ^0.4.2
version: 0.4.4(typescript@3.9.10)
@@ -22111,6 +22114,18 @@ packages:
webpack: 5.76.0(webpack-cli@4.10.0)
dev: false
/source-map-loader@4.0.1(webpack@5.76.0):
resolution: {integrity: sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==}
engines: {node: '>= 14.15.0'}
peerDependencies:
webpack: ^5.72.1
dependencies:
abab: 2.0.6
iconv-lite: 0.6.3
source-map-js: 1.0.2
webpack: 5.76.0(webpack-cli@4.10.0)
dev: false
/source-map-resolve@0.5.3:
resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==}
deprecated: See https://github.com/lydell/source-map-resolve#deprecated