235 lines
9.2 KiB
C#

using System;
using System.Data.OleDb;
using System.Linq;
using System.Threading.Tasks;
using Compliance.Domain.Models;
using Microsoft.Extensions.Configuration;
using System.Net.Http;
using System.Data.Common;
using System.Collections.Generic;
namespace Compliance.Infrastructure.Repositories
{
public class DistributorRepository : IDistributorRepository
{
private readonly string _connectionString;
private const string BASE_QUERY = "SELECT * FROM [{0}] WHERE Distribuidora = @dist";
private const string GROUP_QUERY = BASE_QUERY + " AND Grupo = @grupo";
private const string MONTH_QUERY = BASE_QUERY + " AND Mes = @mes";
private const string GROUP_MONTH_QUERY = GROUP_QUERY + " AND Mes = @mes";
public DistributorRepository(string connectionString)
{
_connectionString = connectionString ??
throw new ArgumentNullException(nameof(connectionString));
}
public async Task<T?> QuerySingleAsync<T>(string tableName, object parameters)
where T : class, new()
{
using var connection = new OleDbConnection(_connectionString);
await connection.OpenAsync();
using var command = CreateCommand(connection, tableName, parameters);
using var reader = await command.ExecuteReaderAsync();
return await reader.ReadAsync()
? MapReaderToType<T>(reader)
: null;
}
private static OleDbCommand CreateCommand(
OleDbConnection connection,
string tableName,
object parameters)
{
var command = connection.CreateCommand();
var query = string.Format(BASE_QUERY, tableName);
foreach (var prop in parameters.GetType().GetProperties())
{
command.Parameters.AddWithValue($"@{prop.Name.ToLower()}",
prop.GetValue(parameters) ?? DBNull.Value);
}
command.CommandText = query;
return command;
}
private static T MapReaderToType<T>(DbDataReader reader) where T : class, new()
{
var result = new T();
var properties = typeof(T).GetProperties();
foreach (var prop in properties)
{
var columnName = prop.Name;
var ordinal = reader.GetOrdinal(columnName);
if (!reader.IsDBNull(ordinal))
{
var value = reader.GetValue(ordinal);
prop.SetValue(result, Convert.ChangeType(value, prop.PropertyType));
}
}
return result;
}
public async Task<DistributorInformation?> GetDistributorInformationAsync(string distributorName, string month)
{
return await QuerySingleAsync<DistributorInformation>("Distribuidoras",
new { dist = distributorName, mes = month });
}
public async Task<TariffInformation?> GetTariffInformationAsync(string distributorName, string month)
{
return await QuerySingleAsync<TariffInformation>("Tarifas",
new { dist = distributorName, mes = month });
}
public async Task<TaxInformation?> GetTaxInformationAsync(string distributorName, string month)
{
return await QuerySingleAsync<TaxInformation>("Impostos",
new { dist = distributorName, mes = month });
}
public async Task<FlagTariffInformation?> GetFlagTariffInformationAsync(string distributorName, string month)
{
return await QuerySingleAsync<FlagTariffInformation>("BandeiraTarifaria",
new { dist = distributorName, mes = month });
}
public async Task<PublicLightingInformation?> GetPublicLightingInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<PublicLightingInformation>("IluminacaoPublica",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
public async Task<ICMSInformation?> GetICMSInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<ICMSInformation>("ICMS",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
public async Task<DemandInformation?> GetDemandInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<DemandInformation>("Demanda",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
public async Task<ReactiveEnergyInformation?> GetReactiveEnergyInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<ReactiveEnergyInformation>("EnergiaReativa",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
public async Task<MunicipalTaxInformation?> GetMunicipalTaxInformationAsync(
string distributorName,
string municipality,
string month)
{
return await QuerySingleAsync<MunicipalTaxInformation>("TaxaMunicipal",
new { dist = distributorName, municipio = municipality, mes = month });
}
public async Task<SeasonalTariffInformation?> GetSeasonalTariffInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<SeasonalTariffInformation>("TarifaSazonal",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
public async Task<PaymentTermsInformation?> GetPaymentTermsInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<PaymentTermsInformation>("CondicoesPagamento",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
public async Task<MinimumBillingInformation?> GetMinimumBillingAsync(string distributorName)
{
return await QuerySingleAsync<MinimumBillingInformation>("FaturamentoMinimo",
new { dist = distributorName });
}
public async Task<ReadingPeriodInfo> GetReadingPeriodRulesAsync()
{
return await QuerySingleAsync<ReadingPeriodInfo>("RegrasLeitura", new { })
?? throw new InvalidOperationException("Reading period rules not found");
}
public async Task<DistributedGenerationInfo> GetDistributedGenerationInfoAsync(string smartCode)
{
return await QuerySingleAsync<DistributedGenerationInfo>("GeracaoDistribuida",
new { codigo = smartCode })
?? throw new InvalidOperationException("Distributed generation info not found");
}
public async Task<AdditionalChargeInformation?> GetAdditionalChargeInformationAsync(
string distributorName,
string month)
{
return await QuerySingleAsync<AdditionalChargeInformation>("CobrancasAdicionais",
new { dist = distributorName, mes = month });
}
public async Task<SubsidyInformation?> GetSubsidyInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<SubsidyInformation>("Subsidios",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
public async Task<MinimumBillingInformation> GetMinimumBillingInformationAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<MinimumBillingInformation>("FaturamentoMinimo",
new { dist = distributorName, grupo = consumerGroup, mes = month })
?? throw new InvalidOperationException("Minimum billing information not found");
}
public async Task<MeasurementSystemInfo?> GetMeasurementSystemInfoAsync(string meterNumber)
{
return await QuerySingleAsync<MeasurementSystemInfo>("MeasurementSystems",
new { medidor = meterNumber });
}
public async Task<ReadingImpedimentInfo?> GetReadingImpedimentInfoAsync(
string smartCode,
DateTime readingDate)
{
return await QuerySingleAsync<ReadingImpedimentInfo>("ReadingImpediments",
new { codigo = smartCode, data = readingDate });
}
public async Task<GroupSpecificRulesInfo?> GetGroupSpecificRulesInfoAsync(
string distributorName,
string consumerGroup,
string month)
{
return await QuerySingleAsync<GroupSpecificRulesInfo>("RegrasGrupo",
new { dist = distributorName, grupo = consumerGroup, mes = month });
}
}
}