mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
Compare commits
61 Commits
abouhuolia
...
fix-filter
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84445d4bac | ||
|
|
75d8864aae | ||
|
|
cb6dab08d8 | ||
|
|
5112ef9b64 | ||
|
|
a630e8a612 | ||
|
|
4df63561cf | ||
|
|
c7a3bac44c | ||
|
|
251c54be60 | ||
|
|
5dec4a7df0 | ||
|
|
0d57ca88bf | ||
|
|
b9be83dc2b | ||
|
|
321de4d327 | ||
|
|
4e66d1ac98 | ||
|
|
b5fe5a8bcb | ||
|
|
508054b594 | ||
|
|
34efd58f34 | ||
|
|
f898acdb8b | ||
|
|
f7b53692f5 | ||
|
|
b665d05526 | ||
|
|
de5300b186 | ||
|
|
abc5631ac2 | ||
|
|
9e7b906c86 | ||
|
|
d5decbbd0b | ||
|
|
fbeb489128 | ||
|
|
5bf8a9e0ff | ||
|
|
68fa5cf5c5 | ||
|
|
b1662c3175 | ||
|
|
0fcee0eaa7 | ||
|
|
5b2be2ac19 | ||
|
|
5bb80fde34 | ||
|
|
58f90a0bcd | ||
|
|
e1a3510f0b | ||
|
|
172eea0ad1 | ||
|
|
74c4418549 | ||
|
|
6b6e19f53b | ||
|
|
01f7effc71 | ||
|
|
1411f64cf6 | ||
|
|
2c9739ac91 | ||
|
|
e214b86a62 | ||
|
|
b01b7010c0 | ||
|
|
e7cd035206 | ||
|
|
f82b78c4eb | ||
|
|
847b4380be | ||
|
|
271011cb3c | ||
|
|
b6d8766173 | ||
|
|
efffdc021b | ||
|
|
01dd0ffb8c | ||
|
|
d910985b37 | ||
|
|
d5799bf720 | ||
|
|
56cc1da034 | ||
|
|
ef9b4ebad6 | ||
|
|
29af788dcd | ||
|
|
b2510145dc | ||
|
|
5f3a309a8f | ||
|
|
e2fdc13b3e | ||
|
|
34cd21cced | ||
|
|
0e589ace82 | ||
|
|
f46f595e96 | ||
|
|
53ef940b05 | ||
|
|
65495775d4 | ||
|
|
1cf11e020f |
@@ -51,6 +51,15 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "KalliopiPliogka",
|
||||
"name": "Kalliopi Pliogka",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/81677549?v=4",
|
||||
"profile": "https://github.com/KalliopiPliogka",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -97,7 +97,7 @@ All notable changes to Bigcapital server-side will be in this file.
|
||||
- fix: delete invoice transaction issue.
|
||||
|
||||
`@bigcapital/webapp`
|
||||
- fix: general, accoutant and items preferences.
|
||||
- fix: general, accountant and items preferences.
|
||||
- fix: auto-increment sale invoices, estiamtes, credit notes, payments and manual journals.
|
||||
- refactor: the setup organization form to use binded Formik components.
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ Please read through this document before submitting any issues or pull requests
|
||||
## Sections
|
||||
|
||||
- [General Instructions](#general-instructions)
|
||||
- [Local Setup Prerequisites](#local-setup-prerequisites)
|
||||
- [Contribute to Backend](#contribute-to-backend)
|
||||
- [Contribute to Frontend](#contribute-to-frontend)
|
||||
- [Other Ways to Contribute](#other-ways-to-contribute)
|
||||
@@ -31,9 +32,18 @@ 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)
|
||||
|
||||
## Contribute to Backend
|
||||
|
||||
- Clone the `bigcapital` repository and `cd` into `bigcapital` directory.
|
||||
- Create `.env` file by copying `.env.example` file to `.env`. (The ``.env.example`` file has all the necessary values of variables to start development directly).
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
```
|
||||
|
||||
@@ -73,6 +73,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/elforjani13"><img src="https://avatars.githubusercontent.com/u/39470382?v=4?s=100" width="100px;" alt="ElforJani13"/><br /><sub><b>ElforJani13</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=elforjani13" title="Code">💻</a></td>
|
||||
<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>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
"Opening Balance Liabilities": "رصيد الالتزامات الافتتاحي",
|
||||
"Loan": "اقراض",
|
||||
"Owner A Drawings": "مسحوبات المالك",
|
||||
"An account that holds valuation of products or goods that availiable for sale.": "حساب يحمل قيم مخزون البضاعة أو السلع المتاحة للبيع.",
|
||||
"An account that holds valuation of products or goods that available for sale.": "حساب يحمل قيم مخزون البضاعة أو السلع المتاحة للبيع.",
|
||||
"Tracks the gain and losses of the exchange differences.": "يسجل مكاسب وخسائر فروق الصرف.",
|
||||
"Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.": "يتم تسجيل أي رسوم مصرفية يتم فرضها في حساب الرسوم والمصروفات البنكية. ومن الأمثلة على ذلك رسوم صيانة الحساب المصرفي ورسوم المعاملات ورسوم الدفع المتأخر.",
|
||||
"The income activities are not associated to the core business.": "لا ترتبط انشطة الدخل إلى الأعمال الأساسية.",
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
"Opening Balance Liabilities": "Opening Balance Liabilities",
|
||||
"Loan": "Loan",
|
||||
"Owner A Drawings": "Owner A Drawings",
|
||||
"An account that holds valuation of products or goods that availiable for sale.": "An account that holds valuation of products or goods that availiable for sale.",
|
||||
"An account that holds valuation of products or goods that available for sale.": "An account that holds valuation of products or goods that available for sale.",
|
||||
"Tracks the gain and losses of the exchange differences.": "Tracks the gain and losses of the exchange differences.",
|
||||
"Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.": "Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.",
|
||||
"The income activities are not associated to the core business.": "The income activities are not associated to the core business.",
|
||||
|
||||
@@ -33,10 +33,13 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC
|
||||
return [
|
||||
...this.sheetNumberFormatValidationSchema,
|
||||
query('as_date').optional().isISO8601(),
|
||||
query('aging_days_before').optional().isNumeric().toInt(),
|
||||
query('aging_periods').optional().isNumeric().toInt(),
|
||||
|
||||
query('aging_days_before').default(30).isInt({ max: 500 }).toInt(),
|
||||
query('aging_periods').default(3).isInt({ max: 12 }).toInt(),
|
||||
|
||||
query('vendors_ids').optional().isArray({ min: 1 }),
|
||||
query('vendors_ids.*').isInt({ min: 1 }).toInt(),
|
||||
|
||||
query('none_zero').default(true).isBoolean().toBoolean(),
|
||||
|
||||
// Filtering by branches.
|
||||
@@ -53,15 +56,36 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC
|
||||
const filter = this.matchedQueryData(req);
|
||||
|
||||
try {
|
||||
const { data, columns, query, meta } =
|
||||
await this.APAgingSummaryService.APAgingSummary(tenantId, filter);
|
||||
const accept = this.accepts(req);
|
||||
const acceptType = accept.types(['json', 'application/json+table']);
|
||||
|
||||
return res.status(200).send({
|
||||
data: this.transfromToResponse(data),
|
||||
columns: this.transfromToResponse(columns),
|
||||
query: this.transfromToResponse(query),
|
||||
meta: this.transfromToResponse(meta),
|
||||
});
|
||||
switch (acceptType) {
|
||||
case 'application/json+table':
|
||||
const table = await this.APAgingSummaryService.APAgingSummaryTable(
|
||||
tenantId,
|
||||
filter
|
||||
);
|
||||
return res.status(200).send({
|
||||
table: {
|
||||
rows: table.rows,
|
||||
columns: table.columns,
|
||||
},
|
||||
meta: table.meta,
|
||||
query: table.query,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
const { data, columns, query, meta } =
|
||||
await this.APAgingSummaryService.APAgingSummary(tenantId, filter);
|
||||
|
||||
return res.status(200).send({
|
||||
data: this.transfromToResponse(data),
|
||||
columns: this.transfromToResponse(columns),
|
||||
query: this.transfromToResponse(query),
|
||||
meta: this.transfromToResponse(meta),
|
||||
});
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC
|
||||
|
||||
query('as_date').optional().isISO8601(),
|
||||
|
||||
query('aging_days_before').optional().isInt({ max: 500 }).toInt(),
|
||||
query('aging_periods').optional().isInt({ max: 12 }).toInt(),
|
||||
query('aging_days_before').default(30).isInt({ max: 500 }).toInt(),
|
||||
query('aging_periods').default(3).isInt({ max: 12 }).toInt(),
|
||||
|
||||
query('customers_ids').optional().isArray({ min: 1 }),
|
||||
query('customers_ids.*').isInt({ min: 1 }).toInt(),
|
||||
@@ -58,15 +58,36 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC
|
||||
const filter = this.matchedQueryData(req);
|
||||
|
||||
try {
|
||||
const { data, columns, query, meta } =
|
||||
await this.ARAgingSummaryService.ARAgingSummary(tenantId, filter);
|
||||
const accept = this.accepts(req);
|
||||
const acceptType = accept.types(['json', 'application/json+table']);
|
||||
|
||||
return res.status(200).send({
|
||||
data: this.transfromToResponse(data),
|
||||
columns: this.transfromToResponse(columns),
|
||||
query: this.transfromToResponse(query),
|
||||
meta: this.transfromToResponse(meta),
|
||||
});
|
||||
switch (acceptType) {
|
||||
case 'application/json+table':
|
||||
const table = await this.ARAgingSummaryService.ARAgingSummaryTable(
|
||||
tenantId,
|
||||
filter
|
||||
);
|
||||
return res.status(200).send({
|
||||
table: {
|
||||
rows: table.rows,
|
||||
columns: table.columns,
|
||||
},
|
||||
meta: table.meta,
|
||||
query: table.query,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
const { data, columns, query, meta } =
|
||||
await this.ARAgingSummaryService.ARAgingSummary(tenantId, filter);
|
||||
|
||||
return res.status(200).send({
|
||||
data: this.transfromToResponse(data),
|
||||
columns: this.transfromToResponse(columns),
|
||||
query: this.transfromToResponse(query),
|
||||
meta: this.transfromToResponse(meta),
|
||||
});
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ export default class ManualJournalsController extends BaseController {
|
||||
errors: [{ type: 'CREDIT.DEBIT.NOT.EQUALS', code: 300 }],
|
||||
});
|
||||
}
|
||||
if (error.errorType === 'acccounts_ids_not_found') {
|
||||
if (error.errorType === 'accounts_ids_not_found') {
|
||||
return res.boom.badRequest(
|
||||
'Journal entries some of accounts ids not exists.',
|
||||
{ errors: [{ type: 'ACCOUNTS.IDS.NOT.FOUND', code: 400 }] }
|
||||
|
||||
@@ -372,7 +372,7 @@ export default class PaymentReceivesController extends BaseController {
|
||||
|
||||
/**
|
||||
* Retrieve the given payment receive details.
|
||||
* @asycn
|
||||
* @async
|
||||
* @param {Request} req -
|
||||
* @param {Response} res -
|
||||
*/
|
||||
|
||||
@@ -81,7 +81,7 @@ export default [
|
||||
parent_account_id: null,
|
||||
index: 1,
|
||||
active: 1,
|
||||
description:'An account that holds valuation of products or goods that availiable for sale.',
|
||||
description:'An account that holds valuation of products or goods that available for sale.',
|
||||
},
|
||||
|
||||
// Libilities
|
||||
|
||||
@@ -1,51 +1,36 @@
|
||||
import {
|
||||
IAgingPeriod,
|
||||
IAgingPeriodTotal,
|
||||
IAgingAmount
|
||||
IAgingAmount,
|
||||
IAgingSummaryQuery,
|
||||
IAgingSummaryTotal,
|
||||
IAgingSummaryContact,
|
||||
IAgingSummaryData,
|
||||
} from './AgingReport';
|
||||
import {
|
||||
INumberFormatQuery
|
||||
} from './FinancialStatements';
|
||||
import { INumberFormatQuery } from './FinancialStatements';
|
||||
|
||||
export interface IAPAgingSummaryQuery {
|
||||
asDate: Date | string;
|
||||
agingDaysBefore: number;
|
||||
agingPeriods: number;
|
||||
numberFormat: INumberFormatQuery;
|
||||
export interface IAPAgingSummaryQuery extends IAgingSummaryQuery {
|
||||
vendorsIds: number[];
|
||||
noneZero: boolean;
|
||||
|
||||
branchesIds?: number[]
|
||||
}
|
||||
|
||||
export interface IAPAgingSummaryVendor {
|
||||
vendorName: string,
|
||||
current: IAgingAmount,
|
||||
aging: IAgingPeriodTotal[],
|
||||
total: IAgingAmount,
|
||||
};
|
||||
export interface IAPAgingSummaryVendor extends IAgingSummaryContact {
|
||||
vendorName: string;
|
||||
}
|
||||
|
||||
export interface IAPAgingSummaryTotal {
|
||||
current: IAgingAmount,
|
||||
aging: IAgingPeriodTotal[],
|
||||
total: IAgingAmount,
|
||||
};
|
||||
export interface IAPAgingSummaryTotal extends IAgingSummaryTotal {}
|
||||
|
||||
export interface IAPAgingSummaryData {
|
||||
vendors: IAPAgingSummaryVendor[],
|
||||
total: IAPAgingSummaryTotal,
|
||||
};
|
||||
export interface IAPAgingSummaryData extends IAgingSummaryData {
|
||||
vendors: IAPAgingSummaryVendor[];
|
||||
}
|
||||
|
||||
export type IAPAgingSummaryColumns = IAgingPeriod[];
|
||||
|
||||
|
||||
export interface IARAgingSummaryMeta {
|
||||
baseCurrency: string,
|
||||
organizationName: string,
|
||||
baseCurrency: string;
|
||||
organizationName: string;
|
||||
}
|
||||
|
||||
|
||||
export interface IAPAgingSummaryMeta {
|
||||
baseCurrency: string,
|
||||
organizationName: string,
|
||||
}
|
||||
baseCurrency: string;
|
||||
organizationName: string;
|
||||
}
|
||||
|
||||
@@ -1,37 +1,28 @@
|
||||
import { IAgingPeriod, IAgingPeriodTotal, IAgingAmount } from './AgingReport';
|
||||
import { INumberFormatQuery } from './FinancialStatements';
|
||||
import {
|
||||
IAgingPeriod,
|
||||
IAgingSummaryQuery,
|
||||
IAgingSummaryTotal,
|
||||
IAgingSummaryContact,
|
||||
IAgingSummaryData,
|
||||
} from './AgingReport';
|
||||
|
||||
export interface IARAgingSummaryQuery {
|
||||
asDate: Date | string;
|
||||
agingDaysBefore: number;
|
||||
agingPeriods: number;
|
||||
numberFormat: INumberFormatQuery;
|
||||
export interface IARAgingSummaryQuery extends IAgingSummaryQuery {
|
||||
customersIds: number[];
|
||||
branchesIds: number[];
|
||||
noneZero: boolean;
|
||||
}
|
||||
|
||||
export interface IARAgingSummaryCustomer {
|
||||
export interface IARAgingSummaryCustomer extends IAgingSummaryContact {
|
||||
customerName: string;
|
||||
current: IAgingAmount;
|
||||
aging: IAgingPeriodTotal[];
|
||||
total: IAgingAmount;
|
||||
}
|
||||
|
||||
export interface IARAgingSummaryTotal {
|
||||
current: IAgingAmount;
|
||||
aging: IAgingPeriodTotal[];
|
||||
total: IAgingAmount;
|
||||
}
|
||||
export interface IARAgingSummaryTotal extends IAgingSummaryTotal {}
|
||||
|
||||
export interface IARAgingSummaryData {
|
||||
export interface IARAgingSummaryData extends IAgingSummaryData {
|
||||
customers: IARAgingSummaryCustomer[];
|
||||
total: IARAgingSummaryTotal;
|
||||
}
|
||||
|
||||
export type IARAgingSummaryColumns = IAgingPeriod[];
|
||||
|
||||
export interface IARAgingSummaryMeta {
|
||||
organizationName: string,
|
||||
baseCurrency: string,
|
||||
}
|
||||
organizationName: string;
|
||||
baseCurrency: string;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ export interface IAccountTransaction {
|
||||
date: string | Date;
|
||||
|
||||
referenceType: string;
|
||||
referenceTypeFormatted: string;
|
||||
referenceId: number;
|
||||
|
||||
referenceNumber?: string;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
import { INumberFormatQuery } from './FinancialStatements';
|
||||
|
||||
export interface IAgingPeriodTotal extends IAgingPeriod {
|
||||
total: IAgingAmount;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IAgingAmount {
|
||||
amount: number;
|
||||
@@ -20,3 +23,22 @@ export interface IAgingSummaryContact {
|
||||
aging: IAgingPeriodTotal[];
|
||||
total: IAgingAmount;
|
||||
}
|
||||
|
||||
export interface IAgingSummaryQuery {
|
||||
asDate: Date | string;
|
||||
agingDaysBefore: number;
|
||||
agingPeriods: number;
|
||||
numberFormat: INumberFormatQuery;
|
||||
branchesIds: number[];
|
||||
noneZero: boolean;
|
||||
}
|
||||
|
||||
export interface IAgingSummaryTotal {
|
||||
current: IAgingAmount;
|
||||
aging: IAgingPeriodTotal[];
|
||||
total: IAgingAmount;
|
||||
}
|
||||
|
||||
export interface IAgingSummaryData {
|
||||
total: IAgingSummaryTotal;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Knex } from 'knex';
|
||||
import { IDynamicListFilterDTO } from './DynamicFilter';
|
||||
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
||||
import { IBillLandedCost } from './LandedCost';
|
||||
import { IBillLandedCost } from './LandedCost';
|
||||
export interface IBillDTO {
|
||||
vendorId: number;
|
||||
billNumber: string;
|
||||
@@ -99,17 +99,17 @@ export interface IBillCreatedPayload {
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
|
||||
export interface IBillCreatingPayload{
|
||||
export interface IBillCreatingPayload {
|
||||
tenantId: number;
|
||||
billDTO: IBillDTO;
|
||||
trx: Knex.Transaction;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
|
||||
export interface IBillEditingPayload {
|
||||
tenantId: number;
|
||||
oldBill: IBill;
|
||||
billDTO: IBillEditDTO;
|
||||
trx: Knex.Transaction;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
export interface IBillEditedPayload {
|
||||
tenantId: number;
|
||||
@@ -129,7 +129,7 @@ export interface IBIllEventDeletedPayload {
|
||||
export interface IBillEventDeletingPayload {
|
||||
tenantId: number;
|
||||
oldBill: IBill;
|
||||
trx: Knex.Transaction;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
export enum BillAction {
|
||||
Create = 'Create',
|
||||
@@ -138,3 +138,16 @@ export enum BillAction {
|
||||
View = 'View',
|
||||
NotifyBySms = 'NotifyBySms',
|
||||
}
|
||||
|
||||
export interface IBillOpeningPayload {
|
||||
trx: Knex.Transaction;
|
||||
tenantId: number;
|
||||
oldBill: IBill;
|
||||
}
|
||||
|
||||
export interface IBillOpenedPayload {
|
||||
trx: Knex.Transaction;
|
||||
bill: IBill;
|
||||
oldBill: IBill;
|
||||
tenantId: number;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export interface ICashFlowStatementAccountMeta {
|
||||
code: string;
|
||||
total: ICashFlowStatementTotal;
|
||||
accountType: string;
|
||||
adjusmentType: string;
|
||||
adjustmentType: string;
|
||||
sectionType: ICashFlowStatementSectionType.ACCOUNT;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ISystemUser } from '@/interfaces';
|
||||
import { Knex } from 'knex';
|
||||
import { pick } from 'lodash';
|
||||
import { ISystemUser } from '@/interfaces';
|
||||
import { ILedgerEntry } from './Ledger';
|
||||
import { ISaleInvoice } from './SaleInvoice';
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ export interface ISaleInvoiceEventDeliveredPayload {
|
||||
tenantId: number;
|
||||
saleInvoiceId: number;
|
||||
saleInvoice: ISaleInvoice;
|
||||
trx: Knex.Transaction;
|
||||
}
|
||||
|
||||
export interface ISaleInvoiceDeliveringPayload {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { forEach, uniqBy } from 'lodash';
|
||||
import DynamicFilterAbstructor from './DynamicFilterAbstructor';
|
||||
import DynamicFilterAbstractor from './DynamicFilterAbstractor';
|
||||
import { IDynamicFilter, IFilterRole, IModel } from '@/interfaces';
|
||||
|
||||
export default class DynamicFilter extends DynamicFilterAbstructor{
|
||||
export default class DynamicFilter extends DynamicFilterAbstractor{
|
||||
private model: IModel;
|
||||
private tableName: string;
|
||||
private dynamicFilters: IDynamicFilter[];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
export default class DynamicFilterAbstructor {
|
||||
export default class DynamicFilterAbstractor {
|
||||
/**
|
||||
* Extract relation table name from relation.
|
||||
* @param {String} column -
|
||||
@@ -1,7 +1,7 @@
|
||||
import DynamicFilterRoleAbstructor from './DynamicFilterRoleAbstructor';
|
||||
import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor';
|
||||
import { IFilterRole } from '@/interfaces';
|
||||
|
||||
export default class FilterRoles extends DynamicFilterRoleAbstructor {
|
||||
export default class FilterRoles extends DynamicFilterRoleAbstractor {
|
||||
private filterRoles: IFilterRole[];
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ import DynamicFilterQueryParser from './DynamicFilterQueryParser';
|
||||
import { Lexer } from '../LogicEvaluation/Lexer';
|
||||
import { COMPARATOR_TYPE, FIELD_TYPE } from './constants';
|
||||
|
||||
export default abstract class DynamicFilterAbstructor
|
||||
export default abstract class DynamicFilterAbstractor
|
||||
implements IDynamicFilter
|
||||
{
|
||||
protected filterRoles: IFilterRole[] = [];
|
||||
@@ -1,4 +1,4 @@
|
||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
||||
import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor';
|
||||
import { FIELD_TYPE } from './constants';
|
||||
|
||||
interface ISortRole {
|
||||
@@ -6,7 +6,7 @@ interface ISortRole {
|
||||
order: string;
|
||||
}
|
||||
|
||||
export default class DynamicFilterSortBy extends DynamicFilterRoleAbstructor {
|
||||
export default class DynamicFilterSortBy extends DynamicFilterRoleAbstractor {
|
||||
private sortRole: ISortRole = {};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { omit } from 'lodash';
|
||||
import { IView, IViewRole } from '@/interfaces';
|
||||
import DynamicFilterRoleAbstructor from './DynamicFilterRoleAbstructor';
|
||||
import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor';
|
||||
|
||||
export default class DynamicFilterViews extends DynamicFilterRoleAbstructor {
|
||||
export default class DynamicFilterViews extends DynamicFilterRoleAbstractor {
|
||||
private viewSlug: string;
|
||||
private logicExpression: string;
|
||||
private filterRoles: IViewRole[];
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
||||
import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor';
|
||||
import {
|
||||
validateViewRoles,
|
||||
buildFilterQuery,
|
||||
} from '@/lib/ViewRolesBuilder';
|
||||
|
||||
export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstructor {
|
||||
export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstractor {
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {*} filterRoles -
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
|
||||
import ItemSubscriber from '@/subscribers/Items/ItemSubscriber';
|
||||
import InventoryAdjustmentsSubscriber from '@/subscribers/Inventory/InventoryAdjustment';
|
||||
import BillWriteInventoryTransactionsSubscriber from '@/subscribers/Bills/WriteInventoryTransactions';
|
||||
import PaymentSyncBillBalance from '@/subscribers/PaymentMades/PaymentSyncBillBalance';
|
||||
@@ -87,7 +86,6 @@ export default () => {
|
||||
|
||||
export const susbcribers = () => {
|
||||
return [
|
||||
ItemSubscriber,
|
||||
InventoryAdjustmentsSubscriber,
|
||||
BillWriteInventoryTransactionsSubscriber,
|
||||
PaymentSyncBillBalance,
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
"Opening Balance Liabilities": "رصيد الالتزامات الافتتاحي",
|
||||
"Loan": "اقراض",
|
||||
"Owner A Drawings": "مسحوبات المالك",
|
||||
"An account that holds valuation of products or goods that availiable for sale.": "حساب يحمل قيم مخزون البضاعة أو السلع المتاحة للبيع.",
|
||||
"An account that holds valuation of products or goods that available for sale.": "حساب يحمل قيم مخزون البضاعة أو السلع المتاحة للبيع.",
|
||||
"Tracks the gain and losses of the exchange differences.": "يسجل مكاسب وخسائر فروق الصرف.",
|
||||
"Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.": "يتم تسجيل أي رسوم مصرفية يتم فرضها في حساب الرسوم والمصروفات البنكية. ومن الأمثلة على ذلك رسوم صيانة الحساب المصرفي ورسوم المعاملات ورسوم الدفع المتأخر.",
|
||||
"The income activities are not associated to the core business.": "لا ترتبط انشطة الدخل إلى الأعمال الأساسية.",
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
"Opening Balance Liabilities": "Opening Balance Liabilities",
|
||||
"Loan": "Loan",
|
||||
"Owner A Drawings": "Owner A Drawings",
|
||||
"An account that holds valuation of products or goods that availiable for sale.": "An account that holds valuation of products or goods that availiable for sale.",
|
||||
"An account that holds valuation of products or goods that available for sale.": "An account that holds valuation of products or goods that available for sale.",
|
||||
"Tracks the gain and losses of the exchange differences.": "Tracks the gain and losses of the exchange differences.",
|
||||
"Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.": "Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.",
|
||||
"The income activities are not associated to the core business.": "The income activities are not associated to the core business.",
|
||||
|
||||
@@ -127,7 +127,7 @@ export default class Account extends mixin(TenantModel, [
|
||||
},
|
||||
filterAccountTypes(query, typesIds) {
|
||||
if (typesIds.length > 0) {
|
||||
query.whereIn('account_types.accoun_type_id', typesIds);
|
||||
query.whereIn('account_types.account_type_id', typesIds);
|
||||
}
|
||||
},
|
||||
viewRolesBuilder(query, conditionals, expression) {
|
||||
|
||||
@@ -2,8 +2,11 @@ import { Model, raw } from 'objection';
|
||||
import moment from 'moment';
|
||||
import { isEmpty, castArray } from 'lodash';
|
||||
import TenantModel from 'models/TenantModel';
|
||||
import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||
|
||||
export default class AccountTransaction extends TenantModel {
|
||||
referenceType: string;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
@@ -30,40 +33,7 @@ export default class AccountTransaction extends TenantModel {
|
||||
* @return {string}
|
||||
*/
|
||||
get referenceTypeFormatted() {
|
||||
return AccountTransaction.getReferenceTypeFormatted(this.referenceType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference type formatted.
|
||||
*/
|
||||
static getReferenceTypeFormatted(referenceType) {
|
||||
const mapped = {
|
||||
SaleInvoice: 'Sale invoice',
|
||||
SaleReceipt: 'Sale receipt',
|
||||
PaymentReceive: 'Payment receive',
|
||||
Bill: 'Bill',
|
||||
BillPayment: 'Payment made',
|
||||
VendorOpeningBalance: 'Vendor opening balance',
|
||||
CustomerOpeningBalance: 'Customer opening balance',
|
||||
InventoryAdjustment: 'Inventory adjustment',
|
||||
ManualJournal: 'Manual journal',
|
||||
Journal: 'Manual journal',
|
||||
Expense: 'Expense',
|
||||
OwnerContribution: 'Owner contribution',
|
||||
TransferToAccount: 'Transfer to account',
|
||||
TransferFromAccount: 'Transfer from account',
|
||||
OtherIncome: 'Other income',
|
||||
OtherExpense: 'Other expense',
|
||||
OwnerDrawing: 'Owner drawing',
|
||||
InvoiceWriteOff: 'Invoice write-off',
|
||||
|
||||
CreditNote: 'transaction_type.credit_note',
|
||||
VendorCredit: 'transaction_type.vendor_credit',
|
||||
|
||||
RefundCreditNote: 'transaction_type.refund_credit_note',
|
||||
RefundVendorCredit: 'transaction_type.refund_vendor_credit',
|
||||
};
|
||||
return mapped[referenceType] || '';
|
||||
return getTransactionTypeLabel(this.referenceType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,15 +59,9 @@ export default class AccountTransaction extends TenantModel {
|
||||
}
|
||||
},
|
||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
const fromDate = moment(startDate)
|
||||
.utcOffset(0)
|
||||
.startOf(type)
|
||||
.format(dateFormat);
|
||||
const toDate = moment(endDate)
|
||||
.utcOffset(0)
|
||||
.endOf(type)
|
||||
.format(dateFormat);
|
||||
const dateFormat = 'YYYY-MM-DD';
|
||||
const fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
||||
|
||||
if (startDate) {
|
||||
query.where('date', '>=', fromDate);
|
||||
@@ -141,7 +105,6 @@ export default class AccountTransaction extends TenantModel {
|
||||
query.modify('filterDateRange', null, toDate);
|
||||
query.modify('sumationCreditDebit');
|
||||
},
|
||||
|
||||
contactsOpeningBalance(
|
||||
query,
|
||||
openingDate,
|
||||
|
||||
@@ -97,7 +97,7 @@ export default class Branch extends TenantModel {
|
||||
},
|
||||
|
||||
/**
|
||||
* Branch may belongs to assocaited bills.
|
||||
* Branch may belongs to associated bills.
|
||||
*/
|
||||
bills: {
|
||||
relation: Model.HasManyRelation,
|
||||
|
||||
@@ -121,7 +121,7 @@ export default class CashflowTransaction extends TenantModel {
|
||||
},
|
||||
|
||||
/**
|
||||
* Cashflow transaction may has assocaited cashflow account.
|
||||
* Cashflow transaction may has associated cashflow account.
|
||||
*/
|
||||
cashflowAccount: {
|
||||
relation: Model.BelongsToOneRelation,
|
||||
|
||||
@@ -33,7 +33,7 @@ export default class InventoryCostLotTracker extends TenantModel {
|
||||
query.groupBy('item_id');
|
||||
},
|
||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
const dateFormat = 'YYYY-MM-DD';
|
||||
const fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
||||
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { Model, raw } from 'objection';
|
||||
import { castArray, isEmpty } from 'lodash';
|
||||
import { castArray } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import TenantModel from 'models/TenantModel';
|
||||
import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||
|
||||
export default class InventoryTransaction extends TenantModel {
|
||||
transactionId: number;
|
||||
transactionType: string;
|
||||
|
||||
/**
|
||||
* Table name
|
||||
*/
|
||||
@@ -23,27 +27,7 @@ export default class InventoryTransaction extends TenantModel {
|
||||
* @return {string}
|
||||
*/
|
||||
get transcationTypeFormatted() {
|
||||
return InventoryTransaction.getReferenceTypeFormatted(this.transactionType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference type formatted.
|
||||
*/
|
||||
static getReferenceTypeFormatted(referenceType) {
|
||||
const mapped = {
|
||||
SaleInvoice: 'Sale invoice',
|
||||
SaleReceipt: 'Sale receipt',
|
||||
PaymentReceive: 'Payment receive',
|
||||
Bill: 'Bill',
|
||||
BillPayment: 'Payment made',
|
||||
VendorOpeningBalance: 'Vendor opening balance',
|
||||
CustomerOpeningBalance: 'Customer opening balance',
|
||||
InventoryAdjustment: 'Inventory adjustment',
|
||||
ManualJournal: 'Manual journal',
|
||||
Journal: 'Manual journal',
|
||||
LandedCost: 'transaction_type.landed_cost',
|
||||
};
|
||||
return mapped[referenceType] || '';
|
||||
return getTransactionTypeLabel(this.transactionType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +36,7 @@ export default class InventoryTransaction extends TenantModel {
|
||||
static get modifiers() {
|
||||
return {
|
||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
const dateFormat = 'YYYY-MM-DD';
|
||||
const fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
||||
* Filters the invoices between the given date range.
|
||||
*/
|
||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
||||
const dateFormat = 'YYYY-MM-DD';
|
||||
const fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export default class Warehouse extends TenantModel {
|
||||
},
|
||||
|
||||
/**
|
||||
* Warehouse may belongs to assocaited bills.
|
||||
* Warehouse may belongs to associated bills.
|
||||
*/
|
||||
bills: {
|
||||
relation: Model.HasManyRelation,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import events from '@/subscribers/events';
|
||||
import { InventoryTransactionsWarehouses } from './AcountsTransactionsWarehouses';
|
||||
import { InventoryTransactionsWarehouses } from './AccountsTransactionsWarehouses';
|
||||
import { IBranchesActivatedPayload } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
|
||||
@@ -79,7 +79,7 @@ export default class JournalPoster implements IJournalPoster {
|
||||
}
|
||||
|
||||
/**
|
||||
* Async initialize acccounts dependency graph.
|
||||
* Async initialize accounts dependency graph.
|
||||
* @private
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
|
||||
@@ -66,14 +66,14 @@ export class LedgerContactsBalanceStorage {
|
||||
): Promise<(entry: ILedgerEntry) => boolean> => {
|
||||
const { Account } = this.tenancy.models(tenantId);
|
||||
|
||||
const ARAPAcounts = await Account.query(trx).whereIn('accountType', [
|
||||
const ARAPAccounts = await Account.query(trx).whereIn('accountType', [
|
||||
ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE,
|
||||
ACCOUNT_TYPE.ACCOUNTS_PAYABLE,
|
||||
]);
|
||||
const ARAPAcountsIds = ARAPAcounts.map((a) => a.id);
|
||||
const ARAPAccountsIds = ARAPAccounts.map((a) => a.id);
|
||||
|
||||
return (entry: ILedgerEntry) => {
|
||||
return ARAPAcountsIds.indexOf(entry.accountId) !== -1;
|
||||
return ARAPAccountsIds.indexOf(entry.accountId) !== -1;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ export default class LedgerStorageService {
|
||||
// Saves the ledger entries.
|
||||
this.ledgerEntriesService.saveEntries(tenantId, ledger, trx),
|
||||
|
||||
// Mutates the assocaited accounts balances.
|
||||
// Mutates the associated accounts balances.
|
||||
this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx),
|
||||
|
||||
// Mutates the associated contacts balances.
|
||||
@@ -60,7 +60,7 @@ export default class LedgerStorageService {
|
||||
// Deletes the ledger entries.
|
||||
this.ledgerEntriesService.deleteEntries(tenantId, ledger, trx),
|
||||
|
||||
// Mutates the assocaited accounts balances.
|
||||
// Mutates the associated accounts balances.
|
||||
this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx),
|
||||
|
||||
// Mutates the associated contacts balances.
|
||||
|
||||
@@ -108,7 +108,7 @@ export class LedegrAccountsStorage {
|
||||
const { Account } = this.tenancy.models(tenantId);
|
||||
const account = await Account.query(trx).findById(accountId);
|
||||
|
||||
// Filters the ledger entries by the current acount.
|
||||
// Filters the ledger entries by the current account.
|
||||
const accountLedger = ledger.whereAccountId(accountId);
|
||||
|
||||
// Retrieves the given tenant metadata.
|
||||
|
||||
@@ -46,7 +46,7 @@ export default class AccountTransactionTransformer extends Transformer {
|
||||
* @returns {string}
|
||||
*/
|
||||
public transactionTypeFormatted(transaction: IAccountTransaction) {
|
||||
return transaction.referenceTypeFormatted;
|
||||
return this.context.i18n.__(transaction.referenceTypeFormatted);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,7 +77,7 @@ export class DeleteAccount {
|
||||
// Authorize before delete account.
|
||||
await this.authorize(tenantId, accountId, oldAccount);
|
||||
|
||||
// Deletes the account and assocaited transactions under UOW envirement.
|
||||
// Deletes the account and associated transactions under UOW envirement.
|
||||
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
|
||||
// Triggers `onAccountDelete` event.
|
||||
await this.eventPublisher.emitAsync(events.accounts.onDelete, {
|
||||
|
||||
@@ -23,15 +23,6 @@ export class GetAccounts {
|
||||
@Inject()
|
||||
private transformer: TransformerInjectable;
|
||||
|
||||
/**
|
||||
* Parsees accounts list filter DTO.
|
||||
* @param filterDTO
|
||||
* @returns
|
||||
*/
|
||||
private parseListFilterDTO(filterDTO) {
|
||||
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve accounts datatable list.
|
||||
* @param {number} tenantId
|
||||
@@ -75,4 +66,13 @@ export class GetAccounts {
|
||||
filterMeta: dynamicList.getResponseMeta(),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Parsees accounts list filter DTO.
|
||||
* @param filterDTO
|
||||
* @returns
|
||||
*/
|
||||
private parseListFilterDTO(filterDTO) {
|
||||
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
|
||||
export class AccountsReceivableRepository {
|
||||
|
||||
|
||||
findOrCreateAccount = (currencyCode?: string) => {
|
||||
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from './CashflowBranchesActviateSubscriber';
|
||||
export * from './CashflowBranchesActivateSubscriber';
|
||||
export * from './CreditNoteBranchesActivateSubscriber';
|
||||
export * from './PaymentMadeBranchesActivateSubscriber';
|
||||
export * from './PaymentReceiveBranchesActivateSubscriber';
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import { includes, difference, camelCase, upperFirst } from 'lodash';
|
||||
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
|
||||
import { IAccount, ICashflowTransactionLine } from '@/interfaces';
|
||||
import { Service } from 'typedi';
|
||||
import { includes, camelCase, upperFirst } from 'lodash';
|
||||
import { IAccount } from '@/interfaces';
|
||||
import { getCashflowTransactionType } from './utils';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { CASHFLOW_TRANSACTION_TYPE, ERRORS } from './constants';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
|
||||
@Service()
|
||||
export class CommandCashflowValidator {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
* Validates the lines accounts type should be cash or bank account.
|
||||
* @param {IAccount} accounts -
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { difference, includes } from 'lodash';
|
||||
import { ICashflowTransactionLine } from '@/interfaces';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { CASHFLOW_TRANSACTION_TYPE, ERRORS } from './constants';
|
||||
import { IAccount } from '@/interfaces';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
|
||||
@Service()
|
||||
export default class CommandCashflowTransaction {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from './constants';
|
||||
|
||||
/**
|
||||
* Ensures the given transaction type to transformed to properiate format.
|
||||
* Ensures the given transaction type to transformed to appropriate format.
|
||||
* @param {string} type
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
@@ -16,16 +16,16 @@ import BaseCreditNotes from './CreditNotes';
|
||||
@Service()
|
||||
export default class CreateCreditNote extends BaseCreditNotes {
|
||||
@Inject()
|
||||
uow: UnitOfWork;
|
||||
private uow: UnitOfWork;
|
||||
|
||||
@Inject()
|
||||
itemsEntriesService: ItemsEntriesService;
|
||||
private itemsEntriesService: ItemsEntriesService;
|
||||
|
||||
@Inject()
|
||||
tenancy: HasTenancyService;
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
eventPublisher: EventPublisher;
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Creates a new credit note.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
IApplyCreditToInvoicesCreatedPayload,
|
||||
@@ -10,15 +9,12 @@ import CreditNoteApplySyncInvoicesCreditedAmount from './CreditNoteApplySyncInvo
|
||||
@Service()
|
||||
export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber {
|
||||
@Inject()
|
||||
tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount;
|
||||
private syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount;
|
||||
|
||||
/**
|
||||
* Attaches events with handlers.
|
||||
*/
|
||||
attach(bus) {
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onApplyToInvoicesCreated,
|
||||
this.incrementAppliedInvoicesOnceCreditCreated
|
||||
|
||||
@@ -15,7 +15,7 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
/**
|
||||
* Attaches events with publisher.
|
||||
*/
|
||||
attach(bus) {
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.creditNote.onCreated,
|
||||
this.writeInventoryTranscationsOnceCreated
|
||||
@@ -37,6 +37,7 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
/**
|
||||
* Writes inventory transactions once credit note created.
|
||||
* @param {ICreditNoteCreatedPayload} payload -
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public writeInventoryTranscationsOnceCreated = async ({
|
||||
tenantId,
|
||||
@@ -44,9 +45,8 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
trx,
|
||||
}: ICreditNoteCreatedPayload) => {
|
||||
// Can't continue if the credit note is open yet.
|
||||
if (!creditNote.isOpen) {
|
||||
return;
|
||||
}
|
||||
if (!creditNote.isOpen) return;
|
||||
|
||||
await this.inventoryTransactions.createInventoryTransactions(
|
||||
tenantId,
|
||||
creditNote,
|
||||
@@ -57,6 +57,7 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
/**
|
||||
* Rewrites inventory transactions once credit note edited.
|
||||
* @param {ICreditNoteEditedPayload} payload -
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public rewriteInventoryTransactionsOnceEdited = async ({
|
||||
tenantId,
|
||||
@@ -65,9 +66,8 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
trx,
|
||||
}: ICreditNoteEditedPayload) => {
|
||||
// Can't continue if the credit note is open yet.
|
||||
if (!creditNote.isOpen) {
|
||||
return;
|
||||
}
|
||||
if (!creditNote.isOpen) return;
|
||||
|
||||
await this.inventoryTransactions.editInventoryTransactions(
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
@@ -87,9 +87,8 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
||||
trx,
|
||||
}: ICreditNoteDeletedPayload) => {
|
||||
// Can't continue if the credit note is open yet.
|
||||
if (!oldCreditNote.isOpen) {
|
||||
return;
|
||||
}
|
||||
if (!oldCreditNote.isOpen) return;
|
||||
|
||||
await this.inventoryTransactions.deleteInventoryTransactions(
|
||||
tenantId,
|
||||
creditNoteId,
|
||||
|
||||
@@ -49,7 +49,7 @@ export default class CreditNoteInventoryTransactions {
|
||||
};
|
||||
|
||||
/**
|
||||
* Edits vendor credit assocaited inventory transactions.
|
||||
* Edits vendor credit associated inventory transactions.
|
||||
* @param {number} tenantId
|
||||
* @param {number} creditNoteId
|
||||
* @param {ICreditNote} creditNote
|
||||
|
||||
@@ -29,7 +29,7 @@ export default class DeleteCustomerLinkedCreditSubscriber {
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate vendor has no assocaited credit transaction once the vendor deleting.
|
||||
* Validate vendor has no associated credit transaction once the vendor deleting.
|
||||
* @param {IVendorEventDeletingPayload} payload -
|
||||
*/
|
||||
public validateCustomerHasNoLinkedCreditsOnDeleting = async ({
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
|
||||
export default class DynamicListAbstract {
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
|
||||
|
||||
export default class DynamicListAbstruct {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
||||
import DynamicListAbstract from './DynamicListAbstract';
|
||||
import DynamicFilterViews from '@/lib/DynamicFilter/DynamicFilterViews';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
@@ -7,7 +7,7 @@ import { ERRORS } from './constants';
|
||||
import { IModel } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export default class DynamicListCustomView extends DynamicListAbstruct {
|
||||
export default class DynamicListCustomView extends DynamicListAbstract {
|
||||
@Inject()
|
||||
tenancy: HasTenancyService;
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ import { Service } from 'typedi';
|
||||
import * as R from 'ramda';
|
||||
import validator from 'is-my-json-valid';
|
||||
import { IFilterRole, IModel } from '@/interfaces';
|
||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
||||
import DynamicListAbstract from './DynamicListAbstract';
|
||||
import DynamicFilterAdvancedFilter from '@/lib/DynamicFilter/DynamicFilterAdvancedFilter';
|
||||
import { ERRORS } from './constants';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
|
||||
@Service()
|
||||
export default class DynamicListFilterRoles extends DynamicListAbstruct {
|
||||
export default class DynamicListFilterRoles extends DynamicListAbstract {
|
||||
/**
|
||||
* Validates filter roles schema.
|
||||
* @param {IFilterRole[]} filterRoles - Filter roles.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Service } from 'typedi';
|
||||
import { IFilterRole, IModel } from '@/interfaces';
|
||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
||||
import DynamicListAbstract from './DynamicListAbstract';
|
||||
import DynamicFilterFilterRoles from '@/lib/DynamicFilter/DynamicFilterFilterRoles';
|
||||
import DynamicFilterSearch from '@/lib/DynamicFilter/DynamicFilterSearch';
|
||||
|
||||
@Service()
|
||||
export default class DynamicListSearch extends DynamicListAbstruct {
|
||||
export default class DynamicListSearch extends DynamicListAbstract {
|
||||
/**
|
||||
* Dynamic list filter roles.
|
||||
* @param {IModel} model
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Service } from 'typedi';
|
||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
||||
import DynamicListAbstract from './DynamicListAbstract';
|
||||
import DynamicFilterSortBy from '@/lib/DynamicFilter/DynamicFilterSortBy';
|
||||
import { IModel, ISortOrder } from '@/interfaces';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { ERRORS } from './constants';
|
||||
|
||||
@Service()
|
||||
export default class DynamicListSortBy extends DynamicListAbstruct {
|
||||
export default class DynamicListSortBy extends DynamicListAbstract {
|
||||
/**
|
||||
* Dynamic list sort by.
|
||||
* @param {IModel} model
|
||||
|
||||
@@ -21,7 +21,7 @@ export class ExpensesWriteGLSubscriber {
|
||||
* Attaches events with handlers.
|
||||
* @param bus
|
||||
*/
|
||||
attach(bus) {
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.expenses.onCreated,
|
||||
this.handleWriteGLEntriesOnceCreated
|
||||
|
||||
@@ -34,7 +34,7 @@ export class FeaturesManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Detarmines the given feature name is accessiable.
|
||||
* Detarmines the given feature name is accessible.
|
||||
* @param {number} tenantId
|
||||
* @param {string} feature
|
||||
* @returns {Promise<void>}
|
||||
|
||||
@@ -33,7 +33,7 @@ export class FeaturesSettingsDriver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Detarmines the given feature name is accessiable.
|
||||
* Detarmines the given feature name is accessible.
|
||||
* @param {number} tenantId
|
||||
* @param {string} feature
|
||||
* @returns {Promise<boolean|null|undefined>}
|
||||
|
||||
@@ -5,6 +5,7 @@ import TenancyService from '@/services/Tenancy/TenancyService';
|
||||
import APAgingSummarySheet from './APAgingSummarySheet';
|
||||
import { Tenant } from '@/system/models';
|
||||
import { isEmpty } from 'lodash';
|
||||
import APAgingSummaryTable from './APAgingSummaryTable';
|
||||
|
||||
@Service()
|
||||
export default class PayableAgingSummaryService {
|
||||
@@ -84,7 +85,7 @@ export default class PayableAgingSummaryService {
|
||||
|
||||
// Common query.
|
||||
const commonQuery = (query) => {
|
||||
if (isEmpty(filter.branchesIds)) {
|
||||
if (!isEmpty(filter.branchesIds)) {
|
||||
query.modify('filterByBranches', filter.branchesIds);
|
||||
}
|
||||
};
|
||||
@@ -118,4 +119,21 @@ export default class PayableAgingSummaryService {
|
||||
meta: this.reportMetadata(tenantId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves A/P aging summary in table format.
|
||||
* @param {number} tenantId
|
||||
* @param {IAPAgingSummaryQuery} query
|
||||
*/
|
||||
async APAgingSummaryTable(tenantId: number, query: IAPAgingSummaryQuery) {
|
||||
const report = await this.APAgingSummary(tenantId, query);
|
||||
const table = new APAgingSummaryTable(report.data, query, {});
|
||||
|
||||
return {
|
||||
columns: table.tableColumns(),
|
||||
rows: table.tableRows(),
|
||||
meta: report.meta,
|
||||
query: report.query,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export default class APAgingSummarySheet extends AgingSummaryReport {
|
||||
|
||||
return {
|
||||
vendorName: vendor.displayName,
|
||||
current: this.formatTotalAmount(currentTotal),
|
||||
current: this.formatAmount(currentTotal),
|
||||
aging: agingPeriods,
|
||||
total: this.formatTotalAmount(amount),
|
||||
};
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import {
|
||||
IAPAgingSummaryData,
|
||||
IAgingSummaryQuery,
|
||||
ITableColumn,
|
||||
ITableColumnAccessor,
|
||||
ITableRow,
|
||||
} from '@/interfaces';
|
||||
import AgingSummaryTable from './AgingSummaryTable';
|
||||
|
||||
export default class APAgingSummaryTable extends AgingSummaryTable {
|
||||
readonly report: IAPAgingSummaryData;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {IARAgingSummaryData} data
|
||||
* @param {IAgingSummaryQuery} query
|
||||
* @param {any} i18n
|
||||
*/
|
||||
constructor(data: IAPAgingSummaryData, query: IAgingSummaryQuery, i18n: any) {
|
||||
super(data, query, i18n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the contacts table rows.
|
||||
* @returns {ITableRow[]}
|
||||
*/
|
||||
get contactsRows(): ITableRow[] {
|
||||
return this.contactsNodes(this.report.vendors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contact name node accessor.
|
||||
* @returns {ITableColumnAccessor}
|
||||
*/
|
||||
get contactNameNodeAccessor(): ITableColumnAccessor {
|
||||
return { key: 'vendor_name', accessor: 'vendorName' };
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the contact name table column.
|
||||
* @returns {ITableColumn}
|
||||
*/
|
||||
contactNameTableColumn = (): ITableColumn => {
|
||||
return { label: 'Vendor name', key: 'vendor_name' };
|
||||
};
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { IARAgingSummaryQuery, IARAgingSummaryMeta } from '@/interfaces';
|
||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||
import ARAgingSummarySheet from './ARAgingSummarySheet';
|
||||
import { Tenant } from '@/system/models';
|
||||
import ARAgingSummaryTable from './ARAgingSummaryTable';
|
||||
|
||||
@Service()
|
||||
export default class ARAgingSummaryService {
|
||||
@@ -89,12 +90,12 @@ export default class ARAgingSummaryService {
|
||||
};
|
||||
// Retrieve all overdue sale invoices.
|
||||
const overdueSaleInvoices = await SaleInvoice.query()
|
||||
.modify('dueInvoicesFromDate', filter.asDate)
|
||||
.modify('overdueInvoicesFromDate', filter.asDate)
|
||||
.onBuild(commonQuery);
|
||||
|
||||
// Retrieve all due sale invoices.
|
||||
const currentInvoices = await SaleInvoice.query()
|
||||
.modify('overdueInvoicesFromDate', filter.asDate)
|
||||
.modify('dueInvoicesFromDate', filter.asDate)
|
||||
.onBuild(commonQuery);
|
||||
|
||||
// AR aging summary report instance.
|
||||
@@ -117,4 +118,21 @@ export default class ARAgingSummaryService {
|
||||
meta: this.reportMetadata(tenantId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves A/R aging summary in table format.
|
||||
* @param {number} tenantId
|
||||
* @param {IARAgingSummaryQuery} query
|
||||
*/
|
||||
async ARAgingSummaryTable(tenantId: number, query: IARAgingSummaryQuery) {
|
||||
const report = await this.ARAgingSummary(tenantId, query);
|
||||
const table = new ARAgingSummaryTable(report.data, query, {});
|
||||
|
||||
return {
|
||||
columns: table.tableColumns(),
|
||||
rows: table.tableRows(),
|
||||
meta: report.meta,
|
||||
query,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { groupBy, isEmpty, sum } from 'lodash';
|
||||
import { Dictionary, groupBy, isEmpty, sum } from 'lodash';
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
ICustomer,
|
||||
@@ -54,7 +54,6 @@ export default class ARAgingSummarySheet extends AgingSummaryReport {
|
||||
currentSaleInvoices,
|
||||
'customerId'
|
||||
);
|
||||
|
||||
// Initializes the aging periods.
|
||||
this.agingPeriods = this.agingRangePeriods(
|
||||
this.query.asDate,
|
||||
@@ -189,7 +188,7 @@ export default class ARAgingSummarySheet extends AgingSummaryReport {
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve AR aging summary report columns.
|
||||
* Retrieve A/R aging summary report columns.
|
||||
* @return {IARAgingSummaryColumns}
|
||||
*/
|
||||
public reportColumns(): IARAgingSummaryColumns {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
IARAgingSummaryData,
|
||||
IAgingSummaryData,
|
||||
IAgingSummaryQuery,
|
||||
ITableColumnAccessor,
|
||||
ITableRow,
|
||||
} from '@/interfaces';
|
||||
import AgingSummaryTable from './AgingSummaryTable';
|
||||
|
||||
export default class ARAgingSummaryTable extends AgingSummaryTable {
|
||||
readonly report: IARAgingSummaryData;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {IARAgingSummaryData} data
|
||||
* @param {IAgingSummaryQuery} query
|
||||
* @param {any} i18n
|
||||
*/
|
||||
constructor(data: IARAgingSummaryData, query: IAgingSummaryQuery, i18n: any) {
|
||||
super(data, query, i18n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the contacts table rows.
|
||||
* @returns {ITableRow[]}
|
||||
*/
|
||||
get contactsRows(): ITableRow[] {
|
||||
return this.contactsNodes(this.report.customers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contact name node accessor.
|
||||
* @returns {ITableColumnAccessor}
|
||||
*/
|
||||
get contactNameNodeAccessor(): ITableColumnAccessor {
|
||||
return { key: 'customer_name', accessor: 'customerName' };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
import * as R from 'ramda';
|
||||
import {
|
||||
IAgingPeriod,
|
||||
IAgingSummaryContact,
|
||||
IAgingSummaryData,
|
||||
IAgingSummaryQuery,
|
||||
IAgingSummaryTotal,
|
||||
ITableColumn,
|
||||
ITableColumnAccessor,
|
||||
ITableRow,
|
||||
} from '@/interfaces';
|
||||
import { tableRowMapper } from '@/utils';
|
||||
import AgingReport from './AgingReport';
|
||||
import { AgingSummaryRowType } from './_constants';
|
||||
import { FinancialTable } from '../FinancialTable';
|
||||
import { FinancialSheetStructure } from '../FinancialSheetStructure';
|
||||
|
||||
export default abstract class AgingSummaryTable extends R.compose(
|
||||
FinancialSheetStructure,
|
||||
FinancialTable
|
||||
)(AgingReport) {
|
||||
protected readonly report: IAgingSummaryData;
|
||||
protected readonly query: IAgingSummaryQuery;
|
||||
protected readonly agingPeriods: IAgingPeriod[];
|
||||
protected readonly i18n: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {IARAgingSummaryData} data
|
||||
* @param {IAgingSummaryQuery} query
|
||||
* @param {any} i18n
|
||||
*/
|
||||
constructor(data: IAgingSummaryData, query: IAgingSummaryQuery, i18n: any) {
|
||||
super();
|
||||
|
||||
this.report = data;
|
||||
this.i18n = i18n;
|
||||
this.query = query;
|
||||
|
||||
this.agingPeriods = this.agingRangePeriods(
|
||||
this.query.asDate,
|
||||
this.query.agingDaysBefore,
|
||||
this.query.agingPeriods
|
||||
);
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// # Accessors.
|
||||
// -------------------------
|
||||
/**
|
||||
* Aging accessors of contact and total nodes.
|
||||
* @param {IAgingSummaryContact | IAgingSummaryTotal} node
|
||||
* @returns {ITableColumnAccessor[]}
|
||||
*/
|
||||
protected agingNodeAccessors = (
|
||||
node: IAgingSummaryContact | IAgingSummaryTotal
|
||||
): ITableColumnAccessor[] => {
|
||||
return node.aging.map((aging, index) => ({
|
||||
key: 'aging',
|
||||
accessor: `aging[${index}].total.formattedAmount`,
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Contact name node accessor.
|
||||
* @returns {ITableColumnAccessor}
|
||||
*/
|
||||
protected get contactNameNodeAccessor(): ITableColumnAccessor {
|
||||
return { key: 'customer_name', accessor: 'customerName' };
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the common columns for all report nodes.
|
||||
* @param {IAgingSummaryContact}
|
||||
* @returns {ITableColumnAccessor[]}
|
||||
*/
|
||||
protected contactNodeAccessors = (
|
||||
node: IAgingSummaryContact
|
||||
): ITableColumnAccessor[] => {
|
||||
return R.compose(
|
||||
R.concat([
|
||||
this.contactNameNodeAccessor,
|
||||
{ key: 'current', accessor: 'current.formattedAmount' },
|
||||
...this.agingNodeAccessors(node),
|
||||
{ key: 'total', accessor: 'total.formattedAmount' },
|
||||
])
|
||||
)([]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the contact name table row.
|
||||
* @param {IAgingSummaryContact} node -
|
||||
* @return {ITableRow}
|
||||
*/
|
||||
protected contactNameNode = (node: IAgingSummaryContact): ITableRow => {
|
||||
const columns = this.contactNodeAccessors(node);
|
||||
const meta = {
|
||||
rowTypes: [AgingSummaryRowType.Contact],
|
||||
};
|
||||
return tableRowMapper(node, columns, meta);
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps the customers nodes to table rows.
|
||||
* @param {IAgingSummaryContact[]} nodes
|
||||
* @returns {ITableRow[]}
|
||||
*/
|
||||
protected contactsNodes = (nodes: IAgingSummaryContact[]): ITableRow[] => {
|
||||
return nodes.map(this.contactNameNode);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the common columns for all report nodes.
|
||||
* @param {IAgingSummaryTotal}
|
||||
* @returns {ITableColumnAccessor[]}
|
||||
*/
|
||||
protected totalNodeAccessors = (
|
||||
node: IAgingSummaryTotal
|
||||
): ITableColumnAccessor[] => {
|
||||
return R.compose(
|
||||
R.concat([
|
||||
{ key: 'blank', value: '' },
|
||||
{ key: 'current', accessor: 'current.formattedAmount' },
|
||||
...this.agingNodeAccessors(node),
|
||||
{ key: 'total', accessor: 'total.formattedAmount' },
|
||||
])
|
||||
)([]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the total row of the given report total node.
|
||||
* @param {IAgingSummaryTotal} node
|
||||
* @returns {ITableRow}
|
||||
*/
|
||||
protected totalNode = (node: IAgingSummaryTotal): ITableRow => {
|
||||
const columns = this.totalNodeAccessors(node);
|
||||
const meta = {
|
||||
rowTypes: [AgingSummaryRowType.Total],
|
||||
};
|
||||
return tableRowMapper(node, columns, meta);
|
||||
};
|
||||
|
||||
// -------------------------
|
||||
// # Computed Rows.
|
||||
// -------------------------
|
||||
/**
|
||||
* Retrieves the contacts table rows.
|
||||
* @returns {ITableRow[]}
|
||||
*/
|
||||
protected get contactsRows(): ITableRow[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Table total row.
|
||||
* @returns {ITableRow}
|
||||
*/
|
||||
protected get totalRow(): ITableRow {
|
||||
return this.totalNode(this.report.total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the table rows.
|
||||
* @returns {ITableRow[]}
|
||||
*/
|
||||
public tableRows = (): ITableRow[] => {
|
||||
return R.compose(
|
||||
R.unless(R.isEmpty, R.append(this.totalRow)),
|
||||
R.concat(this.contactsRows)
|
||||
)([]);
|
||||
};
|
||||
|
||||
// -------------------------
|
||||
// # Columns.
|
||||
// -------------------------
|
||||
/**
|
||||
* Retrieves the aging table columns.
|
||||
* @returns {ITableColumn[]}
|
||||
*/
|
||||
protected agingTableColumns = (): ITableColumn[] => {
|
||||
return this.agingPeriods.map((agingPeriod) => {
|
||||
return {
|
||||
label: `${agingPeriod.beforeDays} - ${
|
||||
agingPeriod.toDays || 'And Over'
|
||||
}`,
|
||||
key: 'aging_period',
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the contact name table column.
|
||||
* @returns {ITableColumn}
|
||||
*/
|
||||
protected contactNameTableColumn = (): ITableColumn => {
|
||||
return { label: 'Customer name', key: 'customer_name' };
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the report columns.
|
||||
* @returns {ITableColumn}
|
||||
*/
|
||||
public tableColumns = (): ITableColumn[] => {
|
||||
return R.compose(this.tableColumnsCellIndexing)([
|
||||
this.contactNameTableColumn(),
|
||||
{ label: 'Current', key: 'current' },
|
||||
...this.agingTableColumns(),
|
||||
{ label: 'Total', key: 'total' },
|
||||
]);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export enum AgingSummaryRowType {
|
||||
Contact = 'contact',
|
||||
Total = 'total',
|
||||
}
|
||||
@@ -37,7 +37,7 @@ export default class BalanceSheetStatementService
|
||||
displayColumnsBy: 'month',
|
||||
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
|
||||
@@ -197,7 +197,7 @@ export default class CashFlowStatement extends compose(
|
||||
code: account.code,
|
||||
label: account.name,
|
||||
accountType: account.accountType,
|
||||
adjusmentType: relation.direction,
|
||||
adjustmentType: relation.direction,
|
||||
total: this.getAmountMeta(closingBalance),
|
||||
sectionType: ICashFlowStatementSectionType.ACCOUNT,
|
||||
};
|
||||
@@ -362,14 +362,14 @@ export default class CashFlowStatement extends compose(
|
||||
/**
|
||||
* Retrieve the total section from the eqauation parser.
|
||||
* @param {ICashFlowSchemaTotalSection} sectionSchema
|
||||
* @param {ICashFlowSchemaSection[]} accumlatedSections
|
||||
* @param {ICashFlowSchemaSection[]} accumulatedSections
|
||||
* @returns {ICashFlowStatementTotalSection}
|
||||
*/
|
||||
private totalEquationSectionParser = (
|
||||
accumlatedSections: ICashFlowSchemaSection[],
|
||||
accumulatedSections: ICashFlowSchemaSection[],
|
||||
sectionSchema: ICashFlowSchemaTotalSection
|
||||
): ICashFlowStatementTotalSection => {
|
||||
const mappedSectionsById = this.transformSectionsToMap(accumlatedSections);
|
||||
const mappedSectionsById = this.transformSectionsToMap(accumulatedSections);
|
||||
const nodesTotalById = this.sectionsMapToTotal(mappedSectionsById);
|
||||
|
||||
const total = this.evaluateEquation(sectionSchema.equation, nodesTotalById);
|
||||
@@ -421,7 +421,7 @@ export default class CashFlowStatement extends compose(
|
||||
code: account.code,
|
||||
label: account.name,
|
||||
accountType: account.accountType,
|
||||
adjusmentType: relation.direction,
|
||||
adjustmentType: relation.direction,
|
||||
total: this.getAmountMeta(closingBalance),
|
||||
sectionType: ICashFlowStatementSectionType.ACCOUNT,
|
||||
};
|
||||
@@ -524,7 +524,7 @@ export default class CashFlowStatement extends compose(
|
||||
* @param {ICashFlowSchemaSection | ICashFlowStatementSection} section
|
||||
* @param {number} key
|
||||
* @param {ICashFlowSchemaSection[]} parentValue
|
||||
* @param {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} accumlatedSections
|
||||
* @param {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} accumulatedSections
|
||||
* @returns {ICashFlowSchemaSection}
|
||||
*/
|
||||
private schemaSectionTotalParser = (
|
||||
@@ -532,13 +532,13 @@ export default class CashFlowStatement extends compose(
|
||||
key: number,
|
||||
parentValue: ICashFlowSchemaSection[],
|
||||
context,
|
||||
accumlatedSections: (ICashFlowSchemaSection | ICashFlowStatementSection)[]
|
||||
accumulatedSections: (ICashFlowSchemaSection | ICashFlowStatementSection)[]
|
||||
): ICashFlowSchemaSection | ICashFlowStatementSection => {
|
||||
return R.compose(
|
||||
// Total equation section.
|
||||
R.when(
|
||||
this.isSchemaSectionType(ICashFlowStatementSectionType.TOTAL),
|
||||
R.curry(this.totalEquationSectionParser)(accumlatedSections)
|
||||
R.curry(this.totalEquationSectionParser)(accumulatedSections)
|
||||
)
|
||||
)(section);
|
||||
};
|
||||
|
||||
@@ -165,7 +165,7 @@ export const CashFlowStatementDatePeriods = (Base) =>
|
||||
.whereAccountId(node.id)
|
||||
.getClosingBalance();
|
||||
|
||||
return this.amountAdjustment(node.adjusmentType, closingBalance);
|
||||
return this.amountAdjustment(node.adjustmentType, closingBalance);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -322,7 +322,7 @@ export const CashFlowStatementDatePeriods = (Base) =>
|
||||
// Cash at beginning ----------------------
|
||||
|
||||
/**
|
||||
* Retrieve the date preioods of the given node and accumlated function.
|
||||
* Retrieve the date preioods of the given node and accumulated function.
|
||||
* @param {} node
|
||||
* @param {}
|
||||
* @return {}
|
||||
|
||||
@@ -40,7 +40,7 @@ export default class CashFlowStatementService
|
||||
displayColumnsType: 'total',
|
||||
displayColumnsBy: 'day',
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
divideOn1000: false,
|
||||
|
||||
@@ -41,7 +41,7 @@ export default class CashflowAccountTransactionsService extends FinancialSheet {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the cashflow accouynt transactions report data.
|
||||
* Retrieve the cashflow account transactions report data.
|
||||
* @param {number} tenantId -
|
||||
* @param {ICashflowAccountTransactionsQuery} query -
|
||||
* @return {Promise<IInvetoryItemDetailDOO>}
|
||||
|
||||
@@ -64,7 +64,7 @@ export const FinancialDatePeriods = (Base) =>
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the date preioods of the given node and accumlated function.
|
||||
* Retrieve the date preioods of the given node and accumulated function.
|
||||
* @param {IBalanceSheetAccountNode} node
|
||||
* @param {(fromDate: Date, toDate: Date, index: number) => any}
|
||||
* @return {}
|
||||
|
||||
@@ -12,7 +12,7 @@ export const FinancialTable = (Base) =>
|
||||
* @param {ITableColumn[]} columns
|
||||
* @returns {ITableColumn[]}
|
||||
*/
|
||||
protected tableColumnsCellIndexing = (
|
||||
public tableColumnsCellIndexing = (
|
||||
columns: ITableColumn[]
|
||||
): ITableColumn[] => {
|
||||
const cellIndex = increment(-1);
|
||||
|
||||
@@ -31,8 +31,8 @@ export default class GeneralLedgerService {
|
||||
*/
|
||||
get defaultQuery() {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
basis: 'cash',
|
||||
numberFormat: {
|
||||
noCents: false,
|
||||
|
||||
@@ -126,7 +126,7 @@ export default class InventoryDetails extends FinancialSheet {
|
||||
);
|
||||
|
||||
/**
|
||||
* Accumlate and mapping running quantity on transactions.
|
||||
* Accumulate and mapping running quantity on transactions.
|
||||
* @param {IInventoryDetailsItemTransaction[]} transactions
|
||||
* @returns {IInventoryDetailsItemTransaction[]}
|
||||
*/
|
||||
@@ -150,7 +150,7 @@ export default class InventoryDetails extends FinancialSheet {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumlate and mapping running valuation on transactions.
|
||||
* Accumulate and mapping running valuation on transactions.
|
||||
* @param {IInventoryDetailsItemTransaction[]} transactions
|
||||
* @returns {IInventoryDetailsItemTransaction}
|
||||
*/
|
||||
@@ -160,8 +160,8 @@ export default class InventoryDetails extends FinancialSheet {
|
||||
const initial = this.getNumberMeta(0);
|
||||
|
||||
const mapAccumAppender = (a, b) => {
|
||||
const adjusmtent = b.direction === 'OUT' ? -1 : 1;
|
||||
const total = a.runningValuation.number + b.cost.number * adjusmtent;
|
||||
const adjustment = b.direction === 'OUT' ? -1 : 1;
|
||||
const total = a.runningValuation.number + b.cost.number * adjustment;
|
||||
const totalMeta = this.getNumberMeta(total, { excerptZero: false });
|
||||
const accum = { ...b, runningValuation: totalMeta };
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ import { Tenant } from '@/system/models';
|
||||
@Service()
|
||||
export default class InventoryDetailsService extends FinancialSheet {
|
||||
@Inject()
|
||||
tenancy: TenancyService;
|
||||
private tenancy: TenancyService;
|
||||
|
||||
@Inject()
|
||||
reportRepo: InventoryDetailsRepository;
|
||||
private reportRepo: InventoryDetailsRepository;
|
||||
|
||||
@Inject()
|
||||
inventoryService: InventoryService;
|
||||
private inventoryService: InventoryService;
|
||||
|
||||
/**
|
||||
* Defaults balance sheet filter query.
|
||||
@@ -30,8 +30,8 @@ export default class InventoryDetailsService extends FinancialSheet {
|
||||
*/
|
||||
private get defaultQuery(): IInventoryDetailsQuery {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
itemsIds: [],
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
|
||||
@@ -27,7 +27,7 @@ export default class InventoryValuationSheetService {
|
||||
*/
|
||||
get defaultQuery(): IInventoryValuationReportQuery {
|
||||
return {
|
||||
asDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
asDate: moment().format('YYYY-MM-DD'),
|
||||
itemsIds: [],
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
|
||||
@@ -25,8 +25,8 @@ export default class JournalSheetService {
|
||||
*/
|
||||
get defaultQuery() {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
fromRange: null,
|
||||
toRange: null,
|
||||
accountsIds: [],
|
||||
|
||||
@@ -8,7 +8,7 @@ import { IProfitLossSheetQuery } from '@/interfaces';
|
||||
*/
|
||||
export const getDefaultPLQuery = (): IProfitLossSheetQuery => ({
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
|
||||
numberFormat: {
|
||||
divideOn1000: false,
|
||||
|
||||
@@ -129,9 +129,9 @@ export class ProjectProfitabilitySummaryRespository {
|
||||
*/
|
||||
public getIncomeAccountsGroupedEntries = async () => {
|
||||
const incomeAccounts = await this.getIncomeAccounts();
|
||||
const incomeAcountssIds = map(incomeAccounts, 'id');
|
||||
const incomeAccountsIds = map(incomeAccounts, 'id');
|
||||
|
||||
return this.getAccountsGroupedEntries(incomeAcountssIds);
|
||||
return this.getAccountsGroupedEntries(incomeAccountsIds);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,10 +12,7 @@ import { Tenant } from '@/system/models';
|
||||
@Service()
|
||||
export default class InventoryValuationReportService {
|
||||
@Inject()
|
||||
tenancy: TenancyService;
|
||||
|
||||
@Inject('logger')
|
||||
logger: any;
|
||||
private tenancy: TenancyService;
|
||||
|
||||
/**
|
||||
* Defaults balance sheet filter query.
|
||||
@@ -23,8 +20,8 @@ export default class InventoryValuationReportService {
|
||||
*/
|
||||
get defaultQuery(): IInventoryValuationReportQuery {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
itemsIds: [],
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
@@ -73,9 +70,9 @@ export default class InventoryValuationReportService {
|
||||
tenantId: number,
|
||||
query: IInventoryValuationReportQuery
|
||||
): Promise<{
|
||||
data: IInventoryValuationStatement,
|
||||
query: IInventoryValuationReportQuery,
|
||||
meta: IInventoryValuationSheetMeta,
|
||||
data: IInventoryValuationStatement;
|
||||
query: IInventoryValuationReportQuery;
|
||||
meta: IInventoryValuationSheetMeta;
|
||||
}> {
|
||||
const { Item, InventoryTransaction } = this.tenancy.models(tenantId);
|
||||
|
||||
@@ -87,7 +84,7 @@ export default class InventoryValuationReportService {
|
||||
...this.defaultQuery,
|
||||
...query,
|
||||
};
|
||||
const inventoryItems = await Item.query().onBuild(q => {
|
||||
const inventoryItems = await Item.query().onBuild((q) => {
|
||||
q.where('type', 'inventory');
|
||||
|
||||
if (filter.itemsIds.length > 0) {
|
||||
@@ -106,7 +103,7 @@ export default class InventoryValuationReportService {
|
||||
builder.whereIn('itemId', inventoryItemsIds);
|
||||
|
||||
// Filter the date range of the sheet.
|
||||
builder.modify('filterDateRange', filter.fromDate, filter.toDate)
|
||||
builder.modify('filterDateRange', filter.fromDate, filter.toDate);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ export default class SalesByItemsReportService {
|
||||
*/
|
||||
get defaultQuery(): ISalesByItemsReportQuery {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
itemsIds: [],
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
|
||||
@@ -31,8 +31,8 @@ export default class TransactionsByCustomersService
|
||||
*/
|
||||
get defaultQuery(): ITransactionsByCustomersFilter {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
divideOn1000: false,
|
||||
|
||||
@@ -32,7 +32,7 @@ export default class TransactionsByVendorsService
|
||||
*/
|
||||
get defaultQuery(): ITransactionsByVendorsFilter {
|
||||
return {
|
||||
fromDate: moment().format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
numberFormat: {
|
||||
precision: 2,
|
||||
|
||||
@@ -27,7 +27,7 @@ export default class TrialBalanceSheetService extends FinancialSheet {
|
||||
get defaultQuery(): ITrialBalanceSheetQuery {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
numberFormat: {
|
||||
divideOn1000: false,
|
||||
negativeFormat: 'mines',
|
||||
|
||||
@@ -95,7 +95,7 @@ export default class InventoryService {
|
||||
) {
|
||||
const { Item } = this.tenancy.models(tenantId);
|
||||
|
||||
// Fetches the item with assocaited item category.
|
||||
// Fetches the item with associated item category.
|
||||
const item = await Item.query().findById(itemId);
|
||||
|
||||
// Cannot continue if the given item was not inventory item.
|
||||
|
||||
@@ -180,7 +180,7 @@ export default class InventoryAdjustmentService {
|
||||
quickAdjustmentDTO,
|
||||
} as IInventoryAdjustmentCreatingPayload
|
||||
);
|
||||
// Saves the inventory adjustment with assocaited entries to the storage.
|
||||
// Saves the inventory adjustment with associated entries to the storage.
|
||||
const inventoryAdjustment = await InventoryAdjustment.query(
|
||||
trx
|
||||
).upsertGraph({
|
||||
|
||||
@@ -49,7 +49,7 @@ export default class InventoryAverageCostMethod
|
||||
public async computeItemCost() {
|
||||
const { InventoryTransaction } = this.tenantModels;
|
||||
const { averageCost, openingQuantity, openingCost } =
|
||||
await this.getOpeningAvaregeCost(this.startingDate, this.itemId);
|
||||
await this.getOpeningAverageCost(this.startingDate, this.itemId);
|
||||
|
||||
const afterInvTransactions: IInventoryTransaction[] =
|
||||
await InventoryTransaction.query()
|
||||
@@ -75,12 +75,12 @@ export default class InventoryAverageCostMethod
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items Avarege cost from specific date from inventory transactions.
|
||||
* Get items Average cost from specific date from inventory transactions.
|
||||
* @async
|
||||
* @param {Date} closingDate
|
||||
* @return {number}
|
||||
*/
|
||||
public async getOpeningAvaregeCost(closingDate: Date, itemId: number) {
|
||||
public async getOpeningAverageCost(closingDate: Date, itemId: number) {
|
||||
const { InventoryCostLotTracker } = this.tenantModels;
|
||||
|
||||
const commonBuilder = (builder: any) => {
|
||||
|
||||
@@ -79,7 +79,7 @@ export default class InventoryCostLotTracker extends InventoryCostMethod impleme
|
||||
|
||||
/**
|
||||
* Fetched inventory transactions that has date from the starting date and
|
||||
* fetches availiable IN LOTs transactions that has remaining bigger than zero.
|
||||
* fetches available IN LOTs transactions that has remaining bigger than zero.
|
||||
* @private
|
||||
*/
|
||||
private async fetchInvINTransactions() {
|
||||
@@ -97,7 +97,7 @@ export default class InventoryCostLotTracker extends InventoryCostMethod impleme
|
||||
.orderBy('lot_number', (this.costMethod === 'LIFO') ? 'DESC' : 'ASC')
|
||||
.withGraphFetched('item');
|
||||
|
||||
const availiableINLots: IInventoryLotCost[] =
|
||||
const availableINLots: IInventoryLotCost[] =
|
||||
await InventoryLotCostTracker.query()
|
||||
.modify('filterDateRange', null, this.startingDate)
|
||||
.orderBy('date', 'ASC')
|
||||
@@ -107,7 +107,7 @@ export default class InventoryCostLotTracker extends InventoryCostMethod impleme
|
||||
.whereNot('remaining', 0);
|
||||
|
||||
this.inTransactions = [
|
||||
...availiableINLots.map((trans) => ({ lotTransId: trans.id, ...trans })),
|
||||
...availableINLots.map((trans) => ({ lotTransId: trans.id, ...trans })),
|
||||
...afterInvTransactions.map((trans) => ({ invTransId: trans.id, ...trans })),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ export default class ItemCategoriesService implements IItemCategoriesService {
|
||||
);
|
||||
// Items categories.
|
||||
const itemCategories = await ItemCategory.query().onBuild((query) => {
|
||||
// Subquery to calculate sumation of assocaited items to the item category.
|
||||
// Subquery to calculate sumation of associated items to the item category.
|
||||
query.select('*', ItemCategory.relatedQuery('items').count().as('count'));
|
||||
|
||||
dynamicList.buildQuery()(query);
|
||||
|
||||
@@ -9,13 +9,9 @@ import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import UnitOfWork from '@/services/UnitOfWork';
|
||||
import events from '@/subscribers/events';
|
||||
import { ERRORS } from './constants';
|
||||
import { ItemsValidators } from './ItemValidators';
|
||||
|
||||
@Service()
|
||||
export class DeleteItem {
|
||||
@Inject()
|
||||
private validators: ItemsValidators;
|
||||
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ export class ItemsValidators {
|
||||
|
||||
/**
|
||||
* Validate the item inventory account whether modified and item
|
||||
* has assocaited inventory transactions.
|
||||
* has associated inventory transactions.
|
||||
* @param {numnber} tenantId
|
||||
* @param {IItem} oldItem
|
||||
* @param {IItemDTO} newItemDTO
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user