All files / src/interfaces/mobile-api/employee mobile-finance.controller.ts

0% Statements 0/35
0% Branches 0/28
0% Functions 0/6
0% Lines 0/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73                                                                                                                                                 
import { Controller, Get, Post, Param, Req, BadRequestException } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { FinancialStatementService } from '../../../domains/finance/services/financial-statement.service';
import { AccountsPayableService } from '../../../domains/finance/services/accounts-payable.service';
import { AccountsReceivableService } from '../../../domains/finance/services/accounts-receivable.service';
import { BankingService } from '../../../domains/finance/services/banking.service';
import { PostingEngineService } from '../../../domains/finance/services/posting-engine.service';
 
@ApiTags('Mobile Finance')
@Controller('api/v1/mobile/finance')
export class MobileFinanceController {
  constructor(
    private readonly statementSvc: FinancialStatementService,
    private readonly apSvc: AccountsPayableService,
    private readonly arSvc: AccountsReceivableService,
    private readonly bankSvc: BankingService,
    private readonly postingEngine: PostingEngineService
  ) {}
 
  @Get('dashboard')
  @ApiOperation({ summary: 'Retrieve compact mobile dashboard statistics' })
  async getDashboardSummary(@Req() req: any) {
    const tenantId = req.headers['x-tenant-id'] || '60c72b2f9b1d8b23c4d5e6f1';
    
    // Multi-service KPIs
    const pl = await this.statementSvc.getProfitAndLoss(tenantId);
    const ap = await this.apSvc.getAgeingReport(tenantId);
    const ar = await this.arSvc.getAgeingReport(tenantId);
    
    return {
      netProfitMinor: pl.netProfitMinor,
      totalPayablesMinor: ap.current + ap.days30 + ap.days60 + ap.days90 + ap.over90,
      totalReceivablesMinor: ar.current + ar.days30 + ar.days60 + ar.days90 + ar.over90,
      periodStatus: 'Open'
    };
  }
 
  @Get('approvals')
  @ApiOperation({ summary: 'List journals awaiting manager approvals' })
  async getApprovalsList(@Req() req: any) {
    const tenantId = req.headers['x-tenant-id'] || '60c72b2f9b1d8b23c4d5e6f1';
    return this.postingEngine.getPendingApprovals(tenantId);
  }
 
  @Post('approvals/:id/approve')
  @ApiOperation({ summary: 'Approve pending journal' })
  async approvePendingJournal(@Req() req: any, @Param('id') id: string) {
    const tenantId = req.headers['x-tenant-id'] || '60c72b2f9b1d8b23c4d5e6f1';
    try {
      const journal = await this.postingEngine.approveJournal(tenantId, id);
      return { success: true, status: journal.status };
    } catch (err) {
      throw new BadRequestException(err.message);
    }
  }
 
  @Get('banks')
  @ApiOperation({ summary: 'Retrieve masked bank account lists' })
  async getMaskedBankAccounts(@Req() req: any) {
    const tenantId = req.headers['x-tenant-id'] || '60c72b2f9b1d8b23c4d5e6f1';
    const accounts = await this.bankSvc.listBankAccounts(tenantId);
    
    // Only return masked account numbers to protect sensitive details
    return accounts.map(acc => ({
      id: acc._id,
      bankName: acc.bankName,
      accountName: acc.accountName,
      accountNumberMasked: acc.accountNumberMasked,
      balanceMinor: acc.balanceMinor
    }));
  }
}