2025-12-17 13:51:48 -03:00
|
|
|
using System.Data;
|
|
|
|
|
using Dapper;
|
|
|
|
|
using SIGCM.Application.DTOs;
|
|
|
|
|
using SIGCM.Domain.Entities;
|
|
|
|
|
using SIGCM.Domain.Interfaces;
|
|
|
|
|
using SIGCM.Infrastructure.Data;
|
|
|
|
|
|
|
|
|
|
namespace SIGCM.Infrastructure.Repositories;
|
|
|
|
|
|
|
|
|
|
public class ListingRepository : IListingRepository
|
|
|
|
|
{
|
|
|
|
|
private readonly IDbConnectionFactory _connectionFactory;
|
|
|
|
|
|
|
|
|
|
public ListingRepository(IDbConnectionFactory connectionFactory)
|
|
|
|
|
{
|
|
|
|
|
_connectionFactory = connectionFactory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<int> CreateAsync(Listing listing, Dictionary<int, string> attributes)
|
|
|
|
|
{
|
|
|
|
|
using var conn = _connectionFactory.CreateConnection();
|
|
|
|
|
conn.Open();
|
|
|
|
|
using var transaction = conn.BeginTransaction();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var sqlListing = @"
|
2025-12-18 13:32:50 -03:00
|
|
|
INSERT INTO Listings (
|
|
|
|
|
CategoryId, OperationId, Title, Description, Price, Currency,
|
|
|
|
|
CreatedAt, Status, UserId, PrintText, PrintStartDate, PrintDaysCount,
|
|
|
|
|
IsBold, IsFrame, PrintFontSize, PrintAlignment
|
|
|
|
|
)
|
|
|
|
|
VALUES (
|
|
|
|
|
@CategoryId, @OperationId, @Title, @Description, @Price, @Currency,
|
|
|
|
|
@CreatedAt, @Status, @UserId, @PrintText, @PrintStartDate, @PrintDaysCount,
|
|
|
|
|
@IsBold, @IsFrame, @PrintFontSize, @PrintAlignment
|
|
|
|
|
);
|
2025-12-17 13:51:48 -03:00
|
|
|
SELECT CAST(SCOPE_IDENTITY() as int);";
|
|
|
|
|
|
|
|
|
|
var listingId = await conn.QuerySingleAsync<int>(sqlListing, listing, transaction);
|
|
|
|
|
|
|
|
|
|
if (attributes != null && attributes.Any())
|
|
|
|
|
{
|
|
|
|
|
var sqlAttr = @"
|
|
|
|
|
INSERT INTO ListingAttributeValues (ListingId, AttributeDefinitionId, Value)
|
|
|
|
|
VALUES (@ListingId, @AttributeDefinitionId, @Value)";
|
|
|
|
|
|
|
|
|
|
foreach (var attr in attributes)
|
|
|
|
|
{
|
|
|
|
|
await conn.ExecuteAsync(sqlAttr, new { ListingId = listingId, AttributeDefinitionId = attr.Key, Value = attr.Value }, transaction);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
transaction.Commit();
|
|
|
|
|
return listingId;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
transaction.Rollback();
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<Listing?> GetByIdAsync(int id)
|
|
|
|
|
{
|
|
|
|
|
using var conn = _connectionFactory.CreateConnection();
|
|
|
|
|
return await conn.QuerySingleOrDefaultAsync<Listing>("SELECT * FROM Listings WHERE Id = @Id", new { Id = id });
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-18 13:32:50 -03:00
|
|
|
public async Task<SIGCM.Domain.Models.ListingDetail?> GetDetailByIdAsync(int id)
|
|
|
|
|
{
|
|
|
|
|
using var conn = _connectionFactory.CreateConnection();
|
|
|
|
|
var sql = @"
|
|
|
|
|
SELECT * FROM Listings WHERE Id = @Id;
|
|
|
|
|
|
|
|
|
|
SELECT lav.*, ad.Name as AttributeName
|
|
|
|
|
FROM ListingAttributeValues lav
|
|
|
|
|
JOIN AttributeDefinitions ad ON lav.AttributeDefinitionId = ad.Id
|
|
|
|
|
WHERE lav.ListingId = @Id;
|
|
|
|
|
|
|
|
|
|
SELECT * FROM ListingImages WHERE ListingId = @Id ORDER BY DisplayOrder;
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
using var multi = await conn.QueryMultipleAsync(sql, new { Id = id });
|
|
|
|
|
var listing = await multi.ReadSingleOrDefaultAsync<Listing>();
|
|
|
|
|
if (listing == null) return null;
|
|
|
|
|
|
|
|
|
|
var attributes = await multi.ReadAsync<SIGCM.Domain.Models.ListingAttributeValueWithName>();
|
|
|
|
|
var images = await multi.ReadAsync<ListingImage>();
|
|
|
|
|
|
|
|
|
|
return new SIGCM.Domain.Models.ListingDetail
|
|
|
|
|
{
|
|
|
|
|
Listing = listing,
|
|
|
|
|
Attributes = attributes,
|
|
|
|
|
Images = images
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-17 13:51:48 -03:00
|
|
|
public async Task<IEnumerable<Listing>> GetAllAsync()
|
|
|
|
|
{
|
|
|
|
|
using var conn = _connectionFactory.CreateConnection();
|
2025-12-18 13:32:50 -03:00
|
|
|
// Subquery para obtener la imagen principal
|
2025-12-17 13:51:48 -03:00
|
|
|
var sql = @"
|
2025-12-18 13:32:50 -03:00
|
|
|
SELECT TOP 20 l.*,
|
|
|
|
|
(SELECT TOP 1 Url FROM ListingImages li WHERE li.ListingId = l.Id ORDER BY IsMainInfo DESC, DisplayOrder ASC) as MainImageUrl
|
2025-12-17 13:51:48 -03:00
|
|
|
FROM Listings l
|
|
|
|
|
ORDER BY l.CreatedAt DESC";
|
2025-12-18 13:32:50 -03:00
|
|
|
|
2025-12-17 13:51:48 -03:00
|
|
|
return await conn.QueryAsync<Listing>(sql);
|
|
|
|
|
}
|
2025-12-18 13:32:50 -03:00
|
|
|
|
|
|
|
|
public async Task<IEnumerable<Listing>> SearchAsync(string? query, int? categoryId)
|
|
|
|
|
{
|
|
|
|
|
using var conn = _connectionFactory.CreateConnection();
|
|
|
|
|
var sql = @"
|
|
|
|
|
SELECT l.*,
|
|
|
|
|
(SELECT TOP 1 Url FROM ListingImages li WHERE li.ListingId = l.Id ORDER BY IsMainInfo DESC, DisplayOrder ASC) as MainImageUrl
|
|
|
|
|
FROM Listings l
|
|
|
|
|
WHERE 1=1";
|
|
|
|
|
|
|
|
|
|
var parameters = new DynamicParameters();
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(query))
|
|
|
|
|
{
|
|
|
|
|
sql += " AND (l.Title LIKE @Query OR l.Description LIKE @Query)";
|
|
|
|
|
parameters.Add("Query", $"%{query}%");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (categoryId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
sql += " AND l.CategoryId = @CategoryId";
|
|
|
|
|
parameters.Add("CategoryId", categoryId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql += " ORDER BY l.CreatedAt DESC";
|
|
|
|
|
|
|
|
|
|
return await conn.QueryAsync<Listing>(sql, parameters);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<IEnumerable<Listing>> GetListingsForPrintAsync(DateTime targetDate)
|
|
|
|
|
{
|
|
|
|
|
using var conn = _connectionFactory.CreateConnection();
|
|
|
|
|
// La lógica: El aviso debe haber empezado antes o en la fecha target
|
|
|
|
|
// Y la fecha target debe ser menor a la fecha de inicio + duración
|
|
|
|
|
var sql = @"
|
|
|
|
|
SELECT l.*, c.Name as CategoryName
|
|
|
|
|
FROM Listings l
|
|
|
|
|
JOIN Categories c ON l.CategoryId = c.Id
|
|
|
|
|
WHERE l.PrintStartDate IS NOT NULL
|
|
|
|
|
AND @TargetDate >= CAST(l.PrintStartDate AS DATE)
|
|
|
|
|
AND @TargetDate < DATEADD(day, l.PrintDaysCount, CAST(l.PrintStartDate AS DATE))
|
|
|
|
|
ORDER BY c.Name, l.Title"; // Ordenado por Rubro y luego alfabético
|
|
|
|
|
|
|
|
|
|
return await conn.QueryAsync<Listing>(sql, new { TargetDate = targetDate.Date });
|
|
|
|
|
}
|
|
|
|
|
}
|