mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 22:30:31 +00:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74b6e41cd4 | ||
|
|
d239003047 | ||
|
|
9f21f649f0 | ||
|
|
d3d2112b8a | ||
|
|
3795322a65 | ||
|
|
fe5cd5a8ea | ||
|
|
c032a5db16 | ||
|
|
3fcb6fefde | ||
|
|
16f5cb713d | ||
|
|
f7a7925028 | ||
|
|
66fb0c9fa3 | ||
|
|
85acc85f17 | ||
|
|
c76ce09191 | ||
|
|
e3532098b2 | ||
|
|
b6783eb22e | ||
|
|
4ef00ab122 | ||
|
|
3dd827417a | ||
|
|
cbacd02aa2 | ||
|
|
3b7e0fb78a | ||
|
|
9add716395 | ||
|
|
083ea28a1f | ||
|
|
1b51742c36 | ||
|
|
0c6f23e770 | ||
|
|
37a8ca4e97 | ||
|
|
795303c3a8 | ||
|
|
63ba3f0898 | ||
|
|
62594efa00 | ||
|
|
9ac0dcbdc3 | ||
|
|
df588dc4ce | ||
|
|
d54f14a87a | ||
|
|
a4d4be54c1 | ||
|
|
ddd17e74b5 | ||
|
|
81c0761fbe | ||
|
|
0812e3087e | ||
|
|
0dd05493b2 | ||
|
|
bfb3909d26 | ||
|
|
266902026e | ||
|
|
791c4a4e9e |
@@ -109,6 +109,7 @@
|
|||||||
"rtl-detect": "^1.0.4",
|
"rtl-detect": "^1.0.4",
|
||||||
"socket.io": "^4.7.4",
|
"socket.io": "^4.7.4",
|
||||||
"source-map-loader": "^4.0.1",
|
"source-map-loader": "^4.0.1",
|
||||||
|
"swagger-ui-express": "^5.0.1",
|
||||||
"tmp-promise": "^3.0.3",
|
"tmp-promise": "^3.0.3",
|
||||||
"ts-transformer-keys": "^0.4.2",
|
"ts-transformer-keys": "^0.4.2",
|
||||||
"tsyringe": "^4.3.0",
|
"tsyringe": "^4.3.0",
|
||||||
|
|||||||
@@ -5,7 +5,14 @@ import { body, param } from 'express-validator';
|
|||||||
import BaseController from '@/api/controllers/BaseController';
|
import BaseController from '@/api/controllers/BaseController';
|
||||||
import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication';
|
import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication';
|
||||||
import { AttachmentUploadPipeline } from '@/services/Attachments/S3UploadPipeline';
|
import { AttachmentUploadPipeline } from '@/services/Attachments/S3UploadPipeline';
|
||||||
|
import {
|
||||||
|
ApiOperation,
|
||||||
|
ApiResponse,
|
||||||
|
ApiTags,
|
||||||
|
Route,
|
||||||
|
} from '@/decorators/swagger-decorators';
|
||||||
|
|
||||||
|
@ApiTags('Attachments')
|
||||||
@Service()
|
@Service()
|
||||||
export class AttachmentsController extends BaseController {
|
export class AttachmentsController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
@@ -121,6 +128,26 @@ export class AttachmentsController extends BaseController {
|
|||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
* @returns {Promise<Response|void>}
|
* @returns {Promise<Response|void>}
|
||||||
*/
|
*/
|
||||||
|
@ApiResponse({
|
||||||
|
status: 200,
|
||||||
|
description: 'Details of the given attachement',
|
||||||
|
schema: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string' },
|
||||||
|
name: { type: 'string' },
|
||||||
|
email: { type: 'string' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
@ApiOperation({
|
||||||
|
summary: 'Retrieve a specific details of attachment',
|
||||||
|
description: 'Get all registered users',
|
||||||
|
})
|
||||||
|
@Route('/attachments/:id')
|
||||||
private async getAttachment(
|
private async getAttachment(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ import { IItemDTO, ItemAction, AbilitySubject } from '@/interfaces';
|
|||||||
import { DATATYPES_LENGTH } from '@/data/DataTypes';
|
import { DATATYPES_LENGTH } from '@/data/DataTypes';
|
||||||
import CheckAbilities from '@/api/middleware/CheckPolicies';
|
import CheckAbilities from '@/api/middleware/CheckPolicies';
|
||||||
import { ItemsApplication } from '@/services/Items/ItemsApplication';
|
import { ItemsApplication } from '@/services/Items/ItemsApplication';
|
||||||
|
import {
|
||||||
|
ApiOperation,
|
||||||
|
ApiResponse,
|
||||||
|
Route,
|
||||||
|
} from '@/decorators/swagger-decorators';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class ItemsController extends BaseController {
|
export default class ItemsController extends BaseController {
|
||||||
@@ -198,6 +203,22 @@ export default class ItemsController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
|
@ApiResponse({
|
||||||
|
status: 200,
|
||||||
|
description: 'Details of the given attachement',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string' },
|
||||||
|
name: { type: 'string' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
@ApiOperation({
|
||||||
|
summary: 'Creates a new item (inventory or service)',
|
||||||
|
description: 'Get all registered users',
|
||||||
|
})
|
||||||
|
@Route('/items')
|
||||||
private async newItem(req: Request, res: Response, next: NextFunction) {
|
private async newItem(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const itemDTO: IItemDTO = this.matchedBodyData(req);
|
const itemDTO: IItemDTO = this.matchedBodyData(req);
|
||||||
|
|||||||
@@ -34,6 +34,42 @@ export const ITEM_EVENT_DELETED = 'Item deleted';
|
|||||||
export const AUTH_SIGNED_UP = 'Auth Signed-up';
|
export const AUTH_SIGNED_UP = 'Auth Signed-up';
|
||||||
export const AUTH_RESET_PASSWORD = 'Auth reset password';
|
export const AUTH_RESET_PASSWORD = 'Auth reset password';
|
||||||
|
|
||||||
|
export const SUBSCRIPTION_CANCELLED = 'Subscription cancelled';
|
||||||
|
export const SUBSCRIPTION_RESUMED = 'Subscription resumed';
|
||||||
|
export const SUBSCRIPTION_PLAN_CHANGED = 'Subscription plan changed';
|
||||||
|
|
||||||
|
export const CUSTOMER_CREATED = 'Customer created';
|
||||||
|
export const CUSTOMER_EDITED = 'Customer edited';
|
||||||
|
export const CUSTOMER_DELETED = 'Customer deleted';
|
||||||
|
|
||||||
|
export const VENDOR_CREATED = 'Vendor created';
|
||||||
|
export const VENDOR_EDITED = 'Vendor edited';
|
||||||
|
export const VENDOR_DELETED = 'Vendor deleted';
|
||||||
|
|
||||||
|
export const TRANSACTIONS_LOCKING_LOCKED = 'Transactions locking locked';
|
||||||
|
export const TRANSACTIONS_LOCKING_LOCKING_CANCELLED =
|
||||||
|
'Transactions locking cancelled';
|
||||||
|
export const TRANSACTIONS_LOCKING_PARTIALLY_UNLOCKED =
|
||||||
|
'Transactions locking partially unlocked';
|
||||||
|
export const TRANSACTIONS_LOCKING_PARTIALLY_UNLOCK_CANCELLED =
|
||||||
|
'Transactions locking partially unlock cancelled';
|
||||||
|
|
||||||
|
export const BANK_TRANSACTION_MATCHED = 'Bank transaction matching deleted';
|
||||||
|
export const BANK_TRANSACTION_EXCLUDED = 'Bank transaction excluded';
|
||||||
|
export const BANK_TRANSACTION_CATEGORIZED = 'Bank transaction categorized';
|
||||||
|
export const BANK_TRANSACTION_UNCATEGORIZED = 'Bank transaction uncategorized';
|
||||||
|
export const BANK_ACCOUNT_DISCONNECTED = 'Bank account disconnected';
|
||||||
|
|
||||||
|
export const MANUAL_JOURNAL_CREATED = 'Manual journal created';
|
||||||
|
export const MANUAL_JOURNAL_EDITED = 'Manual journal edited';
|
||||||
|
export const MANUAL_JOURNAL_DELETED = 'Manual journal deleted';
|
||||||
|
export const MANUAL_JOURNAL_PUBLISHED = 'Manual journal published';
|
||||||
|
|
||||||
|
export const BANK_RULE_CREATED = 'Bank rule created';
|
||||||
|
export const BANK_RULE_EDITED = 'Bank rule edited';
|
||||||
|
export const BANK_RULE_DELETED = 'Bank rule deleted';
|
||||||
|
|
||||||
|
// # Event Groups
|
||||||
export const ACCOUNT_GROUP = 'Account';
|
export const ACCOUNT_GROUP = 'Account';
|
||||||
export const ITEM_GROUP = 'Item';
|
export const ITEM_GROUP = 'Item';
|
||||||
export const AUTH_GROUP = 'Auth';
|
export const AUTH_GROUP = 'Auth';
|
||||||
|
|||||||
63
packages/server/src/decorators/swagger-decorators.ts
Normal file
63
packages/server/src/decorators/swagger-decorators.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
export const swaggerDocs = {
|
||||||
|
tags: {},
|
||||||
|
paths: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Decorator to set a tag for a route
|
||||||
|
export function ApiTags(tag) {
|
||||||
|
return function (target) {
|
||||||
|
if (!swaggerDocs.tags[tag]) {
|
||||||
|
swaggerDocs.tags[tag] = { name: tag };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decorator to add an operation for a specific route
|
||||||
|
export function ApiOperation(options) {
|
||||||
|
return function (target, propertyKey, descriptor) {
|
||||||
|
const routePath = Reflect.getMetadata('path', target, propertyKey);
|
||||||
|
|
||||||
|
swaggerDocs.paths[routePath] = swaggerDocs.paths[routePath] || {};
|
||||||
|
swaggerDocs.paths[routePath].get = {
|
||||||
|
summary: options.summary,
|
||||||
|
description: options.description || '',
|
||||||
|
responses: options.responses || {
|
||||||
|
200: {
|
||||||
|
description: 'Successful Response',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decorator to define the route path
|
||||||
|
export function Route(path) {
|
||||||
|
return function (target, propertyKey, descriptor) {
|
||||||
|
Reflect.defineMetadata('path', path, target, propertyKey);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decorator to add a response schema for a specific route
|
||||||
|
export function ApiResponse(options) {
|
||||||
|
return function (target, propertyKey, descriptor) {
|
||||||
|
const routePath = Reflect.getMetadata('path', target, propertyKey);
|
||||||
|
|
||||||
|
if (!swaggerDocs.paths[routePath]) {
|
||||||
|
swaggerDocs.paths[routePath] = { get: {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
swaggerDocs.paths[routePath].get.responses =
|
||||||
|
swaggerDocs.paths[routePath].get.responses || {};
|
||||||
|
|
||||||
|
swaggerDocs.paths[routePath].get.responses[options.status] = {
|
||||||
|
description: options.description || 'No description provided',
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: options.schema || {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -99,6 +99,7 @@ export interface IBillsFilter extends IDynamicListFilterDTO {
|
|||||||
stringifiedFilterRoles?: string;
|
stringifiedFilterRoles?: string;
|
||||||
page: number;
|
page: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
|
filterQuery?: (q: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBillsService {
|
export interface IBillsService {
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ export interface ICustomerEventCreatingPayload {
|
|||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface ICustomerEventEditedPayload {
|
export interface ICustomerEventEditedPayload {
|
||||||
|
tenantId: number
|
||||||
customerId: number;
|
customerId: number;
|
||||||
customer: ICustomer;
|
customer: ICustomer;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
|
|||||||
@@ -130,7 +130,9 @@ export interface ICreditNoteOpenedPayload {
|
|||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICreditNotesQueryDTO {}
|
export interface ICreditNotesQueryDTO {
|
||||||
|
filterQuery?: (query: any) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ICreditNotesQueryDTO extends IDynamicListFilter {
|
export interface ICreditNotesQueryDTO extends IDynamicListFilter {
|
||||||
page: number;
|
page: number;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export interface IExpensesFilter {
|
|||||||
columnSortBy: string;
|
columnSortBy: string;
|
||||||
sortOrder: string;
|
sortOrder: string;
|
||||||
viewSlug?: string;
|
viewSlug?: string;
|
||||||
|
filterQuery?: (query: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpense {
|
export interface IExpense {
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ export interface IModelMetaFieldCommon2 {
|
|||||||
importHint?: string;
|
importHint?: string;
|
||||||
order?: number;
|
order?: number;
|
||||||
unique?: number;
|
unique?: number;
|
||||||
|
features?: Array<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IModelMetaRelationField2 {
|
export interface IModelMetaRelationField2 {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export interface ISaleEstimateDTO {
|
|||||||
|
|
||||||
export interface ISalesEstimatesFilter extends IDynamicListFilterDTO {
|
export interface ISalesEstimatesFilter extends IDynamicListFilterDTO {
|
||||||
stringifiedFilterRoles?: string;
|
stringifiedFilterRoles?: string;
|
||||||
|
filterQuery?: (q: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISalesEstimatesService {
|
export interface ISalesEstimatesService {
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export interface ISalesInvoicesFilter extends IDynamicListFilter {
|
|||||||
page: number;
|
page: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
searchKeyword?: string;
|
searchKeyword?: string;
|
||||||
|
filterQuery?: (q: Knex.QueryBuilder) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISalesInvoicesService {
|
export interface ISalesInvoicesService {
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ export interface ISaleReceipt {
|
|||||||
entries?: IItemEntry[];
|
entries?: IItemEntry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISalesReceiptsFilter {}
|
export interface ISalesReceiptsFilter {
|
||||||
|
filterQuery?: (query: any) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ISaleReceiptDTO {
|
export interface ISaleReceiptDTO {
|
||||||
customerId: number;
|
customerId: number;
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ export interface IVendorCreditsQueryDTO extends IDynamicListFilter {
|
|||||||
page: number;
|
page: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
searchKeyword?: string;
|
searchKeyword?: string;
|
||||||
|
filterQuery?: (q: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorCreditEditingPayload {
|
export interface IVendorCreditEditingPayload {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'vendor',
|
defaultFilterField: 'vendor',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -167,6 +169,18 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
|
warehouse: {
|
||||||
|
name: 'Warehouse',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'warehouse.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
billNumber: {
|
billNumber: {
|
||||||
@@ -238,6 +252,22 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -402,6 +402,7 @@ export default class Bill extends mixin(TenantModel, [
|
|||||||
const ItemEntry = require('models/ItemEntry');
|
const ItemEntry = require('models/ItemEntry');
|
||||||
const BillLandedCost = require('models/BillLandedCost');
|
const BillLandedCost = require('models/BillLandedCost');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
|
const Warehouse = require('models/Warehouse');
|
||||||
const TaxRateTransaction = require('models/TaxRateTransaction');
|
const TaxRateTransaction = require('models/TaxRateTransaction');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
const { MatchedBankTransaction } = require('models/MatchedBankTransaction');
|
const { MatchedBankTransaction } = require('models/MatchedBankTransaction');
|
||||||
@@ -453,6 +454,18 @@ export default class Bill extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill may has associated warehouse.
|
||||||
|
*/
|
||||||
|
warehouse: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: Warehouse.default,
|
||||||
|
join: {
|
||||||
|
from: 'bills.warehouseId',
|
||||||
|
to: 'warehouses.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bill may has associated tax rate transactions.
|
* Bill may has associated tax rate transactions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'vendor',
|
defaultFilterField: 'vendor',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -141,6 +143,12 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
vendorId: {
|
vendorId: {
|
||||||
@@ -204,5 +212,13 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branchId: {
|
||||||
|
name: 'Branch',
|
||||||
|
fieldType: 'relation',
|
||||||
|
relationModel: 'Branch',
|
||||||
|
relationImportMatch: ['name', 'code'],
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
11
packages/server/src/models/Branch.settings.ts
Normal file
11
packages/server/src/models/Branch.settings.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
fields2: {
|
||||||
|
name: {
|
||||||
|
name: 'Name',
|
||||||
|
fieldType: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: {},
|
||||||
|
fields: {}
|
||||||
|
};
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { Model } from 'objection';
|
import { Model, mixin } from 'objection';
|
||||||
import TenantModel from 'models/TenantModel';
|
import TenantModel from 'models/TenantModel';
|
||||||
|
import BranchMetadata from './Branch.settings';
|
||||||
|
import ModelSetting from './ModelSetting';
|
||||||
|
|
||||||
export default class Branch extends TenantModel {
|
export default class Branch extends mixin(TenantModel, [ModelSetting]) {
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
*/
|
*/
|
||||||
@@ -169,4 +171,11 @@ export default class Branch extends TenantModel {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model settings.
|
||||||
|
*/
|
||||||
|
static get meta() {
|
||||||
|
return BranchMetadata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
function StatusFieldFilterQuery(query, role) {
|
function StatusFieldFilterQuery(query, role) {
|
||||||
query.modify('filterByStatus', role.value);
|
query.modify('filterByStatus', role.value);
|
||||||
}
|
}
|
||||||
@@ -100,7 +102,7 @@ export default {
|
|||||||
},
|
},
|
||||||
creditNoteDate: {
|
creditNoteDate: {
|
||||||
name: 'Credit Note Date',
|
name: 'Credit Note Date',
|
||||||
accessor: 'formattedCreditNoteDate'
|
accessor: 'formattedCreditNoteDate',
|
||||||
},
|
},
|
||||||
referenceNo: {
|
referenceNo: {
|
||||||
name: 'Reference No.',
|
name: 'Reference No.',
|
||||||
@@ -147,6 +149,18 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
|
warehouse: {
|
||||||
|
name: 'Warehouse',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'warehouse.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
customerId: {
|
customerId: {
|
||||||
@@ -215,5 +229,21 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ export default class CreditNote extends mixin(TenantModel, [
|
|||||||
const Customer = require('models/Customer');
|
const Customer = require('models/Customer');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
|
const Warehouse = require('models/Warehouse');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@@ -235,6 +236,18 @@ export default class CreditNote extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credit note may has associated warehouse.
|
||||||
|
*/
|
||||||
|
warehouse: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: Warehouse.default,
|
||||||
|
join: {
|
||||||
|
from: 'credit_notes.warehouseId',
|
||||||
|
to: 'warehouses.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Credit note may has many attached attachments.
|
* Credit note may has many attached attachments.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expense - Settings.
|
* Expense - Settings.
|
||||||
*/
|
*/
|
||||||
@@ -119,6 +121,12 @@ export default {
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
paymentAccountId: {
|
paymentAccountId: {
|
||||||
@@ -178,6 +186,14 @@ export default {
|
|||||||
name: 'expense.field.publish',
|
name: 'expense.field.publish',
|
||||||
fieldType: 'boolean',
|
fieldType: 'boolean',
|
||||||
},
|
},
|
||||||
|
branchId: {
|
||||||
|
name: 'Branch',
|
||||||
|
fieldType: 'relation',
|
||||||
|
relationModel: 'Branch',
|
||||||
|
relationImportMatch: ['name', 'code'],
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
importable: true,
|
importable: true,
|
||||||
|
|
||||||
@@ -128,6 +130,12 @@ export default {
|
|||||||
type: 'date',
|
type: 'date',
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
customerId: {
|
customerId: {
|
||||||
@@ -189,5 +197,13 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branchId: {
|
||||||
|
name: 'Branch',
|
||||||
|
fieldType: 'relation',
|
||||||
|
relationModel: 'Branch',
|
||||||
|
relationImportMatch: ['name', 'code'],
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'estimate_date',
|
defaultFilterField: 'estimate_date',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -174,6 +176,18 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
|
warehouse: {
|
||||||
|
name: 'Warehouse',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'warehouse.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
customerId: {
|
customerId: {
|
||||||
@@ -252,6 +266,22 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
|||||||
const ItemEntry = require('models/ItemEntry');
|
const ItemEntry = require('models/ItemEntry');
|
||||||
const Customer = require('models/Customer');
|
const Customer = require('models/Customer');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
|
const Warehouse = require('models/Warehouse');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -221,6 +222,18 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sale estimate may has associated warehouse.
|
||||||
|
*/
|
||||||
|
warehouse: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: Warehouse.default,
|
||||||
|
join: {
|
||||||
|
from: 'sales_estimates.warehouseId',
|
||||||
|
to: 'warehouses.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sale estimate transaction may has many attached attachments.
|
* Sale estimate transaction may has many attached attachments.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'customer',
|
defaultFilterField: 'customer',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -185,6 +187,18 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
|
warehouse: {
|
||||||
|
name: 'Warehouse',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'warehouse.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
invoiceDate: {
|
invoiceDate: {
|
||||||
@@ -268,6 +282,22 @@ export default {
|
|||||||
fieldType: 'boolean',
|
fieldType: 'boolean',
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -408,6 +408,7 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
const InventoryCostLotTracker = require('models/InventoryCostLotTracker');
|
const InventoryCostLotTracker = require('models/InventoryCostLotTracker');
|
||||||
const PaymentReceiveEntry = require('models/PaymentReceiveEntry');
|
const PaymentReceiveEntry = require('models/PaymentReceiveEntry');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
|
const Warehouse = require('models/Warehouse');
|
||||||
const Account = require('models/Account');
|
const Account = require('models/Account');
|
||||||
const TaxRateTransaction = require('models/TaxRateTransaction');
|
const TaxRateTransaction = require('models/TaxRateTransaction');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
@@ -499,6 +500,18 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice may has associated warehouse.
|
||||||
|
*/
|
||||||
|
warehouse: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: Warehouse.default,
|
||||||
|
join: {
|
||||||
|
from: 'sales_invoices.warehouseId',
|
||||||
|
to: 'warehouses.id',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice may has associated written-off expense account.
|
* Invoice may has associated written-off expense account.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'receipt_date',
|
defaultFilterField: 'receipt_date',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -169,6 +171,18 @@ export default {
|
|||||||
type: 'date',
|
type: 'date',
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
|
warehouse: {
|
||||||
|
name: 'Warehouse',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'warehouse.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
receiptDate: {
|
receiptDate: {
|
||||||
@@ -245,6 +259,22 @@ export default {
|
|||||||
name: 'Receipt Message',
|
name: 'Receipt Message',
|
||||||
fieldType: 'text',
|
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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ export default class SaleReceipt extends mixin(TenantModel, [
|
|||||||
const ItemEntry = require('models/ItemEntry');
|
const ItemEntry = require('models/ItemEntry');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
|
const Warehouse = require('models/Warehouse');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
customer: {
|
customer: {
|
||||||
@@ -169,6 +170,18 @@ export default class SaleReceipt extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sale receipt may has associated warehouse.
|
||||||
|
*/
|
||||||
|
warehouse: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: Warehouse.default,
|
||||||
|
join: {
|
||||||
|
from: 'sales_receipts.warehouseId',
|
||||||
|
to: 'warehouses.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sale receipt transaction may has many attached attachments.
|
* Sale receipt transaction may has many attached attachments.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Features } from '@/interfaces';
|
||||||
|
|
||||||
function StatusFieldFilterQuery(query, role) {
|
function StatusFieldFilterQuery(query, role) {
|
||||||
query.modify('filterByStatus', role.value);
|
query.modify('filterByStatus', role.value);
|
||||||
}
|
}
|
||||||
@@ -160,6 +162,18 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
branch: {
|
||||||
|
name: 'Branch',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'branch.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
|
warehouse: {
|
||||||
|
name: 'Warehouse',
|
||||||
|
type: 'text',
|
||||||
|
accessor: 'warehouse.name',
|
||||||
|
features: [Features.BRANCHES],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
vendorId: {
|
vendorId: {
|
||||||
@@ -225,5 +239,21 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
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
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ export default class VendorCredit extends mixin(TenantModel, [
|
|||||||
const ItemEntry = require('models/ItemEntry');
|
const ItemEntry = require('models/ItemEntry');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const Document = require('models/Document');
|
const Document = require('models/Document');
|
||||||
|
const Warehouse = require('models/Warehouse');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
vendor: {
|
vendor: {
|
||||||
@@ -217,6 +218,18 @@ export default class VendorCredit extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor credit may has associated warehouse.
|
||||||
|
*/
|
||||||
|
warehouse: {
|
||||||
|
relation: Model.BelongsToOneRelation,
|
||||||
|
modelClass: Warehouse.default,
|
||||||
|
join: {
|
||||||
|
from: 'vendor_credits.warehouseId',
|
||||||
|
to: 'warehouses.id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vendor credit may has many attached attachments.
|
* Vendor credit may has many attached attachments.
|
||||||
*/
|
*/
|
||||||
|
|||||||
11
packages/server/src/models/Warehouse.settings.ts
Normal file
11
packages/server/src/models/Warehouse.settings.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
fields2: {
|
||||||
|
name: {
|
||||||
|
name: 'Name',
|
||||||
|
fieldType: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: {},
|
||||||
|
fields: {}
|
||||||
|
};
|
||||||
@@ -78,9 +78,9 @@ export class RecognizeTranasctionsService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const bankRules = await BankRule.query(trx).onBuild((q) => {
|
const bankRules = await BankRule.query(trx).onBuild((q) => {
|
||||||
const rulesIds = castArray(ruleId);
|
const rulesIds = !isEmpty(ruleId) ? castArray(ruleId) : [];
|
||||||
|
|
||||||
if (!isEmpty(rulesIds)) {
|
if (rulesIds?.length > 0) {
|
||||||
q.whereIn('id', rulesIds);
|
q.whereIn('id', rulesIds);
|
||||||
}
|
}
|
||||||
q.withGraphFetched('conditions');
|
q.withGraphFetched('conditions');
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ export class EditCustomer {
|
|||||||
});
|
});
|
||||||
// Triggers `onCustomerEdited` event.
|
// Triggers `onCustomerEdited` event.
|
||||||
await this.eventPublisher.emitAsync(events.customers.onEdited, {
|
await this.eventPublisher.emitAsync(events.customers.onEdited, {
|
||||||
|
tenantId,
|
||||||
customerId,
|
customerId,
|
||||||
customer,
|
customer,
|
||||||
trx,
|
trx,
|
||||||
|
|||||||
@@ -15,12 +15,17 @@ export class CreditNotesExportable extends Exportable {
|
|||||||
* @returns {}
|
* @returns {}
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: ICreditNotesQueryDTO) {
|
public exportable(tenantId: number, query: ICreditNotesQueryDTO) {
|
||||||
|
const filterQuery = (query) => {
|
||||||
|
query.withGraphFetched('branch');
|
||||||
|
query.withGraphFetched('warehouse');
|
||||||
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
...query,
|
...query,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 12000,
|
pageSize: 12000,
|
||||||
|
filterQuery,
|
||||||
} as ICreditNotesQueryDTO;
|
} as ICreditNotesQueryDTO;
|
||||||
|
|
||||||
return this.getCreditNotes
|
return this.getCreditNotes
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export default class ListCreditNotes extends BaseCreditNotes {
|
|||||||
builder.withGraphFetched('entries.item');
|
builder.withGraphFetched('entries.item');
|
||||||
builder.withGraphFetched('customer');
|
builder.withGraphFetched('customer');
|
||||||
dynamicFilter.buildQuery()(builder);
|
dynamicFilter.buildQuery()(builder);
|
||||||
|
creditNotesQuery?.filterQuery && creditNotesQuery?.filterQuery(builder);
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import {
|
||||||
|
IBankRuleEventCreatedPayload,
|
||||||
|
IBankRuleEventEditedPayload,
|
||||||
|
IBankRuleEventDeletedPayload,
|
||||||
|
} from '@/services/Banking/Rules/types'; // Updated import path for interfaces
|
||||||
|
import { PosthogService } from '../PostHog';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import {
|
||||||
|
BANK_RULE_CREATED,
|
||||||
|
BANK_RULE_EDITED,
|
||||||
|
BANK_RULE_DELETED,
|
||||||
|
} from '@/constants/event-tracker';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class BankRuleEventsTracker extends EventSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private posthog: PosthogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.bankRules.onCreated,
|
||||||
|
this.handleTrackBankRuleCreatedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bankRules.onEdited,
|
||||||
|
this.handleTrackEditedBankRuleEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bankRules.onDeleted,
|
||||||
|
this.handleTrackDeletedBankRuleEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTrackBankRuleCreatedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IBankRuleEventCreatedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_RULE_CREATED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackEditedBankRuleEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IBankRuleEventEditedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_RULE_EDITED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackDeletedBankRuleEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IBankRuleEventDeletedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_RULE_DELETED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import { PosthogService } from '../PostHog';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import {
|
||||||
|
BANK_TRANSACTION_MATCHED,
|
||||||
|
BANK_TRANSACTION_EXCLUDED,
|
||||||
|
BANK_TRANSACTION_CATEGORIZED,
|
||||||
|
BANK_TRANSACTION_UNCATEGORIZED,
|
||||||
|
BANK_ACCOUNT_DISCONNECTED,
|
||||||
|
} from '@/constants/event-tracker';
|
||||||
|
import { IBankTransactionMatchedEventPayload } from '@/services/Banking/Matching/types';
|
||||||
|
import { IBankAccountDisconnectedEventPayload } from '@/services/Banking/BankAccounts/types';
|
||||||
|
import {
|
||||||
|
ICashflowTransactionCategorizedPayload,
|
||||||
|
ICashflowTransactionUncategorizedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import { IBankTransactionExcludedEventPayload } from '@/services/Banking/Exclude/_types';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class BankTransactionEventsTracker extends EventSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private posthog: PosthogService;
|
||||||
|
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.bankMatch.onMatched,
|
||||||
|
this.handleTrackBankTransactionMatchedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bankTransactions.onExcluded,
|
||||||
|
this.handleTrackBankTransactionExcludedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.cashflow.onTransactionCategorized,
|
||||||
|
this.handleTrackBankTransactionCategorizedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.cashflow.onTransactionUncategorized,
|
||||||
|
this.handleTrackBankTransactionUncategorizedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bankAccount.onDisconnected,
|
||||||
|
this.handleTrackBankAccountDisconnectedEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTrackBankTransactionMatchedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IBankTransactionMatchedEventPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_TRANSACTION_MATCHED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackBankTransactionExcludedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IBankTransactionExcludedEventPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_TRANSACTION_EXCLUDED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackBankTransactionCategorizedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ICashflowTransactionCategorizedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_TRANSACTION_CATEGORIZED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackBankTransactionUncategorizedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ICashflowTransactionUncategorizedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_TRANSACTION_UNCATEGORIZED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackBankAccountDisconnectedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IBankAccountDisconnectedEventPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: BANK_ACCOUNT_DISCONNECTED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import {
|
||||||
|
ICustomerEventCreatedPayload,
|
||||||
|
ICustomerEventEditedPayload,
|
||||||
|
ICustomerEventDeletedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import { PosthogService } from '../PostHog';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import {
|
||||||
|
CUSTOMER_CREATED,
|
||||||
|
CUSTOMER_EDITED,
|
||||||
|
CUSTOMER_DELETED,
|
||||||
|
} from '@/constants/event-tracker';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class CustomerEventsTracker extends EventSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private posthog: PosthogService;
|
||||||
|
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.customers.onCreated,
|
||||||
|
this.handleTrackCustomerCreatedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.customers.onEdited,
|
||||||
|
this.handleTrackEditedCustomerEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.customers.onDeleted,
|
||||||
|
this.handleTrackDeletedCustomerEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTrackCustomerCreatedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ICustomerEventCreatedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: CUSTOMER_CREATED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackEditedCustomerEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ICustomerEventEditedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: CUSTOMER_EDITED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackDeletedCustomerEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ICustomerEventDeletedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: CUSTOMER_DELETED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import {
|
||||||
|
IManualJournalEventCreatedPayload,
|
||||||
|
IManualJournalEventEditedPayload,
|
||||||
|
IManualJournalEventDeletedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import { PosthogService } from '../PostHog';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import {
|
||||||
|
MANUAL_JOURNAL_CREATED,
|
||||||
|
MANUAL_JOURNAL_EDITED,
|
||||||
|
MANUAL_JOURNAL_DELETED,
|
||||||
|
} from '@/constants/event-tracker';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class ManualJournalEventsTracker extends EventSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private posthog: PosthogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onCreated,
|
||||||
|
this.handleTrackManualJournalCreatedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onEdited,
|
||||||
|
this.handleTrackEditedManualJournalEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onDeleted,
|
||||||
|
this.handleTrackDeletedManualJournalEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTrackManualJournalCreatedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IManualJournalEventCreatedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: MANUAL_JOURNAL_CREATED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackEditedManualJournalEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IManualJournalEventEditedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: MANUAL_JOURNAL_EDITED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackDeletedManualJournalEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IManualJournalEventDeletedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: MANUAL_JOURNAL_DELETED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import { ITransactionsLockingPartialUnlocked } from '@/interfaces';
|
||||||
|
import { PosthogService } from '../PostHog';
|
||||||
|
import {
|
||||||
|
TRANSACTIONS_LOCKING_LOCKED,
|
||||||
|
TRANSACTIONS_LOCKING_LOCKING_CANCELLED,
|
||||||
|
TRANSACTIONS_LOCKING_PARTIALLY_UNLOCK_CANCELLED,
|
||||||
|
TRANSACTIONS_LOCKING_PARTIALLY_UNLOCKED,
|
||||||
|
} from '@/constants/event-tracker';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class TransactionsLockingEventsTracker extends EventSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private posthog: PosthogService;
|
||||||
|
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.transactionsLocking.locked,
|
||||||
|
this.handleTransactionsLockingLockedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.transactionsLocking.lockCanceled,
|
||||||
|
this.handleTransactionsLockingCancelledEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.transactionsLocking.partialUnlocked,
|
||||||
|
this.handleTransactionsLockingPartiallyUnlockedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.transactionsLocking.partialUnlockCanceled,
|
||||||
|
this.handleTransactionsLockingPartiallyUnlockCancelledEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTransactionsLockingLockedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ITransactionsLockingPartialUnlocked) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: TRANSACTIONS_LOCKING_LOCKED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTransactionsLockingCancelledEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ITransactionsLockingPartialUnlocked) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: TRANSACTIONS_LOCKING_LOCKING_CANCELLED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTransactionsLockingPartiallyUnlockedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ITransactionsLockingPartialUnlocked) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: TRANSACTIONS_LOCKING_PARTIALLY_UNLOCKED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTransactionsLockingPartiallyUnlockCancelledEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: ITransactionsLockingPartialUnlocked) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: TRANSACTIONS_LOCKING_PARTIALLY_UNLOCK_CANCELLED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import { ITransactionsLockingPartialUnlocked } from '@/interfaces';
|
||||||
|
import { PosthogService } from '../PostHog';
|
||||||
|
import {
|
||||||
|
SUBSCRIPTION_CANCELLED,
|
||||||
|
SUBSCRIPTION_PLAN_CHANGED,
|
||||||
|
SUBSCRIPTION_RESUMED,
|
||||||
|
} from '@/constants/event-tracker';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class TransactionsLockingEventsTracker extends EventSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private posthog: PosthogService;
|
||||||
|
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.subscription.onSubscriptionResumed,
|
||||||
|
this.handleSubscriptionResumedEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.subscription.onSubscriptionCancelled,
|
||||||
|
this.handleSubscriptionCancelledEvent
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.subscription.onSubscriptionPlanChanged,
|
||||||
|
this.handleSubscriptionPlanChangedEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleSubscriptionResumedEvent = ({ tenantId }) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: SUBSCRIPTION_RESUMED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleSubscriptionCancelledEvent = ({ tenantId }) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: SUBSCRIPTION_CANCELLED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleSubscriptionPlanChangedEvent = ({ tenantId }) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: SUBSCRIPTION_PLAN_CHANGED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import {
|
||||||
|
IVendorEventCreatedPayload,
|
||||||
|
IVendorEventEditedPayload,
|
||||||
|
IVendorEventDeletedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import { PosthogService } from '../PostHog';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import {
|
||||||
|
VENDOR_CREATED,
|
||||||
|
VENDOR_EDITED,
|
||||||
|
VENDOR_DELETED,
|
||||||
|
} from '@/constants/event-tracker';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class VendorEventsTracker extends EventSubscriber {
|
||||||
|
@Inject()
|
||||||
|
private posthog: PosthogService;
|
||||||
|
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(events.vendors.onCreated, this.handleTrackVendorCreatedEvent);
|
||||||
|
bus.subscribe(events.vendors.onEdited, this.handleTrackEditedVendorEvent);
|
||||||
|
bus.subscribe(events.vendors.onDeleted, this.handleTrackDeletedVendorEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTrackVendorCreatedEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IVendorEventCreatedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: VENDOR_CREATED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackEditedVendorEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IVendorEventEditedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: VENDOR_EDITED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private handleTrackDeletedVendorEvent = ({
|
||||||
|
tenantId,
|
||||||
|
}: IVendorEventDeletedPayload) => {
|
||||||
|
this.posthog.trackEvent({
|
||||||
|
distinctId: `tenant-${tenantId}`,
|
||||||
|
event: VENDOR_DELETED,
|
||||||
|
properties: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,6 +7,11 @@ import { ExpenseEventsTracker } from './ExpenseEventsTracker';
|
|||||||
import { AccountEventsTracker } from './AccountEventsTracker';
|
import { AccountEventsTracker } from './AccountEventsTracker';
|
||||||
import { AuthenticationEventsTracker } from './AuthenticationEventsTracker';
|
import { AuthenticationEventsTracker } from './AuthenticationEventsTracker';
|
||||||
import { ItemEventsTracker } from './ItemEventsTracker';
|
import { ItemEventsTracker } from './ItemEventsTracker';
|
||||||
|
import { BankTransactionEventsTracker } from './BankTransactionEventsTracker';
|
||||||
|
import { CustomerEventsTracker } from './CustomerEventsTracker';
|
||||||
|
import { VendorEventsTracker } from './VendorEventsTracker';
|
||||||
|
import { ManualJournalEventsTracker } from './ManualJournalEventsTracker';
|
||||||
|
import { BankRuleEventsTracker } from './BankRuleEventsTracker';
|
||||||
|
|
||||||
export const EventsTrackerListeners = [
|
export const EventsTrackerListeners = [
|
||||||
SaleInvoiceEventsTracker,
|
SaleInvoiceEventsTracker,
|
||||||
@@ -17,5 +22,10 @@ export const EventsTrackerListeners = [
|
|||||||
AccountEventsTracker,
|
AccountEventsTracker,
|
||||||
ExpenseEventsTracker,
|
ExpenseEventsTracker,
|
||||||
AuthenticationEventsTracker,
|
AuthenticationEventsTracker,
|
||||||
ItemEventsTracker
|
ItemEventsTracker,
|
||||||
|
BankTransactionEventsTracker,
|
||||||
|
CustomerEventsTracker,
|
||||||
|
VendorEventsTracker,
|
||||||
|
ManualJournalEventsTracker,
|
||||||
|
BankRuleEventsTracker,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import { sumBy, difference } from 'lodash';
|
import { sumBy, difference } from 'lodash';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { ERRORS } from '../constants';
|
import { ERRORS, SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES } from '../constants';
|
||||||
import {
|
import {
|
||||||
IAccount,
|
IAccount,
|
||||||
IExpense,
|
IExpense,
|
||||||
@@ -79,7 +79,9 @@ export class CommandExpenseValidator {
|
|||||||
* @throws {ServiceError}
|
* @throws {ServiceError}
|
||||||
*/
|
*/
|
||||||
public validatePaymentAccountType = (paymentAccount: number[]) => {
|
public validatePaymentAccountType = (paymentAccount: number[]) => {
|
||||||
if (!paymentAccount.isParentType(ACCOUNT_PARENT_TYPE.CURRENT_ASSET)) {
|
if (
|
||||||
|
!paymentAccount.isAccountType(SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES)
|
||||||
|
) {
|
||||||
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_HAS_INVALID_TYPE);
|
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_HAS_INVALID_TYPE);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export class GetExpenses {
|
|||||||
builder.withGraphFetched('categories.expenseAccount');
|
builder.withGraphFetched('categories.expenseAccount');
|
||||||
|
|
||||||
dynamicList.buildQuery()(builder);
|
dynamicList.buildQuery()(builder);
|
||||||
|
filterDTO?.filterQuery && filterDTO?.filterQuery(builder);
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
113
packages/server/src/services/Expenses/ExpenseGL.ts
Normal file
113
packages/server/src/services/Expenses/ExpenseGL.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import * as R from 'ramda';
|
||||||
|
import {
|
||||||
|
AccountNormal,
|
||||||
|
IExpenseCategory,
|
||||||
|
ILedger,
|
||||||
|
ILedgerEntry,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import Ledger from '../Accounting/Ledger';
|
||||||
|
|
||||||
|
export class ExpenseGL {
|
||||||
|
private expense: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
constructor(expense: any) {
|
||||||
|
this.expense = expense;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL common entry.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {Partial<ILedgerEntry>}
|
||||||
|
*/
|
||||||
|
private getExpenseGLCommonEntry = (): Partial<ILedgerEntry> => {
|
||||||
|
return {
|
||||||
|
currencyCode: this.expense.currencyCode,
|
||||||
|
exchangeRate: this.expense.exchangeRate,
|
||||||
|
|
||||||
|
transactionType: 'Expense',
|
||||||
|
transactionId: this.expense.id,
|
||||||
|
|
||||||
|
date: this.expense.paymentDate,
|
||||||
|
userId: this.expense.userId,
|
||||||
|
|
||||||
|
debit: 0,
|
||||||
|
credit: 0,
|
||||||
|
|
||||||
|
branchId: this.expense.branchId,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL payment entry.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedgerEntry}
|
||||||
|
*/
|
||||||
|
private getExpenseGLPaymentEntry = (): ILedgerEntry => {
|
||||||
|
const commonEntry = this.getExpenseGLCommonEntry();
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonEntry,
|
||||||
|
credit: this.expense.localAmount,
|
||||||
|
accountId: this.expense.paymentAccountId,
|
||||||
|
accountNormal:
|
||||||
|
this.expense?.paymentAccount?.accountNormal === 'debit'
|
||||||
|
? AccountNormal.DEBIT
|
||||||
|
: AccountNormal.CREDIT,
|
||||||
|
index: 1,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL category entry.
|
||||||
|
* @param {IExpense} expense -
|
||||||
|
* @param {IExpenseCategory} expenseCategory -
|
||||||
|
* @param {number} index
|
||||||
|
* @returns {ILedgerEntry}
|
||||||
|
*/
|
||||||
|
private getExpenseGLCategoryEntry = R.curry(
|
||||||
|
(category: IExpenseCategory, index: number): ILedgerEntry => {
|
||||||
|
const commonEntry = this.getExpenseGLCommonEntry();
|
||||||
|
const localAmount = category.amount * this.expense.exchangeRate;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonEntry,
|
||||||
|
accountId: category.expenseAccountId,
|
||||||
|
accountNormal: AccountNormal.DEBIT,
|
||||||
|
debit: localAmount,
|
||||||
|
note: category.description,
|
||||||
|
index: index + 2,
|
||||||
|
projectId: category.projectId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL entries.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedgerEntry[]}
|
||||||
|
*/
|
||||||
|
public getExpenseGLEntries = (): ILedgerEntry[] => {
|
||||||
|
const getCategoryEntry = this.getExpenseGLCategoryEntry();
|
||||||
|
|
||||||
|
const paymentEntry = this.getExpenseGLPaymentEntry();
|
||||||
|
const categoryEntries = this.expense.categories.map(getCategoryEntry);
|
||||||
|
|
||||||
|
return [paymentEntry, ...categoryEntries];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the given expense ledger.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedger}
|
||||||
|
*/
|
||||||
|
public getExpenseLedger = (): ILedger => {
|
||||||
|
const entries = this.getExpenseGLEntries();
|
||||||
|
|
||||||
|
console.log(entries, 'entries');
|
||||||
|
|
||||||
|
return new Ledger(entries);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import * as R from 'ramda';
|
|
||||||
import { Service } from 'typedi';
|
|
||||||
import {
|
|
||||||
AccountNormal,
|
|
||||||
IExpense,
|
|
||||||
IExpenseCategory,
|
|
||||||
ILedger,
|
|
||||||
ILedgerEntry,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import Ledger from '@/services/Accounting/Ledger';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class ExpenseGLEntries {
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL common entry.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
private getExpenseGLCommonEntry = (expense: IExpense) => {
|
|
||||||
return {
|
|
||||||
currencyCode: expense.currencyCode,
|
|
||||||
exchangeRate: expense.exchangeRate,
|
|
||||||
|
|
||||||
transactionType: 'Expense',
|
|
||||||
transactionId: expense.id,
|
|
||||||
|
|
||||||
date: expense.paymentDate,
|
|
||||||
userId: expense.userId,
|
|
||||||
|
|
||||||
debit: 0,
|
|
||||||
credit: 0,
|
|
||||||
|
|
||||||
branchId: expense.branchId,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL payment entry.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns {ILedgerEntry}
|
|
||||||
*/
|
|
||||||
private getExpenseGLPaymentEntry = (expense: IExpense): ILedgerEntry => {
|
|
||||||
const commonEntry = this.getExpenseGLCommonEntry(expense);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...commonEntry,
|
|
||||||
credit: expense.localAmount,
|
|
||||||
accountId: expense.paymentAccountId,
|
|
||||||
accountNormal: AccountNormal.DEBIT,
|
|
||||||
index: 1,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL category entry.
|
|
||||||
* @param {IExpense} expense -
|
|
||||||
* @param {IExpenseCategory} expenseCategory -
|
|
||||||
* @param {number} index
|
|
||||||
* @returns {ILedgerEntry}
|
|
||||||
*/
|
|
||||||
private getExpenseGLCategoryEntry = R.curry(
|
|
||||||
(
|
|
||||||
expense: IExpense,
|
|
||||||
category: IExpenseCategory,
|
|
||||||
index: number
|
|
||||||
): ILedgerEntry => {
|
|
||||||
const commonEntry = this.getExpenseGLCommonEntry(expense);
|
|
||||||
const localAmount = category.amount * expense.exchangeRate;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...commonEntry,
|
|
||||||
accountId: category.expenseAccountId,
|
|
||||||
accountNormal: AccountNormal.DEBIT,
|
|
||||||
debit: localAmount,
|
|
||||||
note: category.description,
|
|
||||||
index: index + 2,
|
|
||||||
projectId: category.projectId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL entries.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns {ILedgerEntry[]}
|
|
||||||
*/
|
|
||||||
public getExpenseGLEntries = (expense: IExpense): ILedgerEntry[] => {
|
|
||||||
const getCategoryEntry = this.getExpenseGLCategoryEntry(expense);
|
|
||||||
|
|
||||||
const paymentEntry = this.getExpenseGLPaymentEntry(expense);
|
|
||||||
const categoryEntries = expense.categories.map(getCategoryEntry);
|
|
||||||
|
|
||||||
return [paymentEntry, ...categoryEntries];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the given expense ledger.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns {ILedger}
|
|
||||||
*/
|
|
||||||
public getExpenseLedger = (expense: IExpense): ILedger => {
|
|
||||||
const entries = this.getExpenseGLEntries(expense);
|
|
||||||
|
|
||||||
return new Ledger(entries);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { Knex } from 'knex';
|
||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { IExpense, ILedger } from '@/interfaces';
|
||||||
|
import { ExpenseGL } from './ExpenseGL';
|
||||||
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class ExpenseGLEntries {
|
||||||
|
@Inject()
|
||||||
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense G/L of the given id.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} expenseId
|
||||||
|
* @param {Knex.Transaction} trx
|
||||||
|
* @returns {Promise<ILedger>}
|
||||||
|
*/
|
||||||
|
public getExpenseLedgerById = async (
|
||||||
|
tenantId: number,
|
||||||
|
expenseId: number,
|
||||||
|
trx?: Knex.Transaction
|
||||||
|
): Promise<ILedger> => {
|
||||||
|
const { Expense } = await this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const expense = await Expense.query(trx)
|
||||||
|
.findById(expenseId)
|
||||||
|
.withGraphFetched('categories')
|
||||||
|
.withGraphFetched('paymentAccount')
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
return this.getExpenseLedger(expense);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the given expense ledger.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedger}
|
||||||
|
*/
|
||||||
|
public getExpenseLedger = (expense: IExpense): ILedger => {
|
||||||
|
const expenseGL = new ExpenseGL(expense);
|
||||||
|
|
||||||
|
return expenseGL.getExpenseLedger();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import { Knex } from 'knex';
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
|
import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { ExpenseGLEntries } from './ExpenseGLEntries';
|
import { ExpenseGLEntries } from './ExpenseGLEntriesService';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExpenseGLEntriesStorage {
|
export class ExpenseGLEntriesStorage {
|
||||||
@@ -12,9 +12,6 @@ export class ExpenseGLEntriesStorage {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private ledgerStorage: LedgerStorageService;
|
private ledgerStorage: LedgerStorageService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private tenancy: HasTenancyService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the expense GL entries.
|
* Writes the expense GL entries.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -26,15 +23,12 @@ export class ExpenseGLEntriesStorage {
|
|||||||
expenseId: number,
|
expenseId: number,
|
||||||
trx?: Knex.Transaction
|
trx?: Knex.Transaction
|
||||||
) => {
|
) => {
|
||||||
const { Expense } = await this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const expense = await Expense.query(trx)
|
|
||||||
.findById(expenseId)
|
|
||||||
.withGraphFetched('categories');
|
|
||||||
|
|
||||||
// Retrieves the given expense ledger.
|
// Retrieves the given expense ledger.
|
||||||
const expenseLedger = this.expenseGLEntries.getExpenseLedger(expense);
|
const expenseLedger = await this.expenseGLEntries.getExpenseLedgerById(
|
||||||
|
tenantId,
|
||||||
|
expenseId,
|
||||||
|
trx
|
||||||
|
);
|
||||||
// Commits the expense ledger entries.
|
// Commits the expense ledger entries.
|
||||||
await this.ledgerStorage.commit(tenantId, expenseLedger, trx);
|
await this.ledgerStorage.commit(tenantId, expenseLedger, trx);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,12 +15,16 @@ export class ExpensesExportable extends Exportable {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: IExpensesFilter) {
|
public exportable(tenantId: number, query: IExpensesFilter) {
|
||||||
|
const filterQuery = (query) => {
|
||||||
|
query.withGraphFetched('branch');
|
||||||
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
...query,
|
...query,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: EXPORT_SIZE_LIMIT,
|
pageSize: EXPORT_SIZE_LIMIT,
|
||||||
|
filterQuery,
|
||||||
} as IExpensesFilter;
|
} as IExpensesFilter;
|
||||||
|
|
||||||
return this.expensesApplication
|
return this.expensesApplication
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
|
||||||
|
|
||||||
export const DEFAULT_VIEW_COLUMNS = [];
|
export const DEFAULT_VIEW_COLUMNS = [];
|
||||||
export const DEFAULT_VIEWS = [
|
export const DEFAULT_VIEWS = [
|
||||||
{
|
{
|
||||||
@@ -76,3 +78,12 @@ export const ExpensesSampleData = [
|
|||||||
Publish: 'T',
|
Publish: 'T',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES = [
|
||||||
|
ACCOUNT_TYPE.CASH,
|
||||||
|
ACCOUNT_TYPE.BANK,
|
||||||
|
ACCOUNT_TYPE.CREDIT_CARD,
|
||||||
|
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
||||||
|
ACCOUNT_TYPE.NON_CURRENT_ASSET,
|
||||||
|
ACCOUNT_TYPE.FIXED_ASSET,
|
||||||
|
];
|
||||||
|
|||||||
@@ -56,7 +56,10 @@ export class ExportResourceService {
|
|||||||
) {
|
) {
|
||||||
const resource = sanitizeResourceName(resourceName);
|
const resource = sanitizeResourceName(resourceName);
|
||||||
const resourceMeta = this.getResourceMeta(tenantId, resource);
|
const resourceMeta = this.getResourceMeta(tenantId, resource);
|
||||||
|
const resourceColumns = this.resourceService.getResourceColumns(
|
||||||
|
tenantId,
|
||||||
|
resource
|
||||||
|
);
|
||||||
this.validateResourceMeta(resourceMeta);
|
this.validateResourceMeta(resourceMeta);
|
||||||
|
|
||||||
const data = await this.getExportableData(tenantId, resource);
|
const data = await this.getExportableData(tenantId, resource);
|
||||||
@@ -64,7 +67,7 @@ export class ExportResourceService {
|
|||||||
|
|
||||||
// Returns the csv, xlsx format.
|
// Returns the csv, xlsx format.
|
||||||
if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) {
|
if (format === ExportFormat.Csv || format === ExportFormat.Xlsx) {
|
||||||
const exportableColumns = this.getExportableColumns(resourceMeta);
|
const exportableColumns = this.getExportableColumns(resourceColumns);
|
||||||
const workbook = this.createWorkbook(transformed, exportableColumns);
|
const workbook = this.createWorkbook(transformed, exportableColumns);
|
||||||
|
|
||||||
return this.exportWorkbook(workbook, format);
|
return this.exportWorkbook(workbook, format);
|
||||||
@@ -143,7 +146,7 @@ export class ExportResourceService {
|
|||||||
* @param {IModelMeta} resourceMeta - The metadata of the resource.
|
* @param {IModelMeta} resourceMeta - The metadata of the resource.
|
||||||
* @returns An array of exportable columns.
|
* @returns An array of exportable columns.
|
||||||
*/
|
*/
|
||||||
private getExportableColumns(resourceMeta: IModelMeta) {
|
private getExportableColumns(resourceColumns: any) {
|
||||||
const processColumns = (
|
const processColumns = (
|
||||||
columns: { [key: string]: IModelMetaColumn },
|
columns: { [key: string]: IModelMetaColumn },
|
||||||
parent = ''
|
parent = ''
|
||||||
@@ -166,7 +169,7 @@ export class ExportResourceService {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return processColumns(resourceMeta.columns);
|
return processColumns(resourceColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPrintableColumns(resourceMeta: IModelMeta) {
|
private getPrintableColumns(resourceMeta: IModelMeta) {
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ export class ImportFileMapping {
|
|||||||
// Invalidate the from/to map attributes.
|
// Invalidate the from/to map attributes.
|
||||||
this.validateMapsAttrs(tenantId, importFile, maps);
|
this.validateMapsAttrs(tenantId, importFile, maps);
|
||||||
|
|
||||||
|
// @todo validate the required fields.
|
||||||
|
|
||||||
// Validate the diplicated relations of map attrs.
|
// Validate the diplicated relations of map attrs.
|
||||||
this.validateDuplicatedMapAttrs(maps);
|
this.validateDuplicatedMapAttrs(maps);
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export class BillPaymentExportable extends Exportable {
|
|||||||
public exportable(tenantId: number, query: any) {
|
public exportable(tenantId: number, query: any) {
|
||||||
const filterQuery = (builder) => {
|
const filterQuery = (builder) => {
|
||||||
builder.withGraphFetched('entries.bill');
|
builder.withGraphFetched('entries.bill');
|
||||||
|
builder.withGraphFetched('branch');
|
||||||
};
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { Knex } from 'knex';
|
||||||
import { IBillsFilter } from '@/interfaces';
|
import { IBillsFilter } from '@/interfaces';
|
||||||
import { Exportable } from '@/services/Export/Exportable';
|
import { Exportable } from '@/services/Export/Exportable';
|
||||||
import { BillsApplication } from './BillsApplication';
|
import { BillsApplication } from './BillsApplication';
|
||||||
import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants';
|
import { EXPORT_SIZE_LIMIT } from '@/services/Export/constants';
|
||||||
|
import Objection from 'objection';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class BillsExportable extends Exportable {
|
export class BillsExportable extends Exportable {
|
||||||
@@ -15,12 +17,17 @@ export class BillsExportable extends Exportable {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: IBillsFilter) {
|
public exportable(tenantId: number, query: IBillsFilter) {
|
||||||
|
const filterQuery = (query) => {
|
||||||
|
query.withGraphFetched('branch');
|
||||||
|
query.withGraphFetched('warehouse');
|
||||||
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
...query,
|
...query,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: EXPORT_SIZE_LIMIT,
|
pageSize: EXPORT_SIZE_LIMIT,
|
||||||
|
filterQuery,
|
||||||
} as IBillsFilter;
|
} as IBillsFilter;
|
||||||
|
|
||||||
return this.billsApplication
|
return this.billsApplication
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ export class GetBills {
|
|||||||
builder.withGraphFetched('vendor');
|
builder.withGraphFetched('vendor');
|
||||||
builder.withGraphFetched('entries.item');
|
builder.withGraphFetched('entries.item');
|
||||||
dynamicFilter.buildQuery()(builder);
|
dynamicFilter.buildQuery()(builder);
|
||||||
|
|
||||||
|
// Filter query.
|
||||||
|
filterDTO?.filterQuery && filterDTO?.filterQuery(builder);
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ export default class ListVendorCredits extends BaseVendorCredit {
|
|||||||
builder.withGraphFetched('entries');
|
builder.withGraphFetched('entries');
|
||||||
builder.withGraphFetched('vendor');
|
builder.withGraphFetched('vendor');
|
||||||
dynamicFilter.buildQuery()(builder);
|
dynamicFilter.buildQuery()(builder);
|
||||||
|
|
||||||
|
// Gives ability to inject custom query to filter results.
|
||||||
|
vendorCreditQuery?.filterQuery &&
|
||||||
|
vendorCreditQuery?.filterQuery(builder);
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Inject, Service } from 'typedi';
|
|||||||
import { IVendorCreditsQueryDTO } from '@/interfaces';
|
import { IVendorCreditsQueryDTO } from '@/interfaces';
|
||||||
import ListVendorCredits from './ListVendorCredits';
|
import ListVendorCredits from './ListVendorCredits';
|
||||||
import { Exportable } from '@/services/Export/Exportable';
|
import { Exportable } from '@/services/Export/Exportable';
|
||||||
|
import { QueryBuilder } from 'knex';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class VendorCreditsExportable extends Exportable {
|
export class VendorCreditsExportable extends Exportable {
|
||||||
@@ -15,12 +16,17 @@ export class VendorCreditsExportable extends Exportable {
|
|||||||
* @returns {}
|
* @returns {}
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: IVendorCreditsQueryDTO) {
|
public exportable(tenantId: number, query: IVendorCreditsQueryDTO) {
|
||||||
|
const filterQuery = (query) => {
|
||||||
|
query.withGraphFetched('branch');
|
||||||
|
query.withGraphFetched('warehouse');
|
||||||
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
...query,
|
...query,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 12000,
|
pageSize: 12000,
|
||||||
|
filterQuery,
|
||||||
} as IVendorCreditsQueryDTO;
|
} as IVendorCreditsQueryDTO;
|
||||||
|
|
||||||
return this.getVendorCredits
|
return this.getVendorCredits
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import { camelCase, upperFirst, pickBy } from 'lodash';
|
import { camelCase, upperFirst, pickBy, isEmpty } from 'lodash';
|
||||||
import * as qim from 'qim';
|
import * as qim from 'qim';
|
||||||
import pluralize from 'pluralize';
|
import pluralize from 'pluralize';
|
||||||
import { IModelMeta, IModelMetaField, IModelMetaField2 } from '@/interfaces';
|
import {
|
||||||
|
Features,
|
||||||
|
IModelMeta,
|
||||||
|
IModelMetaField,
|
||||||
|
IModelMetaField2,
|
||||||
|
} from '@/interfaces';
|
||||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import I18nService from '@/services/I18n/I18nService';
|
import I18nService from '@/services/I18n/I18nService';
|
||||||
|
import { WarehousesSettings } from '../Warehouses/WarehousesSettings';
|
||||||
|
import { BranchesSettings } from '../Branches/BranchesSettings';
|
||||||
|
|
||||||
const ERRORS = {
|
const ERRORS = {
|
||||||
RESOURCE_MODEL_NOT_FOUND: 'RESOURCE_MODEL_NOT_FOUND',
|
RESOURCE_MODEL_NOT_FOUND: 'RESOURCE_MODEL_NOT_FOUND',
|
||||||
@@ -19,6 +26,12 @@ export default class ResourceService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
i18nService: I18nService;
|
i18nService: I18nService;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private branchesSettings: BranchesSettings;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private warehousesSettings: WarehousesSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform resource to model name.
|
* Transform resource to model name.
|
||||||
* @param {string} resourceName
|
* @param {string} resourceName
|
||||||
@@ -74,13 +87,45 @@ export default class ResourceService {
|
|||||||
return meta.fields;
|
return meta.fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public filterSupportFeatures = (
|
||||||
|
tenantId,
|
||||||
|
fields: { [key: string]: IModelMetaField2 }
|
||||||
|
) => {
|
||||||
|
const isMultiFeaturesEnabled =
|
||||||
|
this.branchesSettings.isMultiBranchesActive(tenantId);
|
||||||
|
const isMultiWarehousesEnabled =
|
||||||
|
this.warehousesSettings.isMultiWarehousesActive(tenantId);
|
||||||
|
|
||||||
|
return pickBy(fields, (field) => {
|
||||||
|
if (
|
||||||
|
!isMultiWarehousesEnabled &&
|
||||||
|
field.features?.includes(Features.WAREHOUSES)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!isMultiFeaturesEnabled &&
|
||||||
|
field.features?.includes(Features.BRANCHES)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
public getResourceFields2(
|
public getResourceFields2(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
modelName: string
|
modelName: string
|
||||||
): { [key: string]: IModelMetaField2 } {
|
): { [key: string]: IModelMetaField2 } {
|
||||||
const meta = this.getResourceMeta(tenantId, modelName);
|
const meta = this.getResourceMeta(tenantId, modelName);
|
||||||
|
|
||||||
return meta.fields2;
|
return this.filterSupportFeatures(tenantId, meta.fields2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getResourceColumns(tenantId: number, modelName: string) {
|
||||||
|
const meta = this.getResourceMeta(tenantId, modelName);
|
||||||
|
|
||||||
|
return this.filterSupportFeatures(tenantId, meta.columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ export class GetSaleEstimates {
|
|||||||
builder.withGraphFetched('entries');
|
builder.withGraphFetched('entries');
|
||||||
builder.withGraphFetched('entries.item');
|
builder.withGraphFetched('entries.item');
|
||||||
dynamicFilter.buildQuery()(builder);
|
dynamicFilter.buildQuery()(builder);
|
||||||
|
filterDTO?.filterQuery && filterDTO?.filterQuery(builder);
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,17 @@ export class SaleEstimatesExportable extends Exportable {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: ISalesInvoicesFilter) {
|
public exportable(tenantId: number, query: ISalesInvoicesFilter) {
|
||||||
|
const filterQuery = (query) => {
|
||||||
|
query.withGraphFetched('branch');
|
||||||
|
query.withGraphFetched('warehouse');
|
||||||
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
...query,
|
...query,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: EXPORT_SIZE_LIMIT,
|
pageSize: EXPORT_SIZE_LIMIT,
|
||||||
|
filterQuery,
|
||||||
} as ISalesInvoicesFilter;
|
} as ISalesInvoicesFilter;
|
||||||
|
|
||||||
return this.saleEstimatesApplication
|
return this.saleEstimatesApplication
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export class GetSaleInvoices {
|
|||||||
builder.withGraphFetched('entries.item');
|
builder.withGraphFetched('entries.item');
|
||||||
builder.withGraphFetched('customer');
|
builder.withGraphFetched('customer');
|
||||||
dynamicFilter.buildQuery()(builder);
|
dynamicFilter.buildQuery()(builder);
|
||||||
|
filterDTO?.filterQuery && filterDTO?.filterQuery(builder);
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,17 @@ export class SaleInvoicesExportable extends Exportable {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: ISalesInvoicesFilter) {
|
public exportable(tenantId: number, query: ISalesInvoicesFilter) {
|
||||||
|
const filterQuery = (query) => {
|
||||||
|
query.withGraphFetched('branch');
|
||||||
|
query.withGraphFetched('warehouse');
|
||||||
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
...query,
|
...query,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: EXPORT_SIZE_LIMIT,
|
pageSize: EXPORT_SIZE_LIMIT,
|
||||||
|
filterQuery,
|
||||||
} as ISalesInvoicesFilter;
|
} as ISalesInvoicesFilter;
|
||||||
|
|
||||||
return this.saleInvoicesApplication
|
return this.saleInvoicesApplication
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export class PaymentsReceivedExportable extends Exportable {
|
|||||||
public exportable(tenantId: number, query: IPaymentsReceivedFilter) {
|
public exportable(tenantId: number, query: IPaymentsReceivedFilter) {
|
||||||
const filterQuery = (builder) => {
|
const filterQuery = (builder) => {
|
||||||
builder.withGraphFetched('entries.invoice');
|
builder.withGraphFetched('entries.invoice');
|
||||||
|
builder.withGraphFetched('branch');
|
||||||
};
|
};
|
||||||
|
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export class GetSaleReceipts {
|
|||||||
builder.withGraphFetched('entries.item');
|
builder.withGraphFetched('entries.item');
|
||||||
|
|
||||||
dynamicFilter.buildQuery()(builder);
|
dynamicFilter.buildQuery()(builder);
|
||||||
|
filterDTO?.filterQuery && filterDTO?.filterQuery(builder);
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,17 @@ export class SaleReceiptsExportable extends Exportable {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: ISalesReceiptsFilter) {
|
public exportable(tenantId: number, query: ISalesReceiptsFilter) {
|
||||||
|
const filterQuery = (query) => {
|
||||||
|
query.withGraphFetched('branch');
|
||||||
|
query.withGraphFetched('warehouse');
|
||||||
|
};
|
||||||
const parsedQuery = {
|
const parsedQuery = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
columnSortBy: 'created_at',
|
columnSortBy: 'created_at',
|
||||||
...query,
|
...query,
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: EXPORT_SIZE_LIMIT,
|
pageSize: EXPORT_SIZE_LIMIT,
|
||||||
|
filterQuery,
|
||||||
} as ISalesReceiptsFilter;
|
} as ISalesReceiptsFilter;
|
||||||
|
|
||||||
return this.saleReceiptsApp
|
return this.saleReceiptsApp
|
||||||
|
|||||||
@@ -9,7 +9,12 @@ import {
|
|||||||
Classes,
|
Classes,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Position,
|
Position,
|
||||||
|
MenuItem,
|
||||||
|
Menu,
|
||||||
|
MenuDivider,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
|
import { Popover2 } from '@blueprintjs/popover2';
|
||||||
|
|
||||||
import { FormattedMessage as T, Icon, Hint, If } from '@/components';
|
import { FormattedMessage as T, Icon, Hint, If } from '@/components';
|
||||||
|
|
||||||
import DashboardTopbarUser from '@/components/Dashboard/TopbarUser';
|
import DashboardTopbarUser from '@/components/Dashboard/TopbarUser';
|
||||||
@@ -19,9 +24,20 @@ import DashboardBackLink from '@/components/Dashboard/DashboardBackLink';
|
|||||||
import withUniversalSearchActions from '@/containers/UniversalSearch/withUniversalSearchActions';
|
import withUniversalSearchActions from '@/containers/UniversalSearch/withUniversalSearchActions';
|
||||||
import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
|
import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
|
||||||
import withDashboard from '@/containers/Dashboard/withDashboard';
|
import withDashboard from '@/containers/Dashboard/withDashboard';
|
||||||
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import QuickNewDropdown from '@/containers/QuickNewDropdown/QuickNewDropdown';
|
import QuickNewDropdown from '@/containers/QuickNewDropdown/QuickNewDropdown';
|
||||||
import { DashboardHamburgerButton, DashboardQuickSearchButton } from './_components';
|
import {
|
||||||
|
DashboardHamburgerButton,
|
||||||
|
DashboardQuickSearchButton,
|
||||||
|
} from './_components';
|
||||||
|
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import {
|
||||||
|
COMMUNITY_BIGCAPITAL_LINK,
|
||||||
|
DOCS_BIGCAPITAL_LINK,
|
||||||
|
} from '@/constants/routes';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +57,9 @@ function DashboardTopbar({
|
|||||||
|
|
||||||
// #withGlobalSearch
|
// #withGlobalSearch
|
||||||
openGlobalSearch,
|
openGlobalSearch,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
openDialog,
|
||||||
}) {
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
@@ -112,11 +131,34 @@ function DashboardTopbar({
|
|||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Button
|
<Popover2
|
||||||
className={Classes.MINIMAL}
|
content={
|
||||||
icon={<Icon icon={'help-24'} iconSize={20} />}
|
<Menu>
|
||||||
text={<T id={'help'} />}
|
<MenuItem
|
||||||
/>
|
text={'Documents'}
|
||||||
|
onClick={() => window.open(DOCS_BIGCAPITAL_LINK)}
|
||||||
|
labelElement={<Icon icon={'share'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
text={'Community support'}
|
||||||
|
onClick={() => window.open(COMMUNITY_BIGCAPITAL_LINK)}
|
||||||
|
labelElement={<Icon icon={'share'} iconSize={16} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
text={'Keyboard shortcuts'}
|
||||||
|
onClick={() => openDialog(DialogsName.KeyboardShortcutForm)}
|
||||||
|
/>
|
||||||
|
<MenuDivider />
|
||||||
|
<MenuItem text={'Share feedback'} />
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'help-24'} iconSize={20} />}
|
||||||
|
text={<T id={'help'} />}
|
||||||
|
/>
|
||||||
|
</Popover2>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
</NavbarGroup>
|
</NavbarGroup>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
@@ -138,4 +180,5 @@ export default compose(
|
|||||||
pageHint,
|
pageHint,
|
||||||
})),
|
})),
|
||||||
withDashboardActions,
|
withDashboardActions,
|
||||||
|
withDialogActions,
|
||||||
)(DashboardTopbar);
|
)(DashboardTopbar);
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { camelCase} from 'lodash';
|
import { camelCase } from 'lodash';
|
||||||
|
|
||||||
import { If, Skeleton } from '@/components';
|
import { If, Skeleton } from '@/components';
|
||||||
import { useAppIntlContext } from '@/components/AppIntlProvider';
|
import { useAppIntlContext } from '@/components/AppIntlProvider';
|
||||||
import TableContext from './TableContext';
|
import TableContext from './TableContext';
|
||||||
import { saveInvoke, ignoreEventFromSelectors } from '@/utils';
|
import { saveInvoke, ignoreEventFromSelectors } from '@/utils';
|
||||||
import { isCellLoading } from './utils';
|
import { isCellLoading } from './utils';
|
||||||
|
import { MoneyDisplay } from '../Money/MoneyDisplay';
|
||||||
|
|
||||||
const ROW_CLICK_SELECTORS_INGORED = ['.expand-toggle', '.selection-checkbox'];
|
const ROW_CLICK_SELECTORS_INGORED = ['.expand-toggle', '.selection-checkbox'];
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ export default function TableCell({ cell, row, index }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
saveInvoke(onCellClick, cell, event);
|
saveInvoke(onCellClick, cell, event);
|
||||||
};
|
};
|
||||||
const cellType = camelCase(cell.column.Cell.cellType) || 'text';
|
const cellType = camelCase(cell.column.Cell.cellType) || 'text';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -109,7 +110,11 @@ export default function TableCell({ cell, row, index }) {
|
|||||||
</span>
|
</span>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
{cell.render('Cell')}
|
{cell.column?.money ? (
|
||||||
|
<MoneyDisplay>{cell.render('Cell')}</MoneyDisplay>
|
||||||
|
) : (
|
||||||
|
<>{cell.render('Cell')}</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
.root {
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
9
packages/webapp/src/components/Money/MoneyDisplay.tsx
Normal file
9
packages/webapp/src/components/Money/MoneyDisplay.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import styles from './MoneyDisplay.module.scss';
|
||||||
|
|
||||||
|
interface MoneyDisplayProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MoneyDisplay({ children }: MoneyDisplayProps) {
|
||||||
|
return <span className={styles.root}>{children}</span>;
|
||||||
|
}
|
||||||
2
packages/webapp/src/constants/routes.ts
Normal file
2
packages/webapp/src/constants/routes.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export const DOCS_BIGCAPITAL_LINK = 'https://docs.bigcapital.app';
|
||||||
|
export const COMMUNITY_BIGCAPITAL_LINK = 'https://community.bigcapital.app';
|
||||||
@@ -27,6 +27,7 @@ export const useManualJournalsColumns = () => {
|
|||||||
accessor: 'formatted_amount',
|
accessor: 'formatted_amount',
|
||||||
width: 115,
|
width: 115,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
className: clsx(CLASSES.FONT_BOLD),
|
className: clsx(CLASSES.FONT_BOLD),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import { Intent, Tag } from '@blueprintjs/core';
|
import { Intent, Tag, Classes } from '@blueprintjs/core';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
|
||||||
import { If, AppToaster } from '@/components';
|
import { If, AppToaster } from '@/components';
|
||||||
import { NormalCell, BalanceCell, BankBalanceCell } from './components';
|
import { NormalCell, BalanceCell, BankBalanceCell } from './components';
|
||||||
@@ -73,7 +74,7 @@ export const useAccountsTableColumns = () => {
|
|||||||
id: 'type',
|
id: 'type',
|
||||||
Header: intl.get('type'),
|
Header: intl.get('type'),
|
||||||
accessor: 'account_type_label',
|
accessor: 'account_type_label',
|
||||||
className: 'type',
|
className: clsx('type', Classes.TEXT_MUTED),
|
||||||
width: 140,
|
width: 140,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
@@ -91,6 +92,7 @@ export const useAccountsTableColumns = () => {
|
|||||||
id: 'currency',
|
id: 'currency',
|
||||||
Header: intl.get('currency'),
|
Header: intl.get('currency'),
|
||||||
accessor: 'currency_code',
|
accessor: 'currency_code',
|
||||||
|
className: clsx(Classes.TEXT_MUTED),
|
||||||
width: 75,
|
width: 75,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
},
|
},
|
||||||
@@ -102,6 +104,7 @@ export const useAccountsTableColumns = () => {
|
|||||||
width: 150,
|
width: 150,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'balance',
|
id: 'balance',
|
||||||
@@ -110,6 +113,7 @@ export const useAccountsTableColumns = () => {
|
|||||||
Cell: BalanceCell,
|
Cell: BalanceCell,
|
||||||
width: 150,
|
width: 150,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -34,21 +34,23 @@ import {
|
|||||||
} from '@/constants/cashflowOptions';
|
} from '@/constants/cashflowOptions';
|
||||||
import { useRefreshCashflowTransactions } from '@/hooks/query';
|
import { useRefreshCashflowTransactions } from '@/hooks/query';
|
||||||
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
||||||
|
import { useMediaQuery } from '@/hooks/useMediaQuery';
|
||||||
|
import { useAppShellContext } from '@/components/AppShell/AppContentShell/AppContentShellProvider';
|
||||||
|
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||||
|
import { withBankingActions } from '../withBankingActions';
|
||||||
import { compose } from '@/utils';
|
import { withBanking } from '../withBanking';
|
||||||
|
import withAlertActions from '@/containers/Alert/withAlertActions';
|
||||||
import {
|
import {
|
||||||
useUpdateBankAccount,
|
useUpdateBankAccount,
|
||||||
useExcludeUncategorizedTransactions,
|
useExcludeUncategorizedTransactions,
|
||||||
useUnexcludeUncategorizedTransactions,
|
useUnexcludeUncategorizedTransactions,
|
||||||
} from '@/hooks/query/bank-rules';
|
} from '@/hooks/query/bank-rules';
|
||||||
import { withBankingActions } from '../withBankingActions';
|
|
||||||
import { withBanking } from '../withBanking';
|
|
||||||
import withAlertActions from '@/containers/Alert/withAlertActions';
|
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
function AccountTransactionsActionsBar({
|
function AccountTransactionsActionsBar({
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
@@ -221,6 +223,13 @@ function AccountTransactionsActionsBar({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { hideAside } = useAppShellContext();
|
||||||
|
const isMin1350Query = useMediaQuery('(min-width: 1350px)');
|
||||||
|
|
||||||
|
// Shrink actions to dropdown if the aside is open and matched the media query,
|
||||||
|
// To avoid actions overflow in small screens.
|
||||||
|
const shrinkActions = !hideAside && !isMin1350Query;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardActionsBar>
|
<DashboardActionsBar>
|
||||||
<NavbarGroup>
|
<NavbarGroup>
|
||||||
@@ -241,23 +250,27 @@ function AccountTransactionsActionsBar({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
<Button
|
|
||||||
className={Classes.MINIMAL}
|
<If condition={!shrinkActions}>
|
||||||
icon={<Icon icon="print-16" iconSize={16} />}
|
<Button
|
||||||
text={<T id={'print'} />}
|
className={Classes.MINIMAL}
|
||||||
/>
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
<Button
|
text={<T id={'print'} />}
|
||||||
className={Classes.MINIMAL}
|
/>
|
||||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
<Button
|
||||||
text={<T id={'export'} />}
|
className={Classes.MINIMAL}
|
||||||
/>
|
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||||
<Button
|
text={<T id={'export'} />}
|
||||||
className={Classes.MINIMAL}
|
/>
|
||||||
icon={<Icon icon="file-import-16" iconSize={16} />}
|
<Button
|
||||||
text={<T id={'import'} />}
|
className={Classes.MINIMAL}
|
||||||
onClick={handleImportBtnClick}
|
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||||
/>
|
text={<T id={'import'} />}
|
||||||
<NavbarDivider />
|
onClick={handleImportBtnClick}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
</If>
|
||||||
|
|
||||||
<DashboardRowsHeightButton
|
<DashboardRowsHeightButton
|
||||||
initialValue={cashflowTansactionsTableSize}
|
initialValue={cashflowTansactionsTableSize}
|
||||||
onChange={handleTableRowSizeChange}
|
onChange={handleTableRowSizeChange}
|
||||||
@@ -290,6 +303,40 @@ function AccountTransactionsActionsBar({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</If>
|
</If>
|
||||||
|
|
||||||
|
<If condition={shrinkActions}>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Popover
|
||||||
|
minimal={true}
|
||||||
|
interactionKind={PopoverInteractionKind.CLICK}
|
||||||
|
position={Position.BOTTOM_LEFT}
|
||||||
|
modifiers={{
|
||||||
|
offset: { offset: '0, 4' },
|
||||||
|
}}
|
||||||
|
content={
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="print-16" iconSize={16} />}
|
||||||
|
text={<T id={'print'} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||||
|
text={<T id={'export'} />}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||||
|
text={<T id={'import'} />}
|
||||||
|
onClick={handleImportBtnClick}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<Icon icon="more-h-16" iconSize={16} />}
|
||||||
|
minimal={true}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
</If>
|
||||||
|
|
||||||
{!isEmpty(uncategorizedTransationsIdsSelected) && (
|
{!isEmpty(uncategorizedTransationsIdsSelected) && (
|
||||||
<Button
|
<Button
|
||||||
icon={<Icon icon="disable" iconSize={16} />}
|
icon={<Icon icon="disable" iconSize={16} />}
|
||||||
@@ -368,7 +415,6 @@ function AccountTransactionsActionsBar({
|
|||||||
</If>
|
</If>
|
||||||
|
|
||||||
<MenuItem onClick={handleBankRulesClick} text={'Bank rules'} />
|
<MenuItem onClick={handleBankRulesClick} text={'Bank rules'} />
|
||||||
|
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<If condition={isSyncingOwner && isFeedsActive}>
|
<If condition={isSyncingOwner && isFeedsActive}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Suspense, lazy } from 'react';
|
||||||
|
import { Spinner } from '@blueprintjs/core';
|
||||||
|
import { AppContentShell } from '@/components/AppShell';
|
||||||
|
|
||||||
|
const CategorizeTransactionAside = lazy(() =>
|
||||||
|
import('../CategorizeTransactionAside/CategorizeTransactionAside').then(
|
||||||
|
(module) => ({ default: module.CategorizeTransactionAside }),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
export function AccountTransactionsAside() {
|
||||||
|
return (
|
||||||
|
<AppContentShell.Aside>
|
||||||
|
<Suspense fallback={<Spinner size={20} />}>
|
||||||
|
<CategorizeTransactionAside />
|
||||||
|
</Suspense>
|
||||||
|
</AppContentShell.Aside>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import { withBankingActions } from '../withBankingActions';
|
|||||||
import { useMemorizedColumnsWidths } from '@/hooks';
|
import { useMemorizedColumnsWidths } from '@/hooks';
|
||||||
import { useAccountTransactionsColumns, ActionsMenu } from './components';
|
import { useAccountTransactionsColumns, ActionsMenu } from './components';
|
||||||
import { useAccountTransactionsAllContext } from './AccountTransactionsAllBoot';
|
import { useAccountTransactionsAllContext } from './AccountTransactionsAllBoot';
|
||||||
|
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
||||||
import { useUnmatchMatchedUncategorizedTransaction } from '@/hooks/query/bank-rules';
|
import { useUnmatchMatchedUncategorizedTransaction } from '@/hooks/query/bank-rules';
|
||||||
import { useUncategorizeTransaction } from '@/hooks/query';
|
import { useUncategorizeTransaction } from '@/hooks/query';
|
||||||
import { handleCashFlowTransactionType } from './utils';
|
import { handleCashFlowTransactionType } from './utils';
|
||||||
@@ -62,6 +63,8 @@ function AccountTransactionsDataTable({
|
|||||||
const [initialColumnsWidths, , handleColumnResizing] =
|
const [initialColumnsWidths, , handleColumnResizing] =
|
||||||
useMemorizedColumnsWidths(TABLES.CASHFLOW_Transactions);
|
useMemorizedColumnsWidths(TABLES.CASHFLOW_Transactions);
|
||||||
|
|
||||||
|
const { scrollableRef } = useAccountTransactionsContext();
|
||||||
|
|
||||||
// Handle view details action.
|
// Handle view details action.
|
||||||
const handleViewDetailCashflowTransaction = (referenceType) => {
|
const handleViewDetailCashflowTransaction = (referenceType) => {
|
||||||
handleCashFlowTransactionType(referenceType, openDrawer);
|
handleCashFlowTransactionType(referenceType, openDrawer);
|
||||||
@@ -132,7 +135,7 @@ function AccountTransactionsDataTable({
|
|||||||
ContextMenu={ActionsMenu}
|
ContextMenu={ActionsMenu}
|
||||||
onCellClick={handleCellClick}
|
onCellClick={handleCellClick}
|
||||||
// #TableVirtualizedListRows props.
|
// #TableVirtualizedListRows props.
|
||||||
vListrowHeight={cashflowTansactionsTableSize == 'small' ? 32 : 40}
|
vListrowHeight={32}
|
||||||
vListOverscanRowCount={0}
|
vListOverscanRowCount={0}
|
||||||
initialColumnsWidths={initialColumnsWidths}
|
initialColumnsWidths={initialColumnsWidths}
|
||||||
onColumnResizing={handleColumnResizing}
|
onColumnResizing={handleColumnResizing}
|
||||||
@@ -140,6 +143,7 @@ function AccountTransactionsDataTable({
|
|||||||
onSelectedRowsChange={handleSelectedRowsChange}
|
onSelectedRowsChange={handleSelectedRowsChange}
|
||||||
noResults={<T id={'cash_flow.account_transactions.no_results'} />}
|
noResults={<T id={'cash_flow.account_transactions.no_results'} />}
|
||||||
className="table-constrant"
|
className="table-constrant"
|
||||||
|
windowScrollerProps={{ scrollElement: scrollableRef }}
|
||||||
payload={{
|
payload={{
|
||||||
onViewDetails: handleViewDetailCashflowTransaction,
|
onViewDetails: handleViewDetailCashflowTransaction,
|
||||||
onUncategorize: handleUncategorizeTransaction,
|
onUncategorize: handleUncategorizeTransaction,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { curry } from 'lodash/fp';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Popover,
|
Popover,
|
||||||
Menu,
|
Menu,
|
||||||
@@ -11,10 +13,9 @@ import {
|
|||||||
Classes,
|
Classes,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { Icon } from '@/components';
|
import { Icon } from '@/components';
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { curry } from 'lodash/fp';
|
|
||||||
|
|
||||||
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
||||||
|
import { useAppShellContext } from '@/components/AppShell/AppContentShell/AppContentShellProvider';
|
||||||
|
|
||||||
function AccountSwitchButton() {
|
function AccountSwitchButton() {
|
||||||
const { currentAccount } = useAccountTransactionsContext();
|
const { currentAccount } = useAccountTransactionsContext();
|
||||||
@@ -22,7 +23,7 @@ function AccountSwitchButton() {
|
|||||||
return (
|
return (
|
||||||
<AccountSwitchButtonBase
|
<AccountSwitchButtonBase
|
||||||
minimal={true}
|
minimal={true}
|
||||||
rightIcon={<Icon icon={'arrow-drop-down'} iconSize={24} />}
|
rightIcon={<Icon icon={'caret-down-16'} iconSize={16} />}
|
||||||
>
|
>
|
||||||
<AccountSwitchText>{currentAccount.name}</AccountSwitchText>
|
<AccountSwitchText>{currentAccount.name}</AccountSwitchText>
|
||||||
</AccountSwitchButtonBase>
|
</AccountSwitchButtonBase>
|
||||||
@@ -110,12 +111,16 @@ function AccountTransactionsDetailsBarSkeleton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function AccountTransactionsDetailsContent() {
|
function AccountTransactionsDetailsContent() {
|
||||||
|
const { hideAside } = useAppShellContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<AccountSwitchItem />
|
<AccountSwitchItem />
|
||||||
<AccountNumberItem />
|
|
||||||
|
{/** Hide some details once the aside opens to preserve space on details bar. */}
|
||||||
|
{hideAside && <AccountNumberItem />}
|
||||||
<AccountBalanceItem />
|
<AccountBalanceItem />
|
||||||
<AccountBankBalanceItem />
|
{hideAside && <AccountBankBalanceItem />}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { Suspense } from 'react';
|
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { Spinner } from '@blueprintjs/core';
|
import { Spinner } from '@blueprintjs/core';
|
||||||
|
import { Suspense, lazy } from 'react';
|
||||||
|
|
||||||
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
|
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
import { AccountTransactionsDetailsBar } from './AccountTransactionsDetailsBar';
|
import { AccountTransactionsDetailsBar } from './AccountTransactionsDetailsBar';
|
||||||
import { AccountTransactionsFilterTabs } from './AccountTransactionsFilterTabs';
|
import { AccountTransactionsFilterTabs } from './AccountTransactionsFilterTabs';
|
||||||
import { AppContentShell } from '@/components/AppShell';
|
import { AppContentShell } from '@/components/AppShell';
|
||||||
import { CategorizeTransactionAside } from '../CategorizeTransactionAside/CategorizeTransactionAside';
|
import { AccountTransactionsAside } from './AccountTransactionsAside';
|
||||||
import { AccountTransactionsLoadingBar } from './components';
|
import { AccountTransactionsLoadingBar } from './components';
|
||||||
import { withBanking } from '../withBanking';
|
import { withBanking } from '../withBanking';
|
||||||
|
|
||||||
@@ -56,14 +56,6 @@ function AccountTransactionsMain() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountTransactionsAside() {
|
|
||||||
return (
|
|
||||||
<AppContentShell.Aside>
|
|
||||||
<CategorizeTransactionAside />
|
|
||||||
</AppContentShell.Aside>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default R.compose(
|
export default R.compose(
|
||||||
withBanking(
|
withBanking(
|
||||||
({ selectedUncategorizedTransactionId, openMatchingTransactionAside }) => ({
|
({ selectedUncategorizedTransactionId, openMatchingTransactionAside }) => ({
|
||||||
@@ -73,11 +65,8 @@ export default R.compose(
|
|||||||
),
|
),
|
||||||
)(AccountTransactionsListRoot);
|
)(AccountTransactionsListRoot);
|
||||||
|
|
||||||
const AccountsTransactionsAll = React.lazy(
|
const AccountsTransactionsAll = lazy(() => import('./AccountsTransactionsAll'));
|
||||||
() => import('./AccountsTransactionsAll'),
|
const AccountsTransactionsUncategorized = lazy(
|
||||||
);
|
|
||||||
|
|
||||||
const AccountsTransactionsUncategorized = React.lazy(
|
|
||||||
() => import('./AllTransactionsUncategorized'),
|
() => import('./AllTransactionsUncategorized'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import {
|
import {
|
||||||
DataTable,
|
|
||||||
TableFastCell,
|
TableFastCell,
|
||||||
TableSkeletonRows,
|
TableSkeletonRows,
|
||||||
TableSkeletonHeader,
|
TableSkeletonHeader,
|
||||||
@@ -17,9 +15,10 @@ import { useMemorizedColumnsWidths } from '@/hooks';
|
|||||||
import { useExcludedTransactionsColumns } from './_utils';
|
import { useExcludedTransactionsColumns } from './_utils';
|
||||||
import { useExcludedTransactionsBoot } from './ExcludedTransactionsTableBoot';
|
import { useExcludedTransactionsBoot } from './ExcludedTransactionsTableBoot';
|
||||||
import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
|
import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
|
||||||
|
import { useUnexcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
|
||||||
|
|
||||||
import { ActionsMenu } from './_components';
|
import { ActionsMenu } from './_components';
|
||||||
import { useUnexcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
|
import { BankAccountDataTable } from '../components/BankAccountDataTable';
|
||||||
import {
|
import {
|
||||||
WithBankingActionsProps,
|
WithBankingActionsProps,
|
||||||
withBankingActions,
|
withBankingActions,
|
||||||
@@ -78,7 +77,7 @@ function ExcludedTransactionsTableRoot({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CashflowTransactionsTable
|
<BankAccountDataTable
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={excludedBankTransactions}
|
data={excludedBankTransactions}
|
||||||
@@ -116,42 +115,3 @@ function ExcludedTransactionsTableRoot({
|
|||||||
export const ExcludedTransactionsTable = R.compose(withBankingActions)(
|
export const ExcludedTransactionsTable = R.compose(withBankingActions)(
|
||||||
ExcludedTransactionsTableRoot,
|
ExcludedTransactionsTableRoot,
|
||||||
);
|
);
|
||||||
|
|
||||||
const DashboardConstrantTable = styled(DataTable)`
|
|
||||||
.table {
|
|
||||||
.thead {
|
|
||||||
.th {
|
|
||||||
background: #fff;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody {
|
|
||||||
.tr:last-child .td {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const CashflowTransactionsTable = styled(DashboardConstrantTable)`
|
|
||||||
.table .tbody {
|
|
||||||
.tbody-inner .tr.no-results {
|
|
||||||
.td {
|
|
||||||
padding: 2rem 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #888;
|
|
||||||
font-weight: 400;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody-inner {
|
|
||||||
.tr .td {
|
|
||||||
border-bottom: 1px solid #e6e6e6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|||||||
@@ -54,12 +54,14 @@ export function useExcludedTransactionsColumns() {
|
|||||||
accessor: 'formatted_deposit_amount',
|
accessor: 'formatted_deposit_amount',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
width: depositWidth,
|
width: depositWidth,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Withdrawal',
|
Header: 'Withdrawal',
|
||||||
accessor: 'formatted_withdrawal_amount',
|
accessor: 'formatted_withdrawal_amount',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
width: withdrawalWidth,
|
width: withdrawalWidth,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import clsx from 'classnames';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import {
|
import {
|
||||||
DataTable,
|
|
||||||
TableFastCell,
|
TableFastCell,
|
||||||
TableSkeletonRows,
|
TableSkeletonRows,
|
||||||
TableSkeletonHeader,
|
TableSkeletonHeader,
|
||||||
@@ -16,6 +13,7 @@ import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
|
|||||||
import { usePendingTransactionsContext } from './PendingTransactionsTableBoot';
|
import { usePendingTransactionsContext } from './PendingTransactionsTableBoot';
|
||||||
import { usePendingTransactionsTableColumns } from './_hooks';
|
import { usePendingTransactionsTableColumns } from './_hooks';
|
||||||
|
|
||||||
|
import { BankAccountDataTable } from '../components/BankAccountDataTable';
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,7 +35,7 @@ function PendingTransactionsDataTableRoot({
|
|||||||
} = usePendingTransactionsContext();
|
} = usePendingTransactionsContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CashflowTransactionsTable
|
<BankAccountDataTable
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={pendingTransactions || []}
|
data={pendingTransactions || []}
|
||||||
@@ -54,7 +52,6 @@ function PendingTransactionsDataTableRoot({
|
|||||||
vListOverscanRowCount={0}
|
vListOverscanRowCount={0}
|
||||||
noResults={'There is no pending transactions in the current account.'}
|
noResults={'There is no pending transactions in the current account.'}
|
||||||
windowScrollerProps={{ scrollElement: scrollableRef }}
|
windowScrollerProps={{ scrollElement: scrollableRef }}
|
||||||
className={clsx('table-constrant')}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -65,47 +62,3 @@ export const PendingTransactionsDataTable = compose(
|
|||||||
})),
|
})),
|
||||||
withBankingActions,
|
withBankingActions,
|
||||||
)(PendingTransactionsDataTableRoot);
|
)(PendingTransactionsDataTableRoot);
|
||||||
|
|
||||||
const DashboardConstrantTable = styled(DataTable)`
|
|
||||||
.table {
|
|
||||||
.thead {
|
|
||||||
.th {
|
|
||||||
background: #fff;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
font-size: 13px;i
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody {
|
|
||||||
.tr:last-child .td {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const CashflowTransactionsTable = styled(DashboardConstrantTable)`
|
|
||||||
.table .tbody {
|
|
||||||
.tbody-inner .tr.no-results {
|
|
||||||
.td {
|
|
||||||
padding: 2rem 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #888;
|
|
||||||
font-weight: 400;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody-inner {
|
|
||||||
.tr .td:not(:first-child) {
|
|
||||||
border-left: 1px solid #e6e6e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-description {
|
|
||||||
color: #5f6b7c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export function usePendingTransactionsTableColumns() {
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'withdrawal',
|
id: 'withdrawal',
|
||||||
@@ -58,6 +59,7 @@ export function usePendingTransactionsTableColumns() {
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
withBankingActions,
|
withBankingActions,
|
||||||
} from '../../withBankingActions';
|
} from '../../withBankingActions';
|
||||||
import styles from './RecognizedTransactionsTable.module.scss';
|
import styles from './RecognizedTransactionsTable.module.scss';
|
||||||
|
import { BankAccountDataTable } from '../components/BankAccountDataTable';
|
||||||
|
|
||||||
interface RecognizedTransactionsTableProps extends WithBankingActionsProps {}
|
interface RecognizedTransactionsTableProps extends WithBankingActionsProps {}
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ function RecognizedTransactionsTableRoot({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CashflowTransactionsTable
|
<BankAccountDataTable
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={recognizedTransactions}
|
data={recognizedTransactions}
|
||||||
@@ -100,14 +101,12 @@ function RecognizedTransactionsTableRoot({
|
|||||||
ContextMenu={ActionsMenu}
|
ContextMenu={ActionsMenu}
|
||||||
onCellClick={handleCellClick}
|
onCellClick={handleCellClick}
|
||||||
// #TableVirtualizedListRows props.
|
// #TableVirtualizedListRows props.
|
||||||
vListrowHeight={'small' == 'small' ? 32 : 40}
|
|
||||||
vListrowHeight={40}
|
vListrowHeight={40}
|
||||||
vListOverscanRowCount={0}
|
vListOverscanRowCount={0}
|
||||||
initialColumnsWidths={initialColumnsWidths}
|
initialColumnsWidths={initialColumnsWidths}
|
||||||
onColumnResizing={handleColumnResizing}
|
onColumnResizing={handleColumnResizing}
|
||||||
windowScrollerProps={{ scrollElement: scrollableRef }}
|
windowScrollerProps={{ scrollElement: scrollableRef }}
|
||||||
noResults={<RecognizedTransactionsTableNoResults />}
|
noResults={<RecognizedTransactionsTableNoResults />}
|
||||||
className="table-constrant"
|
|
||||||
payload={{
|
payload={{
|
||||||
onExclude: handleExcludeClick,
|
onExclude: handleExcludeClick,
|
||||||
onCategorize: handleCategorizeClick,
|
onCategorize: handleCategorizeClick,
|
||||||
@@ -120,45 +119,6 @@ export const RecognizedTransactionsTable = compose(withBankingActions)(
|
|||||||
RecognizedTransactionsTableRoot,
|
RecognizedTransactionsTableRoot,
|
||||||
);
|
);
|
||||||
|
|
||||||
const DashboardConstrantTable = styled(DataTable)`
|
|
||||||
.table {
|
|
||||||
.thead {
|
|
||||||
.th {
|
|
||||||
background: #fff;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody {
|
|
||||||
.tr:last-child .td {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const CashflowTransactionsTable = styled(DashboardConstrantTable)`
|
|
||||||
.table .tbody {
|
|
||||||
.tbody-inner .tr.no-results {
|
|
||||||
.td {
|
|
||||||
padding: 2rem 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #888;
|
|
||||||
font-weight: 400;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody-inner {
|
|
||||||
.tr .td {
|
|
||||||
border-bottom: 1px solid #e6e6e6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
function RecognizedTransactionsTableNoResults() {
|
function RecognizedTransactionsTableNoResults() {
|
||||||
return (
|
return (
|
||||||
<Stack spacing={12} className={styles.emptyState}>
|
<Stack spacing={12} className={styles.emptyState}>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
import { Classes } from '@blueprintjs/core';
|
||||||
import { Group, Icon } from '@/components';
|
import { Group, Icon } from '@/components';
|
||||||
import { getColumnWidth } from '@/utils';
|
import { getColumnWidth } from '@/utils';
|
||||||
import React from 'react';
|
|
||||||
import { useRecognizedTransactionsBoot } from './RecognizedTransactionsTableBoot';
|
import { useRecognizedTransactionsBoot } from './RecognizedTransactionsTableBoot';
|
||||||
|
|
||||||
const getReportColWidth = (data, accessor, headerText) => {
|
const getReportColWidth = (data, accessor, headerText) => {
|
||||||
@@ -28,10 +30,6 @@ const recognizeAccessor = (transaction) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const descriptionAccessor = (transaction) => {
|
|
||||||
return <span style={{ color: '#5F6B7C' }}>{transaction.description}</span>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve uncategorized transactions columns table.
|
* Retrieve uncategorized transactions columns table.
|
||||||
*/
|
*/
|
||||||
@@ -59,7 +57,8 @@ export function useUncategorizedTransactionsColumns() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Description',
|
Header: 'Description',
|
||||||
accessor: descriptionAccessor,
|
accessor: 'description',
|
||||||
|
className: clsx(Classes.TEXT_MUTED),
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -82,12 +81,14 @@ export function useUncategorizedTransactionsColumns() {
|
|||||||
accessor: 'formatted_deposit_amount',
|
accessor: 'formatted_deposit_amount',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
width: depositWidth,
|
width: depositWidth,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Withdrawal',
|
Header: 'Withdrawal',
|
||||||
accessor: 'formatted_withdrawal_amount',
|
accessor: 'formatted_withdrawal_amount',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
width: withdrawalWidth,
|
width: withdrawalWidth,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import clsx from 'classnames';
|
import clsx from 'classnames';
|
||||||
import styled from 'styled-components';
|
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import {
|
import {
|
||||||
DataTable,
|
|
||||||
TableFastCell,
|
TableFastCell,
|
||||||
TableSkeletonRows,
|
TableSkeletonRows,
|
||||||
TableSkeletonHeader,
|
TableSkeletonHeader,
|
||||||
TableVirtualizedListRows,
|
TableVirtualizedListRows,
|
||||||
FormattedMessage as T,
|
|
||||||
AppToaster,
|
AppToaster,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { TABLES } from '@/constants/tables';
|
import { TABLES } from '@/constants/tables';
|
||||||
import { ActionsMenu } from './components';
|
import { ActionsMenu } from './components';
|
||||||
|
import { BankAccountDataTable } from '../components/BankAccountDataTable';
|
||||||
|
|
||||||
import withSettings from '@/containers/Settings/withSettings';
|
import withSettings from '@/containers/Settings/withSettings';
|
||||||
import { withBankingActions } from '../../withBankingActions';
|
import { withBankingActions } from '../../withBankingActions';
|
||||||
|
import { withBanking } from '../../withBanking';
|
||||||
|
|
||||||
import { useMemorizedColumnsWidths } from '@/hooks';
|
import { useMemorizedColumnsWidths } from '@/hooks';
|
||||||
import { useAccountUncategorizedTransactionsContext } from '../AllTransactionsUncategorizedBoot';
|
import { useAccountUncategorizedTransactionsContext } from '../AllTransactionsUncategorizedBoot';
|
||||||
@@ -25,7 +24,6 @@ import { useAccountUncategorizedTransactionsColumns } from './hooks';
|
|||||||
import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
|
import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { withBanking } from '../../withBanking';
|
|
||||||
import styles from './AccountTransactionsUncategorizedTable.module.scss';
|
import styles from './AccountTransactionsUncategorizedTable.module.scss';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +46,6 @@ function AccountTransactionsDataTable({
|
|||||||
}) {
|
}) {
|
||||||
// Retrieve table columns.
|
// Retrieve table columns.
|
||||||
const columns = useAccountUncategorizedTransactionsColumns();
|
const columns = useAccountUncategorizedTransactionsColumns();
|
||||||
|
|
||||||
const { scrollableRef } = useAccountTransactionsContext();
|
const { scrollableRef } = useAccountTransactionsContext();
|
||||||
|
|
||||||
// Retrieve list context.
|
// Retrieve list context.
|
||||||
@@ -100,7 +97,7 @@ function AccountTransactionsDataTable({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CashflowTransactionsTable
|
<BankAccountDataTable
|
||||||
noInitialFetch={true}
|
noInitialFetch={true}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={uncategorizedTransactions || []}
|
data={uncategorizedTransactions || []}
|
||||||
@@ -119,7 +116,7 @@ function AccountTransactionsDataTable({
|
|||||||
ContextMenu={ActionsMenu}
|
ContextMenu={ActionsMenu}
|
||||||
onCellClick={handleCellClick}
|
onCellClick={handleCellClick}
|
||||||
// #TableVirtualizedListRows props.
|
// #TableVirtualizedListRows props.
|
||||||
vListrowHeight={cashflowTansactionsTableSize === 'small' ? 32 : 40}
|
vListrowHeight={cashflowTansactionsTableSize === 'small' ? 34 : 40}
|
||||||
vListOverscanRowCount={0}
|
vListOverscanRowCount={0}
|
||||||
initialColumnsWidths={initialColumnsWidths}
|
initialColumnsWidths={initialColumnsWidths}
|
||||||
onColumnResizing={handleColumnResizing}
|
onColumnResizing={handleColumnResizing}
|
||||||
@@ -132,7 +129,7 @@ function AccountTransactionsDataTable({
|
|||||||
}}
|
}}
|
||||||
onSelectedRowsChange={handleSelectedRowsChange}
|
onSelectedRowsChange={handleSelectedRowsChange}
|
||||||
windowScrollerProps={{ scrollElement: scrollableRef }}
|
windowScrollerProps={{ scrollElement: scrollableRef }}
|
||||||
className={clsx('table-constrant', styles.table, {
|
className={clsx(styles.table, {
|
||||||
[styles.showCategorizeColumn]: enableMultipleCategorization,
|
[styles.showCategorizeColumn]: enableMultipleCategorization,
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
@@ -151,47 +148,3 @@ export default compose(
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)(AccountTransactionsDataTable);
|
)(AccountTransactionsDataTable);
|
||||||
|
|
||||||
const DashboardConstrantTable = styled(DataTable)`
|
|
||||||
.table {
|
|
||||||
.thead {
|
|
||||||
.th {
|
|
||||||
background: #fff;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
font-size: 13px;i
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody {
|
|
||||||
.tr:last-child .td {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const CashflowTransactionsTable = styled(DashboardConstrantTable)`
|
|
||||||
.table .tbody {
|
|
||||||
.tbody-inner .tr.no-results {
|
|
||||||
.td {
|
|
||||||
padding: 2rem 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #888;
|
|
||||||
font-weight: 400;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody-inner {
|
|
||||||
.tr .td:not(:first-child) {
|
|
||||||
border-left: 1px solid #e6e6e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.td-description {
|
|
||||||
color: #5f6b7c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
|
import clsx from 'classnames';
|
||||||
import {
|
import {
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Classes,
|
||||||
Intent,
|
Intent,
|
||||||
PopoverInteractionKind,
|
PopoverInteractionKind,
|
||||||
Position,
|
Position,
|
||||||
@@ -97,6 +99,7 @@ export function useAccountUncategorizedTransactionsColumns() {
|
|||||||
width: 160,
|
width: 160,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
className: clsx(Classes.TEXT_MUTED),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'payee',
|
id: 'payee',
|
||||||
@@ -123,21 +126,21 @@ export function useAccountUncategorizedTransactionsColumns() {
|
|||||||
id: 'deposit',
|
id: 'deposit',
|
||||||
Header: intl.get('banking.label.deposit'),
|
Header: intl.get('banking.label.deposit'),
|
||||||
accessor: 'formatted_deposit_amount',
|
accessor: 'formatted_deposit_amount',
|
||||||
width: 40,
|
|
||||||
className: 'deposit',
|
|
||||||
textOverview: true,
|
|
||||||
align: 'right',
|
align: 'right',
|
||||||
|
width: 40,
|
||||||
|
textOverview: true,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'withdrawal',
|
id: 'withdrawal',
|
||||||
Header: intl.get('banking.label.withdrawal'),
|
Header: intl.get('banking.label.withdrawal'),
|
||||||
accessor: 'formatted_withdrawal_amount',
|
accessor: 'formatted_withdrawal_amount',
|
||||||
className: 'withdrawal',
|
|
||||||
width: 40,
|
width: 40,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'categorize_include',
|
id: 'categorize_include',
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ export function useAccountTransactionsColumns() {
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'withdrawal',
|
id: 'withdrawal',
|
||||||
@@ -133,16 +134,18 @@ export function useAccountTransactionsColumns() {
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'running_balance',
|
id: 'running_balance',
|
||||||
Header: intl.get('banking.label.running_balance'),
|
Header: intl.get('banking.label.running_balance'),
|
||||||
accessor: 'formatted_running_balance',
|
accessor: 'formatted_running_balance',
|
||||||
className: 'running_balance',
|
className: 'running_balance',
|
||||||
|
align: 'right',
|
||||||
width: 150,
|
width: 150,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
align: 'right',
|
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
.root {
|
||||||
|
:global .table{
|
||||||
|
.thead {
|
||||||
|
.th {
|
||||||
|
background: #fff;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tbody-inner .tr.no-results {
|
||||||
|
.td {
|
||||||
|
padding: 2rem 0;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #888;
|
||||||
|
font-weight: 400;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tbody-inner {
|
||||||
|
.tr .td{
|
||||||
|
border-bottom: 1px solid #ececec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import clsx from 'classnames';
|
||||||
|
import { DataTable } from '@/components';
|
||||||
|
import styles from './BankAccountDataTable.module.scss';
|
||||||
|
|
||||||
|
interface BankAccountDataTableProps {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function BankAccountDataTable({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: BankAccountDataTableProps) {
|
||||||
|
return (
|
||||||
|
<DataTable
|
||||||
|
{...props}
|
||||||
|
className={clsx('table-constrant', styles.root, className)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
import { Suspense } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
import { Spinner } from '@blueprintjs/core';
|
||||||
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||||
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
||||||
import { withBanking } from '@/containers/CashFlow/withBanking';
|
import { withBanking } from '@/containers/CashFlow/withBanking';
|
||||||
@@ -13,7 +15,9 @@ function CategorizeTransactionContentRoot({
|
|||||||
uncategorizedTransactionsIds={transactionsToCategorizeIdsSelected}
|
uncategorizedTransactionsIds={transactionsToCategorizeIdsSelected}
|
||||||
>
|
>
|
||||||
<CategorizeTransactionDrawerBody>
|
<CategorizeTransactionDrawerBody>
|
||||||
<CategorizeTransactionForm />
|
<Suspense fallback={<Spinner size={40} />}>
|
||||||
|
<CategorizeTransactionForm />
|
||||||
|
</Suspense>
|
||||||
</CategorizeTransactionDrawerBody>
|
</CategorizeTransactionDrawerBody>
|
||||||
</CategorizeTransactionBoot>
|
</CategorizeTransactionBoot>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { createContext } from 'react';
|
|||||||
import { defaultTo } from 'lodash';
|
import { defaultTo } from 'lodash';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { useGetBankTransactionsMatches } from '@/hooks/query/bank-rules';
|
import { useGetBankTransactionsMatches } from '@/hooks/query/bank-rules';
|
||||||
|
import { Spinner } from '@blueprintjs/core';
|
||||||
|
|
||||||
interface MatchingTransactionBootValues {
|
interface MatchingTransactionBootValues {
|
||||||
isMatchingTransactionsLoading: boolean;
|
isMatchingTransactionsLoading: boolean;
|
||||||
@@ -52,6 +53,11 @@ function MatchingTransactionBoot({
|
|||||||
matches,
|
matches,
|
||||||
} as MatchingTransactionBootValues;
|
} as MatchingTransactionBootValues;
|
||||||
|
|
||||||
|
const isLoading = isMatchingTransactionsLoading;
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <Spinner size={40} />;
|
||||||
|
}
|
||||||
return <RuleFormBootContext.Provider value={provider} {...props} />;
|
return <RuleFormBootContext.Provider value={provider} {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
|
import clsx from 'classnames';
|
||||||
import {
|
import {
|
||||||
Menu,
|
Menu,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
@@ -14,6 +15,7 @@ import {
|
|||||||
import { Can, Icon, Money, If, AvatarCell } from '@/components';
|
import { Can, Icon, Money, If, AvatarCell } from '@/components';
|
||||||
import { CustomerAction, AbilitySubject } from '@/constants/abilityOption';
|
import { CustomerAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import { safeCallback } from '@/utils';
|
import { safeCallback } from '@/utils';
|
||||||
|
import { CLASSES } from '@/constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actions menu.
|
* Actions menu.
|
||||||
@@ -140,7 +142,7 @@ export function useCustomersTableColumns() {
|
|||||||
id: 'company_name',
|
id: 'company_name',
|
||||||
Header: intl.get('company_name'),
|
Header: intl.get('company_name'),
|
||||||
accessor: 'company_name',
|
accessor: 'company_name',
|
||||||
className: 'company_name',
|
className: clsx('company_name', CLASSES.TEXT_MUTED),
|
||||||
width: 150,
|
width: 150,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
},
|
},
|
||||||
@@ -148,9 +150,9 @@ export function useCustomersTableColumns() {
|
|||||||
id: 'work_phone',
|
id: 'work_phone',
|
||||||
Header: intl.get('phone_number'),
|
Header: intl.get('phone_number'),
|
||||||
accessor: PhoneNumberAccessor,
|
accessor: PhoneNumberAccessor,
|
||||||
className: 'phone_number',
|
|
||||||
width: 100,
|
width: 100,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
className: clsx('phone_number', CLASSES.TEXT_MUTED)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'note',
|
id: 'note',
|
||||||
@@ -159,6 +161,7 @@ export function useCustomersTableColumns() {
|
|||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
width: 85,
|
width: 85,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
className: clsx(CLASSES.TEXT_MUTED)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'balance',
|
id: 'balance',
|
||||||
@@ -167,6 +170,7 @@ export function useCustomersTableColumns() {
|
|||||||
align: 'right',
|
align: 'right',
|
||||||
width: 100,
|
width: 100,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { InputGroup, FormGroup, Position, Classes } from '@blueprintjs/core';
|
import { FormGroup, Position, Classes } from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FastField, ErrorMessage } from 'formik';
|
import { FastField, ErrorMessage } from 'formik';
|
||||||
import { CustomersSelect, FormattedMessage as T } from '@/components';
|
import { CustomersSelect, FInputGroup, FormattedMessage as T } from '@/components';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { CLASSES } from '@/constants/classes';
|
import { CLASSES } from '@/constants/classes';
|
||||||
import {
|
import {
|
||||||
@@ -15,15 +15,14 @@ import {
|
|||||||
import { customersFieldShouldUpdate, accountsFieldShouldUpdate } from './utils';
|
import { customersFieldShouldUpdate, accountsFieldShouldUpdate } from './utils';
|
||||||
import {
|
import {
|
||||||
CurrencySelectList,
|
CurrencySelectList,
|
||||||
CustomerSelectField,
|
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
AccountsSelect,
|
AccountsSelect,
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
Hint,
|
Hint,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { ExpensesExchangeRateInputField } from './components';
|
import { ExpensesExchangeRateInputField } from './components';
|
||||||
import { ACCOUNT_PARENT_TYPE } from '@/constants/accountTypes';
|
|
||||||
import { useExpenseFormContext } from './ExpenseFormPageProvider';
|
import { useExpenseFormContext } from './ExpenseFormPageProvider';
|
||||||
|
import { SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES } from './constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expense form header.
|
* Expense form header.
|
||||||
@@ -68,7 +67,7 @@ export default function ExpenseFormHeader() {
|
|||||||
name={'payment_account_id'}
|
name={'payment_account_id'}
|
||||||
items={accounts}
|
items={accounts}
|
||||||
placeholder={<T id={'select_payment_account'} />}
|
placeholder={<T id={'select_payment_account'} />}
|
||||||
filterByParentTypes={[ACCOUNT_PARENT_TYPE.CURRENT_ASSET]}
|
filterByTypes={SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES}
|
||||||
allowCreate={true}
|
allowCreate={true}
|
||||||
fastField={true}
|
fastField={true}
|
||||||
shouldUpdate={accountsFieldShouldUpdate}
|
shouldUpdate={accountsFieldShouldUpdate}
|
||||||
@@ -107,19 +106,15 @@ export default function ExpenseFormHeader() {
|
|||||||
formGroupProps={{ label: ' ', inline: true }}
|
formGroupProps={{ label: ' ', inline: true }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FastField name={'reference_no'}>
|
{/* ----------- Reference No. ----------- */}
|
||||||
{({ form, field, meta: { error, touched } }) => (
|
<FFormGroup
|
||||||
<FormGroup
|
name={'reference_no'}
|
||||||
label={<T id={'reference_no'} />}
|
label={<T id={'reference_no'} />}
|
||||||
className={classNames('form-group--ref_no', Classes.FILL)}
|
inline={true}
|
||||||
intent={inputIntent({ error, touched })}
|
fastField
|
||||||
helperText={<ErrorMessage name="reference_no" />}
|
>
|
||||||
inline={true}
|
<FInputGroup minimal={true} name={'reference_no'} fastField />
|
||||||
>
|
</FFormGroup>
|
||||||
<InputGroup minimal={true} {...field} />
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Customer ----------- */}
|
{/* ----------- Customer ----------- */}
|
||||||
<ExpenseFormCustomerSelect />
|
<ExpenseFormCustomerSelect />
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { ACCOUNT_TYPE } from "@/constants";
|
||||||
|
|
||||||
|
export const SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES = [
|
||||||
|
ACCOUNT_TYPE.CASH,
|
||||||
|
ACCOUNT_TYPE.BANK,
|
||||||
|
ACCOUNT_TYPE.CREDIT_CARD,
|
||||||
|
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
||||||
|
ACCOUNT_TYPE.NON_CURRENT_ASSET,
|
||||||
|
ACCOUNT_TYPE.FIXED_ASSET,
|
||||||
|
];
|
||||||
@@ -140,26 +140,25 @@ export function useExpensesTableColumns() {
|
|||||||
id: 'amount',
|
id: 'amount',
|
||||||
Header: intl.get('full_amount'),
|
Header: intl.get('full_amount'),
|
||||||
accessor: 'formatted_amount',
|
accessor: 'formatted_amount',
|
||||||
className: 'amount',
|
|
||||||
align: 'right',
|
align: 'right',
|
||||||
width: 150,
|
width: 150,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
money: true,
|
||||||
className: clsx(CLASSES.FONT_BOLD),
|
className: clsx(CLASSES.FONT_BOLD),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'payment_account',
|
id: 'payment_account',
|
||||||
Header: intl.get('payment_account'),
|
Header: intl.get('payment_account'),
|
||||||
accessor: 'payment_account.name',
|
accessor: 'payment_account.name',
|
||||||
className: 'payment_account',
|
|
||||||
width: 150,
|
width: 150,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
|
className: clsx(CLASSES.TEXT_MUTED),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'expense_account',
|
id: 'expense_account',
|
||||||
Header: intl.get('expense_account'),
|
Header: intl.get('expense_account'),
|
||||||
accessor: ExpenseAccountAccessor,
|
accessor: ExpenseAccountAccessor,
|
||||||
width: 160,
|
width: 160,
|
||||||
className: 'expense_account',
|
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
clickable: true,
|
clickable: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { useMemo } from 'react';
|
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { getColumnWidth } from '@/utils';
|
import { getColumnWidth } from '@/utils';
|
||||||
import { Align } from '@/constants';
|
import { Align } from '@/constants';
|
||||||
@@ -25,6 +24,7 @@ const currentAccessor = R.curry((data, column) => {
|
|||||||
className: column.id,
|
className: column.id,
|
||||||
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ const totalAccessor = R.curry((data, column) => {
|
|||||||
className: column.key,
|
className: column.key,
|
||||||
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ const agingPeriodAccessor = R.curry((data, column) => {
|
|||||||
className: column.key,
|
className: column.key,
|
||||||
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import * as R from 'ramda';
|
|||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
import { Align } from '@/constants';
|
import { Align } from '@/constants';
|
||||||
import { CellTextSpan } from '@/components/Datatable/Cells';
|
|
||||||
import { getColumnWidth } from '@/utils';
|
import { getColumnWidth } from '@/utils';
|
||||||
|
|
||||||
const getTableCellValueAccessor = (index) => `cells[${index}].value`;
|
const getTableCellValueAccessor = (index) => `cells[${index}].value`;
|
||||||
@@ -12,12 +11,11 @@ const getReportColWidth = (data, accessor, headerText) => {
|
|||||||
return getColumnWidth(
|
return getColumnWidth(
|
||||||
data,
|
data,
|
||||||
accessor,
|
accessor,
|
||||||
{ magicSpacing: 10, minWidth: 100 },
|
{ magicSpacing: 12, minWidth: 100 },
|
||||||
headerText,
|
headerText,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Account name column mapper.
|
* Account name column mapper.
|
||||||
*/
|
*/
|
||||||
@@ -77,6 +75,7 @@ const dateRangeMapper = R.curry((data, column) => {
|
|||||||
key: column.key,
|
key: column.key,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
align: isDateColumnHasColumns ? Align.Center : Align.Right,
|
align: isDateColumnHasColumns ? Align.Center : Align.Right,
|
||||||
};
|
};
|
||||||
return R.compose(
|
return R.compose(
|
||||||
@@ -104,9 +103,9 @@ const totalMapper = R.curry((data, column) => {
|
|||||||
Header: column.label,
|
Header: column.label,
|
||||||
accessor,
|
accessor,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
Cell: CellTextSpan,
|
|
||||||
width,
|
width,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
|
money: true,
|
||||||
align: hasChildren ? Align.Center : Align.Right,
|
align: hasChildren ? Align.Center : Align.Right,
|
||||||
};
|
};
|
||||||
return R.compose(
|
return R.compose(
|
||||||
@@ -129,6 +128,7 @@ const percentageOfColumnAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -147,6 +147,7 @@ const percentageOfRowAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -165,6 +166,7 @@ const previousYearAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -183,6 +185,7 @@ const previousYearChangeAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -201,6 +204,7 @@ const previousYearPercentageAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -219,6 +223,7 @@ const previousPeriodAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -237,6 +242,7 @@ const previousPeriodChangeAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -255,6 +261,7 @@ const previousPeriodPercentageAccessor = R.curry((data, column) => {
|
|||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
|
money: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,14 @@ const dateRangeMapper = (data, index, column) => ({
|
|||||||
key: column.key,
|
key: column.key,
|
||||||
accessor: `cells[${index}].value`,
|
accessor: `cells[${index}].value`,
|
||||||
width: getColumnWidth(data, `cells.${index}.value`, {
|
width: getColumnWidth(data, `cells.${index}.value`, {
|
||||||
magicSpacing: 10,
|
magicSpacing: 12,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
}),
|
}),
|
||||||
className: `date-period ${column.key}`,
|
className: `date-period ${column.key}`,
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,11 +51,12 @@ const totalMapper = (data, index, column) => ({
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
Cell: CellTextSpan,
|
Cell: CellTextSpan,
|
||||||
width: getColumnWidth(data, `cells[${index}].value`, {
|
width: getColumnWidth(data, `cells[${index}].value`, {
|
||||||
magicSpacing: 10,
|
magicSpacing: 12,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
}),
|
}),
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -61,9 +61,10 @@ export const useCustomersTransactionsColumns = () => {
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
width: getColumnWidth(tableRows, 'cells[5].value', {
|
width: getColumnWidth(tableRows, 'cells[5].value', {
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
magicSpacing: 10,
|
magicSpacing: 12,
|
||||||
}),
|
}),
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: intl.get('debit'),
|
Header: intl.get('debit'),
|
||||||
@@ -72,9 +73,10 @@ export const useCustomersTransactionsColumns = () => {
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
width: getColumnWidth(tableRows, 'cells[6].value', {
|
width: getColumnWidth(tableRows, 'cells[6].value', {
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
magicSpacing: 10,
|
magicSpacing: 12,
|
||||||
}),
|
}),
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: intl.get('running_balance'),
|
Header: intl.get('running_balance'),
|
||||||
@@ -83,9 +85,10 @@ export const useCustomersTransactionsColumns = () => {
|
|||||||
textOverview: true,
|
textOverview: true,
|
||||||
width: getColumnWidth(tableRows, 'cells[7].value', {
|
width: getColumnWidth(tableRows, 'cells[7].value', {
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
magicSpacing: 10,
|
magicSpacing: 12,
|
||||||
}),
|
}),
|
||||||
align: Align.Right,
|
align: Align.Right,
|
||||||
|
money: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[tableRows],
|
[tableRows],
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user