Compare commits

..

1 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
27fee87106 dix(webapp): create quick customer/vendor 2023-08-14 16:28:56 +02:00
226 changed files with 1271 additions and 1856 deletions

View File

@@ -51,15 +51,6 @@
"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,

View File

@@ -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, accountant and items preferences.
- fix: general, accoutant 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.

View File

@@ -7,7 +7,6 @@ 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)
@@ -32,18 +31,9 @@ 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.
```

View File

@@ -73,7 +73,6 @@ 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>

View File

@@ -152,7 +152,7 @@
"Opening Balance Liabilities": "رصيد الالتزامات الافتتاحي",
"Loan": "اقراض",
"Owner A Drawings": "مسحوبات المالك",
"An account that holds valuation of products or goods that available for sale.": "حساب يحمل قيم مخزون البضاعة أو السلع المتاحة للبيع.",
"An account that holds valuation of products or goods that availiable 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.": "لا ترتبط انشطة الدخل إلى الأعمال الأساسية.",

View File

@@ -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 available 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 availiable for sale.": "An account that holds valuation of products or goods that availiable 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.",

View File

@@ -33,13 +33,10 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC
return [
...this.sheetNumberFormatValidationSchema,
query('as_date').optional().isISO8601(),
query('aging_days_before').default(30).isInt({ max: 500 }).toInt(),
query('aging_periods').default(3).isInt({ max: 12 }).toInt(),
query('aging_days_before').optional().isNumeric().toInt(),
query('aging_periods').optional().isNumeric().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.
@@ -56,36 +53,15 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC
const filter = this.matchedQueryData(req);
try {
const accept = this.accepts(req);
const acceptType = accept.types(['json', 'application/json+table']);
const { data, columns, query, meta } =
await this.APAgingSummaryService.APAgingSummary(tenantId, filter);
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;
}
return res.status(200).send({
data: this.transfromToResponse(data),
columns: this.transfromToResponse(columns),
query: this.transfromToResponse(query),
meta: this.transfromToResponse(meta),
});
} catch (error) {
next(error);
}

View File

@@ -36,8 +36,8 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC
query('as_date').optional().isISO8601(),
query('aging_days_before').default(30).isInt({ max: 500 }).toInt(),
query('aging_periods').default(3).isInt({ max: 12 }).toInt(),
query('aging_days_before').optional().isInt({ max: 500 }).toInt(),
query('aging_periods').optional().isInt({ max: 12 }).toInt(),
query('customers_ids').optional().isArray({ min: 1 }),
query('customers_ids.*').isInt({ min: 1 }).toInt(),
@@ -58,36 +58,15 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC
const filter = this.matchedQueryData(req);
try {
const accept = this.accepts(req);
const acceptType = accept.types(['json', 'application/json+table']);
const { data, columns, query, meta } =
await this.ARAgingSummaryService.ARAgingSummary(tenantId, filter);
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;
}
return res.status(200).send({
data: this.transfromToResponse(data),
columns: this.transfromToResponse(columns),
query: this.transfromToResponse(query),
meta: this.transfromToResponse(meta),
});
} catch (error) {
console.log(error);
}

View File

@@ -387,7 +387,7 @@ export default class ManualJournalsController extends BaseController {
errors: [{ type: 'CREDIT.DEBIT.NOT.EQUALS', code: 300 }],
});
}
if (error.errorType === 'accounts_ids_not_found') {
if (error.errorType === 'acccounts_ids_not_found') {
return res.boom.badRequest(
'Journal entries some of accounts ids not exists.',
{ errors: [{ type: 'ACCOUNTS.IDS.NOT.FOUND', code: 400 }] }

View File

@@ -372,7 +372,7 @@ export default class PaymentReceivesController extends BaseController {
/**
* Retrieve the given payment receive details.
* @async
* @asycn
* @param {Request} req -
* @param {Response} res -
*/

View File

@@ -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 available for sale.',
description:'An account that holds valuation of products or goods that availiable for sale.',
},
// Libilities

View File

@@ -1,36 +1,51 @@
import {
IAgingPeriod,
IAgingPeriodTotal,
IAgingAmount,
IAgingSummaryQuery,
IAgingSummaryTotal,
IAgingSummaryContact,
IAgingSummaryData,
IAgingAmount
} from './AgingReport';
import { INumberFormatQuery } from './FinancialStatements';
import {
INumberFormatQuery
} from './FinancialStatements';
export interface IAPAgingSummaryQuery extends IAgingSummaryQuery {
export interface IAPAgingSummaryQuery {
asDate: Date | string;
agingDaysBefore: number;
agingPeriods: number;
numberFormat: INumberFormatQuery;
vendorsIds: number[];
noneZero: boolean;
branchesIds?: number[]
}
export interface IAPAgingSummaryVendor extends IAgingSummaryContact {
vendorName: string;
}
export interface IAPAgingSummaryVendor {
vendorName: string,
current: IAgingAmount,
aging: IAgingPeriodTotal[],
total: IAgingAmount,
};
export interface IAPAgingSummaryTotal extends IAgingSummaryTotal {}
export interface IAPAgingSummaryTotal {
current: IAgingAmount,
aging: IAgingPeriodTotal[],
total: IAgingAmount,
};
export interface IAPAgingSummaryData extends IAgingSummaryData {
vendors: IAPAgingSummaryVendor[];
}
export interface IAPAgingSummaryData {
vendors: IAPAgingSummaryVendor[],
total: IAPAgingSummaryTotal,
};
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,
}

View File

@@ -1,28 +1,37 @@
import {
IAgingPeriod,
IAgingSummaryQuery,
IAgingSummaryTotal,
IAgingSummaryContact,
IAgingSummaryData,
} from './AgingReport';
import { IAgingPeriod, IAgingPeriodTotal, IAgingAmount } from './AgingReport';
import { INumberFormatQuery } from './FinancialStatements';
export interface IARAgingSummaryQuery extends IAgingSummaryQuery {
export interface IARAgingSummaryQuery {
asDate: Date | string;
agingDaysBefore: number;
agingPeriods: number;
numberFormat: INumberFormatQuery;
customersIds: number[];
branchesIds: number[];
noneZero: boolean;
}
export interface IARAgingSummaryCustomer extends IAgingSummaryContact {
export interface IARAgingSummaryCustomer {
customerName: string;
current: IAgingAmount;
aging: IAgingPeriodTotal[];
total: IAgingAmount;
}
export interface IARAgingSummaryTotal extends IAgingSummaryTotal {}
export interface IARAgingSummaryTotal {
current: IAgingAmount;
aging: IAgingPeriodTotal[];
total: IAgingAmount;
}
export interface IARAgingSummaryData extends IAgingSummaryData {
export interface IARAgingSummaryData {
customers: IARAgingSummaryCustomer[];
total: IARAgingSummaryTotal;
}
export type IARAgingSummaryColumns = IAgingPeriod[];
export interface IARAgingSummaryMeta {
organizationName: string;
baseCurrency: string;
}
organizationName: string,
baseCurrency: string,
}

View File

@@ -58,7 +58,6 @@ export interface IAccountTransaction {
date: string | Date;
referenceType: string;
referenceTypeFormatted: string;
referenceId: number;
referenceNumber?: string;

View File

@@ -1,9 +1,6 @@
import { INumberFormatQuery } from './FinancialStatements';
export interface IAgingPeriodTotal extends IAgingPeriod {
total: IAgingAmount;
}
};
export interface IAgingAmount {
amount: number;
@@ -23,22 +20,3 @@ 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;
}

View File

@@ -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,16 +138,3 @@ 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;
}

View File

@@ -41,7 +41,7 @@ export interface ICashFlowStatementAccountMeta {
code: string;
total: ICashFlowStatementTotal;
accountType: string;
adjustmentType: string;
adjusmentType: string;
sectionType: ICashFlowStatementSectionType.ACCOUNT;
}

View File

@@ -1,5 +1,6 @@
import { Knex } from 'knex';
import { ISystemUser } from '@/interfaces';
import { Knex } from 'knex';
import { pick } from 'lodash';
import { ILedgerEntry } from './Ledger';
import { ISaleInvoice } from './SaleInvoice';

View File

@@ -156,7 +156,6 @@ export interface ISaleInvoiceEventDeliveredPayload {
tenantId: number;
saleInvoiceId: number;
saleInvoice: ISaleInvoice;
trx: Knex.Transaction;
}
export interface ISaleInvoiceDeliveringPayload {

View File

@@ -1,8 +1,8 @@
import { forEach, uniqBy } from 'lodash';
import DynamicFilterAbstractor from './DynamicFilterAbstractor';
import DynamicFilterAbstructor from './DynamicFilterAbstructor';
import { IDynamicFilter, IFilterRole, IModel } from '@/interfaces';
export default class DynamicFilter extends DynamicFilterAbstractor{
export default class DynamicFilter extends DynamicFilterAbstructor{
private model: IModel;
private tableName: string;
private dynamicFilters: IDynamicFilter[];

View File

@@ -1,5 +1,5 @@
export default class DynamicFilterAbstractor {
export default class DynamicFilterAbstructor {
/**
* Extract relation table name from relation.
* @param {String} column -

View File

@@ -1,7 +1,7 @@
import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor';
import DynamicFilterRoleAbstructor from './DynamicFilterRoleAbstructor';
import { IFilterRole } from '@/interfaces';
export default class FilterRoles extends DynamicFilterRoleAbstractor {
export default class FilterRoles extends DynamicFilterRoleAbstructor {
private filterRoles: IFilterRole[];
/**

View File

@@ -6,7 +6,7 @@ import DynamicFilterQueryParser from './DynamicFilterQueryParser';
import { Lexer } from '../LogicEvaluation/Lexer';
import { COMPARATOR_TYPE, FIELD_TYPE } from './constants';
export default abstract class DynamicFilterAbstractor
export default abstract class DynamicFilterAbstructor
implements IDynamicFilter
{
protected filterRoles: IFilterRole[] = [];

View File

@@ -1,4 +1,4 @@
import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor';
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
import { FIELD_TYPE } from './constants';
interface ISortRole {
@@ -6,7 +6,7 @@ interface ISortRole {
order: string;
}
export default class DynamicFilterSortBy extends DynamicFilterRoleAbstractor {
export default class DynamicFilterSortBy extends DynamicFilterRoleAbstructor {
private sortRole: ISortRole = {};
/**

View File

@@ -1,8 +1,8 @@
import { omit } from 'lodash';
import { IView, IViewRole } from '@/interfaces';
import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor';
import DynamicFilterRoleAbstructor from './DynamicFilterRoleAbstructor';
export default class DynamicFilterViews extends DynamicFilterRoleAbstractor {
export default class DynamicFilterViews extends DynamicFilterRoleAbstructor {
private viewSlug: string;
private logicExpression: string;
private filterRoles: IViewRole[];

View File

@@ -1,10 +1,10 @@
import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor';
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
import {
validateViewRoles,
buildFilterQuery,
} from '@/lib/ViewRolesBuilder';
export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstractor {
export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstructor {
/**
* Constructor method.
* @param {*} filterRoles -

View File

@@ -1,5 +1,6 @@
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';
@@ -86,6 +87,7 @@ export default () => {
export const susbcribers = () => {
return [
ItemSubscriber,
InventoryAdjustmentsSubscriber,
BillWriteInventoryTransactionsSubscriber,
PaymentSyncBillBalance,

View File

@@ -152,7 +152,7 @@
"Opening Balance Liabilities": "رصيد الالتزامات الافتتاحي",
"Loan": "اقراض",
"Owner A Drawings": "مسحوبات المالك",
"An account that holds valuation of products or goods that available for sale.": "حساب يحمل قيم مخزون البضاعة أو السلع المتاحة للبيع.",
"An account that holds valuation of products or goods that availiable 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.": "لا ترتبط انشطة الدخل إلى الأعمال الأساسية.",

View File

@@ -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 available 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 availiable for sale.": "An account that holds valuation of products or goods that availiable 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.",

View File

@@ -127,7 +127,7 @@ export default class Account extends mixin(TenantModel, [
},
filterAccountTypes(query, typesIds) {
if (typesIds.length > 0) {
query.whereIn('account_types.account_type_id', typesIds);
query.whereIn('account_types.accoun_type_id', typesIds);
}
},
viewRolesBuilder(query, conditionals, expression) {

View File

@@ -2,11 +2,8 @@ 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
*/
@@ -33,7 +30,40 @@ export default class AccountTransaction extends TenantModel {
* @return {string}
*/
get referenceTypeFormatted() {
return getTransactionTypeLabel(this.referenceType);
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] || '';
}
/**
@@ -59,9 +89,15 @@ export default class AccountTransaction extends TenantModel {
}
},
filterDateRange(query, startDate, endDate, type = 'day') {
const dateFormat = 'YYYY-MM-DD';
const fromDate = moment(startDate).startOf(type).format(dateFormat);
const toDate = moment(endDate).endOf(type).format(dateFormat);
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);
if (startDate) {
query.where('date', '>=', fromDate);
@@ -105,6 +141,7 @@ export default class AccountTransaction extends TenantModel {
query.modify('filterDateRange', null, toDate);
query.modify('sumationCreditDebit');
},
contactsOpeningBalance(
query,
openingDate,

View File

@@ -97,7 +97,7 @@ export default class Branch extends TenantModel {
},
/**
* Branch may belongs to associated bills.
* Branch may belongs to assocaited bills.
*/
bills: {
relation: Model.HasManyRelation,

View File

@@ -121,7 +121,7 @@ export default class CashflowTransaction extends TenantModel {
},
/**
* Cashflow transaction may has associated cashflow account.
* Cashflow transaction may has assocaited cashflow account.
*/
cashflowAccount: {
relation: Model.BelongsToOneRelation,

View File

@@ -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';
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
const fromDate = moment(startDate).startOf(type).format(dateFormat);
const toDate = moment(endDate).endOf(type).format(dateFormat);

View File

@@ -1,13 +1,9 @@
import { Model, raw } from 'objection';
import { castArray } from 'lodash';
import { castArray, isEmpty } 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
*/
@@ -27,7 +23,27 @@ export default class InventoryTransaction extends TenantModel {
* @return {string}
*/
get transcationTypeFormatted() {
return getTransactionTypeLabel(this.transactionType);
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] || '';
}
/**
@@ -36,7 +52,7 @@ export default class InventoryTransaction extends TenantModel {
static get modifiers() {
return {
filterDateRange(query, startDate, endDate, type = 'day') {
const dateFormat = 'YYYY-MM-DD';
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
const fromDate = moment(startDate).startOf(type).format(dateFormat);
const toDate = moment(endDate).endOf(type).format(dateFormat);

View File

@@ -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';
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
const fromDate = moment(startDate).startOf(type).format(dateFormat);
const toDate = moment(endDate).endOf(type).format(dateFormat);

View File

@@ -84,7 +84,7 @@ export default class Warehouse extends TenantModel {
},
/**
* Warehouse may belongs to associated bills.
* Warehouse may belongs to assocaited bills.
*/
bills: {
relation: Model.HasManyRelation,

View File

@@ -1,6 +1,6 @@
import { Service, Inject } from 'typedi';
import events from '@/subscribers/events';
import { InventoryTransactionsWarehouses } from './AccountsTransactionsWarehouses';
import { InventoryTransactionsWarehouses } from './AcountsTransactionsWarehouses';
import { IBranchesActivatedPayload } from '@/interfaces';
@Service()

View File

@@ -79,7 +79,7 @@ export default class JournalPoster implements IJournalPoster {
}
/**
* Async initialize accounts dependency graph.
* Async initialize acccounts dependency graph.
* @private
* @returns {Promise<void>}
*/

View File

@@ -66,14 +66,14 @@ export class LedgerContactsBalanceStorage {
): Promise<(entry: ILedgerEntry) => boolean> => {
const { Account } = this.tenancy.models(tenantId);
const ARAPAccounts = await Account.query(trx).whereIn('accountType', [
const ARAPAcounts = await Account.query(trx).whereIn('accountType', [
ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE,
ACCOUNT_TYPE.ACCOUNTS_PAYABLE,
]);
const ARAPAccountsIds = ARAPAccounts.map((a) => a.id);
const ARAPAcountsIds = ARAPAcounts.map((a) => a.id);
return (entry: ILedgerEntry) => {
return ARAPAccountsIds.indexOf(entry.accountId) !== -1;
return ARAPAcountsIds.indexOf(entry.accountId) !== -1;
};
};

View File

@@ -35,7 +35,7 @@ export default class LedgerStorageService {
// Saves the ledger entries.
this.ledgerEntriesService.saveEntries(tenantId, ledger, trx),
// Mutates the associated accounts balances.
// Mutates the assocaited 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 associated accounts balances.
// Mutates the assocaited accounts balances.
this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx),
// Mutates the associated contacts balances.

View File

@@ -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 account.
// Filters the ledger entries by the current acount.
const accountLedger = ledger.whereAccountId(accountId);
// Retrieves the given tenant metadata.

View File

@@ -46,7 +46,7 @@ export default class AccountTransactionTransformer extends Transformer {
* @returns {string}
*/
public transactionTypeFormatted(transaction: IAccountTransaction) {
return this.context.i18n.__(transaction.referenceTypeFormatted);
return transaction.referenceTypeFormatted;
}
/**

View File

@@ -77,7 +77,7 @@ export class DeleteAccount {
// Authorize before delete account.
await this.authorize(tenantId, accountId, oldAccount);
// Deletes the account and associated transactions under UOW envirement.
// Deletes the account and assocaited transactions under UOW envirement.
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
// Triggers `onAccountDelete` event.
await this.eventPublisher.emitAsync(events.accounts.onDelete, {

View File

@@ -23,6 +23,15 @@ 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
@@ -66,13 +75,4 @@ export class GetAccounts {
filterMeta: dynamicList.getResponseMeta(),
};
};
/**
* Parsees accounts list filter DTO.
* @param filterDTO
* @returns
*/
private parseListFilterDTO(filterDTO) {
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
}
}

View File

@@ -0,0 +1,9 @@
export class AccountsReceivableRepository {
findOrCreateAccount = (currencyCode?: string) => {
};
}

View File

@@ -1,4 +1,4 @@
export * from './CashflowBranchesActivateSubscriber';
export * from './CashflowBranchesActviateSubscriber';
export * from './CreditNoteBranchesActivateSubscriber';
export * from './PaymentMadeBranchesActivateSubscriber';
export * from './PaymentReceiveBranchesActivateSubscriber';

View File

@@ -1,12 +1,17 @@
import { Service } from 'typedi';
import { includes, camelCase, upperFirst } from 'lodash';
import { IAccount } from '@/interfaces';
import { Service, Inject } from 'typedi';
import { includes, difference, camelCase, upperFirst } from 'lodash';
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
import { IAccount, ICashflowTransactionLine } 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 -

View File

@@ -0,0 +1,14 @@
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;
}

View File

@@ -6,7 +6,7 @@ import {
} from './constants';
/**
* Ensures the given transaction type to transformed to appropriate format.
* Ensures the given transaction type to transformed to properiate format.
* @param {string} type
* @returns {string}
*/

View File

@@ -16,16 +16,16 @@ import BaseCreditNotes from './CreditNotes';
@Service()
export default class CreateCreditNote extends BaseCreditNotes {
@Inject()
private uow: UnitOfWork;
uow: UnitOfWork;
@Inject()
private itemsEntriesService: ItemsEntriesService;
itemsEntriesService: ItemsEntriesService;
@Inject()
private tenancy: HasTenancyService;
tenancy: HasTenancyService;
@Inject()
private eventPublisher: EventPublisher;
eventPublisher: EventPublisher;
/**
* Creates a new credit note.

View File

@@ -1,4 +1,5 @@
import { Service, Inject } from 'typedi';
import HasTenancyService from '@/services/Tenancy/TenancyService';
import events from '@/subscribers/events';
import {
IApplyCreditToInvoicesCreatedPayload,
@@ -9,12 +10,15 @@ import CreditNoteApplySyncInvoicesCreditedAmount from './CreditNoteApplySyncInvo
@Service()
export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber {
@Inject()
private syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount;
tenancy: HasTenancyService;
@Inject()
syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount;
/**
* Attaches events with handlers.
*/
public attach(bus) {
attach(bus) {
bus.subscribe(
events.creditNote.onApplyToInvoicesCreated,
this.incrementAppliedInvoicesOnceCreditCreated

View File

@@ -15,7 +15,7 @@ export default class CreditNoteInventoryTransactionsSubscriber {
/**
* Attaches events with publisher.
*/
public attach(bus) {
attach(bus) {
bus.subscribe(
events.creditNote.onCreated,
this.writeInventoryTranscationsOnceCreated
@@ -37,7 +37,6 @@ export default class CreditNoteInventoryTransactionsSubscriber {
/**
* Writes inventory transactions once credit note created.
* @param {ICreditNoteCreatedPayload} payload -
* @returns {Promise<void>}
*/
public writeInventoryTranscationsOnceCreated = async ({
tenantId,
@@ -45,8 +44,9 @@ 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,7 +57,6 @@ export default class CreditNoteInventoryTransactionsSubscriber {
/**
* Rewrites inventory transactions once credit note edited.
* @param {ICreditNoteEditedPayload} payload -
* @returns {Promise<void>}
*/
public rewriteInventoryTransactionsOnceEdited = async ({
tenantId,
@@ -66,8 +65,9 @@ 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,8 +87,9 @@ 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,

View File

@@ -49,7 +49,7 @@ export default class CreditNoteInventoryTransactions {
};
/**
* Edits vendor credit associated inventory transactions.
* Edits vendor credit assocaited inventory transactions.
* @param {number} tenantId
* @param {number} creditNoteId
* @param {ICreditNote} creditNote

View File

@@ -29,7 +29,7 @@ export default class DeleteCustomerLinkedCreditSubscriber {
};
/**
* Validate vendor has no associated credit transaction once the vendor deleting.
* Validate vendor has no assocaited credit transaction once the vendor deleting.
* @param {IVendorEventDeletingPayload} payload -
*/
public validateCustomerHasNoLinkedCreditsOnDeleting = async ({

View File

@@ -1,6 +0,0 @@
export default class DynamicListAbstract {
}

View File

@@ -0,0 +1,6 @@
export default class DynamicListAbstruct {
}

View File

@@ -1,5 +1,5 @@
import { Inject, Service } from 'typedi';
import DynamicListAbstract from './DynamicListAbstract';
import DynamicListAbstruct from './DynamicListAbstruct';
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 DynamicListAbstract {
export default class DynamicListCustomView extends DynamicListAbstruct {
@Inject()
tenancy: HasTenancyService;

View File

@@ -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 DynamicListAbstract from './DynamicListAbstract';
import DynamicListAbstruct from './DynamicListAbstruct';
import DynamicFilterAdvancedFilter from '@/lib/DynamicFilter/DynamicFilterAdvancedFilter';
import { ERRORS } from './constants';
import { ServiceError } from '@/exceptions';
@Service()
export default class DynamicListFilterRoles extends DynamicListAbstract {
export default class DynamicListFilterRoles extends DynamicListAbstruct {
/**
* Validates filter roles schema.
* @param {IFilterRole[]} filterRoles - Filter roles.

View File

@@ -1,11 +1,11 @@
import { Service } from 'typedi';
import { IFilterRole, IModel } from '@/interfaces';
import DynamicListAbstract from './DynamicListAbstract';
import DynamicListAbstruct from './DynamicListAbstruct';
import DynamicFilterFilterRoles from '@/lib/DynamicFilter/DynamicFilterFilterRoles';
import DynamicFilterSearch from '@/lib/DynamicFilter/DynamicFilterSearch';
@Service()
export default class DynamicListSearch extends DynamicListAbstract {
export default class DynamicListSearch extends DynamicListAbstruct {
/**
* Dynamic list filter roles.
* @param {IModel} model

View File

@@ -1,12 +1,12 @@
import { Service } from 'typedi';
import DynamicListAbstract from './DynamicListAbstract';
import DynamicListAbstruct from './DynamicListAbstruct';
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 DynamicListAbstract {
export default class DynamicListSortBy extends DynamicListAbstruct {
/**
* Dynamic list sort by.
* @param {IModel} model

View File

@@ -21,7 +21,7 @@ export class ExpensesWriteGLSubscriber {
* Attaches events with handlers.
* @param bus
*/
public attach(bus) {
attach(bus) {
bus.subscribe(
events.expenses.onCreated,
this.handleWriteGLEntriesOnceCreated

View File

@@ -34,7 +34,7 @@ export class FeaturesManager {
}
/**
* Detarmines the given feature name is accessible.
* Detarmines the given feature name is accessiable.
* @param {number} tenantId
* @param {string} feature
* @returns {Promise<void>}

View File

@@ -33,7 +33,7 @@ export class FeaturesSettingsDriver {
}
/**
* Detarmines the given feature name is accessible.
* Detarmines the given feature name is accessiable.
* @param {number} tenantId
* @param {string} feature
* @returns {Promise<boolean|null|undefined>}

View File

@@ -5,7 +5,6 @@ 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 {
@@ -85,7 +84,7 @@ export default class PayableAgingSummaryService {
// Common query.
const commonQuery = (query) => {
if (!isEmpty(filter.branchesIds)) {
if (isEmpty(filter.branchesIds)) {
query.modify('filterByBranches', filter.branchesIds);
}
};
@@ -119,21 +118,4 @@ 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,
};
}
}

View File

@@ -91,7 +91,7 @@ export default class APAgingSummarySheet extends AgingSummaryReport {
return {
vendorName: vendor.displayName,
current: this.formatAmount(currentTotal),
current: this.formatTotalAmount(currentTotal),
aging: agingPeriods,
total: this.formatTotalAmount(amount),
};

View File

@@ -1,46 +0,0 @@
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' };
};
}

View File

@@ -5,7 +5,6 @@ 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 {
@@ -90,12 +89,12 @@ export default class ARAgingSummaryService {
};
// Retrieve all overdue sale invoices.
const overdueSaleInvoices = await SaleInvoice.query()
.modify('overdueInvoicesFromDate', filter.asDate)
.modify('dueInvoicesFromDate', filter.asDate)
.onBuild(commonQuery);
// Retrieve all due sale invoices.
const currentInvoices = await SaleInvoice.query()
.modify('dueInvoicesFromDate', filter.asDate)
.modify('overdueInvoicesFromDate', filter.asDate)
.onBuild(commonQuery);
// AR aging summary report instance.
@@ -118,21 +117,4 @@ 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,
};
}
}

View File

@@ -1,4 +1,4 @@
import { Dictionary, groupBy, isEmpty, sum } from 'lodash';
import { groupBy, isEmpty, sum } from 'lodash';
import * as R from 'ramda';
import {
ICustomer,
@@ -54,6 +54,7 @@ export default class ARAgingSummarySheet extends AgingSummaryReport {
currentSaleInvoices,
'customerId'
);
// Initializes the aging periods.
this.agingPeriods = this.agingRangePeriods(
this.query.asDate,
@@ -188,7 +189,7 @@ export default class ARAgingSummarySheet extends AgingSummaryReport {
};
/**
* Retrieve A/R aging summary report columns.
* Retrieve AR aging summary report columns.
* @return {IARAgingSummaryColumns}
*/
public reportColumns(): IARAgingSummaryColumns {

View File

@@ -1,38 +0,0 @@
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' };
}
}

View File

@@ -1,211 +0,0 @@
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' },
]);
};
}

View File

@@ -1,4 +0,0 @@
export enum AgingSummaryRowType {
Contact = 'contact',
Total = 'total',
}

View File

@@ -37,7 +37,7 @@ export default class BalanceSheetStatementService
displayColumnsBy: 'month',
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
numberFormat: {
precision: 2,

View File

@@ -197,7 +197,7 @@ export default class CashFlowStatement extends compose(
code: account.code,
label: account.name,
accountType: account.accountType,
adjustmentType: relation.direction,
adjusmentType: 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[]} accumulatedSections
* @param {ICashFlowSchemaSection[]} accumlatedSections
* @returns {ICashFlowStatementTotalSection}
*/
private totalEquationSectionParser = (
accumulatedSections: ICashFlowSchemaSection[],
accumlatedSections: ICashFlowSchemaSection[],
sectionSchema: ICashFlowSchemaTotalSection
): ICashFlowStatementTotalSection => {
const mappedSectionsById = this.transformSectionsToMap(accumulatedSections);
const mappedSectionsById = this.transformSectionsToMap(accumlatedSections);
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,
adjustmentType: relation.direction,
adjusmentType: 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)[]} accumulatedSections
* @param {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} accumlatedSections
* @returns {ICashFlowSchemaSection}
*/
private schemaSectionTotalParser = (
@@ -532,13 +532,13 @@ export default class CashFlowStatement extends compose(
key: number,
parentValue: ICashFlowSchemaSection[],
context,
accumulatedSections: (ICashFlowSchemaSection | ICashFlowStatementSection)[]
accumlatedSections: (ICashFlowSchemaSection | ICashFlowStatementSection)[]
): ICashFlowSchemaSection | ICashFlowStatementSection => {
return R.compose(
// Total equation section.
R.when(
this.isSchemaSectionType(ICashFlowStatementSectionType.TOTAL),
R.curry(this.totalEquationSectionParser)(accumulatedSections)
R.curry(this.totalEquationSectionParser)(accumlatedSections)
)
)(section);
};

View File

@@ -165,7 +165,7 @@ export const CashFlowStatementDatePeriods = (Base) =>
.whereAccountId(node.id)
.getClosingBalance();
return this.amountAdjustment(node.adjustmentType, closingBalance);
return this.amountAdjustment(node.adjusmentType, closingBalance);
};
/**
@@ -322,7 +322,7 @@ export const CashFlowStatementDatePeriods = (Base) =>
// Cash at beginning ----------------------
/**
* Retrieve the date preioods of the given node and accumulated function.
* Retrieve the date preioods of the given node and accumlated function.
* @param {} node
* @param {}
* @return {}

View File

@@ -40,7 +40,7 @@ export default class CashFlowStatementService
displayColumnsType: 'total',
displayColumnsBy: 'day',
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
numberFormat: {
precision: 2,
divideOn1000: false,

View File

@@ -41,7 +41,7 @@ export default class CashflowAccountTransactionsService extends FinancialSheet {
}
/**
* Retrieve the cashflow account transactions report data.
* Retrieve the cashflow accouynt transactions report data.
* @param {number} tenantId -
* @param {ICashflowAccountTransactionsQuery} query -
* @return {Promise<IInvetoryItemDetailDOO>}

View File

@@ -64,7 +64,7 @@ export const FinancialDatePeriods = (Base) =>
};
/**
* Retrieve the date preioods of the given node and accumulated function.
* Retrieve the date preioods of the given node and accumlated function.
* @param {IBalanceSheetAccountNode} node
* @param {(fromDate: Date, toDate: Date, index: number) => any}
* @return {}

View File

@@ -12,7 +12,7 @@ export const FinancialTable = (Base) =>
* @param {ITableColumn[]} columns
* @returns {ITableColumn[]}
*/
public tableColumnsCellIndexing = (
protected tableColumnsCellIndexing = (
columns: ITableColumn[]
): ITableColumn[] => {
const cellIndex = increment(-1);

View File

@@ -31,8 +31,8 @@ export default class GeneralLedgerService {
*/
get defaultQuery() {
return {
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'cash',
numberFormat: {
noCents: false,

View File

@@ -126,7 +126,7 @@ export default class InventoryDetails extends FinancialSheet {
);
/**
* Accumulate and mapping running quantity on transactions.
* Accumlate and mapping running quantity on transactions.
* @param {IInventoryDetailsItemTransaction[]} transactions
* @returns {IInventoryDetailsItemTransaction[]}
*/
@@ -150,7 +150,7 @@ export default class InventoryDetails extends FinancialSheet {
}
/**
* Accumulate and mapping running valuation on transactions.
* Accumlate 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 adjustment = b.direction === 'OUT' ? -1 : 1;
const total = a.runningValuation.number + b.cost.number * adjustment;
const adjusmtent = b.direction === 'OUT' ? -1 : 1;
const total = a.runningValuation.number + b.cost.number * adjusmtent;
const totalMeta = this.getNumberMeta(total, { excerptZero: false });
const accum = { ...b, runningValuation: totalMeta };

View File

@@ -16,13 +16,13 @@ import { Tenant } from '@/system/models';
@Service()
export default class InventoryDetailsService extends FinancialSheet {
@Inject()
private tenancy: TenancyService;
tenancy: TenancyService;
@Inject()
private reportRepo: InventoryDetailsRepository;
reportRepo: InventoryDetailsRepository;
@Inject()
private inventoryService: InventoryService;
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('month').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
itemsIds: [],
numberFormat: {
precision: 2,

View File

@@ -27,7 +27,7 @@ export default class InventoryValuationSheetService {
*/
get defaultQuery(): IInventoryValuationReportQuery {
return {
asDate: moment().format('YYYY-MM-DD'),
asDate: moment().endOf('year').format('YYYY-MM-DD'),
itemsIds: [],
numberFormat: {
precision: 2,

View File

@@ -25,8 +25,8 @@ export default class JournalSheetService {
*/
get defaultQuery() {
return {
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
fromRange: null,
toRange: null,
accountsIds: [],

View File

@@ -8,7 +8,7 @@ import { IProfitLossSheetQuery } from '@/interfaces';
*/
export const getDefaultPLQuery = (): IProfitLossSheetQuery => ({
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
numberFormat: {
divideOn1000: false,

View File

@@ -129,9 +129,9 @@ export class ProjectProfitabilitySummaryRespository {
*/
public getIncomeAccountsGroupedEntries = async () => {
const incomeAccounts = await this.getIncomeAccounts();
const incomeAccountsIds = map(incomeAccounts, 'id');
const incomeAcountssIds = map(incomeAccounts, 'id');
return this.getAccountsGroupedEntries(incomeAccountsIds);
return this.getAccountsGroupedEntries(incomeAcountssIds);
};
/**

View File

@@ -12,7 +12,10 @@ import { Tenant } from '@/system/models';
@Service()
export default class InventoryValuationReportService {
@Inject()
private tenancy: TenancyService;
tenancy: TenancyService;
@Inject('logger')
logger: any;
/**
* Defaults balance sheet filter query.
@@ -20,8 +23,8 @@ export default class InventoryValuationReportService {
*/
get defaultQuery(): IInventoryValuationReportQuery {
return {
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
itemsIds: [],
numberFormat: {
precision: 2,
@@ -70,9 +73,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);
@@ -84,7 +87,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) {
@@ -103,7 +106,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)
}
);

View File

@@ -23,8 +23,8 @@ export default class SalesByItemsReportService {
*/
get defaultQuery(): ISalesByItemsReportQuery {
return {
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
itemsIds: [],
numberFormat: {
precision: 2,

View File

@@ -31,8 +31,8 @@ export default class TransactionsByCustomersService
*/
get defaultQuery(): ITransactionsByCustomersFilter {
return {
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
numberFormat: {
precision: 2,
divideOn1000: false,

View File

@@ -32,7 +32,7 @@ export default class TransactionsByVendorsService
*/
get defaultQuery(): ITransactionsByVendorsFilter {
return {
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
fromDate: moment().format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
numberFormat: {
precision: 2,

View File

@@ -27,7 +27,7 @@ export default class TrialBalanceSheetService extends FinancialSheet {
get defaultQuery(): ITrialBalanceSheetQuery {
return {
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
numberFormat: {
divideOn1000: false,
negativeFormat: 'mines',

View File

@@ -95,7 +95,7 @@ export default class InventoryService {
) {
const { Item } = this.tenancy.models(tenantId);
// Fetches the item with associated item category.
// Fetches the item with assocaited item category.
const item = await Item.query().findById(itemId);
// Cannot continue if the given item was not inventory item.

View File

@@ -180,7 +180,7 @@ export default class InventoryAdjustmentService {
quickAdjustmentDTO,
} as IInventoryAdjustmentCreatingPayload
);
// Saves the inventory adjustment with associated entries to the storage.
// Saves the inventory adjustment with assocaited entries to the storage.
const inventoryAdjustment = await InventoryAdjustment.query(
trx
).upsertGraph({

View File

@@ -49,7 +49,7 @@ export default class InventoryAverageCostMethod
public async computeItemCost() {
const { InventoryTransaction } = this.tenantModels;
const { averageCost, openingQuantity, openingCost } =
await this.getOpeningAverageCost(this.startingDate, this.itemId);
await this.getOpeningAvaregeCost(this.startingDate, this.itemId);
const afterInvTransactions: IInventoryTransaction[] =
await InventoryTransaction.query()
@@ -75,12 +75,12 @@ export default class InventoryAverageCostMethod
}
/**
* Get items Average cost from specific date from inventory transactions.
* Get items Avarege cost from specific date from inventory transactions.
* @async
* @param {Date} closingDate
* @return {number}
*/
public async getOpeningAverageCost(closingDate: Date, itemId: number) {
public async getOpeningAvaregeCost(closingDate: Date, itemId: number) {
const { InventoryCostLotTracker } = this.tenantModels;
const commonBuilder = (builder: any) => {

View File

@@ -79,7 +79,7 @@ export default class InventoryCostLotTracker extends InventoryCostMethod impleme
/**
* Fetched inventory transactions that has date from the starting date and
* fetches available IN LOTs transactions that has remaining bigger than zero.
* fetches availiable 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 availableINLots: IInventoryLotCost[] =
const availiableINLots: 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 = [
...availableINLots.map((trans) => ({ lotTransId: trans.id, ...trans })),
...availiableINLots.map((trans) => ({ lotTransId: trans.id, ...trans })),
...afterInvTransactions.map((trans) => ({ invTransId: trans.id, ...trans })),
];
}

View File

@@ -344,7 +344,7 @@ export default class ItemCategoriesService implements IItemCategoriesService {
);
// Items categories.
const itemCategories = await ItemCategory.query().onBuild((query) => {
// Subquery to calculate sumation of associated items to the item category.
// Subquery to calculate sumation of assocaited items to the item category.
query.select('*', ItemCategory.relatedQuery('items').count().as('count'));
dynamicList.buildQuery()(query);

View File

@@ -9,9 +9,13 @@ 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;

View File

@@ -198,7 +198,7 @@ export class ItemsValidators {
/**
* Validate the item inventory account whether modified and item
* has associated inventory transactions.
* has assocaited 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