mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-22 07:40:32 +00:00
refactor: reports to nestjs
This commit is contained in:
@@ -8,7 +8,7 @@ import { TransactionsByVendorModule } from './modules/TransactionsByVendor/Trans
|
|||||||
import { TransactionsByCustomerModule } from './modules/TransactionsByCustomer/TransactionsByCustomer.module';
|
import { TransactionsByCustomerModule } from './modules/TransactionsByCustomer/TransactionsByCustomer.module';
|
||||||
import { TransactionsByReferenceModule } from './modules/TransactionsByReference/TransactionByReference.module';
|
import { TransactionsByReferenceModule } from './modules/TransactionsByReference/TransactionByReference.module';
|
||||||
import { ARAgingSummaryModule } from './modules/ARAgingSummary/ARAgingSummary.module';
|
import { ARAgingSummaryModule } from './modules/ARAgingSummary/ARAgingSummary.module';
|
||||||
import { APAgingSummaryModule } from './modules/APAgingSummary/APAgingSummary.module';
|
// import { APAgingSummaryModule } from './modules/APAgingSummary/APAgingSummary.module';
|
||||||
import { InventoryItemDetailsModule } from './modules/InventoryItemDetails/InventoryItemDetails.module';
|
import { InventoryItemDetailsModule } from './modules/InventoryItemDetails/InventoryItemDetails.module';
|
||||||
import { InventoryValuationSheetModule } from './modules/InventoryValuationSheet/InventoryValuationSheet.module';
|
import { InventoryValuationSheetModule } from './modules/InventoryValuationSheet/InventoryValuationSheet.module';
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ import { InventoryValuationSheetModule } from './modules/InventoryValuationSheet
|
|||||||
TransactionsByCustomerModule,
|
TransactionsByCustomerModule,
|
||||||
TransactionsByReferenceModule,
|
TransactionsByReferenceModule,
|
||||||
ARAgingSummaryModule,
|
ARAgingSummaryModule,
|
||||||
APAgingSummaryModule,
|
// APAgingSummaryModule,
|
||||||
InventoryItemDetailsModule,
|
InventoryItemDetailsModule,
|
||||||
InventoryValuationSheetModule,
|
InventoryValuationSheetModule,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ import { APAgingSummaryApplication } from './APAgingSummaryApplication';
|
|||||||
import { IAPAgingSummaryQuery } from './APAgingSummary.types';
|
import { IAPAgingSummaryQuery } from './APAgingSummary.types';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
|
import { ApiOperation } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('reports/payable-aging-summary')
|
@Controller('reports/payable-aging-summary')
|
||||||
export class APAgingSummaryController {
|
export class APAgingSummaryController {
|
||||||
constructor(private readonly APAgingSummaryApp: APAgingSummaryApplication) {}
|
constructor(private readonly APAgingSummaryApp: APAgingSummaryApplication) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
|
@ApiOperation({ summary: 'Get payable aging summary' })
|
||||||
public async get(
|
public async get(
|
||||||
@Query() filter: IAPAgingSummaryQuery,
|
@Query() filter: IAPAgingSummaryQuery,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
|
|||||||
@@ -5,13 +5,16 @@ import { ARAgingSummaryApplication } from './ARAgingSummaryApplication';
|
|||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
||||||
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('reports/receivable-aging-summary')
|
@Controller('reports/receivable-aging-summary')
|
||||||
|
@ApiTags('reports')
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
export class ARAgingSummaryController {
|
export class ARAgingSummaryController {
|
||||||
constructor(private readonly ARAgingSummaryApp: ARAgingSummaryApplication) {}
|
constructor(private readonly ARAgingSummaryApp: ARAgingSummaryApplication) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
|
@ApiOperation({ summary: 'Get receivable aging summary' })
|
||||||
public async get(
|
public async get(
|
||||||
@Query() filter: IARAgingSummaryQuery,
|
@Query() filter: IARAgingSummaryQuery,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ICustomerBalanceSummaryQuery } from './CustomerBalanceSummary.types';
|
|||||||
import { CustomerBalanceSummaryApplication } from './CustomerBalanceSummaryApplication';
|
import { CustomerBalanceSummaryApplication } from './CustomerBalanceSummaryApplication';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { ApiResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('/reports/customer-balance-summary')
|
@Controller('/reports/customer-balance-summary')
|
||||||
@ApiTags('reports')
|
@ApiTags('reports')
|
||||||
@@ -14,6 +14,7 @@ export class CustomerBalanceSummaryController {
|
|||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@ApiResponse({ status: 200, description: 'Customer balance summary report' })
|
@ApiResponse({ status: 200, description: 'Customer balance summary report' })
|
||||||
|
@ApiOperation({ summary: 'Get customer balance summary report' })
|
||||||
async customerBalanceSummary(
|
async customerBalanceSummary(
|
||||||
@Query() filter: ICustomerBalanceSummaryQuery,
|
@Query() filter: ICustomerBalanceSummaryQuery,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { IGeneralLedgerSheetQuery } from './GeneralLedger.types';
|
|||||||
import { GeneralLedgerApplication } from './GeneralLedgerApplication';
|
import { GeneralLedgerApplication } from './GeneralLedgerApplication';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { ApiResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('/reports/general-ledger')
|
@Controller('/reports/general-ledger')
|
||||||
@ApiTags('reports')
|
@ApiTags('reports')
|
||||||
@@ -15,6 +15,7 @@ export class GeneralLedgerController {
|
|||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@ApiResponse({ status: 200, description: 'General ledger report' })
|
@ApiResponse({ status: 200, description: 'General ledger report' })
|
||||||
|
@ApiOperation({ summary: 'Get general ledger report' })
|
||||||
public async getGeneralLedger(
|
public async getGeneralLedger(
|
||||||
@Query() query: IGeneralLedgerSheetQuery,
|
@Query() query: IGeneralLedgerSheetQuery,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
import { Controller, Headers, Query, Res } from '@nestjs/common';
|
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||||
import { InventoryItemDetailsApplication } from './InventoryItemDetailsApplication';
|
import { InventoryItemDetailsApplication } from './InventoryItemDetailsApplication';
|
||||||
import { IInventoryDetailsQuery } from './InventoryItemDetails.types';
|
import { IInventoryDetailsQuery } from './InventoryItemDetails.types';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
|
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
||||||
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('reports/inventory-item-details')
|
@Controller('reports/inventory-item-details')
|
||||||
|
@PublicRoute()
|
||||||
|
@ApiTags('reports')
|
||||||
export class InventoryItemDetailsController {
|
export class InventoryItemDetailsController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly inventoryItemDetailsApp: InventoryItemDetailsApplication,
|
private readonly inventoryItemDetailsApp: InventoryItemDetailsApplication,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@Get('/')
|
||||||
|
@ApiOperation({ summary: 'Get inventory item details' })
|
||||||
async inventoryItemDetails(
|
async inventoryItemDetails(
|
||||||
@Query() query: IInventoryDetailsQuery,
|
@Query() query: IInventoryDetailsQuery,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
|
|||||||
@@ -5,14 +5,23 @@ import { InventoryDetailsService } from './InventoryItemDetails.service';
|
|||||||
import { InventoryDetailsTableInjectable } from './InventoryItemDetailsTableInjectable';
|
import { InventoryDetailsTableInjectable } from './InventoryItemDetailsTableInjectable';
|
||||||
import { InventoryItemDetailsExportInjectable } from './InventoryItemDetailsExportInjectable';
|
import { InventoryItemDetailsExportInjectable } from './InventoryItemDetailsExportInjectable';
|
||||||
import { InventoryItemDetailsApplication } from './InventoryItemDetailsApplication';
|
import { InventoryItemDetailsApplication } from './InventoryItemDetailsApplication';
|
||||||
|
import { InventoryItemDetailsRepository } from './InventoryItemDetailsRepository';
|
||||||
|
import { InventoryDetailsMetaInjectable } from './InventoryItemDetailsMeta';
|
||||||
|
import { FinancialSheetCommonModule } from '../../common/FinancialSheetCommon.module';
|
||||||
|
import { InventoryCostModule } from '@/modules/InventoryCost/InventoryCost.module';
|
||||||
|
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [FinancialSheetCommonModule, InventoryCostModule],
|
||||||
providers: [
|
providers: [
|
||||||
InventoryItemDetailsApplication,
|
InventoryItemDetailsApplication,
|
||||||
InventoryItemDetailsExportInjectable,
|
InventoryItemDetailsExportInjectable,
|
||||||
InventoryDetailsTableInjectable,
|
InventoryDetailsTableInjectable,
|
||||||
InventoryDetailsService,
|
InventoryDetailsService,
|
||||||
InventoryDetailsTablePdf,
|
InventoryDetailsTablePdf,
|
||||||
|
InventoryItemDetailsRepository,
|
||||||
|
InventoryDetailsMetaInjectable,
|
||||||
|
TenancyContext,
|
||||||
],
|
],
|
||||||
controllers: [InventoryItemDetailsController],
|
controllers: [InventoryItemDetailsController],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ export class InventoryDetailsService {
|
|||||||
...getInventoryItemDetailsDefaultQuery(),
|
...getInventoryItemDetailsDefaultQuery(),
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initialize the inventory item details repository.
|
||||||
|
this.inventoryItemDetailsRepository.setFilter(filter);
|
||||||
|
await this.inventoryItemDetailsRepository.asyncInit();
|
||||||
|
|
||||||
// Inventory details report mapper.
|
// Inventory details report mapper.
|
||||||
const inventoryDetailsInstance = new InventoryDetails(
|
const inventoryDetailsInstance = new InventoryDetails(
|
||||||
filter,
|
filter,
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
readonly repository: InventoryItemDetailsRepository;
|
readonly repository: InventoryItemDetailsRepository;
|
||||||
readonly query: IInventoryDetailsQuery;
|
readonly query: IInventoryDetailsQuery;
|
||||||
readonly numberFormat: INumberFormatQuery;
|
readonly numberFormat: INumberFormatQuery;
|
||||||
readonly items: ModelObject<Item>[];
|
|
||||||
readonly i18n: I18nService;
|
readonly i18n: I18nService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,9 +111,9 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
* @param {IInventoryDetailsItemTransaction[]} transactions
|
* @param {IInventoryDetailsItemTransaction[]} transactions
|
||||||
* @returns {IInventoryDetailsItemTransaction[]}
|
* @returns {IInventoryDetailsItemTransaction[]}
|
||||||
*/
|
*/
|
||||||
public mapAccumTransactionsRunningQuantity(
|
public mapAccumTransactionsRunningQuantity = (
|
||||||
transactions: IInventoryDetailsItemTransaction[],
|
transactions: IInventoryDetailsItemTransaction[],
|
||||||
): IInventoryDetailsItemTransaction[] {
|
): IInventoryDetailsItemTransaction[] => {
|
||||||
const initial = this.getNumberMeta(0);
|
const initial = this.getNumberMeta(0);
|
||||||
|
|
||||||
const mapAccumAppender = (a, b) => {
|
const mapAccumAppender = (a, b) => {
|
||||||
@@ -125,20 +124,21 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
return [accum, accum];
|
return [accum, accum];
|
||||||
};
|
};
|
||||||
return R.mapAccum(
|
return R.mapAccum(
|
||||||
|
// @ts-ignore
|
||||||
mapAccumAppender,
|
mapAccumAppender,
|
||||||
{ runningQuantity: initial },
|
{ runningQuantity: initial },
|
||||||
transactions,
|
transactions,
|
||||||
)[1];
|
)[1];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accumulate and mapping running valuation on transactions.
|
* Accumulate and mapping running valuation on transactions.
|
||||||
* @param {IInventoryDetailsItemTransaction[]} transactions
|
* @param {IInventoryDetailsItemTransaction[]} transactions
|
||||||
* @returns {IInventoryDetailsItemTransaction}
|
* @returns {IInventoryDetailsItemTransaction}
|
||||||
*/
|
*/
|
||||||
public mapAccumTransactionsRunningValuation(
|
public mapAccumTransactionsRunningValuation = (
|
||||||
transactions: IInventoryDetailsItemTransaction[],
|
transactions: IInventoryDetailsItemTransaction[],
|
||||||
): IInventoryDetailsItemTransaction[] {
|
): IInventoryDetailsItemTransaction[] => {
|
||||||
const initial = this.getNumberMeta(0);
|
const initial = this.getNumberMeta(0);
|
||||||
|
|
||||||
const mapAccumAppender = (a, b) => {
|
const mapAccumAppender = (a, b) => {
|
||||||
@@ -150,11 +150,12 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
return [accum, accum];
|
return [accum, accum];
|
||||||
};
|
};
|
||||||
return R.mapAccum(
|
return R.mapAccum(
|
||||||
|
// @ts-ignore
|
||||||
mapAccumAppender,
|
mapAccumAppender,
|
||||||
{ runningValuation: initial },
|
{ runningValuation: initial },
|
||||||
transactions,
|
transactions,
|
||||||
)[1];
|
)[1];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the inventory transaction total.
|
* Retrieve the inventory transaction total.
|
||||||
@@ -170,15 +171,13 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mappes the item transaction to inventory item transaction node.
|
* Maps the item transaction to inventory item transaction node.
|
||||||
* @param {IItem} item
|
* @param {IInvetoryTransaction} transaction - The inventory transaction.
|
||||||
* @param {IInvetoryTransaction} transaction
|
|
||||||
* @returns {IInventoryDetailsItemTransaction}
|
* @returns {IInventoryDetailsItemTransaction}
|
||||||
*/
|
*/
|
||||||
public itemTransactionMapper(
|
public itemTransactionMapper = (
|
||||||
item: ModelObject<Item>,
|
|
||||||
transaction: ModelObject<InventoryTransaction>,
|
transaction: ModelObject<InventoryTransaction>,
|
||||||
): IInventoryDetailsItemTransaction {
|
): IInventoryDetailsItemTransaction => {
|
||||||
const total = this.getTransactionTotal(transaction);
|
const total = this.getTransactionTotal(transaction);
|
||||||
const amountMovement = this.adjustAmountMovement(transaction.direction);
|
const amountMovement = this.adjustAmountMovement(transaction.direction);
|
||||||
|
|
||||||
@@ -217,7 +216,7 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
runningQuantity: this.getNumberMeta(0),
|
runningQuantity: this.getNumberMeta(0),
|
||||||
runningValuation: this.getNumberMeta(0),
|
runningValuation: this.getNumberMeta(0),
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the inventory transcations by item id.
|
* Retrieve the inventory transcations by item id.
|
||||||
@@ -228,7 +227,7 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
itemId: number,
|
itemId: number,
|
||||||
): ModelObject<InventoryTransaction>[] {
|
): ModelObject<InventoryTransaction>[] {
|
||||||
return defaultTo(
|
return defaultTo(
|
||||||
this.repository.inventoryTransactionsByItemId.get(itemId),
|
this.repository.inventoryTransactionsByItemId.get(itemId.toString()),
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -240,13 +239,13 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
*/
|
*/
|
||||||
public getItemTransactions(
|
public getItemTransactions(
|
||||||
item: ModelObject<Item>,
|
item: ModelObject<Item>,
|
||||||
): ModelObject<InventoryTransaction>[] {
|
): IInventoryDetailsItemTransaction[] {
|
||||||
const transactions = this.getInventoryTransactionsByItemId(item.id);
|
const transactions = this.getInventoryTransactionsByItemId(item.id);
|
||||||
|
|
||||||
return R.compose(
|
return R.pipe(
|
||||||
this.mapAccumTransactionsRunningQuantity.bind(this),
|
R.map(this.itemTransactionMapper),
|
||||||
this.mapAccumTransactionsRunningValuation.bind(this),
|
this.mapAccumTransactionsRunningValuation,
|
||||||
R.map(R.curry(this.itemTransactionMapper.bind(this))(item)),
|
this.mapAccumTransactionsRunningQuantity,
|
||||||
)(transactions);
|
)(transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,11 +260,11 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
*/
|
*/
|
||||||
public itemTransactionsMapper(
|
public itemTransactionsMapper(
|
||||||
item: ModelObject<Item>,
|
item: ModelObject<Item>,
|
||||||
): (
|
): Array<
|
||||||
| IInventoryDetailsItemTransaction
|
| IInventoryDetailsItemTransaction
|
||||||
| IInventoryDetailsOpening
|
| IInventoryDetailsOpening
|
||||||
| IInventoryDetailsClosing
|
| IInventoryDetailsClosing
|
||||||
)[] {
|
> {
|
||||||
const transactions = this.getItemTransactions(item);
|
const transactions = this.getItemTransactions(item);
|
||||||
const openingValuation = this.getItemOpeingValuation(item);
|
const openingValuation = this.getItemOpeingValuation(item);
|
||||||
const closingValuation = this.getItemClosingValuation(
|
const closingValuation = this.getItemClosingValuation(
|
||||||
@@ -280,7 +279,11 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
R.concat(transactions),
|
R.concat(transactions),
|
||||||
R.when(R.always(isItemHasOpeningBalance), R.prepend(openingValuation)),
|
R.when(R.always(isItemHasOpeningBalance), R.prepend(openingValuation)),
|
||||||
R.when(R.always(hasTransactions), R.append(closingValuation)),
|
R.when(R.always(hasTransactions), R.append(closingValuation)),
|
||||||
)([]);
|
)([]) as Array<
|
||||||
|
| IInventoryDetailsItemTransaction
|
||||||
|
| IInventoryDetailsOpening
|
||||||
|
| IInventoryDetailsClosing
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -300,9 +303,8 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
public getItemOpeingValuation(
|
public getItemOpeingValuation(
|
||||||
item: ModelObject<Item>,
|
item: ModelObject<Item>,
|
||||||
): IInventoryDetailsOpening {
|
): IInventoryDetailsOpening {
|
||||||
const openingBalance = this.repository.openingBalanceTransactionsByItemId.get(
|
const openingBalance =
|
||||||
item.id,
|
this.repository.openingBalanceTransactionsByItemId.get(item.id);
|
||||||
);
|
|
||||||
const quantity = defaultTo(get(openingBalance, 'quantity'), 0);
|
const quantity = defaultTo(get(openingBalance, 'quantity'), 0);
|
||||||
const value = defaultTo(get(openingBalance, 'value'), 0);
|
const value = defaultTo(get(openingBalance, 'value'), 0);
|
||||||
|
|
||||||
@@ -321,9 +323,9 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
*/
|
*/
|
||||||
public getItemClosingValuation(
|
public getItemClosingValuation(
|
||||||
item: ModelObject<Item>,
|
item: ModelObject<Item>,
|
||||||
transactions: ModelObject<InventoryTransaction>[],
|
transactions: IInventoryDetailsItemTransaction[],
|
||||||
openingValuation: IInventoryDetailsOpening,
|
openingValuation: IInventoryDetailsOpening,
|
||||||
): IInventoryDetailsOpening {
|
): IInventoryDetailsClosing {
|
||||||
const value = sumBy(transactions, 'valueMovement.number');
|
const value = sumBy(transactions, 'valueMovement.number');
|
||||||
const quantity = sumBy(transactions, 'quantityMovement.number');
|
const quantity = sumBy(transactions, 'quantityMovement.number');
|
||||||
const profitMargin = sumBy(transactions, 'profitMargin.number');
|
const profitMargin = sumBy(transactions, 'profitMargin.number');
|
||||||
@@ -374,7 +376,9 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
public isItemNodeHasTransactions(item: IInventoryDetailsItem) {
|
public isItemNodeHasTransactions(item: IInventoryDetailsItem) {
|
||||||
return !!this.repository.inventoryTransactionsByItemId.get(item.id);
|
return !!this.repository.inventoryTransactionsByItemId.get(
|
||||||
|
item.id?.toString(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -383,7 +387,9 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
public isFilterNode(item: IInventoryDetailsItem): boolean {
|
public isFilterNode(item: IInventoryDetailsItem): boolean {
|
||||||
|
// @ts-ignore
|
||||||
return R.ifElse(
|
return R.ifElse(
|
||||||
|
// @ts-ignore
|
||||||
R.curry(this.isNodeTypeEquals)(INodeTypes.ITEM),
|
R.curry(this.isNodeTypeEquals)(INodeTypes.ITEM),
|
||||||
this.isItemNodeHasTransactions.bind(this),
|
this.isItemNodeHasTransactions.bind(this),
|
||||||
R.always(true),
|
R.always(true),
|
||||||
@@ -410,6 +416,7 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
* @returns {IInventoryDetailsItem[]}
|
* @returns {IInventoryDetailsItem[]}
|
||||||
*/
|
*/
|
||||||
public itemsNodes(items: ModelObject<Item>[]): IInventoryDetailsItem[] {
|
public itemsNodes(items: ModelObject<Item>[]): IInventoryDetailsItem[] {
|
||||||
|
// @ts-ignore
|
||||||
return R.compose(
|
return R.compose(
|
||||||
this.filterItemsNodes.bind(this),
|
this.filterItemsNodes.bind(this),
|
||||||
R.map(this.itemsNodeMapper.bind(this)),
|
R.map(this.itemsNodeMapper.bind(this)),
|
||||||
@@ -421,6 +428,6 @@ export class InventoryDetails extends FinancialSheet {
|
|||||||
* @returns {IInventoryDetailsData}
|
* @returns {IInventoryDetailsData}
|
||||||
*/
|
*/
|
||||||
public reportData(): IInventoryDetailsData {
|
public reportData(): IInventoryDetailsData {
|
||||||
return this.itemsNodes(this.items);
|
return this.itemsNodes(this.repository.items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export interface IInventoryDetailsOpening {
|
|||||||
export interface IInventoryDetailsClosing
|
export interface IInventoryDetailsClosing
|
||||||
extends Omit<IInventoryDetailsOpening, 'nodeType'> {
|
extends Omit<IInventoryDetailsOpening, 'nodeType'> {
|
||||||
nodeType: 'CLOSING_ENTRY';
|
nodeType: 'CLOSING_ENTRY';
|
||||||
|
profitMargin: IInventoryDetailsNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInventoryDetailsItem {
|
export interface IInventoryDetailsItem {
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ export class InventoryItemDetailsRepository {
|
|||||||
* The opening balance transactions by item id.
|
* The opening balance transactions by item id.
|
||||||
* @param {Map<number, ModelObject<InventoryTransaction>>} openingBalanceTransactionsByItemId - The opening balance transactions by item id.
|
* @param {Map<number, ModelObject<InventoryTransaction>>} openingBalanceTransactionsByItemId - The opening balance transactions by item id.
|
||||||
*/
|
*/
|
||||||
openingBalanceTransactionsByItemId: Map<number, ModelObject<InventoryTransaction>>;
|
openingBalanceTransactionsByItemId: Map<
|
||||||
|
number,
|
||||||
|
ModelObject<InventoryTransaction>
|
||||||
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The inventory transactions.
|
* The inventory transactions.
|
||||||
@@ -46,9 +49,12 @@ export class InventoryItemDetailsRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The inventory transactions by item id.
|
* The inventory transactions by item id.
|
||||||
* @param {Map<number, ModelObject<InventoryTransaction>>} inventoryTransactionsByItemId - The inventory transactions by item id.
|
* @param {Map<string, ModelObject<InventoryTransaction>>} inventoryTransactionsByItemId - The inventory transactions by item id.
|
||||||
*/
|
*/
|
||||||
inventoryTransactionsByItemId: Map<number, ModelObject<InventoryTransaction>[]>;
|
inventoryTransactionsByItemId: Map<
|
||||||
|
string,
|
||||||
|
ModelObject<InventoryTransaction>[]
|
||||||
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The filter.
|
* The filter.
|
||||||
@@ -100,7 +106,7 @@ export class InventoryItemDetailsRepository {
|
|||||||
this.openingBalanceTransactions = openingBalanceTransactions;
|
this.openingBalanceTransactions = openingBalanceTransactions;
|
||||||
this.openingBalanceTransactionsByItemId = transformToMapKeyValue(
|
this.openingBalanceTransactionsByItemId = transformToMapKeyValue(
|
||||||
openingBalanceTransactions,
|
openingBalanceTransactions,
|
||||||
'itemId'
|
'itemId',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +121,7 @@ export class InventoryItemDetailsRepository {
|
|||||||
this.inventoryTransactions = inventoryTransactions;
|
this.inventoryTransactions = inventoryTransactions;
|
||||||
this.inventoryTransactionsByItemId = transformToMapBy(
|
this.inventoryTransactionsByItemId = transformToMapBy(
|
||||||
inventoryTransactions,
|
inventoryTransactions,
|
||||||
'itemId'
|
'itemId',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,12 @@ import {
|
|||||||
import { I18nService } from 'nestjs-i18n';
|
import { I18nService } from 'nestjs-i18n';
|
||||||
import { IInventoryDetailsData } from './InventoryItemDetails.types';
|
import { IInventoryDetailsData } from './InventoryItemDetails.types';
|
||||||
import { tableRowMapper } from '../../utils/Table.utils';
|
import { tableRowMapper } from '../../utils/Table.utils';
|
||||||
import { ITableColumn, ITableRow } from '../../types/Table.types';
|
import {
|
||||||
import mapValuesDeep from 'deepdash/es/mapValuesDeep';
|
IColumnMapperMeta,
|
||||||
|
ITableColumn,
|
||||||
|
ITableRow,
|
||||||
|
} from '../../types/Table.types';
|
||||||
|
import { mapValuesDeep } from '@/utils/deepdash';
|
||||||
|
|
||||||
enum IROW_TYPE {
|
enum IROW_TYPE {
|
||||||
ITEM = 'ITEM',
|
ITEM = 'ITEM',
|
||||||
@@ -53,7 +57,7 @@ export class InventoryItemDetailsTable {
|
|||||||
* @returns {ITableRow}
|
* @returns {ITableRow}
|
||||||
*/
|
*/
|
||||||
private itemTransactionNodeMapper = (
|
private itemTransactionNodeMapper = (
|
||||||
transaction: IInventoryDetailsItemTransaction
|
transaction: IInventoryDetailsItemTransaction,
|
||||||
) => {
|
) => {
|
||||||
const columns = [
|
const columns = [
|
||||||
{ key: 'date', accessor: 'date.formattedDate' },
|
{ key: 'date', accessor: 'date.formattedDate' },
|
||||||
@@ -84,15 +88,15 @@ export class InventoryItemDetailsTable {
|
|||||||
* @returns {ITableRow}
|
* @returns {ITableRow}
|
||||||
*/
|
*/
|
||||||
private openingNodeMapper = (
|
private openingNodeMapper = (
|
||||||
transaction: IInventoryDetailsOpening
|
transaction: IInventoryDetailsOpening,
|
||||||
): ITableRow => {
|
): ITableRow => {
|
||||||
const columns = [
|
const columns: Array<IColumnMapperMeta> = [
|
||||||
{ key: 'date', accessor: 'date.formattedDate' },
|
{ key: 'date', accessor: 'date.formattedDate' },
|
||||||
{ key: 'closing', value: this.i18n.t('Opening balance') },
|
{ key: 'closing', value: this.i18n.t('Opening balance') },
|
||||||
{ key: 'empty' },
|
{ key: 'empty', value: '' },
|
||||||
{ key: 'quantity', accessor: 'quantity.formattedNumber' },
|
{ key: 'quantity', accessor: 'quantity.formattedNumber' },
|
||||||
{ key: 'empty' },
|
{ key: 'empty', value: '' },
|
||||||
{ key: 'empty' },
|
{ key: 'empty', value: '' },
|
||||||
{ key: 'value', accessor: 'value.formattedNumber' },
|
{ key: 'value', accessor: 'value.formattedNumber' },
|
||||||
];
|
];
|
||||||
return tableRowMapper(transaction, columns, {
|
return tableRowMapper(transaction, columns, {
|
||||||
@@ -106,19 +110,18 @@ export class InventoryItemDetailsTable {
|
|||||||
* @returns {ITableRow}
|
* @returns {ITableRow}
|
||||||
*/
|
*/
|
||||||
private closingNodeMapper = (
|
private closingNodeMapper = (
|
||||||
transaction: IInventoryDetailsClosing
|
transaction: IInventoryDetailsClosing,
|
||||||
): ITableRow => {
|
): ITableRow => {
|
||||||
const columns = [
|
const columns: Array<IColumnMapperMeta> = [
|
||||||
{ key: 'date', accessor: 'date.formattedDate' },
|
{ key: 'date', accessor: 'date.formattedDate' },
|
||||||
{ key: 'closing', value: this.i18n.t('Closing balance') },
|
{ key: 'closing', value: this.i18n.t('Closing balance') },
|
||||||
{ key: 'empty' },
|
{ key: 'empty', value: '' },
|
||||||
{ key: 'quantity', accessor: 'quantity.formattedNumber' },
|
{ key: 'quantity', accessor: 'quantity.formattedNumber' },
|
||||||
{ key: 'empty' },
|
{ key: 'empty', value: '' },
|
||||||
{ key: 'empty' },
|
{ key: 'empty', value: '' },
|
||||||
{ key: 'value', accessor: 'value.formattedNumber' },
|
{ key: 'value', accessor: 'value.formattedNumber' },
|
||||||
{ key: 'profitMargin', accessor: 'profitMargin.formattedNumber' },
|
{ key: 'profitMargin', accessor: 'profitMargin.formattedNumber' },
|
||||||
];
|
];
|
||||||
|
|
||||||
return tableRowMapper(transaction, columns, {
|
return tableRowMapper(transaction, columns, {
|
||||||
rowTypes: [IROW_TYPE.CLOSING_ENTRY],
|
rowTypes: [IROW_TYPE.CLOSING_ENTRY],
|
||||||
});
|
});
|
||||||
@@ -132,7 +135,7 @@ export class InventoryItemDetailsTable {
|
|||||||
*/
|
*/
|
||||||
private isNodeTypeEquals = (
|
private isNodeTypeEquals = (
|
||||||
type: string,
|
type: string,
|
||||||
node: IInventoryDetailsNode
|
node: IInventoryDetailsNode,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
return node.nodeType === type;
|
return node.nodeType === type;
|
||||||
};
|
};
|
||||||
@@ -143,20 +146,23 @@ export class InventoryItemDetailsTable {
|
|||||||
* @return {ITableRow}
|
* @return {ITableRow}
|
||||||
*/
|
*/
|
||||||
private itemMapper = (node: IInventoryDetailsNode): ITableRow => {
|
private itemMapper = (node: IInventoryDetailsNode): ITableRow => {
|
||||||
|
// @ts-ignore
|
||||||
return R.compose(
|
return R.compose(
|
||||||
R.when(
|
R.when(
|
||||||
|
// @ts-ignore
|
||||||
R.curry(this.isNodeTypeEquals)('OPENING_ENTRY'),
|
R.curry(this.isNodeTypeEquals)('OPENING_ENTRY'),
|
||||||
this.openingNodeMapper
|
this.openingNodeMapper,
|
||||||
),
|
),
|
||||||
R.when(
|
R.when(
|
||||||
|
// @ts-ignore
|
||||||
R.curry(this.isNodeTypeEquals)('CLOSING_ENTRY'),
|
R.curry(this.isNodeTypeEquals)('CLOSING_ENTRY'),
|
||||||
this.closingNodeMapper
|
this.closingNodeMapper,
|
||||||
),
|
),
|
||||||
R.when(R.curry(this.isNodeTypeEquals)('item'), this.itemNodeMapper),
|
R.when(R.curry(this.isNodeTypeEquals)('item'), this.itemNodeMapper),
|
||||||
R.when(
|
R.when(
|
||||||
R.curry(this.isNodeTypeEquals)('transaction'),
|
R.curry(this.isNodeTypeEquals)('transaction'),
|
||||||
this.itemTransactionNodeMapper
|
this.itemTransactionNodeMapper,
|
||||||
)
|
),
|
||||||
)(node);
|
)(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,6 +172,7 @@ export class InventoryItemDetailsTable {
|
|||||||
* @returns {ITableRow[]}
|
* @returns {ITableRow[]}
|
||||||
*/
|
*/
|
||||||
private itemsMapper = (items: IInventoryDetailsItem[]): ITableRow[] => {
|
private itemsMapper = (items: IInventoryDetailsItem[]): ITableRow[] => {
|
||||||
|
// @ts-ignore
|
||||||
return mapValuesDeep(items, this.itemMapper, MAP_CONFIG);
|
return mapValuesDeep(items, this.itemMapper, MAP_CONFIG);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { IInventoryDetailsQuery } from "./InventoryItemDetails.types";
|
import * as moment from 'moment';
|
||||||
|
import { IInventoryDetailsQuery } from './InventoryItemDetails.types';
|
||||||
|
|
||||||
export const HtmlTableCustomCss = `
|
export const HtmlTableCustomCss = `
|
||||||
table tr.row-type--item td,
|
table tr.row-type--item td,
|
||||||
@@ -27,7 +28,6 @@ export const getInventoryItemDetailsDefaultQuery =
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' };
|
export const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' };
|
||||||
|
|
||||||
export enum INodeTypes {
|
export enum INodeTypes {
|
||||||
|
|||||||
@@ -4,7 +4,12 @@ import { PurchasesByItemsApplication } from './PurchasesByItemsApplication';
|
|||||||
import { IPurchasesByItemsReportQuery } from './types/PurchasesByItems.types';
|
import { IPurchasesByItemsReportQuery } from './types/PurchasesByItems.types';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
||||||
import { ApiResponse, ApiTags } from '@nestjs/swagger';
|
import {
|
||||||
|
ApiOperation,
|
||||||
|
ApiResponse,
|
||||||
|
ApiResponseProperty,
|
||||||
|
ApiTags,
|
||||||
|
} from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('/reports/purchases-by-items')
|
@Controller('/reports/purchases-by-items')
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
@@ -16,6 +21,7 @@ export class PurchasesByItemReportController {
|
|||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@ApiResponse({ status: 200, description: 'Purchases by items report' })
|
@ApiResponse({ status: 200, description: 'Purchases by items report' })
|
||||||
|
@ApiOperation({ summary: 'Get purchases by items report' })
|
||||||
async purchasesByItems(
|
async purchasesByItems(
|
||||||
@Query() filter: IPurchasesByItemsReportQuery,
|
@Query() filter: IPurchasesByItemsReportQuery,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
import { Body, Controller, Get, Headers, Query, Req, Res } from '@nestjs/common';
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
Headers,
|
||||||
|
Query,
|
||||||
|
Req,
|
||||||
|
Res,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { ISalesByItemsReportQuery } from './SalesByItems.types';
|
import { ISalesByItemsReportQuery } from './SalesByItems.types';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { SalesByItemsApplication } from './SalesByItemsApplication';
|
import { SalesByItemsApplication } from './SalesByItemsApplication';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { ApiResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('/reports/sales-by-items')
|
@Controller('/reports/sales-by-items')
|
||||||
@ApiTags('reports')
|
@ApiTags('reports')
|
||||||
@@ -12,6 +20,7 @@ export class SalesByItemsController {
|
|||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@ApiResponse({ status: 200, description: 'Sales by items report' })
|
@ApiResponse({ status: 200, description: 'Sales by items report' })
|
||||||
|
@ApiOperation({ summary: 'Get sales by items report' })
|
||||||
public async salesByitems(
|
public async salesByitems(
|
||||||
@Query() filter: ISalesByItemsReportQuery,
|
@Query() filter: ISalesByItemsReportQuery,
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
import { ITransactionsByCustomersFilter } from './TransactionsByCustomer.types';
|
import { ITransactionsByCustomersFilter } from './TransactionsByCustomer.types';
|
||||||
import { TransactionsByCustomerApplication } from './TransactionsByCustomersApplication';
|
import { TransactionsByCustomerApplication } from './TransactionsByCustomersApplication';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
@@ -7,6 +7,7 @@ import { Response } from 'express';
|
|||||||
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
||||||
|
|
||||||
@Controller('/reports/transactions-by-customers')
|
@Controller('/reports/transactions-by-customers')
|
||||||
|
@ApiTags('reports')
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
export class TransactionsByCustomerController {
|
export class TransactionsByCustomerController {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import { Controller, Get, Query } from '@nestjs/common';
|
|||||||
import { TransactionsByReferenceApplication } from './TransactionsByReferenceApplication';
|
import { TransactionsByReferenceApplication } from './TransactionsByReferenceApplication';
|
||||||
import { ITransactionsByReferenceQuery } from './TransactionsByReference.types';
|
import { ITransactionsByReferenceQuery } from './TransactionsByReference.types';
|
||||||
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
||||||
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('reports/transactions-by-reference')
|
@Controller('reports/transactions-by-reference')
|
||||||
|
@ApiTags('reports')
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
export class TransactionsByReferenceController {
|
export class TransactionsByReferenceController {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -11,6 +13,8 @@ export class TransactionsByReferenceController {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
|
@ApiResponse({ status: 200, description: 'Transactions by reference' })
|
||||||
|
@ApiOperation({ summary: 'Get transactions by reference' })
|
||||||
async getTransactionsByReference(
|
async getTransactionsByReference(
|
||||||
@Query() query: ITransactionsByReferenceQuery,
|
@Query() query: ITransactionsByReferenceQuery,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ import { ITransactionsByVendorsFilter } from './TransactionsByVendor.types';
|
|||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { TransactionsByVendorApplication } from './TransactionsByVendorApplication';
|
import { TransactionsByVendorApplication } from './TransactionsByVendorApplication';
|
||||||
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
||||||
|
|
||||||
@Controller('/reports/transactions-by-vendors')
|
@Controller('/reports/transactions-by-vendors')
|
||||||
|
@ApiTags('reports')
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
export class TransactionsByVendorController {
|
export class TransactionsByVendorController {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export class TrialBalanceSheetResponse {}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
import { groupBy } from 'lodash';
|
import { groupBy } from 'lodash';
|
||||||
|
|
||||||
export const transformToMapBy = <T>(collection: T[], key: keyof T): Map<string, T[]> => {
|
export const transformToMapBy = <T>(
|
||||||
|
collection: T[],
|
||||||
|
key: keyof T,
|
||||||
|
): Map<string, T[]> => {
|
||||||
return new Map(Object.entries(groupBy(collection, key)));
|
return new Map(Object.entries(groupBy(collection, key)));
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user