import { Injectable } from '@nestjs/common';
import { randomUUID } from 'node:crypto';
import { DatabaseService } from '../../../infrastructure/database/database.service';
import { DomainConflictError } from '../../../common/errors/domain-conflict.error';
@Injectable()
export class FiscalOutageReceiptService {
constructor(private readonly database:DatabaseService) {}
async policyFor(input:{organizationId:string;fiscalTransactionId:string}) {
const rows=await this.database.query<any>(
`select ft.status,ft.location_id,ft.integration_connection_id,ic.fiscal_outage_mode
from fiscal_transactions ft
join integration_connections ic on ic.id=ft.integration_connection_id
where ft.id=$1 and ft.organization_id=$2`,
[input.fiscalTransactionId,input.organizationId],
);
const row=rows[0];
if(!row) throw new DomainConflictError('fiscal.transaction_not_found');
if(row.status==='completed') {
return {allowReceipt:true,failureNoteKey:null,mode:row.fiscal_outage_mode};
}
if(row.fiscal_outage_mode==='block') {
return {allowReceipt:false,failureNoteKey:null,mode:'block'};
}
if(row.fiscal_outage_mode==='provider_offline_buffer') {
throw new DomainConflictError('fiscal.offline_buffer_not_supported_by_current_provider');
}
const noteKey='fiscal.receipt.tse_unavailable_recovery_pending';
await this.database.query(
`insert into fiscal_outage_receipt_events(
id,organization_id,location_id,fiscal_transaction_id,outage_mode,receipt_note_key
) values($1,$2,$3,$4,$5,$6)
on conflict(fiscal_transaction_id) do nothing`,
[randomUUID(),input.organizationId,row.location_id,input.fiscalTransactionId,row.fiscal_outage_mode,noteKey],
);
return {allowReceipt:true,failureNoteKey:noteKey,mode:row.fiscal_outage_mode};
}
}
