🚀 Multi-invoice extraction and detailed validation feedback
This commit is contained in:
@@ -52,25 +52,44 @@ export class InvoiceProcessor {
|
||||
* الخطوة الأولى: استخراج البيانات باستخدام AI
|
||||
*/
|
||||
@Process('extract-data')
|
||||
async handleExtraction(job: Job<{ invoiceId: string; filePath: string; tenantId: string }>) {
|
||||
const { invoiceId, filePath } = job.data;
|
||||
async handleExtraction(job: Job<{ invoiceId: string; filePath: string; tenantId: string; companyId: string }>) {
|
||||
const { invoiceId, filePath, tenantId, companyId } = job.data;
|
||||
const storageRoot = this.configService.get<string>('STORAGE_PATH', './uploads');
|
||||
|
||||
try {
|
||||
// 1. Update status to EXTRACTING
|
||||
await this.invoiceRepository.update(invoiceId, { status: InvoiceStatus.EXTRACTING });
|
||||
|
||||
// 2. Extract data via Gemini
|
||||
const data = await this.geminiExtractor.extractInvoiceData(filePath, storageRoot);
|
||||
// 2. Extract data via Gemini (Now returns an array)
|
||||
const invoicesData = await this.geminiExtractor.extractInvoiceData(filePath, storageRoot);
|
||||
|
||||
// 3. Save extracted data in a transaction
|
||||
await this.saveExtractedData(invoiceId, data);
|
||||
if (!invoicesData || invoicesData.length === 0) {
|
||||
throw new Error('No invoices found in file');
|
||||
}
|
||||
|
||||
this.logger.log(`Extraction successful for invoice ${invoiceId}`);
|
||||
// 3. Process the first invoice (updates the current record)
|
||||
await this.saveExtractedData(invoiceId, invoicesData[0]);
|
||||
|
||||
// 4. If multiple invoices found, create new records for others
|
||||
if (invoicesData.length > 1) {
|
||||
this.logger.log(`Found ${invoicesData.length} invoices in file ${filePath}. Creating additional records...`);
|
||||
|
||||
for (let i = 1; i < invoicesData.length; i++) {
|
||||
const newInvoice = this.invoiceRepository.create({
|
||||
tenant_id: tenantId,
|
||||
company_id: companyId,
|
||||
original_file_path: filePath,
|
||||
status: InvoiceStatus.EXTRACTING,
|
||||
});
|
||||
const savedNew = await this.invoiceRepository.save(newInvoice);
|
||||
await this.saveExtractedData(savedNew.id, invoicesData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.log(`Extraction successful for invoice(s) in ${filePath}`);
|
||||
} catch (error) {
|
||||
await this.invoiceRepository.update(invoiceId, {
|
||||
status: InvoiceStatus.VALIDATION_FAILED,
|
||||
// Optional: Save error message in a notes column
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
@@ -90,6 +109,7 @@ export class InvoiceProcessor {
|
||||
invoice_number: data.invoice_number,
|
||||
invoice_date: data.invoice_date,
|
||||
invoice_type: data.invoice_type || 'cash',
|
||||
invoice_category: data.invoice_category || 'simplified',
|
||||
supplier_name: data.supplier_name,
|
||||
supplier_tin: data.supplier_tin,
|
||||
buyer_name: data.buyer_name,
|
||||
@@ -149,11 +169,14 @@ export class InvoiceProcessor {
|
||||
const result = this.taxValidation.validateInvoice(invoice);
|
||||
|
||||
if (result.isValid) {
|
||||
await this.invoiceRepository.update(invoiceId, { status: InvoiceStatus.VALIDATED });
|
||||
await this.invoiceRepository.update(invoiceId, {
|
||||
status: InvoiceStatus.VALIDATED,
|
||||
validation_errors: null,
|
||||
});
|
||||
} else {
|
||||
await this.invoiceRepository.update(invoiceId, {
|
||||
status: InvoiceStatus.VALIDATION_FAILED,
|
||||
// Optional: Save detailed error list
|
||||
validation_errors: result.errors,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user