mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
Compare commits
17 Commits
fix-spelli
...
v0.9.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f746b96c8 | ||
|
|
ed2bca6b74 | ||
|
|
f9d5a3c69a | ||
|
|
84445d4bac | ||
|
|
75d8864aae | ||
|
|
cb6dab08d8 | ||
|
|
5112ef9b64 | ||
|
|
a630e8a612 | ||
|
|
4df63561cf | ||
|
|
c7a3bac44c | ||
|
|
251c54be60 | ||
|
|
5dec4a7df0 | ||
|
|
0d57ca88bf | ||
|
|
b9be83dc2b | ||
|
|
321de4d327 | ||
|
|
4e66d1ac98 | ||
|
|
b5fe5a8bcb |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,4 +1,9 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
data
|
|
||||||
|
# Docker volumes data directory
|
||||||
|
/data
|
||||||
|
|
||||||
|
# Production env file
|
||||||
.env
|
.env
|
||||||
|
|
||||||
test-results/
|
test-results/
|
||||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
All notable changes to Bigcapital server-side will be in this file.
|
All notable changes to Bigcapital server-side will be in this file.
|
||||||
|
|
||||||
|
# [0.9.12] - 29-08-2023
|
||||||
|
|
||||||
|
* Refactor: split the services to multiple service classes. (by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/202)
|
||||||
|
* Fix: create quick customer/vendor by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/206
|
||||||
|
* Fix: typo in bill success message without bill number by @KalliopiPliogka in https://github.com/bigcapitalhq/bigcapital/pull/219
|
||||||
|
* Fix: AP/AR aging summary issue by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/229
|
||||||
|
* Fix: shouldn't write GL entries when save transaction as draft. by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/221
|
||||||
|
* Fix: Transaction type of credit note and vendor credit are not defined on account transactions by @abouolia in
|
||||||
|
* Fix: date format of filtering transactions by date range by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/231
|
||||||
|
* Fix: change the default from/date date value of reports by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/230
|
||||||
|
* Fix: typos in words start with `A` letter by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/227
|
||||||
|
* Fix: filter by customers, vendors and items in reports do not work by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/224
|
||||||
|
https://github.com/bigcapitalhq/bigcapital/pull/225
|
||||||
|
|
||||||
# [0.9.11] - 23-07-2023
|
# [0.9.11] - 23-07-2023
|
||||||
|
|
||||||
* added: Restart policy to docker compose files. by @suhaibaffan in https://github.com/bigcapitalhq/bigcapital/pull/198
|
* added: Restart policy to docker compose files. by @suhaibaffan in https://github.com/bigcapitalhq/bigcapital/pull/198
|
||||||
|
|||||||
@@ -33,10 +33,13 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC
|
|||||||
return [
|
return [
|
||||||
...this.sheetNumberFormatValidationSchema,
|
...this.sheetNumberFormatValidationSchema,
|
||||||
query('as_date').optional().isISO8601(),
|
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').optional().isArray({ min: 1 }),
|
||||||
query('vendors_ids.*').isInt({ min: 1 }).toInt(),
|
query('vendors_ids.*').isInt({ min: 1 }).toInt(),
|
||||||
|
|
||||||
query('none_zero').default(true).isBoolean().toBoolean(),
|
query('none_zero').default(true).isBoolean().toBoolean(),
|
||||||
|
|
||||||
// Filtering by branches.
|
// Filtering by branches.
|
||||||
@@ -53,15 +56,36 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC
|
|||||||
const filter = this.matchedQueryData(req);
|
const filter = this.matchedQueryData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data, columns, query, meta } =
|
const accept = this.accepts(req);
|
||||||
await this.APAgingSummaryService.APAgingSummary(tenantId, filter);
|
const acceptType = accept.types(['json', 'application/json+table']);
|
||||||
|
|
||||||
return res.status(200).send({
|
switch (acceptType) {
|
||||||
data: this.transfromToResponse(data),
|
case 'application/json+table':
|
||||||
columns: this.transfromToResponse(columns),
|
const table = await this.APAgingSummaryService.APAgingSummaryTable(
|
||||||
query: this.transfromToResponse(query),
|
tenantId,
|
||||||
meta: this.transfromToResponse(meta),
|
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) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC
|
|||||||
|
|
||||||
query('as_date').optional().isISO8601(),
|
query('as_date').optional().isISO8601(),
|
||||||
|
|
||||||
query('aging_days_before').optional().isInt({ max: 500 }).toInt(),
|
query('aging_days_before').default(30).isInt({ max: 500 }).toInt(),
|
||||||
query('aging_periods').optional().isInt({ max: 12 }).toInt(),
|
query('aging_periods').default(3).isInt({ max: 12 }).toInt(),
|
||||||
|
|
||||||
query('customers_ids').optional().isArray({ min: 1 }),
|
query('customers_ids').optional().isArray({ min: 1 }),
|
||||||
query('customers_ids.*').isInt({ min: 1 }).toInt(),
|
query('customers_ids.*').isInt({ min: 1 }).toInt(),
|
||||||
@@ -58,15 +58,36 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC
|
|||||||
const filter = this.matchedQueryData(req);
|
const filter = this.matchedQueryData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data, columns, query, meta } =
|
const accept = this.accepts(req);
|
||||||
await this.ARAgingSummaryService.ARAgingSummary(tenantId, filter);
|
const acceptType = accept.types(['json', 'application/json+table']);
|
||||||
|
|
||||||
return res.status(200).send({
|
switch (acceptType) {
|
||||||
data: this.transfromToResponse(data),
|
case 'application/json+table':
|
||||||
columns: this.transfromToResponse(columns),
|
const table = await this.ARAgingSummaryService.ARAgingSummaryTable(
|
||||||
query: this.transfromToResponse(query),
|
tenantId,
|
||||||
meta: this.transfromToResponse(meta),
|
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) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|||||||
28
packages/server/src/data/TransactionTypes.ts
Executable file
28
packages/server/src/data/TransactionTypes.ts
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
export const TransactionTypes = {
|
||||||
|
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',
|
||||||
|
|
||||||
|
LandedCost: 'transaction_type.landed_cost',
|
||||||
|
};
|
||||||
@@ -1,51 +1,36 @@
|
|||||||
import {
|
import {
|
||||||
IAgingPeriod,
|
IAgingPeriod,
|
||||||
IAgingPeriodTotal,
|
IAgingPeriodTotal,
|
||||||
IAgingAmount
|
IAgingAmount,
|
||||||
|
IAgingSummaryQuery,
|
||||||
|
IAgingSummaryTotal,
|
||||||
|
IAgingSummaryContact,
|
||||||
|
IAgingSummaryData,
|
||||||
} from './AgingReport';
|
} from './AgingReport';
|
||||||
import {
|
import { INumberFormatQuery } from './FinancialStatements';
|
||||||
INumberFormatQuery
|
|
||||||
} from './FinancialStatements';
|
|
||||||
|
|
||||||
export interface IAPAgingSummaryQuery {
|
export interface IAPAgingSummaryQuery extends IAgingSummaryQuery {
|
||||||
asDate: Date | string;
|
|
||||||
agingDaysBefore: number;
|
|
||||||
agingPeriods: number;
|
|
||||||
numberFormat: INumberFormatQuery;
|
|
||||||
vendorsIds: number[];
|
vendorsIds: number[];
|
||||||
noneZero: boolean;
|
|
||||||
|
|
||||||
branchesIds?: number[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAPAgingSummaryVendor {
|
export interface IAPAgingSummaryVendor extends IAgingSummaryContact {
|
||||||
vendorName: string,
|
vendorName: string;
|
||||||
current: IAgingAmount,
|
}
|
||||||
aging: IAgingPeriodTotal[],
|
|
||||||
total: IAgingAmount,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IAPAgingSummaryTotal {
|
export interface IAPAgingSummaryTotal extends IAgingSummaryTotal {}
|
||||||
current: IAgingAmount,
|
|
||||||
aging: IAgingPeriodTotal[],
|
|
||||||
total: IAgingAmount,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IAPAgingSummaryData {
|
export interface IAPAgingSummaryData extends IAgingSummaryData {
|
||||||
vendors: IAPAgingSummaryVendor[],
|
vendors: IAPAgingSummaryVendor[];
|
||||||
total: IAPAgingSummaryTotal,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export type IAPAgingSummaryColumns = IAgingPeriod[];
|
export type IAPAgingSummaryColumns = IAgingPeriod[];
|
||||||
|
|
||||||
|
|
||||||
export interface IARAgingSummaryMeta {
|
export interface IARAgingSummaryMeta {
|
||||||
baseCurrency: string,
|
baseCurrency: string;
|
||||||
organizationName: string,
|
organizationName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface IAPAgingSummaryMeta {
|
export interface IAPAgingSummaryMeta {
|
||||||
baseCurrency: string,
|
baseCurrency: string;
|
||||||
organizationName: string,
|
organizationName: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,28 @@
|
|||||||
import { IAgingPeriod, IAgingPeriodTotal, IAgingAmount } from './AgingReport';
|
import {
|
||||||
import { INumberFormatQuery } from './FinancialStatements';
|
IAgingPeriod,
|
||||||
|
IAgingSummaryQuery,
|
||||||
|
IAgingSummaryTotal,
|
||||||
|
IAgingSummaryContact,
|
||||||
|
IAgingSummaryData,
|
||||||
|
} from './AgingReport';
|
||||||
|
|
||||||
export interface IARAgingSummaryQuery {
|
export interface IARAgingSummaryQuery extends IAgingSummaryQuery {
|
||||||
asDate: Date | string;
|
|
||||||
agingDaysBefore: number;
|
|
||||||
agingPeriods: number;
|
|
||||||
numberFormat: INumberFormatQuery;
|
|
||||||
customersIds: number[];
|
customersIds: number[];
|
||||||
branchesIds: number[];
|
|
||||||
noneZero: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IARAgingSummaryCustomer {
|
export interface IARAgingSummaryCustomer extends IAgingSummaryContact {
|
||||||
customerName: string;
|
customerName: string;
|
||||||
current: IAgingAmount;
|
|
||||||
aging: IAgingPeriodTotal[];
|
|
||||||
total: IAgingAmount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IARAgingSummaryTotal {
|
export interface IARAgingSummaryTotal extends IAgingSummaryTotal {}
|
||||||
current: IAgingAmount;
|
|
||||||
aging: IAgingPeriodTotal[];
|
|
||||||
total: IAgingAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IARAgingSummaryData {
|
export interface IARAgingSummaryData extends IAgingSummaryData {
|
||||||
customers: IARAgingSummaryCustomer[];
|
customers: IARAgingSummaryCustomer[];
|
||||||
total: IARAgingSummaryTotal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IARAgingSummaryColumns = IAgingPeriod[];
|
export type IARAgingSummaryColumns = IAgingPeriod[];
|
||||||
|
|
||||||
export interface IARAgingSummaryMeta {
|
export interface IARAgingSummaryMeta {
|
||||||
organizationName: string,
|
organizationName: string;
|
||||||
baseCurrency: string,
|
baseCurrency: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
|
||||||
|
import { INumberFormatQuery } from './FinancialStatements';
|
||||||
|
|
||||||
export interface IAgingPeriodTotal extends IAgingPeriod {
|
export interface IAgingPeriodTotal extends IAgingPeriod {
|
||||||
total: IAgingAmount;
|
total: IAgingAmount;
|
||||||
};
|
}
|
||||||
|
|
||||||
export interface IAgingAmount {
|
export interface IAgingAmount {
|
||||||
amount: number;
|
amount: number;
|
||||||
@@ -20,3 +23,22 @@ export interface IAgingSummaryContact {
|
|||||||
aging: IAgingPeriodTotal[];
|
aging: IAgingPeriodTotal[];
|
||||||
total: IAgingAmount;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,15 +59,9 @@ export default class AccountTransaction extends TenantModel {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
filterDateRange(query, startDate, endDate, type = 'day') {
|
||||||
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
|
const dateFormat = 'YYYY-MM-DD';
|
||||||
const fromDate = moment(startDate)
|
const fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||||
.utcOffset(0)
|
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
||||||
.startOf(type)
|
|
||||||
.format(dateFormat);
|
|
||||||
const toDate = moment(endDate)
|
|
||||||
.utcOffset(0)
|
|
||||||
.endOf(type)
|
|
||||||
.format(dateFormat);
|
|
||||||
|
|
||||||
if (startDate) {
|
if (startDate) {
|
||||||
query.where('date', '>=', fromDate);
|
query.where('date', '>=', fromDate);
|
||||||
@@ -111,7 +105,6 @@ export default class AccountTransaction extends TenantModel {
|
|||||||
query.modify('filterDateRange', null, toDate);
|
query.modify('filterDateRange', null, toDate);
|
||||||
query.modify('sumationCreditDebit');
|
query.modify('sumationCreditDebit');
|
||||||
},
|
},
|
||||||
|
|
||||||
contactsOpeningBalance(
|
contactsOpeningBalance(
|
||||||
query,
|
query,
|
||||||
openingDate,
|
openingDate,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export default class InventoryCostLotTracker extends TenantModel {
|
|||||||
query.groupBy('item_id');
|
query.groupBy('item_id');
|
||||||
},
|
},
|
||||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
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 fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||||
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export default class InventoryTransaction extends TenantModel {
|
|||||||
static get modifiers() {
|
static get modifiers() {
|
||||||
return {
|
return {
|
||||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
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 fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||||
const toDate = moment(endDate).endOf(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.
|
* Filters the invoices between the given date range.
|
||||||
*/
|
*/
|
||||||
filterDateRange(query, startDate, endDate, type = 'day') {
|
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 fromDate = moment(startDate).startOf(type).format(dateFormat);
|
||||||
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
const toDate = moment(endDate).endOf(type).format(dateFormat);
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import { includes, difference, camelCase, upperFirst } from 'lodash';
|
import { includes, camelCase, upperFirst } from 'lodash';
|
||||||
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
|
import { IAccount } from '@/interfaces';
|
||||||
import { IAccount, ICashflowTransactionLine } from '@/interfaces';
|
|
||||||
import { getCashflowTransactionType } from './utils';
|
import { getCashflowTransactionType } from './utils';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { CASHFLOW_TRANSACTION_TYPE, ERRORS } from './constants';
|
import { CASHFLOW_TRANSACTION_TYPE, ERRORS } from './constants';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class CommandCashflowValidator {
|
export class CommandCashflowValidator {
|
||||||
@Inject()
|
|
||||||
private tenancy: HasTenancyService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the lines accounts type should be cash or bank account.
|
* Validates the lines accounts type should be cash or bank account.
|
||||||
* @param {IAccount} accounts -
|
* @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;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@ import TenancyService from '@/services/Tenancy/TenancyService';
|
|||||||
import APAgingSummarySheet from './APAgingSummarySheet';
|
import APAgingSummarySheet from './APAgingSummarySheet';
|
||||||
import { Tenant } from '@/system/models';
|
import { Tenant } from '@/system/models';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
import APAgingSummaryTable from './APAgingSummaryTable';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class PayableAgingSummaryService {
|
export default class PayableAgingSummaryService {
|
||||||
@@ -84,7 +85,7 @@ export default class PayableAgingSummaryService {
|
|||||||
|
|
||||||
// Common query.
|
// Common query.
|
||||||
const commonQuery = (query) => {
|
const commonQuery = (query) => {
|
||||||
if (isEmpty(filter.branchesIds)) {
|
if (!isEmpty(filter.branchesIds)) {
|
||||||
query.modify('filterByBranches', filter.branchesIds);
|
query.modify('filterByBranches', filter.branchesIds);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -118,4 +119,21 @@ export default class PayableAgingSummaryService {
|
|||||||
meta: this.reportMetadata(tenantId),
|
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 {
|
return {
|
||||||
vendorName: vendor.displayName,
|
vendorName: vendor.displayName,
|
||||||
current: this.formatTotalAmount(currentTotal),
|
current: this.formatAmount(currentTotal),
|
||||||
aging: agingPeriods,
|
aging: agingPeriods,
|
||||||
total: this.formatTotalAmount(amount),
|
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 TenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import ARAgingSummarySheet from './ARAgingSummarySheet';
|
import ARAgingSummarySheet from './ARAgingSummarySheet';
|
||||||
import { Tenant } from '@/system/models';
|
import { Tenant } from '@/system/models';
|
||||||
|
import ARAgingSummaryTable from './ARAgingSummaryTable';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class ARAgingSummaryService {
|
export default class ARAgingSummaryService {
|
||||||
@@ -89,12 +90,12 @@ export default class ARAgingSummaryService {
|
|||||||
};
|
};
|
||||||
// Retrieve all overdue sale invoices.
|
// Retrieve all overdue sale invoices.
|
||||||
const overdueSaleInvoices = await SaleInvoice.query()
|
const overdueSaleInvoices = await SaleInvoice.query()
|
||||||
.modify('dueInvoicesFromDate', filter.asDate)
|
.modify('overdueInvoicesFromDate', filter.asDate)
|
||||||
.onBuild(commonQuery);
|
.onBuild(commonQuery);
|
||||||
|
|
||||||
// Retrieve all due sale invoices.
|
// Retrieve all due sale invoices.
|
||||||
const currentInvoices = await SaleInvoice.query()
|
const currentInvoices = await SaleInvoice.query()
|
||||||
.modify('overdueInvoicesFromDate', filter.asDate)
|
.modify('dueInvoicesFromDate', filter.asDate)
|
||||||
.onBuild(commonQuery);
|
.onBuild(commonQuery);
|
||||||
|
|
||||||
// AR aging summary report instance.
|
// AR aging summary report instance.
|
||||||
@@ -117,4 +118,21 @@ export default class ARAgingSummaryService {
|
|||||||
meta: this.reportMetadata(tenantId),
|
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 * as R from 'ramda';
|
||||||
import {
|
import {
|
||||||
ICustomer,
|
ICustomer,
|
||||||
@@ -54,7 +54,6 @@ export default class ARAgingSummarySheet extends AgingSummaryReport {
|
|||||||
currentSaleInvoices,
|
currentSaleInvoices,
|
||||||
'customerId'
|
'customerId'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Initializes the aging periods.
|
// Initializes the aging periods.
|
||||||
this.agingPeriods = this.agingRangePeriods(
|
this.agingPeriods = this.agingRangePeriods(
|
||||||
this.query.asDate,
|
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}
|
* @return {IARAgingSummaryColumns}
|
||||||
*/
|
*/
|
||||||
public reportColumns(): 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',
|
displayColumnsBy: 'month',
|
||||||
|
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
|
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default class CashFlowStatementService
|
|||||||
displayColumnsType: 'total',
|
displayColumnsType: 'total',
|
||||||
displayColumnsBy: 'day',
|
displayColumnsBy: 'day',
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
divideOn1000: false,
|
divideOn1000: false,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const FinancialTable = (Base) =>
|
|||||||
* @param {ITableColumn[]} columns
|
* @param {ITableColumn[]} columns
|
||||||
* @returns {ITableColumn[]}
|
* @returns {ITableColumn[]}
|
||||||
*/
|
*/
|
||||||
protected tableColumnsCellIndexing = (
|
public tableColumnsCellIndexing = (
|
||||||
columns: ITableColumn[]
|
columns: ITableColumn[]
|
||||||
): ITableColumn[] => {
|
): ITableColumn[] => {
|
||||||
const cellIndex = increment(-1);
|
const cellIndex = increment(-1);
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ export default class GeneralLedgerService {
|
|||||||
*/
|
*/
|
||||||
get defaultQuery() {
|
get defaultQuery() {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
basis: 'cash',
|
basis: 'cash',
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
noCents: false,
|
noCents: false,
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ import { Tenant } from '@/system/models';
|
|||||||
@Service()
|
@Service()
|
||||||
export default class InventoryDetailsService extends FinancialSheet {
|
export default class InventoryDetailsService extends FinancialSheet {
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: TenancyService;
|
private tenancy: TenancyService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
reportRepo: InventoryDetailsRepository;
|
private reportRepo: InventoryDetailsRepository;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
inventoryService: InventoryService;
|
private inventoryService: InventoryService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defaults balance sheet filter query.
|
* Defaults balance sheet filter query.
|
||||||
@@ -30,8 +30,8 @@ export default class InventoryDetailsService extends FinancialSheet {
|
|||||||
*/
|
*/
|
||||||
private get defaultQuery(): IInventoryDetailsQuery {
|
private get defaultQuery(): IInventoryDetailsQuery {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export default class InventoryValuationSheetService {
|
|||||||
*/
|
*/
|
||||||
get defaultQuery(): IInventoryValuationReportQuery {
|
get defaultQuery(): IInventoryValuationReportQuery {
|
||||||
return {
|
return {
|
||||||
asDate: moment().endOf('year').format('YYYY-MM-DD'),
|
asDate: moment().format('YYYY-MM-DD'),
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export default class JournalSheetService {
|
|||||||
*/
|
*/
|
||||||
get defaultQuery() {
|
get defaultQuery() {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
fromRange: null,
|
fromRange: null,
|
||||||
toRange: null,
|
toRange: null,
|
||||||
accountsIds: [],
|
accountsIds: [],
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { IProfitLossSheetQuery } from '@/interfaces';
|
|||||||
*/
|
*/
|
||||||
export const getDefaultPLQuery = (): IProfitLossSheetQuery => ({
|
export const getDefaultPLQuery = (): IProfitLossSheetQuery => ({
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
|
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
divideOn1000: false,
|
divideOn1000: false,
|
||||||
|
|||||||
@@ -12,10 +12,7 @@ import { Tenant } from '@/system/models';
|
|||||||
@Service()
|
@Service()
|
||||||
export default class InventoryValuationReportService {
|
export default class InventoryValuationReportService {
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: TenancyService;
|
private tenancy: TenancyService;
|
||||||
|
|
||||||
@Inject('logger')
|
|
||||||
logger: any;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defaults balance sheet filter query.
|
* Defaults balance sheet filter query.
|
||||||
@@ -23,8 +20,8 @@ export default class InventoryValuationReportService {
|
|||||||
*/
|
*/
|
||||||
get defaultQuery(): IInventoryValuationReportQuery {
|
get defaultQuery(): IInventoryValuationReportQuery {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
@@ -73,9 +70,9 @@ export default class InventoryValuationReportService {
|
|||||||
tenantId: number,
|
tenantId: number,
|
||||||
query: IInventoryValuationReportQuery
|
query: IInventoryValuationReportQuery
|
||||||
): Promise<{
|
): Promise<{
|
||||||
data: IInventoryValuationStatement,
|
data: IInventoryValuationStatement;
|
||||||
query: IInventoryValuationReportQuery,
|
query: IInventoryValuationReportQuery;
|
||||||
meta: IInventoryValuationSheetMeta,
|
meta: IInventoryValuationSheetMeta;
|
||||||
}> {
|
}> {
|
||||||
const { Item, InventoryTransaction } = this.tenancy.models(tenantId);
|
const { Item, InventoryTransaction } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
@@ -87,7 +84,7 @@ export default class InventoryValuationReportService {
|
|||||||
...this.defaultQuery,
|
...this.defaultQuery,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
const inventoryItems = await Item.query().onBuild(q => {
|
const inventoryItems = await Item.query().onBuild((q) => {
|
||||||
q.where('type', 'inventory');
|
q.where('type', 'inventory');
|
||||||
|
|
||||||
if (filter.itemsIds.length > 0) {
|
if (filter.itemsIds.length > 0) {
|
||||||
@@ -106,7 +103,7 @@ export default class InventoryValuationReportService {
|
|||||||
builder.whereIn('itemId', inventoryItemsIds);
|
builder.whereIn('itemId', inventoryItemsIds);
|
||||||
|
|
||||||
// Filter the date range of the sheet.
|
// 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 {
|
get defaultQuery(): ISalesByItemsReportQuery {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ export default class TransactionsByCustomersService
|
|||||||
*/
|
*/
|
||||||
get defaultQuery(): ITransactionsByCustomersFilter {
|
get defaultQuery(): ITransactionsByCustomersFilter {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
divideOn1000: false,
|
divideOn1000: false,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export default class TransactionsByVendorsService
|
|||||||
*/
|
*/
|
||||||
get defaultQuery(): ITransactionsByVendorsFilter {
|
get defaultQuery(): ITransactionsByVendorsFilter {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
precision: 2,
|
precision: 2,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export default class TrialBalanceSheetService extends FinancialSheet {
|
|||||||
get defaultQuery(): ITrialBalanceSheetQuery {
|
get defaultQuery(): ITrialBalanceSheetQuery {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
numberFormat: {
|
numberFormat: {
|
||||||
divideOn1000: false,
|
divideOn1000: false,
|
||||||
negativeFormat: 'mines',
|
negativeFormat: 'mines',
|
||||||
|
|||||||
@@ -9,13 +9,9 @@ import HasTenancyService from '@/services/Tenancy/TenancyService';
|
|||||||
import UnitOfWork from '@/services/UnitOfWork';
|
import UnitOfWork from '@/services/UnitOfWork';
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import { ItemsValidators } from './ItemValidators';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class DeleteItem {
|
export class DeleteItem {
|
||||||
@Inject()
|
|
||||||
private validators: ItemsValidators;
|
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
export default class ItemsCostService {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import Knex from 'knex';
|
import { Knex } from 'knex';
|
||||||
|
import Bluebird from 'bluebird';
|
||||||
import { IVendorCreditAppliedBill } from '@/interfaces';
|
import { IVendorCreditAppliedBill } from '@/interfaces';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import Bluebird from 'bluebird';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class ApplyVendorCreditSyncBills {
|
export default class ApplyVendorCreditSyncBills {
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment bills credited amount.
|
* Increment bills credited amount.
|
||||||
@@ -49,4 +49,4 @@ export default class ApplyVendorCreditSyncBills {
|
|||||||
.findById(vendorCreditAppliedBill.billId)
|
.findById(vendorCreditAppliedBill.billId)
|
||||||
.decrement('creditedAmount', vendorCreditAppliedBill.amount);
|
.decrement('creditedAmount', vendorCreditAppliedBill.amount);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ function APAgingSummaryBodyJSX({
|
|||||||
// #withCurrentOrganization
|
// #withCurrentOrganization
|
||||||
organizationName,
|
organizationName,
|
||||||
}) {
|
}) {
|
||||||
const { isLoading } = useAPAgingSummaryContext();
|
const { isAPAgingLoading } = useAPAgingSummaryContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FinancialReportBody>
|
<FinancialReportBody>
|
||||||
{isLoading ? (
|
{isAPAgingLoading ? (
|
||||||
<FinancialSheetSkeleton />
|
<FinancialSheetSkeleton />
|
||||||
) : (
|
) : (
|
||||||
<APAgingSummaryTable organizationName={organizationName} />
|
<APAgingSummaryTable organizationName={organizationName} />
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default function APAgingSummaryTable({
|
|||||||
}) {
|
}) {
|
||||||
// AP aging summary report content.
|
// AP aging summary report content.
|
||||||
const {
|
const {
|
||||||
APAgingSummary: { tableRows },
|
APAgingSummary: { table, query },
|
||||||
isAPAgingLoading,
|
isAPAgingLoading,
|
||||||
} = useAPAgingSummaryContext();
|
} = useAPAgingSummaryContext();
|
||||||
|
|
||||||
@@ -31,12 +31,12 @@ export default function APAgingSummaryTable({
|
|||||||
<FinancialSheet
|
<FinancialSheet
|
||||||
companyName={organizationName}
|
companyName={organizationName}
|
||||||
sheetType={intl.get('payable_aging_summary')}
|
sheetType={intl.get('payable_aging_summary')}
|
||||||
asDate={new Date()}
|
asDate={query.as_date}
|
||||||
loading={isAPAgingLoading}
|
loading={isAPAgingLoading}
|
||||||
>
|
>
|
||||||
<APAgingSummaryDataTable
|
<APAgingSummaryDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={tableRows}
|
data={table.rows}
|
||||||
rowClassNames={tableRowTypesToClassnames}
|
rowClassNames={tableRowTypesToClassnames}
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
sticky={true}
|
sticky={true}
|
||||||
@@ -54,6 +54,24 @@ const APAgingSummaryDataTable = styled(ReportDataTable)`
|
|||||||
padding-top: 0.32rem;
|
padding-top: 0.32rem;
|
||||||
padding-bottom: 0.32rem;
|
padding-bottom: 0.32rem;
|
||||||
}
|
}
|
||||||
|
&:not(.no-results) {
|
||||||
|
.td {
|
||||||
|
border-bottom: 0;
|
||||||
|
padding-top: 0.4rem;
|
||||||
|
padding-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
&:not(:first-child) .td {
|
||||||
|
border-top: 1px solid transparent;
|
||||||
|
}
|
||||||
|
&.row_type--total {
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
.td {
|
||||||
|
border-top: 1px solid #bbb;
|
||||||
|
border-bottom: 3px double #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -36,19 +36,23 @@ export const getAPAgingSummaryQuerySchema = () => {
|
|||||||
.required()
|
.required()
|
||||||
.integer()
|
.integer()
|
||||||
.positive()
|
.positive()
|
||||||
.label('agingBeforeDays'),
|
.label('Aging days before')
|
||||||
|
.min(1)
|
||||||
|
.max(500),
|
||||||
agingPeriods: Yup.number()
|
agingPeriods: Yup.number()
|
||||||
.required()
|
.required()
|
||||||
.integer()
|
.integer()
|
||||||
.positive()
|
.positive()
|
||||||
.label('agingPeriods'),
|
.max(12)
|
||||||
|
.min(1)
|
||||||
|
.label('Aging periods'),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the AP aging summary query state.
|
* Parses the AP aging summary query state.
|
||||||
* @param locationQuery
|
* @param locationQuery
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const parseAPAgingSummaryQuery = (locationQuery) => {
|
const parseAPAgingSummaryQuery = (locationQuery) => {
|
||||||
const defaultQuery = getDefaultAPAgingSummaryQuery();
|
const defaultQuery = getDefaultAPAgingSummaryQuery();
|
||||||
|
|||||||
@@ -1,57 +1,20 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import intl from 'react-intl-universal';
|
|
||||||
import { If, FormattedMessage as T } from '@/components';
|
import { If } from '@/components';
|
||||||
import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
|
|
||||||
import { getColumnWidth } from '@/utils';
|
|
||||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||||
|
import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
|
||||||
|
import { agingSummaryDynamicColumns } from '../AgingSummary/dynamicColumns';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve AP aging summary columns.
|
* Retrieve AP aging summary columns.
|
||||||
*/
|
*/
|
||||||
export const useAPAgingSummaryColumns = () => {
|
export const useAPAgingSummaryColumns = () => {
|
||||||
const {
|
const {
|
||||||
APAgingSummary: { tableRows, columns },
|
APAgingSummary: { table },
|
||||||
} = useAPAgingSummaryContext();
|
} = useAPAgingSummaryContext();
|
||||||
|
|
||||||
const agingColumns = React.useMemo(() => {
|
return agingSummaryDynamicColumns(table.columns, table.rows);
|
||||||
return columns.map(
|
|
||||||
(agingColumn) =>
|
|
||||||
`${agingColumn.before_days} - ${
|
|
||||||
agingColumn.to_days || intl.get('and_over')
|
|
||||||
}`,
|
|
||||||
);
|
|
||||||
}, [columns]);
|
|
||||||
|
|
||||||
return useMemo(
|
|
||||||
() => [
|
|
||||||
{
|
|
||||||
Header: <T id={'vendor_name'} />,
|
|
||||||
accessor: 'name',
|
|
||||||
className: 'vendor_name',
|
|
||||||
width: 240,
|
|
||||||
sticky: 'left',
|
|
||||||
textOverview: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Header: <T id={'current'} />,
|
|
||||||
accessor: 'current',
|
|
||||||
className: 'current',
|
|
||||||
width: getColumnWidth(tableRows, `current`, { minWidth: 120 }),
|
|
||||||
},
|
|
||||||
...agingColumns.map((agingColumn, index) => ({
|
|
||||||
Header: agingColumn,
|
|
||||||
accessor: `aging-${index}`,
|
|
||||||
width: getColumnWidth(tableRows, `aging-${index}`, { minWidth: 120 }),
|
|
||||||
})),
|
|
||||||
{
|
|
||||||
Header: <T id={'total'} />,
|
|
||||||
accessor: 'total',
|
|
||||||
width: getColumnWidth(tableRows, 'total', { minWidth: 120 }),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[tableRows, agingColumns],
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ const ARAgingSummaryContext = createContext();
|
|||||||
*/
|
*/
|
||||||
function ARAgingSummaryProvider({ filter, ...props }) {
|
function ARAgingSummaryProvider({ filter, ...props }) {
|
||||||
// Transformes the filter from to the url query.
|
// Transformes the filter from to the url query.
|
||||||
const query = useMemo(() => transformFilterFormToQuery(filter), [filter]);
|
const requestQuery = useMemo(
|
||||||
|
() => transformFilterFormToQuery(filter),
|
||||||
|
[filter],
|
||||||
|
);
|
||||||
|
|
||||||
// A/R aging summary sheet context.
|
// A/R aging summary sheet context.
|
||||||
const {
|
const {
|
||||||
@@ -19,11 +22,10 @@ function ARAgingSummaryProvider({ filter, ...props }) {
|
|||||||
isLoading: isARAgingLoading,
|
isLoading: isARAgingLoading,
|
||||||
isFetching: isARAgingFetching,
|
isFetching: isARAgingFetching,
|
||||||
refetch,
|
refetch,
|
||||||
} = useARAgingSummaryReport(query, { keepPreviousData: true });
|
} = useARAgingSummaryReport(requestQuery, { keepPreviousData: true });
|
||||||
|
|
||||||
const provider = {
|
const provider = {
|
||||||
ARAgingSummary,
|
ARAgingSummary,
|
||||||
|
|
||||||
isARAgingLoading,
|
isARAgingLoading,
|
||||||
isARAgingFetching,
|
isARAgingFetching,
|
||||||
refetch,
|
refetch,
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ export default function ReceivableAgingSummaryTable({
|
|||||||
organizationName,
|
organizationName,
|
||||||
}) {
|
}) {
|
||||||
// AR aging summary report context.
|
// AR aging summary report context.
|
||||||
const { ARAgingSummary, isARAgingLoading } = useARAgingSummaryContext();
|
const {
|
||||||
|
ARAgingSummary: { table, query },
|
||||||
|
isARAgingLoading,
|
||||||
|
} = useARAgingSummaryContext();
|
||||||
|
|
||||||
// AR aging summary columns.
|
// AR aging summary columns.
|
||||||
const columns = useARAgingSummaryColumns();
|
const columns = useARAgingSummaryColumns();
|
||||||
@@ -28,12 +31,12 @@ export default function ReceivableAgingSummaryTable({
|
|||||||
<FinancialSheet
|
<FinancialSheet
|
||||||
companyName={organizationName}
|
companyName={organizationName}
|
||||||
sheetType={intl.get('receivable_aging_summary')}
|
sheetType={intl.get('receivable_aging_summary')}
|
||||||
asDate={new Date()}
|
asDate={query.as_date}
|
||||||
loading={isARAgingLoading}
|
loading={isARAgingLoading}
|
||||||
>
|
>
|
||||||
<ARAgingSummaryDataTable
|
<ARAgingSummaryDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={ARAgingSummary.tableRows}
|
data={table.rows}
|
||||||
rowClassNames={tableRowTypesToClassnames}
|
rowClassNames={tableRowTypesToClassnames}
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
sticky={true}
|
sticky={true}
|
||||||
|
|||||||
@@ -35,12 +35,16 @@ export const getARAgingSummaryQuerySchema = () => {
|
|||||||
.required()
|
.required()
|
||||||
.integer()
|
.integer()
|
||||||
.positive()
|
.positive()
|
||||||
.label('agingDaysBefore'),
|
.label('Aging days before')
|
||||||
|
.min(1)
|
||||||
|
.max(500),
|
||||||
agingPeriods: Yup.number()
|
agingPeriods: Yup.number()
|
||||||
.required()
|
.required()
|
||||||
.integer()
|
.integer()
|
||||||
.positive()
|
.positive()
|
||||||
.label('agingPeriods'),
|
.max(12)
|
||||||
|
.min(1)
|
||||||
|
.label('Aging periods'),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,71 +1,20 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import intl from 'react-intl-universal';
|
|
||||||
|
|
||||||
import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
|
import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
|
||||||
import { If, FormattedMessage as T } from '@/components';
|
import { If, FormattedMessage as T } from '@/components';
|
||||||
import { getColumnWidth } from '@/utils';
|
|
||||||
import { Align } from '@/constants';
|
|
||||||
|
|
||||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||||
|
import { agingSummaryDynamicColumns } from '../AgingSummary/dynamicColumns';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve AR aging summary columns.
|
* Retrieve AR aging summary columns.
|
||||||
*/
|
*/
|
||||||
export const useARAgingSummaryColumns = () => {
|
export const useARAgingSummaryColumns = () => {
|
||||||
const {
|
const {
|
||||||
ARAgingSummary: { tableRows, columns },
|
ARAgingSummary: { table },
|
||||||
} = useARAgingSummaryContext();
|
} = useARAgingSummaryContext();
|
||||||
|
|
||||||
const agingColumns = React.useMemo(() => {
|
return agingSummaryDynamicColumns(table.columns, table.rows);
|
||||||
return columns.map(
|
|
||||||
(agingColumn) =>
|
|
||||||
`${agingColumn.before_days} - ${
|
|
||||||
agingColumn.to_days || intl.get('and_over')
|
|
||||||
}`,
|
|
||||||
);
|
|
||||||
}, [columns]);
|
|
||||||
|
|
||||||
return React.useMemo(
|
|
||||||
() => [
|
|
||||||
{
|
|
||||||
Header: <T id={'customer_name'} />,
|
|
||||||
accessor: 'name',
|
|
||||||
className: 'customer_name',
|
|
||||||
sticky: 'left',
|
|
||||||
width: 240,
|
|
||||||
textOverview: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Header: <T id={'current'} />,
|
|
||||||
accessor: 'current',
|
|
||||||
className: 'current',
|
|
||||||
width: getColumnWidth(tableRows, `current`, {
|
|
||||||
minWidth: 120,
|
|
||||||
}),
|
|
||||||
align: Align.Right
|
|
||||||
},
|
|
||||||
...agingColumns.map((agingColumn, index) => ({
|
|
||||||
Header: agingColumn,
|
|
||||||
accessor: `aging-${index}`,
|
|
||||||
width: getColumnWidth(tableRows, `aging-${index}`, {
|
|
||||||
minWidth: 120,
|
|
||||||
}),
|
|
||||||
align: Align.Right
|
|
||||||
})),
|
|
||||||
{
|
|
||||||
Header: <T id={'total'} />,
|
|
||||||
id: 'total',
|
|
||||||
accessor: 'total',
|
|
||||||
className: 'total',
|
|
||||||
width: getColumnWidth(tableRows, 'total', {
|
|
||||||
minWidth: 120,
|
|
||||||
}),
|
|
||||||
align: Align.Right
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[tableRows, agingColumns],
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import { getColumnWidth } from '@/utils';
|
||||||
|
import { Align } from '@/constants';
|
||||||
|
|
||||||
|
const getTableCellValueAccessor = (index) => `cells[${index}].value`;
|
||||||
|
|
||||||
|
const contactNameAccessor = R.curry((data, column) => ({
|
||||||
|
key: column.key,
|
||||||
|
Header: column.label,
|
||||||
|
accessor: getTableCellValueAccessor(column.cell_index),
|
||||||
|
sticky: 'left',
|
||||||
|
width: 240,
|
||||||
|
textOverview: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const currentAccessor = R.curry((data, column) => {
|
||||||
|
const accessor = getTableCellValueAccessor(column.cell_index);
|
||||||
|
|
||||||
|
return {
|
||||||
|
key: column.key,
|
||||||
|
Header: column.label,
|
||||||
|
accessor,
|
||||||
|
className: column.id,
|
||||||
|
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
||||||
|
align: Align.Right,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalAccessor = R.curry((data, column) => {
|
||||||
|
const accessor = getTableCellValueAccessor(column.cell_index);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Header: column.label,
|
||||||
|
id: column.key,
|
||||||
|
accessor: getTableCellValueAccessor(column.cell_index),
|
||||||
|
className: column.key,
|
||||||
|
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
||||||
|
align: Align.Right,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const agingPeriodAccessor = R.curry((data, column) => {
|
||||||
|
const accessor = getTableCellValueAccessor(column.cell_index);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Header: column.label,
|
||||||
|
id: `${column.key}-${column.cell_index}`,
|
||||||
|
accessor,
|
||||||
|
className: column.key,
|
||||||
|
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
||||||
|
align: Align.Right,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const dynamicColumnMapper = R.curry((data, column) => {
|
||||||
|
const totalAccessorColumn = totalAccessor(data);
|
||||||
|
const currentAccessorColumn = currentAccessor(data);
|
||||||
|
const customerNameAccessorColumn = contactNameAccessor(data);
|
||||||
|
const agingPeriodAccessorColumn = agingPeriodAccessor(data);
|
||||||
|
|
||||||
|
return R.compose(
|
||||||
|
R.when(R.pathEq(['key'], 'total'), totalAccessorColumn),
|
||||||
|
R.when(R.pathEq(['key'], 'current'), currentAccessorColumn),
|
||||||
|
R.when(R.pathEq(['key'], 'customer_name'), customerNameAccessorColumn),
|
||||||
|
R.when(R.pathEq(['key'], 'vendor_name'), customerNameAccessorColumn),
|
||||||
|
R.when(R.pathEq(['key'], 'aging_period'), agingPeriodAccessorColumn),
|
||||||
|
)(column);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const agingSummaryDynamicColumns = (columns, data) => {
|
||||||
|
return R.map(dynamicColumnMapper(data), columns);
|
||||||
|
};
|
||||||
@@ -15,7 +15,7 @@ import { useAppQueryString } from '@/hooks';
|
|||||||
*/
|
*/
|
||||||
export const getDefaultBalanceSheetQuery = () => ({
|
export const getDefaultBalanceSheetQuery = () => ({
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
basis: 'cash',
|
basis: 'cash',
|
||||||
displayColumnsType: 'total',
|
displayColumnsType: 'total',
|
||||||
filterByOption: 'without-zero-balance',
|
filterByOption: 'without-zero-balance',
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { useAppQueryString } from '@/hooks';
|
|||||||
export const getDefaultCashFlowSheetQuery = () => {
|
export const getDefaultCashFlowSheetQuery = () => {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
basis: 'cash',
|
basis: 'cash',
|
||||||
displayColumnsType: 'total',
|
displayColumnsType: 'total',
|
||||||
filterByOption: 'with-transactions',
|
filterByOption: 'with-transactions',
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function CustomersBalanceSummaryTable({
|
|||||||
companyName,
|
companyName,
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
CustomerBalanceSummary: { table },
|
CustomerBalanceSummary: { table, query },
|
||||||
} = useCustomersBalanceSummaryContext();
|
} = useCustomersBalanceSummaryContext();
|
||||||
|
|
||||||
// Retrieves the customers summary columns.
|
// Retrieves the customers summary columns.
|
||||||
@@ -28,7 +28,7 @@ export default function CustomersBalanceSummaryTable({
|
|||||||
<FinancialSheet
|
<FinancialSheet
|
||||||
companyName={companyName}
|
companyName={companyName}
|
||||||
sheetType={intl.get('customers_balance_summary')}
|
sheetType={intl.get('customers_balance_summary')}
|
||||||
asDate={new Date()}
|
asDate={query.as_date}
|
||||||
>
|
>
|
||||||
<CustomerBalanceDataTable
|
<CustomerBalanceDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { CustomersTransactionsBody } from './CustomersTransactionsBody';
|
|||||||
import { CustomersTransactionsProvider } from './CustomersTransactionsProvider';
|
import { CustomersTransactionsProvider } from './CustomersTransactionsProvider';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
import { useCustomersTransactionsQuery } from './_utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customers transactions.
|
* Customers transactions.
|
||||||
@@ -22,11 +23,7 @@ function CustomersTransactions({
|
|||||||
toggleCustomersTransactionsFilterDrawer,
|
toggleCustomersTransactionsFilterDrawer,
|
||||||
}) {
|
}) {
|
||||||
// filter
|
// filter
|
||||||
const [filter, setFilter] = useState({
|
const [filter, setFilter] = useCustomersTransactionsQuery();
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
|
||||||
filterByOption: 'with-transactions',
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleFilterSubmit = (filter) => {
|
const handleFilterSubmit = (filter) => {
|
||||||
const _filter = {
|
const _filter = {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function CustomersTransactionsProvider({ filter, ...props }) {
|
|||||||
filter,
|
filter,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// fetches the customers transactions.
|
// Fetches the customers transactions.
|
||||||
const {
|
const {
|
||||||
data: customersTransactions,
|
data: customersTransactions,
|
||||||
isFetching: isCustomersTransactionsFetching,
|
isFetching: isCustomersTransactionsFetching,
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
// @ts-nocheck
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { transformToForm } from '@/utils';
|
||||||
|
import { castArray } from 'lodash';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { useAppQueryString } from '@/hooks';
|
||||||
|
|
||||||
export const getCustomersTransactionsQuerySchema = () => {
|
export const getCustomersTransactionsQuerySchema = () => {
|
||||||
return Yup.object().shape({
|
return Yup.object().shape({
|
||||||
@@ -13,7 +18,31 @@ export const getCustomersTransactionsQuerySchema = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getCustomersTransactionsDefaultQuery = () => ({
|
export const getCustomersTransactionsDefaultQuery = () => ({
|
||||||
fromDate: moment().toDate(),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().toDate(),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
customersIds: [],
|
customersIds: [],
|
||||||
|
filterByOption: 'with-transactions',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const parseCustomersTransactionsQuery = (query) => {
|
||||||
|
const defaultQuery = getCustomersTransactionsDefaultQuery();
|
||||||
|
|
||||||
|
const transformedQuery = {
|
||||||
|
...defaultQuery,
|
||||||
|
...transformToForm(query, defaultQuery),
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
...transformedQuery,
|
||||||
|
customersIds: castArray(transformedQuery.customersIds),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useCustomersTransactionsQuery = () => {
|
||||||
|
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||||
|
|
||||||
|
const query = useMemo(
|
||||||
|
() => parseCustomersTransactionsQuery(locationQuery),
|
||||||
|
[locationQuery],
|
||||||
|
);
|
||||||
|
return [query, setLocationQuery];
|
||||||
|
};
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ export const filterAccountsOptions = [
|
|||||||
* Retrieves the default general ledger query.
|
* Retrieves the default general ledger query.
|
||||||
*/
|
*/
|
||||||
export const getDefaultGeneralLedgerQuery = () => ({
|
export const getDefaultGeneralLedgerQuery = () => ({
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
basis: 'accrual',
|
basis: 'accrual',
|
||||||
filterByOption: 'with-transactions',
|
filterByOption: 'with-transactions',
|
||||||
branchesIds: [],
|
branchesIds: [],
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ export function InventoryItemDetailsTable({
|
|||||||
companyName={companyName}
|
companyName={companyName}
|
||||||
sheetType={intl.get('inventory_item_details')}
|
sheetType={intl.get('inventory_item_details')}
|
||||||
loading={isInventoryItemDetailsLoading}
|
loading={isInventoryItemDetailsLoading}
|
||||||
fromDate={query.from_date}
|
fromDate={query.fromDate}
|
||||||
toDate={query.to_date}
|
toDate={query.toDate}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
>
|
>
|
||||||
<InventoryItemDetailsDataTable
|
<InventoryItemDetailsDataTable
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ const numericColumn = R.curry((data, index, column) => ({
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/**
|
|
||||||
* columns mapper.
|
|
||||||
*/
|
|
||||||
const columnsMapper = R.curry((data, index, column) => ({
|
const columnsMapper = R.curry((data, index, column) => ({
|
||||||
id: column.key,
|
id: column.key,
|
||||||
key: column.key,
|
key: column.key,
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import { transformToForm } from '@/utils';
|
|||||||
* Retrieves inventory item details default query.
|
* Retrieves inventory item details default query.
|
||||||
*/
|
*/
|
||||||
export const getInventoryItemDetailsDefaultQuery = () => ({
|
export const getInventoryItemDetailsDefaultQuery = () => ({
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
warehousesIds: [],
|
warehousesIds: [],
|
||||||
branchesIds: [],
|
branchesIds: [],
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function InventoryValuationTable({
|
|||||||
}) {
|
}) {
|
||||||
// inventory valuation context.
|
// inventory valuation context.
|
||||||
const {
|
const {
|
||||||
inventoryValuation: { tableRows },
|
inventoryValuation: { tableRows, query },
|
||||||
isLoading,
|
isLoading,
|
||||||
} = useInventoryValuationContext();
|
} = useInventoryValuationContext();
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ export default function InventoryValuationTable({
|
|||||||
<InventoryValuationSheet
|
<InventoryValuationSheet
|
||||||
companyName={companyName}
|
companyName={companyName}
|
||||||
sheetType={intl.get('inventory_valuation')}
|
sheetType={intl.get('inventory_valuation')}
|
||||||
asDate={new Date()}
|
asDate={query.as_date}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
>
|
>
|
||||||
<InventoryValuationDataTable
|
<InventoryValuationDataTable
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const getInventoryValuationQuerySchema = () => {
|
|||||||
* Retrieves the inventory valuation sheet default query.
|
* Retrieves the inventory valuation sheet default query.
|
||||||
*/
|
*/
|
||||||
export const getInventoryValuationQuery = () => ({
|
export const getInventoryValuationQuery = () => ({
|
||||||
asDate: moment().endOf('day').format('YYYY-MM-DD'),
|
asDate: moment().format('YYYY-MM-DD'),
|
||||||
filterByOption: 'with-transactions',
|
filterByOption: 'with-transactions',
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
branchesIds: [],
|
branchesIds: [],
|
||||||
|
|||||||
@@ -11,17 +11,16 @@ import { transformToForm } from '@/utils';
|
|||||||
*/
|
*/
|
||||||
export const getDefaultJournalQuery = () => {
|
export const getDefaultJournalQuery = () => {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
basis: 'accrual',
|
basis: 'accrual',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses balance sheet query.
|
* Parses balance sheet query.
|
||||||
*/
|
*/
|
||||||
const parseJournalQuery = (locationQuery) => {
|
const parseJournalQuery = (locationQuery) => {
|
||||||
const defaultQuery = getDefaultJournalQuery();
|
const defaultQuery = getDefaultJournalQuery();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default function ProfitLossSheetTable({
|
|||||||
} = useProfitLossSheetContext();
|
} = useProfitLossSheetContext();
|
||||||
|
|
||||||
// Retrieves the profit/loss table columns.
|
// Retrieves the profit/loss table columns.
|
||||||
const tableColumns = useProfitLossSheetColumns();
|
const columns = useProfitLossSheetColumns();
|
||||||
|
|
||||||
// Retrieve default expanded rows of balance sheet.
|
// Retrieve default expanded rows of balance sheet.
|
||||||
const expandedRows = React.useMemo(
|
const expandedRows = React.useMemo(
|
||||||
@@ -40,7 +40,7 @@ export default function ProfitLossSheetTable({
|
|||||||
basis={query.basis}
|
basis={query.basis}
|
||||||
>
|
>
|
||||||
<ProfitLossDataTable
|
<ProfitLossDataTable
|
||||||
columns={tableColumns}
|
columns={columns}
|
||||||
data={table.rows}
|
data={table.rows}
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
expanded={expandedRows}
|
expanded={expandedRows}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { castArray } from 'lodash';
|
|||||||
export const getDefaultProfitLossQuery = () => ({
|
export const getDefaultProfitLossQuery = () => ({
|
||||||
basis: 'cash',
|
basis: 'cash',
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
displayColumnsType: 'total',
|
displayColumnsType: 'total',
|
||||||
filterByOption: 'with-transactions',
|
filterByOption: 'with-transactions',
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import { castArray } from 'lodash';
|
|||||||
* Retrieves the purchases by items query.
|
* Retrieves the purchases by items query.
|
||||||
*/
|
*/
|
||||||
export const getDefaultPurchasesByItemsQuery = () => ({
|
export const getDefaultPurchasesByItemsQuery = () => ({
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
filterByOption: 'with-transactions',
|
filterByOption: 'with-transactions',
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export const getSalesByItemsQueryShema = () => {
|
|||||||
* Retrieves the default query.
|
* Retrieves the default query.
|
||||||
*/
|
*/
|
||||||
export const getDefaultSalesByItemsQuery = () => ({
|
export const getDefaultSalesByItemsQuery = () => ({
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
filterByOption: 'with-transactions',
|
filterByOption: 'with-transactions',
|
||||||
itemsIds: [],
|
itemsIds: [],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { transformToForm } from '@/utils';
|
|||||||
export function getDefaultTrialBalanceQuery() {
|
export function getDefaultTrialBalanceQuery() {
|
||||||
return {
|
return {
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
basis: 'accrual',
|
basis: 'accrual',
|
||||||
filterByOption: 'with-transactions',
|
filterByOption: 'with-transactions',
|
||||||
branchesIds: [],
|
branchesIds: [],
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { tableRowTypesToClassnames } from '@/utils';
|
|||||||
import { useVendorsBalanceColumns } from './components';
|
import { useVendorsBalanceColumns } from './components';
|
||||||
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
|
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vendors balance summary table.
|
* Vendors balance summary table.
|
||||||
*/
|
*/
|
||||||
@@ -18,7 +17,7 @@ export default function VendorsBalanceSummaryTable({
|
|||||||
organizationName,
|
organizationName,
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
VendorBalanceSummary: { table },
|
VendorBalanceSummary: { table, query },
|
||||||
} = useVendorsBalanceSummaryContext();
|
} = useVendorsBalanceSummaryContext();
|
||||||
|
|
||||||
// vendors balance summary columns.
|
// vendors balance summary columns.
|
||||||
@@ -28,7 +27,7 @@ export default function VendorsBalanceSummaryTable({
|
|||||||
<VendorBalanceFinancialSheet
|
<VendorBalanceFinancialSheet
|
||||||
companyName={organizationName}
|
companyName={organizationName}
|
||||||
sheetType={intl.get('vendors_balance_summary')}
|
sheetType={intl.get('vendors_balance_summary')}
|
||||||
asDate={new Date()}
|
asDate={query.as_date}
|
||||||
>
|
>
|
||||||
<VendorBalanceDataTable
|
<VendorBalanceDataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import VendorsTransactionsActionsBar from './VendorsTransactionsActionsBar';
|
|||||||
import withVendorsTransactionsActions from './withVendorsTransactionsActions';
|
import withVendorsTransactionsActions from './withVendorsTransactionsActions';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
import { useVendorsTransactionsQuery } from './_utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vendors transactions.
|
* Vendors transactions.
|
||||||
@@ -22,11 +23,7 @@ function VendorsTransactions({
|
|||||||
toggleVendorsTransactionsFilterDrawer,
|
toggleVendorsTransactionsFilterDrawer,
|
||||||
}) {
|
}) {
|
||||||
// filter
|
// filter
|
||||||
const [filter, setFilter] = useState({
|
const [filter, setFilter] = useVendorsTransactionsQuery();
|
||||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
|
||||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
|
||||||
filterByOption: 'with-transactions',
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleFilterSubmit = (filter) => {
|
const handleFilterSubmit = (filter) => {
|
||||||
const _filter = {
|
const _filter = {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
// @ts-nocheck
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { transformToForm } from '@/utils';
|
||||||
|
import { useAppQueryString } from '@/hooks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The validation schema of vendors transactions.
|
* The validation schema of vendors transactions.
|
||||||
@@ -19,7 +23,35 @@ export const getVendorTransactionsQuerySchema = () => {
|
|||||||
* Retrieves the default query of vendors transactions.
|
* Retrieves the default query of vendors transactions.
|
||||||
*/
|
*/
|
||||||
export const getVendorsTransactionsDefaultQuery = () => ({
|
export const getVendorsTransactionsDefaultQuery = () => ({
|
||||||
fromDate: moment().toDate(),
|
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||||
toDate: moment().toDate(),
|
toDate: moment().format('YYYY-MM-DD'),
|
||||||
vendorsIds: [],
|
vendorsIds: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the query of vendors transactions.
|
||||||
|
*/
|
||||||
|
const parseVendorsTransactionsQuery = (query) => {
|
||||||
|
const defaultQuery = getVendorsTransactionsDefaultQuery();
|
||||||
|
const transformed = {
|
||||||
|
...defaultQuery,
|
||||||
|
...transformToForm(query, defaultQuery),
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
...transformed,
|
||||||
|
vendorsIds: transformed.vendorsIds ? transformed.vendorsIds : [],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the query of vendors transactions.
|
||||||
|
*/
|
||||||
|
export const useVendorsTransactionsQuery = () => {
|
||||||
|
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||||
|
|
||||||
|
const query = useMemo(
|
||||||
|
() => parseVendorsTransactionsQuery(locationQuery),
|
||||||
|
[locationQuery],
|
||||||
|
);
|
||||||
|
return [query, setLocationQuery];
|
||||||
|
};
|
||||||
|
|||||||
@@ -138,26 +138,12 @@ export function useARAgingSummaryReport(query, props) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
url: '/financial_statements/receivable_aging_summary',
|
url: '/financial_statements/receivable_aging_summary',
|
||||||
params: query,
|
params: query,
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json+table',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
select: (res) => ({
|
select: (res) => res.data,
|
||||||
columns: res.data.columns,
|
|
||||||
data: res.data.data,
|
|
||||||
query: res.data.query,
|
|
||||||
tableRows: ARAgingSummaryTableRowsMapper({
|
|
||||||
customers: res.data.data.customers,
|
|
||||||
total: res.data.data.total,
|
|
||||||
columns: res.data.columns,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
defaultData: {
|
|
||||||
data: {
|
|
||||||
customers: [],
|
|
||||||
total: {},
|
|
||||||
},
|
|
||||||
columns: [],
|
|
||||||
tableRows: [],
|
|
||||||
},
|
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -173,26 +159,12 @@ export function useAPAgingSummaryReport(query, props) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
url: '/financial_statements/payable_aging_summary',
|
url: '/financial_statements/payable_aging_summary',
|
||||||
params: query,
|
params: query,
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json+table',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
select: (res) => ({
|
select: (res) => res.data,
|
||||||
columns: res.data.columns,
|
|
||||||
data: res.data.data,
|
|
||||||
query: res.data.query,
|
|
||||||
tableRows: APAgingSummaryTableRowsMapper({
|
|
||||||
vendors: res.data.data.vendors,
|
|
||||||
total: res.data.data.total,
|
|
||||||
columns: res.data.columns,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
defaultData: {
|
|
||||||
data: {
|
|
||||||
vendors: [],
|
|
||||||
total: {},
|
|
||||||
},
|
|
||||||
columns: [],
|
|
||||||
tableRows: [],
|
|
||||||
},
|
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user