feat(sync): synchronize Hiboutik data through POST /sync
POST /sync starts the full synchronization in the background (202, or 409 when one is already running). Entities are synced in dependency order: brands, categories, suppliers, products (with versions and stocks), customers. Each row is synced independently so that a failure is logged without stopping the rest. Replaces the default AppService.
This commit is contained in:
49
src/services/hiboutik/customer.hiboutik.service.ts
Normal file
49
src/services/hiboutik/customer.hiboutik.service.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { CustomerHiboutikRepository } from '../../hiboutik/customer.hiboutik.repository';
|
||||
import { CustomerDatabaseRepository } from '../../database/customer.database.repository';
|
||||
import { CustomerConverter } from '../../models/converter/customer.converter';
|
||||
|
||||
@Injectable()
|
||||
export class CustomerHiboutikService {
|
||||
private readonly logger = new Logger('CustomerHiboutikService');
|
||||
|
||||
constructor(
|
||||
private readonly customerHiboutikRepository: CustomerHiboutikRepository,
|
||||
private readonly customerDatabaseRepository: CustomerDatabaseRepository,
|
||||
private readonly customerConverter: CustomerConverter,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Mirrors Hiboutik customers: deletes the customers missing from Hiboutik, then fetches and upserts each of them
|
||||
* (one API call per customer, as the list endpoint lacks addresses and sales).
|
||||
*/
|
||||
async syncCustomers() {
|
||||
const hiboutikCustomers = await this.customerHiboutikRepository.getCustomers();
|
||||
|
||||
// Safety net: an empty answer from Hiboutik most likely means an API issue
|
||||
let nbDeleted = 0;
|
||||
if (hiboutikCustomers.length === 0) {
|
||||
this.logger.warn('Hiboutik returned no customers: deletion skipped.');
|
||||
} else {
|
||||
nbDeleted = await this.customerDatabaseRepository.deleteMissing(hiboutikCustomers.map((dto) => Number(dto.customers_id)));
|
||||
}
|
||||
|
||||
let nbFailed = 0;
|
||||
for (const hiboutikCustomer of hiboutikCustomers) {
|
||||
try {
|
||||
const hiboutikFullCustomer = await this.customerHiboutikRepository.getCustomerById(hiboutikCustomer.customers_id);
|
||||
await this.customerDatabaseRepository.upsert(this.customerConverter.fromHiboutik(hiboutikFullCustomer));
|
||||
// retreive addresses DTOs
|
||||
// save addresses
|
||||
// retreive orders DTOs
|
||||
// save orders
|
||||
} catch (error) {
|
||||
nbFailed++;
|
||||
this.logger.error(`Failed to sync Hiboutik customer ${hiboutikCustomer.customers_id}`, (error as Error)?.stack);
|
||||
}
|
||||
}
|
||||
this.logger.log(
|
||||
`Customers sync ended: ${hiboutikCustomers.length - nbFailed}/${hiboutikCustomers.length} synced, ${nbFailed} failed, ${nbDeleted} deleted.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user