diff --git a/server/src/api/controllers/Sales/PaymentReceives.ts b/server/src/api/controllers/Sales/PaymentReceives.ts index 9d26a7f2f..e5dda2676 100644 --- a/server/src/api/controllers/Sales/PaymentReceives.ts +++ b/server/src/api/controllers/Sales/PaymentReceives.ts @@ -80,7 +80,6 @@ export default class PaymentReceivesController extends BaseController { */ get paymentReceiveSchema(): ValidationChain[] { return [ - check('customer_id').exists().isNumeric().toInt(), check('payment_date').exists(), check('reference_no').optional(), check('deposit_account_id').exists().isNumeric().toInt(), @@ -121,7 +120,10 @@ export default class PaymentReceivesController extends BaseController { * @return {Array} */ get newPaymentReceiveValidation() { - return [...this.paymentReceiveSchema]; + return [ + check('customer_id').exists().isNumeric().toInt(), + ...this.paymentReceiveSchema, + ]; } /** @@ -172,7 +174,10 @@ export default class PaymentReceivesController extends BaseController { await this.paymentReceiveService.editPaymentReceive( tenantId, paymentReceiveId, paymentReceive, ); - return res.status(200).send({ id: paymentReceiveId }); + return res.status(200).send({ + id: paymentReceiveId, + message: 'The payment receive has been edited successfully.' + }); } catch (error) { next(error); } diff --git a/server/src/api/controllers/Sales/SalesInvoices.ts b/server/src/api/controllers/Sales/SalesInvoices.ts index 46b206914..b601dd48b 100644 --- a/server/src/api/controllers/Sales/SalesInvoices.ts +++ b/server/src/api/controllers/Sales/SalesInvoices.ts @@ -206,7 +206,7 @@ export default class SaleInvoicesController extends BaseController { return res.status(200).send({ id: saleInvoiceId, - message: 'The given sale invoice has been published successfully', + message: 'The given sale invoice has been delivered successfully', }); } catch (error) { next(error); diff --git a/server/src/interfaces/PaymentReceive.ts b/server/src/interfaces/PaymentReceive.ts index 2085a3086..60c9c12d4 100644 --- a/server/src/interfaces/PaymentReceive.ts +++ b/server/src/interfaces/PaymentReceive.ts @@ -13,7 +13,7 @@ export interface IPaymentReceive { entries: IPaymentReceiveEntry[], userId: number, }; -export interface IPaymentReceiveDTO { +export interface IPaymentReceiveCreateDTO { customerId: number, paymentDate: Date, amount: number, @@ -24,6 +24,16 @@ export interface IPaymentReceiveDTO { entries: IPaymentReceiveEntryDTO[], }; +export interface IPaymentReceiveEditDTO { + paymentDate: Date, + amount: number, + referenceNo: string, + depositAccountId: number, + paymentReceiveNo?: string, + description: string, + entries: IPaymentReceiveEntryDTO[], +}; + export interface IPaymentReceiveEntry { id?: number, paymentReceiveId: number, diff --git a/server/src/interfaces/SaleInvoice.ts b/server/src/interfaces/SaleInvoice.ts index e5e77d898..63a40bf96 100644 --- a/server/src/interfaces/SaleInvoice.ts +++ b/server/src/interfaces/SaleInvoice.ts @@ -25,7 +25,7 @@ export interface ISaleInvoiceDTO { } export interface ISaleInvoiceCreateDTO extends ISaleInvoiceDTO { - fromEstiamteId: number, + fromEstimateId: number, }; export interface ISaleInvoiceEditDTO extends ISaleInvoiceDTO { diff --git a/server/src/services/Sales/HasItemsEntries.ts b/server/src/services/Sales/HasItemsEntries.ts index 2754bfd60..ccac4a475 100644 --- a/server/src/services/Sales/HasItemsEntries.ts +++ b/server/src/services/Sales/HasItemsEntries.ts @@ -8,62 +8,6 @@ export default class HasItemEntries { @Inject() tenancy: TenancyService; - /** - * Patch items entries to the storage. - * - * @param {Array} newEntries - - * @param {Array} oldEntries - - * @param {String} referenceType - - * @param {String|Number} referenceId - - * @return {Promise} - */ - async patchItemsEntries( - tenantId: number, - newEntries: Array, - oldEntries: Array, - referenceType: string, - referenceId: string|number - ) { - const { ItemEntry } = this.tenancy.models(tenantId); - - const entriesHasIds = newEntries.filter((entry) => entry.id); - const entriesHasNoIds = newEntries.filter((entry) => !entry.id); - const entriesIds = entriesHasIds.map(entry => entry.id); - - const oldEntriesIds = oldEntries.map((e) => e.id); - const excludeAttrs = ['id', 'amount']; - const opers = []; - - const entriesIdsShouldDelete = difference( - oldEntriesIds, - entriesIds, - ); - if (entriesIdsShouldDelete.length > 0) { - const deleteOper = ItemEntry.query() - .whereIn('id', entriesIdsShouldDelete) - .delete(); - opers.push(deleteOper); - } - entriesHasIds.forEach((entry) => { - const updateOper = ItemEntry.query() - .where('id', entry.id) - .update({ - ...omit(entry, excludeAttrs), - }); - opers.push(updateOper); - }); - entriesHasNoIds.forEach((entry) => { - const insertOper = ItemEntry.query() - .insert({ - reference_id: referenceId, - reference_type: referenceType, - ...omit(entry, excludeAttrs), - }); - opers.push(insertOper); - }); - return Promise.all([...opers]); - } - filterNonInventoryEntries(entries: [], items: []) { const nonInventoryItems = items.filter((item: any) => item.type !== 'inventory'); const nonInventoryItemsIds = nonInventoryItems.map((i: any) => i.id); diff --git a/server/src/services/Sales/PaymentsReceives.ts b/server/src/services/Sales/PaymentsReceives.ts index d4fd3028a..d6fa68687 100644 --- a/server/src/services/Sales/PaymentsReceives.ts +++ b/server/src/services/Sales/PaymentsReceives.ts @@ -12,6 +12,8 @@ import { IPaginationMeta, IPaymentReceive, IPaymentReceiveDTO, + IPaymentReceiveCreateDTO, + IPaymentReceiveEditDTO, IPaymentReceiveEntry, IPaymentReceiveEntryDTO, IPaymentReceivesFilter, @@ -236,7 +238,7 @@ export default class PaymentReceiveService { * @param {number} tenantId - Tenant id. * @param {IPaymentReceive} paymentReceive */ - public async createPaymentReceive(tenantId: number, paymentReceiveDTO: IPaymentReceiveDTO) { + public async createPaymentReceive(tenantId: number, paymentReceiveDTO: IPaymentReceiveCreateDTO) { const { PaymentReceive } = this.tenancy.models(tenantId); const paymentAmount = sumBy(paymentReceiveDTO.entries, 'paymentAmount'); @@ -293,7 +295,7 @@ export default class PaymentReceiveService { public async editPaymentReceive( tenantId: number, paymentReceiveId: number, - paymentReceiveDTO: any, + paymentReceiveDTO: IPaymentReceiveEditDTO, ) { const { PaymentReceive } = this.tenancy.models(tenantId); const paymentAmount = sumBy(paymentReceiveDTO.entries, 'paymentAmount'); @@ -310,14 +312,11 @@ export default class PaymentReceiveService { // Validate the deposit account existance and type. this.getDepositAccountOrThrowError(tenantId, paymentReceiveDTO.depositAccountId); - // Validate customer existance. - await this.customersService.getCustomerByIdOrThrowError(tenantId, paymentReceiveDTO.customerId); - // Validate the entries ids existance on payment receive type. await this.validateEntriesIdsExistance(tenantId, paymentReceiveId, paymentReceiveDTO.entries); // Validate payment receive invoices IDs existance and associated to the given customer id. - await this.validateInvoicesIDsExistance(tenantId, paymentReceiveDTO.customerId, paymentReceiveDTO.entries); + await this.validateInvoicesIDsExistance(tenantId, oldPaymentReceive.customerId, paymentReceiveDTO.entries); // Validate invoice payment amount. await this.validateInvoicesPaymentsAmount(tenantId, paymentReceiveDTO.entries, oldPaymentReceive.entries); @@ -536,7 +535,7 @@ export default class PaymentReceiveService { * @param {number} tenantId - Tenant id. * @param {Array} paymentReceiveEntries * @param {Array} newPaymentReceiveEntries - * @return + * @return {Promise} */ public async saveChangeInvoicePaymentAmount( tenantId: number, diff --git a/server/src/subscribers/paymentReceives.ts b/server/src/subscribers/paymentReceives.ts index 861dc4d86..9f5505e13 100644 --- a/server/src/subscribers/paymentReceives.ts +++ b/server/src/subscribers/paymentReceives.ts @@ -17,7 +17,6 @@ export default class PaymentReceivesSubscriber { this.tenancy = Container.get(TenancyService); this.logger = Container.get('logger'); this.paymentReceivesService = Container.get(PaymentReceiveService); - this.settingsService = Container.get(SettingsService); } @@ -25,39 +24,17 @@ export default class PaymentReceivesSubscriber { * Handle customer balance decrement once payment receive created. */ @On(events.paymentReceive.onCreated) - async handleCustomerBalanceDecrement({ tenantId, paymentReceiveId, paymentReceive }) { + async handleCustomerBalanceDecrement({ + tenantId, + paymentReceiveId, + paymentReceive, + }) { const { customerRepository } = this.tenancy.repositories(tenantId); this.logger.info('[payment_receive] trying to decrement customer balance.'); - await customerRepository.changeBalance(paymentReceive.customerId, paymentReceive.amount * -1); - } - - /** - * Handle sale invoice increment/decrement payment amount once created, edited or deleted. - */ - @On(events.paymentReceive.onCreated) - @On(events.paymentReceive.onEdited) - async handleInvoiceIncrementPaymentAmount({ tenantId, paymentReceiveId, paymentReceive, oldPaymentReceive }) { - - this.logger.info('[payment_receive] trying to change sale invoice payment amount.', { tenantId }); - await this.paymentReceivesService.saveChangeInvoicePaymentAmount( - tenantId, - paymentReceive.entries, - oldPaymentReceive?.entries || null, - ); - } - - /** - * Handle revert invoices payment amount once payment receive deleted. - */ - @On(events.paymentReceive.onDeleted) - async handleInvoiceDecrementPaymentAmount({ tenantId, paymentReceiveId, oldPaymentReceive }) { - this.logger.info('[payment_receive] trying to decrement sale invoice payment amount.'); - - await this.paymentReceivesService.saveChangeInvoicePaymentAmount( - tenantId, - oldPaymentReceive.entries.map((entry) => ({ ...entry, paymentAmount: 0 })), - oldPaymentReceive.entries, + await customerRepository.changeBalance( + paymentReceive.customerId, + paymentReceive.amount * -1 ); } @@ -65,13 +42,17 @@ export default class PaymentReceivesSubscriber { * Handle customer balance increment once payment receive deleted. */ @On(events.paymentReceive.onDeleted) - async handleCustomerBalanceIncrement({ tenantId, paymentReceiveId, oldPaymentReceive }) { + async handleCustomerBalanceIncrement({ + tenantId, + paymentReceiveId, + oldPaymentReceive, + }) { const { customerRepository } = this.tenancy.repositories(tenantId); this.logger.info('[payment_receive] trying to increment customer balance.'); await customerRepository.changeBalance( oldPaymentReceive.customerId, - oldPaymentReceive.amount, + oldPaymentReceive.amount ); } @@ -79,14 +60,62 @@ export default class PaymentReceivesSubscriber { * Handles customer balance diff balance change once payment receive edited. */ @On(events.paymentReceive.onEdited) - async handleCustomerBalanceDiffChange({ tenantId, paymentReceiveId, paymentReceive, oldPaymentReceive }) { + async handleCustomerBalanceDiffChange({ + tenantId, + paymentReceiveId, + paymentReceive, + oldPaymentReceive, + }) { const { customerRepository } = this.tenancy.repositories(tenantId); await customerRepository.changeDiffBalance( paymentReceive.customerId, paymentReceive.amount * -1, oldPaymentReceive.amount * -1, - oldPaymentReceive.customerId, + ); + } + + /** + * Handle sale invoice increment/decrement payment amount once created, edited or deleted. + */ + @On(events.paymentReceive.onCreated) + @On(events.paymentReceive.onEdited) + async handleInvoiceIncrementPaymentAmount({ + tenantId, + paymentReceiveId, + paymentReceive, + oldPaymentReceive, + }) { + this.logger.info( + '[payment_receive] trying to change sale invoice payment amount.', + { tenantId } + ); + await this.paymentReceivesService.saveChangeInvoicePaymentAmount( + tenantId, + paymentReceive.entries, + oldPaymentReceive?.entries || null + ); + } + + /** + * Handle revert invoices payment amount once payment receive deleted. + */ + @On(events.paymentReceive.onDeleted) + async handleInvoiceDecrementPaymentAmount({ + tenantId, + paymentReceiveId, + oldPaymentReceive, + }) { + this.logger.info( + '[payment_receive] trying to decrement sale invoice payment amount.' + ); + await this.paymentReceivesService.saveChangeInvoicePaymentAmount( + tenantId, + oldPaymentReceive.entries.map((entry) => ({ + ...entry, + paymentAmount: 0, + })), + oldPaymentReceive.entries ); } @@ -94,10 +123,13 @@ export default class PaymentReceivesSubscriber { * Handles increment next number of payment receive once be created. */ @On(events.paymentReceive.onCreated) - public async handlePaymentNextNumberIncrement({ tenantId, paymentReceiveId }) { + public async handlePaymentNextNumberIncrement({ + tenantId, + paymentReceiveId, + }) { await this.settingsService.incrementNextNumber(tenantId, { key: 'next_number', group: 'payment_receives', }); } -} \ No newline at end of file +} diff --git a/server/src/utils/index.js b/server/src/utils/index.js index 2b4061414..1c9fc2ea3 100644 --- a/server/src/utils/index.js +++ b/server/src/utils/index.js @@ -190,10 +190,15 @@ const entriesAmountDiff = ( .mapValues((group) => _.sumBy(group, amountAttribute) || 0) .value(); - return _.chain(newEntries) + const newEntriesTable = _.chain(newEntries) .groupBy(idAttribute) .mapValues((group) => _.sumBy(group, amountAttribute) || 0) - .mapValues((value, key) => value - (oldEntriesTable[key] || 0)) + .mergeWith(oldEntriesTable, (objValue, srcValue) => { + return (_.isNumber(objValue) ? objValue - srcValue : srcValue * -1); + }) + .value(); + + return _.chain(newEntriesTable) .mapValues((value, key) => ({ [idAttribute]: key, [amountAttribute]: value,