mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
Compare commits
1 Commits
swagger
...
date-forma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e6f1efe30 |
@@ -89,7 +89,3 @@ S3_ACCESS_KEY_ID=
|
|||||||
S3_SECRET_ACCESS_KEY=
|
S3_SECRET_ACCESS_KEY=
|
||||||
S3_ENDPOINT=
|
S3_ENDPOINT=
|
||||||
S3_BUCKET=
|
S3_BUCKET=
|
||||||
|
|
||||||
# PostHog
|
|
||||||
POSTHOG_API_KEY=
|
|
||||||
POSTHOG_HOST=
|
|
||||||
@@ -99,7 +99,6 @@
|
|||||||
"objection-unique": "^1.2.2",
|
"objection-unique": "^1.2.2",
|
||||||
"plaid": "^10.3.0",
|
"plaid": "^10.3.0",
|
||||||
"pluralize": "^8.0.0",
|
"pluralize": "^8.0.0",
|
||||||
"posthog-node": "^4.2.0",
|
|
||||||
"pug": "^3.0.2",
|
"pug": "^3.0.2",
|
||||||
"puppeteer": "^10.2.0",
|
"puppeteer": "^10.2.0",
|
||||||
"qim": "0.0.52",
|
"qim": "0.0.52",
|
||||||
@@ -109,7 +108,6 @@
|
|||||||
"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,14 +5,7 @@ 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()
|
||||||
@@ -128,26 +121,6 @@ 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,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export class ImportController extends BaseController {
|
|||||||
body('mapping.*.group').optional(),
|
body('mapping.*.group').optional(),
|
||||||
body('mapping.*.from').exists(),
|
body('mapping.*.from').exists(),
|
||||||
body('mapping.*.to').exists(),
|
body('mapping.*.to').exists(),
|
||||||
|
body('mapping.*.dateFormat').optional({ nullable: true }),
|
||||||
],
|
],
|
||||||
this.validationResult,
|
this.validationResult,
|
||||||
this.asyncMiddleware(this.mapping.bind(this)),
|
this.asyncMiddleware(this.mapping.bind(this)),
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ 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 {
|
||||||
@@ -203,22 +198,6 @@ 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);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { Container } from 'typedi';
|
import { Container } from 'typedi';
|
||||||
import { Request, Response, NextFunction } from 'express';
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
|
||||||
const SupportedMethods = ['POST', 'PUT'];
|
|
||||||
|
|
||||||
export default (subscriptionSlug = 'main') =>
|
export default (subscriptionSlug = 'main') =>
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
const { tenant, tenantId } = req;
|
const { tenant, tenantId } = req;
|
||||||
@@ -21,10 +19,8 @@ export default (subscriptionSlug = 'main') =>
|
|||||||
errors: [{ type: 'TENANT.HAS.NO.SUBSCRIPTION' }],
|
errors: [{ type: 'TENANT.HAS.NO.SUBSCRIPTION' }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const isMethodSupported = SupportedMethods.includes(req.method);
|
// Validate in case the subscription is inactive.
|
||||||
const isSubscriptionInactive = subscription.inactive();
|
else if (subscription.inactive()) {
|
||||||
|
|
||||||
if (isMethodSupported && isSubscriptionInactive) {
|
|
||||||
return res.boom.badRequest(null, {
|
return res.boom.badRequest(null, {
|
||||||
errors: [{ type: 'ORGANIZATION.SUBSCRIPTION.INACTIVE' }],
|
errors: [{ type: 'ORGANIZATION.SUBSCRIPTION.INACTIVE' }],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -253,12 +253,4 @@ module.exports = {
|
|||||||
enable: parseBoolean(process.env.ONE_CLICK_DEMO_ACCOUNTS, false),
|
enable: parseBoolean(process.env.ONE_CLICK_DEMO_ACCOUNTS, false),
|
||||||
demoUrl: process.env.ONE_CLICK_DEMO_ACCOUNTS_URL || '',
|
demoUrl: process.env.ONE_CLICK_DEMO_ACCOUNTS_URL || '',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* PostHog
|
|
||||||
*/
|
|
||||||
posthog: {
|
|
||||||
apiKey: process.env.POSTHOG_API_KEY,
|
|
||||||
host: process.env.POSTHOG_HOST
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
export const SALE_INVOICE_CREATED = 'Sale invoice created';
|
|
||||||
export const SALE_INVOICE_EDITED = 'Sale invoice d';
|
|
||||||
export const SALE_INVOICE_DELETED = 'Sale invoice deleted';
|
|
||||||
export const SALE_INVOICE_MAIL_DELIVERED = 'Sale invoice mail delivered';
|
|
||||||
|
|
||||||
export const SALE_ESTIMATE_CREATED = 'Sale estimate created';
|
|
||||||
export const SALE_ESTIMATE_EDITED = 'Sale estimate edited';
|
|
||||||
export const SALE_ESTIMATE_DELETED = 'Sale estimate deleted';
|
|
||||||
|
|
||||||
export const PAYMENT_RECEIVED_CREATED = 'Payment received created';
|
|
||||||
export const PAYMENT_RECEIVED_EDITED = 'payment received edited';
|
|
||||||
export const PAYMENT_RECEIVED_DELETED = 'Payment received deleted';
|
|
||||||
|
|
||||||
export const BILL_CREATED = 'Bill created';
|
|
||||||
export const BILL_EDITED = 'Bill edited';
|
|
||||||
export const BILL_DELETED = 'Bill deleted';
|
|
||||||
|
|
||||||
export const PAYMENT_MADE_CREATED = 'Payment made created';
|
|
||||||
export const PAYMENT_MADE_EDITED = 'Payment made edited';
|
|
||||||
export const PAYMENT_MADE_DELETED = 'Payment made deleted';
|
|
||||||
|
|
||||||
export const EXPENSE_CREATED = 'Expense created';
|
|
||||||
export const EXPENSE_EDITED = 'Expense edited';
|
|
||||||
export const EXPENSE_DELETED = 'Expense deleted';
|
|
||||||
|
|
||||||
export const ACCOUNT_CREATED = 'Account created';
|
|
||||||
export const ACCOUNT_EDITED = 'Account Edited';
|
|
||||||
export const ACCOUNT_DELETED = 'Account deleted';
|
|
||||||
|
|
||||||
export const ITEM_EVENT_CREATED = 'Item created';
|
|
||||||
export const ITEM_EVENT_EDITED = 'Item edited';
|
|
||||||
export const ITEM_EVENT_DELETED = 'Item deleted';
|
|
||||||
|
|
||||||
export const AUTH_SIGNED_UP = 'Auth Signed-up';
|
|
||||||
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 ITEM_GROUP = 'Item';
|
|
||||||
export const AUTH_GROUP = 'Auth';
|
|
||||||
export const SALE_GROUP = 'Sale';
|
|
||||||
export const PAYMENT_GROUP = 'Payment';
|
|
||||||
export const BILL_GROUP = 'Bill';
|
|
||||||
export const EXPENSE_GROUP = 'Expense';
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
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,7 +99,6 @@ 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,7 +241,6 @@ 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;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { IDynamicListFilter, IItemEntry } from '@/interfaces';
|
import { IDynamicListFilter, IItemEntry, IVendorCredit } from '@/interfaces';
|
||||||
import { ILedgerEntry } from './Ledger';
|
import { ILedgerEntry } from './Ledger';
|
||||||
import { AttachmentLinkDTO } from './Attachments';
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface ICreditNoteEntryNewDTO {
|
export interface ICreditNoteEntryNewDTO {
|
||||||
index?: number;
|
index: number;
|
||||||
itemId: number;
|
itemId: number;
|
||||||
rate: number;
|
rate: number;
|
||||||
quantity: number;
|
quantity: number;
|
||||||
@@ -22,7 +22,7 @@ export interface ICreditNoteNewDTO {
|
|||||||
entries: ICreditNoteEntryNewDTO[];
|
entries: ICreditNoteEntryNewDTO[];
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
attachments?: AttachmentLinkDTO[];
|
attachments?: AttachmentLinkDTO[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICreditNoteEditDTO {
|
export interface ICreditNoteEditDTO {
|
||||||
@@ -35,7 +35,7 @@ export interface ICreditNoteEditDTO {
|
|||||||
entries: ICreditNoteEntryNewDTO[];
|
entries: ICreditNoteEntryNewDTO[];
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
attachments?: AttachmentLinkDTO[];
|
attachments?: AttachmentLinkDTO[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICreditNoteEntry extends IItemEntry {}
|
export interface ICreditNoteEntry extends IItemEntry {}
|
||||||
@@ -61,7 +61,7 @@ export interface ICreditNote {
|
|||||||
localAmount?: number;
|
localAmount?: number;
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId: number;
|
warehouseId: number;
|
||||||
createdAt?: Date;
|
createdAt?: Date,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CreditNoteAction {
|
export enum CreditNoteAction {
|
||||||
@@ -130,9 +130,7 @@ 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,7 +17,6 @@ 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 {
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ export interface IItemEntry {
|
|||||||
|
|
||||||
export interface IItemEntryDTO {
|
export interface IItemEntryDTO {
|
||||||
id?: number;
|
id?: number;
|
||||||
index?: number;
|
|
||||||
itemId: number;
|
itemId: number;
|
||||||
landedCost?: boolean;
|
landedCost?: boolean;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ export interface IModelMetaFieldCommon2 {
|
|||||||
importHint?: string;
|
importHint?: string;
|
||||||
order?: number;
|
order?: number;
|
||||||
unique?: number;
|
unique?: number;
|
||||||
features?: Array<any>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IModelMetaRelationField2 {
|
export interface IModelMetaRelationField2 {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export interface IPaymentReceivedEntry {
|
|||||||
|
|
||||||
export interface IPaymentReceivedEntryDTO {
|
export interface IPaymentReceivedEntryDTO {
|
||||||
id?: number;
|
id?: number;
|
||||||
index?: number;
|
index: number;
|
||||||
paymentReceiveId?: number;
|
paymentReceiveId?: number;
|
||||||
invoiceId: number;
|
invoiceId: number;
|
||||||
paymentAmount: number;
|
paymentAmount: number;
|
||||||
@@ -74,7 +74,6 @@ export interface IPaymentReceivedEntryDTO {
|
|||||||
|
|
||||||
export interface IPaymentsReceivedFilter extends IDynamicListFilterDTO {
|
export interface IPaymentsReceivedFilter extends IDynamicListFilterDTO {
|
||||||
stringifiedFilterRoles?: string;
|
stringifiedFilterRoles?: string;
|
||||||
filterQuery?: (trx: Knex.Transaction) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPaymentReceivePageEntry {
|
export interface IPaymentReceivePageEntry {
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ 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,7 +79,6 @@ 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,9 +29,7 @@ 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,7 +106,6 @@ 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 {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import moment from 'moment';
|
|||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { includes, isFunction, isObject, isUndefined, omit } from 'lodash';
|
import { includes, isFunction, isObject, isUndefined, omit } from 'lodash';
|
||||||
import { formatNumber, sortObjectKeysAlphabetically } from 'utils';
|
import { formatNumber, sortObjectKeysAlphabetically } from 'utils';
|
||||||
import { EXPORT_DTE_FORMAT } from '@/services/Export/constants';
|
|
||||||
|
|
||||||
export class Transformer {
|
export class Transformer {
|
||||||
public context: any;
|
public context: any;
|
||||||
@@ -156,35 +155,23 @@ export class Transformer {
|
|||||||
this.dateFormat = format;
|
this.dateFormat = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Format date.
|
|
||||||
* @param {} date
|
|
||||||
* @param {string} format -
|
|
||||||
* @returns {}
|
|
||||||
*/
|
|
||||||
protected formatDate(date, format?: string) {
|
|
||||||
// Use the export date format if the async operation is in exporting,
|
|
||||||
// otherwise use the given or default format.
|
|
||||||
const _format = this.context.exportAls.isExport
|
|
||||||
? EXPORT_DTE_FORMAT
|
|
||||||
: format || this.dateFormat;
|
|
||||||
|
|
||||||
return date ? moment(date).format(_format) : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param date
|
* @param date
|
||||||
* @returns {}
|
* @returns
|
||||||
*/
|
*/
|
||||||
protected formatDateFromNow(date) {
|
protected formatDate(date) {
|
||||||
|
return date ? moment(date).format(this.dateFormat) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected formatDateFromNow(date){
|
||||||
return date ? moment(date).fromNow(true) : '';
|
return date ? moment(date).fromNow(true) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param number
|
* @param number
|
||||||
* @returns {}
|
* @returns
|
||||||
*/
|
*/
|
||||||
protected formatNumber(number, props?) {
|
protected formatNumber(number, props?) {
|
||||||
return formatNumber(number, { money: false, ...props });
|
return formatNumber(number, { money: false, ...props });
|
||||||
@@ -194,7 +181,7 @@ export class Transformer {
|
|||||||
*
|
*
|
||||||
* @param money
|
* @param money
|
||||||
* @param options
|
* @param options
|
||||||
* @returns {}
|
* @returns
|
||||||
*/
|
*/
|
||||||
protected formatMoney(money, options?) {
|
protected formatMoney(money, options?) {
|
||||||
return formatNumber(money, {
|
return formatNumber(money, {
|
||||||
|
|||||||
@@ -3,17 +3,12 @@ import { isNull } from 'lodash';
|
|||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { TenantMetadata } from '@/system/models';
|
import { TenantMetadata } from '@/system/models';
|
||||||
import { Transformer } from './Transformer';
|
import { Transformer } from './Transformer';
|
||||||
import { ImportAls } from '@/services/Import/ImportALS';
|
|
||||||
import { ExportAls } from '@/services/Export/ExportAls';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class TransformerInjectable {
|
export class TransformerInjectable {
|
||||||
@Inject()
|
@Inject()
|
||||||
private tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private exportAls: ExportAls;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the application context of all tenant transformers.
|
* Retrieves the application context of all tenant transformers.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -22,12 +17,10 @@ export class TransformerInjectable {
|
|||||||
async getApplicationContext(tenantId: number) {
|
async getApplicationContext(tenantId: number) {
|
||||||
const i18n = this.tenancy.i18n(tenantId);
|
const i18n = this.tenancy.i18n(tenantId);
|
||||||
const organization = await TenantMetadata.query().findOne({ tenantId });
|
const organization = await TenantMetadata.query().findOne({ tenantId });
|
||||||
const exportAls = this.exportAls;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
organization,
|
organization,
|
||||||
i18n,
|
i18n,
|
||||||
exportAls,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ import { LoopsEventsSubscriber } from '@/services/Loops/LoopsEventsSubscriber';
|
|||||||
import { DeleteUncategorizedTransactionsOnAccountDeleting } from '@/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting';
|
import { DeleteUncategorizedTransactionsOnAccountDeleting } from '@/services/Banking/BankAccounts/events/DeleteUncategorizedTransactionsOnAccountDeleting';
|
||||||
import { SeedInitialDemoAccountDataOnOrgBuild } from '@/services/OneClickDemo/events/SeedInitialDemoAccountData';
|
import { SeedInitialDemoAccountDataOnOrgBuild } from '@/services/OneClickDemo/events/SeedInitialDemoAccountData';
|
||||||
import { TriggerInvalidateCacheOnSubscriptionChange } from '@/services/Subscription/events/TriggerInvalidateCacheOnSubscriptionChange';
|
import { TriggerInvalidateCacheOnSubscriptionChange } from '@/services/Subscription/events/TriggerInvalidateCacheOnSubscriptionChange';
|
||||||
import { EventsTrackerListeners } from '@/services/EventsTracker/events/events';
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
return new EventPublisher();
|
return new EventPublisher();
|
||||||
@@ -290,7 +289,5 @@ export const susbcribers = () => {
|
|||||||
|
|
||||||
// Demo Account
|
// Demo Account
|
||||||
SeedInitialDemoAccountDataOnOrgBuild,
|
SeedInitialDemoAccountDataOnOrgBuild,
|
||||||
|
|
||||||
...EventsTrackerListeners
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'vendor',
|
defaultFilterField: 'vendor',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -169,18 +167,6 @@ 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: {
|
||||||
@@ -252,22 +238,6 @@ 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,7 +402,6 @@ 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');
|
||||||
@@ -454,18 +453,6 @@ 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,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'vendor',
|
defaultFilterField: 'vendor',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -7,8 +5,6 @@ export default {
|
|||||||
sortField: 'bill_date',
|
sortField: 'bill_date',
|
||||||
},
|
},
|
||||||
exportable: true,
|
exportable: true,
|
||||||
exportFlattenOn: 'entries',
|
|
||||||
|
|
||||||
importable: true,
|
importable: true,
|
||||||
importAggregator: 'group',
|
importAggregator: 'group',
|
||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
@@ -81,7 +77,7 @@ export default {
|
|||||||
paymentDate: {
|
paymentDate: {
|
||||||
name: 'bill_payment.field.payment_date',
|
name: 'bill_payment.field.payment_date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
accessor: 'formattedPaymentDate',
|
accessor: 'formattedPaymentDate'
|
||||||
},
|
},
|
||||||
paymentNumber: {
|
paymentNumber: {
|
||||||
name: 'bill_payment.field.payment_number',
|
name: 'bill_payment.field.payment_number',
|
||||||
@@ -115,40 +111,6 @@ export default {
|
|||||||
name: 'bill_payment.field.reference',
|
name: 'bill_payment.field.reference',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
entries: {
|
|
||||||
name: 'Entries',
|
|
||||||
accessor: 'entries',
|
|
||||||
type: 'collection',
|
|
||||||
collectionOf: 'object',
|
|
||||||
columns: {
|
|
||||||
date: {
|
|
||||||
name: 'Bill date',
|
|
||||||
accessor: 'bill.formattedBillDate',
|
|
||||||
},
|
|
||||||
billNo: {
|
|
||||||
name: 'Bill No.',
|
|
||||||
accessor: 'bill.billNo',
|
|
||||||
},
|
|
||||||
billRefNo: {
|
|
||||||
name: 'Bill Reference No.',
|
|
||||||
accessor: 'bill.referenceNo',
|
|
||||||
},
|
|
||||||
billAmount: {
|
|
||||||
name: 'Bill Amount',
|
|
||||||
accessor: 'bill.totalFormatted',
|
|
||||||
},
|
|
||||||
paidAmount: {
|
|
||||||
name: 'Paid Amount',
|
|
||||||
accessor: 'paymentAmountFormatted',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
branch: {
|
|
||||||
name: 'Branch',
|
|
||||||
type: 'text',
|
|
||||||
accessor: 'branch.name',
|
|
||||||
features: [Features.BRANCHES],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
vendorId: {
|
vendorId: {
|
||||||
@@ -212,13 +174,5 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
branchId: {
|
|
||||||
name: 'Branch',
|
|
||||||
fieldType: 'relation',
|
|
||||||
relationModel: 'Branch',
|
|
||||||
relationImportMatch: ['name', 'code'],
|
|
||||||
features: [Features.BRANCHES],
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
export default {
|
|
||||||
fields2: {
|
|
||||||
name: {
|
|
||||||
name: 'Name',
|
|
||||||
fieldType: 'text',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
columns: {},
|
|
||||||
fields: {}
|
|
||||||
};
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
import { Model, mixin } from 'objection';
|
import { Model } 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 mixin(TenantModel, [ModelSetting]) {
|
export default class Branch extends TenantModel {
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
*/
|
*/
|
||||||
@@ -171,11 +169,4 @@ export default class Branch extends mixin(TenantModel, [ModelSetting]) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Model settings.
|
|
||||||
*/
|
|
||||||
static get meta() {
|
|
||||||
return BranchMetadata;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
function StatusFieldFilterQuery(query, role) {
|
function StatusFieldFilterQuery(query, role) {
|
||||||
query.modify('filterByStatus', role.value);
|
query.modify('filterByStatus', role.value);
|
||||||
}
|
}
|
||||||
@@ -102,7 +100,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.',
|
||||||
@@ -149,18 +147,6 @@ 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: {
|
||||||
@@ -229,21 +215,5 @@ 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,7 +175,6 @@ 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 {
|
||||||
/**
|
/**
|
||||||
@@ -236,18 +235,6 @@ 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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -95,11 +95,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
customerType: {
|
|
||||||
name: 'Customer Type',
|
|
||||||
type: 'text',
|
|
||||||
accessor: 'formattedCustomerType',
|
|
||||||
},
|
|
||||||
firstName: {
|
firstName: {
|
||||||
name: 'vendor.field.first_name',
|
name: 'vendor.field.first_name',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
@@ -140,117 +135,116 @@ export default {
|
|||||||
openingBalance: {
|
openingBalance: {
|
||||||
name: 'vendor.field.opening_balance',
|
name: 'vendor.field.opening_balance',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
openingBalanceAt: {
|
openingBalanceAt: {
|
||||||
name: 'vendor.field.opening_balance_at',
|
name: 'vendor.field.opening_balance_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
printable: false,
|
printable: false
|
||||||
accessor: 'formattedOpeningBalanceAt'
|
|
||||||
},
|
},
|
||||||
currencyCode: {
|
currencyCode: {
|
||||||
name: 'vendor.field.currency',
|
name: 'vendor.field.currency',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
name: 'vendor.field.status',
|
name: 'vendor.field.status',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
note: {
|
note: {
|
||||||
name: 'vendor.field.note',
|
name: 'vendor.field.note',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
// Billing Address
|
// Billing Address
|
||||||
billingAddress1: {
|
billingAddress1: {
|
||||||
name: 'Billing Address 1',
|
name: 'Billing Address 1',
|
||||||
column: 'billing_address1',
|
column: 'billing_address1',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddress2: {
|
billingAddress2: {
|
||||||
name: 'Billing Address 2',
|
name: 'Billing Address 2',
|
||||||
column: 'billing_address2',
|
column: 'billing_address2',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressCity: {
|
billingAddressCity: {
|
||||||
name: 'Billing Address City',
|
name: 'Billing Address City',
|
||||||
column: 'billing_address_city',
|
column: 'billing_address_city',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressCountry: {
|
billingAddressCountry: {
|
||||||
name: 'Billing Address Country',
|
name: 'Billing Address Country',
|
||||||
column: 'billing_address_country',
|
column: 'billing_address_country',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressPostcode: {
|
billingAddressPostcode: {
|
||||||
name: 'Billing Address Postcode',
|
name: 'Billing Address Postcode',
|
||||||
column: 'billing_address_postcode',
|
column: 'billing_address_postcode',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressState: {
|
billingAddressState: {
|
||||||
name: 'Billing Address State',
|
name: 'Billing Address State',
|
||||||
column: 'billing_address_state',
|
column: 'billing_address_state',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
billingAddressPhone: {
|
billingAddressPhone: {
|
||||||
name: 'Billing Address Phone',
|
name: 'Billing Address Phone',
|
||||||
column: 'billing_address_phone',
|
column: 'billing_address_phone',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
// Shipping Address
|
// Shipping Address
|
||||||
shippingAddress1: {
|
shippingAddress1: {
|
||||||
name: 'Shipping Address 1',
|
name: 'Shipping Address 1',
|
||||||
column: 'shipping_address1',
|
column: 'shipping_address1',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddress2: {
|
shippingAddress2: {
|
||||||
name: 'Shipping Address 2',
|
name: 'Shipping Address 2',
|
||||||
column: 'shipping_address2',
|
column: 'shipping_address2',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressCity: {
|
shippingAddressCity: {
|
||||||
name: 'Shipping Address City',
|
name: 'Shipping Address City',
|
||||||
column: 'shipping_address_city',
|
column: 'shipping_address_city',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressCountry: {
|
shippingAddressCountry: {
|
||||||
name: 'Shipping Address Country',
|
name: 'Shipping Address Country',
|
||||||
column: 'shipping_address_country',
|
column: 'shipping_address_country',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressPostcode: {
|
shippingAddressPostcode: {
|
||||||
name: 'Shipping Address Postcode',
|
name: 'Shipping Address Postcode',
|
||||||
column: 'shipping_address_postcode',
|
column: 'shipping_address_postcode',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressPhone: {
|
shippingAddressPhone: {
|
||||||
name: 'Shipping Address Phone',
|
name: 'Shipping Address Phone',
|
||||||
column: 'shipping_address_phone',
|
column: 'shipping_address_phone',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
shippingAddressState: {
|
shippingAddressState: {
|
||||||
name: 'Shipping Address State',
|
name: 'Shipping Address State',
|
||||||
column: 'shipping_address_state',
|
column: 'shipping_address_state',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
name: 'vendor.field.created_at',
|
name: 'vendor.field.created_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
printable: false,
|
printable: false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expense - Settings.
|
* Expense - Settings.
|
||||||
*/
|
*/
|
||||||
@@ -121,12 +119,6 @@ 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: {
|
||||||
@@ -186,14 +178,6 @@ 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,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,17 +41,17 @@ export default {
|
|||||||
fieldType: 'boolean',
|
fieldType: 'boolean',
|
||||||
},
|
},
|
||||||
sell_price: {
|
sell_price: {
|
||||||
name: 'item.field.sell_price',
|
name: 'item.field.cost_price',
|
||||||
column: 'sell_price',
|
column: 'sell_price',
|
||||||
fieldType: 'number',
|
fieldType: 'number',
|
||||||
},
|
},
|
||||||
cost_price: {
|
cost_price: {
|
||||||
name: 'item.field.cost_price',
|
name: 'item.field.cost_account',
|
||||||
column: 'cost_price',
|
column: 'cost_price',
|
||||||
fieldType: 'number',
|
fieldType: 'number',
|
||||||
},
|
},
|
||||||
cost_account: {
|
cost_account: {
|
||||||
name: 'item.field.cost_account',
|
name: 'item.field.sell_account',
|
||||||
column: 'cost_account_id',
|
column: 'cost_account_id',
|
||||||
fieldType: 'relation',
|
fieldType: 'relation',
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ export default {
|
|||||||
relationEntityKey: 'slug',
|
relationEntityKey: 'slug',
|
||||||
},
|
},
|
||||||
sell_account: {
|
sell_account: {
|
||||||
name: 'item.field.sell_account',
|
name: 'item.field.sell_description',
|
||||||
column: 'sell_account_id',
|
column: 'sell_account_id',
|
||||||
fieldType: 'relation',
|
fieldType: 'relation',
|
||||||
|
|
||||||
@@ -155,24 +155,24 @@ export default {
|
|||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
sellPrice: {
|
sellPrice: {
|
||||||
name: 'item.field.sell_price',
|
|
||||||
type: 'number',
|
|
||||||
exportable: true,
|
|
||||||
},
|
|
||||||
costPrice: {
|
|
||||||
name: 'item.field.cost_price',
|
name: 'item.field.cost_price',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
},
|
},
|
||||||
costAccount: {
|
costPrice: {
|
||||||
name: 'item.field.cost_account',
|
name: 'item.field.cost_account',
|
||||||
|
type: 'number',
|
||||||
|
exportable: true,
|
||||||
|
},
|
||||||
|
costAccount: {
|
||||||
|
name: 'item.field.sell_account',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
accessor: 'costAccount.name',
|
accessor: 'costAccount.name',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
sellAccount: {
|
sellAccount: {
|
||||||
name: 'item.field.sell_account',
|
name: 'item.field.sell_description',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
accessor: 'sellAccount.name',
|
accessor: 'sellAccount.name',
|
||||||
exportable: true,
|
exportable: true,
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
importable: true,
|
importable: true,
|
||||||
|
|
||||||
exportable: true,
|
exportable: true,
|
||||||
exportFlattenOn: 'entries',
|
|
||||||
|
|
||||||
importAggregator: 'group',
|
importAggregator: 'group',
|
||||||
importAggregateOn: 'entries',
|
importAggregateOn: 'entries',
|
||||||
importAggregateBy: 'paymentReceiveNo',
|
importAggregateBy: 'paymentReceiveNo',
|
||||||
@@ -77,7 +72,7 @@ export default {
|
|||||||
amount: {
|
amount: {
|
||||||
name: 'payment_receive.field.amount',
|
name: 'payment_receive.field.amount',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
accessor: 'formattedAmount',
|
accessor: 'formattedAmount'
|
||||||
},
|
},
|
||||||
referenceNo: {
|
referenceNo: {
|
||||||
name: 'payment_receive.field.reference_no',
|
name: 'payment_receive.field.reference_no',
|
||||||
@@ -97,45 +92,11 @@ export default {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
entries: {
|
|
||||||
name: 'Entries',
|
|
||||||
accessor: 'entries',
|
|
||||||
type: 'collection',
|
|
||||||
collectionOf: 'object',
|
|
||||||
columns: {
|
|
||||||
date: {
|
|
||||||
name: 'Invoice date',
|
|
||||||
accessor: 'invoice.invoiceDateFormatted',
|
|
||||||
},
|
|
||||||
invoiceNo: {
|
|
||||||
name: 'Invoice No.',
|
|
||||||
accessor: 'invoice.invoiceNo',
|
|
||||||
},
|
|
||||||
invoiceRefNo: {
|
|
||||||
name: 'Invoice Reference No.',
|
|
||||||
accessor: 'invoice.referenceNo',
|
|
||||||
},
|
|
||||||
invoiceAmount: {
|
|
||||||
name: 'Invoice Amount',
|
|
||||||
accessor: 'invoice.totalFormatted',
|
|
||||||
},
|
|
||||||
paidAmount: {
|
|
||||||
name: 'Paid Amount',
|
|
||||||
accessor: 'paymentAmountFormatted',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created_at: {
|
created_at: {
|
||||||
name: 'payment_receive.field.created_at',
|
name: 'payment_receive.field.created_at',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
branch: {
|
|
||||||
name: 'Branch',
|
|
||||||
type: 'text',
|
|
||||||
accessor: 'branch.name',
|
|
||||||
features: [Features.BRANCHES],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
fields2: {
|
fields2: {
|
||||||
customerId: {
|
customerId: {
|
||||||
@@ -197,13 +158,5 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
branchId: {
|
|
||||||
name: 'Branch',
|
|
||||||
fieldType: 'relation',
|
|
||||||
relationModel: 'Branch',
|
|
||||||
relationImportMatch: ['name', 'code'],
|
|
||||||
features: [Features.BRANCHES],
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'estimate_date',
|
defaultFilterField: 'estimate_date',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -15,7 +13,7 @@ export default {
|
|||||||
importAggregateBy: 'estimateNumber',
|
importAggregateBy: 'estimateNumber',
|
||||||
|
|
||||||
print: {
|
print: {
|
||||||
pageTitle: 'Sale Estimates',
|
pageTitle: 'Sale Estimates'
|
||||||
},
|
},
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
@@ -144,7 +142,6 @@ export default {
|
|||||||
delivered: {
|
delivered: {
|
||||||
name: 'Delivered',
|
name: 'Delivered',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
accessor: 'isDelivered',
|
|
||||||
exportable: true,
|
exportable: true,
|
||||||
printable: false,
|
printable: false,
|
||||||
},
|
},
|
||||||
@@ -176,18 +173,6 @@ 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: {
|
||||||
@@ -266,22 +251,6 @@ 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,7 +182,6 @@ 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 {
|
||||||
@@ -222,18 +221,6 @@ 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,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'customer',
|
defaultFilterField: 'customer',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -157,7 +155,6 @@ export default {
|
|||||||
name: 'invoice.field.delivered',
|
name: 'invoice.field.delivered',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
printable: false,
|
printable: false,
|
||||||
accessor: 'isDelivered',
|
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
name: 'Entries',
|
name: 'Entries',
|
||||||
@@ -187,18 +184,6 @@ 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: {
|
||||||
@@ -282,22 +267,6 @@ 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,7 +408,6 @@ 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');
|
||||||
@@ -500,18 +499,6 @@ 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,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
defaultFilterField: 'receipt_date',
|
defaultFilterField: 'receipt_date',
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
@@ -171,18 +169,6 @@ 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: {
|
||||||
@@ -259,22 +245,6 @@ 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,7 +109,6 @@ 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: {
|
||||||
@@ -170,18 +169,6 @@ 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,5 +1,3 @@
|
|||||||
import { Features } from '@/interfaces';
|
|
||||||
|
|
||||||
function StatusFieldFilterQuery(query, role) {
|
function StatusFieldFilterQuery(query, role) {
|
||||||
query.modify('filterByStatus', role.value);
|
query.modify('filterByStatus', role.value);
|
||||||
}
|
}
|
||||||
@@ -162,18 +160,6 @@ 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: {
|
||||||
@@ -239,21 +225,5 @@ 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,7 +178,6 @@ 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: {
|
||||||
@@ -218,18 +217,6 @@ 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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
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 = !isEmpty(ruleId) ? castArray(ruleId) : [];
|
const rulesIds = castArray(ruleId);
|
||||||
|
|
||||||
if (rulesIds?.length > 0) {
|
if (!isEmpty(rulesIds)) {
|
||||||
q.whereIn('id', rulesIds);
|
q.whereIn('id', rulesIds);
|
||||||
}
|
}
|
||||||
q.withGraphFetched('conditions');
|
q.withGraphFetched('conditions');
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ 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,
|
||||||
|
|||||||
@@ -5,17 +5,11 @@ import * as R from 'ramda';
|
|||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import {
|
import { ICreditNote, ICreditNoteEditDTO, ICreditNoteNewDTO } from '@/interfaces';
|
||||||
ICreditNote,
|
|
||||||
ICreditNoteEditDTO,
|
|
||||||
ICreditNoteEntryNewDTO,
|
|
||||||
ICreditNoteNewDTO,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import ItemsEntriesService from '@/services/Items/ItemsEntriesService';
|
import ItemsEntriesService from '@/services/Items/ItemsEntriesService';
|
||||||
import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService';
|
import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService';
|
||||||
import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||||
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
||||||
import { assocItemEntriesDefaultIndex } from '../Items/utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class BaseCreditNotes {
|
export default class BaseCreditNotes {
|
||||||
@@ -49,17 +43,10 @@ export default class BaseCreditNotes {
|
|||||||
const amount = this.itemsEntriesService.getTotalItemsEntries(
|
const amount = this.itemsEntriesService.getTotalItemsEntries(
|
||||||
creditNoteDTO.entries
|
creditNoteDTO.entries
|
||||||
);
|
);
|
||||||
const entries = R.compose(
|
const entries = creditNoteDTO.entries.map((entry) => ({
|
||||||
// Associate the default index to each item entry.
|
...entry,
|
||||||
assocItemEntriesDefaultIndex,
|
referenceType: 'CreditNote',
|
||||||
|
}));
|
||||||
// Associate the reference type to credit note entries.
|
|
||||||
R.map((entry: ICreditNoteEntryNewDTO) => ({
|
|
||||||
...entry,
|
|
||||||
referenceType: 'CreditNote',
|
|
||||||
}))
|
|
||||||
)(creditNoteDTO.entries);
|
|
||||||
|
|
||||||
// Retreive the next credit note number.
|
// Retreive the next credit note number.
|
||||||
const autoNextNumber = this.getNextCreditNumber(tenantId);
|
const autoNextNumber = this.getNextCreditNumber(tenantId);
|
||||||
|
|
||||||
|
|||||||
@@ -15,17 +15,12 @@ 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,7 +48,6 @@ 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);
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
import { PostHog } from 'posthog-node';
|
|
||||||
import { Service } from 'typedi';
|
|
||||||
import { EventMessage } from 'posthog-node/src/types';
|
|
||||||
import config from '@/config';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class PosthogService {
|
|
||||||
public posthog: PostHog;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
if (config.posthog.apiKey && config.posthog.host) {
|
|
||||||
this.posthog = new PostHog(config.posthog.apiKey, {
|
|
||||||
host: config.posthog.host,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public trackEvent(event: EventMessage) {
|
|
||||||
// Cannot continue if the Posthog not configured.
|
|
||||||
if (!this.posthog) return;
|
|
||||||
|
|
||||||
this.posthog.capture(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
IAccountEventCreatedPayload,
|
|
||||||
IAccountEventEditedPayload,
|
|
||||||
IAccountEventDeletedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
ACCOUNT_CREATED,
|
|
||||||
ACCOUNT_EDITED,
|
|
||||||
ACCOUNT_DELETED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class AccountEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(
|
|
||||||
events.accounts.onCreated,
|
|
||||||
this.handleTrackAccountCreatedEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(events.accounts.onEdited, this.handleTrackEditedAccountEvent);
|
|
||||||
bus.subscribe(
|
|
||||||
events.accounts.onDeleted,
|
|
||||||
this.handleTrackDeletedAccountEvent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackAccountCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IAccountEventCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: ACCOUNT_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedAccountEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IAccountEventEditedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: ACCOUNT_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedAccountEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IAccountEventDeletedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: ACCOUNT_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import { IAuthSignedUpEventPayload } from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import { AUTH_SIGNED_UP } from '@/constants/event-tracker';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class AuthenticationEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(events.auth.signUp, this.handleTrackSignUpEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackSignUpEvent = ({
|
|
||||||
signupDTO,
|
|
||||||
user,
|
|
||||||
tenant,
|
|
||||||
}: IAuthSignedUpEventPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: user.email,
|
|
||||||
event: AUTH_SIGNED_UP,
|
|
||||||
properties: {
|
|
||||||
firstName: user.firstName,
|
|
||||||
lastName: user.lastName,
|
|
||||||
email: user.email,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
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: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
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: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
IBillPaymentEventCreatedPayload,
|
|
||||||
IBillPaymentEventEditedPayload,
|
|
||||||
IBillPaymentEventDeletedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
BILL_CREATED,
|
|
||||||
BILL_EDITED,
|
|
||||||
BILL_DELETED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class BillEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(events.bill.onCreated, this.handleTrackBillCreatedEvent);
|
|
||||||
bus.subscribe(events.bill.onEdited, this.handleTrackEditedBillEvent);
|
|
||||||
bus.subscribe(events.bill.onDeleted, this.handleTrackDeletedBillEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackBillCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IBillPaymentEventCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: BILL_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedBillEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IBillPaymentEventEditedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: BILL_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedBillEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IBillPaymentEventDeletedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: BILL_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
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: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
IExpenseCreatedPayload,
|
|
||||||
IExpenseEventEditPayload,
|
|
||||||
IExpenseEventDeletePayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
EXPENSE_CREATED,
|
|
||||||
EXPENSE_EDITED,
|
|
||||||
EXPENSE_DELETED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class ExpenseEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(
|
|
||||||
events.expenses.onCreated,
|
|
||||||
this.handleTrackExpenseCreatedEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(events.expenses.onEdited, this.handleTrackEditedExpenseEvent);
|
|
||||||
bus.subscribe(
|
|
||||||
events.expenses.onDeleted,
|
|
||||||
this.handleTrackDeletedExpenseEvent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackExpenseCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IExpenseCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: EXPENSE_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedExpenseEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IExpenseEventEditPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: EXPENSE_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedExpenseEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IExpenseEventDeletePayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: EXPENSE_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
IItemEventCreatedPayload,
|
|
||||||
IItemEventEditedPayload,
|
|
||||||
IItemEventDeletedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
ITEM_EVENT_CREATED,
|
|
||||||
ITEM_EVENT_EDITED,
|
|
||||||
ITEM_EVENT_DELETED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class ItemEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(events.item.onCreated, this.handleTrackItemCreatedEvent);
|
|
||||||
bus.subscribe(events.item.onEdited, this.handleTrackEditedItemEvent);
|
|
||||||
bus.subscribe(events.item.onDeleted, this.handleTrackDeletedItemEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackItemCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IItemEventCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: ITEM_EVENT_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedItemEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IItemEventEditedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: ITEM_EVENT_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedItemEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IItemEventDeletedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: ITEM_EVENT_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
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: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
IBillPaymentEventCreatedPayload,
|
|
||||||
IBillPaymentEditingPayload,
|
|
||||||
IBillPaymentEventDeletedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
PAYMENT_MADE_CREATED,
|
|
||||||
PAYMENT_MADE_EDITED,
|
|
||||||
PAYMENT_MADE_DELETED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class PaymentMadeEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(
|
|
||||||
events.billPayment.onCreated,
|
|
||||||
this.handleTrackPaymentMadeCreatedEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.billPayment.onEdited,
|
|
||||||
this.handleTrackEditedPaymentMadeEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.billPayment.onDeleted,
|
|
||||||
this.handleTrackDeletedPaymentMadeEvent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackPaymentMadeCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IBillPaymentEventCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: PAYMENT_MADE_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedPaymentMadeEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IBillPaymentEditingPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: PAYMENT_MADE_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedPaymentMadeEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IBillPaymentEventDeletedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: PAYMENT_MADE_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
IPaymentReceivedCreatedPayload,
|
|
||||||
IPaymentReceivedEditedPayload,
|
|
||||||
IPaymentReceivedDeletedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
PAYMENT_RECEIVED_CREATED,
|
|
||||||
PAYMENT_RECEIVED_EDITED,
|
|
||||||
PAYMENT_RECEIVED_DELETED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class PaymentReceivedEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(
|
|
||||||
events.paymentReceive.onCreated,
|
|
||||||
this.handleTrackPaymentReceivedCreatedEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.paymentReceive.onEdited,
|
|
||||||
this.handleTrackEditedPaymentReceivedEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.paymentReceive.onDeleted,
|
|
||||||
this.handleTrackDeletedPaymentReceivedEvent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackPaymentReceivedCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IPaymentReceivedCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: PAYMENT_RECEIVED_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedPaymentReceivedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IPaymentReceivedEditedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: PAYMENT_RECEIVED_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedPaymentReceivedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: IPaymentReceivedDeletedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: PAYMENT_RECEIVED_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
ISaleEstimateCreatedPayload,
|
|
||||||
ISaleEstimateEditedPayload,
|
|
||||||
ISaleEstimateDeletedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
SALE_ESTIMATE_CREATED,
|
|
||||||
SALE_ESTIMATE_EDITED,
|
|
||||||
SALE_ESTIMATE_DELETED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class SaleEstimateEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(
|
|
||||||
events.saleEstimate.onCreated,
|
|
||||||
this.handleTrackEstimateCreatedEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.saleEstimate.onEdited,
|
|
||||||
this.handleTrackEditedEstimateEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.saleEstimate.onDeleted,
|
|
||||||
this.handleTrackDeletedEstimateEvent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackEstimateCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: ISaleEstimateCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: SALE_ESTIMATE_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedEstimateEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: ISaleEstimateEditedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: SALE_ESTIMATE_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedEstimateEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: ISaleEstimateDeletedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: SALE_ESTIMATE_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import {
|
|
||||||
ISaleInvoiceCreatedPayload,
|
|
||||||
ISaleInvoiceEditedPayload,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import { PosthogService } from '../PostHog';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
SALE_INVOICE_CREATED,
|
|
||||||
SALE_INVOICE_DELETED,
|
|
||||||
SALE_INVOICE_EDITED,
|
|
||||||
} from '@/constants/event-tracker';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class SaleInvoiceEventsTracker extends EventSubscriber {
|
|
||||||
@Inject()
|
|
||||||
private posthog: PosthogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor method.
|
|
||||||
*/
|
|
||||||
public attach(bus) {
|
|
||||||
bus.subscribe(
|
|
||||||
events.saleInvoice.onCreated,
|
|
||||||
this.handleTrackInvoiceCreatedEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.saleInvoice.onEdited,
|
|
||||||
this.handleTrackEditedInvoiceEvent
|
|
||||||
);
|
|
||||||
bus.subscribe(
|
|
||||||
events.saleInvoice.onDeleted,
|
|
||||||
this.handleTrackDeletedInvoiceEvent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleTrackInvoiceCreatedEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: ISaleInvoiceCreatedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: SALE_INVOICE_CREATED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackEditedInvoiceEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: ISaleInvoiceEditedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: SALE_INVOICE_EDITED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
private handleTrackDeletedInvoiceEvent = ({
|
|
||||||
tenantId,
|
|
||||||
}: ISaleInvoiceEditedPayload) => {
|
|
||||||
this.posthog.trackEvent({
|
|
||||||
distinctId: `tenant-${tenantId}`,
|
|
||||||
event: SALE_INVOICE_DELETED,
|
|
||||||
properties: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
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: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
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: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
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: {},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { SaleInvoiceEventsTracker } from './SaleInvoicesEventsTracker';
|
|
||||||
import { SaleEstimateEventsTracker } from './SaleEstimateEventsTracker';
|
|
||||||
import { PaymentMadeEventsTracker } from './PaymentMadeEventsTracker';
|
|
||||||
import { PaymentReceivedEventsTracker } from './PaymentReceivedEventsTracker';
|
|
||||||
import { BillEventsTracker } from './BillEventsTracker';
|
|
||||||
import { ExpenseEventsTracker } from './ExpenseEventsTracker';
|
|
||||||
import { AccountEventsTracker } from './AccountEventsTracker';
|
|
||||||
import { AuthenticationEventsTracker } from './AuthenticationEventsTracker';
|
|
||||||
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 = [
|
|
||||||
SaleInvoiceEventsTracker,
|
|
||||||
SaleEstimateEventsTracker,
|
|
||||||
PaymentMadeEventsTracker,
|
|
||||||
PaymentReceivedEventsTracker,
|
|
||||||
BillEventsTracker,
|
|
||||||
AccountEventsTracker,
|
|
||||||
ExpenseEventsTracker,
|
|
||||||
AuthenticationEventsTracker,
|
|
||||||
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, SUPPORTED_EXPENSE_PAYMENT_ACCOUNT_TYPES } from '../constants';
|
import { ERRORS } from '../constants';
|
||||||
import {
|
import {
|
||||||
IAccount,
|
IAccount,
|
||||||
IExpense,
|
IExpense,
|
||||||
@@ -79,9 +79,7 @@ export class CommandExpenseValidator {
|
|||||||
* @throws {ServiceError}
|
* @throws {ServiceError}
|
||||||
*/
|
*/
|
||||||
public validatePaymentAccountType = (paymentAccount: number[]) => {
|
public validatePaymentAccountType = (paymentAccount: number[]) => {
|
||||||
if (
|
if (!paymentAccount.isParentType(ACCOUNT_PARENT_TYPE.CURRENT_ASSET)) {
|
||||||
!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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
||||||
import { TenantMetadata } from '@/system/models';
|
import { TenantMetadata } from '@/system/models';
|
||||||
import { assocItemEntriesDefaultIndex } from '@/services/Items/utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExpenseDTOTransformer {
|
export class ExpenseDTOTransformer {
|
||||||
@@ -41,8 +40,8 @@ export class ExpenseDTOTransformer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapping expense DTO to model.
|
* Mapping expense DTO to model.
|
||||||
* @param {IExpenseDTO} expenseDTO
|
* @param {IExpenseDTO} expenseDTO
|
||||||
* @param {ISystemUser} authorizedUser
|
* @param {ISystemUser} authorizedUser
|
||||||
* @return {IExpense}
|
* @return {IExpense}
|
||||||
*/
|
*/
|
||||||
private expenseDTOToModel(
|
private expenseDTOToModel(
|
||||||
@@ -53,14 +52,9 @@ export class ExpenseDTOTransformer {
|
|||||||
const landedCostAmount = this.getExpenseLandedCostAmount(expenseDTO);
|
const landedCostAmount = this.getExpenseLandedCostAmount(expenseDTO);
|
||||||
const totalAmount = this.getExpenseCategoriesTotal(expenseDTO.categories);
|
const totalAmount = this.getExpenseCategoriesTotal(expenseDTO.categories);
|
||||||
|
|
||||||
const categories = R.compose(
|
|
||||||
// Associate the default index to categories lines.
|
|
||||||
assocItemEntriesDefaultIndex
|
|
||||||
)(expenseDTO.categories || []);
|
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
|
categories: [],
|
||||||
...omit(expenseDTO, ['publish', 'attachments']),
|
...omit(expenseDTO, ['publish', 'attachments']),
|
||||||
categories,
|
|
||||||
totalAmount,
|
totalAmount,
|
||||||
landedCostAmount,
|
landedCostAmount,
|
||||||
paymentDate: moment(expenseDTO.paymentDate).toMySqlDateTime(),
|
paymentDate: moment(expenseDTO.paymentDate).toMySqlDateTime(),
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ 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);
|
||||||
|
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
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);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
106
packages/server/src/services/Expenses/ExpenseGLEntries.ts
Normal file
106
packages/server/src/services/Expenses/ExpenseGLEntries.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
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 './ExpenseGLEntriesService';
|
import { ExpenseGLEntries } from './ExpenseGLEntries';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExpenseGLEntriesStorage {
|
export class ExpenseGLEntriesStorage {
|
||||||
@@ -12,6 +12,9 @@ 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
|
||||||
@@ -23,12 +26,15 @@ 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 = await this.expenseGLEntries.getExpenseLedgerById(
|
const expenseLedger = this.expenseGLEntries.getExpenseLedger(expense);
|
||||||
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,16 +15,12 @@ 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,5 +1,3 @@
|
|||||||
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
|
|
||||||
|
|
||||||
export const DEFAULT_VIEW_COLUMNS = [];
|
export const DEFAULT_VIEW_COLUMNS = [];
|
||||||
export const DEFAULT_VIEWS = [
|
export const DEFAULT_VIEWS = [
|
||||||
{
|
{
|
||||||
@@ -78,12 +76,3 @@ 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,
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
import { Service } from 'typedi';
|
|
||||||
import { AsyncLocalStorage } from 'async_hooks';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class ExportAls {
|
|
||||||
private als: AsyncLocalStorage<Map<string, any>>;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.als = new AsyncLocalStorage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a callback function within the context of a new AsyncLocalStorage store.
|
|
||||||
* @param callback The function to be executed within the AsyncLocalStorage context.
|
|
||||||
* @returns The result of the callback function.
|
|
||||||
*/
|
|
||||||
public run<T>(callback: () => T): T {
|
|
||||||
return this.als.run<T>(new Map(), () => {
|
|
||||||
this.markAsExport();
|
|
||||||
|
|
||||||
return callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the current AsyncLocalStorage store.
|
|
||||||
* @returns The current store or undefined if not in a valid context.
|
|
||||||
*/
|
|
||||||
public getStore(): Map<string, any> | undefined {
|
|
||||||
return this.als.getStore();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks the current context as an export operation.
|
|
||||||
* @param flag Boolean flag to set or unset the export status. Defaults to true.
|
|
||||||
*/
|
|
||||||
public markAsExport(flag: boolean = true): void {
|
|
||||||
const store = this.getStore();
|
|
||||||
store?.set('isExport', flag);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Checks if the current context is an export operation.
|
|
||||||
* @returns {boolean} True if the context is an export operation, false otherwise.
|
|
||||||
*/
|
|
||||||
public get isExport(): boolean {
|
|
||||||
return !!this.getStore()?.get('isExport');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,6 @@ import { Errors, ExportFormat } from './common';
|
|||||||
import { IModelMeta, IModelMetaColumn } from '@/interfaces';
|
import { IModelMeta, IModelMetaColumn } from '@/interfaces';
|
||||||
import { flatDataCollections, getDataAccessor } from './utils';
|
import { flatDataCollections, getDataAccessor } from './utils';
|
||||||
import { ExportPdf } from './ExportPdf';
|
import { ExportPdf } from './ExportPdf';
|
||||||
import { ExportAls } from './ExportAls';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExportResourceService {
|
export class ExportResourceService {
|
||||||
@@ -23,43 +22,20 @@ export class ExportResourceService {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private exportPdf: ExportPdf;
|
private exportPdf: ExportPdf;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private exportAls: ExportAls;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {string} resourceName
|
|
||||||
* @param {ExportFormat} format
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
public async export(
|
|
||||||
tenantId: number,
|
|
||||||
resourceName: string,
|
|
||||||
format: ExportFormat = ExportFormat.Csv
|
|
||||||
) {
|
|
||||||
return this.exportAls.run(() =>
|
|
||||||
this.exportAlsRun(tenantId, resourceName, format)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports the given resource data through csv, xlsx or pdf.
|
* Exports the given resource data through csv, xlsx or pdf.
|
||||||
* @param {number} tenantId - Tenant id.
|
* @param {number} tenantId - Tenant id.
|
||||||
* @param {string} resourceName - Resource name.
|
* @param {string} resourceName - Resource name.
|
||||||
* @param {ExportFormat} format - File format.
|
* @param {ExportFormat} format - File format.
|
||||||
*/
|
*/
|
||||||
public async exportAlsRun(
|
public async export(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
resourceName: string,
|
resourceName: string,
|
||||||
format: ExportFormat = ExportFormat.Csv
|
format: ExportFormat = ExportFormat.Csv
|
||||||
) {
|
) {
|
||||||
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);
|
||||||
@@ -67,7 +43,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(resourceColumns);
|
const exportableColumns = this.getExportableColumns(resourceMeta);
|
||||||
const workbook = this.createWorkbook(transformed, exportableColumns);
|
const workbook = this.createWorkbook(transformed, exportableColumns);
|
||||||
|
|
||||||
return this.exportWorkbook(workbook, format);
|
return this.exportWorkbook(workbook, format);
|
||||||
@@ -146,7 +122,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(resourceColumns: any) {
|
private getExportableColumns(resourceMeta: IModelMeta) {
|
||||||
const processColumns = (
|
const processColumns = (
|
||||||
columns: { [key: string]: IModelMetaColumn },
|
columns: { [key: string]: IModelMetaColumn },
|
||||||
parent = ''
|
parent = ''
|
||||||
@@ -169,7 +145,7 @@ export class ExportResourceService {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return processColumns(resourceColumns);
|
return processColumns(resourceMeta.columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPrintableColumns(resourceMeta: IModelMeta) {
|
private getPrintableColumns(resourceMeta: IModelMeta) {
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
export const EXPORT_SIZE_LIMIT = 9999999;
|
export const EXPORT_SIZE_LIMIT = 9999999;
|
||||||
export const EXPORT_DTE_FORMAT = 'YYYY-MM-DD';
|
|
||||||
@@ -8,7 +8,6 @@ export class ImportAls {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.als = new AsyncLocalStorage();
|
this.als = new AsyncLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a callback function within the context of a new AsyncLocalStorage store.
|
* Runs a callback function within the context of a new AsyncLocalStorage store.
|
||||||
* @param callback The function to be executed within the AsyncLocalStorage context.
|
* @param callback The function to be executed within the AsyncLocalStorage context.
|
||||||
@@ -83,7 +82,7 @@ export class ImportAls {
|
|||||||
* Checks if the current context is an import operation.
|
* Checks if the current context is an import operation.
|
||||||
* @returns {boolean} True if the context is an import operation, false otherwise.
|
* @returns {boolean} True if the context is an import operation, false otherwise.
|
||||||
*/
|
*/
|
||||||
public get isImport(): boolean {
|
public isImport(): boolean {
|
||||||
return !!this.getStore()?.get('isImport');
|
return !!this.getStore()?.get('isImport');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +90,7 @@ export class ImportAls {
|
|||||||
* Checks if the current context is an import commit operation.
|
* Checks if the current context is an import commit operation.
|
||||||
* @returns {boolean} True if the context is an import commit operation, false otherwise.
|
* @returns {boolean} True if the context is an import commit operation, false otherwise.
|
||||||
*/
|
*/
|
||||||
public get isImportCommit(): boolean {
|
public isImportCommit(): boolean {
|
||||||
return !!this.getStore()?.get('isImportCommit');
|
return !!this.getStore()?.get('isImportCommit');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +98,7 @@ export class ImportAls {
|
|||||||
* Checks if the current context is an import preview operation.
|
* Checks if the current context is an import preview operation.
|
||||||
* @returns {boolean} True if the context is an import preview operation, false otherwise.
|
* @returns {boolean} True if the context is an import preview operation, false otherwise.
|
||||||
*/
|
*/
|
||||||
public get isImportPreview(): boolean {
|
public isImportPreview(): boolean {
|
||||||
return !!this.getStore()?.get('isImportPreview');
|
return !!this.getStore()?.get('isImportPreview');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import XLSX from 'xlsx';
|
||||||
import bluebird from 'bluebird';
|
import bluebird from 'bluebird';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
@@ -11,7 +12,11 @@ import {
|
|||||||
ImportableContext,
|
ImportableContext,
|
||||||
} from './interfaces';
|
} from './interfaces';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { getUniqueImportableValue, trimObject } from './_utils';
|
import {
|
||||||
|
convertMappingsToObject,
|
||||||
|
getUniqueImportableValue,
|
||||||
|
trimObject,
|
||||||
|
} from './_utils';
|
||||||
import { ImportableResources } from './ImportableResources';
|
import { ImportableResources } from './ImportableResources';
|
||||||
import ResourceService from '../Resource/ResourceService';
|
import ResourceService from '../Resource/ResourceService';
|
||||||
import { Import } from '@/system/models';
|
import { Import } from '@/system/models';
|
||||||
@@ -26,7 +31,22 @@ export class ImportFileCommon {
|
|||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private resource: ResourceService;
|
private resource: ResourceService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps the columns of the imported data based on the provided mapping attributes.
|
||||||
|
* @param {Record<string, any>[]} body - The array of data objects to map.
|
||||||
|
* @param {ImportMappingAttr[]} map - The mapping attributes.
|
||||||
|
* @returns {Record<string, any>[]} - The mapped data objects.
|
||||||
|
*/
|
||||||
|
public parseXlsxSheet(buffer: Buffer): Record<string, unknown>[] {
|
||||||
|
const workbook = XLSX.read(buffer, { type: 'buffer', raw: true });
|
||||||
|
|
||||||
|
const firstSheetName = workbook.SheetNames[0];
|
||||||
|
const worksheet = workbook.Sheets[firstSheetName];
|
||||||
|
|
||||||
|
return XLSX.utils.sheet_to_json(worksheet, {});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imports the given parsed data to the resource storage through registered importable service.
|
* Imports the given parsed data to the resource storage through registered importable service.
|
||||||
* @param {number} tenantId -
|
* @param {number} tenantId -
|
||||||
@@ -65,11 +85,14 @@ export class ImportFileCommon {
|
|||||||
rowNumber,
|
rowNumber,
|
||||||
uniqueValue,
|
uniqueValue,
|
||||||
};
|
};
|
||||||
|
const mappingSettings = convertMappingsToObject(importFile.columnsParsed);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Validate the DTO object before passing it to the service layer.
|
// Validate the DTO object before passing it to the service layer.
|
||||||
await this.importFileValidator.validateData(
|
await this.importFileValidator.validateData(
|
||||||
resourceFields,
|
resourceFields,
|
||||||
transformedDTO
|
transformedDTO,
|
||||||
|
mappingSettings
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
// Run the importable function and listen to the errors.
|
// Run the importable function and listen to the errors.
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import { ImportInsertError, ResourceMetaFieldsMap } from './interfaces';
|
import {
|
||||||
|
ImportInsertError,
|
||||||
|
ImportMappingAttr,
|
||||||
|
ResourceMetaFieldsMap,
|
||||||
|
} from './interfaces';
|
||||||
import { ERRORS, convertFieldsToYupValidation } from './_utils';
|
import { ERRORS, convertFieldsToYupValidation } from './_utils';
|
||||||
import { IModelMeta } from '@/interfaces';
|
import { IModelMeta } from '@/interfaces';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
@@ -24,9 +28,13 @@ export class ImportFileDataValidator {
|
|||||||
*/
|
*/
|
||||||
public async validateData(
|
public async validateData(
|
||||||
importableFields: ResourceMetaFieldsMap,
|
importableFields: ResourceMetaFieldsMap,
|
||||||
data: Record<string, any>
|
data: Record<string, any>,
|
||||||
|
mappingSettings: Record<string, ImportMappingAttr> = {}
|
||||||
): Promise<void | ImportInsertError[]> {
|
): Promise<void | ImportInsertError[]> {
|
||||||
const YupSchema = convertFieldsToYupValidation(importableFields);
|
const YupSchema = convertFieldsToYupValidation(
|
||||||
|
importableFields,
|
||||||
|
mappingSettings
|
||||||
|
);
|
||||||
const _data = { ...data };
|
const _data = { ...data };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ 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);
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,18 @@ import { Inject, Service } from 'typedi';
|
|||||||
import { chain } from 'lodash';
|
import { chain } from 'lodash';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { ERRORS, getUnmappedSheetColumns, readImportFile } from './_utils';
|
import {
|
||||||
|
ERRORS,
|
||||||
|
getSheetColumns,
|
||||||
|
getUnmappedSheetColumns,
|
||||||
|
readImportFile,
|
||||||
|
} from './_utils';
|
||||||
import { ImportFileCommon } from './ImportFileCommon';
|
import { ImportFileCommon } from './ImportFileCommon';
|
||||||
import { ImportFileDataTransformer } from './ImportFileDataTransformer';
|
import { ImportFileDataTransformer } from './ImportFileDataTransformer';
|
||||||
import ResourceService from '../Resource/ResourceService';
|
import ResourceService from '../Resource/ResourceService';
|
||||||
import UnitOfWork from '../UnitOfWork';
|
import UnitOfWork from '../UnitOfWork';
|
||||||
import { ImportFilePreviewPOJO } from './interfaces';
|
import { ImportFilePreviewPOJO } from './interfaces';
|
||||||
import { Import } from '@/system/models';
|
import { Import } from '@/system/models';
|
||||||
import { parseSheetData } from './sheet_utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ImportFileProcess {
|
export class ImportFileProcess {
|
||||||
@@ -45,10 +49,10 @@ export class ImportFileProcess {
|
|||||||
if (!importFile.isMapped) {
|
if (!importFile.isMapped) {
|
||||||
throw new ServiceError(ERRORS.IMPORT_FILE_NOT_MAPPED);
|
throw new ServiceError(ERRORS.IMPORT_FILE_NOT_MAPPED);
|
||||||
}
|
}
|
||||||
// Read the imported file and parse the given buffer to get columns
|
// Read the imported file.
|
||||||
// and sheet data in json format.
|
|
||||||
const buffer = await readImportFile(importFile.filename);
|
const buffer = await readImportFile(importFile.filename);
|
||||||
const [sheetData, sheetColumns] = parseSheetData(buffer);
|
const sheetData = this.importCommon.parseXlsxSheet(buffer);
|
||||||
|
const header = getSheetColumns(sheetData);
|
||||||
|
|
||||||
const resource = importFile.resource;
|
const resource = importFile.resource;
|
||||||
const resourceFields = this.resource.getResourceFields2(tenantId, resource);
|
const resourceFields = this.resource.getResourceFields2(tenantId, resource);
|
||||||
@@ -83,7 +87,7 @@ export class ImportFileProcess {
|
|||||||
.flatten()
|
.flatten()
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
const unmappedColumns = getUnmappedSheetColumns(sheetColumns, mapping);
|
const unmappedColumns = getUnmappedSheetColumns(header, mapping);
|
||||||
const totalCount = allData.length;
|
const totalCount = allData.length;
|
||||||
|
|
||||||
const createdCount = successedImport.length;
|
const createdCount = successedImport.length;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import { ImportFileCommon } from './ImportFileCommon';
|
|||||||
import { ImportFileDataValidator } from './ImportFileDataValidator';
|
import { ImportFileDataValidator } from './ImportFileDataValidator';
|
||||||
import { ImportFileUploadPOJO } from './interfaces';
|
import { ImportFileUploadPOJO } from './interfaces';
|
||||||
import { Import } from '@/system/models';
|
import { Import } from '@/system/models';
|
||||||
import { parseSheetData } from './sheet_utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ImportFileUploadService {
|
export class ImportFileUploadService {
|
||||||
@@ -78,12 +77,14 @@ export class ImportFileUploadService {
|
|||||||
const buffer = await readImportFile(filename);
|
const buffer = await readImportFile(filename);
|
||||||
|
|
||||||
// Parse the buffer file to array data.
|
// Parse the buffer file to array data.
|
||||||
const [sheetData, sheetColumns] = parseSheetData(buffer);
|
const sheetData = this.importFileCommon.parseXlsxSheet(buffer);
|
||||||
const coumnsStringified = JSON.stringify(sheetColumns);
|
|
||||||
|
|
||||||
// Throws service error if the sheet data is empty.
|
// Throws service error if the sheet data is empty.
|
||||||
validateSheetEmpty(sheetData);
|
validateSheetEmpty(sheetData);
|
||||||
|
|
||||||
|
const sheetColumns = this.importFileCommon.parseSheetColumns(sheetData);
|
||||||
|
const coumnsStringified = JSON.stringify(sheetColumns);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Validates the params Yup schema.
|
// Validates the params Yup schema.
|
||||||
await this.importFileCommon.validateParamsSchema(resource, params);
|
await this.importFileCommon.validateParamsSchema(resource, params);
|
||||||
|
|||||||
@@ -17,9 +17,10 @@ import {
|
|||||||
head,
|
head,
|
||||||
split,
|
split,
|
||||||
last,
|
last,
|
||||||
|
set,
|
||||||
} from 'lodash';
|
} from 'lodash';
|
||||||
import pluralize from 'pluralize';
|
import pluralize from 'pluralize';
|
||||||
import { ResourceMetaFieldsMap } from './interfaces';
|
import { ImportMappingAttr, ResourceMetaFieldsMap } from './interfaces';
|
||||||
import { IModelMetaField, IModelMetaField2 } from '@/interfaces';
|
import { IModelMetaField, IModelMetaField2 } from '@/interfaces';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { multiNumberParse } from '@/utils/multi-number-parse';
|
import { multiNumberParse } from '@/utils/multi-number-parse';
|
||||||
@@ -58,11 +59,19 @@ export function trimObject(obj: Record<string, string | number>) {
|
|||||||
* @param {ResourceMetaFieldsMap} fields
|
* @param {ResourceMetaFieldsMap} fields
|
||||||
* @returns {Yup}
|
* @returns {Yup}
|
||||||
*/
|
*/
|
||||||
export const convertFieldsToYupValidation = (fields: ResourceMetaFieldsMap) => {
|
export const convertFieldsToYupValidation = (
|
||||||
|
fields: ResourceMetaFieldsMap,
|
||||||
|
parentFieldName: string = '',
|
||||||
|
mappingSettings: Record<string, ImportMappingAttr> = {}
|
||||||
|
) => {
|
||||||
const yupSchema = {};
|
const yupSchema = {};
|
||||||
|
|
||||||
Object.keys(fields).forEach((fieldName: string) => {
|
Object.keys(fields).forEach((fieldName: string) => {
|
||||||
const field = fields[fieldName] as IModelMetaField;
|
const field = fields[fieldName] as IModelMetaField;
|
||||||
|
const fieldPath = parentFieldName
|
||||||
|
? `${parentFieldName}.${fieldName}`
|
||||||
|
: fieldName;
|
||||||
|
|
||||||
let fieldSchema;
|
let fieldSchema;
|
||||||
fieldSchema = Yup.string().label(field.name);
|
fieldSchema = Yup.string().label(field.name);
|
||||||
|
|
||||||
@@ -105,13 +114,23 @@ export const convertFieldsToYupValidation = (fields: ResourceMetaFieldsMap) => {
|
|||||||
if (!val) {
|
if (!val) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return moment(val, 'YYYY-MM-DD', true).isValid();
|
const fieldDateFormat =
|
||||||
|
(get(
|
||||||
|
mappingSettings,
|
||||||
|
`${fieldPath}.dateFormat`
|
||||||
|
) as unknown as string) || 'YYYY-MM-DD';
|
||||||
|
|
||||||
|
return moment(val, fieldDateFormat, true).isValid();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else if (field.fieldType === 'url') {
|
} else if (field.fieldType === 'url') {
|
||||||
fieldSchema = fieldSchema.url();
|
fieldSchema = fieldSchema.url();
|
||||||
} else if (field.fieldType === 'collection') {
|
} else if (field.fieldType === 'collection') {
|
||||||
const nestedFieldShema = convertFieldsToYupValidation(field.fields);
|
const nestedFieldShema = convertFieldsToYupValidation(
|
||||||
|
field.fields,
|
||||||
|
field.name,
|
||||||
|
mappingSettings
|
||||||
|
);
|
||||||
fieldSchema = Yup.array().label(field.name);
|
fieldSchema = Yup.array().label(field.name);
|
||||||
|
|
||||||
if (!isUndefined(field.collectionMaxLength)) {
|
if (!isUndefined(field.collectionMaxLength)) {
|
||||||
@@ -258,6 +277,7 @@ export const getResourceColumns = (resourceColumns: {
|
|||||||
]) => {
|
]) => {
|
||||||
const extra: Record<string, any> = {};
|
const extra: Record<string, any> = {};
|
||||||
const key = fieldKey;
|
const key = fieldKey;
|
||||||
|
const type = field.fieldType;
|
||||||
|
|
||||||
if (group) {
|
if (group) {
|
||||||
extra.group = group;
|
extra.group = group;
|
||||||
@@ -270,6 +290,7 @@ export const getResourceColumns = (resourceColumns: {
|
|||||||
name,
|
name,
|
||||||
required,
|
required,
|
||||||
hint: importHint,
|
hint: importHint,
|
||||||
|
type,
|
||||||
order,
|
order,
|
||||||
...extra,
|
...extra,
|
||||||
};
|
};
|
||||||
@@ -322,6 +343,8 @@ export const valueParser =
|
|||||||
});
|
});
|
||||||
const result = await relationQuery.first();
|
const result = await relationQuery.first();
|
||||||
_value = get(result, 'id');
|
_value = get(result, 'id');
|
||||||
|
} else if (field.fieldType === 'date') {
|
||||||
|
|
||||||
} else if (field.fieldType === 'collection') {
|
} else if (field.fieldType === 'collection') {
|
||||||
const ObjectFieldKey = key.includes('.') ? key.split('.')[1] : key;
|
const ObjectFieldKey = key.includes('.') ? key.split('.')[1] : key;
|
||||||
const _valueParser = valueParser(fields, tenantModels);
|
const _valueParser = valueParser(fields, tenantModels);
|
||||||
@@ -433,8 +456,8 @@ export const getMapToPath = (to: string, group = '') =>
|
|||||||
group ? `${group}.${to}` : to;
|
group ? `${group}.${to}` : to;
|
||||||
|
|
||||||
export const getImportsStoragePath = () => {
|
export const getImportsStoragePath = () => {
|
||||||
return path.join(global.__storage_dir, `/imports`);
|
return path.join(global.__storage_dir, `/imports`);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the imported file from the storage and database.
|
* Deletes the imported file from the storage and database.
|
||||||
@@ -457,3 +480,19 @@ export const readImportFile = (filename: string) => {
|
|||||||
|
|
||||||
return fs.readFile(`${filePath}/${filename}`);
|
return fs.readFile(`${filePath}/${filename}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of mapping objects to a structured object.
|
||||||
|
* @param {Array<Object>} mappings - Array of mapping objects.
|
||||||
|
* @returns {Object} - Structured object based on the mappings.
|
||||||
|
*/
|
||||||
|
export const convertMappingsToObject = (mappings) => {
|
||||||
|
return mappings.reduce((acc, mapping) => {
|
||||||
|
const { to, group } = mapping;
|
||||||
|
const key = group ? `['${group}.${to}']` : to;
|
||||||
|
|
||||||
|
set(acc, key, mapping);
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
import XLSX from 'xlsx';
|
|
||||||
import { first } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given sheet buffer to worksheet.
|
|
||||||
* @param {Buffer} buffer
|
|
||||||
* @returns {XLSX.WorkSheet}
|
|
||||||
*/
|
|
||||||
export function parseFirstSheet(buffer: Buffer): XLSX.WorkSheet {
|
|
||||||
const workbook = XLSX.read(buffer, { type: 'buffer', raw: true });
|
|
||||||
|
|
||||||
const firstSheetName = workbook.SheetNames[0];
|
|
||||||
const worksheet = workbook.Sheets[firstSheetName];
|
|
||||||
|
|
||||||
return worksheet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the given worksheet to columns.
|
|
||||||
* @param {XLSX.WorkSheet} worksheet
|
|
||||||
* @returns {Array<string>}
|
|
||||||
*/
|
|
||||||
export function extractSheetColumns(worksheet: XLSX.WorkSheet): Array<string> {
|
|
||||||
// By default, sheet_to_json scans the first row and uses the values as headers.
|
|
||||||
// With the header: 1 option, the function exports an array of arrays of values.
|
|
||||||
const sheetCells = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
|
|
||||||
const sheetCols = first(sheetCells) as Array<string>;
|
|
||||||
|
|
||||||
return sheetCols.filter((col) => col);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given worksheet to json values. the keys are columns labels.
|
|
||||||
* @param {XLSX.WorkSheet} worksheet
|
|
||||||
* @returns {Array<Record<string, string>>}
|
|
||||||
*/
|
|
||||||
export function parseSheetToJson(
|
|
||||||
worksheet: XLSX.WorkSheet
|
|
||||||
): Array<Record<string, string>> {
|
|
||||||
return XLSX.utils.sheet_to_json(worksheet, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given sheet buffer then retrieves the sheet data and columns.
|
|
||||||
* @param {Buffer} buffer
|
|
||||||
*/
|
|
||||||
export function parseSheetData(
|
|
||||||
buffer: Buffer
|
|
||||||
): [Array<Record<string, string>>, string[]] {
|
|
||||||
const worksheet = parseFirstSheet(buffer);
|
|
||||||
|
|
||||||
const columns = extractSheetColumns(worksheet);
|
|
||||||
const data = parseSheetToJson(worksheet);
|
|
||||||
|
|
||||||
return [data, columns];
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { IItemEntry } from '@/interfaces';
|
|
||||||
import { isNull, isUndefined } from 'lodash';
|
|
||||||
|
|
||||||
export function assocItemEntriesDefaultIndex<T>(
|
|
||||||
entries: Array<T & { index?: number }>
|
|
||||||
): Array<T & { index: number }> {
|
|
||||||
return entries.map((entry, index) => {
|
|
||||||
return {
|
|
||||||
index:
|
|
||||||
isUndefined(entry.index) || isNull(entry.index)
|
|
||||||
? index + 1
|
|
||||||
: entry.index,
|
|
||||||
...entry,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -18,8 +18,6 @@ import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
|||||||
import { CommandManualJournalValidators } from './CommandManualJournalValidators';
|
import { CommandManualJournalValidators } from './CommandManualJournalValidators';
|
||||||
import { AutoIncrementManualJournal } from './AutoIncrementManualJournal';
|
import { AutoIncrementManualJournal } from './AutoIncrementManualJournal';
|
||||||
import { ManualJournalBranchesDTOTransformer } from '@/services/Branches/Integrations/ManualJournals/ManualJournalDTOTransformer';
|
import { ManualJournalBranchesDTOTransformer } from '@/services/Branches/Integrations/ManualJournals/ManualJournalDTOTransformer';
|
||||||
import { assocItemEntriesDefaultIndex } from '../Items/utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class CreateManualJournalService {
|
export class CreateManualJournalService {
|
||||||
@Inject()
|
@Inject()
|
||||||
@@ -60,22 +58,16 @@ export class CreateManualJournalService {
|
|||||||
// The manual or auto-increment journal number.
|
// The manual or auto-increment journal number.
|
||||||
const journalNumber = manualJournalDTO.journalNumber || autoNextNumber;
|
const journalNumber = manualJournalDTO.journalNumber || autoNextNumber;
|
||||||
|
|
||||||
const entries = R.compose(
|
|
||||||
// Associate the default index to each item entry.
|
|
||||||
assocItemEntriesDefaultIndex
|
|
||||||
)(manualJournalDTO.entries);
|
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
...omit(manualJournalDTO, ['publish', 'attachments']),
|
...omit(manualJournalDTO, ['publish', 'attachments']),
|
||||||
...(manualJournalDTO.publish
|
...(manualJournalDTO.publish
|
||||||
? { publishedAt: moment().toMySqlDateTime() }
|
? { publishedAt: moment().toMySqlDateTime() }
|
||||||
: {}),
|
: {}),
|
||||||
amount,
|
amount,
|
||||||
date,
|
|
||||||
currencyCode: manualJournalDTO.currencyCode || baseCurrency,
|
currencyCode: manualJournalDTO.currencyCode || baseCurrency,
|
||||||
exchangeRate: manualJournalDTO.exchangeRate || 1,
|
exchangeRate: manualJournalDTO.exchangeRate || 1,
|
||||||
|
date,
|
||||||
journalNumber,
|
journalNumber,
|
||||||
entries,
|
|
||||||
userId: authorizedUser.id,
|
userId: authorizedUser.id,
|
||||||
};
|
};
|
||||||
return R.compose(
|
return R.compose(
|
||||||
|
|||||||
@@ -14,17 +14,12 @@ export class BillPaymentExportable extends Exportable {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public exportable(tenantId: number, query: any) {
|
public exportable(tenantId: number, query: any) {
|
||||||
const filterQuery = (builder) => {
|
|
||||||
builder.withGraphFetched('entries.bill');
|
|
||||||
builder.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 any;
|
} as any;
|
||||||
|
|
||||||
return this.billPaymentsApplication
|
return this.billPaymentsApplication
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import * as R from 'ramda';
|
|||||||
import { omit, sumBy } from 'lodash';
|
import { omit, sumBy } from 'lodash';
|
||||||
import { IBillPayment, IBillPaymentDTO, IVendor } from '@/interfaces';
|
import { IBillPayment, IBillPaymentDTO, IVendor } from '@/interfaces';
|
||||||
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
||||||
import { assocItemEntriesDefaultIndex } from '@/services/Items/utils';
|
|
||||||
import { formatDateFields } from '@/utils';
|
import { formatDateFields } from '@/utils';
|
||||||
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class CommandBillPaymentDTOTransformer {
|
export class CommandBillPaymentDTOTransformer {
|
||||||
@@ -27,12 +27,6 @@ export class CommandBillPaymentDTOTransformer {
|
|||||||
const amount =
|
const amount =
|
||||||
billPaymentDTO.amount ?? sumBy(billPaymentDTO.entries, 'paymentAmount');
|
billPaymentDTO.amount ?? sumBy(billPaymentDTO.entries, 'paymentAmount');
|
||||||
|
|
||||||
// Associate the default index to each item entry.
|
|
||||||
const entries = R.compose(
|
|
||||||
// Associate the default index to payment entries.
|
|
||||||
assocItemEntriesDefaultIndex
|
|
||||||
)(billPaymentDTO.entries);
|
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
...formatDateFields(omit(billPaymentDTO, ['attachments']), [
|
...formatDateFields(omit(billPaymentDTO, ['attachments']), [
|
||||||
'paymentDate',
|
'paymentDate',
|
||||||
@@ -40,7 +34,7 @@ export class CommandBillPaymentDTOTransformer {
|
|||||||
amount,
|
amount,
|
||||||
currencyCode: vendor.currencyCode,
|
currencyCode: vendor.currencyCode,
|
||||||
exchangeRate: billPaymentDTO.exchangeRate || 1,
|
exchangeRate: billPaymentDTO.exchangeRate || 1,
|
||||||
entries,
|
entries: billPaymentDTO.entries,
|
||||||
};
|
};
|
||||||
return R.compose(
|
return R.compose(
|
||||||
this.branchDTOTransform.transformDTO<IBillPayment>(tenantId)
|
this.branchDTOTransform.transformDTO<IBillPayment>(tenantId)
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ export class GetBillPayments {
|
|||||||
builder.withGraphFetched('paymentAccount');
|
builder.withGraphFetched('paymentAccount');
|
||||||
|
|
||||||
dynamicList.buildQuery()(builder);
|
dynamicList.buildQuery()(builder);
|
||||||
filter?.filterQuery && filter?.filterQuery(builder);
|
|
||||||
})
|
})
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
.pagination(filter.page - 1, filter.pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import moment from 'moment';
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import composeAsync from 'async/compose';
|
import composeAsync from 'async/compose';
|
||||||
import { assocDepthLevelToObjectTree, formatDateFields } from 'utils';
|
import { formatDateFields } from 'utils';
|
||||||
import {
|
import {
|
||||||
IBillDTO,
|
IBillDTO,
|
||||||
IBill,
|
IBill,
|
||||||
@@ -15,7 +15,6 @@ import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/
|
|||||||
import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { ItemEntriesTaxTransactions } from '@/services/TaxRates/ItemEntriesTaxTransactions';
|
import { ItemEntriesTaxTransactions } from '@/services/TaxRates/ItemEntriesTaxTransactions';
|
||||||
import { assocItemEntriesDefaultIndex } from '@/services/Items/utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class BillDTOTransformer {
|
export class BillDTOTransformer {
|
||||||
@@ -55,9 +54,9 @@ export class BillDTOTransformer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts create bill DTO to model.
|
* Converts create bill DTO to model.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {IBillDTO} billDTO
|
* @param {IBillDTO} billDTO
|
||||||
* @param {IBill} oldBill
|
* @param {IBill} oldBill
|
||||||
* @returns {IBill}
|
* @returns {IBill}
|
||||||
*/
|
*/
|
||||||
public async billDTOToModel(
|
public async billDTOToModel(
|
||||||
@@ -93,9 +92,7 @@ export class BillDTOTransformer {
|
|||||||
|
|
||||||
const entries = R.compose(
|
const entries = R.compose(
|
||||||
// Remove tax code from entries.
|
// Remove tax code from entries.
|
||||||
R.map(R.omit(['taxCode'])),
|
R.map(R.omit(['taxCode']))
|
||||||
// Associate the default index to each item entry line.
|
|
||||||
assocItemEntriesDefaultIndex
|
|
||||||
)(asyncEntries);
|
)(asyncEntries);
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
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 {
|
||||||
@@ -17,17 +15,12 @@ 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,9 +51,6 @@ 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);
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,11 @@ import {
|
|||||||
IVendorCredit,
|
IVendorCredit,
|
||||||
IVendorCreditCreateDTO,
|
IVendorCreditCreateDTO,
|
||||||
IVendorCreditEditDTO,
|
IVendorCreditEditDTO,
|
||||||
IVendorCreditEntryDTO,
|
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import ItemsEntriesService from '@/services/Items/ItemsEntriesService';
|
import ItemsEntriesService from '@/services/Items/ItemsEntriesService';
|
||||||
import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService';
|
import AutoIncrementOrdersService from '@/services/Sales/AutoIncrementOrdersService';
|
||||||
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
||||||
import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||||
import { assocItemEntriesDefaultIndex } from '@/services/Items/utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class BaseVendorCredit {
|
export default class BaseVendorCredit {
|
||||||
@@ -52,18 +50,10 @@ export default class BaseVendorCredit {
|
|||||||
const amount = this.itemsEntriesService.getTotalItemsEntries(
|
const amount = this.itemsEntriesService.getTotalItemsEntries(
|
||||||
vendorCreditDTO.entries
|
vendorCreditDTO.entries
|
||||||
);
|
);
|
||||||
|
const entries = vendorCreditDTO.entries.map((entry) => ({
|
||||||
const entries = R.compose(
|
...entry,
|
||||||
// Associate the default index to each item entry.
|
referenceType: 'VendorCredit',
|
||||||
assocItemEntriesDefaultIndex,
|
}));
|
||||||
|
|
||||||
// Associate the reference type to item entries.
|
|
||||||
R.map((entry: IVendorCreditEntryDTO) => ({
|
|
||||||
referenceType: 'VendorCredit',
|
|
||||||
...entry,
|
|
||||||
}))
|
|
||||||
)(vendorCreditDTO.entries);
|
|
||||||
|
|
||||||
// Retreive the next vendor credit number.
|
// Retreive the next vendor credit number.
|
||||||
const autoNextNumber = this.getNextCreditNumber(tenantId);
|
const autoNextNumber = this.getNextCreditNumber(tenantId);
|
||||||
|
|
||||||
|
|||||||
@@ -48,10 +48,6 @@ 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,7 +2,6 @@ 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 {
|
||||||
@@ -16,17 +15,12 @@ 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,18 +1,11 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import { camelCase, upperFirst, pickBy, isEmpty } from 'lodash';
|
import { camelCase, upperFirst, pickBy } from 'lodash';
|
||||||
import * as qim from 'qim';
|
import * as qim from 'qim';
|
||||||
import pluralize from 'pluralize';
|
import pluralize from 'pluralize';
|
||||||
import {
|
import { IModelMeta, IModelMetaField, IModelMetaField2 } from '@/interfaces';
|
||||||
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',
|
||||||
@@ -26,12 +19,6 @@ 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
|
||||||
@@ -87,45 +74,13 @@ 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 this.filterSupportFeatures(tenantId, meta.fields2);
|
return meta.fields2;
|
||||||
}
|
|
||||||
|
|
||||||
public getResourceColumns(tenantId: number, modelName: string) {
|
|
||||||
const meta = this.getResourceMeta(tenantId, modelName);
|
|
||||||
|
|
||||||
return this.filterSupportFeatures(tenantId, meta.columns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ 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);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrat
|
|||||||
import { formatDateFields } from '@/utils';
|
import { formatDateFields } from '@/utils';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { SaleEstimateIncrement } from './SaleEstimateIncrement';
|
import { SaleEstimateIncrement } from './SaleEstimateIncrement';
|
||||||
import { assocItemEntriesDefaultIndex } from '@/services/Items/utils';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SaleEstimateDTOTransformer {
|
export class SaleEstimateDTOTransformer {
|
||||||
@@ -57,14 +56,6 @@ export class SaleEstimateDTOTransformer {
|
|||||||
// Validate the sale estimate number require.
|
// Validate the sale estimate number require.
|
||||||
this.validators.validateEstimateNoRequire(estimateNumber);
|
this.validators.validateEstimateNoRequire(estimateNumber);
|
||||||
|
|
||||||
const entries = R.compose(
|
|
||||||
// Associate the reference type to item entries.
|
|
||||||
R.map((entry) => R.assoc('reference_type', 'SaleEstimate', entry)),
|
|
||||||
|
|
||||||
// Associate default index to item entries.
|
|
||||||
assocItemEntriesDefaultIndex
|
|
||||||
)(estimateDTO.entries);
|
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
amount,
|
amount,
|
||||||
...formatDateFields(
|
...formatDateFields(
|
||||||
@@ -74,7 +65,10 @@ export class SaleEstimateDTOTransformer {
|
|||||||
currencyCode: paymentCustomer.currencyCode,
|
currencyCode: paymentCustomer.currencyCode,
|
||||||
exchangeRate: estimateDTO.exchangeRate || 1,
|
exchangeRate: estimateDTO.exchangeRate || 1,
|
||||||
...(estimateNumber ? { estimateNumber } : {}),
|
...(estimateNumber ? { estimateNumber } : {}),
|
||||||
entries,
|
entries: estimateDTO.entries.map((entry) => ({
|
||||||
|
reference_type: 'SaleEstimate',
|
||||||
|
...entry,
|
||||||
|
})),
|
||||||
// Avoid rewrite the deliver date in edit mode when already published.
|
// Avoid rewrite the deliver date in edit mode when already published.
|
||||||
...(estimateDTO.delivered &&
|
...(estimateDTO.delivered &&
|
||||||
!oldSaleEstimate?.deliveredAt && {
|
!oldSaleEstimate?.deliveredAt && {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user