mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
feat: wip attach attachments to resource models
This commit is contained in:
@@ -84,7 +84,7 @@ export class ExpensesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Expense DTO schema.
|
* Expense DTO schema.
|
||||||
*/
|
*/
|
||||||
get expenseDTOSchema() {
|
private get expenseDTOSchema() {
|
||||||
return [
|
return [
|
||||||
check('reference_no')
|
check('reference_no')
|
||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
@@ -130,6 +130,9 @@ export class ExpensesController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isInt({ max: DATATYPES_LENGTH.INT_10 })
|
.isInt({ max: DATATYPES_LENGTH.INT_10 })
|
||||||
.toInt(),
|
.toInt(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +186,9 @@ export class ExpensesController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isInt({ max: DATATYPES_LENGTH.INT_10 })
|
.isInt({ max: DATATYPES_LENGTH.INT_10 })
|
||||||
.toInt(),
|
.toInt(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +275,7 @@ export class ExpensesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async deleteExpense(req: Request, res: Response, next: NextFunction) {
|
private async deleteExpense(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const { id: expenseId } = req.params;
|
const { id: expenseId } = req.params;
|
||||||
|
|
||||||
@@ -291,7 +297,11 @@ export class ExpensesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async publishExpense(req: Request, res: Response, next: NextFunction) {
|
private async publishExpense(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const { id: expenseId } = req.params;
|
const { id: expenseId } = req.params;
|
||||||
|
|
||||||
@@ -313,7 +323,11 @@ export class ExpensesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async getExpensesList(req: Request, res: Response, next: NextFunction) {
|
private async getExpensesList(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const filter = {
|
const filter = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
@@ -343,7 +357,7 @@ export class ExpensesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async getExpense(req: Request, res: Response, next: NextFunction) {
|
private async getExpense(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: expenseId } = req.params;
|
const { id: expenseId } = req.params;
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,9 @@ export default class ManualJournalsController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isNumeric()
|
.isNumeric()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ export default class BillsController extends BaseController {
|
|||||||
check('is_inclusive_tax').default(false).isBoolean().toBoolean(),
|
check('is_inclusive_tax').default(false).isBoolean().toBoolean(),
|
||||||
|
|
||||||
check('entries').isArray({ min: 1 }),
|
check('entries').isArray({ min: 1 }),
|
||||||
|
|
||||||
check('entries.*.index').exists().isNumeric().toInt(),
|
check('entries.*.index').exists().isNumeric().toInt(),
|
||||||
check('entries.*.item_id').exists().isNumeric().toInt(),
|
check('entries.*.item_id').exists().isNumeric().toInt(),
|
||||||
check('entries.*.rate').exists().isNumeric().toFloat(),
|
check('entries.*.rate').exists().isNumeric().toFloat(),
|
||||||
@@ -148,6 +147,9 @@ export default class BillsController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isNumeric()
|
.isNumeric()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +192,9 @@ export default class BillsController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isBoolean()
|
.isBoolean()
|
||||||
.toBoolean(),
|
.toBoolean(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,9 @@ export default class BillsPayments extends BaseController {
|
|||||||
check('entries.*.index').optional().isNumeric().toInt(),
|
check('entries.*.index').optional().isNumeric().toInt(),
|
||||||
check('entries.*.bill_id').exists().isNumeric().toInt(),
|
check('entries.*.bill_id').exists().isNumeric().toInt(),
|
||||||
check('entries.*.payment_amount').exists().isNumeric().toFloat(),
|
check('entries.*.payment_amount').exists().isNumeric().toFloat(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ export default class VendorCreditController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isNumeric()
|
.isNumeric()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +231,9 @@ export default class VendorCreditController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isNumeric()
|
.isNumeric()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -236,6 +236,9 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
.optional({ nullable: true })
|
.optional({ nullable: true })
|
||||||
.isNumeric()
|
.isNumeric()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,6 +164,9 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
check('entries.*.index').optional().isNumeric().toInt(),
|
check('entries.*.index').optional().isNumeric().toInt(),
|
||||||
check('entries.*.invoice_id').exists().isNumeric().toInt(),
|
check('entries.*.invoice_id').exists().isNumeric().toInt(),
|
||||||
check('entries.*.payment_amount').exists().isNumeric().toFloat(),
|
check('entries.*.payment_amount').exists().isNumeric().toFloat(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,9 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
check('note').optional().trim().escape(),
|
check('note').optional().trim().escape(),
|
||||||
check('terms_conditions').optional().trim().escape(),
|
check('terms_conditions').optional().trim().escape(),
|
||||||
check('send_to_email').optional().trim().escape(),
|
check('send_to_email').optional().trim().escape(),
|
||||||
|
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
[
|
[
|
||||||
...this.saleInvoiceValidationSchema,
|
...this.saleInvoiceValidationSchema,
|
||||||
check('from_estimate_id').optional().isNumeric().toInt(),
|
check('from_estimate_id').optional().isNumeric().toInt(),
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
],
|
],
|
||||||
this.validationResult,
|
this.validationResult,
|
||||||
asyncMiddleware(this.newSaleInvoice.bind(this)),
|
asyncMiddleware(this.newSaleInvoice.bind(this)),
|
||||||
@@ -98,6 +100,8 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
[
|
[
|
||||||
...this.saleInvoiceValidationSchema,
|
...this.saleInvoiceValidationSchema,
|
||||||
...this.specificSaleInvoiceValidation,
|
...this.specificSaleInvoiceValidation,
|
||||||
|
check('attachments').isArray().optional(),
|
||||||
|
check('attachments.*.key').exists().isString(),
|
||||||
],
|
],
|
||||||
this.validationResult,
|
this.validationResult,
|
||||||
asyncMiddleware(this.editSaleInvoice.bind(this)),
|
asyncMiddleware(this.editSaleInvoice.bind(this)),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ exports.up = function (knex) {
|
|||||||
table.string('model_ref').notNullable();
|
table.string('model_ref').notNullable();
|
||||||
table.string('model_id').notNullable();
|
table.string('model_id').notNullable();
|
||||||
table.integer('document_id').unsigned();
|
table.integer('document_id').unsigned();
|
||||||
|
table.datetime('expires_at').nullable();
|
||||||
table.timestamps();
|
table.timestamps();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
3
packages/server/src/interfaces/Attachments.ts
Normal file
3
packages/server/src/interfaces/Attachments.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export interface AttachmentLinkDTO {
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Knex } from 'knex';
|
|||||||
import { IDynamicListFilterDTO } from './DynamicFilter';
|
import { IDynamicListFilterDTO } from './DynamicFilter';
|
||||||
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
||||||
import { IBillLandedCost } from './LandedCost';
|
import { IBillLandedCost } from './LandedCost';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface IBillDTO {
|
export interface IBillDTO {
|
||||||
vendorId: number;
|
vendorId: number;
|
||||||
@@ -20,6 +21,7 @@ export interface IBillDTO {
|
|||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
projectId?: number;
|
projectId?: number;
|
||||||
isInclusiveTax?: boolean;
|
isInclusiveTax?: boolean;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBillEditDTO {
|
export interface IBillEditDTO {
|
||||||
@@ -38,6 +40,7 @@ export interface IBillEditDTO {
|
|||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
projectId?: number;
|
projectId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBill {
|
export interface IBill {
|
||||||
@@ -105,6 +108,7 @@ export interface IBillsService {
|
|||||||
export interface IBillCreatedPayload {
|
export interface IBillCreatedPayload {
|
||||||
tenantId: number;
|
tenantId: number;
|
||||||
bill: IBill;
|
bill: IBill;
|
||||||
|
billDTO: IBillDTO;
|
||||||
billId: number;
|
billId: number;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
@@ -126,6 +130,7 @@ export interface IBillEditedPayload {
|
|||||||
billId: number;
|
billId: number;
|
||||||
oldBill: IBill;
|
oldBill: IBill;
|
||||||
bill: IBill;
|
bill: IBill;
|
||||||
|
billDTO: IBillDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { IBill } from './Bill';
|
import { IBill } from './Bill';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface IBillPaymentEntry {
|
export interface IBillPaymentEntry {
|
||||||
id?: number;
|
id?: number;
|
||||||
@@ -45,6 +46,7 @@ export interface IBillPaymentDTO {
|
|||||||
reference: string;
|
reference: string;
|
||||||
entries: IBillPaymentEntryDTO[];
|
entries: IBillPaymentEntryDTO[];
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBillReceivePageEntry {
|
export interface IBillReceivePageEntry {
|
||||||
@@ -66,6 +68,7 @@ export interface IBillPaymentsService {
|
|||||||
export interface IBillPaymentEventCreatedPayload {
|
export interface IBillPaymentEventCreatedPayload {
|
||||||
tenantId: number;
|
tenantId: number;
|
||||||
billPayment: IBillPayment;
|
billPayment: IBillPayment;
|
||||||
|
billPaymentDTO: IBillPaymentDTO;
|
||||||
billPaymentId: number;
|
billPaymentId: number;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
@@ -87,6 +90,7 @@ export interface IBillPaymentEventEditedPayload {
|
|||||||
billPaymentId: number;
|
billPaymentId: number;
|
||||||
billPayment: IBillPayment;
|
billPayment: IBillPayment;
|
||||||
oldBillPayment: IBillPayment;
|
oldBillPayment: IBillPayment;
|
||||||
|
billPaymentDTO: IBillPaymentDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { IDynamicListFilter, IItemEntry, IVendorCredit } from '@/interfaces';
|
import { IDynamicListFilter, IItemEntry, IVendorCredit } from '@/interfaces';
|
||||||
import { ILedgerEntry } from './Ledger';
|
import { ILedgerEntry } from './Ledger';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface ICreditNoteEntryNewDTO {
|
export interface ICreditNoteEntryNewDTO {
|
||||||
index: number;
|
index: number;
|
||||||
@@ -21,6 +22,7 @@ export interface ICreditNoteNewDTO {
|
|||||||
entries: ICreditNoteEntryNewDTO[];
|
entries: ICreditNoteEntryNewDTO[];
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICreditNoteEditDTO {
|
export interface ICreditNoteEditDTO {
|
||||||
@@ -33,6 +35,7 @@ export interface ICreditNoteEditDTO {
|
|||||||
entries: ICreditNoteEntryNewDTO[];
|
entries: ICreditNoteEntryNewDTO[];
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICreditNoteEntry extends IItemEntry {}
|
export interface ICreditNoteEntry extends IItemEntry {}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Knex } from 'knex';
|
|||||||
import { ISystemUser } from './User';
|
import { ISystemUser } from './User';
|
||||||
import { IFilterRole } from './DynamicFilter';
|
import { IFilterRole } from './DynamicFilter';
|
||||||
import { IAccount } from './Account';
|
import { IAccount } from './Account';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface IPaginationMeta {
|
export interface IPaginationMeta {
|
||||||
total: number;
|
total: number;
|
||||||
@@ -81,6 +82,7 @@ export interface IExpenseCommonDTO {
|
|||||||
categories: IExpenseCategoryDTO[];
|
categories: IExpenseCategoryDTO[];
|
||||||
|
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IExpenseCreateDTO extends IExpenseCommonDTO {}
|
export interface IExpenseCreateDTO extends IExpenseCommonDTO {}
|
||||||
@@ -152,6 +154,7 @@ export interface IExpenseCreatedPayload {
|
|||||||
expenseId: number;
|
expenseId: number;
|
||||||
authorizedUser: ISystemUser;
|
authorizedUser: ISystemUser;
|
||||||
expense: IExpense;
|
expense: IExpense;
|
||||||
|
expenseDTO: IExpenseCreateDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Knex } from 'knex';
|
|||||||
import { IDynamicListFilterDTO } from './DynamicFilter';
|
import { IDynamicListFilterDTO } from './DynamicFilter';
|
||||||
import { ISystemUser } from './User';
|
import { ISystemUser } from './User';
|
||||||
import { IAccount } from './Account';
|
import { IAccount } from './Account';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface IManualJournal {
|
export interface IManualJournal {
|
||||||
id?: number;
|
id?: number;
|
||||||
@@ -56,6 +57,7 @@ export interface IManualJournalDTO {
|
|||||||
publish?: boolean;
|
publish?: boolean;
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
entries: IManualJournalEntryDTO[];
|
entries: IManualJournalEntryDTO[];
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IManualJournalsFilter extends IDynamicListFilterDTO {
|
export interface IManualJournalsFilter extends IDynamicListFilterDTO {
|
||||||
@@ -142,6 +144,7 @@ export interface IManualJournalEventEditedPayload {
|
|||||||
tenantId: number;
|
tenantId: number;
|
||||||
manualJournal: IManualJournal;
|
manualJournal: IManualJournal;
|
||||||
oldManualJournal: IManualJournal;
|
oldManualJournal: IManualJournal;
|
||||||
|
manualJournalDTO: IManualJournalDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
export interface IManualJournalEditingPayload {
|
export interface IManualJournalEditingPayload {
|
||||||
@@ -161,6 +164,7 @@ export interface IManualJournalEventCreatedPayload {
|
|||||||
tenantId: number;
|
tenantId: number;
|
||||||
manualJournal: IManualJournal;
|
manualJournal: IManualJournal;
|
||||||
manualJournalId: number;
|
manualJournalId: number;
|
||||||
|
manualJournalDTO: IManualJournalDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import { ILedgerEntry } from './Ledger';
|
import { ILedgerEntry } from './Ledger';
|
||||||
import { ISaleInvoice } from './SaleInvoice';
|
import { ISaleInvoice } from './SaleInvoice';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface IPaymentReceive {
|
export interface IPaymentReceive {
|
||||||
id?: number;
|
id?: number;
|
||||||
@@ -37,6 +38,7 @@ export interface IPaymentReceiveCreateDTO {
|
|||||||
entries: IPaymentReceiveEntryDTO[];
|
entries: IPaymentReceiveEntryDTO[];
|
||||||
|
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPaymentReceiveEditDTO {
|
export interface IPaymentReceiveEditDTO {
|
||||||
@@ -50,6 +52,7 @@ export interface IPaymentReceiveEditDTO {
|
|||||||
statement: string;
|
statement: string;
|
||||||
entries: IPaymentReceiveEntryDTO[];
|
entries: IPaymentReceiveEntryDTO[];
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPaymentReceiveEntry {
|
export interface IPaymentReceiveEntry {
|
||||||
@@ -114,6 +117,7 @@ export interface IPaymentReceiveCreatedPayload {
|
|||||||
paymentReceive: IPaymentReceive;
|
paymentReceive: IPaymentReceive;
|
||||||
paymentReceiveId: number;
|
paymentReceiveId: number;
|
||||||
authorizedUser: ISystemUser;
|
authorizedUser: ISystemUser;
|
||||||
|
paymentReceiveDTO: IPaymentReceiveCreateDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +126,7 @@ export interface IPaymentReceiveEditedPayload {
|
|||||||
paymentReceiveId: number;
|
paymentReceiveId: number;
|
||||||
paymentReceive: IPaymentReceive;
|
paymentReceive: IPaymentReceive;
|
||||||
oldPaymentReceive: IPaymentReceive;
|
oldPaymentReceive: IPaymentReceive;
|
||||||
|
paymentReceiveDTO: IPaymentReceiveEditDTO;
|
||||||
authorizedUser: ISystemUser;
|
authorizedUser: ISystemUser;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Knex } from 'knex';
|
|||||||
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
||||||
import { IDynamicListFilterDTO } from '@/interfaces/DynamicFilter';
|
import { IDynamicListFilterDTO } from '@/interfaces/DynamicFilter';
|
||||||
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface ISaleEstimate {
|
export interface ISaleEstimate {
|
||||||
id?: number;
|
id?: number;
|
||||||
@@ -38,6 +39,7 @@ export interface ISaleEstimateDTO {
|
|||||||
|
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISalesEstimatesFilter extends IDynamicListFilterDTO {
|
export interface ISalesEstimatesFilter extends IDynamicListFilterDTO {
|
||||||
@@ -70,6 +72,7 @@ export interface ISaleEstimateEditedPayload {
|
|||||||
estimateId: number;
|
estimateId: number;
|
||||||
saleEstimate: ISaleEstimate;
|
saleEstimate: ISaleEstimate;
|
||||||
oldSaleEstimate: ISaleEstimate;
|
oldSaleEstimate: ISaleEstimate;
|
||||||
|
estimateDTO: ISaleEstimateDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { ISystemUser, IAccount, ITaxTransaction } from '@/interfaces';
|
|||||||
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
||||||
import { IDynamicListFilter } from '@/interfaces/DynamicFilter';
|
import { IDynamicListFilter } from '@/interfaces/DynamicFilter';
|
||||||
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
import { IItemEntry, IItemEntryDTO } from './ItemEntry';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface ISaleInvoice {
|
export interface ISaleInvoice {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -64,6 +65,8 @@ export interface ISaleInvoiceDTO {
|
|||||||
branchId?: number | null;
|
branchId?: number | null;
|
||||||
|
|
||||||
isInclusiveTax?: boolean;
|
isInclusiveTax?: boolean;
|
||||||
|
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISaleInvoiceCreateDTO extends ISaleInvoiceDTO {
|
export interface ISaleInvoiceCreateDTO extends ISaleInvoiceDTO {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { IItemEntry } from './ItemEntry';
|
import { IItemEntry } from './ItemEntry';
|
||||||
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export interface ISaleReceipt {
|
export interface ISaleReceipt {
|
||||||
id?: number;
|
id?: number;
|
||||||
@@ -43,6 +44,7 @@ export interface ISaleReceiptDTO {
|
|||||||
closed: boolean;
|
closed: boolean;
|
||||||
entries: any[];
|
entries: any[];
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISalesReceiptsService {
|
export interface ISalesReceiptsService {
|
||||||
@@ -85,6 +87,7 @@ export interface ISaleReceiptCreatedPayload {
|
|||||||
tenantId: number;
|
tenantId: number;
|
||||||
saleReceipt: ISaleReceipt;
|
saleReceipt: ISaleReceipt;
|
||||||
saleReceiptId: number;
|
saleReceiptId: number;
|
||||||
|
saleReceiptDTO: ISaleReceiptDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +96,7 @@ export interface ISaleReceiptEditedPayload {
|
|||||||
oldSaleReceipt: number;
|
oldSaleReceipt: number;
|
||||||
saleReceipt: ISaleReceipt;
|
saleReceipt: ISaleReceipt;
|
||||||
saleReceiptId: number;
|
saleReceiptId: number;
|
||||||
|
saleReceiptDTO: ISaleReceiptDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { IDynamicListFilter, IItemEntry, IItemEntryDTO } from '@/interfaces';
|
import { IDynamicListFilter, IItemEntry, IItemEntryDTO } from '@/interfaces';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
|
import { AttachmentLinkDTO } from './Attachments';
|
||||||
|
|
||||||
export enum VendorCreditAction {
|
export enum VendorCreditAction {
|
||||||
Create = 'Create',
|
Create = 'Create',
|
||||||
@@ -61,6 +62,7 @@ export interface IVendorCreditDTO {
|
|||||||
|
|
||||||
branchId?: number;
|
branchId?: number;
|
||||||
warehouseId?: number;
|
warehouseId?: number;
|
||||||
|
attachments?: AttachmentLinkDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVendorCreditCreateDTO extends IVendorCreditDTO {}
|
export interface IVendorCreditCreateDTO extends IVendorCreditDTO {}
|
||||||
@@ -118,6 +120,7 @@ export interface IVendorCreditEditedPayload {
|
|||||||
oldVendorCredit: IVendorCredit;
|
oldVendorCredit: IVendorCredit;
|
||||||
vendorCredit: IVendorCredit;
|
vendorCredit: IVendorCredit;
|
||||||
vendorCreditId: number;
|
vendorCreditId: number;
|
||||||
|
vendorCreditDTO: IVendorCreditEditDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,16 @@ import { DeleteCashflowTransactionOnUncategorize } from '@/services/Cashflow/sub
|
|||||||
import { PreventDeleteTransactionOnDelete } from '@/services/Cashflow/subscribers/PreventDeleteTransactionsOnDelete';
|
import { PreventDeleteTransactionOnDelete } from '@/services/Cashflow/subscribers/PreventDeleteTransactionsOnDelete';
|
||||||
import { SubscribeFreeOnSignupCommunity } from '@/services/Subscription/events/SubscribeFreeOnSignupCommunity';
|
import { SubscribeFreeOnSignupCommunity } from '@/services/Subscription/events/SubscribeFreeOnSignupCommunity';
|
||||||
import { SendVerfiyMailOnSignUp } from '@/services/Authentication/events/SendVerfiyMailOnSignUp';
|
import { SendVerfiyMailOnSignUp } from '@/services/Authentication/events/SendVerfiyMailOnSignUp';
|
||||||
|
import { AttachmentsOnSaleInvoiceCreated } from '@/services/Attachments/events/AttachmentsOnSaleInvoice';
|
||||||
|
import { AttachmentsOnSaleReceipt } from '@/services/Attachments/events/AttachmentsOnSaleReceipts';
|
||||||
|
import { AttachmentsOnManualJournals } from '@/services/Attachments/events/AttachmentsOnManualJournals';
|
||||||
|
import { AttachmentsOnExpenses } from '@/services/Attachments/events/AttachmentsOnExpenses';
|
||||||
|
import { AttachmentsOnBills } from '@/services/Attachments/events/AttachmentsOnBills';
|
||||||
|
import { AttachmentsOnPaymentsReceived } from '@/services/Attachments/events/AttachmentsOnPaymentsReceived';
|
||||||
|
import { AttachmentsOnVendorCredits } from '@/services/Attachments/events/AttachmentsOnVendorCredits';
|
||||||
|
import { AttachmentsOnCreditNote } from '@/services/Attachments/events/AttachmentsOnCreditNote';
|
||||||
|
import { AttachmentsOnBillPayments } from '@/services/Attachments/events/AttachmentsOnPaymentsMade';
|
||||||
|
import { AttachmentsOnSaleEstimates } from '@/services/Attachments/events/AttachmentsOnSaleEstimates';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
return new EventPublisher();
|
return new EventPublisher();
|
||||||
@@ -224,6 +233,18 @@ export const susbcribers = () => {
|
|||||||
PreventDeleteTransactionOnDelete,
|
PreventDeleteTransactionOnDelete,
|
||||||
|
|
||||||
SubscribeFreeOnSignupCommunity,
|
SubscribeFreeOnSignupCommunity,
|
||||||
SendVerfiyMailOnSignUp
|
SendVerfiyMailOnSignUp,
|
||||||
|
|
||||||
|
// Attachments
|
||||||
|
AttachmentsOnSaleInvoiceCreated,
|
||||||
|
AttachmentsOnSaleEstimates,
|
||||||
|
AttachmentsOnSaleReceipt,
|
||||||
|
AttachmentsOnPaymentsReceived,
|
||||||
|
AttachmentsOnCreditNote,
|
||||||
|
AttachmentsOnVendorCredits,
|
||||||
|
AttachmentsOnBills,
|
||||||
|
AttachmentsOnBillPayments,
|
||||||
|
AttachmentsOnManualJournals,
|
||||||
|
AttachmentsOnExpenses,
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -403,6 +403,7 @@ export default class Bill extends mixin(TenantModel, [
|
|||||||
const BillLandedCost = require('models/BillLandedCost');
|
const BillLandedCost = require('models/BillLandedCost');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const TaxRateTransaction = require('models/TaxRateTransaction');
|
const TaxRateTransaction = require('models/TaxRateTransaction');
|
||||||
|
const Document = require('models/Document');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
vendor: {
|
vendor: {
|
||||||
@@ -465,6 +466,25 @@ export default class Bill extends mixin(TenantModel, [
|
|||||||
builder.where('reference_type', 'Bill');
|
builder.where('reference_type', 'Bill');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.ManyToManyRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'bills.id',
|
||||||
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
|
},
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'Bill');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export default class BillPayment extends mixin(TenantModel, [
|
|||||||
const Vendor = require('models/Vendor');
|
const Vendor = require('models/Vendor');
|
||||||
const Account = require('models/Account');
|
const Account = require('models/Account');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
|
const Document = require('models/Document');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entries: {
|
entries: {
|
||||||
@@ -114,6 +115,25 @@ export default class BillPayment extends mixin(TenantModel, [
|
|||||||
to: 'branches.id',
|
to: 'branches.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill payment may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.ManyToManyRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'bills_payments.id',
|
||||||
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
|
},
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'BillPayment');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ export default class CreditNote 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 Document = require('models/Document');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@@ -233,6 +234,25 @@ export default class CreditNote extends mixin(TenantModel, [
|
|||||||
to: 'branches.id',
|
to: 'branches.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credit note may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.ManyToManyRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'credit_notes.id',
|
||||||
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
|
},
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'CreditNote');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ export default class Expense extends mixin(TenantModel, [
|
|||||||
static get relationMappings() {
|
static get relationMappings() {
|
||||||
const Account = require('models/Account');
|
const Account = require('models/Account');
|
||||||
const ExpenseCategory = require('models/ExpenseCategory');
|
const ExpenseCategory = require('models/ExpenseCategory');
|
||||||
const Media = require('models/Media');
|
const Document = require('models/Document');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -217,21 +217,21 @@ export default class Expense extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Expense transaction may has many attached attachments.
|
||||||
*/
|
*/
|
||||||
media: {
|
attachments: {
|
||||||
relation: Model.ManyToManyRelation,
|
relation: Model.ManyToManyRelation,
|
||||||
modelClass: Media.default,
|
modelClass: Document.default,
|
||||||
join: {
|
join: {
|
||||||
from: 'expenses_transactions.id',
|
from: 'expenses_transactions.id',
|
||||||
through: {
|
through: {
|
||||||
from: 'media_links.model_id',
|
from: 'document_links.modelId',
|
||||||
to: 'media_links.media_id',
|
to: 'document_links.documentId',
|
||||||
},
|
},
|
||||||
to: 'media.id',
|
to: 'documents.id',
|
||||||
},
|
},
|
||||||
filter(query) {
|
filter(query) {
|
||||||
query.where('model_name', 'Expense');
|
query.where('model_ref', 'Expense');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -94,9 +94,9 @@ export default class ManualJournal extends mixin(TenantModel, [
|
|||||||
* Relationship mapping.
|
* Relationship mapping.
|
||||||
*/
|
*/
|
||||||
static get relationMappings() {
|
static get relationMappings() {
|
||||||
const Media = require('models/Media');
|
|
||||||
const AccountTransaction = require('models/AccountTransaction');
|
const AccountTransaction = require('models/AccountTransaction');
|
||||||
const ManualJournalEntry = require('models/ManualJournalEntry');
|
const ManualJournalEntry = require('models/ManualJournalEntry');
|
||||||
|
const ManualJournal = require('models/ManualJournal');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entries: {
|
entries: {
|
||||||
@@ -121,19 +121,23 @@ export default class ManualJournal extends mixin(TenantModel, [
|
|||||||
query.where('referenceType', 'Journal');
|
query.where('referenceType', 'Journal');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
media: {
|
|
||||||
|
/**
|
||||||
|
* Manual journal may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
relation: Model.ManyToManyRelation,
|
relation: Model.ManyToManyRelation,
|
||||||
modelClass: Media.default,
|
modelClass: ManualJournal.default,
|
||||||
join: {
|
join: {
|
||||||
from: 'manual_journals.id',
|
from: 'manual_journals.id',
|
||||||
through: {
|
through: {
|
||||||
from: 'media_links.model_id',
|
from: 'document_links.modelId',
|
||||||
to: 'media_links.media_id',
|
to: 'document_links.documentId',
|
||||||
},
|
},
|
||||||
to: 'media.id',
|
to: 'documents.id',
|
||||||
},
|
},
|
||||||
filter(query) {
|
filter(query) {
|
||||||
query.where('model_name', 'ManualJournal');
|
query.where('model_ref', 'ManualJournal');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
|||||||
const Customer = require('models/Customer');
|
const Customer = require('models/Customer');
|
||||||
const Account = require('models/Account');
|
const Account = require('models/Account');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
|
const Document = require('models/Document');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
customer: {
|
customer: {
|
||||||
@@ -111,6 +112,25 @@ export default class PaymentReceive extends mixin(TenantModel, [
|
|||||||
to: 'branches.id',
|
to: 'branches.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment transaction may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.ManyToManyRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'payment_receives.id',
|
||||||
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
|
},
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'PaymentReceive');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
|||||||
const ItemEntry = require('models/ItemEntry');
|
const ItemEntry = require('models/ItemEntry');
|
||||||
const Customer = require('models/Customer');
|
const Customer = require('models/Customer');
|
||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
|
const Document = require('models/Document');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
customer: {
|
customer: {
|
||||||
@@ -219,6 +220,25 @@ export default class SaleEstimate extends mixin(TenantModel, [
|
|||||||
to: 'branches.id',
|
to: 'branches.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sale estimate transaction may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.ManyToManyRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'sales_estimates.id',
|
||||||
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
|
},
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'Expense');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
const Branch = require('models/Branch');
|
const Branch = require('models/Branch');
|
||||||
const Account = require('models/Account');
|
const Account = require('models/Account');
|
||||||
const TaxRateTransaction = require('models/TaxRateTransaction');
|
const TaxRateTransaction = require('models/TaxRateTransaction');
|
||||||
const DocumentLink = require('models/DocumentLink');
|
const Document = require('models/Document');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@@ -526,17 +526,21 @@ export default class SaleInvoice extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice may has many attachments.
|
* Sale invoice transaction may has many attached attachments.
|
||||||
*/
|
*/
|
||||||
attachments: {
|
attachments: {
|
||||||
relation: Model.HasManyRelation,
|
relation: Model.ManyToManyRelation,
|
||||||
modelClass: DocumentLink.default,
|
modelClass: Document.default,
|
||||||
join: {
|
join: {
|
||||||
from: 'sales_invoices.id',
|
from: 'sales_invoices.id',
|
||||||
to: 'document_links.modelId',
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
},
|
},
|
||||||
filter: (builder) => {
|
to: 'documents.id',
|
||||||
builder.where('modelRef', 'SaleInvoice');
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'Expense');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ export default class SaleReceipt extends mixin(TenantModel, [
|
|||||||
const AccountTransaction = require('models/AccountTransaction');
|
const AccountTransaction = require('models/AccountTransaction');
|
||||||
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');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
customer: {
|
customer: {
|
||||||
@@ -167,6 +168,25 @@ export default class SaleReceipt extends mixin(TenantModel, [
|
|||||||
to: 'branches.id',
|
to: 'branches.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sale receipt transaction may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.ManyToManyRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'sales_receipts.id',
|
||||||
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
|
},
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'SaleReceipt');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ export default class VendorCredit extends mixin(TenantModel, [
|
|||||||
const Vendor = require('models/Vendor');
|
const Vendor = require('models/Vendor');
|
||||||
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');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
vendor: {
|
vendor: {
|
||||||
@@ -215,6 +216,25 @@ export default class VendorCredit extends mixin(TenantModel, [
|
|||||||
to: 'branches.id',
|
to: 'branches.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor credit may has many attached attachments.
|
||||||
|
*/
|
||||||
|
attachments: {
|
||||||
|
relation: Model.ManyToManyRelation,
|
||||||
|
modelClass: Document.default,
|
||||||
|
join: {
|
||||||
|
from: 'vendor_credits.id',
|
||||||
|
through: {
|
||||||
|
from: 'document_links.modelId',
|
||||||
|
to: 'document_links.documentId',
|
||||||
|
},
|
||||||
|
to: 'documents.id',
|
||||||
|
},
|
||||||
|
filter(query) {
|
||||||
|
query.where('model_ref', 'VendorCredit');
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||||
|
|
||||||
|
export class AttachmentTransformer extends Transformer {
|
||||||
|
/**
|
||||||
|
* Exclude attributes.
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
public excludeAttributes = (): string[] => {
|
||||||
|
return ['*'];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includeded attributes.
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
public includeAttributes = (): string[] => {
|
||||||
|
return ['extension', 'key'];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
|
import bluebird from 'bluebird';
|
||||||
|
import { Knex } from 'knex';
|
||||||
import {
|
import {
|
||||||
validateLinkModelEntryExists,
|
validateLinkModelEntryExists,
|
||||||
validateLinkModelExists,
|
validateLinkModelExists,
|
||||||
@@ -12,38 +14,68 @@ export class LinkAttachment {
|
|||||||
private tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Links the given file key to the given model type and id.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {string} filekey
|
* @param {string} filekey
|
||||||
* @param {string} modelRef
|
* @param {string} modelRef
|
||||||
* @param {number} modelId
|
* @param {number} modelId
|
||||||
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async link(
|
async link(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
filekey: string,
|
filekey: string,
|
||||||
modelRef: string,
|
modelRef: string,
|
||||||
modelId: number
|
modelId: number,
|
||||||
|
trx?: Knex.Transaction
|
||||||
) {
|
) {
|
||||||
const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId);
|
const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId);
|
||||||
const LinkModel = models[modelRef];
|
const LinkModel = models[modelRef];
|
||||||
validateLinkModelExists(LinkModel);
|
validateLinkModelExists(LinkModel);
|
||||||
|
|
||||||
const foundLinkModel = await LinkModel.query().findById(modelId);
|
const foundLinkModel = await LinkModel.query(trx).findById(modelId);
|
||||||
validateLinkModelEntryExists(foundLinkModel);
|
validateLinkModelEntryExists(foundLinkModel);
|
||||||
|
|
||||||
const foundLinks = await DocumentLink.query()
|
const foundLinks = await DocumentLink.query(trx)
|
||||||
.where('modelRef', modelRef)
|
.where('modelRef', modelRef)
|
||||||
.where('modelId', modelId);
|
.where('modelId', modelId);
|
||||||
|
|
||||||
if (foundLinks.length > 0) {
|
if (foundLinks.length > 0) {
|
||||||
throw new ServiceError('');
|
throw new ServiceError('DOCUMENT_LINK_ALREADY_LINKED');
|
||||||
}
|
}
|
||||||
const foundFile = await Document.query().findOne('key', filekey);
|
const foundFile = await Document.query(trx).findOne('key', filekey);
|
||||||
|
|
||||||
await DocumentLink.query().insert({
|
await DocumentLink.query(trx).insert({
|
||||||
modelRef,
|
modelRef,
|
||||||
modelId,
|
modelId,
|
||||||
documentId: foundFile.id,
|
documentId: foundFile.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links the given file keys to the given model type and id.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {string[]} filekeys
|
||||||
|
* @param {string} modelRef
|
||||||
|
* @param {number} modelId
|
||||||
|
* @param {Knex.Transaction} trx
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async bulkLink(
|
||||||
|
tenantId: number,
|
||||||
|
filekeys: string[],
|
||||||
|
modelRef: string,
|
||||||
|
modelId: number,
|
||||||
|
trx?: Knex.Transaction
|
||||||
|
) {
|
||||||
|
await bluebird.map(
|
||||||
|
filekeys,
|
||||||
|
(fieldKey: string) =>
|
||||||
|
this.link(tenantId, fieldKey, modelRef, modelId, trx),
|
||||||
|
{
|
||||||
|
concurrency: CONCURRENCY_ASYNC,
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CONCURRENCY_ASYNC = 10;
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
|
import bluebird from 'bluebird';
|
||||||
import HasTenancyService from '../Tenancy/TenancyService';
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
import {
|
import {
|
||||||
validateLinkModelEntryExists,
|
validateLinkModelEntryExists,
|
||||||
validateLinkModelExists,
|
validateLinkModelExists,
|
||||||
} from './_utils';
|
} from './_utils';
|
||||||
|
import { Knex } from 'knex';
|
||||||
|
import { difference } from 'lodash';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class UnlinkAttachment {
|
export class UnlinkAttachment {
|
||||||
@@ -11,7 +14,7 @@ export class UnlinkAttachment {
|
|||||||
private tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Unlink the attachments from the model entry.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {string} filekey
|
* @param {string} filekey
|
||||||
* @param {string} modelRef
|
* @param {string} modelRef
|
||||||
@@ -21,19 +24,105 @@ export class UnlinkAttachment {
|
|||||||
tenantId: number,
|
tenantId: number,
|
||||||
filekey: string,
|
filekey: string,
|
||||||
modelRef: string,
|
modelRef: string,
|
||||||
modelId: number
|
modelId: number,
|
||||||
) {
|
trx?: Knex.Transaction
|
||||||
const { DocumentLink, ...models } = this.tenancy.models(tenantId);
|
): Promise<void> {
|
||||||
|
const { DocumentLink, Document, ...models } = this.tenancy.models(tenantId);
|
||||||
const LinkModel = models[modelRef];
|
const LinkModel = models[modelRef];
|
||||||
validateLinkModelExists(LinkModel);
|
validateLinkModelExists(LinkModel);
|
||||||
|
|
||||||
const foundLinkModel = await LinkModel.query().findById(modelId);
|
const foundLinkModel = await LinkModel.query(trx).findById(modelId);
|
||||||
validateLinkModelEntryExists(foundLinkModel);
|
validateLinkModelEntryExists(foundLinkModel);
|
||||||
|
|
||||||
|
const document = await Document.query().findOne('key', filekey);
|
||||||
|
|
||||||
// Delete the document link.
|
// Delete the document link.
|
||||||
await DocumentLink.query()
|
await DocumentLink.query(trx)
|
||||||
.where('modelRef', modelRef)
|
.where('modelRef', modelRef)
|
||||||
.where('modelId', modelId)
|
.where('modelId', modelId)
|
||||||
|
.where('documentId', document.id)
|
||||||
.delete();
|
.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk unlink the attachments from the model entry.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {string} fieldkey
|
||||||
|
* @param {string} modelRef
|
||||||
|
* @param {number} modelId
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async bulkUnlink(
|
||||||
|
tenantId: number,
|
||||||
|
filekeys: string[],
|
||||||
|
modelRef: string,
|
||||||
|
modelId: number,
|
||||||
|
trx?: Knex.Transaction
|
||||||
|
): Promise<void> {
|
||||||
|
await bluebird.map(
|
||||||
|
filekeys,
|
||||||
|
(fieldKey: string) =>
|
||||||
|
this.unlink(tenantId, fieldKey, modelRef, modelId, trx),
|
||||||
|
{
|
||||||
|
concurrency: CONCURRENCY_ASYNC,
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all the unpresented keys of the given model type and id.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {string[]} presentedKeys
|
||||||
|
* @param {string} modelRef
|
||||||
|
* @param {number} modelId
|
||||||
|
* @param {Knex.Transaction} trx
|
||||||
|
*/
|
||||||
|
async unlinkUnpresentedKeys(
|
||||||
|
tenantId: number,
|
||||||
|
presentedKeys: string[],
|
||||||
|
modelRef: string,
|
||||||
|
modelId: number,
|
||||||
|
trx?: Knex.Transaction
|
||||||
|
): Promise<void> {
|
||||||
|
const { DocumentLink } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const modelLinks = await DocumentLink.query(trx)
|
||||||
|
.where('modelRef', modelRef)
|
||||||
|
.where('modelId', modelId)
|
||||||
|
.withGraphFetched('document');
|
||||||
|
|
||||||
|
const modelLinkKeys = modelLinks.map((link) => link.document.key);
|
||||||
|
const unpresentedKeys = difference(modelLinkKeys, presentedKeys);
|
||||||
|
|
||||||
|
await this.bulkUnlink(tenantId, unpresentedKeys, modelRef, modelId, trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments of the given model type and id.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {string} modelRef
|
||||||
|
* @param {number} modelId
|
||||||
|
* @param {Knex.Transaction} trx
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async unlinkAllModelKeys(
|
||||||
|
tenantId: number,
|
||||||
|
modelRef: string,
|
||||||
|
modelId: number,
|
||||||
|
trx?: Knex.Transaction
|
||||||
|
): Promise<void> {
|
||||||
|
const { DocumentLink } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
// Get all the keys of the modelRef and modelId.
|
||||||
|
const modelLinks = await DocumentLink.query(trx)
|
||||||
|
.where('modelRef', modelRef)
|
||||||
|
.where('modelId', modelId)
|
||||||
|
.withGraphFetched('document');
|
||||||
|
|
||||||
|
const modelLinkKeys = modelLinks.map((link) => link.document.key);
|
||||||
|
|
||||||
|
await this.bulkUnlink(tenantId, modelLinkKeys, modelRef, modelId, trx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CONCURRENCY_ASYNC = 10;
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { castArray, difference } from 'lodash';
|
||||||
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
|
import { ServiceError } from '@/exceptions';
|
||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class ValidateAttachments {
|
||||||
|
@Inject()
|
||||||
|
tenancy: HasTenancyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the given file keys existance.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {string|string[]} key
|
||||||
|
*/
|
||||||
|
async validate(tenantId: number, key: string | string[]) {
|
||||||
|
const { Document } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const keys = castArray(key);
|
||||||
|
const documents = await Document.query().whereIn('key', key);
|
||||||
|
const documentKeys = documents.map((document) => document.key);
|
||||||
|
|
||||||
|
const notFoundKeys = difference(keys, documentKeys);
|
||||||
|
|
||||||
|
if (notFoundKeys.length > 0) {
|
||||||
|
throw new ServiceError('DOCUMENT_KEYS_INVALID');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
IBIllEventDeletedPayload,
|
||||||
|
IBillCreatedPayload,
|
||||||
|
IBillCreatingPayload,
|
||||||
|
IBillEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnBills {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.bill.onCreating,
|
||||||
|
this.validateAttachmentsOnBillCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bill.onCreated,
|
||||||
|
this.handleAttachmentsOnBillCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bill.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnBillEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bill.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnBillEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.bill.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnBillDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating bill.
|
||||||
|
* @param {ISaleInvoiceCreatingPaylaod}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnBillCreate({
|
||||||
|
billDTO,
|
||||||
|
tenantId,
|
||||||
|
}: IBillCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(billDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = billDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created bill.
|
||||||
|
* @param {ISaleInvoiceCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnBillCreated({
|
||||||
|
tenantId,
|
||||||
|
bill,
|
||||||
|
billDTO,
|
||||||
|
trx,
|
||||||
|
}: IBillCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(billDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = billDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'Bill',
|
||||||
|
bill.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited bill.
|
||||||
|
* @param {IBillEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnBillEdited({
|
||||||
|
tenantId,
|
||||||
|
billDTO,
|
||||||
|
bill,
|
||||||
|
}: IBillEditedPayload) {
|
||||||
|
const keys = billDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'Bill',
|
||||||
|
bill.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited bill.
|
||||||
|
* @param {ISaleInvoiceEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnBillEdited({
|
||||||
|
tenantId,
|
||||||
|
billDTO,
|
||||||
|
oldBill,
|
||||||
|
trx,
|
||||||
|
}: IBillEditedPayload) {
|
||||||
|
if (isEmpty(billDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = billDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'Bill',
|
||||||
|
oldBill.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the bill deleted.
|
||||||
|
* @param {ISaleInvoiceDeletedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnBillDeleted({
|
||||||
|
tenantId,
|
||||||
|
oldBill,
|
||||||
|
trx,
|
||||||
|
}: IBIllEventDeletedPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'Bill',
|
||||||
|
oldBill.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
ICreditNoteCreatedPayload,
|
||||||
|
ICreditNoteCreatingPayload,
|
||||||
|
ICreditNoteDeletingPayload,
|
||||||
|
ICreditNoteEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnCreditNote {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.creditNote.onCreating,
|
||||||
|
this.validateAttachmentsOnCreditNoteCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.creditNote.onCreated,
|
||||||
|
this.handleAttachmentsOnCreditNoteCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.creditNote.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnCreditNoteEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.creditNote.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnCreditNoteEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.creditNote.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnCreditNoteDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating credit note.
|
||||||
|
* @param {ICreditNoteCreatingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnCreditNoteCreate({
|
||||||
|
creditNoteDTO,
|
||||||
|
tenantId,
|
||||||
|
}: ICreditNoteCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(creditNoteDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = creditNoteDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created credit note.
|
||||||
|
* @param {ICreditNoteCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnCreditNoteCreated({
|
||||||
|
tenantId,
|
||||||
|
creditNote,
|
||||||
|
creditNoteDTO,
|
||||||
|
trx,
|
||||||
|
}: ICreditNoteCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(creditNoteDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = creditNoteDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'CreditNote',
|
||||||
|
creditNote.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited credit note.
|
||||||
|
* @param {ICreditNoteEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnCreditNoteEdited({
|
||||||
|
tenantId,
|
||||||
|
creditNoteEditDTO,
|
||||||
|
oldCreditNote,
|
||||||
|
}: ICreditNoteEditedPayload) {
|
||||||
|
const keys = creditNoteEditDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'CreditNote',
|
||||||
|
oldCreditNote.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited credit note.
|
||||||
|
* @param {ICreditNoteEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnCreditNoteEdited({
|
||||||
|
tenantId,
|
||||||
|
creditNoteEditDTO,
|
||||||
|
oldCreditNote,
|
||||||
|
trx,
|
||||||
|
}: ICreditNoteEditedPayload) {
|
||||||
|
if (isEmpty(creditNoteEditDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = creditNoteEditDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'CreditNote',
|
||||||
|
oldCreditNote.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the credit note deleted.
|
||||||
|
* @param {ICreditNoteDeletingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnCreditNoteDeleted({
|
||||||
|
tenantId,
|
||||||
|
oldCreditNote,
|
||||||
|
trx,
|
||||||
|
}: ICreditNoteDeletingPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'CreditNote',
|
||||||
|
oldCreditNote.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
IExpenseCreatedPayload,
|
||||||
|
IExpenseCreatingPayload,
|
||||||
|
IExpenseDeletingPayload,
|
||||||
|
IExpenseEventEditPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnExpenses {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.expenses.onCreating,
|
||||||
|
this.validateAttachmentsOnExpenseCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.expenses.onCreated,
|
||||||
|
this.handleAttachmentsOnExpenseCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.expenses.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnExpenseEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.expenses.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnExpenseEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.expenses.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnExpenseDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating expense.
|
||||||
|
* @param {ISaleInvoiceCreatingPaylaod}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnExpenseCreate({
|
||||||
|
expenseDTO,
|
||||||
|
tenantId,
|
||||||
|
}: IExpenseCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(expenseDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = expenseDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created expense.
|
||||||
|
* @param {ISaleInvoiceCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnExpenseCreated({
|
||||||
|
tenantId,
|
||||||
|
expenseDTO,
|
||||||
|
expense,
|
||||||
|
trx,
|
||||||
|
}: IExpenseCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(expenseDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = expenseDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'Expense',
|
||||||
|
expense.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited expense.
|
||||||
|
* @param {ISaleInvoiceEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnExpenseEdited({
|
||||||
|
tenantId,
|
||||||
|
expenseDTO,
|
||||||
|
expense,
|
||||||
|
}: IExpenseEventEditPayload) {
|
||||||
|
const keys = expenseDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'Expense',
|
||||||
|
expense.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited expense.
|
||||||
|
* @param {ISaleInvoiceEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnExpenseEdited({
|
||||||
|
tenantId,
|
||||||
|
expenseDTO,
|
||||||
|
oldExpense,
|
||||||
|
trx,
|
||||||
|
}: IExpenseEventEditPayload) {
|
||||||
|
if (isEmpty(expenseDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = expenseDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'Expense',
|
||||||
|
oldExpense.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the expense deleted.
|
||||||
|
* @param {ISaleInvoiceDeletedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnExpenseDeleted({
|
||||||
|
tenantId,
|
||||||
|
oldExpense,
|
||||||
|
trx,
|
||||||
|
}: IExpenseDeletingPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'Expense',
|
||||||
|
oldExpense.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
IManualJournalCreatingPayload,
|
||||||
|
IManualJournalEventCreatedPayload,
|
||||||
|
IManualJournalEventDeletedPayload,
|
||||||
|
IManualJournalEventEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnManualJournals {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onCreating,
|
||||||
|
this.validateAttachmentsOnManualJournalCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onCreated,
|
||||||
|
this.handleAttachmentsOnManualJournalCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnManualJournalEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnManualJournalEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.manualJournals.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnManualJournalDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating manual journal.
|
||||||
|
* @param {IManualJournalCreatingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnManualJournalCreate({
|
||||||
|
manualJournalDTO,
|
||||||
|
tenantId,
|
||||||
|
}: IManualJournalCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(manualJournalDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = manualJournalDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created manual journal.
|
||||||
|
* @param {IManualJournalEventCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnManualJournalCreated({
|
||||||
|
tenantId,
|
||||||
|
manualJournalDTO,
|
||||||
|
manualJournal,
|
||||||
|
trx,
|
||||||
|
}: IManualJournalEventCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(manualJournalDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = manualJournalDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'ManualJournal',
|
||||||
|
manualJournal.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited manual journal.
|
||||||
|
* @param {ISaleInvoiceEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnManualJournalEdited({
|
||||||
|
tenantId,
|
||||||
|
manualJournalDTO,
|
||||||
|
manualJournal,
|
||||||
|
}: IManualJournalEventEditedPayload) {
|
||||||
|
// if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = manualJournalDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleInvoice',
|
||||||
|
manualJournal.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited manual journal.
|
||||||
|
* @param {ISaleInvoiceEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnManualJournalEdited({
|
||||||
|
tenantId,
|
||||||
|
manualJournalDTO,
|
||||||
|
oldManualJournal,
|
||||||
|
trx,
|
||||||
|
}: IManualJournalEventEditedPayload) {
|
||||||
|
if (isEmpty(manualJournalDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = manualJournalDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'ManualJournal',
|
||||||
|
oldManualJournal.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the manual journal deleted.
|
||||||
|
* @param {ISaleInvoiceDeletedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnManualJournalDeleted({
|
||||||
|
tenantId,
|
||||||
|
oldManualJournal,
|
||||||
|
trx,
|
||||||
|
}: IManualJournalEventDeletedPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'SaleInvoice',
|
||||||
|
oldManualJournal.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
IBillPaymentCreatingPayload,
|
||||||
|
IBillPaymentDeletingPayload,
|
||||||
|
IBillPaymentEventCreatedPayload,
|
||||||
|
IBillPaymentEventEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnBillPayments{
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.billPayment.onCreating,
|
||||||
|
this.validateAttachmentsOnBillPaymentCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.billPayment.onCreated,
|
||||||
|
this.handleAttachmentsOnBillPaymentCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.billPayment.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnBillPaymentEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.billPayment.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnBillPaymentEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.billPayment.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnBillPaymentDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating bill payment.
|
||||||
|
* @param {IBillPaymentCreatingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnBillPaymentCreate({
|
||||||
|
billPaymentDTO,
|
||||||
|
tenantId,
|
||||||
|
}: IBillPaymentCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(billPaymentDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = billPaymentDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created bill payment.
|
||||||
|
* @param {IBillPaymentEventCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnBillPaymentCreated({
|
||||||
|
tenantId,
|
||||||
|
billPaymentDTO,
|
||||||
|
billPayment,
|
||||||
|
trx,
|
||||||
|
}: IBillPaymentEventCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(billPaymentDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = billPaymentDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'BillPayment',
|
||||||
|
billPayment.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited bill payment.
|
||||||
|
* @param {IBillPaymentEventEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnBillPaymentEdited({
|
||||||
|
tenantId,
|
||||||
|
billPaymentDTO,
|
||||||
|
oldBillPayment,
|
||||||
|
}: IBillPaymentEventEditedPayload) {
|
||||||
|
const keys = billPaymentDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'BillPayment',
|
||||||
|
oldBillPayment.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited bill payment.
|
||||||
|
* @param {IBillPaymentEventEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnBillPaymentEdited({
|
||||||
|
tenantId,
|
||||||
|
billPaymentDTO,
|
||||||
|
oldBillPayment,
|
||||||
|
trx,
|
||||||
|
}: IBillPaymentEventEditedPayload) {
|
||||||
|
if (isEmpty(billPaymentDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = billPaymentDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'BillPayment',
|
||||||
|
oldBillPayment.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the bill payment deleted.
|
||||||
|
* @param {IBillPaymentDeletingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnBillPaymentDeleted({
|
||||||
|
tenantId,
|
||||||
|
oldBillPayment,
|
||||||
|
trx,
|
||||||
|
}: IBillPaymentDeletingPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'BillPayment',
|
||||||
|
oldBillPayment.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
IPaymentReceiveCreatedPayload,
|
||||||
|
IPaymentReceiveCreatingPayload,
|
||||||
|
IPaymentReceiveDeletingPayload,
|
||||||
|
IPaymentReceiveEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnPaymentsReceived {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.paymentReceive.onCreating,
|
||||||
|
this.validateAttachmentsOnPaymentCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.paymentReceive.onCreated,
|
||||||
|
this.handleAttachmentsOnPaymentCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.paymentReceive.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnPaymentEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.paymentReceive.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnPaymentEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.paymentReceive.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnPaymentDelete.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating payment.
|
||||||
|
* @param {IPaymentReceiveCreatingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnPaymentCreate({
|
||||||
|
paymentReceiveDTO,
|
||||||
|
tenantId,
|
||||||
|
}: IPaymentReceiveCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(paymentReceiveDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = paymentReceiveDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created payment.
|
||||||
|
* @param {IPaymentReceiveCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnPaymentCreated({
|
||||||
|
tenantId,
|
||||||
|
paymentReceiveDTO,
|
||||||
|
paymentReceive,
|
||||||
|
trx,
|
||||||
|
}: IPaymentReceiveCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(paymentReceiveDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = paymentReceiveDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'PaymentReceive',
|
||||||
|
paymentReceive.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited payment.
|
||||||
|
* @param {IPaymentReceiveEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnPaymentEdited({
|
||||||
|
tenantId,
|
||||||
|
paymentReceiveDTO,
|
||||||
|
oldPaymentReceive,
|
||||||
|
}: IPaymentReceiveEditedPayload) {
|
||||||
|
const keys = paymentReceiveDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'PaymentReceive',
|
||||||
|
oldPaymentReceive.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited payment.
|
||||||
|
* @param {IPaymentReceiveEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnPaymentEdited({
|
||||||
|
tenantId,
|
||||||
|
paymentReceiveDTO,
|
||||||
|
oldPaymentReceive,
|
||||||
|
trx,
|
||||||
|
}: IPaymentReceiveEditedPayload) {
|
||||||
|
if (isEmpty(paymentReceiveDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = paymentReceiveDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'PaymentReceive',
|
||||||
|
oldPaymentReceive.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the payment deleted.
|
||||||
|
* @param {ISaleInvoiceDeletedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnPaymentDelete({
|
||||||
|
tenantId,
|
||||||
|
oldPaymentReceive,
|
||||||
|
trx,
|
||||||
|
}: IPaymentReceiveDeletingPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'PaymentReceive',
|
||||||
|
oldPaymentReceive.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
ISaleEstimateCreatedPayload,
|
||||||
|
ISaleEstimateCreatingPayload,
|
||||||
|
ISaleEstimateDeletingPayload,
|
||||||
|
ISaleEstimateEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnSaleEstimates {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleEstimate.onCreating,
|
||||||
|
this.validateAttachmentsOnSaleEstimateCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleEstimate.onCreated,
|
||||||
|
this.handleAttachmentsOnSaleEstimateCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleEstimate.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnSaleEstimateEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleEstimate.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnSaleEstimateEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleEstimate.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnSaleEstimateDelete.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating sale estimate.
|
||||||
|
* @param {ISaleEstimateCreatingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnSaleEstimateCreated({
|
||||||
|
estimateDTO,
|
||||||
|
tenantId,
|
||||||
|
}: ISaleEstimateCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(estimateDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = estimateDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created sale estimate.
|
||||||
|
* @param {ISaleEstimateCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnSaleEstimateCreated({
|
||||||
|
tenantId,
|
||||||
|
saleEstimateDTO,
|
||||||
|
saleEstimate,
|
||||||
|
trx,
|
||||||
|
}: ISaleEstimateCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(saleEstimateDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = saleEstimateDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleEstimate',
|
||||||
|
saleEstimate.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited sale estimate.
|
||||||
|
* @param {ISaleEstimateEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnSaleEstimateEdited({
|
||||||
|
tenantId,
|
||||||
|
estimateDTO,
|
||||||
|
oldSaleEstimate,
|
||||||
|
}: ISaleEstimateEditedPayload) {
|
||||||
|
const keys = estimateDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleEstimate',
|
||||||
|
oldSaleEstimate.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited sale estimate.
|
||||||
|
* @param {ISaleEstimateEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnSaleEstimateEdited({
|
||||||
|
tenantId,
|
||||||
|
estimateDTO,
|
||||||
|
oldSaleEstimate,
|
||||||
|
trx,
|
||||||
|
}: ISaleEstimateEditedPayload) {
|
||||||
|
if (isEmpty(estimateDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = estimateDTO.attachments?.map((attachment) => attachment.key);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleEstimate',
|
||||||
|
oldSaleEstimate.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the estimate deleted.
|
||||||
|
* @param {ISaleEstimateDeletingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnSaleEstimateDelete({
|
||||||
|
tenantId,
|
||||||
|
oldSaleEstimate,
|
||||||
|
trx,
|
||||||
|
}: ISaleEstimateDeletingPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'SaleEstimate',
|
||||||
|
oldSaleEstimate.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
ISaleInvoiceCreatedPayload,
|
||||||
|
ISaleInvoiceCreatingPaylaod,
|
||||||
|
ISaleInvoiceDeletePayload,
|
||||||
|
ISaleInvoiceEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnSaleInvoiceCreated {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onCreating,
|
||||||
|
this.validateAttachmentsOnSaleInvoiceCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onCreated,
|
||||||
|
this.handleAttachmentsOnSaleInvoiceCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnInvoiceEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnInvoiceEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnInvoiceDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating sale invoice.
|
||||||
|
* @param {ISaleInvoiceCreatingPaylaod}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnSaleInvoiceCreate({
|
||||||
|
saleInvoiceDTO,
|
||||||
|
tenantId,
|
||||||
|
}: ISaleInvoiceCreatingPaylaod): Promise<void> {
|
||||||
|
if (isEmpty(saleInvoiceDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = saleInvoiceDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created sale invoice.
|
||||||
|
* @param {ISaleInvoiceCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnSaleInvoiceCreated({
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceDTO,
|
||||||
|
saleInvoice,
|
||||||
|
trx,
|
||||||
|
}: ISaleInvoiceCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = saleInvoiceDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleInvoice',
|
||||||
|
saleInvoice.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited sale invoice.
|
||||||
|
* @param {ISaleInvoiceEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnInvoiceEdited({
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceDTO,
|
||||||
|
saleInvoice,
|
||||||
|
}: ISaleInvoiceEditedPayload) {
|
||||||
|
// if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = saleInvoiceDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleInvoice',
|
||||||
|
saleInvoice.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited sale invoice.
|
||||||
|
* @param {ISaleInvoiceEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnInvoiceEdited({
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceDTO,
|
||||||
|
oldSaleInvoice,
|
||||||
|
trx,
|
||||||
|
}: ISaleInvoiceEditedPayload) {
|
||||||
|
if (isEmpty(saleInvoiceDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = saleInvoiceDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleInvoice',
|
||||||
|
oldSaleInvoice.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the invoice deleted.
|
||||||
|
* @param {ISaleInvoiceDeletedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnInvoiceDeleted({
|
||||||
|
tenantId,
|
||||||
|
saleInvoice,
|
||||||
|
trx,
|
||||||
|
}: ISaleInvoiceDeletePayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'SaleInvoice',
|
||||||
|
saleInvoice.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
ISaleReceiptCreatedPayload,
|
||||||
|
ISaleReceiptCreatingPayload,
|
||||||
|
ISaleReceiptDeletingPayload,
|
||||||
|
ISaleReceiptEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnSaleReceipt {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleReceipt.onCreating,
|
||||||
|
this.validateAttachmentsOnSaleInvoiceCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleReceipt.onCreated,
|
||||||
|
this.handleAttachmentsOnSaleInvoiceCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleReceipt.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnInvoiceEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleReceipt.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnInvoiceEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleReceipt.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnReceiptDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating sale receipt.
|
||||||
|
* @param {ISaleReceiptCreatingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnSaleInvoiceCreate({
|
||||||
|
saleReceiptDTO,
|
||||||
|
tenantId,
|
||||||
|
}: ISaleReceiptCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(saleReceiptDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = saleReceiptDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created sale receipt.
|
||||||
|
* @param {ISaleReceiptCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnSaleInvoiceCreated({
|
||||||
|
tenantId,
|
||||||
|
saleReceiptDTO,
|
||||||
|
saleReceipt,
|
||||||
|
trx,
|
||||||
|
}: ISaleReceiptCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(saleReceiptDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = saleReceiptDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleReceipt',
|
||||||
|
saleReceipt.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited sale receipt.
|
||||||
|
* @param {ISaleReceiptEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnInvoiceEdited({
|
||||||
|
tenantId,
|
||||||
|
saleReceiptDTO,
|
||||||
|
saleReceipt,
|
||||||
|
}: ISaleReceiptEditedPayload) {
|
||||||
|
const keys = saleReceiptDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleReceipt',
|
||||||
|
saleReceipt.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited sale receipt.
|
||||||
|
* @param {ISaleReceiptEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnInvoiceEdited({
|
||||||
|
tenantId,
|
||||||
|
saleReceiptDTO,
|
||||||
|
oldSaleReceipt,
|
||||||
|
trx,
|
||||||
|
}: ISaleReceiptEditedPayload) {
|
||||||
|
if (isEmpty(saleReceiptDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = saleReceiptDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'SaleReceipt',
|
||||||
|
oldSaleReceipt.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the receipt deleted.
|
||||||
|
* @param {ISaleReceiptDeletingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnReceiptDeleted({
|
||||||
|
tenantId,
|
||||||
|
oldSaleReceipt,
|
||||||
|
trx,
|
||||||
|
}: ISaleReceiptDeletingPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'SaleReceipt',
|
||||||
|
oldSaleReceipt.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import {
|
||||||
|
IVendorCreditCreatedPayload,
|
||||||
|
IVendorCreditCreatingPayload,
|
||||||
|
IVendorCreditDeletingPayload,
|
||||||
|
IVendorCreditEditedPayload,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { LinkAttachment } from '../LinkAttachment';
|
||||||
|
import { ValidateAttachments } from '../ValidateAttachments';
|
||||||
|
import { UnlinkAttachment } from '../UnlinkAttachment';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class AttachmentsOnVendorCredits {
|
||||||
|
@Inject()
|
||||||
|
private linkAttachmentService: LinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private unlinkAttachmentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private validateDocuments: ValidateAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
public attach(bus) {
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onCreating,
|
||||||
|
this.validateAttachmentsOnVendorCreditCreate.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onCreated,
|
||||||
|
this.handleAttachmentsOnVendorCreditCreated.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onEdited,
|
||||||
|
this.handleUnlinkUnpresentedKeysOnVendorCreditEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onEdited,
|
||||||
|
this.handleLinkPresentedKeysOnVendorCreditEdited.bind(this)
|
||||||
|
);
|
||||||
|
bus.subscribe(
|
||||||
|
events.saleInvoice.onDeleting,
|
||||||
|
this.handleUnlinkAttachmentsOnVendorCreditDeleted.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the attachment keys on creating vendor credit.
|
||||||
|
* @param {IVendorCreditCreatingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async validateAttachmentsOnVendorCreditCreate({
|
||||||
|
vendorCreditCreateDTO,
|
||||||
|
tenantId,
|
||||||
|
}: IVendorCreditCreatingPayload): Promise<void> {
|
||||||
|
if (isEmpty(vendorCreditCreateDTO.attachments)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const documentKeys = vendorCreditCreateDTO?.attachments?.map((a) => a.key);
|
||||||
|
|
||||||
|
await this.validateDocuments.validate(tenantId, documentKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking the attachments of the created vendor credit.
|
||||||
|
* @param {IVendorCreditCreatedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleAttachmentsOnVendorCreditCreated({
|
||||||
|
tenantId,
|
||||||
|
vendorCreditCreateDTO,
|
||||||
|
vendorCredit,
|
||||||
|
trx,
|
||||||
|
}: IVendorCreditCreatedPayload): Promise<void> {
|
||||||
|
if (isEmpty(vendorCreditCreateDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = vendorCreditCreateDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'VendorCredit',
|
||||||
|
vendorCredit.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unlinking all the unpresented keys of the edited vendor credit.
|
||||||
|
* @param {IVendorCreditEditedPayload}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkUnpresentedKeysOnVendorCreditEdited({
|
||||||
|
tenantId,
|
||||||
|
vendorCreditDTO,
|
||||||
|
oldVendorCredit,
|
||||||
|
}: IVendorCreditEditedPayload) {
|
||||||
|
const keys = vendorCreditDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.unlinkAttachmentService.unlinkUnpresentedKeys(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'VendorCredit',
|
||||||
|
oldVendorCredit.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles linking all the presented keys of the edited vendor credit.
|
||||||
|
* @param {IVendorCreditEditedPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleLinkPresentedKeysOnVendorCreditEdited({
|
||||||
|
tenantId,
|
||||||
|
vendorCreditDTO,
|
||||||
|
oldVendorCredit,
|
||||||
|
trx,
|
||||||
|
}: IVendorCreditEditedPayload) {
|
||||||
|
if (isEmpty(vendorCreditDTO.attachments)) return;
|
||||||
|
|
||||||
|
const keys = vendorCreditDTO.attachments?.map(
|
||||||
|
(attachment) => attachment.key
|
||||||
|
);
|
||||||
|
await this.linkAttachmentService.bulkLink(
|
||||||
|
tenantId,
|
||||||
|
keys,
|
||||||
|
'VendorCredit',
|
||||||
|
oldVendorCredit.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all attachments once the vendor credit deleted.
|
||||||
|
* @param {IVendorCreditDeletingPayload}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
private async handleUnlinkAttachmentsOnVendorCreditDeleted({
|
||||||
|
tenantId,
|
||||||
|
oldVendorCredit,
|
||||||
|
trx,
|
||||||
|
}: IVendorCreditDeletingPayload) {
|
||||||
|
await this.unlinkAttachmentService.unlinkAllModelKeys(
|
||||||
|
tenantId,
|
||||||
|
'VendorCredit',
|
||||||
|
oldVendorCredit.id,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,7 +57,7 @@ export default class BaseCreditNotes {
|
|||||||
autoNextNumber;
|
autoNextNumber;
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
...omit(creditNoteDTO, ['open']),
|
...omit(creditNoteDTO, ['open', 'attachments']),
|
||||||
creditNoteNumber,
|
creditNoteNumber,
|
||||||
amount,
|
amount,
|
||||||
currencyCode: customerCurrencyCode,
|
currencyCode: customerCurrencyCode,
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ export class CreateExpense {
|
|||||||
tenantId,
|
tenantId,
|
||||||
expenseId: expense.id,
|
expenseId: expense.id,
|
||||||
authorizedUser,
|
authorizedUser,
|
||||||
|
expenseDTO,
|
||||||
expense,
|
expense,
|
||||||
trx,
|
trx,
|
||||||
} as IExpenseCreatedPayload);
|
} as IExpenseCreatedPayload);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export class ExpenseDTOTransformer {
|
|||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
categories: [],
|
categories: [],
|
||||||
...omit(expenseDTO, ['publish']),
|
...omit(expenseDTO, ['publish', 'attachments']),
|
||||||
totalAmount,
|
totalAmount,
|
||||||
landedCostAmount,
|
landedCostAmount,
|
||||||
paymentDate: moment(expenseDTO.paymentDate).toMySqlDateTime(),
|
paymentDate: moment(expenseDTO.paymentDate).toMySqlDateTime(),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Transformer } from '@/lib/Transformer/Transformer';
|
|||||||
import { formatNumber } from 'utils';
|
import { formatNumber } from 'utils';
|
||||||
import { IExpense } from '@/interfaces';
|
import { IExpense } from '@/interfaces';
|
||||||
import { ExpenseCategoryTransformer } from './ExpenseCategoryTransformer';
|
import { ExpenseCategoryTransformer } from './ExpenseCategoryTransformer';
|
||||||
|
import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer';
|
||||||
|
|
||||||
export class ExpenseTransfromer extends Transformer {
|
export class ExpenseTransfromer extends Transformer {
|
||||||
/**
|
/**
|
||||||
@@ -15,6 +16,7 @@ export class ExpenseTransfromer extends Transformer {
|
|||||||
'formattedAllocatedCostAmount',
|
'formattedAllocatedCostAmount',
|
||||||
'formattedDate',
|
'formattedDate',
|
||||||
'categories',
|
'categories',
|
||||||
|
'attachments',
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,4 +72,13 @@ export class ExpenseTransfromer extends Transformer {
|
|||||||
currencyCode: expense.currencyCode,
|
currencyCode: expense.currencyCode,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the sale invoice attachments.
|
||||||
|
* @param {ISaleInvoice} invoice
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
protected attachments = (expense: IExpense) => {
|
||||||
|
return this.item(expense.attachments, new AttachmentTransformer());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export class GetExpense {
|
|||||||
.withGraphFetched('categories.expenseAccount')
|
.withGraphFetched('categories.expenseAccount')
|
||||||
.withGraphFetched('paymentAccount')
|
.withGraphFetched('paymentAccount')
|
||||||
.withGraphFetched('branch')
|
.withGraphFetched('branch')
|
||||||
|
.withGraphFetched('attachments')
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
// Transformes expense model to POJO.
|
// Transformes expense model to POJO.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import { Tenant, TenantMetadata } from '@/system/models';
|
import { TenantMetadata } from '@/system/models';
|
||||||
import UnitOfWork from '@/services/UnitOfWork';
|
import UnitOfWork from '@/services/UnitOfWork';
|
||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
import { CommandManualJournalValidators } from './CommandManualJournalValidators';
|
import { CommandManualJournalValidators } from './CommandManualJournalValidators';
|
||||||
@@ -59,7 +59,7 @@ export class CreateManualJournalService {
|
|||||||
const journalNumber = manualJournalDTO.journalNumber || autoNextNumber;
|
const journalNumber = manualJournalDTO.journalNumber || autoNextNumber;
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
...omit(manualJournalDTO, ['publish']),
|
...omit(manualJournalDTO, ['publish', 'attachments']),
|
||||||
...(manualJournalDTO.publish
|
...(manualJournalDTO.publish
|
||||||
? { publishedAt: moment().toMySqlDateTime() }
|
? { publishedAt: moment().toMySqlDateTime() }
|
||||||
: {}),
|
: {}),
|
||||||
@@ -173,6 +173,7 @@ export class CreateManualJournalService {
|
|||||||
tenantId,
|
tenantId,
|
||||||
manualJournal,
|
manualJournal,
|
||||||
manualJournalId: manualJournal.id,
|
manualJournalId: manualJournal.id,
|
||||||
|
manualJournalDTO,
|
||||||
trx,
|
trx,
|
||||||
} as IManualJournalEventCreatedPayload);
|
} as IManualJournalEventCreatedPayload);
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ export class CreateBillPayment {
|
|||||||
tenantId,
|
tenantId,
|
||||||
billPayment,
|
billPayment,
|
||||||
billPaymentId: billPayment.id,
|
billPaymentId: billPayment.id,
|
||||||
|
billPaymentDTO,
|
||||||
trx,
|
trx,
|
||||||
} as IBillPaymentEventCreatedPayload);
|
} as IBillPaymentEventCreatedPayload);
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ export class EditBillPayment {
|
|||||||
billPaymentId,
|
billPaymentId,
|
||||||
billPayment,
|
billPayment,
|
||||||
oldBillPayment,
|
oldBillPayment,
|
||||||
|
billPaymentDTO,
|
||||||
trx,
|
trx,
|
||||||
} as IBillPaymentEventEditedPayload);
|
} as IBillPaymentEventEditedPayload);
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ export class BillDTOTransformer {
|
|||||||
)(asyncEntries);
|
)(asyncEntries);
|
||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
...formatDateFields(omit(billDTO, ['open', 'entries']), [
|
...formatDateFields(omit(billDTO, ['open', 'entries', 'attachments']), [
|
||||||
'billDate',
|
'billDate',
|
||||||
'dueDate',
|
'dueDate',
|
||||||
]),
|
]),
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ export class CreateBill {
|
|||||||
tenantId,
|
tenantId,
|
||||||
bill,
|
bill,
|
||||||
billId: bill.id,
|
billId: bill.id,
|
||||||
|
billDTO,
|
||||||
trx,
|
trx,
|
||||||
} as IBillCreatedPayload);
|
} as IBillCreatedPayload);
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ export class EditBill {
|
|||||||
billId,
|
billId,
|
||||||
oldBill,
|
oldBill,
|
||||||
bill,
|
bill,
|
||||||
|
billDTO,
|
||||||
trx,
|
trx,
|
||||||
} as IBillEditedPayload);
|
} as IBillEditedPayload);
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ export default class EditVendorCredit extends BaseVendorCredit {
|
|||||||
oldVendorCredit,
|
oldVendorCredit,
|
||||||
vendorCredit,
|
vendorCredit,
|
||||||
vendorCreditId,
|
vendorCreditId,
|
||||||
|
vendorCreditDTO,
|
||||||
trx,
|
trx,
|
||||||
} as IVendorCreditEditedPayload);
|
} as IVendorCreditEditedPayload);
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ export class EditSaleEstimate {
|
|||||||
estimateId,
|
estimateId,
|
||||||
saleEstimate,
|
saleEstimate,
|
||||||
oldSaleEstimate,
|
oldSaleEstimate,
|
||||||
|
estimateDTO,
|
||||||
trx,
|
trx,
|
||||||
} as ISaleEstimateEditedPayload);
|
} as ISaleEstimateEditedPayload);
|
||||||
|
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ export class SaleEstimateDTOTransformer {
|
|||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
amount,
|
amount,
|
||||||
...formatDateFields(omit(estimateDTO, ['delivered', 'entries']), [
|
...formatDateFields(
|
||||||
'estimateDate',
|
omit(estimateDTO, ['delivered', 'entries', 'attachments']),
|
||||||
'expirationDate',
|
['estimateDate', 'expirationDate']
|
||||||
]),
|
),
|
||||||
currencyCode: paymentCustomer.currencyCode,
|
currencyCode: paymentCustomer.currencyCode,
|
||||||
exchangeRate: estimateDTO.exchangeRate || 1,
|
exchangeRate: estimateDTO.exchangeRate || 1,
|
||||||
...(estimateNumber ? { estimateNumber } : {}),
|
...(estimateNumber ? { estimateNumber } : {}),
|
||||||
|
|||||||
@@ -86,7 +86,12 @@ export class CommandSaleInvoiceDTOTransformer {
|
|||||||
|
|
||||||
const initialDTO = {
|
const initialDTO = {
|
||||||
...formatDateFields(
|
...formatDateFields(
|
||||||
omit(saleInvoiceDTO, ['delivered', 'entries', 'fromEstimateId']),
|
omit(saleInvoiceDTO, [
|
||||||
|
'delivered',
|
||||||
|
'entries',
|
||||||
|
'fromEstimateId',
|
||||||
|
'attachments',
|
||||||
|
]),
|
||||||
['invoiceDate', 'dueDate']
|
['invoiceDate', 'dueDate']
|
||||||
),
|
),
|
||||||
// Avoid rewrite the deliver date in edit mode when already published.
|
// Avoid rewrite the deliver date in edit mode when already published.
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ export class GetSaleInvoice {
|
|||||||
.withGraphFetched('entries.tax')
|
.withGraphFetched('entries.tax')
|
||||||
.withGraphFetched('customer')
|
.withGraphFetched('customer')
|
||||||
.withGraphFetched('branch')
|
.withGraphFetched('branch')
|
||||||
.withGraphFetched('taxes.taxRate');
|
.withGraphFetched('taxes.taxRate')
|
||||||
|
.withGraphFetched('attachments');
|
||||||
|
|
||||||
// Validates the given sale invoice existance.
|
// Validates the given sale invoice existance.
|
||||||
this.validators.validateInvoiceExistance(saleInvoice);
|
this.validators.validateInvoiceExistance(saleInvoice);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Transformer } from '@/lib/Transformer/Transformer';
|
|||||||
import { formatNumber } from 'utils';
|
import { formatNumber } from 'utils';
|
||||||
import { SaleInvoiceTaxEntryTransformer } from './SaleInvoiceTaxEntryTransformer';
|
import { SaleInvoiceTaxEntryTransformer } from './SaleInvoiceTaxEntryTransformer';
|
||||||
import { ItemEntryTransformer } from './ItemEntryTransformer';
|
import { ItemEntryTransformer } from './ItemEntryTransformer';
|
||||||
|
import { AttachmentTransformer } from '@/services/Attachments/AttachmentTransformer';
|
||||||
|
|
||||||
export class SaleInvoiceTransformer extends Transformer {
|
export class SaleInvoiceTransformer extends Transformer {
|
||||||
/**
|
/**
|
||||||
@@ -25,6 +26,7 @@ export class SaleInvoiceTransformer extends Transformer {
|
|||||||
'totalLocalFormatted',
|
'totalLocalFormatted',
|
||||||
'taxes',
|
'taxes',
|
||||||
'entries',
|
'entries',
|
||||||
|
'attachments',
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -190,4 +192,13 @@ export class SaleInvoiceTransformer extends Transformer {
|
|||||||
currencyCode: invoice.currencyCode,
|
currencyCode: invoice.currencyCode,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the sale invoice attachments.
|
||||||
|
* @param {ISaleInvoice} invoice
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
protected attachments = (invoice) => {
|
||||||
|
return this.item(invoice.attachments, new AttachmentTransformer());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ export class CreatePaymentReceive {
|
|||||||
tenantId,
|
tenantId,
|
||||||
paymentReceive,
|
paymentReceive,
|
||||||
paymentReceiveId: paymentReceive.id,
|
paymentReceiveId: paymentReceive.id,
|
||||||
|
paymentReceiveDTO,
|
||||||
authorizedUser,
|
authorizedUser,
|
||||||
trx,
|
trx,
|
||||||
} as IPaymentReceiveCreatedPayload);
|
} as IPaymentReceiveCreatedPayload);
|
||||||
|
|||||||
Reference in New Issue
Block a user