using DoliMiddlewareApi.Dtos.command; using DoliMiddlewareApi.Dtos.Dolibarr; using DoliMiddlewareApi.Dtos.query; using DoliMiddlewareApi.Exceptions; using DoliMiddlewareApi.Mappers; using DoliMiddlewareApi.Services.Clients; namespace DoliMiddlewareApi.Services; public class BankService(IDolibarrApiClient apiClient) { public async Task> GetAccountsAsync() { var accounts = await apiClient.GetCollectionAsync("bankaccounts?sortfield=t.rowid&sortorder=ASC&limit=100"); return accounts.Select(BankMapper.MapToAccountDto).ToList(); } public async Task GetAccountAsync(int id) { var account = await apiClient.GetResourceAsync($"bankaccounts/{id}"); return BankMapper.MapToAccountDto(account); } public async Task GetBalanceAsync(int id) { var result = await apiClient.GetResourceAsync($"bankaccounts/{id}/balance"); return result.solde ?? 0; } public async Task> GetMovementsAsync(int limit = 20) { // Fetch all accounts first, then their lines in parallel List accounts; try { accounts = await apiClient.GetCollectionAsync("bankaccounts?sortfield=t.rowid&sortorder=ASC&limit=100"); } catch (ApiException) { return []; } if (accounts.Count == 0) return []; var lineTasks = accounts .Where(a => int.TryParse(a.id, out _)) .Select(async a => { var accountId = int.Parse(a.id!); try { var lines = await apiClient.GetCollectionAsync($"bankaccounts/{accountId}/lines"); return lines.Select(l => BankMapper.MapToLineDto(l, accountId)); } catch { return Enumerable.Empty(); } }); var results = await Task.WhenAll(lineTasks); return results .SelectMany(lines => lines) .OrderByDescending(l => l.Date ?? l.DateValue ?? DateTime.MinValue) .Take(limit) .ToList(); } public async Task> GetAccountLinesAsync(int accountId) { var lines = await apiClient.GetCollectionAsync($"bankaccounts/{accountId}/lines"); return lines.Select(l => BankMapper.MapToLineDto(l, accountId)).ToList(); } public async Task UpdateAccountAsync(int id, UpdateBankAccountDto dto) { var requestBody = new Dictionary(); if (dto.Label != null) requestBody["label"] = dto.Label; if (dto.Ref != null) requestBody["ref"] = dto.Ref; if (dto.Type != null) requestBody["type"] = dto.Type; if (dto.CurrencyCode != null) requestBody["currency_code"] = dto.CurrencyCode; if (dto.CountryId != null) requestBody["country_id"] = dto.CountryId; if (dto.AccountNumber!= null) requestBody["number"] = dto.AccountNumber; if (dto.Iban != null) requestBody["iban_prefix"] = dto.Iban; if (dto.Bic != null) requestBody["bic"] = dto.Bic; if (dto.Bank != null) requestBody["bank"] = dto.Bank; await apiClient.PutAsync($"bankaccounts/{id}", requestBody); } public async Task CreateAccountAsync(CreateBankAccountDto dto) { var requestBody = new Dictionary { ["ref"] = dto.Ref, ["label"] = dto.Label, ["type"] = dto.Type, ["currency_code"] = dto.CurrencyCode, ["country_id"] = dto.CountryId, ["number"] = dto.AccountNumber, ["iban_prefix"] = dto.Iban, ["bic"] = dto.Bic, ["bank"] = dto.Bank, ["clos"] = 0, }; var response = await apiClient.PostAsync("bankaccounts", requestBody); return int.TryParse(response, out var id) ? id : 0; } }