@accounter/server
Version:
Accounter GraphQL server
120 lines (111 loc) • 4.62 kB
text/typescript
import { GraphQLError } from 'graphql';
import { Injector } from 'graphql-modules';
import type { UpdateBusinessInput } from '../../../__generated__/types.js';
import { updateGreenInvoiceClient } from '../../green-invoice/helpers/green-invoice-clients.helper.js';
import { BusinessesProvider } from '../providers/businesses.provider.js';
import { FinancialEntitiesProvider } from '../providers/financial-entities.provider.js';
import { TaxCategoriesProvider } from '../providers/tax-categories.provider.js';
import type {
IGetBusinessesByIdsResult,
IUpdateBusinessParams,
IUpdateBusinessTaxCategoryParams,
} from '../types.js';
import type { SuggestionData } from './business-suggestion-data-schema.helper.js';
import { updateSuggestions } from './businesses.helper.js';
import { hasFinancialEntitiesCoreProperties } from './financial-entities.helper.js';
/**
* Update a single business' core financial-entity fields, business fields, suggestions and
* tax-category match, then sync the green-invoice client. Throws on failure; returns the
* refreshed business on success. Shared by the `updateBusiness` and `batchUpdateBusinesses`
* mutations.
*/
export async function updateSingleBusiness(
injector: Injector,
businessId: string,
ownerId: string,
fields: UpdateBusinessInput,
): Promise<IGetBusinessesByIdsResult> {
if (hasFinancialEntitiesCoreProperties(fields)) {
await injector.get(FinancialEntitiesProvider).updateFinancialEntity({
...fields,
financialEntityId: businessId,
irsCode: fields.irsCode ?? null,
isActive: fields.isActive ?? null,
});
}
let suggestionData: SuggestionData | null = null;
if (fields.suggestions) {
const currentBusiness = await injector
.get(BusinessesProvider)
.getBusinessByIdLoader.load(businessId);
if (!currentBusiness) {
throw new GraphQLError(`Business ID="${businessId}" not found`);
}
suggestionData = updateSuggestions(fields.suggestions, currentBusiness.suggestion_data);
}
const adjustedFields: IUpdateBusinessParams = {
address: fields.address,
city: fields.city,
zipCode: fields.zipCode,
email: fields.email,
exemptDealer: fields.exemptDealer,
vatNumber: fields.governmentId,
hebrewName: fields.hebrewName,
phoneNumber: fields.phoneNumber,
website: fields.website,
optionalVat: fields.optionalVAT,
isReceiptEnough: fields.isReceiptEnough ?? null,
isDocumentsOptional: fields.isDocumentsOptional ?? null,
country: fields.country,
suggestionData,
pcn874RecordTypeOverride: fields.pcn874RecordType,
};
if (Object.values(adjustedFields).some(field => field != null)) {
await injector
.get(BusinessesProvider)
.updateBusiness({ ...adjustedFields, businessId })
.catch((e: Error) => {
const message = `Error updating business ID="${businessId}"`;
console.error(`${message}: ${e}`);
if (e instanceof GraphQLError) {
throw e;
}
throw new Error(message);
});
}
if (fields.taxCategory) {
const taxCategoryParams: IUpdateBusinessTaxCategoryParams = {
businessId,
ownerId,
taxCategoryId: fields.taxCategory,
};
const taxCategoriesProvider = injector.get(TaxCategoriesProvider);
const taxCategoryMatchLoader = taxCategoriesProvider.taxCategoryByBusinessIDsLoader;
// check whether a match already exists rather than insert-then-catch-update, which
// would log false-positive errors and (inside a transaction) abort it on conflict
const existingTaxCategory = await taxCategoryMatchLoader.load(businessId);
if (existingTaxCategory) {
await taxCategoriesProvider.updateBusinessTaxCategory(taxCategoryParams).catch((e: Error) => {
const message = `Error updating tax category for business ID="${businessId}"`;
console.error(`${message}: ${e}`);
throw new Error(message);
});
} else {
await taxCategoriesProvider.insertBusinessTaxCategory(taxCategoryParams).catch((e: Error) => {
const message = `Error inserting tax category for business ID="${businessId}"`;
console.error(`${message}: ${e}`);
throw new Error(message);
});
}
taxCategoryMatchLoader.clear(businessId);
}
const updatedBusiness = await injector
.get(BusinessesProvider)
.getBusinessByIdLoader.load(businessId);
if (!updatedBusiness) {
throw new Error(`Updated business not found`);
}
// update green invoice client if needed
await updateGreenInvoiceClient(businessId, injector, fields);
return updatedBusiness;
}