mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 23:00:34 +00:00
refactor: nestjs
This commit is contained in:
@@ -20,6 +20,16 @@ import { IFilterMeta } from '@/interfaces/Model';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AccountsApplication {
|
export class AccountsApplication {
|
||||||
|
/**
|
||||||
|
* @param {CreateAccountService} createAccountService - The create account service.
|
||||||
|
* @param {EditAccount} editAccountService - The edit account service.
|
||||||
|
* @param {DeleteAccount} deleteAccountService - The delete account service.
|
||||||
|
* @param {ActivateAccount} activateAccountService - The activate account service.
|
||||||
|
* @param {GetAccountTypesService} getAccountTypesService - The get account types service.
|
||||||
|
* @param {GetAccount} getAccountService - The get account service.
|
||||||
|
* @param {GetAccountTransactionsService} getAccountTransactionsService - The get account transactions service.
|
||||||
|
* @param {GetAccountsService} getAccountsService - The get accounts service.
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private readonly createAccountService: CreateAccountService,
|
private readonly createAccountService: CreateAccountService,
|
||||||
private readonly editAccountService: EditAccount,
|
private readonly editAccountService: EditAccount,
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ActivateAccount {
|
export class ActivateAccount {
|
||||||
|
/**
|
||||||
|
* @param {EventEmitter2} eventEmitter - The event emitter.
|
||||||
|
* @param {UnitOfWork} uow - The unit of work.
|
||||||
|
* @param {AccountRepository} accountRepository - The account repository.
|
||||||
|
* @param {TenantModelProxy<typeof Account>} accountModel - The account model.
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
private readonly uow: UnitOfWork,
|
private readonly uow: UnitOfWork,
|
||||||
@@ -21,8 +27,8 @@ export class ActivateAccount {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates/Inactivates the given account.
|
* Activates/Inactivates the given account.
|
||||||
* @param {number} accountId
|
* @param {number} accountId - The account id.
|
||||||
* @param {boolean} activate
|
* @param {boolean} activate - Activate or inactivate the account.
|
||||||
*/
|
*/
|
||||||
public activateAccount = async (accountId: number, activate?: boolean) => {
|
public activateAccount = async (accountId: number, activate?: boolean) => {
|
||||||
// Retrieve the given account or throw not found error.
|
// Retrieve the given account or throw not found error.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
IsString,
|
IsString,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
@@ -11,41 +12,92 @@ export class CreateAccountDTO {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@MinLength(3)
|
@MinLength(3)
|
||||||
@MaxLength(255) // Assuming DATATYPES_LENGTH.STRING is 255
|
@MaxLength(255) // Assuming DATATYPES_LENGTH.STRING is 255
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Account name',
|
||||||
|
example: 'Cash Account',
|
||||||
|
minLength: 3,
|
||||||
|
maxLength: 255,
|
||||||
|
})
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@MinLength(3)
|
@MinLength(3)
|
||||||
@MaxLength(6)
|
@MaxLength(6)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Account code',
|
||||||
|
example: 'CA001',
|
||||||
|
required: false,
|
||||||
|
minLength: 3,
|
||||||
|
maxLength: 6,
|
||||||
|
})
|
||||||
code?: string;
|
code?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Currency code for the account',
|
||||||
|
example: 'USD',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
currencyCode?: string;
|
currencyCode?: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@MinLength(3)
|
@MinLength(3)
|
||||||
@MaxLength(255)
|
@MaxLength(255)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Type of account',
|
||||||
|
example: 'asset',
|
||||||
|
minLength: 3,
|
||||||
|
maxLength: 255,
|
||||||
|
})
|
||||||
accountType: string;
|
accountType: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@MaxLength(65535)
|
@MaxLength(65535)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Account description',
|
||||||
|
example: 'Main cash account for daily operations',
|
||||||
|
required: false,
|
||||||
|
maxLength: 65535,
|
||||||
|
})
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the parent account',
|
||||||
|
example: 1,
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
parentAccountId?: number;
|
parentAccountId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the account is active',
|
||||||
|
example: true,
|
||||||
|
required: false,
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Plaid account ID for syncing',
|
||||||
|
example: 'plaid_account_123456',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
plaidAccountId?: string;
|
plaidAccountId?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Plaid item ID for syncing',
|
||||||
|
example: 'plaid_item_123456',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
plaidItemId?: string;
|
plaidItemId?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
IsString,
|
IsString,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
@@ -9,26 +10,45 @@ import {
|
|||||||
export class EditAccountDTO {
|
export class EditAccountDTO {
|
||||||
@IsString()
|
@IsString()
|
||||||
@MinLength(3)
|
@MinLength(3)
|
||||||
@MaxLength(255) // Assuming DATATYPES_LENGTH.STRING is 255
|
@MaxLength(255)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The name of the account',
|
||||||
|
example: 'Bank Account',
|
||||||
|
})
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@MinLength(3)
|
@MinLength(3)
|
||||||
@MaxLength(6)
|
@MaxLength(6)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The code of the account',
|
||||||
|
example: '123456',
|
||||||
|
})
|
||||||
code?: string;
|
code?: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@MinLength(3)
|
@MinLength(3)
|
||||||
@MaxLength(255) // Assuming DATATYPES_LENGTH.STRING is 255
|
@MaxLength(255)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The type of the account',
|
||||||
|
example: 'Bank Account',
|
||||||
|
})
|
||||||
accountType: string;
|
accountType: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@MaxLength(65535) // Assuming DATATYPES_LENGTH.TEXT is 65535
|
@ApiProperty({
|
||||||
|
description: 'The description of the account',
|
||||||
|
example: 'This is a description',
|
||||||
|
})
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The parent account ID of the account',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
parentAccountId?: number;
|
parentAccountId?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { BankRuleComparator } from '../types';
|
import { BankRuleComparator } from '../types';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
class BankRuleConditionDto {
|
class BankRuleConditionDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@@ -37,43 +38,83 @@ class BankRuleConditionDto {
|
|||||||
export class CommandBankRuleDto {
|
export class CommandBankRuleDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The name of the bank rule',
|
||||||
|
example: 'Monthly Salary',
|
||||||
|
})
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The order of the bank rule',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
order: number;
|
order: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The account ID to apply the rule if',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
applyIfAccountId?: number;
|
applyIfAccountId?: number;
|
||||||
|
|
||||||
@IsIn(['deposit', 'withdrawal'])
|
@IsIn(['deposit', 'withdrawal'])
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The transaction type to apply the rule if',
|
||||||
|
example: 'deposit',
|
||||||
|
})
|
||||||
applyIfTransactionType: 'deposit' | 'withdrawal';
|
applyIfTransactionType: 'deposit' | 'withdrawal';
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsIn(['and', 'or'])
|
@IsIn(['and', 'or'])
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The conditions type to apply the rule if',
|
||||||
|
example: 'and',
|
||||||
|
})
|
||||||
conditionsType: 'and' | 'or' = 'and';
|
conditionsType: 'and' | 'or' = 'and';
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@ArrayMinSize(1)
|
@ArrayMinSize(1)
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => BankRuleConditionDto)
|
@Type(() => BankRuleConditionDto)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The conditions to apply the rule if',
|
||||||
|
example: [{ field: 'description', comparator: 'contains', value: 'Salary' }],
|
||||||
|
})
|
||||||
conditions: BankRuleConditionDto[];
|
conditions: BankRuleConditionDto[];
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The category to assign the rule if',
|
||||||
|
example: 'Income:Salary',
|
||||||
|
})
|
||||||
assignCategory: string;
|
assignCategory: string;
|
||||||
|
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The account ID to assign the rule if',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
assignAccountId: number;
|
assignAccountId: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The payee to assign the rule if',
|
||||||
|
example: 'Employer Inc.',
|
||||||
|
})
|
||||||
assignPayee?: string;
|
assignPayee?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The memo to assign the rule if',
|
||||||
|
example: 'Monthly Salary',
|
||||||
|
})
|
||||||
assignMemo?: string;
|
assignMemo?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export class GetBankRuleService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the bank rule.
|
* Retrieves the bank rule.
|
||||||
* @param {number} ruleId
|
* @param {number} ruleId - Rule id.
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
async getBankRule(ruleId: number): Promise<any> {
|
async getBankRule(ruleId: number): Promise<any> {
|
||||||
|
|||||||
@@ -6,14 +6,23 @@ import {
|
|||||||
ValidateNested,
|
ValidateNested,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class MatchTransactionEntryDto {
|
export class MatchTransactionEntryDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The type of the reference',
|
||||||
|
example: 'SaleInvoice',
|
||||||
|
})
|
||||||
referenceType: string;
|
referenceType: string;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The ID of the reference',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
referenceId: number;
|
referenceId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,5 +30,12 @@ export class MatchBankTransactionDto {
|
|||||||
@IsArray()
|
@IsArray()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => MatchTransactionEntryDto)
|
@Type(() => MatchTransactionEntryDto)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The entries to match',
|
||||||
|
example: [
|
||||||
|
{ referenceType: 'SaleInvoice', referenceId: 1 },
|
||||||
|
{ referenceType: 'SaleInvoice', referenceId: 2 },
|
||||||
|
],
|
||||||
|
})
|
||||||
entries: MatchTransactionEntryDto[];
|
entries: MatchTransactionEntryDto[];
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,15 @@ import { CreateBranchDto, EditBranchDto } from './dtos/Branch.dto';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BranchesApplication {
|
export class BranchesApplication {
|
||||||
|
/**
|
||||||
|
* @param {CreateBranchService} createBranchService - Create branch service.
|
||||||
|
* @param {EditBranchService} editBranchService - Edit branch service.
|
||||||
|
* @param {DeleteBranchService} deleteBranchService - Delete branch service.
|
||||||
|
* @param {GetBranchService} getBranchService - Get branch service.
|
||||||
|
* @param {GetBranchesService} getBranchesService - Get branches service.
|
||||||
|
* @param {ActivateBranches} activateBranchesService - Activate branches service.
|
||||||
|
* @param {MarkBranchAsPrimaryService} markBranchAsPrimaryService - Mark branch as primary service.
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private readonly createBranchService: CreateBranchService,
|
private readonly createBranchService: CreateBranchService,
|
||||||
private readonly editBranchService: EditBranchService,
|
private readonly editBranchService: EditBranchService,
|
||||||
|
|||||||
@@ -9,48 +9,76 @@ import {
|
|||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
class CommandBranchDto {
|
class CommandBranchDto {
|
||||||
@ApiProperty({ description: 'Branch name' })
|
@ApiProperty({
|
||||||
|
description: 'Branch name',
|
||||||
|
example: 'Main Branch',
|
||||||
|
})
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsString()
|
@IsString()
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch code' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Whether this is the primary branch',
|
||||||
|
example: true,
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
primary?: boolean;
|
primary?: boolean;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch code' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Branch code',
|
||||||
|
example: 'BR001',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
code?: string;
|
code?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch address' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Branch address',
|
||||||
|
example: '123 Main Street',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
address?: string;
|
address?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch city' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Branch city',
|
||||||
|
example: 'New York',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
city?: string;
|
city?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch country' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Branch country',
|
||||||
|
example: 'USA',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
country?: string;
|
country?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch phone number' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Branch phone number',
|
||||||
|
example: '+1-555-123-4567',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
phone_number?: string;
|
phone_number?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch email' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Branch email',
|
||||||
|
example: 'branch@example.com',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsEmail()
|
@IsEmail()
|
||||||
@IsString()
|
@IsString()
|
||||||
email?: string;
|
email?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: 'Branch website' })
|
@ApiPropertyOptional({
|
||||||
|
description: 'Branch website',
|
||||||
|
example: 'https://www.example.com/branch',
|
||||||
|
})
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsUrl()
|
@IsUrl()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { BrandingTemplateDTOTransformer } from '../../PdfTemplate/BrandingTempla
|
|||||||
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
|
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
|
||||||
import { CreditNoteAutoIncrementService } from './CreditNoteAutoIncrement.service';
|
import { CreditNoteAutoIncrementService } from './CreditNoteAutoIncrement.service';
|
||||||
import { CreditNote } from '../models/CreditNote';
|
import { CreditNote } from '../models/CreditNote';
|
||||||
import { CreateCreditNoteDto, EditCreditNoteDto } from '../dtos/CreditNote.dto';
|
import { CreateCreditNoteDto, CreditNoteEntryDto, EditCreditNoteDto } from '../dtos/CreditNote.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CommandCreditNoteDTOTransform {
|
export class CommandCreditNoteDTOTransform {
|
||||||
@@ -55,7 +55,7 @@ export class CommandCreditNoteDTOTransform {
|
|||||||
assocItemEntriesDefaultIndex,
|
assocItemEntriesDefaultIndex,
|
||||||
|
|
||||||
// Associate the reference type to credit note entries.
|
// Associate the reference type to credit note entries.
|
||||||
R.map((entry: ICreditNoteEntryNewDTO) => ({
|
R.map((entry: CreditNoteEntryDto) => ({
|
||||||
...entry,
|
...entry,
|
||||||
referenceType: 'CreditNote',
|
referenceType: 'CreditNote',
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ enum DiscountType {
|
|||||||
Amount = 'amount',
|
Amount = 'amount',
|
||||||
}
|
}
|
||||||
|
|
||||||
class CreditNoteEntryDto extends ItemEntryDto {}
|
export class CreditNoteEntryDto extends ItemEntryDto {}
|
||||||
|
|
||||||
class AttachmentDto {
|
class AttachmentDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@@ -8,13 +8,11 @@ import {
|
|||||||
Put,
|
Put,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { CustomersApplication } from './CustomersApplication.service';
|
import { CustomersApplication } from './CustomersApplication.service';
|
||||||
import {
|
import { ICustomerOpeningBalanceEditDTO } from './types/Customers.types';
|
||||||
ICustomerEditDTO,
|
|
||||||
ICustomerNewDTO,
|
|
||||||
ICustomerOpeningBalanceEditDTO,
|
|
||||||
} from './types/Customers.types';
|
|
||||||
import { PublicRoute } from '../Auth/Jwt.guard';
|
import { PublicRoute } from '../Auth/Jwt.guard';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { CreateCustomerDto } from './dtos/CreateCustomer.dto';
|
||||||
|
import { EditCustomerDto } from './dtos/EditCustomer.dto';
|
||||||
|
|
||||||
@Controller('customers')
|
@Controller('customers')
|
||||||
@ApiTags('customers')
|
@ApiTags('customers')
|
||||||
@@ -30,7 +28,7 @@ export class CustomersController {
|
|||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@ApiOperation({ summary: 'Create a new customer.' })
|
@ApiOperation({ summary: 'Create a new customer.' })
|
||||||
createCustomer(@Body() customerDTO: ICustomerNewDTO) {
|
createCustomer(@Body() customerDTO: CreateCustomerDto) {
|
||||||
return this.customersApplication.createCustomer(customerDTO);
|
return this.customersApplication.createCustomer(customerDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +36,7 @@ export class CustomersController {
|
|||||||
@ApiOperation({ summary: 'Edit the given customer.' })
|
@ApiOperation({ summary: 'Edit the given customer.' })
|
||||||
editCustomer(
|
editCustomer(
|
||||||
@Param('id') customerId: number,
|
@Param('id') customerId: number,
|
||||||
@Body() customerDTO: ICustomerEditDTO,
|
@Body() customerDTO: EditCustomerDto,
|
||||||
) {
|
) {
|
||||||
return this.customersApplication.editCustomer(customerId, customerDTO);
|
return this.customersApplication.editCustomer(customerId, customerDTO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ import { CreateCustomer } from './commands/CreateCustomer.service';
|
|||||||
import { EditCustomer } from './commands/EditCustomer.service';
|
import { EditCustomer } from './commands/EditCustomer.service';
|
||||||
import { DeleteCustomer } from './commands/DeleteCustomer.service';
|
import { DeleteCustomer } from './commands/DeleteCustomer.service';
|
||||||
import { EditOpeningBalanceCustomer } from './commands/EditOpeningBalanceCustomer.service';
|
import { EditOpeningBalanceCustomer } from './commands/EditOpeningBalanceCustomer.service';
|
||||||
import {
|
import { ICustomerOpeningBalanceEditDTO } from './types/Customers.types';
|
||||||
ICustomerEditDTO,
|
import { CreateCustomerDto } from './dtos/CreateCustomer.dto';
|
||||||
ICustomerNewDTO,
|
import { EditCustomerDto } from './dtos/EditCustomer.dto';
|
||||||
ICustomerOpeningBalanceEditDTO,
|
|
||||||
// ICustomersFilter,
|
|
||||||
} from './types/Customers.types';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CustomersApplication {
|
export class CustomersApplication {
|
||||||
@@ -36,7 +33,7 @@ export class CustomersApplication {
|
|||||||
* @param {ICustomerNewDTO} customerDTO
|
* @param {ICustomerNewDTO} customerDTO
|
||||||
* @returns {Promise<ICustomer>}
|
* @returns {Promise<ICustomer>}
|
||||||
*/
|
*/
|
||||||
public createCustomer = (customerDTO: ICustomerNewDTO) => {
|
public createCustomer = (customerDTO: CreateCustomerDto) => {
|
||||||
return this.createCustomerService.createCustomer(customerDTO);
|
return this.createCustomerService.createCustomer(customerDTO);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,7 +43,7 @@ export class CustomersApplication {
|
|||||||
* @param {ICustomerEditDTO} customerDTO - Customer edit DTO.
|
* @param {ICustomerEditDTO} customerDTO - Customer edit DTO.
|
||||||
* @return {Promise<ICustomer>}
|
* @return {Promise<ICustomer>}
|
||||||
*/
|
*/
|
||||||
public editCustomer = (customerId: number, customerDTO: ICustomerEditDTO) => {
|
public editCustomer = (customerId: number, customerDTO: EditCustomerDto) => {
|
||||||
return this.editCustomerService.editCustomer(customerId, customerDTO);
|
return this.editCustomerService.editCustomer(customerId, customerDTO);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import { events } from '@/common/events/events';
|
|||||||
import {
|
import {
|
||||||
ICustomerEventCreatedPayload,
|
ICustomerEventCreatedPayload,
|
||||||
ICustomerEventCreatingPayload,
|
ICustomerEventCreatingPayload,
|
||||||
ICustomerNewDTO,
|
|
||||||
} from '../types/Customers.types';
|
} from '../types/Customers.types';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
|
import { CreateCustomerDto } from '../dtos/CreateCustomer.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CreateCustomer {
|
export class CreateCustomer {
|
||||||
@@ -35,7 +35,7 @@ export class CreateCustomer {
|
|||||||
* @return {Promise<ICustomer>}
|
* @return {Promise<ICustomer>}
|
||||||
*/
|
*/
|
||||||
public async createCustomer(
|
public async createCustomer(
|
||||||
customerDTO: ICustomerNewDTO,
|
customerDTO: CreateCustomerDto,
|
||||||
trx?: Knex.Transaction,
|
trx?: Knex.Transaction,
|
||||||
): Promise<Customer> {
|
): Promise<Customer> {
|
||||||
// Transformes the customer DTO to customer object.
|
// Transformes the customer DTO to customer object.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { events } from '@/common/events/events';
|
|||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
|
import { EditCustomerDto } from '../dtos/EditCustomer.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EditCustomer {
|
export class EditCustomer {
|
||||||
@@ -37,7 +38,7 @@ export class EditCustomer {
|
|||||||
*/
|
*/
|
||||||
public async editCustomer(
|
public async editCustomer(
|
||||||
customerId: number,
|
customerId: number,
|
||||||
customerDTO: ICustomerEditDTO,
|
customerDTO: EditCustomerDto,
|
||||||
): Promise<Customer> {
|
): Promise<Customer> {
|
||||||
// Retrieve the customer or throw not found error.
|
// Retrieve the customer or throw not found error.
|
||||||
const oldCustomer = await this.customerModel()
|
const oldCustomer = await this.customerModel()
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import { IsEmail, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class ContactAddressDto {
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address line 1' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
billingAddress1?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address line 2' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
billingAddress2?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address city' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
billingAddressCity?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address country' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
billingAddressCountry?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address email' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail()
|
||||||
|
billingAddressEmail?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address zipcode' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
billingAddressZipcode?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address phone' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
billingAddressPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Billing address state' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
billingAddressState?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address line 1' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
shippingAddress1?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address line 2' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
shippingAddress2?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address city' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
shippingAddressCity?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address country' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
shippingAddressCountry?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address email' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail()
|
||||||
|
shippingAddressEmail?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address zipcode' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
shippingAddressZipcode?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address phone' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
shippingAddressPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Shipping address state' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
shippingAddressState?: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import {
|
||||||
|
IsBoolean,
|
||||||
|
IsEmail,
|
||||||
|
IsNotEmpty,
|
||||||
|
IsNumber,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
} from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { ContactAddressDto } from './ContactAddress.dto';
|
||||||
|
|
||||||
|
export class CreateCustomerDto extends ContactAddressDto {
|
||||||
|
@ApiProperty({ required: true, description: 'Customer type' })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
customerType: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: true, description: 'Currency code' })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
currencyCode: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Opening balance' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
openingBalance?: number;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Opening balance date' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
openingBalanceAt?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
required: false,
|
||||||
|
description: 'Opening balance exchange rate',
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
openingBalanceExchangeRate?: number;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Opening balance branch ID' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
openingBalanceBranchId?: number;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Salutation' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
salutation?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'First name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
firstName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Last name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
lastName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Company name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
companyName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: true, description: 'Display name' })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
displayName: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Website' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
website?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Email' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail()
|
||||||
|
email?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Work phone' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
workPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Personal phone' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
personalPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Note' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
note?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Active status', default: true })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
active?: boolean;
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { ContactAddressDto } from './ContactAddress.dto';
|
||||||
|
|
||||||
|
export class EditCustomerDto extends ContactAddressDto {
|
||||||
|
@ApiProperty({ required: true, description: 'Customer type' })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
customerType: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Salutation' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
salutation?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'First name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
firstName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Last name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
lastName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Company name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
companyName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: true, description: 'Display name' })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
displayName: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Website' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
website?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Email' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail()
|
||||||
|
email?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Work phone' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
workPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Personal phone' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
personalPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Note' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
note?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Active status' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
active?: boolean;
|
||||||
|
}
|
||||||
@@ -1,23 +1,5 @@
|
|||||||
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
|
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
|
||||||
// import TenantModel from 'models/TenantModel';
|
|
||||||
// import PaginationQueryBuilder from './Pagination';
|
|
||||||
// import ModelSetting from './ModelSetting';
|
|
||||||
// import CustomerSettings from './Customer.Settings';
|
|
||||||
// import CustomViewBaseModel from './CustomViewBaseModel';
|
|
||||||
// import { DEFAULT_VIEWS } from '@/services/Contacts/Customers/constants';
|
|
||||||
// import ModelSearchable from './ModelSearchable';
|
|
||||||
|
|
||||||
// class CustomerQueryBuilder extends PaginationQueryBuilder {
|
|
||||||
// constructor(...args) {
|
|
||||||
// super(...args);
|
|
||||||
|
|
||||||
// this.onBuild((builder) => {
|
|
||||||
// if (builder.isFind() || builder.isDelete() || builder.isUpdate()) {
|
|
||||||
// builder.where('contact_service', 'customer');
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
export class Customer extends TenantBaseModel{
|
export class Customer extends TenantBaseModel{
|
||||||
contactService: string;
|
contactService: string;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { Customer } from '../models/Customer';
|
|||||||
import { IContactAddressDTO } from '@/modules/Contacts/types/Contacts.types';
|
import { IContactAddressDTO } from '@/modules/Contacts/types/Contacts.types';
|
||||||
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
|
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
|
||||||
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
|
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
|
||||||
|
import { CreateCustomerDto } from '../dtos/CreateCustomer.dto';
|
||||||
|
import { EditCustomerDto } from '../dtos/EditCustomer.dto';
|
||||||
|
|
||||||
// Customer Interfaces.
|
// Customer Interfaces.
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
@@ -63,46 +65,38 @@ export interface GetCustomersResponse {
|
|||||||
// Customer Events.
|
// Customer Events.
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
export interface ICustomerEventCreatedPayload {
|
export interface ICustomerEventCreatedPayload {
|
||||||
// tenantId: number;
|
|
||||||
customerId: number;
|
customerId: number;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
customer: Customer;
|
customer: Customer;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface ICustomerEventCreatingPayload {
|
export interface ICustomerEventCreatingPayload {
|
||||||
// tenantId: number;
|
customerDTO: CreateCustomerDto;
|
||||||
customerDTO: ICustomerNewDTO;
|
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface ICustomerEventEditedPayload {
|
export interface ICustomerEventEditedPayload {
|
||||||
// tenantId: number
|
|
||||||
customerId: number;
|
customerId: number;
|
||||||
customer: Customer;
|
customer: Customer;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICustomerEventEditingPayload {
|
export interface ICustomerEventEditingPayload {
|
||||||
// tenantId: number;
|
customerDTO: EditCustomerDto;
|
||||||
customerDTO: ICustomerEditDTO;
|
|
||||||
customerId: number;
|
customerId: number;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICustomerDeletingPayload {
|
export interface ICustomerDeletingPayload {
|
||||||
// tenantId: number;
|
|
||||||
customerId: number;
|
customerId: number;
|
||||||
oldCustomer: Customer;
|
oldCustomer: Customer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICustomerEventDeletedPayload {
|
export interface ICustomerEventDeletedPayload {
|
||||||
// tenantId: number;
|
|
||||||
customerId: number;
|
customerId: number;
|
||||||
oldCustomer: Customer;
|
oldCustomer: Customer;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface ICustomerEventCreatingPayload {
|
export interface ICustomerEventCreatingPayload {
|
||||||
// tenantId: number;
|
customerDTO: CreateCustomerDto;
|
||||||
customerDTO: ICustomerNewDTO;
|
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export enum CustomerAction {
|
export enum CustomerAction {
|
||||||
@@ -141,13 +135,11 @@ export interface ICustomerOpeningBalanceEditedPayload {
|
|||||||
|
|
||||||
|
|
||||||
export interface ICustomerActivatingPayload {
|
export interface ICustomerActivatingPayload {
|
||||||
// tenantId: number;
|
|
||||||
trx: Knex.Transaction,
|
trx: Knex.Transaction,
|
||||||
oldCustomer: Customer;
|
oldCustomer: Customer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICustomerActivatedPayload {
|
export interface ICustomerActivatedPayload {
|
||||||
// tenantId: number;
|
|
||||||
trx?: Knex.Transaction;
|
trx?: Knex.Transaction;
|
||||||
oldCustomer: Customer;
|
oldCustomer: Customer;
|
||||||
customer: Customer;
|
customer: Customer;
|
||||||
|
|||||||
@@ -9,13 +9,10 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ExpensesApplication } from './ExpensesApplication.service';
|
import { ExpensesApplication } from './ExpensesApplication.service';
|
||||||
import {
|
|
||||||
IExpenseCreateDTO,
|
|
||||||
IExpenseEditDTO,
|
|
||||||
} from './interfaces/Expenses.interface';
|
|
||||||
import { PublicRoute } from '../Auth/Jwt.guard';
|
import { PublicRoute } from '../Auth/Jwt.guard';
|
||||||
import { IExpensesFilter } from './Expenses.types';
|
import { IExpensesFilter } from './Expenses.types';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { CreateExpenseDto, EditExpenseDto } from './dtos/Expense.dto';
|
||||||
|
|
||||||
@Controller('expenses')
|
@Controller('expenses')
|
||||||
@ApiTags('expenses')
|
@ApiTags('expenses')
|
||||||
@@ -29,7 +26,7 @@ export class ExpensesController {
|
|||||||
*/
|
*/
|
||||||
@Post()
|
@Post()
|
||||||
@ApiOperation({ summary: 'Create a new expense transaction.' })
|
@ApiOperation({ summary: 'Create a new expense transaction.' })
|
||||||
public createExpense(@Body() expenseDTO: IExpenseCreateDTO) {
|
public createExpense(@Body() expenseDTO: CreateExpenseDto) {
|
||||||
return this.expensesApplication.createExpense(expenseDTO);
|
return this.expensesApplication.createExpense(expenseDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +39,7 @@ export class ExpensesController {
|
|||||||
@ApiOperation({ summary: 'Edit the given expense transaction.' })
|
@ApiOperation({ summary: 'Edit the given expense transaction.' })
|
||||||
public editExpense(
|
public editExpense(
|
||||||
@Param('id') expenseId: number,
|
@Param('id') expenseId: number,
|
||||||
@Body() expenseDTO: IExpenseEditDTO,
|
@Body() expenseDTO: EditExpenseDto,
|
||||||
) {
|
) {
|
||||||
return this.expensesApplication.editExpense(expenseId, expenseDTO);
|
return this.expensesApplication.editExpense(expenseId, expenseDTO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ import { EditExpense } from './commands/EditExpense.service';
|
|||||||
import { DeleteExpense } from './commands/DeleteExpense.service';
|
import { DeleteExpense } from './commands/DeleteExpense.service';
|
||||||
import { PublishExpense } from './commands/PublishExpense.service';
|
import { PublishExpense } from './commands/PublishExpense.service';
|
||||||
import { GetExpenseService } from './queries/GetExpense.service';
|
import { GetExpenseService } from './queries/GetExpense.service';
|
||||||
import {
|
import { IExpensesFilter } from './interfaces/Expenses.interface';
|
||||||
IExpenseCreateDTO,
|
|
||||||
IExpenseEditDTO,
|
|
||||||
IExpensesFilter,
|
|
||||||
} from './interfaces/Expenses.interface';
|
|
||||||
import { GetExpensesService } from './queries/GetExpenses.service';
|
import { GetExpensesService } from './queries/GetExpenses.service';
|
||||||
|
import { CreateExpenseDto, EditExpenseDto } from './dtos/Expense.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExpensesApplication {
|
export class ExpensesApplication {
|
||||||
@@ -24,55 +21,55 @@ export class ExpensesApplication {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new expense transaction.
|
* Create a new expense transaction.
|
||||||
* @param {IExpenseDTO} expenseDTO
|
* @param {CreateExpenseDto} expenseDTO
|
||||||
* @returns {Promise<Expense>}
|
* @returns {Promise<Expense>}
|
||||||
*/
|
*/
|
||||||
public createExpense = (expenseDTO: IExpenseCreateDTO) => {
|
public createExpense(expenseDTO: CreateExpenseDto) {
|
||||||
return this.createExpenseService.newExpense(expenseDTO);
|
return this.createExpenseService.newExpense(expenseDTO);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits the given expense transaction.
|
* Edits the given expense transaction.
|
||||||
* @param {number} expenseId - Expense id.
|
* @param {number} expenseId - Expense id.
|
||||||
* @param {IExpenseEditDTO} expenseDTO
|
* @param {EditExpenseDto} expenseDTO
|
||||||
* @returns {Promise<Expense>}
|
* @returns {Promise<Expense>}
|
||||||
*/
|
*/
|
||||||
public editExpense = (expenseId: number, expenseDTO: IExpenseEditDTO) => {
|
public editExpense(expenseId: number, expenseDTO: EditExpenseDto) {
|
||||||
return this.editExpenseService.editExpense(expenseId, expenseDTO);
|
return this.editExpenseService.editExpense(expenseId, expenseDTO);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the given expense.
|
* Deletes the given expense.
|
||||||
* @param {number} expenseId - Expense id.
|
* @param {number} expenseId - Expense id.
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public deleteExpense = (expenseId: number) => {
|
public deleteExpense(expenseId: number) {
|
||||||
return this.deleteExpenseService.deleteExpense(expenseId);
|
return this.deleteExpenseService.deleteExpense(expenseId);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publishes the given expense.
|
* Publishes the given expense.
|
||||||
* @param {number} expenseId - Expense id.
|
* @param {number} expenseId - Expense id.
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public publishExpense = (expenseId: number) => {
|
public publishExpense(expenseId: number) {
|
||||||
return this.publishExpenseService.publishExpense(expenseId);
|
return this.publishExpenseService.publishExpense(expenseId);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the given expense details.
|
* Retrieve the given expense details.
|
||||||
* @param {number} expenseId -Expense id.
|
* @param {number} expenseId -Expense id.
|
||||||
* @return {Promise<Expense>}
|
* @return {Promise<Expense>}
|
||||||
*/
|
*/
|
||||||
public getExpense = (expenseId: number) => {
|
public getExpense(expenseId: number) {
|
||||||
return this.getExpenseService.getExpense(expenseId);
|
return this.getExpenseService.getExpense(expenseId);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve expenses paginated list.
|
* Retrieve expenses paginated list.
|
||||||
* @param {IExpensesFilter} expensesFilter
|
* @param {IExpensesFilter} expensesFilter
|
||||||
*/
|
*/
|
||||||
public getExpenses = (filterDTO: IExpensesFilter) => {
|
public getExpenses(filterDTO: IExpensesFilter) {
|
||||||
return this.getExpensesService.getExpensesList(filterDTO);
|
return this.getExpensesService.getExpensesList(filterDTO);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,11 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { omit, sumBy } from 'lodash';
|
import { omit, sumBy } from 'lodash';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import {
|
|
||||||
IExpenseCreateDTO,
|
|
||||||
IExpenseEditDTO,
|
|
||||||
} from '../interfaces/Expenses.interface';
|
|
||||||
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
||||||
import { Expense } from '../models/Expense.model';
|
import { Expense } from '../models/Expense.model';
|
||||||
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
|
import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index';
|
||||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||||
|
import { CreateExpenseDto, EditExpenseDto } from '../dtos/Expense.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExpenseDTOTransformer {
|
export class ExpenseDTOTransformer {
|
||||||
@@ -28,7 +25,7 @@ export class ExpenseDTOTransformer {
|
|||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
private getExpenseLandedCostAmount = (
|
private getExpenseLandedCostAmount = (
|
||||||
expenseDTO: IExpenseCreateDTO | IExpenseEditDTO,
|
expenseDTO: CreateExpenseDto | EditExpenseDto,
|
||||||
): number => {
|
): number => {
|
||||||
const landedCostEntries = expenseDTO.categories.filter((entry) => {
|
const landedCostEntries = expenseDTO.categories.filter((entry) => {
|
||||||
return entry.landedCost === true;
|
return entry.landedCost === true;
|
||||||
@@ -52,7 +49,7 @@ export class ExpenseDTOTransformer {
|
|||||||
* @return {IExpense}
|
* @return {IExpense}
|
||||||
*/
|
*/
|
||||||
private expenseDTOToModel(
|
private expenseDTOToModel(
|
||||||
expenseDTO: IExpenseCreateDTO | IExpenseEditDTO,
|
expenseDTO: CreateExpenseDto | EditExpenseDto,
|
||||||
): Expense {
|
): Expense {
|
||||||
const landedCostAmount = this.getExpenseLandedCostAmount(expenseDTO);
|
const landedCostAmount = this.getExpenseLandedCostAmount(expenseDTO);
|
||||||
const totalAmount = this.getExpenseCategoriesTotal(expenseDTO.categories);
|
const totalAmount = this.getExpenseCategoriesTotal(expenseDTO.categories);
|
||||||
@@ -85,7 +82,7 @@ export class ExpenseDTOTransformer {
|
|||||||
* @returns {Promise<Expense>}
|
* @returns {Promise<Expense>}
|
||||||
*/
|
*/
|
||||||
public expenseCreateDTO = async (
|
public expenseCreateDTO = async (
|
||||||
expenseDTO: IExpenseCreateDTO,
|
expenseDTO: CreateExpenseDto | EditExpenseDto,
|
||||||
): Promise<Partial<Expense>> => {
|
): Promise<Partial<Expense>> => {
|
||||||
const initialDTO = this.expenseDTOToModel(expenseDTO);
|
const initialDTO = this.expenseDTOToModel(expenseDTO);
|
||||||
const tenant = await this.tenancyContext.getTenant(true);
|
const tenant = await this.tenancyContext.getTenant(true);
|
||||||
@@ -104,13 +101,11 @@ export class ExpenseDTOTransformer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Transformes the expense edit DTO.
|
* Transformes the expense edit DTO.
|
||||||
* @param {number} tenantId
|
* @param {EditExpenseDto} expenseDTO
|
||||||
* @param {IExpenseEditDTO} expenseDTO
|
* @returns {Promise<Expense>}
|
||||||
* @param {ISystemUser} user
|
|
||||||
* @returns {IExpense}
|
|
||||||
*/
|
*/
|
||||||
public expenseEditDTO = async (
|
public expenseEditDTO = async (
|
||||||
expenseDTO: IExpenseEditDTO,
|
expenseDTO: EditExpenseDto,
|
||||||
): Promise<Expense> => {
|
): Promise<Expense> => {
|
||||||
return this.expenseDTOToModel(expenseDTO);
|
return this.expenseDTOToModel(expenseDTO);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
import { sumBy, difference } from 'lodash';
|
import { sumBy, difference } from 'lodash';
|
||||||
import { ERRORS, SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES } from '../constants';
|
import { ERRORS, SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES } from '../constants';
|
||||||
import {
|
|
||||||
IExpenseCreateDTO,
|
|
||||||
IExpenseEditDTO,
|
|
||||||
} from '../interfaces/Expenses.interface';
|
|
||||||
import { ACCOUNT_ROOT_TYPE } from '@/constants/accounts';
|
import { ACCOUNT_ROOT_TYPE } from '@/constants/accounts';
|
||||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Expense } from '../models/Expense.model';
|
import { Expense } from '../models/Expense.model';
|
||||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||||
|
import { CreateExpenseDto, EditExpenseDto } from '../dtos/Expense.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CommandExpenseValidator {
|
export class CommandExpenseValidator {
|
||||||
@@ -18,7 +15,7 @@ export class CommandExpenseValidator {
|
|||||||
* @throws {ServiceError}
|
* @throws {ServiceError}
|
||||||
*/
|
*/
|
||||||
public validateCategoriesNotEqualZero = (
|
public validateCategoriesNotEqualZero = (
|
||||||
expenseDTO: IExpenseCreateDTO | IExpenseEditDTO,
|
expenseDTO: CreateExpenseDto | EditExpenseDto,
|
||||||
) => {
|
) => {
|
||||||
const totalAmount = sumBy(expenseDTO.categories, 'amount') || 0;
|
const totalAmount = sumBy(expenseDTO.categories, 'amount') || 0;
|
||||||
|
|
||||||
@@ -30,7 +27,6 @@ export class CommandExpenseValidator {
|
|||||||
/**
|
/**
|
||||||
* Retrieve expense accounts or throw error in case one of the given accounts
|
* Retrieve expense accounts or throw error in case one of the given accounts
|
||||||
* not found not the storage.
|
* not found not the storage.
|
||||||
* @param {Array<Account>} tenantId
|
|
||||||
* @param {number} expenseAccountsIds
|
* @param {number} expenseAccountsIds
|
||||||
* @throws {ServiceError}
|
* @throws {ServiceError}
|
||||||
* @returns {Promise<IAccount[]>}
|
* @returns {Promise<IAccount[]>}
|
||||||
@@ -40,7 +36,6 @@ export class CommandExpenseValidator {
|
|||||||
DTOAccountsIds: number[],
|
DTOAccountsIds: number[],
|
||||||
) {
|
) {
|
||||||
const storedExpenseAccountsIds = expenseAccounts.map((a: Account) => a.id);
|
const storedExpenseAccountsIds = expenseAccounts.map((a: Account) => a.id);
|
||||||
|
|
||||||
const notStoredAccountsIds = difference(
|
const notStoredAccountsIds = difference(
|
||||||
DTOAccountsIds,
|
DTOAccountsIds,
|
||||||
storedExpenseAccountsIds,
|
storedExpenseAccountsIds,
|
||||||
@@ -84,7 +79,6 @@ export class CommandExpenseValidator {
|
|||||||
/**
|
/**
|
||||||
* Validates the expense has not associated landed cost
|
* Validates the expense has not associated landed cost
|
||||||
* references to the given expense.
|
* references to the given expense.
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {number} expenseId
|
* @param {number} expenseId
|
||||||
*/
|
*/
|
||||||
public async validateNoAssociatedLandedCost(expenseId: number) {
|
public async validateNoAssociatedLandedCost(expenseId: number) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import {
|
import {
|
||||||
IExpenseCreateDTO,
|
|
||||||
IExpenseCreatedPayload,
|
IExpenseCreatedPayload,
|
||||||
IExpenseCreatingPayload,
|
IExpenseCreatingPayload,
|
||||||
} from '../interfaces/Expenses.interface';
|
} from '../interfaces/Expenses.interface';
|
||||||
@@ -13,6 +12,7 @@ import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
|||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
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 { CreateExpenseDto } from '../dtos/Expense.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CreateExpense {
|
export class CreateExpense {
|
||||||
@@ -41,7 +41,7 @@ export class CreateExpense {
|
|||||||
* Authorize before create a new expense transaction.
|
* Authorize before create a new expense transaction.
|
||||||
* @param {IExpenseDTO} expenseDTO
|
* @param {IExpenseDTO} expenseDTO
|
||||||
*/
|
*/
|
||||||
private authorize = async (expenseDTO: IExpenseCreateDTO) => {
|
private authorize = async (expenseDTO: CreateExpenseDto) => {
|
||||||
// Validate payment account existance on the storage.
|
// Validate payment account existance on the storage.
|
||||||
const paymentAccount = await this.accountModel()
|
const paymentAccount = await this.accountModel()
|
||||||
.query()
|
.query()
|
||||||
@@ -86,7 +86,7 @@ export class CreateExpense {
|
|||||||
* @param {IExpenseDTO} expenseDTO
|
* @param {IExpenseDTO} expenseDTO
|
||||||
*/
|
*/
|
||||||
public newExpense = async (
|
public newExpense = async (
|
||||||
expenseDTO: IExpenseCreateDTO,
|
expenseDTO: CreateExpenseDto,
|
||||||
trx?: Knex.Transaction,
|
trx?: Knex.Transaction,
|
||||||
): Promise<Expense> => {
|
): Promise<Expense> => {
|
||||||
// Authorize before create a new expense.
|
// Authorize before create a new expense.
|
||||||
|
|||||||
@@ -3,17 +3,16 @@ import { Knex } from 'knex';
|
|||||||
import {
|
import {
|
||||||
IExpenseEventEditPayload,
|
IExpenseEventEditPayload,
|
||||||
IExpenseEventEditingPayload,
|
IExpenseEventEditingPayload,
|
||||||
IExpenseEditDTO,
|
|
||||||
} from '../interfaces/Expenses.interface';
|
} from '../interfaces/Expenses.interface';
|
||||||
import { CommandExpenseValidator } from './CommandExpenseValidator.service';
|
import { CommandExpenseValidator } from './CommandExpenseValidator.service';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { ExpenseDTOTransformer } from './CommandExpenseDTO.transformer';
|
import { ExpenseDTOTransformer } from './CommandExpenseDTO.transformer';
|
||||||
// import { EntriesService } from '@/services/Entries';
|
|
||||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||||
import { Expense } from '../models/Expense.model';
|
import { Expense } from '../models/Expense.model';
|
||||||
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 { EditExpenseDto } from '../dtos/Expense.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EditExpense {
|
export class EditExpense {
|
||||||
@@ -30,7 +29,6 @@ export class EditExpense {
|
|||||||
private uow: UnitOfWork,
|
private uow: UnitOfWork,
|
||||||
private validator: CommandExpenseValidator,
|
private validator: CommandExpenseValidator,
|
||||||
private transformDTO: ExpenseDTOTransformer,
|
private transformDTO: ExpenseDTOTransformer,
|
||||||
// private entriesService: EntriesService,
|
|
||||||
@Inject(Expense.name)
|
@Inject(Expense.name)
|
||||||
private expenseModel: TenantModelProxy<typeof Expense>,
|
private expenseModel: TenantModelProxy<typeof Expense>,
|
||||||
|
|
||||||
@@ -40,11 +38,11 @@ export class EditExpense {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorize the DTO before editing expense transaction.
|
* Authorize the DTO before editing expense transaction.
|
||||||
* @param {IExpenseEditDTO} expenseDTO
|
* @param {EditExpenseDto} expenseDTO
|
||||||
*/
|
*/
|
||||||
public authorize = async (
|
public authorize = async (
|
||||||
oldExpense: Expense,
|
oldExpense: Expense,
|
||||||
expenseDTO: IExpenseEditDTO,
|
expenseDTO: EditExpenseDto,
|
||||||
) => {
|
) => {
|
||||||
// Validate payment account existance on the storage.
|
// Validate payment account existance on the storage.
|
||||||
const paymentAccount = await this.accountModel()
|
const paymentAccount = await this.accountModel()
|
||||||
@@ -102,7 +100,7 @@ export class EditExpense {
|
|||||||
*/
|
*/
|
||||||
public async editExpense(
|
public async editExpense(
|
||||||
expenseId: number,
|
expenseId: number,
|
||||||
expenseDTO: IExpenseEditDTO,
|
expenseDTO: EditExpenseDto,
|
||||||
): Promise<Expense> {
|
): Promise<Expense> {
|
||||||
// Retrieves the expense model or throw not found error.
|
// Retrieves the expense model or throw not found error.
|
||||||
const oldExpense = await this.expenseModel()
|
const oldExpense = await this.expenseModel()
|
||||||
|
|||||||
@@ -1,3 +1,166 @@
|
|||||||
export class CreateExpenseDto {}
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { Type } from 'class-transformer';
|
||||||
|
import {
|
||||||
|
IsArray,
|
||||||
|
IsBoolean,
|
||||||
|
IsDate,
|
||||||
|
IsInt,
|
||||||
|
IsNotEmpty,
|
||||||
|
IsNumber,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
MaxLength,
|
||||||
|
ValidateNested,
|
||||||
|
} from 'class-validator';
|
||||||
|
|
||||||
export class EditExpenseDto {}
|
class AttachmentDto {
|
||||||
|
@IsString()
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExpenseCategoryDto {
|
||||||
|
@IsInt()
|
||||||
|
@IsNotEmpty()
|
||||||
|
index: number;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@IsNotEmpty()
|
||||||
|
expenseAccountId: number;
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@IsOptional()
|
||||||
|
amount?: number;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(255)
|
||||||
|
@IsOptional()
|
||||||
|
description?: string;
|
||||||
|
|
||||||
|
@IsBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
landedCost?: boolean;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@IsOptional()
|
||||||
|
projectId?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandExpenseDto {
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(255)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The reference number of the expense',
|
||||||
|
example: 'INV-123456',
|
||||||
|
})
|
||||||
|
referenceNo?: string;
|
||||||
|
|
||||||
|
@IsDate()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The payment date of the expense',
|
||||||
|
example: '2021-01-01',
|
||||||
|
})
|
||||||
|
paymentDate: Date;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The payment account id of the expense',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
paymentAccountId: number;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(1000)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The description of the expense',
|
||||||
|
example: 'This is a description',
|
||||||
|
})
|
||||||
|
description?: string;
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The exchange rate of the expense',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
exchangeRate?: number;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@MaxLength(3)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The currency code of the expense',
|
||||||
|
example: 'USD',
|
||||||
|
})
|
||||||
|
currencyCode?: string;
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The exchange rate of the expense',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
exchange_rate?: number;
|
||||||
|
|
||||||
|
@IsBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The publish status of the expense',
|
||||||
|
example: true,
|
||||||
|
})
|
||||||
|
publish?: boolean;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The payee id of the expense',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
payeeId?: number;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The branch id of the expense',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
branchId?: number;
|
||||||
|
|
||||||
|
@IsArray()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => ExpenseCategoryDto)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The categories of the expense',
|
||||||
|
example: [
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
expenseAccountId: 1,
|
||||||
|
amount: 100,
|
||||||
|
description: 'This is a description',
|
||||||
|
landedCost: true,
|
||||||
|
projectId: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
categories: ExpenseCategoryDto[];
|
||||||
|
|
||||||
|
@IsArray()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => AttachmentDto)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The attachments of the expense',
|
||||||
|
example: [
|
||||||
|
{
|
||||||
|
key: '123456',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
attachments?: AttachmentDto[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateExpenseDto extends CommandExpenseDto {}
|
||||||
|
export class EditExpenseDto extends CommandExpenseDto {}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { IFilterRole } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
|
import { IFilterRole } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { Expense } from '../models/Expense.model';
|
import { Expense } from '../models/Expense.model';
|
||||||
|
import { CreateExpenseDto, EditExpenseDto } from '../dtos/Expense.dto';
|
||||||
|
|
||||||
// import { AttachmentLinkDTO } from '../Attachments/Attachments';
|
// import { AttachmentLinkDTO } from '../Attachments/Attachments';
|
||||||
|
|
||||||
@@ -20,26 +21,6 @@ export interface IExpensesFilter {
|
|||||||
filterQuery?: (query: any) => void;
|
filterQuery?: (query: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpenseCommonDTO {
|
|
||||||
currencyCode: string;
|
|
||||||
exchangeRate?: number;
|
|
||||||
description?: string;
|
|
||||||
paymentAccountId: number;
|
|
||||||
peyeeId?: number;
|
|
||||||
referenceNo?: string;
|
|
||||||
publish: boolean;
|
|
||||||
userId: number;
|
|
||||||
paymentDate: Date;
|
|
||||||
payeeId: number;
|
|
||||||
categories: IExpenseCategoryDTO[];
|
|
||||||
|
|
||||||
branchId?: number;
|
|
||||||
// attachments?: AttachmentLinkDTO[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IExpenseCreateDTO extends IExpenseCommonDTO {}
|
|
||||||
export interface IExpenseEditDTO extends IExpenseCommonDTO {}
|
|
||||||
|
|
||||||
export interface IExpenseCategoryDTO {
|
export interface IExpenseCategoryDTO {
|
||||||
id?: number;
|
id?: number;
|
||||||
expenseAccountId: number;
|
expenseAccountId: number;
|
||||||
@@ -52,55 +33,44 @@ export interface IExpenseCategoryDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpenseCreatingPayload {
|
export interface IExpenseCreatingPayload {
|
||||||
|
expenseDTO: CreateExpenseDto;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
tenantId: number;
|
|
||||||
expenseDTO: IExpenseCreateDTO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpenseEventEditingPayload {
|
export interface IExpenseEventEditingPayload {
|
||||||
tenantId: number;
|
|
||||||
oldExpense: Expense;
|
oldExpense: Expense;
|
||||||
expenseDTO: IExpenseEditDTO;
|
expenseDTO: EditExpenseDto;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface IExpenseCreatedPayload {
|
export interface IExpenseCreatedPayload {
|
||||||
tenantId: number;
|
|
||||||
expenseId: number;
|
expenseId: number;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
expense: Expense;
|
expense: Expense;
|
||||||
expenseDTO: IExpenseCreateDTO;
|
expenseDTO: CreateExpenseDto;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpenseEventEditPayload {
|
export interface IExpenseEventEditPayload {
|
||||||
tenantId: number;
|
|
||||||
expenseId: number;
|
expenseId: number;
|
||||||
expense: Expense;
|
expense: Expense;
|
||||||
expenseDTO: IExpenseEditDTO;
|
expenseDTO: EditExpenseDto;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
oldExpense: Expense;
|
oldExpense: Expense;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpenseEventDeletePayload {
|
export interface IExpenseEventDeletePayload {
|
||||||
tenantId: number;
|
|
||||||
expenseId: number;
|
expenseId: number;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
oldExpense: Expense;
|
oldExpense: Expense;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpenseDeletingPayload {
|
export interface IExpenseDeletingPayload {
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
tenantId: number;
|
|
||||||
oldExpense: Expense;
|
oldExpense: Expense;
|
||||||
}
|
}
|
||||||
export interface IExpenseEventPublishedPayload {
|
export interface IExpenseEventPublishedPayload {
|
||||||
tenantId: number;
|
|
||||||
expenseId: number;
|
expenseId: number;
|
||||||
oldExpense: Expense;
|
oldExpense: Expense;
|
||||||
expense: Expense;
|
expense: Expense;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,95 +13,190 @@ import {
|
|||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class CommandItemDto {
|
export class CommandItemDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@MaxLength(255)
|
@MaxLength(255)
|
||||||
|
@ApiProperty({ description: 'Item name', example: 'Office Chair' })
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsIn(['service', 'non-inventory', 'inventory'])
|
@IsIn(['service', 'non-inventory', 'inventory'])
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Item type',
|
||||||
|
enum: ['service', 'non-inventory', 'inventory'],
|
||||||
|
example: 'inventory',
|
||||||
|
})
|
||||||
type: 'service' | 'non-inventory' | 'inventory';
|
type: 'service' | 'non-inventory' | 'inventory';
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@MaxLength(255)
|
@MaxLength(255)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Item code/SKU',
|
||||||
|
required: false,
|
||||||
|
example: 'ITEM-001',
|
||||||
|
})
|
||||||
code?: string;
|
code?: string;
|
||||||
|
|
||||||
// Purchase attributes
|
// Purchase attributes
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the item can be purchased',
|
||||||
|
required: false,
|
||||||
|
example: true,
|
||||||
|
})
|
||||||
purchasable?: boolean;
|
purchasable?: boolean;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber({ maxDecimalPlaces: 3 })
|
@IsNumber({ maxDecimalPlaces: 3 })
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@ValidateIf((o) => o.purchasable === true)
|
@ValidateIf((o) => o.purchasable === true)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Cost price of the item',
|
||||||
|
required: false,
|
||||||
|
minimum: 0,
|
||||||
|
example: 100.5,
|
||||||
|
})
|
||||||
costPrice?: number;
|
costPrice?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@ValidateIf((o) => o.purchasable === true)
|
@ValidateIf((o) => o.purchasable === true)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the cost account',
|
||||||
|
required: false,
|
||||||
|
minimum: 0,
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
costAccountId?: number;
|
costAccountId?: number;
|
||||||
|
|
||||||
// Sell attributes
|
// Sell attributes
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the item can be sold',
|
||||||
|
required: false,
|
||||||
|
example: true,
|
||||||
|
})
|
||||||
sellable?: boolean;
|
sellable?: boolean;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber({ maxDecimalPlaces: 3 })
|
@IsNumber({ maxDecimalPlaces: 3 })
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@ValidateIf((o) => o.sellable === true)
|
@ValidateIf((o) => o.sellable === true)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Selling price of the item',
|
||||||
|
required: false,
|
||||||
|
minimum: 0,
|
||||||
|
example: 150.75,
|
||||||
|
})
|
||||||
sellPrice?: number;
|
sellPrice?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@ValidateIf((o) => o.sellable === true)
|
@ValidateIf((o) => o.sellable === true)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the sell account',
|
||||||
|
required: false,
|
||||||
|
minimum: 0,
|
||||||
|
example: 2,
|
||||||
|
})
|
||||||
sellAccountId?: number;
|
sellAccountId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@ValidateIf((o) => o.type === 'inventory')
|
@ValidateIf((o) => o.type === 'inventory')
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the inventory account (required for inventory items)',
|
||||||
|
required: false,
|
||||||
|
minimum: 0,
|
||||||
|
example: 3,
|
||||||
|
})
|
||||||
inventoryAccountId?: number;
|
inventoryAccountId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Description shown on sales documents',
|
||||||
|
required: false,
|
||||||
|
example: 'High-quality ergonomic office chair',
|
||||||
|
})
|
||||||
sellDescription?: string;
|
sellDescription?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Description shown on purchase documents',
|
||||||
|
required: false,
|
||||||
|
example: 'Ergonomic office chair with adjustable height',
|
||||||
|
})
|
||||||
purchaseDescription?: string;
|
purchaseDescription?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the tax rate applied to sales',
|
||||||
|
required: false,
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
sellTaxRateId?: number;
|
sellTaxRateId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the tax rate applied to purchases',
|
||||||
|
required: false,
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
purchaseTaxRateId?: number;
|
purchaseTaxRateId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the item category',
|
||||||
|
required: false,
|
||||||
|
minimum: 0,
|
||||||
|
example: 5,
|
||||||
|
})
|
||||||
categoryId?: number;
|
categoryId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Additional notes about the item',
|
||||||
|
required: false,
|
||||||
|
example: 'Available in multiple colors',
|
||||||
|
})
|
||||||
note?: string;
|
note?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the item is active',
|
||||||
|
required: false,
|
||||||
|
default: true,
|
||||||
|
example: true,
|
||||||
|
})
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
@IsInt({ each: true })
|
@IsInt({ each: true })
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'IDs of media files associated with the item',
|
||||||
|
required: false,
|
||||||
|
type: [Number],
|
||||||
|
example: [1, 2, 3],
|
||||||
|
})
|
||||||
mediaIds?: number[];
|
mediaIds?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
|
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import {
|
import {
|
||||||
IsArray,
|
IsArray,
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsDate,
|
IsDate,
|
||||||
IsEnum,
|
IsEnum,
|
||||||
|
IsNotEmpty,
|
||||||
IsNumber,
|
IsNumber,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
@@ -26,18 +28,35 @@ class AttachmentDto {
|
|||||||
}
|
}
|
||||||
export class CommandSaleEstimateDto {
|
export class CommandSaleEstimateDto {
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The id of the customer',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
customerId: number;
|
customerId: number;
|
||||||
|
|
||||||
@IsDate()
|
@IsDate()
|
||||||
@Type(() => Date)
|
@Type(() => Date)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The date of the estimate',
|
||||||
|
example: '2021-01-01',
|
||||||
|
})
|
||||||
estimateDate: Date;
|
estimateDate: Date;
|
||||||
|
|
||||||
@IsDate()
|
@IsDate()
|
||||||
@Type(() => Date)
|
@Type(() => Date)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The expiration date of the estimate',
|
||||||
|
example: '2021-01-01',
|
||||||
|
})
|
||||||
expirationDate: Date;
|
expirationDate: Date;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The reference of the estimate',
|
||||||
|
example: '123456',
|
||||||
|
})
|
||||||
reference?: string;
|
reference?: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@@ -50,53 +69,111 @@ export class CommandSaleEstimateDto {
|
|||||||
@IsNumber()
|
@IsNumber()
|
||||||
@Min(0.01)
|
@Min(0.01)
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The exchange rate of the estimate',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
exchangeRate?: number;
|
exchangeRate?: number;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The id of the warehouse',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The id of the branch',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@MinLength(1)
|
@MinLength(1)
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => SaleEstimateEntryDto)
|
@Type(() => SaleEstimateEntryDto)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The entries of the estimate',
|
||||||
|
example: [
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
itemId: 1,
|
||||||
|
description: 'This is a description',
|
||||||
|
quantity: 100,
|
||||||
|
cost: 100,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
entries: SaleEstimateEntryDto[];
|
entries: SaleEstimateEntryDto[];
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The note of the estimate',
|
||||||
|
example: 'This is a note',
|
||||||
|
})
|
||||||
note?: string;
|
note?: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The terms and conditions of the estimate',
|
||||||
|
example: 'This is a terms and conditions',
|
||||||
|
})
|
||||||
termsConditions?: string;
|
termsConditions?: string;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The email to send the estimate to',
|
||||||
|
example: 'test@test.com',
|
||||||
|
})
|
||||||
sendToEmail?: string;
|
sendToEmail?: string;
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => AttachmentDto)
|
@Type(() => AttachmentDto)
|
||||||
attachments?: AttachmentDto[];
|
@ApiProperty({
|
||||||
|
description: 'The attachments of the estimate',
|
||||||
|
example: [
|
||||||
|
{
|
||||||
|
key: '123456',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The id of the pdf template',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
pdfTemplateId?: number;
|
pdfTemplateId?: number;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The discount of the estimate',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
discount?: number;
|
discount?: number;
|
||||||
|
|
||||||
@IsEnum(DiscountType)
|
@IsEnum(DiscountType)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The type of the discount',
|
||||||
|
example: DiscountType.Amount,
|
||||||
|
})
|
||||||
discountType: DiscountType = DiscountType.Amount;
|
discountType: DiscountType = DiscountType.Amount;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The adjustment of the estimate',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
adjustment?: number;
|
adjustment?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
|
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import {
|
import {
|
||||||
IsArray,
|
IsArray,
|
||||||
@@ -31,89 +32,159 @@ class PaymentMethodDto {
|
|||||||
class CommandSaleInvoiceDto {
|
class CommandSaleInvoiceDto {
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ description: 'Customer ID', example: 1 })
|
||||||
customerId: number;
|
customerId: number;
|
||||||
|
|
||||||
@IsDate()
|
@IsDate()
|
||||||
@Type(() => Date)
|
@Type(() => Date)
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ description: 'Invoice date', example: '2023-01-01T00:00:00Z' })
|
||||||
invoiceDate: Date;
|
invoiceDate: Date;
|
||||||
|
|
||||||
@IsDate()
|
@IsDate()
|
||||||
@Type(() => Date)
|
@Type(() => Date)
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ description: 'Due date', example: '2023-01-15T00:00:00Z' })
|
||||||
dueDate: Date;
|
dueDate: Date;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Invoice number',
|
||||||
|
required: false,
|
||||||
|
example: 'INV-001',
|
||||||
|
})
|
||||||
invoiceNo?: string;
|
invoiceNo?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Reference number',
|
||||||
|
required: false,
|
||||||
|
example: 'REF-001',
|
||||||
|
})
|
||||||
referenceNo?: string;
|
referenceNo?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the invoice is delivered',
|
||||||
|
default: false,
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
delivered: boolean = false;
|
delivered: boolean = false;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Invoice message',
|
||||||
|
required: false,
|
||||||
|
example: 'Thank you for your business',
|
||||||
|
})
|
||||||
invoiceMessage?: string;
|
invoiceMessage?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Terms and conditions',
|
||||||
|
required: false,
|
||||||
|
example: 'Payment due within 14 days',
|
||||||
|
})
|
||||||
termsConditions?: string;
|
termsConditions?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Exchange rate',
|
||||||
|
required: false,
|
||||||
|
minimum: 0,
|
||||||
|
example: 1.0,
|
||||||
|
})
|
||||||
exchangeRate?: number;
|
exchangeRate?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({ description: 'Warehouse ID', required: false, example: 1 })
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({ description: 'Branch ID', required: false, example: 1 })
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({ description: 'Project ID', required: false, example: 1 })
|
||||||
projectId?: number;
|
projectId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether tax is inclusive',
|
||||||
|
required: false,
|
||||||
|
example: false,
|
||||||
|
})
|
||||||
isInclusiveTax?: boolean;
|
isInclusiveTax?: boolean;
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => ItemEntryDto)
|
@Type(() => ItemEntryDto)
|
||||||
@MinLength(1)
|
@MinLength(1)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Invoice line items',
|
||||||
|
type: [ItemEntryDto],
|
||||||
|
minItems: 1,
|
||||||
|
})
|
||||||
entries: ItemEntryDto[];
|
entries: ItemEntryDto[];
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({ description: 'PDF template ID', required: false, example: 1 })
|
||||||
pdfTemplateId?: number;
|
pdfTemplateId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => PaymentMethodDto)
|
@Type(() => PaymentMethodDto)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Payment methods',
|
||||||
|
type: [PaymentMethodDto],
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
paymentMethods?: PaymentMethodDto[];
|
paymentMethods?: PaymentMethodDto[];
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@ApiProperty({ description: 'Discount value', required: false, example: 10 })
|
||||||
discount?: number;
|
discount?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsEnum(DiscountType)
|
@IsEnum(DiscountType)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Discount type',
|
||||||
|
enum: DiscountType,
|
||||||
|
required: false,
|
||||||
|
example: DiscountType.Percentage,
|
||||||
|
})
|
||||||
discountType?: DiscountType;
|
discountType?: DiscountType;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Adjustment amount',
|
||||||
|
required: false,
|
||||||
|
example: 5,
|
||||||
|
})
|
||||||
adjustment?: number;
|
adjustment?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'ID of the estimate this invoice is created from',
|
||||||
|
required: false,
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
fromEstimateId?: number;
|
fromEstimateId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { DiscountType } from '@/common/types/Discount';
|
import { DiscountType } from '@/common/types/Discount';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
IsEnum,
|
IsEnum,
|
||||||
IsIn,
|
IsIn,
|
||||||
@@ -11,66 +12,130 @@ import {
|
|||||||
|
|
||||||
export class ItemEntryDto {
|
export class ItemEntryDto {
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The index of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
index: number;
|
index: number;
|
||||||
|
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The id of the item',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
itemId: number;
|
itemId: number;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The rate of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
rate: number;
|
rate: number;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The quantity of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
quantity: number;
|
quantity: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The discount of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
discount?: number;
|
discount?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsEnum(DiscountType)
|
@IsEnum(DiscountType)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The type of the discount',
|
||||||
|
example: DiscountType.Percentage,
|
||||||
|
})
|
||||||
discountType?: DiscountType = DiscountType.Percentage;
|
discountType?: DiscountType = DiscountType.Percentage;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The description of the item entry',
|
||||||
|
example: 'This is a description',
|
||||||
|
})
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The tax code of the item entry',
|
||||||
|
example: '123456',
|
||||||
|
})
|
||||||
taxCode?: string;
|
taxCode?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The tax rate id of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
taxRateId?: number;
|
taxRateId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The warehouse id of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The project id of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
projectId?: number;
|
projectId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The project ref id of the item entry',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
projectRefId?: number;
|
projectRefId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsIn(['TASK', 'BILL', 'EXPENSE'])
|
@IsIn(['TASK', 'BILL', 'EXPENSE'])
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The project ref type of the item entry',
|
||||||
|
example: 'TASK',
|
||||||
|
})
|
||||||
projectRefType?: string;
|
projectRefType?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The project ref invoiced amount of the item entry',
|
||||||
|
example: 100,
|
||||||
|
})
|
||||||
projectRefInvoicedAmount?: number;
|
projectRefInvoicedAmount?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The sell account id of the item entry',
|
||||||
|
example: 1020,
|
||||||
|
})
|
||||||
sellAccountId?: number;
|
sellAccountId?: number;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The cost account id of the item entry',
|
||||||
|
example: 1021,
|
||||||
|
})
|
||||||
costAccountId?: number;
|
costAccountId?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export class TransactionsLockingController {
|
|||||||
@ApiOperation({ summary: 'Partial unlock all transactions locking for a module or all modules' })
|
@ApiOperation({ summary: 'Partial unlock all transactions locking for a module or all modules' })
|
||||||
async unlockTransactionsLockingBetweenPeriod(
|
async unlockTransactionsLockingBetweenPeriod(
|
||||||
@Body('module') module: TransactionsLockingGroup,
|
@Body('module') module: TransactionsLockingGroup,
|
||||||
@Body() unlockDTO: UnlockTransactionsLockingDto,
|
@Body() unlockDTO: ITransactionLockingPartiallyDTO,
|
||||||
) {
|
) {
|
||||||
const transactionMeta =
|
const transactionMeta =
|
||||||
await this.transactionsLockingService.unlockTransactionsLockingPartially(
|
await this.transactionsLockingService.unlockTransactionsLockingPartially(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { Knex } from 'knex';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import {
|
import {
|
||||||
IVendorCreditEditDTO,
|
|
||||||
IVendorCreditEditedPayload,
|
IVendorCreditEditedPayload,
|
||||||
IVendorCreditEditingPayload,
|
IVendorCreditEditingPayload,
|
||||||
} from '../types/VendorCredit.types';
|
} from '../types/VendorCredit.types';
|
||||||
@@ -10,7 +10,6 @@ import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
|
|||||||
import { VendorCredit } from '../models/VendorCredit';
|
import { VendorCredit } from '../models/VendorCredit';
|
||||||
import { Contact } from '@/modules/Contacts/models/Contact';
|
import { Contact } from '@/modules/Contacts/models/Contact';
|
||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { Knex } from 'knex';
|
|
||||||
import { VendorCreditDTOTransformService } from './VendorCreditDTOTransform.service';
|
import { VendorCreditDTOTransformService } from './VendorCreditDTOTransform.service';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
import { EditVendorCreditDto } from '../dtos/VendorCredit.dto';
|
import { EditVendorCreditDto } from '../dtos/VendorCredit.dto';
|
||||||
@@ -40,7 +39,7 @@ export class EditVendorCreditService {
|
|||||||
/**
|
/**
|
||||||
* Deletes the given vendor credit.
|
* Deletes the given vendor credit.
|
||||||
* @param {number} vendorCreditId - Vendor credit id.
|
* @param {number} vendorCreditId - Vendor credit id.
|
||||||
* @param {EditVendorCreditDto} vendorCreditDto -
|
* @param {EditVendorCreditDto} vendorCreditDto -
|
||||||
*/
|
*/
|
||||||
public editVendorCredit = async (
|
public editVendorCredit = async (
|
||||||
vendorCreditId: number,
|
vendorCreditId: number,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import * as moment from 'moment';
|
|||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { ERRORS } from '../constants';
|
import { ERRORS } from '../constants';
|
||||||
import { IVendorCreditEntryDTO } from '../types/VendorCredit.types';
|
|
||||||
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
|
import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service';
|
||||||
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
||||||
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||||
@@ -14,6 +13,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import {
|
import {
|
||||||
CreateVendorCreditDto,
|
CreateVendorCreditDto,
|
||||||
EditVendorCreditDto,
|
EditVendorCreditDto,
|
||||||
|
VendorCreditEntryDto,
|
||||||
} from '../dtos/VendorCredit.dto';
|
} from '../dtos/VendorCredit.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -52,7 +52,7 @@ export class VendorCreditDTOTransformService {
|
|||||||
assocItemEntriesDefaultIndex,
|
assocItemEntriesDefaultIndex,
|
||||||
|
|
||||||
// Associate the reference type to item entries.
|
// Associate the reference type to item entries.
|
||||||
R.map((entry: IVendorCreditEntryDTO) => ({
|
R.map((entry: VendorCreditEntryDto) => ({
|
||||||
referenceType: 'VendorCredit',
|
referenceType: 'VendorCredit',
|
||||||
...entry,
|
...entry,
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ enum DiscountType {
|
|||||||
Amount = 'amount',
|
Amount = 'amount',
|
||||||
}
|
}
|
||||||
|
|
||||||
class VendorCreditEntryDto extends ItemEntryDto {}
|
export class VendorCreditEntryDto extends ItemEntryDto {}
|
||||||
|
|
||||||
class AttachmentDto {
|
class AttachmentDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { VendorsApplication } from './VendorsApplication.service';
|
import { VendorsApplication } from './VendorsApplication.service';
|
||||||
import {
|
import {
|
||||||
IVendorEditDTO,
|
|
||||||
IVendorNewDTO,
|
|
||||||
IVendorOpeningBalanceEditDTO,
|
IVendorOpeningBalanceEditDTO,
|
||||||
IVendorsFilter,
|
IVendorsFilter,
|
||||||
} from './types/Vendors.types';
|
} from './types/Vendors.types';
|
||||||
import { PublicRoute } from '../Auth/Jwt.guard';
|
import { PublicRoute } from '../Auth/Jwt.guard';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { CreateVendorDto } from './dtos/CreateVendor.dto';
|
||||||
|
import { EditVendorDto } from './dtos/EditVendor.dto';
|
||||||
|
|
||||||
@Controller('vendors')
|
@Controller('vendors')
|
||||||
@ApiTags('vendors')
|
@ApiTags('vendors')
|
||||||
@@ -38,13 +38,13 @@ export class VendorsController {
|
|||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@ApiOperation({ summary: 'Create a new vendor.' })
|
@ApiOperation({ summary: 'Create a new vendor.' })
|
||||||
createVendor(@Body() vendorDTO: IVendorNewDTO) {
|
createVendor(@Body() vendorDTO: CreateVendorDto) {
|
||||||
return this.vendorsApplication.createVendor(vendorDTO);
|
return this.vendorsApplication.createVendor(vendorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@ApiOperation({ summary: 'Edit the given vendor.' })
|
@ApiOperation({ summary: 'Edit the given vendor.' })
|
||||||
editVendor(@Param('id') vendorId: number, @Body() vendorDTO: IVendorEditDTO) {
|
editVendor(@Param('id') vendorId: number, @Body() vendorDTO: EditVendorDto) {
|
||||||
return this.vendorsApplication.editVendor(vendorId, vendorDTO);
|
return this.vendorsApplication.editVendor(vendorId, vendorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import { DeleteVendorService } from './commands/DeleteVendor.service';
|
|||||||
import { EditOpeningBalanceVendorService } from './commands/EditOpeningBalanceVendor.service';
|
import { EditOpeningBalanceVendorService } from './commands/EditOpeningBalanceVendor.service';
|
||||||
import { GetVendorService } from './queries/GetVendor';
|
import { GetVendorService } from './queries/GetVendor';
|
||||||
import {
|
import {
|
||||||
IVendorEditDTO,
|
|
||||||
IVendorNewDTO,
|
|
||||||
IVendorOpeningBalanceEditDTO,
|
IVendorOpeningBalanceEditDTO,
|
||||||
IVendorsFilter,
|
IVendorsFilter,
|
||||||
} from './types/Vendors.types';
|
} from './types/Vendors.types';
|
||||||
import { GetVendorsService } from './queries/GetVendors.service';
|
import { GetVendorsService } from './queries/GetVendors.service';
|
||||||
|
import { CreateVendorDto } from './dtos/CreateVendor.dto';
|
||||||
|
import { EditVendorDto } from './dtos/EditVendor.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class VendorsApplication {
|
export class VendorsApplication {
|
||||||
@@ -29,7 +29,7 @@ export class VendorsApplication {
|
|||||||
* @param {IVendorNewDTO} vendorDTO
|
* @param {IVendorNewDTO} vendorDTO
|
||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public createVendor(vendorDTO: IVendorNewDTO, trx?: Knex.Transaction) {
|
public createVendor(vendorDTO: CreateVendorDto, trx?: Knex.Transaction) {
|
||||||
return this.createVendorService.createVendor(vendorDTO, trx);
|
return this.createVendorService.createVendor(vendorDTO, trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ export class VendorsApplication {
|
|||||||
* @param {IVendorEditDTO} vendorDTO -
|
* @param {IVendorEditDTO} vendorDTO -
|
||||||
* @returns {Promise<IVendor>}
|
* @returns {Promise<IVendor>}
|
||||||
*/
|
*/
|
||||||
public editVendor(vendorId: number, vendorDTO: IVendorEditDTO) {
|
public editVendor(vendorId: number, vendorDTO: EditVendorDto) {
|
||||||
return this.editVendorService.editVendor(vendorId, vendorDTO);
|
return this.editVendorService.editVendor(vendorId, vendorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,5 +84,5 @@ export class VendorsApplication {
|
|||||||
*/
|
*/
|
||||||
public getVendors(filterDTO: IVendorsFilter) {
|
public getVendors(filterDTO: IVendorsFilter) {
|
||||||
return this.getVendorsService.getVendorsList(filterDTO);
|
return this.getVendorsService.getVendorsList(filterDTO);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { IVendorEditDTO, IVendorNewDTO } from '../types/Vendors.types';
|
|||||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||||
import { ContactService } from '@/modules/Contacts/types/Contacts.types';
|
import { ContactService } from '@/modules/Contacts/types/Contacts.types';
|
||||||
import { Vendor } from '../models/Vendor';
|
import { Vendor } from '../models/Vendor';
|
||||||
|
import { CreateVendorDto } from '../dtos/CreateVendor.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CreateEditVendorDTOService {
|
export class CreateEditVendorDTOService {
|
||||||
@@ -30,7 +31,7 @@ export class CreateEditVendorDTOService {
|
|||||||
* @returns {IVendorNewDTO}
|
* @returns {IVendorNewDTO}
|
||||||
*/
|
*/
|
||||||
public transformCreateDTO = async (
|
public transformCreateDTO = async (
|
||||||
vendorDTO: IVendorNewDTO,
|
vendorDTO: CreateVendorDto,
|
||||||
): Promise<Partial<Vendor>> => {
|
): Promise<Partial<Vendor>> => {
|
||||||
const commonDTO = this.transformCommonDTO(vendorDTO);
|
const commonDTO = this.transformCommonDTO(vendorDTO);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
} from '../types/Vendors.types';
|
} from '../types/Vendors.types';
|
||||||
import { CreateEditVendorDTOService } from './CreateEditVendorDTO';
|
import { CreateEditVendorDTOService } from './CreateEditVendorDTO';
|
||||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||||
|
import { CreateVendorDto } from '../dtos/CreateVendor.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CreateVendorService {
|
export class CreateVendorService {
|
||||||
@@ -34,7 +35,7 @@ export class CreateVendorService {
|
|||||||
* @param {IVendorNewDTO} vendorDTO
|
* @param {IVendorNewDTO} vendorDTO
|
||||||
* @return {Promise<void>}
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public async createVendor(vendorDTO: IVendorNewDTO, trx?: Knex.Transaction) {
|
public async createVendor(vendorDTO: CreateVendorDto, trx?: Knex.Transaction) {
|
||||||
// Transforms create DTO to customer object.
|
// Transforms create DTO to customer object.
|
||||||
const vendorObject = await this.transformDTO.transformCreateDTO(vendorDTO);
|
const vendorObject = await this.transformDTO.transformCreateDTO(vendorDTO);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
IVendorEditDTO,
|
|
||||||
IVendorEventEditedPayload,
|
IVendorEventEditedPayload,
|
||||||
IVendorEventEditingPayload,
|
IVendorEventEditingPayload,
|
||||||
} from '../types/Vendors.types';
|
} from '../types/Vendors.types';
|
||||||
@@ -11,6 +10,7 @@ import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
|||||||
import { Vendor } from '../models/Vendor';
|
import { Vendor } from '../models/Vendor';
|
||||||
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 { EditVendorDto } from '../dtos/EditVendor.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EditVendorService {
|
export class EditVendorService {
|
||||||
@@ -29,7 +29,7 @@ export class EditVendorService {
|
|||||||
* @param {IVendorEditDTO} vendorDTO -
|
* @param {IVendorEditDTO} vendorDTO -
|
||||||
* @returns {Promise<IVendor>}
|
* @returns {Promise<IVendor>}
|
||||||
*/
|
*/
|
||||||
public async editVendor(vendorId: number, vendorDTO: IVendorEditDTO) {
|
public async editVendor(vendorId: number, vendorDTO: EditVendorDto) {
|
||||||
// Retrieve the vendor or throw not found error.
|
// Retrieve the vendor or throw not found error.
|
||||||
const oldVendor = await this.vendorModel()
|
const oldVendor = await this.vendorModel()
|
||||||
.query()
|
.query()
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, IsEmail, IsString } from 'class-validator';
|
||||||
|
import { ContactAddressDto } from '@/modules/Customers/dtos/ContactAddress.dto';
|
||||||
|
import { IsInt, IsNumber } from 'class-validator';
|
||||||
|
import { IsOptional, Min } from 'class-validator';
|
||||||
|
import { IsISO8601 } from 'class-validator';
|
||||||
|
|
||||||
|
export class CreateVendorDto extends ContactAddressDto {
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor opening balance' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@Min(0)
|
||||||
|
openingBalance?: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
required: false,
|
||||||
|
description: 'Vendor opening balance exchange rate',
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
@Min(0.01)
|
||||||
|
openingBalanceExchangeRate?: number;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Date of the opening balance' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsISO8601()
|
||||||
|
openingBalanceAt?: Date;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
required: false,
|
||||||
|
description: 'Branch ID for the opening balance',
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
openingBalanceBranchId?: number;
|
||||||
|
|
||||||
|
@ApiProperty({ description: 'Currency code for the vendor' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
currencyCode: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor salutation' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
salutation?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor first name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
firstName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor last name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
lastName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor company name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
companyName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor display name' })
|
||||||
|
@IsString()
|
||||||
|
displayName: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor website' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
website?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor email address' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail()
|
||||||
|
email?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor work phone number' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
workPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor personal phone number' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
personalPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
required: false,
|
||||||
|
description: 'Additional notes about the vendor',
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
note?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
required: false,
|
||||||
|
description: 'Whether the vendor is active',
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
active?: boolean;
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import { ContactAddressDto } from '@/modules/Customers/dtos/ContactAddress.dto';
|
||||||
|
import { IsEmail, IsString, IsBoolean, IsOptional } from 'class-validator';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class EditVendorDto extends ContactAddressDto {
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor salutation' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
salutation?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor first name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
firstName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor last name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
lastName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor company name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
companyName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor display name' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
displayName?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor website' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
website?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor email address' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail()
|
||||||
|
email?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor work phone number' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
workPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Vendor personal phone number' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
personalPhone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Additional notes about the vendor' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
note?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, description: 'Whether the vendor is active' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
active?: boolean;
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ import { Vendor } from '../models/Vendor';
|
|||||||
import { IContactAddressDTO } from '@/modules/Contacts/types/Contacts.types';
|
import { IContactAddressDTO } from '@/modules/Contacts/types/Contacts.types';
|
||||||
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
|
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
|
||||||
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
|
import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model';
|
||||||
|
import { CreateVendorDto } from '../dtos/CreateVendor.dto';
|
||||||
|
import { EditVendorDto } from '../dtos/EditVendor.dto';
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
export interface IVendorNewDTO extends IContactAddressDTO {
|
export interface IVendorNewDTO extends IContactAddressDTO {
|
||||||
@@ -60,43 +62,33 @@ export interface GetVendorsResponse {
|
|||||||
// Vendor Events.
|
// Vendor Events.
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
export interface IVendorEventCreatingPayload {
|
export interface IVendorEventCreatingPayload {
|
||||||
// tenantId: number;
|
vendorDTO: CreateVendorDto;
|
||||||
vendorDTO: IVendorNewDTO;
|
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorEventCreatedPayload {
|
export interface IVendorEventCreatedPayload {
|
||||||
// tenantId: number;
|
|
||||||
vendorId: number;
|
vendorId: number;
|
||||||
vendor: Vendor;
|
vendor: Vendor;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorEventDeletingPayload {
|
export interface IVendorEventDeletingPayload {
|
||||||
// tenantId: number;
|
|
||||||
vendorId: number;
|
vendorId: number;
|
||||||
oldVendor: Vendor;
|
oldVendor: Vendor;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorEventDeletedPayload {
|
export interface IVendorEventDeletedPayload {
|
||||||
// tenantId: number;
|
|
||||||
vendorId: number;
|
vendorId: number;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
oldVendor: Vendor;
|
oldVendor: Vendor;
|
||||||
trx?: Knex.Transaction;
|
trx?: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface IVendorEventEditingPayload {
|
export interface IVendorEventEditingPayload {
|
||||||
// tenantId: number;
|
vendorDTO: EditVendorDto;
|
||||||
vendorDTO: IVendorEditDTO;
|
|
||||||
trx?: Knex.Transaction;
|
trx?: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface IVendorEventEditedPayload {
|
export interface IVendorEventEditedPayload {
|
||||||
// tenantId: number;
|
|
||||||
vendorId: number;
|
vendorId: number;
|
||||||
vendor: Vendor;
|
vendor: Vendor;
|
||||||
// authorizedUser: ISystemUser;
|
|
||||||
trx?: Knex.Transaction;
|
trx?: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,14 +100,12 @@ export interface IVendorOpeningBalanceEditDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorOpeningBalanceEditingPayload {
|
export interface IVendorOpeningBalanceEditingPayload {
|
||||||
// tenantId: number;
|
|
||||||
oldVendor: Vendor;
|
oldVendor: Vendor;
|
||||||
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO;
|
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO;
|
||||||
trx?: Knex.Transaction;
|
trx?: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorOpeningBalanceEditedPayload {
|
export interface IVendorOpeningBalanceEditedPayload {
|
||||||
// tenantId: number;
|
|
||||||
vendor: Vendor;
|
vendor: Vendor;
|
||||||
oldVendor: Vendor;
|
oldVendor: Vendor;
|
||||||
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO;
|
openingBalanceEditDTO: IVendorOpeningBalanceEditDTO;
|
||||||
@@ -123,13 +113,11 @@ export interface IVendorOpeningBalanceEditedPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorActivatingPayload {
|
export interface IVendorActivatingPayload {
|
||||||
// tenantId: number;
|
|
||||||
oldVendor: Vendor;
|
oldVendor: Vendor;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorActivatedPayload {
|
export interface IVendorActivatedPayload {
|
||||||
// tenantId: number;
|
|
||||||
vendor: Vendor;
|
vendor: Vendor;
|
||||||
oldVendor: Vendor;
|
oldVendor: Vendor;
|
||||||
trx?: Knex.Transaction;
|
trx?: Knex.Transaction;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import {
|
import {
|
||||||
IsArray,
|
IsArray,
|
||||||
@@ -39,32 +40,68 @@ export class WarehouseTransferEntryDto {
|
|||||||
export class CommandWarehouseTransferDto {
|
export class CommandWarehouseTransferDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The id of the warehouse to transfer from',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
fromWarehouseId: number;
|
fromWarehouseId: number;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The id of the warehouse to transfer to',
|
||||||
|
example: 2,
|
||||||
|
})
|
||||||
toWarehouseId: number;
|
toWarehouseId: number;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsDate()
|
@IsDate()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The date of the warehouse transfer',
|
||||||
|
example: '2021-01-01',
|
||||||
|
})
|
||||||
date: Date;
|
date: Date;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The transaction number of the warehouse transfer',
|
||||||
|
example: '123456',
|
||||||
|
})
|
||||||
transactionNumber?: string;
|
transactionNumber?: string;
|
||||||
|
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the warehouse transfer has been initiated',
|
||||||
|
example: false,
|
||||||
|
})
|
||||||
transferInitiated: boolean = false;
|
transferInitiated: boolean = false;
|
||||||
|
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'Whether the warehouse transfer has been delivered',
|
||||||
|
example: false,
|
||||||
|
})
|
||||||
transferDelivered: boolean = false;
|
transferDelivered: boolean = false;
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@ArrayMinSize(1)
|
@ArrayMinSize(1)
|
||||||
@ValidateNested({ each: true })
|
@ValidateNested({ each: true })
|
||||||
@Type(() => WarehouseTransferEntryDto)
|
@Type(() => WarehouseTransferEntryDto)
|
||||||
|
@ApiProperty({
|
||||||
|
description: 'The entries of the warehouse transfer',
|
||||||
|
example: [
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
itemId: 1,
|
||||||
|
description: 'This is a description',
|
||||||
|
quantity: 100,
|
||||||
|
cost: 100,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
entries: WarehouseTransferEntryDto[];
|
entries: WarehouseTransferEntryDto[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user