import { Body,Controller,Get,Post,Req,UseGuards } from '@nestjs/common';
import type { z } from 'zod';
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 { AccountingConfigService } from '../application/accounting-config.service';
import { AccountingExportService } from '../application/accounting-export.service';
import { AccountingProviderRegistry } from '../providers/accounting-provider.registry';
import { AccountingExportWorker } from '../workers/accounting-export.worker';
import { AccountingReadModelService } from '../application/accounting-read-model.service';
import { ZodValidationPipe } from '../../../common/validation/zod-validation.pipe';
import { accountingConfigSchema,accountingExportSchema,accountingRuleSchema,accountingRunExportSchema } from '../../../common/validation/critical-write.schemas';
type AccountingConfigBody = z.infer<typeof accountingConfigSchema>;
type AccountingRuleBody = z.infer<typeof accountingRuleSchema>;
type AccountingExportBody = z.infer<typeof accountingExportSchema>;
type AccountingRunExportBody = z.infer<typeof accountingRunExportSchema>;
@Controller('/accounting')
@UseGuards(AuthGuard,OrganizationContextGuard,LocationContextGuard,PermissionGuard)
export class AccountingController {
constructor(
private readonly config:AccountingConfigService,
private readonly exports:AccountingExportService,
private readonly providers:AccountingProviderRegistry,
private readonly exportWorker:AccountingExportWorker,
private readonly read:AccountingReadModelService,
) {}
@Get('/providers')
@RequirePermissions('accounting.read')
providersList(){return this.providers.list();}
@Get('/overview')
@RequirePermissions('accounting.read')
overview(@Req() req:LocationScopedRequest) {
return this.read.overview({organizationId:req.organizationId!,locationId:req.locationId!});
}
@Post('/config')
@RequirePermissions('accounting.manage')
configUpsert(@Req() req:LocationScopedRequest,@Body(new ZodValidationPipe(accountingConfigSchema)) body:AccountingConfigBody){
return this.config.upsert({organizationId:req.organizationId!,locationId:req.locationId!,...body});
}
@Post('/rules')
@RequirePermissions('accounting.manage')
rule(@Req() req:LocationScopedRequest,@Body(new ZodValidationPipe(accountingRuleSchema)) body:AccountingRuleBody){
return this.config.addRule({organizationId:req.organizationId!,locationId:req.locationId!,...body});
}
@Post('/exports')
@RequirePermissions('accounting.export')
export(@Req() req:LocationScopedRequest,@Body(new ZodValidationPipe(accountingExportSchema)) body:AccountingExportBody){
return this.exports.create({
organizationId:req.organizationId!,locationId:req.locationId!,userId:req.auth?.userId,...body,
});
}
@Get('/exports')
@RequirePermissions('accounting.read')
exportsList(@Req() req:LocationScopedRequest) {
return this.exports.list({organizationId:req.organizationId!,locationId:req.locationId!});
}
@Post('/exports/run')
@RequirePermissions('accounting.export')
runExport(@Req() req:LocationScopedRequest,@Body(new ZodValidationPipe(accountingRunExportSchema)) body:AccountingRunExportBody) {
return this.exportWorker.runOne({
organizationId:req.organizationId!,
locationId:req.locationId!,
exportJobId:body.exportJobId,
});
}
}
