import { Body,Controller,Get,Param,Post,Req,UseGuards } from '@nestjs/common';
import { AuthGuard } from '../../../common/auth/auth.guard';
import { OrganizationContextGuard } from '../../../common/auth/organization-context.guard';
import { LocationContextGuard,type LocationScopedRequest } from '../../../common/auth/location-context.guard';
import { PermissionGuard } from '../../../common/auth/permission.guard';
import { RequirePermissions } from '../../../common/auth/permissions.decorator';
import { RealFiscalService } from '../application/real-fiscal.service';
import { ZodValidationPipe } from '../../../common/validation/zod-validation.pipe';
import { fiscalRealStartSchema } from '../../../common/validation/critical-write.schemas';
import { RealFiscalRecoveryWorker } from '../workers/real-fiscal-recovery.worker';
import { FiscalReceiptService } from '../application/fiscal-receipt.service';
import { FiscalOutageReceiptService } from '../application/fiscal-outage-receipt.service';
import { FiscalDomainEventRouterWorker } from '../workers/fiscal-domain-event-router.worker';
import type { z } from 'zod';
@Controller('/fiscal/v2')
@UseGuards(AuthGuard,OrganizationContextGuard,LocationContextGuard,PermissionGuard)
export class RealFiscalController {
constructor(
private readonly fiscal:RealFiscalService,
private readonly recovery:RealFiscalRecoveryWorker,
private readonly receipts:FiscalReceiptService,
private readonly outage:FiscalOutageReceiptService,
private readonly router:FiscalDomainEventRouterWorker,
) {}
@Post('/transactions/start')
@RequirePermissions('fiscal.retry')
start(@Req() req:LocationScopedRequest,@Body(new ZodValidationPipe(fiscalRealStartSchema)) body:z.infer<typeof fiscalRealStartSchema>) {
return this.fiscal.start({
organizationId:req.organizationId!,locationId:req.locationId!,
checkId:body.checkId,paymentId:body.paymentId,transactionType:body.transactionType,
mappingId:body.mappingId,clientTransactionRef:body.clientTransactionRef,
});
}
@Post('/transactions/:id/finish')
@RequirePermissions('fiscal.retry')
finish(@Req() req:LocationScopedRequest,@Param('id') id:string) {
return this.fiscal.finish({
organizationId:req.organizationId!,locationId:req.locationId!,fiscalTransactionId:id,
});
}
@Get('/transactions/:id/status')
@RequirePermissions('fiscal.read')
status(@Req() req:LocationScopedRequest,@Param('id') id:string) {
return this.fiscal.status({
organizationId:req.organizationId!,locationId:req.locationId!,fiscalTransactionId:id,
});
}
@Get('/transactions/:id/receipt')
@RequirePermissions('fiscal.receipts.read')
async receipt(@Req() req:LocationScopedRequest,@Param('id') id:string) {
const policy=await this.outage.policyFor({
organizationId:req.organizationId!,fiscalTransactionId:id,
});
if(!policy.allowReceipt) {
throw new Error('fiscal.receipt_blocked_by_outage_policy');
}
const dto=await this.receipts.dto({organizationId:req.organizationId!,fiscalTransactionId:id});
return {...dto,failureNoteKey:policy.failureNoteKey};
}
@Post('/recovery/run')
@RequirePermissions('fiscal.retry')
run(){return this.recovery.runBatch();}
@Post('/workers/route-events')
@RequirePermissions('fiscal.retry')
routeEvents(){return this.router.runBatch();}
}
