mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-23 00:00:31 +00:00
Merge branch 'master' of https://github.com/abouolia/Bigcapital
This commit is contained in:
@@ -139,6 +139,7 @@ export default class AccountsController extends BaseController {
|
|||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
|
|
||||||
query('inactive_mode').optional().isBoolean().toBoolean(),
|
query('inactive_mode').optional().isBoolean().toBoolean(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ export default class CustomersController extends ContactsController {
|
|||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
|
|
||||||
query('inactive_mode').optional().isBoolean().toBoolean(),
|
query('inactive_mode').optional().isBoolean().toBoolean(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ export default class VendorsController extends ContactsController {
|
|||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
|
||||||
query('inactive_mode').optional().isBoolean().toBoolean(),
|
query('inactive_mode').optional().isBoolean().toBoolean(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,8 @@ export default class ExpensesController extends BaseController {
|
|||||||
|
|
||||||
query('page').optional().isNumeric().toInt(),
|
query('page').optional().isNumeric().toInt(),
|
||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ export default class ItemsController extends BaseController {
|
|||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
|
|
||||||
query('inactive_mode').optional().isBoolean().toBoolean(),
|
query('inactive_mode').optional().isBoolean().toBoolean(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ export default class ManualJournalsController extends BaseController {
|
|||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
|
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ export default class BillsController extends BaseController {
|
|||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
query('column_sort_by').optional(),
|
query('column_sort_by').optional(),
|
||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
query('page').optional().isNumeric().toInt(),
|
query('page').optional().isNumeric().toInt(),
|
||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,12 +115,17 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
get validatePaymentReceiveList(): ValidationChain[] {
|
get validatePaymentReceiveList(): ValidationChain[] {
|
||||||
return [
|
return [
|
||||||
query('view_slug').optional({ nullable: true }).isString().trim(),
|
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
|
|
||||||
|
query('view_slug').optional({ nullable: true }).isString().trim(),
|
||||||
|
|
||||||
query('column_sort_by').optional(),
|
query('column_sort_by').optional(),
|
||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
|
|
||||||
query('page').optional().isNumeric().toInt(),
|
query('page').optional().isNumeric().toInt(),
|
||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
query('page').optional().isNumeric().toInt(),
|
query('page').optional().isNumeric().toInt(),
|
||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
query('page').optional().isNumeric().toInt(),
|
query('page').optional().isNumeric().toInt(),
|
||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
query('sort_order').optional().isIn(['desc', 'asc']),
|
query('sort_order').optional().isIn(['desc', 'asc']),
|
||||||
query('page').optional().isNumeric().toInt(),
|
query('page').optional().isNumeric().toInt(),
|
||||||
query('page_size').optional().isNumeric().toInt(),
|
query('page_size').optional().isNumeric().toInt(),
|
||||||
|
query('search_keyword').optional({ nullable: true }).isString().trim(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
import Container from 'typedi';
|
|
||||||
import TenancyService from 'services/Tenancy/TenancyService';
|
|
||||||
|
|
||||||
exports.up = (knex) => {
|
|
||||||
const tenancyService = Container.get(TenancyService);
|
|
||||||
const i18n = tenancyService.i18n(knex.userParams.tenantId);
|
|
||||||
|
|
||||||
// Deletes ALL existing entries
|
|
||||||
return knex('views').del()
|
|
||||||
.then(() => {
|
|
||||||
// Inserts seed entries
|
|
||||||
return knex('views').insert([
|
|
||||||
// Accounts.
|
|
||||||
{ id: 15, name: i18n.__('Inactive'), slug: 'inactive', roles_logic_expression: '1', resource_model: 'Account', predefined: true },
|
|
||||||
{ id: 1, name: i18n.__('Assets'), slug: 'assets', roles_logic_expression: '1', resource_model: 'Account', predefined: true },
|
|
||||||
{ id: 2, name: i18n.__('Liabilities'), slug: 'liabilities', roles_logic_expression: '1', resource_model: 'Account', predefined: true },
|
|
||||||
{ id: 3, name: i18n.__('Equity'), slug: 'equity', roles_logic_expression: '1', resource_model: 'Account', predefined: true },
|
|
||||||
{ id: 4, name: i18n.__('Income'), slug: 'income', roles_logic_expression: '1', resource_model: 'Account', predefined: true },
|
|
||||||
{ id: 5, name: i18n.__('Expenses'), slug: 'expenses', roles_logic_expression: '1', resource_model: 'Account', predefined: true },
|
|
||||||
|
|
||||||
// Items.
|
|
||||||
{ id: 6, name: i18n.__('Services'), slug: 'services', roles_logic_expression: '1', resource_model: 'Item', predefined: true },
|
|
||||||
{ id: 7, name: i18n.__('Inventory'), slug: 'inventory', roles_logic_expression: '1', resource_model: 'Item', predefined: true },
|
|
||||||
{ id: 8, name: i18n.__('Non-Inventory'), slug: 'non-inventory', roles_logic_expression: '1', resource_model: 'Item', predefined: true },
|
|
||||||
|
|
||||||
// Manual Journals
|
|
||||||
{ id: 9, name: i18n.__('Journal'), roles_logic_expression: '1', resource_model: 'ManualJournal', predefined: true },
|
|
||||||
{ id: 10, name: i18n.__('Credit'), roles_logic_expression: '1', resource_model: 'ManualJournal', predefined: true },
|
|
||||||
{ id: 11, name: i18n.__('Reconciliation'), roles_logic_expression: '1', resource_model: 'ManualJournal', predefined: true },
|
|
||||||
|
|
||||||
// Expenses.
|
|
||||||
{ id: 12, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'Expense', predefined: true, },
|
|
||||||
{ id: 13, name: i18n.__('Published'), slug: 'published', roles_logic_expression: '1', resource_model: 'Expense', predefined: true, },
|
|
||||||
|
|
||||||
// Sales invoices.
|
|
||||||
{ id: 16, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true, },
|
|
||||||
{ id: 17, name: i18n.__('Delivered'), slug: 'delivered', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
|
|
||||||
{ id: 18, name: i18n.__('Unpaid'), slug: 'unpaid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
|
|
||||||
{ id: 19, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
|
|
||||||
{ id: 20, name: i18n.__('Partially paid'), slug: 'partially-paid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
|
|
||||||
{ id: 21, name: i18n.__('Paid'), slug: 'paid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
|
|
||||||
|
|
||||||
// Bills.
|
|
||||||
{ id: 22, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'Bill', predefined: true, },
|
|
||||||
{ id: 23, name: i18n.__('Opened'), slug: 'opened', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
|
|
||||||
{ id: 24, name: i18n.__('Unpaid'), slug: 'unpaid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
|
|
||||||
{ id: 25, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
|
|
||||||
{ id: 26, name: i18n.__('Partially paid'), slug: 'partially-paid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
|
|
||||||
{ id: 27, name: i18n.__('Paid'), slug: 'paid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
|
|
||||||
|
|
||||||
// Sale estimate.
|
|
||||||
{ id: 28, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
|
|
||||||
{ id: 29, name: i18n.__('Delivered'), slug: 'delivered', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
|
|
||||||
{ id: 30, name: i18n.__('Approved'), slug: 'approved', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
|
|
||||||
{ id: 31, name: i18n.__('Rejected'), slug: 'rejected', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
|
|
||||||
{ id: 32, name: i18n.__('Invoiced'), slug: 'invoiced', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
|
|
||||||
{ id: 33, name: i18n.__('Expired'), slug: 'expired', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
|
|
||||||
|
|
||||||
// Sale receipts.
|
|
||||||
{ id: 34, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleReceipt', predefined: true },
|
|
||||||
{ id: 35, name: i18n.__('Closed'), slug: 'closed', roles_logic_expression: '1', resource_model: 'SaleReceipt', predefined: true },
|
|
||||||
|
|
||||||
// Customers
|
|
||||||
{ id: 36, name: i18n.__('Active'), slug: 'active', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
|
|
||||||
{ id: 37, name: i18n.__('Inactive'), slug: 'inactive', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
|
|
||||||
{ id: 38, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
|
|
||||||
{ id: 39, name: i18n.__('Unpaid'), slug: 'inpaid', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
|
|
||||||
|
|
||||||
// Vendors
|
|
||||||
{ id: 40, name: i18n.__('Active'), slug: 'active', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
|
|
||||||
{ id: 41, name: i18n.__('Inactive'), slug: 'inactive', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
|
|
||||||
{ id: 42, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
|
|
||||||
{ id: 43, name: i18n.__('Unpaid'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
exports.down = (knex) => {
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
|
|
||||||
exports.up = (knex) => {
|
|
||||||
// Deletes ALL existing entries
|
|
||||||
return knex('view_roles').del()
|
|
||||||
.then(() => {
|
|
||||||
// Inserts seed entries
|
|
||||||
return knex('view_roles').insert([
|
|
||||||
// Accounts
|
|
||||||
{ field_key: 'root_type', index: 1, comparator: 'equals', value: 'asset', view_id: 1 },
|
|
||||||
{ field_key: 'root_type', index: 1, comparator: 'equals', value: 'liability', view_id: 2 },
|
|
||||||
{ field_key: 'root_type', index: 1, comparator: 'equals', value: 'equity', view_id: 3 },
|
|
||||||
{ field_key: 'root_type', index: 1, comparator: 'equals', value: 'income', view_id: 4 },
|
|
||||||
{ field_key: 'root_type', index: 1, comparator: 'equals', value: 'expense', view_id: 5 },
|
|
||||||
{ field_key: 'active', index: 1, comparator: 'is', value: 1, view_id: 15 },
|
|
||||||
|
|
||||||
// Items.
|
|
||||||
{ field_key: 'type', index: 1, comparator: 'equals', value: 'service', view_id: 6 },
|
|
||||||
{ field_key: 'type', index: 1, comparator: 'equals', value: 'inventory', view_id: 7 },
|
|
||||||
{ field_key: 'type', index: 1, comparator: 'equals', value: 'non-inventory', view_id: 8 },
|
|
||||||
|
|
||||||
// Expenses.
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'equals', value: 'draft', view_id: 12 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'equals', value: 'published', view_id: 13 },
|
|
||||||
|
|
||||||
// Manual Journals.
|
|
||||||
{ field_key: 'journal_type', index: 1, comparator: 'equals', value: 'Journal', view_id: 9 },
|
|
||||||
{ field_key: 'journal_type', index: 1, comparator: 'equals', value: 'CreditNote', view_id: 10 },
|
|
||||||
{ field_key: 'journal_type', index: 1, comparator: 'equals', value: 'Reconciliation', view_id: 11 },
|
|
||||||
|
|
||||||
// Sale invoice.
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'draft', view_id: 16 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'delivered', view_id: 17 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'unpaid', view_id: 18 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'overdue', view_id: 19 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'partially-paid', view_id: 20 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'paid', view_id: 21 },
|
|
||||||
|
|
||||||
// Bills
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'draft', view_id: 22 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'opened', view_id: 23 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'unpaid', view_id: 24 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'overdue', view_id: 25 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'partially-paid', view_id: 26 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'paid', view_id: 27 },
|
|
||||||
|
|
||||||
// Sale estimates
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'draft', view_id: 28 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'delivered', view_id: 29 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'approved', view_id: 30 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'rejected', view_id: 31 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'invoiced', view_id: 32 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'expired', view_id: 33 },
|
|
||||||
|
|
||||||
// Sale receipts.
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'draft', view_id: 34 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'closed', view_id: 35 },
|
|
||||||
|
|
||||||
// Customers
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'active', view_id: 36 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'inactive', view_id: 37 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'overdue', view_id: 38 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'unpaid', view_id: 39 },
|
|
||||||
|
|
||||||
// Vendors
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'active', view_id: 40 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'inactive', view_id: 41 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'overdue', view_id: 42 },
|
|
||||||
{ field_key: 'status', index: 1, comparator: 'is', value: 'unpaid', view_id: 43 },
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.down = (knex) => {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -19,6 +19,7 @@ export interface IDynamicListFilter {
|
|||||||
columnSortBy: ISortOrder;
|
columnSortBy: ISortOrder;
|
||||||
sortOrder: string;
|
sortOrder: string;
|
||||||
stringifiedFilterRoles: string;
|
stringifiedFilterRoles: string;
|
||||||
|
searchKeyword?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDynamicListService {
|
export interface IDynamicListService {
|
||||||
@@ -29,3 +30,9 @@ export interface IDynamicListService {
|
|||||||
): Promise<any>;
|
): Promise<any>;
|
||||||
handlerErrorsToResponse(error, req, res, next): void;
|
handlerErrorsToResponse(error, req, res, next): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search role.
|
||||||
|
export interface ISearchRole {
|
||||||
|
fieldKey: string;
|
||||||
|
comparator: string;
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ export interface ISaleInvoiceEditDTO extends ISaleInvoiceDTO {}
|
|||||||
export interface ISalesInvoicesFilter extends IDynamicListFilter {
|
export interface ISalesInvoicesFilter extends IDynamicListFilter {
|
||||||
page: number;
|
page: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
|
searchKeyword?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISalesInvoicesService {
|
export interface ISalesInvoicesService {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { IModel, IFilterRole } from 'interfaces';
|
|
||||||
import { FIELD_TYPE } from './constants';
|
|
||||||
|
|
||||||
export default class DynamicFilterAbstructor {
|
export default class DynamicFilterAbstructor {
|
||||||
/**
|
/**
|
||||||
@@ -25,6 +23,11 @@ export default class DynamicFilterAbstructor {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds join queries of fields.
|
||||||
|
* @param builder -
|
||||||
|
* @param {string[]} fieldsRelations -
|
||||||
|
*/
|
||||||
private buildFieldsJoinQueries = (builder, fieldsRelations: string[]) => {
|
private buildFieldsJoinQueries = (builder, fieldsRelations: string[]) => {
|
||||||
fieldsRelations.forEach((fieldRelation) => {
|
fieldsRelations.forEach((fieldRelation) => {
|
||||||
const relation = this.model.relationMappings[fieldRelation];
|
const relation = this.model.relationMappings[fieldRelation];
|
||||||
@@ -38,7 +41,10 @@ export default class DynamicFilterAbstructor {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getModel() {
|
/**
|
||||||
|
* Retrieve the dynamic filter mode.
|
||||||
|
*/
|
||||||
|
protected getModel() {
|
||||||
return this.model;
|
return this.model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
server/src/lib/DynamicFilter/DynamicFilterAdvancedFilter.ts
Normal file
27
server/src/lib/DynamicFilter/DynamicFilterAdvancedFilter.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { IFilterRole } from 'interfaces';
|
||||||
|
import DynamicFilterFilterRoles from './DynamicFilterFilterRoles';
|
||||||
|
|
||||||
|
export default class DynamicFilterAdvancedFilter extends DynamicFilterFilterRoles {
|
||||||
|
private filterRoles: IFilterRole[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
* @param {Array} filterRoles -
|
||||||
|
* @param {Array} resourceFields -
|
||||||
|
*/
|
||||||
|
constructor(filterRoles: IFilterRole[]) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.filterRoles = filterRoles;
|
||||||
|
this.setResponseMeta();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets response meta.
|
||||||
|
*/
|
||||||
|
private setResponseMeta() {
|
||||||
|
this.responseMeta = {
|
||||||
|
filterRoles: this.filterRoles,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,19 +5,10 @@ export default class FilterRoles extends DynamicFilterRoleAbstructor {
|
|||||||
private filterRoles: IFilterRole[];
|
private filterRoles: IFilterRole[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor method.
|
* On initialize filter roles.
|
||||||
* @param {Array} filterRoles -
|
|
||||||
* @param {Array} resourceFields -
|
|
||||||
*/
|
*/
|
||||||
constructor(filterRoles: IFilterRole[]) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.filterRoles = filterRoles;
|
|
||||||
|
|
||||||
this.setResponseMeta();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onInitialize() {
|
public onInitialize() {
|
||||||
|
super.onInitialize();
|
||||||
this.setFilterRolesRelations();
|
this.setFilterRolesRelations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,15 +41,6 @@ export default class FilterRoles extends DynamicFilterRoleAbstructor {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets response meta.
|
|
||||||
*/
|
|
||||||
private setResponseMeta() {
|
|
||||||
this.responseMeta = {
|
|
||||||
filterRoles: this.filterRoles,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets filter roles relations if field was relation type.
|
* Sets filter roles relations if field was relation type.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import * as R from 'ramda';
|
||||||
import { IFilterRole, IDynamicFilter, IModel } from 'interfaces';
|
import { IFilterRole, IDynamicFilter, IModel } from 'interfaces';
|
||||||
import { Lexer } from 'lib/LogicEvaluation/Lexer';
|
import { Lexer } from 'lib/LogicEvaluation/Lexer';
|
||||||
import Parser from 'lib/LogicEvaluation/Parser';
|
import Parser from 'lib/LogicEvaluation/Parser';
|
||||||
@@ -63,6 +64,18 @@ export default abstract class DynamicFilterAbstructor
|
|||||||
return queryParser.parse();
|
return queryParser.parse();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the logic expression to base expression.
|
||||||
|
* @param {string} logicExpression -
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
private parseLogicExpression(logicExpression: string): string {
|
||||||
|
return R.compose(
|
||||||
|
R.replace(/or|OR/g, '||'),
|
||||||
|
R.replace(/and|AND/g, '&&'),
|
||||||
|
)(logicExpression);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds filter query for query builder.
|
* Builds filter query for query builder.
|
||||||
* @param {String} tableName - Table name.
|
* @param {String} tableName - Table name.
|
||||||
@@ -74,8 +87,10 @@ export default abstract class DynamicFilterAbstructor
|
|||||||
roles: IFilterRole[],
|
roles: IFilterRole[],
|
||||||
logicExpression: string
|
logicExpression: string
|
||||||
) => {
|
) => {
|
||||||
|
const basicExpression = this.parseLogicExpression(logicExpression);
|
||||||
|
|
||||||
return (builder) => {
|
return (builder) => {
|
||||||
this.buildFilterRolesQuery(model, roles, logicExpression)(builder);
|
this.buildFilterRolesQuery(model, roles, basicExpression)(builder);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -347,11 +362,15 @@ export default abstract class DynamicFilterAbstructor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the model.
|
||||||
|
*/
|
||||||
getModel() {
|
getModel() {
|
||||||
return this.model;
|
return this.model;
|
||||||
}
|
}
|
||||||
|
|
||||||
onInitialize() {
|
/**
|
||||||
|
* On initialize the registered dynamic filter.
|
||||||
}
|
*/
|
||||||
|
onInitialize() {}
|
||||||
}
|
}
|
||||||
|
|||||||
48
server/src/lib/DynamicFilter/DynamicFilterSearch.ts
Normal file
48
server/src/lib/DynamicFilter/DynamicFilterSearch.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { IFilterRole } from 'interfaces';
|
||||||
|
import DynamicFilterFilterRoles from './DynamicFilterFilterRoles';
|
||||||
|
|
||||||
|
export default class DynamicFilterSearch extends DynamicFilterFilterRoles {
|
||||||
|
private searchKeyword: string;
|
||||||
|
private filterRoles: IFilterRole[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
* @param {string} searchKeyword - Search keyword.
|
||||||
|
*/
|
||||||
|
constructor(searchKeyword: string) {
|
||||||
|
super();
|
||||||
|
this.searchKeyword = searchKeyword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On initialize the dynamic filter.
|
||||||
|
*/
|
||||||
|
public onInitialize() {
|
||||||
|
super.onInitialize();
|
||||||
|
this.filterRoles = this.getModelSearchFilterRoles(this.searchKeyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the filter roles from model search roles.
|
||||||
|
* @param {string} searchKeyword
|
||||||
|
* @returns {IFilterRole[]}
|
||||||
|
*/
|
||||||
|
private getModelSearchFilterRoles(searchKeyword: string): IFilterRole[] {
|
||||||
|
const model = this.getModel();
|
||||||
|
|
||||||
|
return model.searchRoles.map((searchRole, index) => ({
|
||||||
|
...searchRole,
|
||||||
|
value: searchKeyword,
|
||||||
|
index: index + 1,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
setResponseMeta() {
|
||||||
|
this.responseMeta = {
|
||||||
|
searchKeyword: this.searchKeyword,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,10 +11,12 @@ import ModelSettings from './ModelSetting';
|
|||||||
import { ACCOUNT_TYPES } from 'data/AccountTypes';
|
import { ACCOUNT_TYPES } from 'data/AccountTypes';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Accounts/constants';
|
import { DEFAULT_VIEWS } from 'services/Accounts/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class Account extends mixin(TenantModel, [
|
export default class Account extends mixin(TenantModel, [
|
||||||
ModelSettings,
|
ModelSettings,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
@@ -257,7 +259,17 @@ export default class Account extends mixin(TenantModel, [
|
|||||||
/**
|
/**
|
||||||
* Retrieve the default custom views, roles and columns.
|
* Retrieve the default custom views, roles and columns.
|
||||||
*/
|
*/
|
||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search roles.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ condition: 'or', fieldKey: 'name', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'code', comparator: 'like' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import BillSettings from './Bill.Settings';
|
|||||||
import ModelSetting from './ModelSetting';
|
import ModelSetting from './ModelSetting';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Purchases/constants';
|
import { DEFAULT_VIEWS } from 'services/Purchases/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class Bill extends mixin(TenantModel, [
|
export default class Bill extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
@@ -315,4 +317,15 @@ export default class Bill extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'bill_number', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'reference_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import ModelSetting from './ModelSetting';
|
|||||||
import BillPaymentSettings from './BillPayment.Settings';
|
import BillPaymentSettings from './BillPayment.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Sales/PaymentReceives/constants';
|
import { DEFAULT_VIEWS } from 'services/Sales/PaymentReceives/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class BillPayment extends mixin(TenantModel, [
|
export default class BillPayment extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
@@ -90,4 +92,15 @@ export default class BillPayment extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'payment_number', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'reference_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,69 +1,67 @@
|
|||||||
export default {
|
export default {
|
||||||
fields: {
|
fields: {
|
||||||
|
first_name: {
|
||||||
|
name: 'First name',
|
||||||
|
column: 'first_name',
|
||||||
|
fieldType: 'text',
|
||||||
|
},
|
||||||
|
last_name: {
|
||||||
|
name: 'Last name',
|
||||||
|
column: 'last_name',
|
||||||
|
fieldType: 'text',
|
||||||
|
},
|
||||||
display_name: {
|
display_name: {
|
||||||
name: 'Display name',
|
name: 'Display name',
|
||||||
column: 'display_name',
|
column: 'display_name',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
email: {
|
email: {
|
||||||
name: 'Email',
|
name: 'Email',
|
||||||
column: 'email',
|
column: 'email',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
work_phone: {
|
work_phone: {
|
||||||
name: 'Work phone',
|
name: 'Work phone',
|
||||||
column: 'work_phone',
|
column: 'work_phone',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
personal_phone: {
|
personal_phone: {
|
||||||
name: 'Personal phone',
|
name: 'Personal phone',
|
||||||
column: 'personal_phone',
|
column: 'personal_phone',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
company_name: {
|
company_name: {
|
||||||
name: 'Company name',
|
name: 'Company name',
|
||||||
column: 'company_name',
|
column: 'company_name',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
website: {
|
website: {
|
||||||
name: 'Website',
|
name: 'Website',
|
||||||
column: 'website',
|
column: 'website',
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
created_at: {
|
created_at: {
|
||||||
name: 'Created at',
|
name: 'Created at',
|
||||||
column: 'created_at',
|
column: 'created_at',
|
||||||
fieldType: 'date',
|
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
balance: {
|
balance: {
|
||||||
name: 'Balance',
|
name: 'Balance',
|
||||||
column: 'balance',
|
column: 'balance',
|
||||||
fieldType: 'number',
|
fieldType: 'number',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
opening_balance: {
|
opening_balance: {
|
||||||
name: 'Opening balance',
|
name: 'Opening balance',
|
||||||
column: 'opening_balance',
|
column: 'opening_balance',
|
||||||
fieldType: 'number',
|
fieldType: 'number',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
opening_balance_at: {
|
opening_balance_at: {
|
||||||
name: 'Opening balance at',
|
name: 'Opening balance at',
|
||||||
column: 'opening_balance_at',
|
column: 'opening_balance_at',
|
||||||
filterable: false,
|
filterable: false,
|
||||||
fieldType: 'date',
|
fieldType: 'date',
|
||||||
columnable: true,
|
|
||||||
},
|
},
|
||||||
currency_code: {
|
currency_code: {
|
||||||
column: 'currency_code',
|
column: 'currency_code',
|
||||||
columnable: true,
|
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
@@ -74,7 +72,6 @@ export default {
|
|||||||
{ key: 'overdue', label: 'Overdue' },
|
{ key: 'overdue', label: 'Overdue' },
|
||||||
{ key: 'unpaid', label: 'Unpaid' },
|
{ key: 'unpaid', label: 'Unpaid' },
|
||||||
],
|
],
|
||||||
columnable: true,
|
|
||||||
filterCustomQuery: statusFieldFilterQuery,
|
filterCustomQuery: statusFieldFilterQuery,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import ModelSetting from './ModelSetting';
|
|||||||
import CustomerSettings from './Customer.Settings';
|
import CustomerSettings from './Customer.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Contacts/Customers/constants';
|
import { DEFAULT_VIEWS } from 'services/Contacts/Customers/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
class CustomerQueryBuilder extends PaginationQueryBuilder {
|
class CustomerQueryBuilder extends PaginationQueryBuilder {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
@@ -21,6 +22,7 @@ class CustomerQueryBuilder extends PaginationQueryBuilder {
|
|||||||
export default class Customer extends mixin(TenantModel, [
|
export default class Customer extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Query builder.
|
* Query builder.
|
||||||
@@ -149,4 +151,20 @@ export default class Customer extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'display_name', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'first_name', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'last_name', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'company_name', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'email', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'work_phone', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'personal_phone', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'website', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import ModelSetting from './ModelSetting';
|
|||||||
import ExpenseSettings from './Expense.Settings';
|
import ExpenseSettings from './Expense.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Expenses/constants';
|
import { DEFAULT_VIEWS } from 'services/Expenses/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class Expense extends mixin(TenantModel, [
|
export default class Expense extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
@@ -160,4 +162,14 @@ export default class Expense extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'reference_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import ItemSettings from './Item.Settings';
|
|||||||
import ModelSetting from './ModelSetting';
|
import ModelSetting from './ModelSetting';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Items/constants';
|
import { DEFAULT_VIEWS } from 'services/Items/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class Item extends mixin(TenantModel, [
|
export default class Item extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
@@ -128,4 +130,14 @@ export default class Item extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search roles.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'name', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'code', comparator: 'like' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import ModelSetting from './ModelSetting';
|
|||||||
import ManualJournalSettings from './ManualJournal.Settings';
|
import ManualJournalSettings from './ManualJournal.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/ManualJournals/constants';
|
import { DEFAULT_VIEWS } from 'services/ManualJournals/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
export default class ManualJournal extends mixin(TenantModel, [
|
export default class ManualJournal extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
@@ -115,4 +117,15 @@ export default class ManualJournal extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'journal_number', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'reference', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
server/src/models/ModelSearchable.ts
Normal file
18
server/src/models/ModelSearchable.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { IModelMeta, ISearchRole } from 'interfaces';
|
||||||
|
|
||||||
|
export default (Model) =>
|
||||||
|
class ModelSearchable extends Model {
|
||||||
|
/**
|
||||||
|
* Searchable model.
|
||||||
|
*/
|
||||||
|
static get searchable(): IModelMeta {
|
||||||
|
throw true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search roles.
|
||||||
|
*/
|
||||||
|
static get searchRoles(): ISearchRole[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -4,10 +4,12 @@ import ModelSetting from './ModelSetting';
|
|||||||
import PaymentReceiveSettings from './PaymentReceive.Settings';
|
import PaymentReceiveSettings from './PaymentReceive.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Sales/PaymentReceives/constants';
|
import { DEFAULT_VIEWS } from 'services/Sales/PaymentReceives/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class PaymentReceive extends mixin(TenantModel, [
|
export default class PaymentReceive extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
@@ -94,4 +96,15 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'payment_receive_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'reference_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import SaleEstimateSettings from './SaleEstimate.Settings';
|
|||||||
import ModelSetting from './ModelSetting';
|
import ModelSetting from './ModelSetting';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Sales/Estimates/constants';
|
import { DEFAULT_VIEWS } from 'services/Sales/Estimates/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class SaleEstimate extends mixin(TenantModel, [
|
export default class SaleEstimate extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
@@ -210,4 +212,15 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search roles.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'estimate_number', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'reference_no', comparator: 'contains' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import ModelSetting from './ModelSetting';
|
|||||||
import SaleInvoiceMeta from './SaleInvoice.Settings';
|
import SaleInvoiceMeta from './SaleInvoice.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Sales/constants';
|
import { DEFAULT_VIEWS } from 'services/Sales/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class SaleInvoice extends mixin(TenantModel, [
|
export default class SaleInvoice extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
@@ -371,4 +373,22 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model searchable.
|
||||||
|
*/
|
||||||
|
static get searchable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'invoice_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'reference_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,12 @@ import ModelSetting from './ModelSetting';
|
|||||||
import SaleReceiptSettings from './SaleReceipt.Settings';
|
import SaleReceiptSettings from './SaleReceipt.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Sales/Receipts/constants';
|
import { DEFAULT_VIEWS } from 'services/Sales/Receipts/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class SaleReceipt extends mixin(TenantModel, [
|
export default class SaleReceipt extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable,
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
@@ -159,4 +161,15 @@ export default class SaleReceipt extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'receipt_number', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'reference_no', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'amount', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,16 @@ export default {
|
|||||||
sortField: 'created_at',
|
sortField: 'created_at',
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
|
first_name: {
|
||||||
|
name: 'First name',
|
||||||
|
column: 'first_name',
|
||||||
|
fieldType: 'text',
|
||||||
|
},
|
||||||
|
last_name: {
|
||||||
|
name: 'Last name',
|
||||||
|
column: 'last_name',
|
||||||
|
fieldType: 'text',
|
||||||
|
},
|
||||||
'display_name': {
|
'display_name': {
|
||||||
name: 'Display name',
|
name: 'Display name',
|
||||||
column: 'display_name',
|
column: 'display_name',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import ModelSetting from './ModelSetting';
|
|||||||
import VendorSettings from './Vendor.Settings';
|
import VendorSettings from './Vendor.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from 'services/Contacts/Vendors/constants';
|
import { DEFAULT_VIEWS } from 'services/Contacts/Vendors/constants';
|
||||||
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
class VendorQueryBuilder extends PaginationQueryBuilder {
|
class VendorQueryBuilder extends PaginationQueryBuilder {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
@@ -21,6 +22,7 @@ class VendorQueryBuilder extends PaginationQueryBuilder {
|
|||||||
export default class Vendor extends mixin(TenantModel, [
|
export default class Vendor extends mixin(TenantModel, [
|
||||||
ModelSetting,
|
ModelSetting,
|
||||||
CustomViewBaseModel,
|
CustomViewBaseModel,
|
||||||
|
ModelSearchable
|
||||||
]) {
|
]) {
|
||||||
/**
|
/**
|
||||||
* Query builder.
|
* Query builder.
|
||||||
@@ -148,4 +150,20 @@ export default class Vendor extends mixin(TenantModel, [
|
|||||||
static get defaultViews() {
|
static get defaultViews() {
|
||||||
return DEFAULT_VIEWS;
|
return DEFAULT_VIEWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model search attributes.
|
||||||
|
*/
|
||||||
|
static get searchRoles() {
|
||||||
|
return [
|
||||||
|
{ fieldKey: 'display_name', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'first_name', comparator: 'contains' },
|
||||||
|
{ condition: 'or', fieldKey: 'last_name', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'company_name', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'email', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'work_phone', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'personal_phone', comparator: 'equals' },
|
||||||
|
{ condition: 'or', fieldKey: 'website', comparator: 'equals' },
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as R from 'ramda';
|
|||||||
import validator from 'is-my-json-valid';
|
import validator from 'is-my-json-valid';
|
||||||
import { IFilterRole, IModel } from 'interfaces';
|
import { IFilterRole, IModel } from 'interfaces';
|
||||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
import DynamicListAbstruct from './DynamicListAbstruct';
|
||||||
import DynamicFilterFilterRoles from 'lib/DynamicFilter/DynamicFilterFilterRoles';
|
import DynamicFilterAdvancedFilter from 'lib/DynamicFilter/DynamicFilterAdvancedFilter';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import { ServiceError } from 'exceptions';
|
import { ServiceError } from 'exceptions';
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ export default class DynamicListFilterRoles extends DynamicListAbstruct {
|
|||||||
public dynamicList = (
|
public dynamicList = (
|
||||||
model: IModel,
|
model: IModel,
|
||||||
filterRoles: IFilterRole[]
|
filterRoles: IFilterRole[]
|
||||||
): DynamicFilterFilterRoles => {
|
): DynamicFilterAdvancedFilter => {
|
||||||
const filterRolesParsed = R.compose(this.incrementFilterRolesIndex)(
|
const filterRolesParsed = R.compose(this.incrementFilterRolesIndex)(
|
||||||
filterRoles
|
filterRoles
|
||||||
);
|
);
|
||||||
@@ -98,6 +98,6 @@ export default class DynamicListFilterRoles extends DynamicListAbstruct {
|
|||||||
// Validate the model resource fields.
|
// Validate the model resource fields.
|
||||||
this.validateFilterRolesFieldsExistance(model, filterRoles);
|
this.validateFilterRolesFieldsExistance(model, filterRoles);
|
||||||
|
|
||||||
return new DynamicFilterFilterRoles(filterRolesParsed);
|
return new DynamicFilterAdvancedFilter(filterRolesParsed);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
18
server/src/services/DynamicListing/DynamicListSearch.ts
Normal file
18
server/src/services/DynamicListing/DynamicListSearch.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Service } from 'typedi';
|
||||||
|
import { IFilterRole, IModel } from 'interfaces';
|
||||||
|
import DynamicListAbstruct from './DynamicListAbstruct';
|
||||||
|
import DynamicFilterFilterRoles from 'lib/DynamicFilter/DynamicFilterFilterRoles';
|
||||||
|
import DynamicFilterSearch from 'lib/DynamicFilter/DynamicFilterSearch';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export default class DynamicListSearch extends DynamicListAbstruct {
|
||||||
|
/**
|
||||||
|
* Dynamic list filter roles.
|
||||||
|
* @param {IModel} model
|
||||||
|
* @param {IFilterRole[]} filterRoles
|
||||||
|
* @returns {DynamicFilterFilterRoles}
|
||||||
|
*/
|
||||||
|
public dynamicSearch = (model: IModel, searchKeyword: string) => {
|
||||||
|
return new DynamicFilterSearch(searchKeyword);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import TenancyService from 'services/Tenancy/TenancyService';
|
|||||||
import DynamicListFilterRoles from './DynamicListFilterRoles';
|
import DynamicListFilterRoles from './DynamicListFilterRoles';
|
||||||
import DynamicListSortBy from './DynamicListSortBy';
|
import DynamicListSortBy from './DynamicListSortBy';
|
||||||
import DynamicListCustomView from './DynamicListCustomView';
|
import DynamicListCustomView from './DynamicListCustomView';
|
||||||
|
import DynamicListSearch from './DynamicListSearch';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DynamicListService implements IDynamicListService {
|
export default class DynamicListService implements IDynamicListService {
|
||||||
@@ -28,6 +29,9 @@ export default class DynamicListService implements IDynamicListService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
dynamicListView: DynamicListCustomView;
|
dynamicListView: DynamicListCustomView;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
dynamicListSearch: DynamicListSearch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses filter DTO.
|
* Parses filter DTO.
|
||||||
* @param {IMode} model -
|
* @param {IMode} model -
|
||||||
@@ -62,6 +66,14 @@ export default class DynamicListService implements IDynamicListService {
|
|||||||
// Parses the filter object.
|
// Parses the filter object.
|
||||||
const parsedFilter = this.parseFilterObject(model, filter);
|
const parsedFilter = this.parseFilterObject(model, filter);
|
||||||
|
|
||||||
|
// Search by keyword.
|
||||||
|
if (filter.searchKeyword) {
|
||||||
|
const dynamicListSearch = this.dynamicListSearch.dynamicSearch(
|
||||||
|
model,
|
||||||
|
filter.searchKeyword
|
||||||
|
);
|
||||||
|
dynamicFilter.setFilter(dynamicListSearch);
|
||||||
|
}
|
||||||
// Custom view filter roles.
|
// Custom view filter roles.
|
||||||
if (filter.viewSlug) {
|
if (filter.viewSlug) {
|
||||||
const dynamicListCustomView =
|
const dynamicListCustomView =
|
||||||
|
|||||||
Reference in New Issue
Block a user