using System.Text.Json; using Asp.Versioning; using General_Ledger_Service.DTOs.Accounts; using General_Ledger_Service.DTOs.CostCenters; using General_Ledger_Service.DTOs.FiscalCalendar; using General_Ledger_Service.DTOs.AuditLog; using General_Ledger_Service.DTOs.Bank; using General_Ledger_Service.DTOs.Budget; using General_Ledger_Service.DTOs.Cheques; using General_Ledger_Service.DTOs.Common; using General_Ledger_Service.DTOs.FixedAssets; using General_Ledger_Service.DTOs.JournalEntries; using General_Ledger_Service.DTOs.RecurringTemplates; using General_Ledger_Service.DTOs.Reports; using General_Ledger_Service.DTOs.SystemConfig; using General_Ledger_Service.DTOs.Tax; using General_Ledger_Service.Interfaces.Services; using Microsoft.AspNetCore.Mvc; namespace General_Ledger_Service.Controllers { [ApiVersion("1.0")] [ApiController] [Route("api/v{version:apiVersion}")] public class GeneralLedgerController( IAccountService accountService, IFiscalCalendarService fiscalCalendarService, ICurrencyService currencyService, ICostCenterService costCenterService, IJournalEntryService journalEntryService, IRecurringTemplateService recurringTemplateService, IReportService reportService, ITaxService taxService, IFixedAssetService fixedAssetService, IBankService bankService, IBudgetService budgetService, ISystemConfigService systemConfigService, IAuditLogService auditLogService, IChequeService chequeService, IDevToolsService devToolsService) : ControllerBase { private readonly IAccountService _accountService = accountService; private readonly IFiscalCalendarService _fiscalCalendarService = fiscalCalendarService; private readonly ICurrencyService _currencyService = currencyService; private readonly ICostCenterService _costCenterService = costCenterService; private readonly IJournalEntryService _journalEntryService = journalEntryService; private readonly IRecurringTemplateService _recurringTemplateService = recurringTemplateService; private readonly IReportService _reportService = reportService; private readonly ITaxService _taxService = taxService; private readonly IFixedAssetService _fixedAssetService = fixedAssetService; private readonly IBankService _bankService = bankService; private readonly IBudgetService _budgetService = budgetService; private readonly ISystemConfigService _systemConfigService = systemConfigService; private readonly IAuditLogService _auditLogService = auditLogService; private readonly IChequeService _chequeService = chequeService; private readonly IDevToolsService _devToolsService = devToolsService; private IActionResult Respond(ApiResponse response) => StatusCode(response.StatusCode, response); [HttpGet("status")] public IActionResult GetStatus() { return Ok(new { service = "General Ledger Service", status = "Running", timestampUtc = DateTime.UtcNow }); } [HttpPost("accounts")] public async Task CreateAccount([FromBody] CreateAccountRequest request) => Respond(await _accountService.CreateAccountAsync(request)); [HttpGet("accounts/{accountCode}")] public async Task GetAccount(string accountCode, [FromQuery] string? expand) => Respond(await _accountService.GetAccountByCodeAsync(accountCode, expand)); [HttpGet("accounts")] public async Task ListAccounts([FromQuery] ListAccountsRequest request) => Respond(await _accountService.ListAccountsAsync(request)); [HttpPut("accounts/{accountCode}")] public async Task UpdateAccount(string accountCode, [FromBody] Dictionary payload) => Respond(await _accountService.UpdateAccountAsync(accountCode, payload)); [HttpPost("fiscal-years")] public async Task CreateFiscalYear([FromBody] CreateFiscalYearRequest request) => Respond(await _fiscalCalendarService.CreateFiscalYearAsync(request)); [HttpPost("fiscal-years/{id}/periods")] public async Task GeneratePeriods(int id, [FromBody] GeneratePeriodsRequest request) => Respond(await _fiscalCalendarService.GeneratePeriodsAsync(id, request)); [HttpPut("periods/{id}/lock")] public async Task LockPeriod(int id, [FromBody] Dictionary payload) => Respond(await _fiscalCalendarService.LockPeriodAsync(id, payload)); [HttpGet("fiscal-years/periods/by-date")] public async Task GetPeriodByDate([FromQuery] DateOnly date) => Respond(await _fiscalCalendarService.GetPeriodByDateAsync(date)); [HttpGet("currencies")] public async Task ListCurrencies() => Respond(await _currencyService.ListCurrenciesAsync()); [HttpPost("cost-centers")] public async Task CreateCostCenter([FromBody] CreateCostCenterRequest request) => Respond(await _costCenterService.CreateCostCenterAsync(request)); [HttpGet("cost-centers/{costCenterCode}")] public async Task GetCostCenter(string costCenterCode, [FromQuery] string? expand) => Respond(await _costCenterService.GetCostCenterByCodeAsync(costCenterCode, expand)); [HttpPost("journal-entries")] public async Task CreateJournalEntry([FromBody] CreateJournalEntryRequest request) => Respond(await _journalEntryService.CreateAsync(request)); [HttpGet("journal-entries/{journalNo}")] public async Task GetJournalEntry(string journalNo) => Respond(await _journalEntryService.GetByJournalNoAsync(journalNo)); [HttpPost("recurring-templates")] public async Task CreateRecurringTemplate([FromBody] CreateRecurringTemplateRequest request) => Respond(await _recurringTemplateService.CreateAsync(request)); [HttpPost("recurring-templates/{id}/generate")] public async Task GenerateRecurringTemplate(long id) => Respond(await _recurringTemplateService.GenerateAsync(id)); [HttpGet("reports")] public async Task GetReport([FromQuery] ListReportsRequest request) => Respond(await _reportService.GenerateAsync(request)); [HttpPost("tax-codes")] public async Task CreateTaxCode([FromBody] CreateTaxCodeRequest request) => Respond(await _taxService.CreateTaxCodeAsync(request)); [HttpGet("tax-codes/calculate")] public async Task CalculateTax([FromQuery] CalculateTaxRequest request) => Respond(await _taxService.CalculateTaxAsync(request)); [HttpGet("tax-types")] public async Task ListTaxTypes() => Respond(await _taxService.ListTaxTypesAsync()); [HttpGet("tax-codes")] public async Task ListTaxCodes() => Respond(await _taxService.ListTaxCodesAsync()); [HttpPost("fixed-assets")] public async Task CreateFixedAsset([FromBody] CreateFixedAssetRequest request) => Respond(await _fixedAssetService.CreateAsync(request)); [HttpPost("fixed-assets/{assetCode}/transactions")] public async Task CreateFixedAssetTransaction(string assetCode, [FromBody] CreateFixedAssetTransactionRequest request) => Respond(await _fixedAssetService.CreateTransactionAsync(assetCode, request)); [HttpGet("fixed-assets")] public async Task ListFixedAssets() => Respond(await _fixedAssetService.ListAsync()); [HttpPost("bank-accounts")] public async Task CreateBankAccount([FromBody] CreateBankAccountRequest request) => Respond(await _bankService.CreateBankAccountAsync(request)); [HttpPost("bank-accounts/{id}/statement-lines/import")] public async Task ImportBankStatementLines(long id, IFormFile file) { using var stream = file.OpenReadStream(); return Respond(await _bankService.ImportStatementLinesAsync(id, stream)); } [HttpPut("bank-statement-lines/{id}/reconcile")] public async Task ReconcileBankStatementLine(long id, [FromBody] ReconcileStatementLineRequest request) => Respond(await _bankService.ReconcileStatementLineAsync(id, request)); [HttpGet("bank-accounts")] public async Task ListCashAndBankAccounts([FromQuery] string? accountType) => Respond(await _bankService.ListCashAndBankAccountsAsync(accountType)); [HttpPost("cash-accounts")] public async Task CreateCashAccount([FromBody] CreateCashAccountRequest request) => Respond(await _bankService.CreateCashAccountAsync(request)); [HttpGet("cash-account-types")] public async Task ListCashAccountTypes() => Respond(await _bankService.ListCashAccountTypesAsync()); [HttpPut("cash-accounts/{id}")] public async Task UpdateCashAccount(long id, [FromBody] UpdateCashAccountRequest request) => Respond(await _bankService.UpdateCashAccountAsync(id, request)); [HttpPatch("cash-accounts/{id}/status")] public async Task SetCashAccountStatus(long id, [FromBody] SetCashAccountStatusRequest request) => Respond(await _bankService.SetCashAccountStatusAsync(id, request)); [HttpDelete("cash-accounts/{id}")] public async Task DeleteCashAccount(long id) => Respond(await _bankService.DeleteCashAccountAsync(id)); [HttpPost("budgets")] public async Task CreateBudget([FromBody] CreateBudgetRequest request) => Respond(await _budgetService.CreateAsync(request)); [HttpPost("budgets/{id}/lines")] public async Task AddBudgetLines(long id, [FromBody] List request) => Respond(await _budgetService.AddLinesAsync(id, request)); [HttpGet("budgets")] public async Task ListBudgets() => Respond(await _budgetService.ListAsync()); [HttpPut("system-config/{key}")] public async Task UpdateSystemConfig(string key, [FromBody] UpdateSystemConfigRequest request) => Respond(await _systemConfigService.UpdateAsync(key, request)); [HttpGet("system-config")] public async Task ListSystemConfig() => Respond(await _systemConfigService.ListAsync()); [HttpGet("audit-log")] public async Task ListAuditLog([FromQuery] ListAuditLogRequest request) => Respond(await _auditLogService.ListAsync(request)); [HttpPost("cheque-books")] public async Task CreateChequeBook([FromBody] CreateChequeBookRequest request) => Respond(await _chequeService.CreateChequeBookAsync(request)); [HttpGet("cheque-books/{chequeBookNo}")] public async Task GetChequeBook(string chequeBookNo, [FromQuery] string? expand) => Respond(await _chequeService.GetChequeBookByNoAsync(chequeBookNo, expand)); [HttpGet("cheque-books")] public async Task ListChequeBooks([FromQuery] ListChequeBooksRequest request) => Respond(await _chequeService.ListChequeBooksAsync(request)); [HttpPut("cheque-pages/{chequeNo}/issue")] public async Task IssueChequePage(string chequeNo, [FromBody] IssueChequePageRequest request) => Respond(await _chequeService.IssueChequePageAsync(chequeNo, request)); [HttpPut("cheque-pages/{chequeNo}/status")] public async Task UpdateChequePageStatus(string chequeNo, [FromBody] Dictionary payload) => Respond(await _chequeService.UpdateChequePageStatusAsync(chequeNo, payload)); [HttpGet("cheque-pages/{chequeNo}")] public async Task GetChequePage(string chequeNo) => Respond(await _chequeService.GetChequePageByNoAsync(chequeNo)); [HttpGet("cheque-pages")] public async Task ListChequePages([FromQuery] ListChequePagesRequest request) => Respond(await _chequeService.ListChequePagesAsync(request)); [HttpPost("received-cheques")] public async Task CreateReceivedCheque([FromBody] CreateReceivedChequeRequest request) => Respond(await _chequeService.CreateReceivedChequeAsync(request)); [HttpPut("received-cheques/{id}/status")] public async Task UpdateReceivedChequeStatus(long id, [FromBody] Dictionary payload) => Respond(await _chequeService.UpdateReceivedChequeStatusAsync(id, payload)); [HttpGet("received-cheques/{id}")] public async Task GetReceivedCheque(long id) => Respond(await _chequeService.GetReceivedChequeByIdAsync(id)); [HttpGet("received-cheques")] public async Task ListReceivedCheques([FromQuery] ListReceivedChequesRequest request) => Respond(await _chequeService.ListReceivedChequesAsync(request)); [HttpPost("dev-tools/generate-api-key")] public IActionResult GenerateApiKey() => Respond(_devToolsService.GenerateApiKey()); } }