mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 14:50:32 +00:00
refactor(nestjs): bank transactions matching
This commit is contained in:
4
packages/server/src/i18n/en/inventory_adjustment.json
Normal file
4
packages/server/src/i18n/en/inventory_adjustment.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"decrement": "Decrement",
|
||||||
|
"increment": "Increment"
|
||||||
|
}
|
||||||
@@ -2,14 +2,21 @@ import { Body, Controller, Delete, Param, Post, Query } from '@nestjs/common';
|
|||||||
import { castArray, omit } from 'lodash';
|
import { castArray, omit } from 'lodash';
|
||||||
import { BankingCategorizeApplication } from './BankingCategorize.application';
|
import { BankingCategorizeApplication } from './BankingCategorize.application';
|
||||||
import { CategorizeBankTransactionRouteDto } from './dtos/CategorizeBankTransaction.dto';
|
import { CategorizeBankTransactionRouteDto } from './dtos/CategorizeBankTransaction.dto';
|
||||||
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
@Controller('banking/categorize')
|
@Controller('banking/categorize')
|
||||||
|
@ApiTags('banking-categorization')
|
||||||
export class BankingCategorizeController {
|
export class BankingCategorizeController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly bankingCategorizeApplication: BankingCategorizeApplication,
|
private readonly bankingCategorizeApplication: BankingCategorizeApplication,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
|
@ApiOperation({ summary: 'Categorize bank transactions.' })
|
||||||
|
@ApiResponse({
|
||||||
|
status: 200,
|
||||||
|
description: 'The bank transactions have been categorized successfully.',
|
||||||
|
})
|
||||||
public categorizeTransaction(
|
public categorizeTransaction(
|
||||||
@Body() body: CategorizeBankTransactionRouteDto,
|
@Body() body: CategorizeBankTransactionRouteDto,
|
||||||
) {
|
) {
|
||||||
@@ -20,6 +27,11 @@ export class BankingCategorizeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Delete('/bulk')
|
@Delete('/bulk')
|
||||||
|
@ApiOperation({ summary: 'Uncategorize bank transactions.' })
|
||||||
|
@ApiResponse({
|
||||||
|
status: 200,
|
||||||
|
description: 'The bank transactions have been uncategorized successfully.',
|
||||||
|
})
|
||||||
public uncategorizeTransactionsBulk(
|
public uncategorizeTransactionsBulk(
|
||||||
@Query() uncategorizedTransactionIds: number[] | number,
|
@Query() uncategorizedTransactionIds: number[] | number,
|
||||||
) {
|
) {
|
||||||
@@ -29,6 +41,11 @@ export class BankingCategorizeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Delete('/:id')
|
@Delete('/:id')
|
||||||
|
@ApiOperation({ summary: 'Uncategorize a bank transaction.' })
|
||||||
|
@ApiResponse({
|
||||||
|
status: 200,
|
||||||
|
description: 'The bank transaction has been uncategorized successfully.',
|
||||||
|
})
|
||||||
public uncategorizeTransaction(
|
public uncategorizeTransaction(
|
||||||
@Param('id') uncategorizedTransactionId: number,
|
@Param('id') uncategorizedTransactionId: number,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -8,48 +8,106 @@ import {
|
|||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for categorizing bank transactions
|
||||||
|
*/
|
||||||
export class CategorizeBankTransactionDto {
|
export class CategorizeBankTransactionDto {
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The date of the bank transaction',
|
||||||
|
type: Date,
|
||||||
|
example: '2023-01-01T00:00:00.000Z',
|
||||||
|
})
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
date: Date;
|
date: Date;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the credit account associated with this transaction',
|
||||||
|
type: Number,
|
||||||
|
example: 1001,
|
||||||
|
})
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@ToNumber()
|
@ToNumber()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
creditAccountId: number;
|
creditAccountId: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Optional external reference number',
|
||||||
|
type: String,
|
||||||
|
example: 'REF-001',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
referenceNo: string;
|
referenceNo: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Optional transaction number or reference',
|
||||||
|
type: String,
|
||||||
|
example: 'TRX-001',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
transactionNumber: string;
|
transactionNumber: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Type of bank transaction (e.g., deposit, withdrawal)',
|
||||||
|
type: String,
|
||||||
|
example: 'deposit',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
transactionType: string;
|
transactionType: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Exchange rate for currency conversion',
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
example: 1.15,
|
||||||
|
})
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@ToNumber()
|
@ToNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
exchangeRate: number = 1;
|
exchangeRate: number = 1;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Currency code for the transaction',
|
||||||
|
type: String,
|
||||||
|
example: 'USD',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
currencyCode: string;
|
currencyCode: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Description of the bank transaction',
|
||||||
|
type: String,
|
||||||
|
example: 'Monthly rent payment',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'ID of the branch where the transaction occurred',
|
||||||
|
type: Number,
|
||||||
|
example: 101,
|
||||||
|
})
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
branchId: number;
|
branchId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended DTO for categorizing bank transactions with IDs of uncategorized transactions
|
||||||
|
*/
|
||||||
export class CategorizeBankTransactionRouteDto extends CategorizeBankTransactionDto {
|
export class CategorizeBankTransactionRouteDto extends CategorizeBankTransactionDto {
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Array of uncategorized transaction IDs to be categorized',
|
||||||
|
type: [Number],
|
||||||
|
example: [1001, 1002, 1003],
|
||||||
|
})
|
||||||
@IsArray()
|
@IsArray()
|
||||||
uncategorizedTransactionIds: Array<number>;
|
uncategorizedTransactionIds: Array<number>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,16 +23,12 @@ export class BankingMatchingController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/match/:uncategorizedTransactionId')
|
@Post('/match')
|
||||||
@ApiOperation({ summary: 'Match the given uncategorized transaction.' })
|
@ApiOperation({ summary: 'Match the given uncategorized transaction.' })
|
||||||
async matchTransaction(
|
async matchTransaction(@Body() matchedTransactions: MatchBankTransactionDto) {
|
||||||
@Param('uncategorizedTransactionId')
|
|
||||||
uncategorizedTransactionId: number | number[],
|
|
||||||
@Body() matchedTransactions: MatchBankTransactionDto,
|
|
||||||
) {
|
|
||||||
return this.bankingMatchingApplication.matchTransaction(
|
return this.bankingMatchingApplication.matchTransaction(
|
||||||
uncategorizedTransactionId,
|
matchedTransactions.uncategorizedTransactions,
|
||||||
matchedTransactions,
|
matchedTransactions.matchedTransactions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { GetMatchedTransactions } from './queries/GetMatchedTransactions.service';
|
import { GetMatchedTransactions } from './queries/GetMatchedTransactions.service';
|
||||||
import { MatchBankTransactions } from './commands/MatchTransactions';
|
import { MatchBankTransactions } from './commands/MatchTransactions';
|
||||||
import { UnmatchMatchedBankTransaction } from './commands/UnmatchMatchedTransaction.service';
|
import { UnmatchMatchedBankTransaction } from './commands/UnmatchMatchedTransaction.service';
|
||||||
import { GetMatchedTransactionsFilter, IMatchTransactionDTO } from './types';
|
import { GetMatchedTransactionsFilter } from './types';
|
||||||
import { MatchBankTransactionDto } from './dtos/MatchBankTransaction.dto';
|
import { MatchTransactionEntryDto } from './dtos/MatchBankTransaction.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BankingMatchingApplication {
|
export class BankingMatchingApplication {
|
||||||
@@ -31,17 +31,18 @@ export class BankingMatchingApplication {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the given uncategorized transaction with the given system transaction.
|
* Matches the given uncategorized transaction with the given system transaction.
|
||||||
* @param {number} uncategorizedTransactionId
|
* @param {IMatchBankTransactionDto} matchedTransactionsDTO
|
||||||
* @param {IMatchTransactionDTO} matchTransactionsDTO
|
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public matchTransaction(
|
public matchTransaction(
|
||||||
uncategorizedTransactionId: number | Array<number>,
|
uncategorizedTransactionId: number | Array<number>,
|
||||||
matchedTransactions: MatchBankTransactionDto,
|
matchedTransactionsDto:
|
||||||
|
| MatchTransactionEntryDto
|
||||||
|
| Array<MatchTransactionEntryDto>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return this.matchTransactionService.matchTransaction(
|
return this.matchTransactionService.matchTransaction(
|
||||||
uncategorizedTransactionId,
|
uncategorizedTransactionId,
|
||||||
matchedTransactions,
|
matchedTransactionsDto,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { ServiceError } from '@/modules/Items/ServiceError';
|
|||||||
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
|
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
|
||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
import { MatchBankTransactionDto } from '../dtos/MatchBankTransaction.dto';
|
import { MatchTransactionEntryDto } from '../dtos/MatchBankTransaction.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MatchBankTransactions {
|
export class MatchBankTransactions {
|
||||||
@@ -107,16 +107,15 @@ export class MatchBankTransactions {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the given uncategorized transaction to the given references.
|
* Matches the given uncategorized transaction to the given references.
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {number} uncategorizedTransactionId
|
* @param {number} uncategorizedTransactionId
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public async matchTransaction(
|
public async matchTransaction(
|
||||||
uncategorizedTransactionId: number | Array<number>,
|
uncategorizedTransactionId: number | Array<number>,
|
||||||
matchedTransactionsDto: MatchBankTransactionDto,
|
matchedTransactionsDto: MatchTransactionEntryDto | Array<MatchTransactionEntryDto>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const uncategorizedTransactionIds = castArray(uncategorizedTransactionId);
|
const uncategorizedTransactionIds = castArray(uncategorizedTransactionId);
|
||||||
const matchedTransactions = matchedTransactionsDto.entries;
|
const matchedTransactions = castArray(matchedTransactionsDto);
|
||||||
|
|
||||||
// Validates the given matching transactions DTO.
|
// Validates the given matching transactions DTO.
|
||||||
await this.validate(uncategorizedTransactionIds, matchedTransactions);
|
await this.validate(uncategorizedTransactionIds, matchedTransactions);
|
||||||
@@ -131,7 +130,7 @@ export class MatchBankTransactions {
|
|||||||
// Matches the given transactions under promise pool concurrency controlling.
|
// Matches the given transactions under promise pool concurrency controlling.
|
||||||
await PromisePool.withConcurrency(10)
|
await PromisePool.withConcurrency(10)
|
||||||
.for(matchedTransactions)
|
.for(matchedTransactions)
|
||||||
.process(async (matchedTransaction) => {
|
.process(async (matchedTransaction: MatchTransactionEntryDto) => {
|
||||||
const getMatchedTransactionsService =
|
const getMatchedTransactionsService =
|
||||||
this.matchedBankTransactions.registry.get(
|
this.matchedBankTransactions.registry.get(
|
||||||
matchedTransaction.referenceType,
|
matchedTransaction.referenceType,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
ArrayMinSize,
|
||||||
IsArray,
|
IsArray,
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsNumber,
|
IsNumber,
|
||||||
@@ -27,6 +28,10 @@ export class MatchTransactionEntryDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class MatchBankTransactionDto {
|
export class MatchBankTransactionDto {
|
||||||
|
@IsArray()
|
||||||
|
@ArrayMinSize(1)
|
||||||
|
uncategorizedTransactions: Array<number>
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => MatchTransactionEntryDto)
|
@Type(() => MatchTransactionEntryDto)
|
||||||
@@ -37,5 +42,5 @@ export class MatchBankTransactionDto {
|
|||||||
{ referenceType: 'SaleInvoice', referenceId: 2 },
|
{ referenceType: 'SaleInvoice', referenceId: 2 },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
entries: MatchTransactionEntryDto[];
|
matchedTransactions: MatchTransactionEntryDto[];
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
|
import PromisePool from '@supercharge/promise-pool';
|
||||||
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import {
|
import {
|
||||||
IBankTransactionMatchedEventPayload,
|
IBankTransactionMatchedEventPayload,
|
||||||
IBankTransactionUnmatchedEventPayload,
|
IBankTransactionUnmatchedEventPayload,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import PromisePool from '@supercharge/promise-pool';
|
|
||||||
import { OnEvent } from '@nestjs/event-emitter';
|
|
||||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
|
import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction';
|
||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DecrementUncategorizedTransactionOnMatchingSubscriber {
|
export class DecrementUncategorizedTransactionOnMatchingSubscriber {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Body, Controller, Post } from '@nestjs/common';
|
import { Body, Controller, Post } from '@nestjs/common';
|
||||||
import { PlaidWebhookDto } from './dtos/PlaidItem.dto';
|
import { PlaidWebhookDto } from './dtos/PlaidItem.dto';
|
||||||
import { ApiOperation } from '@nestjs/swagger';
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
import { PlaidApplication } from './PlaidApplication';
|
import { PlaidApplication } from './PlaidApplication';
|
||||||
import { PublicRoute } from '../Auth/guards/jwt.guard';
|
import { PublicRoute } from '../Auth/guards/jwt.guard';
|
||||||
import { SetupPlaidItemTenantService } from './command/SetupPlaidItemTenant.service';
|
import { SetupPlaidItemTenantService } from './command/SetupPlaidItemTenant.service';
|
||||||
|
|
||||||
@Controller('banking/plaid')
|
@Controller('banking/plaid')
|
||||||
|
@ApiTags('banking-plaid')
|
||||||
@PublicRoute()
|
@PublicRoute()
|
||||||
export class BankingPlaidWebhooksController {
|
export class BankingPlaidWebhooksController {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { OnEvent } from '@nestjs/event-emitter';
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
|
import { Queue } from 'bullmq';
|
||||||
|
import { InjectQueue } from '@nestjs/bullmq';
|
||||||
import {
|
import {
|
||||||
IPlaidItemCreatedEventPayload,
|
IPlaidItemCreatedEventPayload,
|
||||||
UpdateBankingPlaidTransitionsJob,
|
UpdateBankingPlaidTransitionsJob,
|
||||||
UpdateBankingPlaidTransitionsQueueJob,
|
UpdateBankingPlaidTransitionsQueueJob,
|
||||||
} from '../types/BankingPlaid.types';
|
} from '../types/BankingPlaid.types';
|
||||||
import { Queue } from 'bullmq';
|
|
||||||
import { InjectQueue } from '@nestjs/bullmq';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PlaidUpdateTransactionsOnItemCreatedSubscriber {
|
export class PlaidUpdateTransactionsOnItemCreatedSubscriber {
|
||||||
|
|||||||
@@ -8,67 +8,145 @@ import {
|
|||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class CreateBankTransactionDto {
|
export class CreateBankTransactionDto {
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The date of the bank transaction',
|
||||||
|
type: Date,
|
||||||
|
example: '2023-01-01T00:00:00.000Z',
|
||||||
|
})
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
date: Date;
|
date: Date;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Optional transaction number or reference',
|
||||||
|
type: String,
|
||||||
|
example: 'TRX-001',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
transactionNumber?: string;
|
transactionNumber?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Optional external reference number',
|
||||||
|
type: String,
|
||||||
|
example: 'REF-001',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
referenceNo?: string;
|
referenceNo?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Type of bank transaction (e.g., deposit, withdrawal)',
|
||||||
|
type: String,
|
||||||
|
example: 'deposit',
|
||||||
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsString()
|
@IsString()
|
||||||
transactionType: string;
|
transactionType: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Description of the bank transaction',
|
||||||
|
type: String,
|
||||||
|
example: 'Monthly rent payment',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Transaction amount',
|
||||||
|
type: Number,
|
||||||
|
example: 1000.5,
|
||||||
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@ToNumber()
|
@ToNumber()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
amount: number;
|
amount: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Exchange rate for currency conversion',
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
example: 1.15,
|
||||||
|
})
|
||||||
@ToNumber()
|
@ToNumber()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
exchangeRate: number = 1;
|
exchangeRate: number = 1;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Currency code for the transaction',
|
||||||
|
type: String,
|
||||||
|
example: 'USD',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
currencyCode: string;
|
currencyCode: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the credit account associated with this transaction',
|
||||||
|
type: Number,
|
||||||
|
example: 1001,
|
||||||
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@ToNumber()
|
@ToNumber()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
creditAccountId: number;
|
creditAccountId: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the cashflow account associated with this transaction',
|
||||||
|
type: Number,
|
||||||
|
example: 2001,
|
||||||
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@ToNumber()
|
@ToNumber()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
cashflowAccountId: number;
|
cashflowAccountId: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the transaction should be published',
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
publish: boolean = true;
|
publish: boolean = true;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'ID of the branch where the transaction occurred',
|
||||||
|
type: Number,
|
||||||
|
example: 101,
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@ToNumber()
|
@ToNumber()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Plaid transaction ID if imported from Plaid',
|
||||||
|
type: String,
|
||||||
|
example: 'plaid_trx_12345',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
plaidTransactionId?: string;
|
plaidTransactionId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: 'Plaid account ID if imported from Plaid',
|
||||||
|
type: String,
|
||||||
|
example: 'plaid_acc_67890',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
plaidAccountId?: string;
|
plaidAccountId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description:
|
||||||
|
'ID of the uncategorized transaction if this is categorizing an existing transaction',
|
||||||
|
type: Number,
|
||||||
|
example: 5001,
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
uncategorizedTransactionId?: number;
|
uncategorizedTransactionId?: number;
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
|
import * as moment from 'moment';
|
||||||
|
import * as R from 'ramda';
|
||||||
import type { Knex } from 'knex';
|
import type { Knex } from 'knex';
|
||||||
import { Model, raw } from 'objection';
|
import { Model, raw } from 'objection';
|
||||||
import { castArray, difference, defaultTo } from 'lodash';
|
import { castArray, difference, defaultTo } from 'lodash';
|
||||||
import * as moment from 'moment';
|
|
||||||
import * as R from 'ramda';
|
|
||||||
// import TenantModel from 'models/TenantModel';
|
|
||||||
// import BillSettings from './Bill.Settings';
|
|
||||||
// import ModelSetting from './ModelSetting';
|
|
||||||
// import CustomViewBaseModel from './CustomViewBaseModel';
|
|
||||||
// import { DEFAULT_VIEWS } from '@/services/Purchases/Bills/constants';
|
|
||||||
// import ModelSearchable from './ModelSearchable';
|
|
||||||
import { BaseModel, PaginationQueryBuilderType } from '@/models/Model';
|
import { BaseModel, PaginationQueryBuilderType } from '@/models/Model';
|
||||||
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
|
||||||
import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost';
|
import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost';
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { ToNumber } from '@/common/decorators/Validators';
|
||||||
|
import { IsArray, IsEnum, IsInt, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { IFilterRole, ISortOrder } from '../DynamicFilter/DynamicFilter.types';
|
||||||
|
|
||||||
|
export class DynamicFilterQueryDto {
|
||||||
|
@IsOptional()
|
||||||
|
@ToNumber()
|
||||||
|
customViewId?: number;
|
||||||
|
|
||||||
|
@IsArray()
|
||||||
|
@IsOptional()
|
||||||
|
filterRoles?: IFilterRole[];
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
columnSortBy: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
sortOrder: ISortOrder;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
stringifiedFilterRoles?: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
searchKeyword?: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
viewSlug?: string;
|
||||||
|
}
|
||||||
@@ -52,8 +52,6 @@ export class ExportResourceService {
|
|||||||
const data = await this.getExportableData(resource);
|
const data = await this.getExportableData(resource);
|
||||||
const transformed = this.transformExportedData(resource, data);
|
const transformed = this.transformExportedData(resource, data);
|
||||||
|
|
||||||
console.log(format);
|
|
||||||
|
|
||||||
// Returns the csv, xlsx format.
|
// Returns the csv, xlsx format.
|
||||||
if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) {
|
if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) {
|
||||||
const exportableColumns = this.getExportableColumns(resourceColumns);
|
const exportableColumns = this.getExportableColumns(resourceColumns);
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ export class InventoryAdjustmentTransformer extends Transformer {
|
|||||||
*/
|
*/
|
||||||
formattedType(inventoryAdjustment: InventoryAdjustment) {
|
formattedType(inventoryAdjustment: InventoryAdjustment) {
|
||||||
const types = {
|
const types = {
|
||||||
increment: 'inventory_adjustment.type.increment',
|
increment: 'inventory_adjustment.increment',
|
||||||
decrement: 'inventory_adjustment.type.decrement',
|
decrement: 'inventory_adjustment.decrement',
|
||||||
};
|
};
|
||||||
return this.context.i18n.t(types[inventoryAdjustment.type] || '');
|
return this.context.i18n.t(types[inventoryAdjustment.type] || '');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsDate,
|
IsDateString,
|
||||||
IsEnum,
|
IsEnum,
|
||||||
|
IsInt,
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsNumber,
|
IsNumber,
|
||||||
IsOptional,
|
|
||||||
IsPositive,
|
IsPositive,
|
||||||
IsString,
|
IsString,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { Type } from 'class-transformer';
|
import { Transform } from 'class-transformer';
|
||||||
|
import { IsOptional, ToNumber } from '@/common/decorators/Validators';
|
||||||
|
import { parseBoolean } from '@/utils/parse-boolean';
|
||||||
|
|
||||||
enum IAdjustmentTypes {
|
enum IAdjustmentTypes {
|
||||||
INCREMENT = 'increment',
|
INCREMENT = 'increment',
|
||||||
@@ -19,8 +21,7 @@ enum IAdjustmentTypes {
|
|||||||
export class CreateQuickInventoryAdjustmentDto {
|
export class CreateQuickInventoryAdjustmentDto {
|
||||||
@ApiProperty({ description: 'Date of the inventory adjustment' })
|
@ApiProperty({ description: 'Date of the inventory adjustment' })
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsDate()
|
@IsDateString()
|
||||||
@Type(() => Date)
|
|
||||||
date: Date;
|
date: Date;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Type of adjustment', enum: IAdjustmentTypes })
|
@ApiProperty({ description: 'Type of adjustment', enum: IAdjustmentTypes })
|
||||||
@@ -30,7 +31,8 @@ export class CreateQuickInventoryAdjustmentDto {
|
|||||||
|
|
||||||
@ApiProperty({ description: 'ID of the adjustment account' })
|
@ApiProperty({ description: 'ID of the adjustment account' })
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsNumber()
|
@ToNumber()
|
||||||
|
@IsInt()
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
adjustmentAccountId: number;
|
adjustmentAccountId: number;
|
||||||
|
|
||||||
@@ -40,47 +42,52 @@ export class CreateQuickInventoryAdjustmentDto {
|
|||||||
reason: string;
|
reason: string;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Description of the adjustment' })
|
@ApiProperty({ description: 'Description of the adjustment' })
|
||||||
@IsNotEmpty()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Reference number' })
|
@ApiProperty({ description: 'Reference number' })
|
||||||
@IsNotEmpty()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
referenceNo: string;
|
referenceNo: string;
|
||||||
|
|
||||||
@ApiProperty({ description: 'ID of the item being adjusted' })
|
@ApiProperty({ description: 'ID of the item being adjusted' })
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ToNumber()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
itemId: number;
|
itemId: number;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Quantity to adjust' })
|
@ApiProperty({ description: 'Quantity to adjust' })
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ToNumber()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
quantity: number;
|
quantity: number;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Cost of the item' })
|
@ApiProperty({ description: 'Cost of the item' })
|
||||||
@IsNotEmpty()
|
@IsOptional()
|
||||||
|
@ToNumber()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsPositive()
|
|
||||||
cost: number;
|
cost: number;
|
||||||
|
|
||||||
@ApiProperty({ description: 'Whether to publish the adjustment immediately' })
|
@ApiProperty({ description: 'Whether to publish the adjustment immediately' })
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@Transform((param) => parseBoolean(param.value, false))
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
publish: boolean;
|
publish: boolean;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'ID of the warehouse (optional)' })
|
@ApiPropertyOptional({ description: 'ID of the warehouse (optional)' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@ToNumber()
|
||||||
|
@IsInt()
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'ID of the branch (optional)' })
|
@ApiPropertyOptional({ description: 'ID of the branch (optional)' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@ToNumber()
|
||||||
|
@IsInt()
|
||||||
@IsPositive()
|
@IsPositive()
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { Controller, Get, Query } from '@nestjs/common';
|
||||||
|
import { GetItemsInventoryValuationListService } from './queries/GetItemsInventoryValuationList.service';
|
||||||
|
import { GetInventoyItemsCostQueryDto } from './dtos/GetInventoryItemsCostQuery.dto';
|
||||||
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
@Controller('inventory-cost')
|
||||||
|
@ApiTags('inventory-cost')
|
||||||
|
export class InventoryCostController {
|
||||||
|
constructor(
|
||||||
|
private readonly inventoryItemCost: GetItemsInventoryValuationListService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Get('items')
|
||||||
|
@ApiOperation({ summary: 'Get items inventory valuation list' })
|
||||||
|
async getItemsCost(
|
||||||
|
@Query() itemsCostsQueryDto: GetInventoyItemsCostQueryDto,
|
||||||
|
) {
|
||||||
|
const costs = await this.inventoryItemCost.getItemsInventoryValuationList(
|
||||||
|
itemsCostsQueryDto.itemsIds,
|
||||||
|
itemsCostsQueryDto.date,
|
||||||
|
);
|
||||||
|
return { costs };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,8 @@ import { InventoryItemOpeningAvgCostService } from './commands/InventoryItemOpen
|
|||||||
import { InventoryCostSubscriber } from './subscribers/InventoryCost.subscriber';
|
import { InventoryCostSubscriber } from './subscribers/InventoryCost.subscriber';
|
||||||
import { SaleInvoicesModule } from '../SaleInvoices/SaleInvoices.module';
|
import { SaleInvoicesModule } from '../SaleInvoices/SaleInvoices.module';
|
||||||
import { ImportModule } from '../Import/Import.module';
|
import { ImportModule } from '../Import/Import.module';
|
||||||
|
import { GetItemsInventoryValuationListService } from './queries/GetItemsInventoryValuationList.service';
|
||||||
|
import { InventoryCostController } from './InventoryCost.controller';
|
||||||
|
|
||||||
const models = [
|
const models = [
|
||||||
RegisterTenancyModel(InventoryCostLotTracker),
|
RegisterTenancyModel(InventoryCostLotTracker),
|
||||||
@@ -54,6 +56,7 @@ const models = [
|
|||||||
InventoryItemCostService,
|
InventoryItemCostService,
|
||||||
InventoryItemOpeningAvgCostService,
|
InventoryItemOpeningAvgCostService,
|
||||||
InventoryCostSubscriber,
|
InventoryCostSubscriber,
|
||||||
|
GetItemsInventoryValuationListService
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
...models,
|
...models,
|
||||||
@@ -61,5 +64,6 @@ const models = [
|
|||||||
InventoryItemCostService,
|
InventoryItemCostService,
|
||||||
InventoryComputeCostService,
|
InventoryComputeCostService,
|
||||||
],
|
],
|
||||||
|
controllers: [InventoryCostController]
|
||||||
})
|
})
|
||||||
export class InventoryCostModule {}
|
export class InventoryCostModule {}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import {
|
||||||
|
ArrayMinSize,
|
||||||
|
IsArray,
|
||||||
|
IsDateString,
|
||||||
|
IsNotEmpty,
|
||||||
|
} from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class GetInventoyItemsCostQueryDto {
|
||||||
|
@IsDateString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The date to get the inventory cost for',
|
||||||
|
example: '2021-01-01',
|
||||||
|
})
|
||||||
|
date: Date;
|
||||||
|
|
||||||
|
@IsArray()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ArrayMinSize(1)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The ids of the items to get the inventory cost for',
|
||||||
|
example: [1, 2, 3],
|
||||||
|
})
|
||||||
|
itemsIds: Array<number>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InventoryItemCostService } from '../commands/InventoryCosts.service';
|
||||||
|
import { IInventoryItemCostMeta } from '../types/InventoryCost.types';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GetItemsInventoryValuationListService {
|
||||||
|
constructor(private readonly inventoryCost: InventoryItemCostService) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the items inventory valuation list.
|
||||||
|
* @param {number[]} itemsId
|
||||||
|
* @param {Date} date
|
||||||
|
* @returns {Promise<IInventoryItemCostMeta[]>}
|
||||||
|
*/
|
||||||
|
public getItemsInventoryValuationList = async (
|
||||||
|
itemsId: number[],
|
||||||
|
date: Date,
|
||||||
|
): Promise<IInventoryItemCostMeta[]> => {
|
||||||
|
const itemsMap = await this.inventoryCost.getItemsInventoryValuation(
|
||||||
|
itemsId,
|
||||||
|
date,
|
||||||
|
);
|
||||||
|
return [...itemsMap.values()];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import { IItemsFilter } from './types/Items.types';
|
|||||||
import { ItemTransformer } from './Item.transformer';
|
import { ItemTransformer } from './Item.transformer';
|
||||||
import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
||||||
import { ISortOrder } from '../DynamicListing/DynamicFilter/DynamicFilter.types';
|
import { ISortOrder } from '../DynamicListing/DynamicFilter/DynamicFilter.types';
|
||||||
|
import { GetItemsQueryDto } from './dtos/GetItemsQuery.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GetItemsService {
|
export class GetItemsService {
|
||||||
@@ -32,7 +33,7 @@ export class GetItemsService {
|
|||||||
* Retrieves items datatable list.
|
* Retrieves items datatable list.
|
||||||
* @param {IItemsFilter} itemsFilter - Items filter.
|
* @param {IItemsFilter} itemsFilter - Items filter.
|
||||||
*/
|
*/
|
||||||
public async getItems(filterDto: Partial<IItemsFilter>) {
|
public async getItems(filterDto: Partial<GetItemsQueryDto>) {
|
||||||
const _filterDto = {
|
const _filterDto = {
|
||||||
sortOrder: ISortOrder.DESC,
|
sortOrder: ISortOrder.DESC,
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
import { IItemsFilter } from './types/Items.types';
|
import { IItemsFilter } from './types/Items.types';
|
||||||
import { CreateItemDto, EditItemDto } from './dtos/Item.dto';
|
import { CreateItemDto, EditItemDto } from './dtos/Item.dto';
|
||||||
|
import { GetItemsQueryDto } from './dtos/GetItemsQuery.dto';
|
||||||
|
|
||||||
@Controller('/items')
|
@Controller('/items')
|
||||||
@UseGuards(SubscriptionGuard)
|
@UseGuards(SubscriptionGuard)
|
||||||
@@ -99,7 +100,7 @@ export class ItemsController extends TenantController {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
description: 'Filter for inactive items',
|
description: 'Filter for inactive items',
|
||||||
})
|
})
|
||||||
async getItems(@Query() filterDTO: IItemsFilter): Promise<any> {
|
async getItems(@Query() filterDTO: GetItemsQueryDto): Promise<any> {
|
||||||
return this.itemsApplication.getItems(filterDTO);
|
return this.itemsApplication.getItems(filterDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { GetItemsService } from './GetItems.service';
|
import { GetItemsService } from './GetItems.service';
|
||||||
import { IItemsFilter } from './types/Items.types';
|
import { IItemsFilter } from './types/Items.types';
|
||||||
import { EditItemDto, CreateItemDto } from './dtos/Item.dto';
|
import { EditItemDto, CreateItemDto } from './dtos/Item.dto';
|
||||||
|
import { GetItemsQueryDto } from './dtos/GetItemsQuery.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ItemsApplicationService {
|
export class ItemsApplicationService {
|
||||||
@@ -94,7 +95,7 @@ export class ItemsApplicationService {
|
|||||||
* Retrieves the paginated filterable items list.
|
* Retrieves the paginated filterable items list.
|
||||||
* @param {Partial<IItemsFilter>} filterDTO
|
* @param {Partial<IItemsFilter>} filterDTO
|
||||||
*/
|
*/
|
||||||
async getItems(filterDTO: Partial<IItemsFilter>) {
|
async getItems(filterDTO: Partial<GetItemsQueryDto>) {
|
||||||
return this.getItemsService.getItems(filterDTO);
|
return this.getItemsService.getItems(filterDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
packages/server/src/modules/Items/dtos/GetItemsQuery.dto.ts
Normal file
22
packages/server/src/modules/Items/dtos/GetItemsQuery.dto.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { ToNumber } from '@/common/decorators/Validators';
|
||||||
|
import { DynamicFilterQueryDto } from '@/modules/DynamicListing/dtos/DynamicFilterQuery.dto';
|
||||||
|
import { parseBoolean } from '@/utils/parse-boolean';
|
||||||
|
import { Transform, Type } from 'class-transformer';
|
||||||
|
import { IsBoolean, IsInt, IsOptional } from 'class-validator';
|
||||||
|
|
||||||
|
export class GetItemsQueryDto extends DynamicFilterQueryDto {
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@ToNumber()
|
||||||
|
page?: number;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@ToNumber()
|
||||||
|
pageSize?: number;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@Transform((param) => parseBoolean(param.value, false))
|
||||||
|
@IsBoolean()
|
||||||
|
inactiveMode?: boolean;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import async from 'async';
|
import * as async from 'async';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import {
|
import {
|
||||||
ILedger,
|
ILedger,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import async from 'async';
|
import * as async from 'async';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { transformLedgerEntryToTransaction } from './utils';
|
import { transformLedgerEntryToTransaction } from './utils';
|
||||||
import {
|
import {
|
||||||
@@ -33,7 +33,7 @@ export class LedgerEntriesStorageService {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public saveEntries = async (ledger: ILedger, trx?: Knex.Transaction) => {
|
public saveEntries = async (ledger: ILedger, trx?: Knex.Transaction) => {
|
||||||
const saveEntryQueue = async.queue(this.saveEntryTask, 10);
|
const saveEntryQueue = async.queue(this.saveEntryTask.bind(this), 10);
|
||||||
const entries = ledger.filter(filterBlankEntry).getEntries();
|
const entries = ledger.filter(filterBlankEntry).getEntries();
|
||||||
|
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import async from 'async';
|
import * as async from 'async';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { uniq } from 'lodash';
|
import { uniq } from 'lodash';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import * as moment from 'moment';
|
||||||
import { AccountTransaction } from "../Accounts/models/AccountTransaction.model";
|
import { AccountTransaction } from "../Accounts/models/AccountTransaction.model";
|
||||||
import { ILedgerEntry } from "./types/Ledger.types";
|
import { ILedgerEntry } from "./types/Ledger.types";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import async from 'async';
|
import * as async from 'async';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { PaymentReceivedGLEntries } from '../PaymentReceived/commands/PaymentReceivedGLEntries';
|
import { PaymentReceivedGLEntries } from '../PaymentReceived/commands/PaymentReceivedGLEntries';
|
||||||
import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Model, raw } from 'objection';
|
|
||||||
import { castArray } from 'lodash';
|
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
import { Model, raw } from 'objection';
|
||||||
|
import { castArray } from 'lodash';
|
||||||
import { MomentInput, unitOfTime } from 'moment';
|
import { MomentInput, unitOfTime } from 'moment';
|
||||||
import { defaultTo } from 'ramda';
|
import { defaultTo } from 'ramda';
|
||||||
import { TaxRateTransaction } from '@/modules/TaxRates/models/TaxRateTransaction.model';
|
import { TaxRateTransaction } from '@/modules/TaxRates/models/TaxRateTransaction.model';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { BaseModel } from '@/models/Model';
|
import { BaseModel } from '@/models/Model';
|
||||||
|
|
||||||
export class UserInvite extends BaseModel {
|
export class UserInvite extends BaseModel {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { IEditWarehouseDTO, IWarehouse } from '../Warehouse.types';
|
|
||||||
import { WarehouseValidator } from './WarehouseValidator.service';
|
import { WarehouseValidator } from './WarehouseValidator.service';
|
||||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { ToNumber } from '@/common/decorators/Validators';
|
||||||
|
import { IsInt, IsOptional, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class GetWarehouseTransfersQueryDto {
|
||||||
|
@IsInt()
|
||||||
|
@ToNumber()
|
||||||
|
@IsOptional()
|
||||||
|
page: number;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@ToNumber()
|
||||||
|
@IsOptional()
|
||||||
|
pageSize: number;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
searchKeyword: string;
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
CreateWarehouseTransferDto,
|
CreateWarehouseTransferDto,
|
||||||
EditWarehouseTransferDto,
|
EditWarehouseTransferDto,
|
||||||
} from './dtos/WarehouseTransfer.dto';
|
} from './dtos/WarehouseTransfer.dto';
|
||||||
|
import { GetWarehouseTransfersQueryDto } from '../Warehouses/dtos/GetWarehouseTransfersQuery.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WarehouseTransferApplication {
|
export class WarehouseTransferApplication {
|
||||||
@@ -86,7 +87,7 @@ export class WarehouseTransferApplication {
|
|||||||
* @returns {Promise<IWarehouseTransfer>}
|
* @returns {Promise<IWarehouseTransfer>}
|
||||||
*/
|
*/
|
||||||
public getWarehousesTransfers = (
|
public getWarehousesTransfers = (
|
||||||
filterDTO: IGetWarehousesTransfersFilterDTO,
|
filterDTO: GetWarehouseTransfersQueryDto,
|
||||||
) => {
|
) => {
|
||||||
return this.getWarehousesTransfersService.getWarehouseTransfers(filterDTO);
|
return this.getWarehousesTransfersService.getWarehouseTransfers(filterDTO);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
CreateWarehouseTransferDto,
|
CreateWarehouseTransferDto,
|
||||||
EditWarehouseTransferDto,
|
EditWarehouseTransferDto,
|
||||||
} from './dtos/WarehouseTransfer.dto';
|
} from './dtos/WarehouseTransfer.dto';
|
||||||
|
import { GetWarehouseTransfersQueryDto } from '../Warehouses/dtos/GetWarehouseTransfersQuery.dto';
|
||||||
|
|
||||||
@Controller('warehouse-transfers')
|
@Controller('warehouse-transfers')
|
||||||
@ApiTags('warehouse-transfers')
|
@ApiTags('warehouse-transfers')
|
||||||
@@ -129,7 +130,7 @@ export class WarehouseTransfersController {
|
|||||||
description:
|
description:
|
||||||
'The warehouse transfer transactions have been retrieved successfully.',
|
'The warehouse transfer transactions have been retrieved successfully.',
|
||||||
})
|
})
|
||||||
async getWarehousesTransfers(@Query() query: any) {
|
async getWarehousesTransfers(@Query() query: GetWarehouseTransfersQueryDto) {
|
||||||
const { warehousesTransfers, pagination, filter } =
|
const { warehousesTransfers, pagination, filter } =
|
||||||
await this.warehouseTransferApplication.getWarehousesTransfers(query);
|
await this.warehouseTransferApplication.getWarehousesTransfers(query);
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
|
import { ToNumber } from '@/common/decorators/Validators';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import {
|
import {
|
||||||
IsArray,
|
IsArray,
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsDate,
|
|
||||||
IsDecimal,
|
IsDecimal,
|
||||||
IsInt,
|
IsInt,
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsNumber,
|
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsPositive,
|
IsPositive,
|
||||||
IsString,
|
IsString,
|
||||||
ValidateNested,
|
ValidateNested,
|
||||||
ArrayMinSize,
|
ArrayMinSize,
|
||||||
|
IsDateString,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
export class WarehouseTransferEntryDto {
|
export class WarehouseTransferEntryDto {
|
||||||
@@ -39,6 +39,7 @@ export class WarehouseTransferEntryDto {
|
|||||||
|
|
||||||
export class CommandWarehouseTransferDto {
|
export class CommandWarehouseTransferDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ToNumber()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'The id of the warehouse to transfer from',
|
description: 'The id of the warehouse to transfer from',
|
||||||
@@ -47,6 +48,7 @@ export class CommandWarehouseTransferDto {
|
|||||||
fromWarehouseId: number;
|
fromWarehouseId: number;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ToNumber()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'The id of the warehouse to transfer to',
|
description: 'The id of the warehouse to transfer to',
|
||||||
@@ -55,7 +57,7 @@ export class CommandWarehouseTransferDto {
|
|||||||
toWarehouseId: number;
|
toWarehouseId: number;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsDate()
|
@IsDateString()
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: 'The date of the warehouse transfer',
|
description: 'The date of the warehouse transfer',
|
||||||
example: '2021-01-01',
|
example: '2021-01-01',
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
function StatusFieldFilterQuery(query, role) {
|
||||||
|
query.modify('filterByStatus', role.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WarehouseTransferMeta = {
|
||||||
|
defaultFilterField: 'name',
|
||||||
|
defaultSort: {
|
||||||
|
sortField: 'name',
|
||||||
|
sortOrder: 'DESC',
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
date: {
|
||||||
|
name: 'warehouse_transfer.field.date',
|
||||||
|
type: 'date',
|
||||||
|
exportable: true,
|
||||||
|
},
|
||||||
|
transaction_number: {
|
||||||
|
name: 'warehouse_transfer.field.transaction_number',
|
||||||
|
type: 'text',
|
||||||
|
exportable: true,
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
name: 'warehouse_transfer.field.status',
|
||||||
|
fieldType: 'enumeration',
|
||||||
|
options: [
|
||||||
|
{ key: 'draft', label: 'Draft' },
|
||||||
|
{ key: 'in-transit', label: 'In Transit' },
|
||||||
|
{ key: 'transferred', label: 'Transferred' },
|
||||||
|
],
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
name: 'warehouse_transfer.field.created_at',
|
||||||
|
column: 'created_at',
|
||||||
|
columnType: 'date',
|
||||||
|
fieldType: 'date',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
date: {
|
||||||
|
name: 'warehouse_transfer.field.date',
|
||||||
|
column: 'date',
|
||||||
|
columnType: 'date',
|
||||||
|
fieldType: 'date',
|
||||||
|
},
|
||||||
|
transaction_number: {
|
||||||
|
name: 'warehouse_transfer.field.transaction_number',
|
||||||
|
column: 'transaction_number',
|
||||||
|
fieldType: 'text',
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
name: 'warehouse_transfer.field.status',
|
||||||
|
fieldType: 'enumeration',
|
||||||
|
options: [
|
||||||
|
{ key: 'draft', label: 'Draft' },
|
||||||
|
{ key: 'in-transit', label: 'In Transit' },
|
||||||
|
{ key: 'transferred', label: 'Transferred' },
|
||||||
|
],
|
||||||
|
filterCustomQuery: StatusFieldFilterQuery,
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
name: 'warehouse_transfer.field.created_at',
|
||||||
|
column: 'created_at',
|
||||||
|
columnType: 'date',
|
||||||
|
fieldType: 'date',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -2,7 +2,10 @@ import { Model, mixin } from 'objection';
|
|||||||
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
|
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
|
||||||
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
|
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
|
||||||
import { WarehouseTransferEntry } from './WarehouseTransferEntry';
|
import { WarehouseTransferEntry } from './WarehouseTransferEntry';
|
||||||
|
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
|
||||||
|
import { WarehouseTransferMeta } from './WarehouseTransfer.meta';
|
||||||
|
|
||||||
|
@InjectModelMeta(WarehouseTransferMeta)
|
||||||
export class WarehouseTransfer extends TenantBaseModel {
|
export class WarehouseTransfer extends TenantBaseModel {
|
||||||
public date!: Date;
|
public date!: Date;
|
||||||
public transferInitiatedAt!: Date;
|
public transferInitiatedAt!: Date;
|
||||||
@@ -14,7 +17,6 @@ export class WarehouseTransfer extends TenantBaseModel {
|
|||||||
public fromWarehouse!: Warehouse;
|
public fromWarehouse!: Warehouse;
|
||||||
public toWarehouse!: Warehouse;
|
public toWarehouse!: Warehouse;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
*/
|
*/
|
||||||
@@ -126,27 +128,13 @@ export class WarehouseTransfer extends TenantBaseModel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Model settings.
|
|
||||||
*/
|
|
||||||
// static get meta() {
|
|
||||||
// return WarehouseTransferSettings;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Retrieve the default custom views, roles and columns.
|
|
||||||
// */
|
|
||||||
// static get defaultViews() {
|
|
||||||
// return DEFAULT_VIEWS;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model search roles.
|
* Model search roles.
|
||||||
*/
|
*/
|
||||||
static get searchRoles() {
|
static get searchRoles() {
|
||||||
return [
|
return [
|
||||||
// { fieldKey: 'name', comparator: 'contains' },
|
{ fieldKey: 'name', comparator: 'contains' },
|
||||||
// { condition: 'or', fieldKey: 'code', comparator: 'like' },
|
{ condition: 'or', fieldKey: 'code', comparator: 'like' },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { TransformerInjectable } from '../../Transformer/TransformerInjectable.s
|
|||||||
import { DynamicListService } from '../../DynamicListing/DynamicList.service';
|
import { DynamicListService } from '../../DynamicListing/DynamicList.service';
|
||||||
import { TenantModelProxy } from '../../System/models/TenantBaseModel';
|
import { TenantModelProxy } from '../../System/models/TenantBaseModel';
|
||||||
import { WarehouseTransfer } from '../models/WarehouseTransfer';
|
import { WarehouseTransfer } from '../models/WarehouseTransfer';
|
||||||
|
import { GetWarehouseTransfersQueryDto } from '@/modules/Warehouses/dtos/GetWarehouseTransfersQuery.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GetWarehouseTransfers {
|
export class GetWarehouseTransfers {
|
||||||
@@ -30,16 +31,19 @@ export class GetWarehouseTransfers {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves warehouse transfers paginated list.
|
* Retrieves warehouse transfers paginated list.
|
||||||
* @param {number} tenantId
|
* @param {IGetWarehousesTransfersFilterDTO} filterDTO
|
||||||
* @param {IGetWarehousesTransfersFilterDTO} filterDTO
|
|
||||||
* @returns {}
|
|
||||||
*/
|
*/
|
||||||
public getWarehouseTransfers = async (
|
public getWarehouseTransfers = async (
|
||||||
filterDTO: IGetWarehousesTransfersFilterDTO,
|
filterDTO: GetWarehouseTransfersQueryDto,
|
||||||
) => {
|
) => {
|
||||||
// Parses stringified filter roles.
|
// Parses stringified filter roles.
|
||||||
const filter = this.parseListFilterDTO(filterDTO);
|
const filter = this.parseListFilterDTO({
|
||||||
|
sortOrder: 'desc',
|
||||||
|
columnSortBy: 'created_at',
|
||||||
|
page: 1,
|
||||||
|
pageSize: 12,
|
||||||
|
...filterDTO,
|
||||||
|
});
|
||||||
// Dynamic list service.
|
// Dynamic list service.
|
||||||
const dynamicFilter = await this.dynamicListService.dynamicList(
|
const dynamicFilter = await this.dynamicListService.dynamicList(
|
||||||
this.warehouseTransferModel(),
|
this.warehouseTransferModel(),
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ export function useMatchUncategorizedTransaction(
|
|||||||
MatchUncategorizedTransactionRes,
|
MatchUncategorizedTransactionRes,
|
||||||
Error,
|
Error,
|
||||||
MatchUncategorizedTransactionValues
|
MatchUncategorizedTransactionValues
|
||||||
>((value) => apiRequest.post('/banking/matches/match', value), {
|
>((value) => apiRequest.post('/banking/matching/match', value), {
|
||||||
onSuccess: (res, id) => {
|
onSuccess: (res, id) => {
|
||||||
queryClient.invalidateQueries(
|
queryClient.invalidateQueries(
|
||||||
t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY,
|
t.CASHFLOW_ACCOUNT_UNCATEGORIZED_TRANSACTIONS_INFINITY,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import t from './types';
|
|||||||
|
|
||||||
const commonInvalidateQueries = (queryClient) => {
|
const commonInvalidateQueries = (queryClient) => {
|
||||||
// Invalidate inventory adjustments.
|
// Invalidate inventory adjustments.
|
||||||
queryClient.invalidateQueries(t.inventory-adjustments);
|
queryClient.invalidateQueries(t.INVENTORY_ADJUSTMENTS);
|
||||||
queryClient.invalidateQueries(t.INVENTORY_ADJUSTMENT);
|
queryClient.invalidateQueries(t.INVENTORY_ADJUSTMENT);
|
||||||
|
|
||||||
// Invalidate items.
|
// Invalidate items.
|
||||||
@@ -120,7 +120,7 @@ export function useInventoryAdjustment(id, props, requestProps) {
|
|||||||
[t.INVENTORY_ADJUSTMENT, id],
|
[t.INVENTORY_ADJUSTMENT, id],
|
||||||
{ method: 'get', url: `inventory-adjustments/${id}`, ...requestProps },
|
{ method: 'get', url: `inventory-adjustments/${id}`, ...requestProps },
|
||||||
{
|
{
|
||||||
select: (res) => res.data.data,
|
select: (res) => res.data,
|
||||||
defaultData: {},
|
defaultData: {},
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ export function useItemInventoryCost(query, props) {
|
|||||||
[t.ITEM_INVENTORY_COST, query],
|
[t.ITEM_INVENTORY_COST, query],
|
||||||
{
|
{
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url: `inventory/items-cost`,
|
url: `inventory-cost/items`,
|
||||||
params: { ...query },
|
params: { ...query },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export function useCreateWarehouseTransfer(props) {
|
|||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
(values) => apiRequest.post('warehouses/transfers', values),
|
(values) => apiRequest.post('warehouse-transfers', values),
|
||||||
{
|
{
|
||||||
onSuccess: (res, values) => {
|
onSuccess: (res, values) => {
|
||||||
// Common invalidate queries.
|
// Common invalidate queries.
|
||||||
@@ -45,7 +45,7 @@ export function useEditWarehouseTransfer(props) {
|
|||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
([id, values]) => apiRequest.post(`warehouses/transfers/${id}`, values),
|
([id, values]) => apiRequest.post(`warehouse-transfers/${id}`, values),
|
||||||
{
|
{
|
||||||
onSuccess: (res, [id, values]) => {
|
onSuccess: (res, [id, values]) => {
|
||||||
// Invalidate specific sale invoice.
|
// Invalidate specific sale invoice.
|
||||||
@@ -66,7 +66,7 @@ export function useDeleteWarehouseTransfer(props) {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
return useMutation((id) => apiRequest.delete(`warehouses/transfers/${id}`), {
|
return useMutation((id) => apiRequest.delete(`warehouse-transfers/${id}`), {
|
||||||
onSuccess: (res, id) => {
|
onSuccess: (res, id) => {
|
||||||
// Common invalidate queries.
|
// Common invalidate queries.
|
||||||
commonInvalidateQueries(queryClient);
|
commonInvalidateQueries(queryClient);
|
||||||
@@ -87,7 +87,7 @@ const transformWarehousesTransfer = (res) => ({
|
|||||||
export function useWarehousesTransfers(query, props) {
|
export function useWarehousesTransfers(query, props) {
|
||||||
return useRequestQuery(
|
return useRequestQuery(
|
||||||
[t.WAREHOUSE_TRANSFERS, query],
|
[t.WAREHOUSE_TRANSFERS, query],
|
||||||
{ method: 'get', url: 'warehouses/transfers', params: query },
|
{ method: 'get', url: 'warehouse-transfers', params: query },
|
||||||
{
|
{
|
||||||
select: transformWarehousesTransfer,
|
select: transformWarehousesTransfer,
|
||||||
defaultData: {
|
defaultData: {
|
||||||
@@ -111,7 +111,7 @@ export function useWarehousesTransfers(query, props) {
|
|||||||
export function useWarehouseTransfer(id, props, requestProps) {
|
export function useWarehouseTransfer(id, props, requestProps) {
|
||||||
return useRequestQuery(
|
return useRequestQuery(
|
||||||
[t.WAREHOUSE_TRANSFER, id],
|
[t.WAREHOUSE_TRANSFER, id],
|
||||||
{ method: 'get', url: `warehouses/transfers/${id}`, ...requestProps },
|
{ method: 'get', url: `warehouse-transfers/${id}`, ...requestProps },
|
||||||
{
|
{
|
||||||
select: (res) => res.data.data,
|
select: (res) => res.data.data,
|
||||||
defaultData: {},
|
defaultData: {},
|
||||||
@@ -130,7 +130,7 @@ export function useInitiateWarehouseTransfer(props) {
|
|||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
(id) => apiRequest.put(`warehouses/transfers/${id}/initiate`),
|
(id) => apiRequest.put(`warehouse-transfers/${id}/initiate`),
|
||||||
{
|
{
|
||||||
onSuccess: (res, id) => {
|
onSuccess: (res, id) => {
|
||||||
queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
|
queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
|
||||||
@@ -153,7 +153,7 @@ export function useTransferredWarehouseTransfer(props) {
|
|||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
(id) => apiRequest.put(`warehouses/transfers/${id}/transferred`),
|
(id) => apiRequest.put(`warehouse-transfers/${id}/transferred`),
|
||||||
{
|
{
|
||||||
onSuccess: (res, id) => {
|
onSuccess: (res, id) => {
|
||||||
queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
|
queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
|
||||||
|
|||||||
Reference in New Issue
Block a user