littleshop/Services/ProductService.cs
2025-08-20 13:20:19 +01:00

242 lines
8.2 KiB
C#

using Microsoft.EntityFrameworkCore;
using LittleShop.Data;
using LittleShop.Models;
using LittleShop.DTOs;
namespace LittleShop.Services;
public class ProductService : IProductService
{
private readonly LittleShopContext _context;
private readonly IWebHostEnvironment _environment;
public ProductService(LittleShopContext context, IWebHostEnvironment environment)
{
_context = context;
_environment = environment;
}
public async Task<IEnumerable<ProductDto>> GetAllProductsAsync()
{
return await _context.Products
.Include(p => p.Category)
.Include(p => p.Photos)
.Where(p => p.IsActive)
.Select(p => new ProductDto
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
ProductWeightUnit = p.ProductWeightUnit,
ProductWeight = p.ProductWeight,
BasePrice = p.BasePrice,
CategoryId = p.CategoryId,
CategoryName = p.Category.Name,
CreatedAt = p.CreatedAt,
IsActive = p.IsActive,
Photos = p.Photos.OrderBy(ph => ph.SortOrder).Select(ph => new ProductPhotoDto
{
Id = ph.Id,
FileName = ph.FileName,
FilePath = ph.FilePath,
AltText = ph.AltText,
SortOrder = ph.SortOrder
}).ToList()
})
.ToListAsync();
}
public async Task<IEnumerable<ProductDto>> GetProductsByCategoryAsync(Guid categoryId)
{
return await _context.Products
.Include(p => p.Category)
.Include(p => p.Photos)
.Where(p => p.IsActive && p.CategoryId == categoryId)
.Select(p => new ProductDto
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
ProductWeightUnit = p.ProductWeightUnit,
ProductWeight = p.ProductWeight,
BasePrice = p.BasePrice,
CategoryId = p.CategoryId,
CategoryName = p.Category.Name,
CreatedAt = p.CreatedAt,
IsActive = p.IsActive,
Photos = p.Photos.OrderBy(ph => ph.SortOrder).Select(ph => new ProductPhotoDto
{
Id = ph.Id,
FileName = ph.FileName,
FilePath = ph.FilePath,
AltText = ph.AltText,
SortOrder = ph.SortOrder
}).ToList()
})
.ToListAsync();
}
public async Task<ProductDto?> GetProductByIdAsync(Guid id)
{
var product = await _context.Products
.Include(p => p.Category)
.Include(p => p.Photos)
.FirstOrDefaultAsync(p => p.Id == id);
if (product == null) return null;
return new ProductDto
{
Id = product.Id,
Name = product.Name,
Description = product.Description,
ProductWeightUnit = product.ProductWeightUnit,
ProductWeight = product.ProductWeight,
BasePrice = product.BasePrice,
CategoryId = product.CategoryId,
CategoryName = product.Category.Name,
CreatedAt = product.CreatedAt,
IsActive = product.IsActive,
Photos = product.Photos.OrderBy(ph => ph.SortOrder).Select(ph => new ProductPhotoDto
{
Id = ph.Id,
FileName = ph.FileName,
FilePath = ph.FilePath,
AltText = ph.AltText,
SortOrder = ph.SortOrder
}).ToList()
};
}
public async Task<ProductDto> CreateProductAsync(CreateProductDto createProductDto)
{
var product = new Product
{
Id = Guid.NewGuid(),
Name = createProductDto.Name,
Description = createProductDto.Description,
ProductWeightUnit = createProductDto.ProductWeightUnit,
ProductWeight = createProductDto.ProductWeight,
BasePrice = createProductDto.BasePrice,
CategoryId = createProductDto.CategoryId,
CreatedAt = DateTime.UtcNow,
IsActive = true
};
_context.Products.Add(product);
await _context.SaveChangesAsync();
var category = await _context.Categories.FindAsync(createProductDto.CategoryId);
return new ProductDto
{
Id = product.Id,
Name = product.Name,
Description = product.Description,
ProductWeightUnit = product.ProductWeightUnit,
ProductWeight = product.ProductWeight,
BasePrice = product.BasePrice,
CategoryId = product.CategoryId,
CategoryName = category?.Name ?? "",
CreatedAt = product.CreatedAt,
IsActive = product.IsActive,
Photos = new List<ProductPhotoDto>()
};
}
public async Task<bool> UpdateProductAsync(Guid id, UpdateProductDto updateProductDto)
{
var product = await _context.Products.FindAsync(id);
if (product == null) return false;
if (!string.IsNullOrEmpty(updateProductDto.Name))
product.Name = updateProductDto.Name;
if (!string.IsNullOrEmpty(updateProductDto.Description))
product.Description = updateProductDto.Description;
if (updateProductDto.ProductWeightUnit.HasValue)
product.ProductWeightUnit = updateProductDto.ProductWeightUnit.Value;
if (updateProductDto.ProductWeight.HasValue)
product.ProductWeight = updateProductDto.ProductWeight.Value;
if (updateProductDto.BasePrice.HasValue)
product.BasePrice = updateProductDto.BasePrice.Value;
if (updateProductDto.CategoryId.HasValue)
product.CategoryId = updateProductDto.CategoryId.Value;
if (updateProductDto.IsActive.HasValue)
product.IsActive = updateProductDto.IsActive.Value;
await _context.SaveChangesAsync();
return true;
}
public async Task<bool> DeleteProductAsync(Guid id)
{
var product = await _context.Products.FindAsync(id);
if (product == null) return false;
product.IsActive = false;
await _context.SaveChangesAsync();
return true;
}
public async Task<bool> AddProductPhotoAsync(Guid productId, IFormFile file, string? altText = null)
{
var product = await _context.Products.FindAsync(productId);
if (product == null) return false;
var uploadsPath = Path.Combine(_environment.WebRootPath ?? "wwwroot", "uploads", "products");
Directory.CreateDirectory(uploadsPath);
var fileName = $"{Guid.NewGuid()}_{file.FileName}";
var filePath = Path.Combine(uploadsPath, fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var maxSortOrder = await _context.ProductPhotos
.Where(pp => pp.ProductId == productId)
.Select(pp => pp.SortOrder)
.DefaultIfEmpty(0)
.MaxAsync();
var productPhoto = new ProductPhoto
{
Id = Guid.NewGuid(),
ProductId = productId,
FileName = fileName,
FilePath = $"/uploads/products/{fileName}",
AltText = altText,
SortOrder = maxSortOrder + 1,
CreatedAt = DateTime.UtcNow
};
_context.ProductPhotos.Add(productPhoto);
await _context.SaveChangesAsync();
return true;
}
public async Task<bool> RemoveProductPhotoAsync(Guid productId, Guid photoId)
{
var photo = await _context.ProductPhotos
.FirstOrDefaultAsync(pp => pp.Id == photoId && pp.ProductId == productId);
if (photo == null) return false;
var physicalPath = Path.Combine(_environment.WebRootPath, photo.FilePath.TrimStart('/'));
if (File.Exists(physicalPath))
{
File.Delete(physicalPath);
}
_context.ProductPhotos.Remove(photo);
await _context.SaveChangesAsync();
return true;
}
}