refactor(nestjs): add importable service to other modules

This commit is contained in:
Ahmed Bouhuolia
2025-04-12 19:26:15 +02:00
parent 51de3631fc
commit 1d53063e09
30 changed files with 1666 additions and 139 deletions

View File

@@ -18,6 +18,7 @@ import { BankAccount } from '../BankingTransactions/models/BankAccount';
import { GetAccountsService } from './GetAccounts.service';
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { AccountsExportable } from './AccountsExportable.service';
import { AccountsImportable } from './AccountsImportable.service';
const models = [RegisterTenancyModel(BankAccount)];
@@ -39,12 +40,14 @@ const models = [RegisterTenancyModel(BankAccount)];
GetAccountTransactionsService,
GetAccountsService,
AccountsExportable,
AccountsImportable
],
exports: [
AccountRepository,
CreateAccountService,
...models,
AccountsExportable,
AccountsImportable
],
})
export class AccountsModule {}

View File

@@ -4,8 +4,11 @@ import { Importable } from '../Import/Importable';
import { AccountsSampleData } from './AccountsImportable.SampleData';
import { CreateAccountDTO } from './CreateAccount.dto';
import { CreateAccountService } from './CreateAccount.service';
import { ImportableService } from '../Import/decorators/Import.decorator';
import { Account } from './models/Account.model';
@Injectable()
@ImportableService({ name: Account.name })
export class AccountsImportable extends Importable {
constructor(private readonly createAccountService: CreateAccountService) {
super();

View File

@@ -13,8 +13,10 @@ import { flatToNestedArray } from '@/utils/flat-to-nested-array';
import { ExportableModel } from '../../Export/decorators/ExportableModel.decorator';
import { AccountMeta } from './Account.meta';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
@ExportableModel()
@ImportableModel()
@InjectModelMeta(AccountMeta)
export class Account extends TenantBaseModel {
public name!: string;

View File

@@ -18,6 +18,7 @@ import { LedgerModule } from '../Ledger/Ledger.module';
import { AccountsModule } from '../Accounts/Accounts.module';
import { BillPaymentsExportable } from './queries/BillPaymentsExportable';
import { GetBillPayments } from '../Bills/queries/GetBillPayments';
import { BillPaymentsImportable } from './commands/BillPaymentsImportable';
@Module({
imports: [LedgerModule, AccountsModule],
@@ -37,9 +38,15 @@ import { GetBillPayments } from '../Bills/queries/GetBillPayments';
BillPaymentGLEntries,
BillPaymentGLEntriesSubscriber,
GetBillPayments,
BillPaymentsExportable
BillPaymentsExportable,
BillPaymentsImportable,
],
exports: [
BillPaymentValidators,
CreateBillPaymentService,
BillPaymentsExportable,
BillPaymentsImportable,
],
exports: [BillPaymentValidators, CreateBillPaymentService],
controllers: [BillPaymentsController],
})
export class BillPaymentsModule {}

View File

@@ -1,45 +1,49 @@
// import { Inject, Service } from 'typedi';
// import { Knex } from 'knex';
// import { IBillPaymentDTO } from '@/interfaces';
// import { CreateBillPayment } from './CreateBillPayment';
// import { Importable } from '@/services/Import/Importable';
// import { BillsPaymentsSampleData } from './constants';
import { Injectable } from '@nestjs/common';
import { Knex } from 'knex';
import { CreateBillPaymentService } from './CreateBillPayment.service';
import { Importable } from '@/modules/Import/Importable';
import { CreateBillPaymentDto } from '../dtos/BillPayment.dto';
import { BillsPaymentsSampleData } from '../constants';
import { ImportableService } from '@/modules/Import/decorators/Import.decorator';
import { BillPayment } from '../models/BillPayment';
// @Service()
// export class BillPaymentsImportable extends Importable {
// @Inject()
// private createBillPaymentService: CreateBillPayment;
@Injectable()
@ImportableService({ name: BillPayment.name })
export class BillPaymentsImportable extends Importable {
constructor(
private readonly createBillPaymentService: CreateBillPaymentService
) {
super();
}
// /**
// * Importing to account service.
// * @param {number} tenantId
// * @param {IAccountCreateDTO} createAccountDTO
// * @returns
// */
// public importable(
// tenantId: number,
// billPaymentDTO: IBillPaymentDTO,
// trx?: Knex.Transaction
// ) {
// return this.createBillPaymentService.createBillPayment(
// tenantId,
// billPaymentDTO,
// trx
// );
// }
/**
* Importing to account service.
* @param {number} tenantId
* @param {IAccountCreateDTO} createAccountDTO
* @returns
*/
public importable(
billPaymentDTO: CreateBillPaymentDto,
trx?: Knex.Transaction
) {
return this.createBillPaymentService.createBillPayment(
billPaymentDTO,
trx
);
}
// /**
// * Concurrrency controlling of the importing process.
// * @returns {number}
// */
// public get concurrency() {
// return 1;
// }
/**
* Concurrrency controlling of the importing process.
* @returns {number}
*/
public get concurrency() {
return 1;
}
// /**
// * Retrieves the sample data that used to download accounts sample sheet.
// */
// public sampleData(): any[] {
// return BillsPaymentsSampleData;
// }
// }
/**
* Retrieves the sample data that used to download accounts sample sheet.
*/
public sampleData(): any[] {
return BillsPaymentsSampleData;
}
}

View File

@@ -0,0 +1,224 @@
import { Features } from "@/common/types/Features";
export const BillPaymentMeta = {
defaultFilterField: 'vendor',
defaultSort: {
sortOrder: 'DESC',
sortField: 'bill_date',
},
exportable: true,
exportFlattenOn: 'entries',
importable: true,
importAggregator: 'group',
importAggregateOn: 'entries',
importAggregateBy: 'paymentNumber',
fields: {
vendor: {
name: 'bill_payment.field.vendor',
column: 'vendor_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'vendor',
relationEntityLabel: 'display_name',
relationEntityKey: 'id',
},
amount: {
name: 'bill_payment.field.amount',
column: 'amount',
fieldType: 'number',
},
due_amount: {
name: 'bill_payment.field.due_amount',
column: 'due_amount',
fieldType: 'number',
},
payment_account: {
name: 'bill_payment.field.payment_account',
column: 'payment_account_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'paymentAccount',
relationEntityLabel: 'name',
relationEntityKey: 'slug',
},
payment_number: {
name: 'bill_payment.field.payment_number',
column: 'payment_number',
fieldType: 'text',
},
payment_date: {
name: 'bill_payment.field.payment_date',
column: 'payment_date',
fieldType: 'date',
},
reference_no: {
name: 'bill_payment.field.reference_no',
column: 'reference',
fieldType: 'text',
},
description: {
name: 'bill_payment.field.description',
column: 'description',
fieldType: 'text',
},
created_at: {
name: 'bill_payment.field.created_at',
column: 'created_at',
fieldType: 'date',
},
},
columns: {
vendor: {
name: 'bill_payment.field.vendor',
type: 'relation',
accessor: 'vendor.displayName',
},
paymentDate: {
name: 'bill_payment.field.payment_date',
type: 'date',
accessor: 'formattedPaymentDate',
},
paymentNumber: {
name: 'bill_payment.field.payment_number',
type: 'text',
},
paymentAccount: {
name: 'bill_payment.field.payment_account',
accessor: 'paymentAccount.name',
type: 'text',
},
amount: {
name: 'Amount',
accessor: 'formattedAmount',
},
currencyCode: {
name: 'Currency Code',
type: 'text',
printable: false,
},
exchangeRate: {
name: 'bill_payment.field.exchange_rate',
type: 'number',
printable: false,
},
statement: {
name: 'bill_payment.field.note',
type: 'text',
printable: false,
},
reference: {
name: 'bill_payment.field.reference',
type: 'text',
},
entries: {
name: 'Entries',
accessor: 'entries',
type: 'collection',
collectionOf: 'object',
columns: {
date: {
name: 'Bill date',
accessor: 'bill.formattedBillDate',
},
billNo: {
name: 'Bill No.',
accessor: 'bill.billNo',
},
billRefNo: {
name: 'Bill Reference No.',
accessor: 'bill.referenceNo',
},
billAmount: {
name: 'Bill Amount',
accessor: 'bill.totalFormatted',
},
paidAmount: {
name: 'Paid Amount',
accessor: 'paymentAmountFormatted',
},
},
},
branch: {
name: 'Branch',
type: 'text',
accessor: 'branch.name',
features: [Features.BRANCHES],
},
},
fields2: {
vendorId: {
name: 'bill_payment.field.vendor',
fieldType: 'relation',
relationModel: 'Contact',
relationImportMatch: ['displayName'],
required: true,
},
payment_date: {
name: 'bill_payment.field.payment_date',
fieldType: 'date',
required: true,
},
paymentNumber: {
name: 'bill_payment.field.payment_number',
fieldType: 'text',
unique: true,
importHint: 'The payment number should be unique.',
},
paymentAccountId: {
name: 'bill_payment.field.payment_account',
fieldType: 'relation',
relationModel: 'Account',
relationImportMatch: ['name', 'code'],
required: true,
importHint: 'Matches the account name or code.',
},
exchangeRate: {
name: 'bill_payment.field.exchange_rate',
fieldType: 'number',
},
statement: {
name: 'bill_payment.field.note',
fieldType: 'text',
},
reference: {
name: 'bill_payment.field.reference',
fieldType: 'text',
},
entries: {
name: 'bill_payment.field.entries',
column: 'entries',
fieldType: 'collection',
collectionOf: 'object',
collectionMinLength: 1,
required: true,
fields: {
billId: {
name: 'bill_payment.field.entries.bill',
fieldType: 'relation',
relationModel: 'Bill',
relationImportMatch: 'billNumber',
required: true,
importHint: 'Matches the bill number.',
},
paymentAmount: {
name: 'bill_payment.field.entries.payment_amount',
fieldType: 'number',
required: true,
},
},
},
branchId: {
name: 'Branch',
fieldType: 'relation',
relationModel: 'Branch',
relationImportMatch: ['name', 'code'],
features: [Features.BRANCHES],
required: true,
},
},
};

View File

@@ -9,8 +9,15 @@ import { BaseModel } from '@/models/Model';
import { BillPaymentEntry } from './BillPaymentEntry';
import { Vendor } from '@/modules/Vendors/models/Vendor';
import { Document } from '@/modules/ChromiumlyTenancy/models/Document';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { BillPaymentMeta } from './BillPayment.meta';
export class BillPayment extends BaseModel{
@ImportableModel()
@ExportableModel()
@InjectModelMeta(BillPaymentMeta)
export class BillPayment extends BaseModel {
vendorId: number;
amount: number;
currencyCode: string;

View File

@@ -25,6 +25,7 @@ import { AccountsModule } from '../Accounts/Accounts.module';
import { GetCreditNotesService } from './queries/GetCreditNotes.service';
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { CreditNotesExportable } from './commands/CreditNotesExportable';
import { CreditNotesImportable } from './commands/CreditNotesImportable';
@Module({
imports: [
@@ -55,6 +56,7 @@ import { CreditNotesExportable } from './commands/CreditNotesExportable';
CreditNoteGLEntries,
CreditNoteGLEntriesSubscriber,
CreditNotesExportable,
CreditNotesImportable,
],
exports: [
CreateCreditNoteService,
@@ -69,6 +71,7 @@ import { CreditNotesExportable } from './commands/CreditNotesExportable';
CreditNoteApplication,
CreditNoteBrandingTemplate,
CreditNotesExportable,
CreditNotesImportable,
],
controllers: [CreditNotesController],
})

View File

@@ -1,44 +1,45 @@
// import { Inject, Service } from 'typedi';
// import { Knex } from 'knex';
// import { ICreditNoteNewDTO } from '@/interfaces';
// import { Importable } from '../Import/Importable';
// import CreateCreditNote from './commands/CreateCreditNote.service';
import { Knex } from 'knex';
import { Injectable } from '@nestjs/common';
import { CreateCreditNoteService } from './CreateCreditNote.service';
import { Importable } from '@/modules/Import/Importable';
import { CreateCreditNoteDto } from '../dtos/CreditNote.dto';
import { ImportableService } from '@/modules/Import/decorators/Import.decorator';
import { CreditNote } from '../models/CreditNote';
// @Service()
// export class CreditNotesImportable extends Importable {
// @Inject()
// private createCreditNoteImportable: CreateCreditNote;
@Injectable()
@ImportableService({ name: CreditNote.name })
export class CreditNotesImportable extends Importable {
constructor(
private readonly createCreditNoteImportable: CreateCreditNoteService,
) {
super();
}
// /**
// * Importing to account service.
// * @param {number} tenantId
// * @param {IAccountCreateDTO} createAccountDTO
// * @returns
// */
// public importable(
// tenantId: number,
// createAccountDTO: ICreditNoteNewDTO,
// trx?: Knex.Transaction
// ) {
// return this.createCreditNoteImportable.newCreditNote(
// tenantId,
// createAccountDTO,
// trx
// );
// }
/**
* Importing to credit note service.
*/
public importable(
createAccountDTO: CreateCreditNoteDto,
trx?: Knex.Transaction,
) {
return this.createCreditNoteImportable.creditCreditNote(
createAccountDTO,
trx,
);
}
// /**
// * Concurrrency controlling of the importing process.
// * @returns {number}
// */
// public get concurrency() {
// return 1;
// }
/**
* Concurrrency controlling of the importing process.
* @returns {number}
*/
public get concurrency() {
return 1;
}
// /**
// * Retrieves the sample data that used to download accounts sample sheet.
// */
// public sampleData(): any[] {
// return [];
// }
// }
/**
* Retrieves the sample data that used to download accounts sample sheet.
*/
public sampleData(): any[] {
return [];
}
}

View File

@@ -0,0 +1,249 @@
import { Features } from "@/common/types/Features";
function StatusFieldFilterQuery(query, role) {
query.modify('filterByStatus', role.value);
}
function StatusFieldSortQuery(query, role) {
query.modify('sortByStatus', role.order);
}
export const CreditNoteMeta = {
defaultFilterField: 'name',
defaultSort: {
sortOrder: 'DESC',
sortField: 'name',
},
exportable: true,
exportFlattenOn: 'entries',
importable: true,
importAggregator: 'group',
importAggregateOn: 'entries',
importAggregateBy: 'creditNoteNumber',
print: {
pageTitle: 'Credit Notes',
},
fields: {
customer: {
name: 'credit_note.field.customer',
column: 'customer_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'customer',
relationEntityLabel: 'display_name',
relationEntityKey: 'id',
},
credit_date: {
name: 'credit_note.field.credit_note_date',
column: 'credit_note_date',
fieldType: 'date',
},
credit_number: {
name: 'credit_note.field.credit_note_number',
column: 'credit_note_number',
fieldType: 'text',
},
reference_no: {
name: 'credit_note.field.reference_no',
column: 'reference_no',
fieldType: 'text',
},
amount: {
name: 'credit_note.field.amount',
column: 'amount',
fieldType: 'number',
},
currency_code: {
name: 'credit_note.field.currency_code',
column: 'currency_code',
fieldType: 'number',
},
note: {
name: 'credit_note.field.note',
column: 'note',
fieldType: 'text',
},
terms_conditions: {
name: 'credit_note.field.terms_conditions',
column: 'terms_conditions',
fieldType: 'text',
},
status: {
name: 'credit_note.field.status',
fieldType: 'enumeration',
options: [
{ key: 'draft', label: 'credit_note.field.status.draft' },
{ key: 'published', label: 'credit_note.field.status.published' },
{ key: 'open', label: 'credit_note.field.status.open' },
{ key: 'closed', label: 'credit_note.field.status.closed' },
],
filterCustomQuery: StatusFieldFilterQuery,
sortCustomQuery: StatusFieldSortQuery,
},
created_at: {
name: 'credit_note.field.created_at',
column: 'created_at',
fieldType: 'date',
},
},
columns: {
customer: {
name: 'Customer',
accessor: 'customer.displayName',
},
exchangeRate: {
name: 'Exchange Rate',
printable: false,
},
creditNoteDate: {
name: 'Credit Note Date',
accessor: 'formattedCreditNoteDate',
},
referenceNo: {
name: 'Reference No.',
},
note: {
name: 'Note',
},
termsConditions: {
name: 'Terms & Conditions',
printable: false,
},
creditNoteNumber: {
name: 'Credit Note Number',
printable: false,
},
open: {
name: 'Open',
type: 'boolean',
printable: false,
},
entries: {
name: 'Entries',
type: 'collection',
collectionOf: 'object',
columns: {
itemName: {
name: 'Item Name',
accessor: 'item.name',
},
rate: {
name: 'Item Rate',
accessor: 'rateFormatted',
},
quantity: {
name: 'Item Quantity',
accessor: 'quantityFormatted',
},
description: {
name: 'Item Description',
},
amount: {
name: 'Item Amount',
accessor: 'totalFormatted',
},
},
},
branch: {
name: 'Branch',
type: 'text',
accessor: 'branch.name',
features: [Features.BRANCHES],
},
warehouse: {
name: 'Warehouse',
type: 'text',
accessor: 'warehouse.name',
features: [Features.BRANCHES],
},
},
fields2: {
customerId: {
name: 'Customer',
fieldType: 'relation',
relationModel: 'Contact',
relationImportMatch: 'displayName',
required: true,
},
exchangeRate: {
name: 'Exchange Rate',
fieldType: 'number',
},
creditNoteDate: {
name: 'Credit Note Date',
fieldType: 'date',
required: true,
},
referenceNo: {
name: 'Reference No.',
fieldType: 'text',
},
note: {
name: 'Note',
fieldType: 'text',
},
termsConditions: {
name: 'Terms & Conditions',
fieldType: 'text',
},
creditNoteNumber: {
name: 'Credit Note Number',
fieldType: 'text',
},
open: {
name: 'Open',
fieldType: 'boolean',
},
entries: {
name: 'Entries',
fieldType: 'collection',
collectionOf: 'object',
collectionMinLength: 1,
fields: {
itemId: {
name: 'Item',
fieldType: 'relation',
relationModel: 'Item',
relationImportMatch: ['name', 'code'],
required: true,
importHint: 'Matches the item name or code.',
},
rate: {
name: 'Rate',
fieldType: 'number',
required: true,
},
quantity: {
name: 'Quantity',
fieldType: 'number',
required: true,
},
description: {
name: 'Description',
fieldType: 'text',
},
},
},
branchId: {
name: 'Branch',
fieldType: 'relation',
relationModel: 'Branch',
relationImportMatch: ['name', 'code'],
features: [Features.BRANCHES],
required: true,
},
warehouseId: {
name: 'Warehouse',
fieldType: 'relation',
relationModel: 'Warehouse',
relationImportMatch: ['name', 'code'],
features: [Features.WAREHOUSES],
required: true,
},
},
};

View File

@@ -3,12 +3,17 @@ import { BaseModel } from '@/models/Model';
import { Branch } from '@/modules/Branches/models/Branch.model';
import { Customer } from '@/modules/Customers/models/Customer';
import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model';
import { mixin, Model, raw } from 'objection';
import { CreditNoteMeta } from './CreditNote.meta';
@ExportableModel()
@ImportableModel()
@InjectModelMeta(CreditNoteMeta)
export class CreditNote extends TenantBaseModel {
public amount: number;
public exchangeRate: number;

View File

@@ -1,27 +1,28 @@
import { Knex } from 'knex';
import { Injectable } from '@nestjs/common';
import { Importable } from '../Import/Importable';
import { ExpensesSampleData } from './constants';
import { Injectable } from '@nestjs/common';
import { CreateExpense } from './commands/CreateExpense.service';
import { CreateExpenseDto } from './dtos/Expense.dto';
import { ImportableService } from '../Import/decorators/Import.decorator';
import { ManualJournal } from '../ManualJournals/models/ManualJournal';
@Injectable()
@ImportableService({ name: ManualJournal.name })
export class ExpensesImportable extends Importable {
constructor(private readonly createExpenseService: CreateExpense) {
super();
}
/**
* Importing to account service.
* @param {number} tenantId
* @param {IAccountCreateDTO} createAccountDTO
* @returns
* Importing to expense service.
* @param {CreateExpenseDto} createAccountDTO
*/
public importable(
createAccountDTO: CreateExpenseDto,
createExpenseDto: CreateExpenseDto,
trx?: Knex.Transaction,
) {
return this.createExpenseService.newExpense(createAccountDTO, trx);
return this.createExpenseService.newExpense(createExpenseDto, trx);
}
/**

View File

@@ -0,0 +1,206 @@
import { Features } from "@/common/types/Features";
/**
* Expense - Settings.
*/
export const ExpenseMeta = {
defaultFilterField: 'description',
defaultSort: {
sortOrder: 'DESC',
sortField: 'name',
},
importable: true,
exportFlattenOn: 'categories',
exportable: true,
print: {
pageTitle: 'Expenses',
},
fields: {
payment_date: {
name: 'expense.field.payment_date',
column: 'payment_date',
fieldType: 'date',
},
payment_account: {
name: 'expense.field.payment_account',
column: 'payment_account_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'paymentAccount',
relationEntityLabel: 'name',
relationEntityKey: 'slug',
},
amount: {
name: 'expense.field.amount',
column: 'total_amount',
fieldType: 'number',
},
reference_no: {
name: 'expense.field.reference_no',
column: 'reference_no',
fieldType: 'text',
},
description: {
name: 'expense.field.description',
column: 'description',
fieldType: 'text',
},
published: {
name: 'expense.field.published',
column: 'published_at',
fieldType: 'date',
},
status: {
name: 'expense.field.status',
fieldType: 'enumeration',
options: [
{ label: 'expense.field.status.draft', key: 'draft' },
{ label: 'expense.field.status.published', key: 'published' },
],
filterCustomQuery: StatusFieldFilterQuery,
sortCustomQuery: StatusFieldSortQuery,
},
created_at: {
name: 'expense.field.created_at',
column: 'created_at',
fieldType: 'date',
},
},
columns: {
paymentReceive: {
name: 'expense.field.payment_account',
type: 'text',
accessor: 'paymentAccount.name',
},
referenceNo: {
name: 'expense.field.reference_no',
type: 'text',
},
paymentDate: {
name: 'expense.field.payment_date',
accessor: 'formattedDate',
type: 'date',
},
currencyCode: {
name: 'expense.field.currency_code',
type: 'text',
printable: false,
},
exchangeRate: {
name: 'expense.field.exchange_rate',
type: 'number',
printable: false,
},
description: {
name: 'expense.field.description',
type: 'text',
},
categories: {
name: 'expense.field.categories',
type: 'collection',
collectionOf: 'object',
columns: {
expenseAccount: {
name: 'expense.field.expense_account',
accessor: 'expenseAccount.name',
},
amount: {
name: 'expense.field.amount',
accessor: 'amountFormatted',
},
description: {
name: 'expense.field.line_description',
type: 'text',
},
},
},
publish: {
name: 'expense.field.publish',
type: 'boolean',
printable: false,
},
branch: {
name: 'Branch',
type: 'text',
accessor: 'branch.name',
features: [Features.BRANCHES],
},
},
fields2: {
paymentAccountId: {
name: 'expense.field.payment_account',
fieldType: 'relation',
relationModel: 'Account',
relationImportMatch: ['name', 'code'],
required: true,
importHint: 'Matches the account name or code.',
},
referenceNo: {
name: 'expense.field.reference_no',
fieldType: 'text',
},
paymentDate: {
name: 'expense.field.payment_date',
fieldType: 'date',
required: true,
},
currencyCode: {
name: 'expense.field.currency_code',
fieldType: 'text',
},
exchangeRate: {
name: 'expense.field.exchange_rate',
fieldType: 'number',
},
description: {
name: 'expense.field.description',
fieldType: 'text',
},
categories: {
name: 'expense.field.categories',
fieldType: 'collection',
collectionOf: 'object',
fields: {
expenseAccountId: {
name: 'expense.field.expense_account',
fieldType: 'relation',
relationModel: 'Account',
relationImportMatch: ['name', 'code'],
required: true,
importHint: 'Matches the account name or code.',
},
amount: {
name: 'expense.field.amount',
fieldType: 'number',
required: true,
},
description: {
name: 'expense.field.line_description',
fieldType: 'text',
},
},
},
publish: {
name: 'expense.field.publish',
fieldType: 'boolean',
},
branchId: {
name: 'Branch',
fieldType: 'relation',
relationModel: 'Branch',
relationImportMatch: ['name', 'code'],
features: [Features.BRANCHES],
required: true,
},
},
};
function StatusFieldFilterQuery(query, role) {
query.modify('filterByStatus', role.value);
}
function StatusFieldSortQuery(query, role) {
query.modify('sortByStatus', role.order);
}

View File

@@ -4,8 +4,13 @@ import { ExpenseCategory } from './ExpenseCategory.model';
import { Account } from '@/modules/Accounts/models/Account.model';
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { ExpenseMeta } from './Expense.meta';
@ExportableModel()
@ImportableModel()
@InjectModelMeta(ExpenseMeta)
export class Expense extends TenantBaseModel {
totalAmount!: number;
currencyCode!: string;

View File

@@ -1,11 +1,16 @@
import { Knex } from 'knex';
import * as Yup from 'yup';
import { Injectable } from '@nestjs/common';
import { Importable } from '../../Import/Importable';
import { CreateManualJournalService } from './CreateManualJournal.service';
import { ImportableContext } from '../../Import/interfaces';
import { ManualJournalsSampleData } from '../constants';
import { CreateManualJournalDto } from '../dtos/ManualJournal.dto';
import { ImportableService } from '@/modules/Import/decorators/Import.decorator';
import { ManualJournal } from '../models/ManualJournal';
@Injectable()
@ImportableService({ name: ManualJournal.name })
export class ManualJournalImportable extends Importable {
constructor(
private readonly createManualJournalService: CreateManualJournalService,

View File

@@ -12,8 +12,10 @@ import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { ManualJournalMeta } from './ManualJournal.meta';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
@ExportableModel()
@ImportableModel()
@InjectModelMeta(ManualJournalMeta)
export class ManualJournal extends TenantBaseModel {
date: Date;

View File

@@ -1,4 +1,5 @@
import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { PaymentReceivesController } from './PaymentsReceived.controller';
import { PaymentReceivesApplication } from './PaymentReceived.application';
import { CreatePaymentReceivedService } from './commands/CreatePaymentReceived.serivce';
@@ -32,7 +33,6 @@ import { MailNotificationModule } from '../MailNotification/MailNotification.mod
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { MailModule } from '../Mail/Mail.module';
import { SendPaymentReceivedMailProcessor } from './processors/PaymentReceivedMailNotification.processor';
import { BullModule } from '@nestjs/bull';
import { SEND_PAYMENT_RECEIVED_MAIL_QUEUE } from './constants';
import { PaymentsReceivedExportable } from './commands/PaymentsReceivedExportable';
import { PaymentsReceivedImportable } from './commands/PaymentsReceivedImportable';
@@ -62,12 +62,14 @@ import { PaymentsReceivedImportable } from './commands/PaymentsReceivedImportabl
SendPaymentReceiveMailNotification,
SendPaymentReceivedMailProcessor,
PaymentsReceivedExportable,
PaymentsReceivedImportable
PaymentsReceivedImportable,
],
exports: [
PaymentReceivesApplication,
CreatePaymentReceivedService,
PaymentReceivedGLEntries,
PaymentsReceivedExportable,
PaymentsReceivedImportable,
],
imports: [
ChromiumlyTenancyModule,

View File

@@ -3,8 +3,11 @@ import { PaymentReceivesApplication } from '../PaymentReceived.application';
import { IPaymentsReceivedFilter } from '../types/PaymentReceived.types';
import { EXPORT_SIZE_LIMIT } from '@/modules/Export/constants';
import { Exportable } from '@/modules/Export/Exportable';
import { ExportableService } from '@/modules/Export/decorators/ExportableModel.decorator';
import { PaymentReceived } from '../models/PaymentReceived';
@Injectable()
@ExportableService({ name: PaymentReceived.name })
export class PaymentsReceivedExportable extends Exportable {
constructor(private readonly paymentReceivedApp: PaymentReceivesApplication) {
super();

View File

@@ -4,8 +4,11 @@ import { Injectable } from '@nestjs/common';
import { PaymentsReceiveSampleData } from '../constants';
import { CreatePaymentReceivedService } from './CreatePaymentReceived.serivce';
import { Importable } from '@/modules/Import/Importable';
import { ImportableService } from '@/modules/Import/decorators/Import.decorator';
import { PaymentReceived } from '../models/PaymentReceived';
@Injectable()
@ImportableService({ name: PaymentReceived.name })
export class PaymentsReceivedImportable extends Importable {
constructor(
private readonly createPaymentReceiveService: CreatePaymentReceivedService,

View File

@@ -0,0 +1,210 @@
import { Features } from "@/common/types/Features";
export const PaymentReceivedMeta = {
importable: true,
exportable: true,
exportFlattenOn: 'entries',
importAggregator: 'group',
importAggregateOn: 'entries',
importAggregateBy: 'paymentReceiveNo',
fields: {
customer: {
name: 'payment_receive.field.customer',
column: 'customer_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'customer',
relationEntityLabel: 'display_name',
relationEntityKey: 'id',
},
payment_date: {
name: 'payment_receive.field.payment_date',
column: 'payment_date',
fieldType: 'date',
},
amount: {
name: 'payment_receive.field.amount',
column: 'amount',
fieldType: 'number',
},
reference_no: {
name: 'payment_receive.field.reference_no',
column: 'reference_no',
fieldType: 'text',
},
deposit_account: {
name: 'payment_receive.field.deposit_account',
column: 'deposit_account_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'depositAccount',
relationEntityLabel: 'name',
relationEntityKey: 'slug',
},
payment_receive_no: {
name: 'payment_receive.field.payment_receive_no',
column: 'payment_receive_no',
fieldType: 'text',
},
statement: {
name: 'payment_receive.field.statement',
column: 'statement',
fieldType: 'text',
},
created_at: {
name: 'payment_receive.field.created_at',
column: 'created_at',
fieldDate: 'date',
},
},
columns: {
customer: {
name: 'payment_receive.field.customer',
accessor: 'customer.displayName',
type: 'text',
},
paymentDate: {
name: 'payment_receive.field.payment_date',
type: 'date',
accessor: 'formattedPaymentDate',
},
amount: {
name: 'payment_receive.field.amount',
type: 'number',
accessor: 'formattedAmount',
},
referenceNo: {
name: 'payment_receive.field.reference_no',
type: 'text',
},
depositAccount: {
name: 'payment_receive.field.deposit_account',
accessor: 'depositAccount.name',
type: 'text',
},
paymentReceiveNo: {
name: 'payment_receive.field.payment_receive_no',
type: 'text',
},
statement: {
name: 'payment_receive.field.statement',
type: 'text',
printable: false,
},
entries: {
name: 'Entries',
accessor: 'entries',
type: 'collection',
collectionOf: 'object',
columns: {
date: {
name: 'Invoice date',
accessor: 'invoice.invoiceDateFormatted',
},
invoiceNo: {
name: 'Invoice No.',
accessor: 'invoice.invoiceNo',
},
invoiceRefNo: {
name: 'Invoice Reference No.',
accessor: 'invoice.referenceNo',
},
invoiceAmount: {
name: 'Invoice Amount',
accessor: 'invoice.totalFormatted',
},
paidAmount: {
name: 'Paid Amount',
accessor: 'paymentAmountFormatted',
},
},
},
created_at: {
name: 'payment_receive.field.created_at',
type: 'date',
printable: false,
},
branch: {
name: 'Branch',
type: 'text',
accessor: 'branch.name',
features: [Features.BRANCHES],
},
},
fields2: {
customerId: {
name: 'payment_receive.field.customer',
fieldType: 'relation',
relationModel: 'Contact',
relationImportMatch: ['displayName'],
required: true,
},
exchangeRate: {
name: 'payment_receive.field.exchange_rate',
fieldType: 'number',
},
paymentDate: {
name: 'payment_receive.field.payment_date',
fieldType: 'date',
required: true,
},
referenceNo: {
name: 'payment_receive.field.reference_no',
fieldType: 'text',
},
depositAccountId: {
name: 'payment_receive.field.deposit_account',
fieldType: 'relation',
relationModel: 'Account',
relationImportMatch: ['name', 'code'],
required: true,
importHint: 'Matches the account name or code.',
},
paymentReceiveNo: {
name: 'payment_receive.field.payment_receive_no',
fieldType: 'text',
importHint: 'The payment number should be unique.',
},
statement: {
name: 'payment_receive.field.statement',
fieldType: 'text',
},
entries: {
name: 'payment_receive.field.entries',
fieldType: 'collection',
collectionOf: 'object',
collectionMinLength: 1,
required: true,
fields: {
invoiceId: {
name: 'payment_receive.field.invoice',
fieldType: 'relation',
relationModel: 'SaleInvoice',
relationImportMatch: 'invoiceNo',
required: true,
importHint: 'Matches the invoice number.',
},
paymentAmount: {
name: 'payment_receive.field.entries.payment_amount',
fieldType: 'number',
required: true,
},
},
},
branchId: {
name: 'Branch',
fieldType: 'relation',
relationModel: 'Branch',
relationImportMatch: ['name', 'code'],
features: [Features.BRANCHES],
required: true,
},
},
};

View File

@@ -2,8 +2,13 @@ import { Model } from 'objection';
import { PaymentReceivedEntry } from './PaymentReceivedEntry';
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { PaymentReceivedMeta } from './PaymentReceived.meta';
@ExportableModel()
@ImportableModel()
@InjectModelMeta(PaymentReceivedMeta)
export class PaymentReceived extends TenantBaseModel {
customerId: number;
paymentDate: string;

View File

@@ -4,8 +4,11 @@ import { SaleEstimatesSampleData } from './constants';
import { Injectable } from '@nestjs/common';
import { CreateSaleEstimateDto } from './dtos/SaleEstimate.dto';
import { Importable } from '../Import/Importable';
import { ImportableService } from '../Import/decorators/Import.decorator';
import { SaleEstimate } from './models/SaleEstimate';
@Injectable()
@ImportableService({ name: SaleEstimate.name })
export class SaleEstimatesImportable extends Importable{
constructor(
private readonly createEstimateService: CreateSaleEstimate

View File

@@ -0,0 +1,294 @@
import { Features } from "@/common/types/Features";
export const SaleEstimateMeta = {
defaultFilterField: 'estimate_date',
defaultSort: {
sortOrder: 'DESC',
sortField: 'estimate_date',
},
exportable: true,
exportFlattenOn: 'entries',
importable: true,
importAggregator: 'group',
importAggregateOn: 'entries',
importAggregateBy: 'estimateNumber',
print: {
pageTitle: 'Sale Estimates',
},
fields: {
amount: {
name: 'estimate.field.amount',
column: 'amount',
fieldType: 'number',
},
estimate_number: {
name: 'estimate.field.estimate_number',
column: 'estimate_number',
fieldType: 'text',
},
customer: {
name: 'estimate.field.customer',
column: 'customer_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'customer',
relationEntityLabel: 'display_name',
relationEntityKey: 'id',
},
estimate_date: {
name: 'estimate.field.estimate_date',
column: 'estimate_date',
fieldType: 'date',
},
expiration_date: {
name: 'estimate.field.expiration_date',
column: 'expiration_date',
fieldType: 'date',
},
reference_no: {
name: 'estimate.field.reference_no',
column: 'reference',
fieldType: 'text',
},
note: {
name: 'estimate.field.note',
column: 'note',
fieldType: 'text',
},
terms_conditions: {
name: 'estimate.field.terms_conditions',
column: 'terms_conditions',
fieldType: 'text',
},
status: {
name: 'estimate.field.status',
fieldType: 'enumeration',
options: [
{ label: 'estimate.field.status.delivered', key: 'delivered' },
{ label: 'estimate.field.status.rejected', key: 'rejected' },
{ label: 'estimate.field.status.approved', key: 'approved' },
{ label: 'estimate.field.status.draft', key: 'draft' },
],
filterCustomQuery: StatusFieldFilterQuery,
sortCustomQuery: StatusFieldSortQuery,
},
created_at: {
name: 'estimate.field.created_at',
column: 'created_at',
columnType: 'date',
},
},
columns: {
customer: {
name: 'Customer',
type: 'text',
accessor: 'customer.displayName',
exportable: true,
},
estimateDate: {
name: 'Estimate Date',
type: 'date',
accessor: 'formattedEstimateDate',
exportable: true,
},
expirationDate: {
name: 'Expiration Date',
type: 'date',
accessor: 'formattedExpirationDate',
exportable: true,
},
estimateNumber: {
name: 'Estimate No.',
type: 'text',
exportable: true,
},
reference: {
name: 'Reference No.',
type: 'text',
exportable: true,
},
amount: {
name: 'Amount',
accessor: 'formattedAmount',
type: 'text',
},
exchangeRate: {
name: 'Exchange Rate',
type: 'number',
exportable: true,
printable: false,
},
currencyCode: {
name: 'Currency',
type: 'text',
exportable: true,
printable: false,
},
note: {
name: 'Note',
type: 'text',
exportable: true,
printable: false,
},
termsConditions: {
name: 'Terms & Conditions',
type: 'text',
exportable: true,
printable: false,
},
delivered: {
name: 'Delivered',
type: 'boolean',
accessor: 'isDelivered',
exportable: true,
printable: false,
},
entries: {
name: 'Entries',
accessor: 'entries',
type: 'collection',
collectionOf: 'object',
columns: {
itemName: {
name: 'Item Name',
accessor: 'item.name',
},
rate: {
name: 'Item Rate',
accessor: 'rateFormatted',
},
quantity: {
name: 'Item Quantity',
accessor: 'quantityFormatted',
},
description: {
name: 'Item Description',
printable: false,
},
amount: {
name: 'Item Amount',
accessor: 'totalFormatted',
},
},
},
branch: {
name: 'Branch',
type: 'text',
accessor: 'branch.name',
features: [Features.BRANCHES],
},
warehouse: {
name: 'Warehouse',
type: 'text',
accessor: 'warehouse.name',
features: [Features.BRANCHES],
},
},
fields2: {
customerId: {
name: 'Customer',
fieldType: 'relation',
relationModel: 'Contact',
relationImportMatch: ['displayName'],
required: true,
},
estimateDate: {
name: 'Estimate Date',
fieldType: 'date',
required: true,
},
expirationDate: {
name: 'Expiration Date',
fieldType: 'date',
required: true,
},
estimateNumber: {
name: 'Estimate No.',
fieldType: 'text',
},
reference: {
name: 'Reference No.',
fieldType: 'text',
},
exchangeRate: {
name: 'Exchange Rate',
fieldType: 'number',
},
currencyCode: {
name: 'Currency',
fieldType: 'text',
},
note: {
name: 'Note',
fieldType: 'text',
},
termsConditions: {
name: 'Terms & Conditions',
fieldType: 'text',
},
delivered: {
name: 'Delivered',
type: 'boolean',
},
entries: {
name: 'Entries',
fieldType: 'collection',
collectionOf: 'object',
collectionMinLength: 1,
required: true,
fields: {
itemId: {
name: 'invoice.field.item_name',
fieldType: 'relation',
relationModel: 'Item',
relationImportMatch: ['name', 'code'],
required: true,
importHint: 'Matches the item name or code.',
},
rate: {
name: 'invoice.field.rate',
fieldType: 'number',
required: true,
},
quantity: {
name: 'invoice.field.quantity',
fieldType: 'number',
required: true,
},
description: {
name: 'Line Description',
fieldType: 'text',
},
},
},
branchId: {
name: 'Branch',
fieldType: 'relation',
relationModel: 'Branch',
relationImportMatch: ['name', 'code'],
features: [Features.BRANCHES],
required: true,
},
warehouseId: {
name: 'Warehouse',
fieldType: 'relation',
relationModel: 'Warehouse',
relationImportMatch: ['name', 'code'],
features: [Features.WAREHOUSES],
required: true,
},
},
};
function StatusFieldSortQuery(query, role) {
query.modify('orderByStatus', role.order);
}
function StatusFieldFilterQuery(query, role) {
query.modify('filterByStatus', role.value);
}

View File

@@ -3,8 +3,13 @@ import { Model } from 'objection';
import { Injectable } from '@nestjs/common';
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { SaleEstimateMeta } from './SaleEstimate.meta';
@ExportableModel()
@ImportableModel()
@InjectModelMeta(SaleEstimateMeta)
export class SaleEstimate extends TenantBaseModel {
exchangeRate!: number;
amount!: number;

View File

@@ -4,8 +4,11 @@ import { CreateSaleInvoice } from './CreateSaleInvoice.service';
import { Importable } from '@/modules/Import/Importable';
import { CreateSaleInvoiceDto } from '../dtos/SaleInvoice.dto';
import { SaleInvoicesSampleData } from '../constants';
import { ImportableService } from '@/modules/Import/decorators/Import.decorator';
import { ManualJournal } from '@/modules/ManualJournals/models/ManualJournal';
@Injectable()
@ImportableService({ name: ManualJournal.name })
export class SaleInvoicesImportable extends Importable {
constructor(private readonly createInvoiceService: CreateSaleInvoice) {
super();

View File

@@ -20,12 +20,13 @@ import { VendorCreditGlEntriesSubscriber } from './subscribers/VendorCreditGLEnt
import { VendorCreditGLEntries } from './commands/VendorCreditGLEntries';
import { LedgerModule } from '../Ledger/Ledger.module';
import { AccountsModule } from '../Accounts/Accounts.module';
import VendorCreditInventoryTransactionsSubscriber from './subscribers/VendorCreditInventoryTransactionsSusbcriber';
import { VendorCreditInventoryTransactionsSubscriber } from './subscribers/VendorCreditInventoryTransactionsSusbcriber';
import { VendorCreditInventoryTransactions } from './commands/VendorCreditInventoryTransactions';
import { GetVendorCreditsService } from './queries/GetVendorCredits.service';
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { InventoryCostModule } from '../InventoryCost/InventoryCost.module';
import { VendorCreditsExportable } from './commands/VendorCreditsExportable';
import { VendorCreditsImportable } from './commands/VendorCreditsImportable';
@Module({
imports: [
@@ -39,7 +40,7 @@ import { VendorCreditsExportable } from './commands/VendorCreditsExportable';
LedgerModule,
AccountsModule,
DynamicListModule,
InventoryCostModule
InventoryCostModule,
],
providers: [
CreateVendorCreditService,
@@ -56,7 +57,8 @@ import { VendorCreditsExportable } from './commands/VendorCreditsExportable';
VendorCreditGlEntriesSubscriber,
VendorCreditInventoryTransactions,
VendorCreditInventoryTransactionsSubscriber,
VendorCreditsExportable
VendorCreditsExportable,
VendorCreditsImportable,
],
exports: [
CreateVendorCreditService,
@@ -67,7 +69,9 @@ import { VendorCreditsExportable } from './commands/VendorCreditsExportable';
GetRefundVendorCreditService,
GetVendorCreditService,
VendorCreditsApplicationService,
OpenVendorCreditService
OpenVendorCreditService,
VendorCreditsExportable,
VendorCreditsImportable,
],
controllers: [VendorCreditsController],
})

View File

@@ -1,45 +1,49 @@
// import { Inject, Service } from 'typedi';
// import { Knex } from 'knex';
// import { Importable } from '@/services/Import/Importable';
// import CreateVendorCredit from './CreateVendorCredit.service';
// import { IVendorCreditCreateDTO } from '@/interfaces';
// import { VendorCreditsSampleData } from '../constants';
import { Knex } from 'knex';
import { VendorCreditsSampleData } from '../constants';
import { Injectable } from '@nestjs/common';
import { CreateVendorCreditService } from './CreateVendorCredit.service';
import { CreateVendorCreditDto } from '../dtos/VendorCredit.dto';
import { Importable } from '@/modules/Import/Importable';
import { ImportableService } from '@/modules/Import/decorators/Import.decorator';
import { VendorCredit } from '../models/VendorCredit';
// @Service()
// export class VendorCreditsImportable extends Importable {
// @Inject()
// private createVendorCreditService: CreateVendorCredit;
@Injectable()
@ImportableService({ name: VendorCredit.name })
export class VendorCreditsImportable extends Importable {
constructor(
private readonly createVendorCreditService: CreateVendorCreditService,
) {
super()
}
// /**
// * Importing to account service.
// * @param {number} tenantId
// * @param {IAccountCreateDTO} createAccountDTO
// * @returns
// */
// public importable(
// tenantId: number,
// createPaymentDTO: IVendorCreditCreateDTO,
// trx?: Knex.Transaction
// ) {
// return this.createVendorCreditService.newVendorCredit(
// tenantId,
// createPaymentDTO,
// trx
// );
// }
/**
* Importing to account service.
* @param {number} tenantId
* @param {IAccountCreateDTO} createAccountDTO
* @returns
*/
public importable(
createPaymentDTO: CreateVendorCreditDto,
trx?: Knex.Transaction
) {
return this.createVendorCreditService.newVendorCredit(
createPaymentDTO,
trx
);
}
// /**
// * Concurrrency controlling of the importing process.
// * @returns {number}
// */
// public get concurrency() {
// return 1;
// }
/**
* Concurrrency controlling of the importing process.
* @returns {number}
*/
public get concurrency() {
return 1;
}
// /**
// * Retrieves the sample data that used to download accounts sample sheet.
// */
// public sampleData(): any[] {
// return VendorCreditsSampleData;
// }
// }
/**
* Retrieves the sample data that used to download accounts sample sheet.
*/
public sampleData(): any[] {
return VendorCreditsSampleData;
}
}

View File

@@ -0,0 +1,259 @@
import { Features } from '@/common/types/Features';
function StatusFieldFilterQuery(query, role) {
query.modify('filterByStatus', role.value);
}
function StatusFieldSortQuery(query, role) {
query.modify('sortByStatus', role.order);
}
export const VendorCreditMeta = {
defaultFilterField: 'name',
defaultSort: {
sortOrder: 'DESC',
sortField: 'name',
},
exportable: true,
exportFlattenOn: 'entries',
importable: true,
importAggregator: 'group',
importAggregateOn: 'entries',
importAggregateBy: 'vendorCreditNumber',
print: {
pageTitle: 'Vendor Credits',
},
fields: {
vendor: {
name: 'vendor_credit.field.vendor',
column: 'vendor_id',
fieldType: 'relation',
relationType: 'enumeration',
relationKey: 'vendor',
relationEntityLabel: 'display_name',
relationEntityKey: 'id',
},
amount: {
name: 'vendor_credit.field.amount',
column: 'amount',
fieldType: 'number',
},
currency_code: {
name: 'vendor_credit.field.currency_code',
column: 'currency_code',
fieldType: 'string',
},
credit_date: {
name: 'vendor_credit.field.credit_date',
column: 'vendor_credit_date',
fieldType: 'date',
},
reference_no: {
name: 'vendor_credit.field.reference_no',
column: 'reference_no',
fieldType: 'text',
},
credit_number: {
name: 'vendor_credit.field.credit_number',
column: 'vendor_credit_number',
fieldType: 'text',
},
note: {
name: 'vendor_credit.field.note',
column: 'note',
fieldType: 'text',
},
status: {
name: 'vendor_credit.field.status',
fieldType: 'enumeration',
options: [
{ key: 'draft', label: 'vendor_credit.field.status.draft' },
{ key: 'published', label: 'vendor_credit.field.status.published' },
{ key: 'open', label: 'vendor_credit.field.status.open' },
{ key: 'closed', label: 'vendor_credit.field.status.closed' },
],
filterCustomQuery: StatusFieldFilterQuery,
sortCustomQuery: StatusFieldSortQuery,
},
created_at: {
name: 'vendor_credit.field.created_at',
column: 'created_at',
fieldType: 'date',
},
},
columns: {
vendorId: {
name: 'Vendor',
type: 'relation',
accessor: 'vendor.displayName',
},
exchangeRate: {
name: 'Echange Rate',
type: 'text',
printable: false,
},
vendorCreditNumber: {
name: 'Vendor Credit No.',
type: 'text',
},
referenceNo: {
name: 'Refernece No.',
type: 'text',
},
vendorCreditDate: {
name: 'Vendor Credit Date',
accessor: 'formattedVendorCreditDate',
},
amount: {
name: 'Amount',
accessor: 'formattedAmount',
},
creditRemaining: {
name: 'Credits Remaining',
accessor: 'formattedCreditsRemaining',
printable: false,
},
refundedAmount: {
name: 'Refunded Amount',
accessor: 'refundedAmount',
printable: false,
},
invoicedAmount: {
name: 'Invoiced Amount',
accessor: 'formattedInvoicedAmount',
},
note: {
name: 'Note',
type: 'text',
printable: false,
},
open: {
name: 'Open',
type: 'boolean',
printable: false,
},
entries: {
name: 'Entries',
type: 'collection',
collectionOf: 'object',
columns: {
itemName: {
name: 'Item Name',
accessor: 'item.name',
},
rate: {
name: 'Item Rate',
accessor: 'rateFormatted',
},
quantity: {
name: 'Item Quantity',
accessor: 'quantityFormatted',
},
description: {
name: 'Item Description',
},
amount: {
name: 'Item Amount',
accessor: 'totalFormatted',
},
},
},
branch: {
name: 'Branch',
type: 'text',
accessor: 'branch.name',
features: [Features.BRANCHES],
},
warehouse: {
name: 'Warehouse',
type: 'text',
accessor: 'warehouse.name',
features: [Features.BRANCHES],
},
},
fields2: {
vendorId: {
name: 'Vendor',
fieldType: 'relation',
relationModel: 'Contact',
relationImportMatch: 'displayName',
required: true,
},
exchangeRate: {
name: 'Echange Rate',
fieldType: 'text',
},
vendorCreditNumber: {
name: 'Vendor Credit No.',
fieldType: 'text',
},
referenceNo: {
name: 'Refernece No.',
fieldType: 'text',
},
vendorCreditDate: {
name: 'Vendor Credit Date',
fieldType: 'date',
required: true,
},
note: {
name: 'Note',
fieldType: 'text',
},
open: {
name: 'Open',
fieldType: 'boolean',
},
entries: {
name: 'Entries',
fieldType: 'collection',
collectionOf: 'object',
collectionMinLength: 1,
required: true,
fields: {
itemId: {
name: 'Item Name',
fieldType: 'relation',
relationModel: 'Item',
relationImportMatch: ['name', 'code'],
required: true,
importHint: 'Matches the item name or code.',
},
rate: {
name: 'Rate',
fieldType: 'number',
required: true,
},
quantity: {
name: 'Quantity',
fieldType: 'number',
required: true,
},
description: {
name: 'Description',
fieldType: 'text',
},
},
},
branchId: {
name: 'Branch',
fieldType: 'relation',
relationModel: 'Branch',
relationImportMatch: ['name', 'code'],
features: [Features.BRANCHES],
required: true
},
warehouseId: {
name: 'Warehouse',
fieldType: 'relation',
relationModel: 'Warehouse',
relationImportMatch: ['name', 'code'],
features: [Features.WAREHOUSES],
required: true
},
},
};

View File

@@ -6,8 +6,13 @@ import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
import { DiscountType } from '@/common/types/Discount';
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
import { ExportableModel } from '@/modules/Export/decorators/ExportableModel.decorator';
import { ImportableModel } from '@/modules/Import/decorators/Import.decorator';
import { InjectModelMeta } from '@/modules/Tenancy/TenancyModels/decorators/InjectModelMeta.decorator';
import { VendorCreditMeta } from './VendorCredit.meta';
@ExportableModel()
@ImportableModel()
@InjectModelMeta(VendorCreditMeta)
export class VendorCredit extends TenantBaseModel {
vendorId: number;
amount: number;

View File

@@ -9,7 +9,7 @@ import { Injectable } from '@nestjs/common';
import { events } from '@/common/events/events';
@Injectable()
export default class VendorCreditInventoryTransactionsSubscriber {
export class VendorCreditInventoryTransactionsSubscriber {
constructor(
private readonly inventoryTransactions: VendorCreditInventoryTransactions,
) {}