fix: delete sale invoice issue.

This commit is contained in:
a.bouhuolia
2021-01-02 11:59:20 +02:00
parent cdee2e5314
commit b5a849abda
3 changed files with 204 additions and 117 deletions

View File

@@ -201,27 +201,6 @@ export default class CustomersController extends ContactsController {
} }
} }
/**
* Deletes the given customer from the storage.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
async deleteCustomer(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const { id: contactId } = req.params;
try {
await this.customersService.deleteCustomer(tenantId, contactId)
return res.status(200).send({
id: contactId,
message: 'The customer has been deleted successfully.',
});
} catch (error) {
next(error);
}
}
/** /**
* Retrieve details of the given customer id. * Retrieve details of the given customer id.
* @param {Request} req * @param {Request} req
@@ -243,6 +222,28 @@ export default class CustomersController extends ContactsController {
} }
} }
/**
* Deletes the given customer from the storage.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
async deleteCustomer(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const { id: contactId } = req.params;
try {
await this.customersService.deleteCustomer(tenantId, contactId);
return res.status(200).send({
id: contactId,
message: 'The customer has been deleted successfully.',
});
} catch (error) {
next(error);
}
}
/** /**
* Deletes customers in bulk. * Deletes customers in bulk.
* @param {Request} req * @param {Request} req

View File

@@ -4,10 +4,10 @@ import {
EventDispatcher, EventDispatcher,
EventDispatcherInterface, EventDispatcherInterface,
} from 'decorators/eventDispatcher'; } from 'decorators/eventDispatcher';
import JournalPoster from "services/Accounting/JournalPoster"; import JournalPoster from 'services/Accounting/JournalPoster';
import JournalCommands from "services/Accounting/JournalCommands"; import JournalCommands from 'services/Accounting/JournalCommands';
import ContactsService from 'services/Contacts/ContactsService'; import ContactsService from 'services/Contacts/ContactsService';
import { import {
ICustomerNewDTO, ICustomerNewDTO,
ICustomerEditDTO, ICustomerEditDTO,
ICustomer, ICustomer,
@@ -17,7 +17,7 @@ import {
IContactEditDTO, IContactEditDTO,
IContact, IContact,
ISaleInvoice, ISaleInvoice,
} from 'interfaces'; } from 'interfaces';
import { ServiceError } from 'exceptions'; import { ServiceError } from 'exceptions';
import TenancyService from 'services/Tenancy/TenancyService'; import TenancyService from 'services/Tenancy/TenancyService';
import DynamicListingService from 'services/DynamicListing/DynamicListService'; import DynamicListingService from 'services/DynamicListing/DynamicListService';
@@ -43,11 +43,11 @@ export default class CustomersService {
/** /**
* Converts customer to contact DTO. * Converts customer to contact DTO.
* @param {ICustomerNewDTO|ICustomerEditDTO} customerDTO * @param {ICustomerNewDTO|ICustomerEditDTO} customerDTO
* @returns {IContactDTO} * @returns {IContactDTO}
*/ */
private customerToContactDTO( private customerToContactDTO(
customerDTO: ICustomerNewDTO | ICustomerEditDTO, customerDTO: ICustomerNewDTO | ICustomerEditDTO
): IContactNewDTO | IContactEditDTO { ): IContactNewDTO | IContactEditDTO {
return { return {
...omit(customerDTO, ['customerType']), ...omit(customerDTO, ['customerType']),
@@ -58,14 +58,17 @@ export default class CustomersService {
/** /**
* Transforms new customer DTO to contact. * Transforms new customer DTO to contact.
* @param customerDTO * @param customerDTO
*/ */
private transformNewCustomerDTO(customerDTO: ICustomerNewDTO): IContactNewDTO { private transformNewCustomerDTO(
customerDTO: ICustomerNewDTO
): IContactNewDTO {
return { return {
...this.customerToContactDTO(customerDTO), ...this.customerToContactDTO(customerDTO),
openingBalanceAt: customerDTO?.openingBalanceAt openingBalanceAt: customerDTO?.openingBalanceAt
? moment(customerDTO.openingBalanceAt).toMySqlDateTime() : null, ? moment(customerDTO.openingBalanceAt).toMySqlDateTime()
} : null,
};
} }
private transformContactToCustomer(contactModel: IContact) { private transformContactToCustomer(contactModel: IContact) {
@@ -77,22 +80,34 @@ export default class CustomersService {
/** /**
* Creates a new customer. * Creates a new customer.
* @param {number} tenantId * @param {number} tenantId
* @param {ICustomerNewDTO} customerDTO * @param {ICustomerNewDTO} customerDTO
* @return {Promise<ICustomer>} * @return {Promise<ICustomer>}
*/ */
public async newCustomer( public async newCustomer(
tenantId: number, tenantId: number,
customerDTO: ICustomerNewDTO customerDTO: ICustomerNewDTO
): Promise<ICustomer> { ): Promise<ICustomer> {
this.logger.info('[customer] trying to create a new customer.', { tenantId, customerDTO }); this.logger.info('[customer] trying to create a new customer.', {
tenantId,
customerDTO,
});
const customerObj = this.transformNewCustomerDTO(customerDTO); const customerObj = this.transformNewCustomerDTO(customerDTO);
const customer = await this.contactService.newContact(tenantId, customerObj, 'customer'); const customer = await this.contactService.newContact(
tenantId,
customerObj,
'customer'
);
this.logger.info('[customer] created successfully.', { tenantId, customerDTO }); this.logger.info('[customer] created successfully.', {
tenantId,
customerDTO,
});
await this.eventDispatcher.dispatch(events.customers.onCreated, { await this.eventDispatcher.dispatch(events.customers.onCreated, {
customer, tenantId, customerId: customer.id, customer,
tenantId,
customerId: customer.id,
}); });
return customer; return customer;
@@ -100,24 +115,35 @@ export default class CustomersService {
/** /**
* Edits details of the given customer. * Edits details of the given customer.
* @param {number} tenantId * @param {number} tenantId
* @param {number} customerId * @param {number} customerId
* @param {ICustomerEditDTO} customerDTO * @param {ICustomerEditDTO} customerDTO
* @return {Promise<ICustomer>} * @return {Promise<ICustomer>}
*/ */
public async editCustomer( public async editCustomer(
tenantId: number, tenantId: number,
customerId: number, customerId: number,
customerDTO: ICustomerEditDTO, customerDTO: ICustomerEditDTO
): Promise<ICustomer> { ): Promise<ICustomer> {
const contactDTO = this.customerToContactDTO(customerDTO); const contactDTO = this.customerToContactDTO(customerDTO);
this.logger.info('[customer] trying to edit customer.', { tenantId, customerId, customerDTO }); this.logger.info('[customer] trying to edit customer.', {
const customer = this.contactService.editContact(tenantId, customerId, contactDTO, 'customer'); tenantId,
customerId,
customerDTO,
});
const customer = this.contactService.editContact(
tenantId,
customerId,
contactDTO,
'customer'
);
this.eventDispatcher.dispatch(events.customers.onEdited); this.eventDispatcher.dispatch(events.customers.onEdited);
this.logger.info('[customer] edited successfully.', { this.logger.info('[customer] edited successfully.', {
tenantId, customerId, customer, tenantId,
customerId,
customer,
}); });
return customer; return customer;
@@ -125,20 +151,35 @@ export default class CustomersService {
/** /**
* Deletes the given customer from the storage. * Deletes the given customer from the storage.
* @param {number} tenantId * @param {number} tenantId
* @param {number} customerId * @param {number} customerId
* @return {Promise<void>} * @return {Promise<void>}
*/ */
public async deleteCustomer(tenantId: number, customerId: number): Promise<void> { public async deleteCustomer(
this.logger.info('[customer] trying to delete customer.', { tenantId, customerId }); tenantId: number,
customerId: number
): Promise<void> {
this.logger.info('[customer] trying to delete customer.', {
tenantId,
customerId,
});
// Retrieve the customer of throw not found service error.
await this.getCustomerByIdOrThrowError(tenantId, customerId); await this.getCustomerByIdOrThrowError(tenantId, customerId);
// Validate whether the customer has no assocaited invoices tranasctions.
await this.customerHasNoInvoicesOrThrowError(tenantId, customerId); await this.customerHasNoInvoicesOrThrowError(tenantId, customerId);
await this.contactService.deleteContact(tenantId, customerId, 'customer'); await this.contactService.deleteContact(tenantId, customerId, 'customer');
await this.eventDispatcher.dispatch(events.customers.onDeleted, { tenantId, customerId }); await this.eventDispatcher.dispatch(events.customers.onDeleted, {
this.logger.info('[customer] deleted successfully.', { tenantId, customerId }); tenantId,
customerId,
});
this.logger.info('[customer] deleted successfully.', {
tenantId,
customerId,
});
} }
/** /**
@@ -147,22 +188,34 @@ export default class CustomersService {
* @param {number} customerId - * @param {number} customerId -
* @return {Promise<void>} * @return {Promise<void>}
*/ */
public async revertOpeningBalanceEntries(tenantId: number, customerId: number|number[]) { public async revertOpeningBalanceEntries(
tenantId: number,
customerId: number | number[]
) {
const id = Array.isArray(customerId) ? customerId : [customerId]; const id = Array.isArray(customerId) ? customerId : [customerId];
this.logger.info('[customer] trying to revert opening balance journal entries.', { tenantId, customerId }); this.logger.info(
'[customer] trying to revert opening balance journal entries.',
{ tenantId, customerId }
);
await this.contactService.revertJEntriesContactsOpeningBalance( await this.contactService.revertJEntriesContactsOpeningBalance(
tenantId, id, 'customer', tenantId,
id,
'customer'
); );
} }
/** /**
* Retrieve the given customer details. * Retrieve the given customer details.
* @param {number} tenantId * @param {number} tenantId
* @param {number} customerId * @param {number} customerId
*/ */
public async getCustomer(tenantId: number, customerId: number) { public async getCustomer(tenantId: number, customerId: number) {
const contact = await this.contactService.getContact(tenantId, customerId, 'customer'); const contact = await this.contactService.getContact(
tenantId,
customerId,
'customer'
);
return this.transformContactToCustomer(contact); return this.transformContactToCustomer(contact);
} }
@@ -175,20 +228,23 @@ export default class CustomersService {
tenantId: number, tenantId: number,
customersFilter: ICustomersFilter customersFilter: ICustomersFilter
): Promise<{ ): Promise<{
customers: ICustomer[], customers: ICustomer[];
pagination: IPaginationMeta, pagination: IPaginationMeta;
filterMeta: IFilterMeta, filterMeta: IFilterMeta;
}> { }> {
const { Customer } = this.tenancy.models(tenantId); const { Customer } = this.tenancy.models(tenantId);
const dynamicList = await this.dynamicListService.dynamicList(tenantId, Customer, customersFilter); const dynamicList = await this.dynamicListService.dynamicList(
tenantId,
const { results, pagination } = await Customer.query().onBuild((query) => { Customer,
dynamicList.buildQuery()(query); customersFilter
}).pagination(
customersFilter.page - 1,
customersFilter.pageSize,
); );
const { results, pagination } = await Customer.query()
.onBuild((query) => {
dynamicList.buildQuery()(query);
})
.pagination(customersFilter.page - 1, customersFilter.pageSize);
return { return {
customers: results.map(this.transformContactToCustomer), customers: results.map(this.transformContactToCustomer),
pagination, pagination,
@@ -198,49 +254,57 @@ export default class CustomersService {
/** /**
* Writes customer opening balance journal entries. * Writes customer opening balance journal entries.
* @param {number} tenantId * @param {number} tenantId
* @param {number} customerId * @param {number} customerId
* @param {number} openingBalance * @param {number} openingBalance
* @return {Promise<void>} * @return {Promise<void>}
*/ */
public async writeCustomerOpeningBalanceJournal( public async writeCustomerOpeningBalanceJournal(
tenantId: number, tenantId: number,
customerId: number, customerId: number,
openingBalance: number, openingBalance: number
) { ) {
const journal = new JournalPoster(tenantId); const journal = new JournalPoster(tenantId);
const journalCommands = new JournalCommands(journal); const journalCommands = new JournalCommands(journal);
await journalCommands.customerOpeningBalance(customerId, openingBalance) await journalCommands.customerOpeningBalance(customerId, openingBalance);
await Promise.all([ await Promise.all([journal.saveBalance(), journal.saveEntries()]);
journal.saveBalance(),
journal.saveEntries(),
]);
} }
/** /**
* Retrieve the given customer by id or throw not found. * Retrieve the given customer by id or throw not found.
* @param {number} tenantId * @param {number} tenantId
* @param {number} customerId * @param {number} customerId
*/ */
public getCustomerByIdOrThrowError(tenantId: number, customerId: number) { public getCustomerByIdOrThrowError(tenantId: number, customerId: number) {
return this.contactService.getContactByIdOrThrowError(tenantId, customerId, 'customer'); return this.contactService.getContactByIdOrThrowError(
tenantId,
customerId,
'customer'
);
} }
/** /**
* Retrieve the given customers or throw error if one of them not found. * Retrieve the given customers or throw error if one of them not found.
* @param {numebr} tenantId * @param {numebr} tenantId
* @param {number[]} customersIds * @param {number[]} customersIds
*/ */
private getCustomersOrThrowErrorNotFound(tenantId: number, customersIds: number[]) { private getCustomersOrThrowErrorNotFound(
return this.contactService.getContactsOrThrowErrorNotFound(tenantId, customersIds, 'customer'); tenantId: number,
customersIds: number[]
) {
return this.contactService.getContactsOrThrowErrorNotFound(
tenantId,
customersIds,
'customer'
);
} }
/** /**
* Deletes the given customers from the storage. * Deletes the given customers from the storage.
* @param {number} tenantId * @param {number} tenantId
* @param {number[]} customersIds * @param {number[]} customersIds
* @return {Promise<void>} * @return {Promise<void>}
*/ */
public async deleteBulkCustomers(tenantId: number, customersIds: number[]) { public async deleteBulkCustomers(tenantId: number, customersIds: number[]) {
@@ -256,16 +320,21 @@ export default class CustomersService {
/** /**
* Validates the customer has no associated sales invoice * Validates the customer has no associated sales invoice
* or throw service error. * or throw service error.
* @param {number} tenantId * @param {number} tenantId
* @param {number} customerId * @param {number} customerId
* @throws {ServiceError} * @throws {ServiceError}
* @return {Promise<void>} * @return {Promise<void>}
*/ */
private async customerHasNoInvoicesOrThrowError(tenantId: number, customerId: number) { private async customerHasNoInvoicesOrThrowError(
tenantId: number,
customerId: number
) {
const { saleInvoiceRepository } = this.tenancy.repositories(tenantId); const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
// Retrieve the sales invoices that assocaited to the given customer. // Retrieve the sales invoices that assocaited to the given customer.
const salesInvoice = await saleInvoiceRepository.find({ customer_id: customerId }); const salesInvoice = await saleInvoiceRepository.find({
customer_id: customerId,
});
if (salesInvoice.length > 0) { if (salesInvoice.length > 0) {
throw new ServiceError('customer_has_invoices'); throw new ServiceError('customer_has_invoices');
@@ -274,21 +343,29 @@ export default class CustomersService {
/** /**
* Throws error in case one of customers have associated sales invoices. * Throws error in case one of customers have associated sales invoices.
* @param {number} tenantId * @param {number} tenantId
* @param {number[]} customersIds * @param {number[]} customersIds
* @throws {ServiceError} * @throws {ServiceError}
* @return {Promise<void>} * @return {Promise<void>}
*/ */
private async customersHaveNoInvoicesOrThrowError(tenantId: number, customersIds: number[]) { private async customersHaveNoInvoicesOrThrowError(
tenantId: number,
customersIds: number[]
) {
const { saleInvoiceRepository } = this.tenancy.repositories(tenantId); const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
const customersInvoices = await saleInvoiceRepository.findWhereIn( const customersInvoices = await saleInvoiceRepository.findWhereIn(
'customer_id', customersIds 'customer_id',
customersIds
);
const customersIdsWithInvoice = customersInvoices.map(
(saleInvoice: ISaleInvoice) => saleInvoice.customerId
); );
const customersIdsWithInvoice = customersInvoices
.map((saleInvoice: ISaleInvoice) => saleInvoice.customerId);
const customersHaveInvoices = difference(customersIds, customersIdsWithInvoice); const customersHaveInvoices = difference(
customersIds,
customersIdsWithInvoice
);
if (customersHaveInvoices.length > 0) { if (customersHaveInvoices.length > 0) {
throw new ServiceError('some_customers_have_invoices'); throw new ServiceError('some_customers_have_invoices');
@@ -297,28 +374,33 @@ export default class CustomersService {
/** /**
* Changes the opening balance of the given customer. * Changes the opening balance of the given customer.
* @param {number} tenantId * @param {number} tenantId
* @param {number} customerId * @param {number} customerId
* @param {number} openingBalance * @param {number} openingBalance
* @param {string|Date} openingBalanceAt * @param {string|Date} openingBalanceAt
*/ */
public async changeOpeningBalance( public async changeOpeningBalance(
tenantId: number, tenantId: number,
customerId: number, customerId: number,
openingBalance: number, openingBalance: number,
openingBalanceAt: Date|string, openingBalanceAt: Date | string
) { ) {
await this.contactService.changeOpeningBalance( await this.contactService.changeOpeningBalance(
tenantId, tenantId,
customerId, customerId,
'customer', 'customer',
openingBalance, openingBalance,
openingBalanceAt, openingBalanceAt
); );
// Triggers `onOpeingBalanceChanged` event. // Triggers `onOpeingBalanceChanged` event.
await this.eventDispatcher.dispatch(events.customers.onOpeningBalanceChanged, { await this.eventDispatcher.dispatch(
tenantId, customerId, openingBalance, openingBalanceAt events.customers.onOpeningBalanceChanged,
}); {
tenantId,
customerId,
openingBalance,
openingBalanceAt,
}
);
} }
} }

View File

@@ -24,7 +24,6 @@ import ItemsService from 'services/Items/ItemsService';
import ItemsEntriesService from 'services/Items/ItemsEntriesService'; import ItemsEntriesService from 'services/Items/ItemsEntriesService';
import CustomersService from 'services/Contacts/CustomersService'; import CustomersService from 'services/Contacts/CustomersService';
import SaleEstimateService from 'services/Sales/SalesEstimate'; import SaleEstimateService from 'services/Sales/SalesEstimate';
import { PaymentReceiveEntry } from 'models';
const ERRORS = { const ERRORS = {
INVOICE_NUMBER_NOT_UNIQUE: 'INVOICE_NUMBER_NOT_UNIQUE', INVOICE_NUMBER_NOT_UNIQUE: 'INVOICE_NUMBER_NOT_UNIQUE',
@@ -33,7 +32,8 @@ const ERRORS = {
ENTRIES_ITEMS_IDS_NOT_EXISTS: 'ENTRIES_ITEMS_IDS_NOT_EXISTS', ENTRIES_ITEMS_IDS_NOT_EXISTS: 'ENTRIES_ITEMS_IDS_NOT_EXISTS',
NOT_SELLABLE_ITEMS: 'NOT_SELLABLE_ITEMS', NOT_SELLABLE_ITEMS: 'NOT_SELLABLE_ITEMS',
SALE_INVOICE_NO_NOT_UNIQUE: 'SALE_INVOICE_NO_NOT_UNIQUE', SALE_INVOICE_NO_NOT_UNIQUE: 'SALE_INVOICE_NO_NOT_UNIQUE',
INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES: 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES', INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES:
'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES',
}; };
/** /**
@@ -107,11 +107,12 @@ export default class SaleInvoicesService extends SalesInvoicesCost {
* @param {Function} next * @param {Function} next
*/ */
async getInvoiceOrThrowError(tenantId: number, saleInvoiceId: number) { async getInvoiceOrThrowError(tenantId: number, saleInvoiceId: number) {
const { SaleInvoice } = this.tenancy.models(tenantId); const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
const saleInvoice = await SaleInvoice.query()
.findById(saleInvoiceId)
.withGraphFetched('entries');
const saleInvoice = await saleInvoiceRepository.findOneById(
saleInvoiceId,
'entries'
);
if (!saleInvoice) { if (!saleInvoice) {
throw new ServiceError(ERRORS.SALE_INVOICE_NOT_FOUND); throw new ServiceError(ERRORS.SALE_INVOICE_NOT_FOUND);
} }
@@ -223,7 +224,7 @@ export default class SaleInvoicesService extends SalesInvoicesCost {
saleInvoiceId: number, saleInvoiceId: number,
saleInvoiceDTO: any saleInvoiceDTO: any
): Promise<ISaleInvoice> { ): Promise<ISaleInvoice> {
const { SaleInvoice, ItemEntry } = this.tenancy.models(tenantId); const { SaleInvoice } = this.tenancy.models(tenantId);
const oldSaleInvoice = await this.getInvoiceOrThrowError( const oldSaleInvoice = await this.getInvoiceOrThrowError(
tenantId, tenantId,
@@ -328,7 +329,7 @@ export default class SaleInvoicesService extends SalesInvoicesCost {
// Retrieve the sale invoice associated payment receive entries. // Retrieve the sale invoice associated payment receive entries.
const entries = await PaymentReceiveEntry.query().where( const entries = await PaymentReceiveEntry.query().where(
'invoice_id', 'invoice_id',
saleInvoiceId, saleInvoiceId
); );
if (entries.length > 0) { if (entries.length > 0) {
throw new ServiceError(ERRORS.INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES); throw new ServiceError(ERRORS.INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES);
@@ -346,7 +347,8 @@ export default class SaleInvoicesService extends SalesInvoicesCost {
tenantId: number, tenantId: number,
saleInvoiceId: number saleInvoiceId: number
): Promise<void> { ): Promise<void> {
const { SaleInvoice, ItemEntry } = this.tenancy.models(tenantId); const { ItemEntry } = this.tenancy.models(tenantId);
const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
// Retrieve the given sale invoice with associated entries or throw not found error. // Retrieve the given sale invoice with associated entries or throw not found error.
const oldSaleInvoice = await this.getInvoiceOrThrowError( const oldSaleInvoice = await this.getInvoiceOrThrowError(
@@ -369,7 +371,8 @@ export default class SaleInvoicesService extends SalesInvoicesCost {
); );
this.logger.info('[sale_invoice] delete sale invoice with entries.'); this.logger.info('[sale_invoice] delete sale invoice with entries.');
await SaleInvoice.query().where('id', saleInvoiceId).delete(); await saleInvoiceRepository.deleteById(saleInvoiceId);
await ItemEntry.query() await ItemEntry.query()
.where('reference_id', saleInvoiceId) .where('reference_id', saleInvoiceId)
.where('reference_type', 'SaleInvoice') .where('reference_type', 'SaleInvoice')
@@ -453,7 +456,7 @@ export default class SaleInvoicesService extends SalesInvoicesCost {
saleInvoiceId: number, saleInvoiceId: number,
override: boolean = false override: boolean = false
): Promise<void> { ): Promise<void> {
const { SaleInvoice } = this.tenancy.models(tenantId); const { saleInvoiceRepository } = this.tenancy.repositories(tenantId);
// Loads the inventory items entries of the given sale invoice. // Loads the inventory items entries of the given sale invoice.
const inventoryEntries = await this.itemsEntriesService.getInventoryEntries( const inventoryEntries = await this.itemsEntriesService.getInventoryEntries(
@@ -464,9 +467,10 @@ export default class SaleInvoicesService extends SalesInvoicesCost {
// Can't continue if the sale invoice has inventory items entries. // Can't continue if the sale invoice has inventory items entries.
if (inventoryEntries.length > 0) return; if (inventoryEntries.length > 0) return;
const saleInvoice = await SaleInvoice.query() const saleInvoice = await saleInvoiceRepository.findOneById(
.findById(saleInvoiceId) saleInvoiceId,
.withGraphFetched('entries.item'); 'entries.item'
);
await this.writeNonInventoryInvoiceEntries(tenantId, saleInvoice, override); await this.writeNonInventoryInvoiceEntries(tenantId, saleInvoice, override);
} }