feat(sync): synchronize customer adresses and orders from Hiboutik sales (#1)

Co-authored-by: MastersGame <quentin.duwa1210@gmail.com>
Reviewed-on: #1
This commit is contained in:
2026-11-07 09:56:53 +00:00
parent c5f65dcb62
commit 9dddf7562a
16 changed files with 755 additions and 17 deletions

View File

@@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import { Converter } from './converter';
import { OrderSource } from '../../../prisma/generated/client';
import { OrderWithLinesInput } from '../../../prisma/customObjects/prisma.custom.object';
import { SaleHiboutikDto, SaleLineHiboutikDto } from '../hiboutikDTO/sale.hiboutik.dto';
import { parseHiboutikDate } from '../../utils/date';
import { OrderStatus } from '../orderStatus';
@Injectable()
export class OrderConverter extends Converter<OrderWithLinesInput, SaleHiboutikDto> {
/**
* Maps a Hiboutik sale to an order (source STORE) with a snapshot of its lines.
* @throws if the sale has neither a valid completion date nor a valid creation date.
*/
fromHiboutik(dto: SaleHiboutikDto): OrderWithLinesInput {
const completedAt = parseHiboutikDate(dto.completed_at);
const orderedAt = completedAt ?? parseHiboutikDate(dto.created_at);
if (!orderedAt) throw new Error(`Hiboutik sale ${dto.sale_id} has no valid date`);
const customerId = Number(dto.customer_id);
return {
hiboutikSaleId: Number(dto.sale_id),
orderedAt,
source: OrderSource.STORE,
status: completedAt ? OrderStatus.COMPLETED : OrderStatus.PENDING,
total: dto.total,
// 0 for an anonymous sale
customer: customerId > 0 ? { connect: { hiboutikId: customerId } } : undefined,
lines: (dto.line_items ?? []).map((line) => this.lineFromHiboutik(line)),
};
}
private lineFromHiboutik(line: SaleLineHiboutikDto): OrderWithLinesInput['lines'][number] {
return {
barcode: line.product_barcode?.trim() || null,
hiboutikProductId: Number(line.product_id),
hiboutikSizeId: Number(line.product_size),
productName: line.product_model,
quantity: Number(line.quantity),
unitPrice: line.item_unit_gross,
// same rule as ProductVersion: the product name for a product without sizes
versionName: line.size_name?.trim() || line.product_model,
};
}
toHiboutik(): SaleHiboutikDto {
throw new Error('Method not implemented.');
}
}