diff --git a/server/src/api/controllers/Sales/PaymentReceives.ts b/server/src/api/controllers/Sales/PaymentReceives.ts index 1a25a6c6a..d86031151 100644 --- a/server/src/api/controllers/Sales/PaymentReceives.ts +++ b/server/src/api/controllers/Sales/PaymentReceives.ts @@ -178,13 +178,11 @@ export default class PaymentReceivesController extends BaseController { const { id: paymentReceiveId } = req.params; try { - await this.paymentReceiveService.deletePaymentReceive( - tenantId, - paymentReceiveId, - ); + await this.paymentReceiveService.deletePaymentReceive(tenantId, paymentReceiveId); + return res.status(200).send({ id: paymentReceiveId, - message: 'The payment receive has been edited successfully', + message: 'The payment receive has been deleted successfully', }); } catch (error) { next(error); diff --git a/server/src/api/controllers/Sales/SalesInvoices.ts b/server/src/api/controllers/Sales/SalesInvoices.ts index 938179819..df4fb1fa0 100644 --- a/server/src/api/controllers/Sales/SalesInvoices.ts +++ b/server/src/api/controllers/Sales/SalesInvoices.ts @@ -331,7 +331,6 @@ export default class SaleInvoicesController extends BaseController{ }); } } - console.log(error.errorType); next(error); } } diff --git a/server/src/models/Contact.js b/server/src/models/Contact.js index 9fd718ecd..35fbd255f 100644 --- a/server/src/models/Contact.js +++ b/server/src/models/Contact.js @@ -16,6 +16,20 @@ export default class Contact extends TenantModel { return ['createdAt', 'updatedAt']; } + /** + * Defined virtual attributes. + */ + static get virtualAttributes() { + return ['closingBalance']; + } + + /** + * Closing balance attribute. + */ + closingBalance() { + return this.openingBalance + this.balance; + } + /** * Model modifiers. */ diff --git a/server/src/services/Purchases/BillPayments.ts b/server/src/services/Purchases/BillPayments.ts index 0e7494b9a..8fd3c6366 100644 --- a/server/src/services/Purchases/BillPayments.ts +++ b/server/src/services/Purchases/BillPayments.ts @@ -146,17 +146,14 @@ export default class BillPaymentsService { * @param {Response} res * @param {NextFunction} next */ - private async validateBillsExistance(tenantId: number, billPaymentEntries: IBillPaymentEntry[], notVendorId?: number) { + private async validateBillsExistance(tenantId: number, billPaymentEntries: IBillPaymentEntry[], vendorId: number) { const { Bill } = this.tenancy.models(tenantId); const entriesBillsIds = billPaymentEntries.map((e: any) => e.billId); - const storedBills = await Bill.query().onBuild((builder) => { - builder.whereIn('id', entriesBillsIds); + const storedBills = await Bill.query() + .whereIn('id', entriesBillsIds) + .where('vendor_id', vendorId); - if (notVendorId) { - builder.where('vendor_id', notVendorId); - } - }); const storedBillsIds = storedBills.map((t: IBill) => t.id); const notFoundBillsIds = difference(entriesBillsIds, storedBillsIds); @@ -252,14 +249,24 @@ export default class BillPaymentsService { amount: sumBy(billPaymentDTO.entries, 'paymentAmount'), ...formatDateFields(billPaymentDTO, ['paymentDate']), }; + + // Validate vendor existance on the storage. await this.getVendorOrThrowError(tenantId, billPaymentObj.vendorId); + + // Validate the payment account existance and type. await this.getPaymentAccountOrThrowError(tenantId, billPaymentObj.paymentAccountId); + + // Validate the payment number uniquiness. await this.validatePaymentNumber(tenantId, billPaymentObj.paymentNumber); - await this.validateBillsExistance(tenantId, billPaymentObj.entries); + + // Validates the bills existance and associated to the given vendor. + await this.validateBillsExistance(tenantId, billPaymentObj.entries, billPaymentDTO.vendorId); + + // Validates the bills due payment amount. await this.validateBillsDueAmount(tenantId, billPaymentObj.entries); const billPayment = await BillPayment.query() - .insertGraph({ + .insertGraphAndFetch({ ...omit(billPaymentObj, ['entries']), entries: billPaymentDTO.entries, }); @@ -304,14 +311,23 @@ export default class BillPaymentsService { ...formatDateFields(billPaymentDTO, ['paymentDate']), }; + // Validate vendor existance on the storage. await this.getVendorOrThrowError(tenantId, billPaymentObj.vendorId); + + // Validate the payment account existance and type. await this.getPaymentAccountOrThrowError(tenantId, billPaymentObj.paymentAccountId); + + // Validate the items entries IDs existance on the storage. await this.validateEntriesIdsExistance(tenantId, billPaymentId, billPaymentObj.entries); - await this.validateBillsExistance(tenantId, billPaymentObj.entries); + + // Validate the bills existance and associated to the given vendor. + await this.validateBillsExistance(tenantId, billPaymentObj.entries, billPaymentDTO.vendorId); + + // Validates the bills due payment amount. await this.validateBillsDueAmount(tenantId, billPaymentObj.entries); const billPayment = await BillPayment.query() - .upsertGraph({ + .upsertGraphAndFetch({ id: billPaymentId, ...omit(billPaymentObj, ['entries']), entries: billPaymentDTO.entries, diff --git a/server/src/services/Sales/PaymentsReceives.ts b/server/src/services/Sales/PaymentsReceives.ts index d25691afe..9325599e9 100644 --- a/server/src/services/Sales/PaymentsReceives.ts +++ b/server/src/services/Sales/PaymentsReceives.ts @@ -135,13 +135,15 @@ export default class PaymentReceiveService { * @param {number} tenantId - * @param {} paymentReceiveEntries - */ - async validateInvoicesIDsExistance(tenantId: number, paymentReceiveEntries: any): Promise { + async validateInvoicesIDsExistance(tenantId: number, customerId: number, paymentReceiveEntries: IPaymentReceiveEntryDTO[]): Promise { const { SaleInvoice } = this.tenancy.models(tenantId); - const invoicesIds = paymentReceiveEntries.map((e) => e.invoiceId); - const storedInvoices = await SaleInvoice.query().whereIn('id', invoicesIds); - const storedInvoicesIds = storedInvoices.map((invoice) => invoice.id); + const invoicesIds = paymentReceiveEntries.map((e: IPaymentReceiveEntryDTO) => e.invoiceId); + const storedInvoices = await SaleInvoice.query() + .whereIn('id', invoicesIds) + .where('customer_id', customerId); + const storedInvoicesIds = storedInvoices.map((invoice) => invoice.id); const notFoundInvoicesIDs = difference(invoicesIds, storedInvoicesIds); if (notFoundInvoicesIDs.length > 0) { @@ -200,7 +202,7 @@ export default class PaymentReceiveService { await this.getDepositAccountOrThrowError(tenantId, paymentReceiveDTO.depositAccountId); // Validate payment receive invoices IDs existance. - await this.validateInvoicesIDsExistance(tenantId, paymentReceiveDTO.entries); + await this.validateInvoicesIDsExistance(tenantId, paymentReceiveDTO.customerId, paymentReceiveDTO.entries); // Validate invoice payment amount. await this.validateInvoicesPaymentsAmount(tenantId, paymentReceiveDTO.entries); @@ -265,8 +267,8 @@ export default class PaymentReceiveService { await this.itemsEntries.validateEntriesIdsExistance( tenantId, paymentReceiveId, 'PaymentReceive', paymentReceiveDTO.entries ); - // Validate payment receive invoices IDs existance. - await this.validateInvoicesIDsExistance(tenantId, paymentReceiveDTO.entries); + // Validate payment receive invoices IDs existance and associated to the given customer id. + await this.validateInvoicesIDsExistance(tenantId, paymentReceiveDTO.customerId, paymentReceiveDTO.entries); // Validate invoice payment amount. await this.validateInvoicesPaymentsAmount(tenantId, paymentReceiveDTO.entries); @@ -300,16 +302,16 @@ export default class PaymentReceiveService { * @param {Integer} paymentReceiveId - Payment receive id. * @param {IPaymentReceive} paymentReceive - Payment receive object. */ - async deletePaymentReceive(tenantId: number, paymentReceiveId: number, paymentReceive: any) { + async deletePaymentReceive(tenantId: number, paymentReceiveId: number) { const { PaymentReceive, PaymentReceiveEntry } = this.tenancy.models(tenantId); - const oldPaymentReceive = this.getPaymentReceiveOrThrowError(tenantId, paymentReceiveId); + const oldPaymentReceive = await this.getPaymentReceiveOrThrowError(tenantId, paymentReceiveId); // Deletes the payment receive associated entries. await PaymentReceiveEntry.query().where('payment_receive_id', paymentReceiveId).delete(); // Deletes the payment receive transaction. - await PaymentReceive.query().where('id', paymentReceiveId).delete(); + await PaymentReceive.query().findById(paymentReceiveId).delete(); await this.eventDispatcher.dispatch(events.paymentReceipts.onDeleted, { tenantId, paymentReceiveId, oldPaymentReceive, diff --git a/server/src/services/Sales/SalesReceipts.ts b/server/src/services/Sales/SalesReceipts.ts index 02040f238..f45995f44 100644 --- a/server/src/services/Sales/SalesReceipts.ts +++ b/server/src/services/Sales/SalesReceipts.ts @@ -97,7 +97,7 @@ export default class SalesReceiptService { this.logger.info('[sale_receipt] trying to insert sale receipt graph.', { tenantId, saleReceiptDTO }); const saleReceipt = await SaleReceipt.query() - .insertGraph({ + .insertGraphAndFetch({ ...omit(saleReceiptObj, ['entries']), entries: saleReceiptObj.entries.map((entry) => ({ @@ -133,7 +133,7 @@ export default class SalesReceiptService { await this.itemsEntriesService.validateNonSellableEntriesItems(tenantId, saleReceiptDTO.entries); const saleReceipt = await SaleReceipt.query() - .upsertGraph({ + .upsertGraphAndFetch({ id: saleReceiptId, ...omit(saleReceiptObj, ['entries']), diff --git a/server/src/subscribers/paymentMades.ts b/server/src/subscribers/paymentMades.ts index c0df884d7..1a3e51727 100644 --- a/server/src/subscribers/paymentMades.ts +++ b/server/src/subscribers/paymentMades.ts @@ -51,7 +51,7 @@ export default class PaymentMadesSubscriber { this.logger.info('[bill_payment] trying to increment vendor balance.', { tenantId }); await vendorRepository.changeBalance( billPayment.vendorId, - billPayment.amount, + billPayment.amount * -1, ); } @@ -75,7 +75,7 @@ export default class PaymentMadesSubscriber { await vendorRepository.changeBalance( oldPaymentMade.vendorId, - oldPaymentMade.amount * -1, + oldPaymentMade.amount, ); } diff --git a/server/src/subscribers/paymentReceives.ts b/server/src/subscribers/paymentReceives.ts index 049bf2696..b279a4796 100644 --- a/server/src/subscribers/paymentReceives.ts +++ b/server/src/subscribers/paymentReceives.ts @@ -66,7 +66,10 @@ export default class PaymentReceivesSubscriber { const { customerRepository } = this.tenancy.repositories(tenantId); this.logger.info('[payment_receive] trying to increment customer balance.'); - await customerRepository.changeBalance(oldPaymentReceive.customerId, oldPaymentReceive.amount); + await customerRepository.changeBalance( + oldPaymentReceive.customerId, + oldPaymentReceive.amount, + ); } /** @@ -76,8 +79,6 @@ export default class PaymentReceivesSubscriber { async handleCustomerBalanceDiffChange({ tenantId, paymentReceiveId, paymentReceive, oldPaymentReceive }) { const { customerRepository } = this.tenancy.repositories(tenantId); - console.log(paymentReceive, oldPaymentReceive, 'XX'); - await customerRepository.changeDiffBalance( paymentReceive.customerId, paymentReceive.amount * -1,