Feat ERP 2
This commit is contained in:
43
src/SIGCM.Infrastructure/Repositories/CalendarRepository.cs
Normal file
43
src/SIGCM.Infrastructure/Repositories/CalendarRepository.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Dapper;
|
||||
using SIGCM.Domain.Entities;
|
||||
using SIGCM.Domain.Interfaces;
|
||||
using SIGCM.Infrastructure.Data;
|
||||
|
||||
namespace SIGCM.Infrastructure.Repositories;
|
||||
|
||||
public class CalendarRepository : ICalendarRepository
|
||||
{
|
||||
private readonly IDbConnectionFactory _db;
|
||||
public CalendarRepository(IDbConnectionFactory db) => _db = db;
|
||||
|
||||
public async Task AddBlackoutAsync(PublicationBlackout blackout)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
await conn.ExecuteAsync(
|
||||
"INSERT INTO PublicationBlackouts (CompanyId, BlackoutDate, Reason) VALUES (@CompanyId, @BlackoutDate, @Reason)",
|
||||
blackout);
|
||||
}
|
||||
|
||||
public async Task DeleteBlackoutAsync(int id)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
await conn.ExecuteAsync("DELETE FROM PublicationBlackouts WHERE Id = @Id", new { Id = id });
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PublicationBlackout>> GetBlackoutsAsync(int companyId, int year)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
return await conn.QueryAsync<PublicationBlackout>(
|
||||
"SELECT * FROM PublicationBlackouts WHERE CompanyId = @CompanyId AND YEAR(BlackoutDate) = @Year ORDER BY BlackoutDate",
|
||||
new { CompanyId = companyId, Year = year });
|
||||
}
|
||||
|
||||
public async Task<bool> IsDateBlockedAsync(int companyId, DateTime date)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
var count = await conn.ExecuteScalarAsync<int>(
|
||||
"SELECT COUNT(1) FROM PublicationBlackouts WHERE CompanyId = @CompanyId AND BlackoutDate = @Date",
|
||||
new { CompanyId = companyId, Date = date.Date });
|
||||
return count > 0;
|
||||
}
|
||||
}
|
||||
53
src/SIGCM.Infrastructure/Repositories/CompanyRepository.cs
Normal file
53
src/SIGCM.Infrastructure/Repositories/CompanyRepository.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Dapper;
|
||||
using SIGCM.Domain.Entities;
|
||||
using SIGCM.Domain.Interfaces;
|
||||
using SIGCM.Infrastructure.Data;
|
||||
|
||||
namespace SIGCM.Infrastructure.Repositories;
|
||||
|
||||
public class CompanyRepository : ICompanyRepository
|
||||
{
|
||||
private readonly IDbConnectionFactory _db;
|
||||
public CompanyRepository(IDbConnectionFactory db) => _db = db;
|
||||
|
||||
public async Task<IEnumerable<Company>> GetAllAsync()
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
// Traemos todas para el admin, ordenadas por nombre
|
||||
return await conn.QueryAsync<Company>("SELECT * FROM Companies ORDER BY Name");
|
||||
}
|
||||
|
||||
public async Task<Company?> GetByIdAsync(int id)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
return await conn.QuerySingleOrDefaultAsync<Company>("SELECT * FROM Companies WHERE Id = @Id", new { Id = id });
|
||||
}
|
||||
|
||||
public async Task<int> CreateAsync(Company company)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
var sql = @"
|
||||
INSERT INTO Companies (Name, TaxId, LegalAddress, LogoUrl, ExternalSystemId, IsActive)
|
||||
VALUES (@Name, @TaxId, @LegalAddress, @LogoUrl, @ExternalSystemId, @IsActive);
|
||||
SELECT CAST(SCOPE_IDENTITY() as int);";
|
||||
return await conn.QuerySingleAsync<int>(sql, company);
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(Company company)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
var sql = @"
|
||||
UPDATE Companies
|
||||
SET Name = @Name, TaxId = @TaxId, LegalAddress = @LegalAddress,
|
||||
LogoUrl = @LogoUrl, ExternalSystemId = @ExternalSystemId, IsActive = @IsActive
|
||||
WHERE Id = @Id";
|
||||
await conn.ExecuteAsync(sql, company);
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
// Soft delete para mantener integridad referencial con productos/ventas históricas
|
||||
await conn.ExecuteAsync("UPDATE Companies SET IsActive = 0 WHERE Id = @Id", new { Id = id });
|
||||
}
|
||||
}
|
||||
@@ -126,4 +126,39 @@ public class ProductRepository : IProductRepository
|
||||
"DELETE FROM ProductBundles WHERE ParentProductId = @ParentId AND ChildProductId = @ChildId",
|
||||
new { ParentId = bundleId, ChildId = childProductId });
|
||||
}
|
||||
|
||||
// Obtener el precio vigente para una fecha dada
|
||||
public async Task<decimal> GetCurrentPriceAsync(int productId, DateTime date)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
// Buscamos el precio específico vigente. Si no hay, fallback al BasePrice del producto.
|
||||
var sql = @"
|
||||
SELECT TOP 1 Price
|
||||
FROM ProductPrices
|
||||
WHERE ProductId = @ProductId
|
||||
AND ValidFrom <= @Date
|
||||
AND (ValidTo IS NULL OR ValidTo >= @Date)
|
||||
ORDER BY ValidFrom DESC";
|
||||
|
||||
var specificPrice = await conn.ExecuteScalarAsync<decimal?>(sql, new { ProductId = productId, Date = date });
|
||||
|
||||
if (specificPrice.HasValue) return specificPrice.Value;
|
||||
|
||||
// Fallback
|
||||
return await conn.ExecuteScalarAsync<decimal>("SELECT BasePrice FROM Products WHERE Id = @Id", new { Id = productId });
|
||||
}
|
||||
|
||||
// Crear nuevo precio histórico
|
||||
public async Task AddPriceAsync(ProductPrice price)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
// Opcional: Cerrar vigencia del precio anterior automáticamente
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE ProductPrices SET ValidTo = GETUTCDATE() WHERE ProductId = @ProductId AND ValidTo IS NULL",
|
||||
new { price.ProductId });
|
||||
|
||||
var sql = @"INSERT INTO ProductPrices (ProductId, Price, ValidFrom, ValidTo, CreatedByUserId)
|
||||
VALUES (@ProductId, @Price, @ValidFrom, @ValidTo, @CreatedByUserId)";
|
||||
await conn.ExecuteAsync(sql, price);
|
||||
}
|
||||
}
|
||||
37
src/SIGCM.Infrastructure/Repositories/ReportRepository.cs
Normal file
37
src/SIGCM.Infrastructure/Repositories/ReportRepository.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Dapper;
|
||||
using SIGCM.Domain.Interfaces;
|
||||
using SIGCM.Infrastructure.Data;
|
||||
|
||||
namespace SIGCM.Infrastructure.Repositories;
|
||||
|
||||
public class ReportRepository : IReportRepository
|
||||
{
|
||||
private readonly IDbConnectionFactory _db;
|
||||
|
||||
public ReportRepository(IDbConnectionFactory db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SettlementItem>> GetInterCompanySettlementAsync(DateTime from, DateTime to)
|
||||
{
|
||||
using var conn = _db.CreateConnection();
|
||||
var sql = @"
|
||||
SELECT
|
||||
b.Name as BillingCompany,
|
||||
s.Name as ServiceCompany,
|
||||
COUNT(*) as TransactionCount,
|
||||
SUM(oi.SubTotal) as TotalAmount
|
||||
FROM OrderItems oi
|
||||
JOIN Orders o ON oi.OrderId = o.Id
|
||||
JOIN Companies b ON oi.BillingCompanyId = b.Id
|
||||
JOIN Companies s ON oi.ServiceCompanyId = s.Id
|
||||
WHERE oi.BillingCompanyId <> oi.ServiceCompanyId
|
||||
AND o.PaymentStatus = 'Paid' -- Solo liquidamos dinero efectivamente cobrado
|
||||
AND o.CreatedAt >= @From AND o.CreatedAt <= @To
|
||||
GROUP BY b.Name, s.Name
|
||||
ORDER BY b.Name, s.Name";
|
||||
|
||||
return await conn.QueryAsync<SettlementItem>(sql, new { From = from, To = to });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user