Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f54f5e02dc | |||
| d17f2fb23e | |||
| 697e1431d9 | |||
| de6a1c5385 | |||
| 29759cf896 | |||
| f0ad9b536a | |||
| fb97729c71 | |||
| 1bd92a8732 | |||
| 8c38255ed9 | |||
| 639631a63b | |||
| 5869ae18c4 | |||
| fc9da89ebe | |||
| 76239b41bd | |||
| 88882f9db8 | |||
| 6339fbdb8c | |||
| 6f2c60e6c0 | |||
| cac880e35f | |||
| 897b036fc5 | |||
| 19c63ef317 | |||
| fdaead91ff | |||
| aa40ae2e7a | |||
| ed59efe4f8 | |||
| b13b8ebfb6 | |||
| 57646a1417 | |||
| 3cb619cfa6 | |||
| 48b9db6e1c | |||
| c0ac9f7a65 | |||
| d46fa606b7 | |||
| b59a8b6c3d | |||
| 1ae8072219 |
@@ -0,0 +1,7 @@
|
|||||||
|
namespace PyroFetes.DTO.Customer.Response;
|
||||||
|
|
||||||
|
public class GetCustomerDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? Note { get; set; }
|
||||||
|
}
|
||||||
@@ -3,10 +3,9 @@ namespace PyroFetes.DTO.DeliveryNote.Request;
|
|||||||
public class CreateDeliveryNoteDto
|
public class CreateDeliveryNoteDto
|
||||||
{
|
{
|
||||||
public string? TrackingNumber { get; set; }
|
public string? TrackingNumber { get; set; }
|
||||||
public DateOnly EstimateDeliveryDate { get; set; }
|
|
||||||
public DateOnly ExpeditionDate { get; set; }
|
|
||||||
|
|
||||||
public int DelivererId { get; set; }
|
public int DelivererId { get; set; }
|
||||||
|
public int SupplierId { get; set; }
|
||||||
|
|
||||||
public Dictionary<int, int>? ProductQuantities { get; set; }
|
public Dictionary<int, int>? ProductQuantities { get; set; }
|
||||||
}
|
}
|
||||||
@@ -5,5 +5,6 @@ namespace PyroFetes.DTO.PurchaseOrder.Request;
|
|||||||
public class CreatePurchaseOrderDto
|
public class CreatePurchaseOrderDto
|
||||||
{
|
{
|
||||||
public string? PurchaseConditions { get; set; }
|
public string? PurchaseConditions { get; set; }
|
||||||
|
public int SupplierId { get; set; }
|
||||||
public List<CreatePurchaseOrderProductDto>? Products { get; set; }
|
public List<CreatePurchaseOrderProductDto>? Products { get; set; }
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,6 @@ public class GetPurchaseOrderDto
|
|||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string? PurchaseConditions { get; set; }
|
public string? PurchaseConditions { get; set; }
|
||||||
public int SupplierId { get; set; }
|
public int SupplierId { get; set; }
|
||||||
|
public string? SupplierName { get; set; }
|
||||||
public List<GetPurchaseProductDto>? Products { get; set; }
|
public List<GetPurchaseProductDto>? Products { get; set; }
|
||||||
}
|
}
|
||||||
@@ -15,5 +15,7 @@ public class GetPurchaseProductDto
|
|||||||
public int ProductMinimalQuantity { get; set; }
|
public int ProductMinimalQuantity { get; set; }
|
||||||
public decimal ProductPrice { get; set; }
|
public decimal ProductPrice { get; set; }
|
||||||
|
|
||||||
|
public int PurchaseOrderId { get; set; }
|
||||||
|
|
||||||
public int Quantity { get; set; }
|
public int Quantity { get; set; }
|
||||||
}
|
}
|
||||||
@@ -6,5 +6,7 @@ public class CreateQuotationDto
|
|||||||
{
|
{
|
||||||
public string? Message { get; set; }
|
public string? Message { get; set; }
|
||||||
public string? ConditionsSale { get; set; }
|
public string? ConditionsSale { get; set; }
|
||||||
|
public int CustomerId { get; set; }
|
||||||
|
public int SupplierId { get; set; }
|
||||||
public List<CreateProductQuotationDto>? Products { get; set; }
|
public List<CreateProductQuotationDto>? Products { get; set; }
|
||||||
}
|
}
|
||||||
@@ -15,4 +15,6 @@ public class GetQuotationProductDto
|
|||||||
public string? ProductImage { get; set; }
|
public string? ProductImage { get; set; }
|
||||||
public string? ProductLink { get; set; }
|
public string? ProductLink { get; set; }
|
||||||
public int ProductMinimalQuantity { get; set; }
|
public int ProductMinimalQuantity { get; set; }
|
||||||
|
public decimal ProductPrice { get; set; }
|
||||||
|
public int QuotationId { get; set; }
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace PyroFetes.DTO.Refresh.Request;
|
||||||
|
|
||||||
|
public class RefreshTokenDto
|
||||||
|
{
|
||||||
|
public string? Token { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace PyroFetes.DTO.Refresh.Response;
|
||||||
|
|
||||||
|
public class GetRefreshTokenDto
|
||||||
|
{
|
||||||
|
public string? Token { get; set; }
|
||||||
|
}
|
||||||
@@ -2,6 +2,5 @@ namespace PyroFetes.DTO.SettingDTO.Request;
|
|||||||
|
|
||||||
public class PatchSettingElectronicSignatureDto
|
public class PatchSettingElectronicSignatureDto
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
|
||||||
public IFormFile? ElectronicSignature { get; set; }
|
public IFormFile? ElectronicSignature { get; set; }
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,5 @@ namespace PyroFetes.DTO.SettingDTO.Request;
|
|||||||
|
|
||||||
public class PatchSettingLogoDto
|
public class PatchSettingLogoDto
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
|
||||||
public IFormFile? Logo { get; set; }
|
public IFormFile? Logo { get; set; }
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,6 @@ public class GetUserDto
|
|||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
public string? Password { get; set; }
|
public string? Password { get; set; }
|
||||||
public string? Salt { get; set; }
|
|
||||||
public string? Fonction { get; set; }
|
public string? Fonction { get; set; }
|
||||||
public string? Email { get; set; }
|
public string? Email { get; set; }
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace PyroFetes.DTO.WareHouse.Response;
|
||||||
|
|
||||||
|
public class GetWareHouseDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using PyroFetes.DTO.Customer.Response;
|
||||||
|
using PyroFetes.Repositories;
|
||||||
|
|
||||||
|
namespace PyroFetes.Endpoints.Customers;
|
||||||
|
|
||||||
|
public class GetAllCustomersEndpoint(CustomersRepository customersRepository, AutoMapper.IMapper mapper) : EndpointWithoutRequest<List<GetCustomerDto>>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Get("/customers");
|
||||||
|
Roles("Admin","Employe");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
{
|
||||||
|
await Send.OkAsync(await customersRepository.ProjectToListAsync<GetCustomerDto>(ct), ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ public class CreateDelivererEndpoint(DeliverersRepository deliverersRepository)
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/deliverers");
|
Post("/deliverers");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateDelivererDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreateDelivererDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class DeleteDelivererEndpoint(DeliverersRepository deliverersRepository)
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/deliverers/{@Id}", x => new { x.DelivererId });
|
Delete("/deliverers/{@Id}", x => new { x.DelivererId });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteDelivererRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeleteDelivererRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class GetAllDelivererEndpoint(DeliverersRepository deliverersRepository)
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/deliverers");
|
Get("/deliverers");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class GetDelivererEndpoint(DeliverersRepository deliverersRepository, Aut
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/deliverers/{@Id}", x => new { x.DelivererId });
|
Get("/deliverers/{@Id}", x => new { x.DelivererId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetDelivererRequest req, CancellationToken ct)
|
public override async Task HandleAsync(GetDelivererRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class UpdateDelivererEndpoint(DeliverersRepository deliverersRepository,
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Put("/deliverers/{@Id}", x => new { x.Id });
|
Put("/deliverers/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin", "Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateDelivererDto req, CancellationToken ct)
|
public override async Task HandleAsync(UpdateDelivererDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using PyroFetes.Models;
|
|||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
using PyroFetes.Specifications.Deliverers;
|
using PyroFetes.Specifications.Deliverers;
|
||||||
using PyroFetes.Specifications.Products;
|
using PyroFetes.Specifications.Products;
|
||||||
|
using PyroFetes.Specifications.Suppliers;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.DeliveryNotes;
|
namespace PyroFetes.Endpoints.DeliveryNotes;
|
||||||
|
|
||||||
@@ -11,18 +12,20 @@ public class CreateDeliveryNoteEndpoint(
|
|||||||
DeliveryNotesRepository deliveryNotesRepository,
|
DeliveryNotesRepository deliveryNotesRepository,
|
||||||
DeliverersRepository deliverersRepository,
|
DeliverersRepository deliverersRepository,
|
||||||
ProductsRepository productsRepository,
|
ProductsRepository productsRepository,
|
||||||
|
SuppliersRepository suppliersRepository,
|
||||||
ProductDeliveriesRepository productDeliveriesRepository) : Endpoint<CreateDeliveryNoteDto>
|
ProductDeliveriesRepository productDeliveriesRepository) : Endpoint<CreateDeliveryNoteDto>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/deliveryNotes");
|
Post("/deliveryNotes");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateDeliveryNoteDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreateDeliveryNoteDto req, CancellationToken ct)
|
||||||
{
|
{
|
||||||
Deliverer? deliverer = await deliverersRepository.SingleOrDefaultAsync(new GetDelivererByIdSpec(req.DelivererId), ct);
|
Deliverer? deliverer = await deliverersRepository.SingleOrDefaultAsync(new GetDelivererByIdSpec(req.DelivererId), ct);
|
||||||
if (deliverer is null)
|
Supplier? supplier = await suppliersRepository.SingleOrDefaultAsync(new GetSupplierByIdSpec(req.SupplierId), ct);
|
||||||
|
if (deliverer is null || supplier is null)
|
||||||
{
|
{
|
||||||
await Send.NotFoundAsync(ct);
|
await Send.NotFoundAsync(ct);
|
||||||
return;
|
return;
|
||||||
@@ -32,10 +35,12 @@ public class CreateDeliveryNoteEndpoint(
|
|||||||
DeliveryNote newDeliveryNote = new()
|
DeliveryNote newDeliveryNote = new()
|
||||||
{
|
{
|
||||||
TrackingNumber = req.TrackingNumber,
|
TrackingNumber = req.TrackingNumber,
|
||||||
EstimateDeliveryDate = req.EstimateDeliveryDate,
|
EstimateDeliveryDate = DateOnly.FromDateTime(DateTime.Today).AddMonths(2),
|
||||||
ExpeditionDate = req.ExpeditionDate,
|
ExpeditionDate = DateOnly.FromDateTime(DateTime.Today),
|
||||||
DelivererId = deliverer.Id,
|
DelivererId = deliverer.Id,
|
||||||
Deliverer = deliverer,
|
Deliverer = deliverer,
|
||||||
|
SupplierId = req.SupplierId,
|
||||||
|
Supplier = supplier
|
||||||
};
|
};
|
||||||
|
|
||||||
await deliveryNotesRepository.AddAsync(newDeliveryNote, ct);
|
await deliveryNotesRepository.AddAsync(newDeliveryNote, ct);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class DeleteDeliveryNoteEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/deliveryNotes/{@Id}", x => new { x.Id });
|
Delete("/deliveryNotes/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteDeliveryNoteRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeleteDeliveryNoteRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class GetAllDeliveryNoteEndpoint(DeliveryNotesRepository deliveryNotesRep
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/deliveryNotes");
|
Get("/deliveryNotes");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using PyroFetes.DTO.DeliveryNote.Response;
|
||||||
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Specifications.DeliveryNotes;
|
||||||
|
|
||||||
|
namespace PyroFetes.Endpoints.DeliveryNotes;
|
||||||
|
|
||||||
|
public class GetAllDeliveryNotesNotArrivedEndpoint(DeliveryNotesRepository deliveryNotesRepository) : EndpointWithoutRequest<List<GetDeliveryNoteDto>>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Get("/deliveryNotes/validation");
|
||||||
|
Roles("Admin","Employe");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
{
|
||||||
|
await Send.OkAsync(await deliveryNotesRepository.ProjectToListAsync<GetDeliveryNoteDto>(new GetAllDeliveryNotesByRealDateSpec(), ct), ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ public class GetDeliveryNoteEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/deliveryNotes/{@Id}", x => new { x.DeliveryNoteId });
|
Get("/deliveryNotes/{@Id}", x => new { x.DeliveryNoteId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetDeliveryNoteRequest req, CancellationToken ct)
|
public override async Task HandleAsync(GetDeliveryNoteRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -3,18 +3,23 @@ using FastEndpoints;
|
|||||||
using PyroFetes.DTO.DeliveryNote.Request;
|
using PyroFetes.DTO.DeliveryNote.Request;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Services;
|
||||||
using PyroFetes.Services.Pdf;
|
using PyroFetes.Services.Pdf;
|
||||||
using PyroFetes.Specifications.DeliveryNotes;
|
using PyroFetes.Specifications.DeliveryNotes;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.DeliveryNotes;
|
namespace PyroFetes.Endpoints.DeliveryNotes;
|
||||||
|
|
||||||
public class GetDeliveryNotePdfEndpoint(DeliveryNotesRepository deliveryNotesRepository, IDeliveryNotePdfService deliveryNotePdfService, SettingsRepository settingsRepository)
|
public class GetDeliveryNotePdfEndpoint(
|
||||||
|
DeliveryNotesRepository deliveryNotesRepository,
|
||||||
|
DeliveryNotePdfService deliveryNotePdfService,
|
||||||
|
SettingsRepository settingsRepository,
|
||||||
|
StorageService storageService)
|
||||||
: Endpoint<GetDeliveryNotePdfDto, byte[]>
|
: Endpoint<GetDeliveryNotePdfDto, byte[]>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/deliveryNotes/{@Id}/pdf", x => new { x.Id });
|
Get("/deliveryNotes/{@Id}/pdf", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin", "Employe");
|
||||||
Description(b => b.Produces<byte[]>(200, MediaTypeNames.Application.Pdf));
|
Description(b => b.Produces<byte[]>(200, MediaTypeNames.Application.Pdf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +36,7 @@ public class GetDeliveryNotePdfEndpoint(DeliveryNotesRepository deliveryNotesRep
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = deliveryNotePdfService.Generate(deliveryNote, deliveryNote.ProductDeliveries!, setting!);
|
byte[] bytes = await deliveryNotePdfService.Generate(deliveryNote, setting!, storageService);
|
||||||
|
|
||||||
await Send.BytesAsync(
|
await Send.BytesAsync(
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class PatchRealDeliveryDateEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/deliveryNotes/{@Id}", x => new { x.Id });
|
Patch("/deliveryNotes/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchDeliveryNoteRealDeliveryDateDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchDeliveryNoteRealDeliveryDateDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class UpdateDeliveryNoteEndpoint(DeliveryNotesRepository deliveryNotesRep
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Put("/deliveryNotes/{@Id}", x => new { x.Id });
|
Put("/deliveryNotes/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateDeliveryNoteDto req, CancellationToken ct)
|
public override async Task HandleAsync(UpdateDeliveryNoteDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public class DeleteProductEndpoint(ProductsRepository productsRepository) : Endp
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/products/{@Id}", x => new { x.ProductId });
|
Delete("/products/{@Id}", x => new { x.ProductId });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteProductsRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeleteProductsRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class GetAllProductsEndpoint(ProductsRepository productsRepository) : End
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/products");
|
Get("/products");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class GetAllProductsUnderLimitEndpoint(ProductsRepository productsReposit
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/products/underLimit");
|
Get("/products/underLimit");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ public class GetProductEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/products/{@Id}", x => new { x.Id });
|
Get("/products/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetProductRequest req, CancellationToken ct)
|
public override async Task HandleAsync(GetProductRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class PatchProductMinimalStockEndpoint(ProductsRepository productsReposit
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/products/{@Id}/MinimalStock", x => new { x.Id });
|
Patch("/products/{@Id}/MinimalStock", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchProductMinimalStockDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchProductMinimalStockDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class UpdateProductEndpoint(ProductsRepository productsRepository, AutoMa
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Put("/products/{@Id}", x => new { x.Id });
|
Put("/products/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateProductDto req, CancellationToken ct)
|
public override async Task HandleAsync(UpdateProductDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class AddProductFromPurchaseOrderEndpoint(PurchaseProductsRepository purc
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/purchaseOrders/{@PurchaseOrderId}/{@ProductId}", x => new { x.PurchaseOrderId, x.ProductId });
|
Post("/purchaseOrders/{@PurchaseOrderId}/{@ProductId}", x => new { x.PurchaseOrderId, x.ProductId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreatePurchaseProductDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreatePurchaseProductDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using FastEndpoints;
|
using FastEndpoints;
|
||||||
using PyroFetes.DTO.PurchaseOrder.Request;
|
using PyroFetes.DTO.PurchaseOrder.Request;
|
||||||
|
using PyroFetes.DTO.PurchaseOrder.Response;
|
||||||
using PyroFetes.DTO.PurchaseProduct.Request;
|
using PyroFetes.DTO.PurchaseProduct.Request;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
@@ -12,17 +13,18 @@ public class CreatePurchaseOrder(
|
|||||||
PurchaseOrdersRepository purchaseOrdersRepository,
|
PurchaseOrdersRepository purchaseOrdersRepository,
|
||||||
ProductsRepository productsRepository,
|
ProductsRepository productsRepository,
|
||||||
PurchaseProductsRepository purchaseProductsRepository,
|
PurchaseProductsRepository purchaseProductsRepository,
|
||||||
AutoMapper.IMapper mapper) : Endpoint<CreatePurchaseOrderDto>
|
AutoMapper.IMapper mapper) : Endpoint<CreatePurchaseOrderDto, GetPurchaseOrderDto>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/purchaseOrders");
|
Post("/purchaseOrders");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreatePurchaseOrderDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreatePurchaseOrderDto req, CancellationToken ct)
|
||||||
{
|
{
|
||||||
PurchaseOrder purchaseOrder = mapper.Map<PurchaseOrder>(req);
|
PurchaseOrder purchaseOrder = mapper.Map<PurchaseOrder>(req);
|
||||||
|
await purchaseOrdersRepository.AddAsync(purchaseOrder, ct);
|
||||||
|
|
||||||
if (req.Products != null)
|
if (req.Products != null)
|
||||||
{
|
{
|
||||||
@@ -41,6 +43,7 @@ public class CreatePurchaseOrder(
|
|||||||
if (purchaseProduct is not null)
|
if (purchaseProduct is not null)
|
||||||
{
|
{
|
||||||
await Send.StringAsync("Le produit est déjà dans le bon de commande", 400, cancellation: ct);
|
await Send.StringAsync("Le produit est déjà dans le bon de commande", 400, cancellation: ct);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PurchaseProduct? productOnPurchase = mapper.Map<PurchaseProduct>(line);
|
PurchaseProduct? productOnPurchase = mapper.Map<PurchaseProduct>(line);
|
||||||
@@ -49,8 +52,6 @@ public class CreatePurchaseOrder(
|
|||||||
await purchaseProductsRepository.AddAsync(productOnPurchase, ct);
|
await purchaseProductsRepository.AddAsync(productOnPurchase, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await Send.OkAsync(mapper.Map<GetPurchaseOrderDto>(purchaseOrder), ct);
|
||||||
await purchaseOrdersRepository.AddAsync(purchaseOrder, ct);
|
|
||||||
await Send.NoContentAsync(ct);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ public class DeleteProductFromPurchaseOrderEndpoint(PurchaseProductsRepository p
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/purchaseOrders/{@ProductId}/{@PurchaseOrderId}", x => new { x.ProductId, x.PurchaseOrderId });
|
Delete("/purchaseOrders/{@ProductId}/{@PurchaseOrderId}", x => new { x.ProductId, x.PurchaseOrderId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeletePurchaseProductRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeletePurchaseProductRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public class DeletePurchaseOrderEndpoint(PurchaseOrdersRepository purchaseOrders
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/purchaseOrders/{@Id}", x => new { x.Id });
|
Delete("/purchaseOrders/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeletePurchaseOrderRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeletePurchaseOrderRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using FastEndpoints;
|
using FastEndpoints;
|
||||||
using PyroFetes.DTO.PurchaseOrder.Response;
|
using PyroFetes.DTO.PurchaseOrder.Response;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Specifications.PurchaseOrders;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.PurchaseOrders;
|
namespace PyroFetes.Endpoints.PurchaseOrders;
|
||||||
|
|
||||||
@@ -9,11 +10,11 @@ public class GetAllPurchaseOrderEndpoint(PurchaseOrdersRepository purchaseOrders
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/purchaseOrders");
|
Get("/purchaseOrders");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
await Send.OkAsync(await purchaseOrdersRepository.ProjectToListAsync<GetPurchaseOrderDto>(ct), ct);
|
await Send.OkAsync(await purchaseOrdersRepository.ProjectToListAsync<GetPurchaseOrderDto>(new GetAllPurchaseOrderSpec(), ct), ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ public class GetPurchaseOrderEndpoint(PurchaseOrdersRepository purchaseOrdersRep
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/purchaseOrders/{@Id}", x => new { x.Id });
|
Get("/purchaseOrders/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetPurchaseOrderRequest req, CancellationToken ct)
|
public override async Task HandleAsync(GetPurchaseOrderRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using FastEndpoints;
|
|||||||
using PyroFetes.DTO.PurchaseOrder.Request;
|
using PyroFetes.DTO.PurchaseOrder.Request;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Services;
|
||||||
using PyroFetes.Services.Pdf;
|
using PyroFetes.Services.Pdf;
|
||||||
using PyroFetes.Specifications.PurchaseOrders;
|
using PyroFetes.Specifications.PurchaseOrders;
|
||||||
|
|
||||||
@@ -10,14 +11,15 @@ namespace PyroFetes.Endpoints.PurchaseOrders;
|
|||||||
|
|
||||||
public class GetPurchaseOrderPdfEndpoint(
|
public class GetPurchaseOrderPdfEndpoint(
|
||||||
PurchaseOrdersRepository purchaseOrdersRepository,
|
PurchaseOrdersRepository purchaseOrdersRepository,
|
||||||
IPurchaseOrderPdfService purchaseOrderPdfService,
|
PurchaseOrderPdfService purchaseOrderPdfService,
|
||||||
SettingsRepository settingsRepository)
|
SettingsRepository settingsRepository,
|
||||||
|
StorageService storageService)
|
||||||
: Endpoint<GetPurchaseOrderPdfDto, byte[]>
|
: Endpoint<GetPurchaseOrderPdfDto, byte[]>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/purchaseOrders/{@Id}/pdf", x => new { x.Id });
|
Get("/purchaseOrders/{@Id}/pdf", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
Description(b => b.Produces<byte[]>(200, MediaTypeNames.Application.Pdf));
|
Description(b => b.Produces<byte[]>(200, MediaTypeNames.Application.Pdf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ public class GetPurchaseOrderPdfEndpoint(
|
|||||||
|
|
||||||
Setting? setting = await settingsRepository.FirstOrDefaultAsync(ct);
|
Setting? setting = await settingsRepository.FirstOrDefaultAsync(ct);
|
||||||
|
|
||||||
byte[] bytes = purchaseOrderPdfService.Generate(purchaseOrder, purchaseOrder.PurchaseProducts!, setting!);
|
byte[] bytes = await purchaseOrderPdfService.Generate(purchaseOrder, setting!, storageService);
|
||||||
|
|
||||||
await Send.BytesAsync(
|
await Send.BytesAsync(
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class PatchPurchaseOrderPurchaseConditionsEndpoint(PurchaseOrdersReposito
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/purchaseOrders/{@Id}/PurchaseConditions", x => new { x.Id });
|
Patch("/purchaseOrders/{@Id}/PurchaseConditions", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchPurchaseOrderPurchaseConditionsDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchPurchaseOrderPurchaseConditionsDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class PatchPurchaseProductQuantityEndpoint(PurchaseProductsRepository pur
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/purchaseOrders/{@ProductId}/{@PurchaseOrderId}/Quantity", x => new { x.ProductId, x.PurchaseOrderId });
|
Patch("/purchaseOrders/{@ProductId}/{@PurchaseOrderId}/Quantity", x => new { x.ProductId, x.PurchaseOrderId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchPurchaseProductQuantityDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchPurchaseProductQuantityDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class AddProductoToQuotationEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/quotations/{@Id}/products", x => new { x.ProductId, x.QuotationId });
|
Post("/quotations/{@Id}/products", x => new { x.ProductId, x.QuotationId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(AddQuotationProductDto req, CancellationToken ct)
|
public override async Task HandleAsync(AddQuotationProductDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using FastEndpoints;
|
using FastEndpoints;
|
||||||
using PyroFetes.DTO.Quotation.Request;
|
using PyroFetes.DTO.Quotation.Request;
|
||||||
using PyroFetes.DTO.Quotation.Response;
|
|
||||||
using PyroFetes.DTO.QuotationProduct.Request;
|
using PyroFetes.DTO.QuotationProduct.Request;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
@@ -18,13 +17,13 @@ public class CreateQuotationEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/quotations");
|
Post("/quotations");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateQuotationDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreateQuotationDto req, CancellationToken ct)
|
||||||
{
|
{
|
||||||
Quotation quotation = mapper.Map<Quotation>(req);
|
Quotation quotation = mapper.Map<Quotation>(req);
|
||||||
quotation.CustomerId = 1; // TODO: A changer
|
await quotationsRepository.AddAsync(quotation, ct);
|
||||||
|
|
||||||
if (req.Products != null)
|
if (req.Products != null)
|
||||||
{
|
{
|
||||||
@@ -43,6 +42,7 @@ public class CreateQuotationEndpoint(
|
|||||||
if (quotationProduct is not null)
|
if (quotationProduct is not null)
|
||||||
{
|
{
|
||||||
await Send.StringAsync("Le produit est déjà dans le devis", 400, cancellation: ct);
|
await Send.StringAsync("Le produit est déjà dans le devis", 400, cancellation: ct);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QuotationProduct? productOnQuotation = mapper.Map<QuotationProduct>(line);
|
QuotationProduct? productOnQuotation = mapper.Map<QuotationProduct>(line);
|
||||||
@@ -52,7 +52,6 @@ public class CreateQuotationEndpoint(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await quotationsRepository.AddAsync(quotation, ct);
|
|
||||||
await Send.NoContentAsync(ct);
|
await Send.NoContentAsync(ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ public class DeleteProductFromQuotationEndpoint(QuotationProductsRepository quot
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/quotations/{@ProductId}/{@QuotationId}", x => new { x.ProductId, x.QuotationId });
|
Delete("/quotations/{@ProductId}/{@QuotationId}", x => new { x.ProductId, x.QuotationId });
|
||||||
AllowAnonymous();
|
Roles("Admin", "Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteQuotationProductRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeleteQuotationProductRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public class DeleteQuotationEndpoint(QuotationsRepository quotationsRepository)
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/quotations/{@Id}", x => new { x.Id });
|
Delete("/quotations/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteQuotationRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeleteQuotationRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using FastEndpoints;
|
using FastEndpoints;
|
||||||
using PyroFetes.DTO.Quotation.Response;
|
using PyroFetes.DTO.Quotation.Response;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Specifications.Quotations;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.Quotations;
|
namespace PyroFetes.Endpoints.Quotations;
|
||||||
|
|
||||||
@@ -9,11 +10,11 @@ public class GetAllQuotationEndpoint(QuotationsRepository quotationsRepository)
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/quotations");
|
Get("/quotations");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
await Send.OkAsync(await quotationsRepository.ProjectToListAsync<GetQuotationDto>(ct), ct);
|
await Send.OkAsync(await quotationsRepository.ProjectToListAsync<GetQuotationDto>(new GetAllQuotationSpec(), ct), ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ public class GetQuotationEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/quotations/{@Id}", x => new { x.Id });
|
Get("/quotations/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetQuotationRequest req, CancellationToken ct)
|
public override async Task HandleAsync(GetQuotationRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using FastEndpoints;
|
|||||||
using PyroFetes.DTO.Quotation.Request;
|
using PyroFetes.DTO.Quotation.Request;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Services;
|
||||||
using PyroFetes.Services.Pdf;
|
using PyroFetes.Services.Pdf;
|
||||||
using PyroFetes.Specifications.Quotations;
|
using PyroFetes.Specifications.Quotations;
|
||||||
|
|
||||||
@@ -10,14 +11,15 @@ namespace PyroFetes.Endpoints.Quotations;
|
|||||||
|
|
||||||
public class GetQuotationPdfEndpoint(
|
public class GetQuotationPdfEndpoint(
|
||||||
QuotationsRepository quotationRepository,
|
QuotationsRepository quotationRepository,
|
||||||
IQuotationPdfService quotationPdfService,
|
QuotationPdfService quotationPdfService,
|
||||||
SettingsRepository settingsRepository)
|
SettingsRepository settingsRepository,
|
||||||
|
StorageService storageService)
|
||||||
: Endpoint<GetQuotationPdfDto, byte[]>
|
: Endpoint<GetQuotationPdfDto, byte[]>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/quotations/{@Id}/pdf", x => new { x.Id });
|
Get("/quotations/{@Id}/pdf", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
Description(b => b.Produces<byte[]>(200, MediaTypeNames.Application.Pdf));
|
Description(b => b.Produces<byte[]>(200, MediaTypeNames.Application.Pdf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ public class GetQuotationPdfEndpoint(
|
|||||||
|
|
||||||
Setting? setting = await settingsRepository.FirstOrDefaultAsync(ct);
|
Setting? setting = await settingsRepository.FirstOrDefaultAsync(ct);
|
||||||
|
|
||||||
byte[] bytes = quotationPdfService.Generate(quotation, quotation.QuotationProducts!, setting!);
|
byte[] bytes = await quotationPdfService.Generate(quotation, setting!, storageService);
|
||||||
|
|
||||||
await Send.BytesAsync(
|
await Send.BytesAsync(
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class PatchQuotationConditionsSaleEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/quotations/{@Id}/saleConditions", x => new { x.Id });
|
Patch("/quotations/{@Id}/saleConditions", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchQuotationConditionsSaleDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchQuotationConditionsSaleDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class PatchQuotationMessageEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/quotations/{@Id}/message", x => new { x.Id });
|
Patch("/quotations/{@Id}/message", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchQuotationMessageDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchQuotationMessageDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class PatchQuotationProductQuantityEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/quotations/{@ProductId}/{@QuotationId}/Quantity", x => new { x.ProductId, x.QuotationId });
|
Patch("/quotations/{@ProductId}/{@QuotationId}/Quantity", x => new { x.ProductId, x.QuotationId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchQuotationProductQuantityDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchQuotationProductQuantityDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using FastEndpoints;
|
using FastEndpoints;
|
||||||
using PyroFetes.DTO.Quotation.Request;
|
using PyroFetes.DTO.Quotation.Request;
|
||||||
using PyroFetes.DTO.Quotation.Response;
|
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
using PyroFetes.Specifications.Quotations;
|
using PyroFetes.Specifications.Quotations;
|
||||||
@@ -14,7 +13,8 @@ public class UpdateQuotationEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Put("/quotations/{@Id}", x => new { x.Id });
|
Put("/quotations/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateQuotationDto req, CancellationToken ct)
|
public override async Task HandleAsync(UpdateQuotationDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using FastEndpoints;
|
||||||
|
using FastEndpoints.Security;
|
||||||
|
using PyroFetes.DTO.Refresh.Request;
|
||||||
|
using PyroFetes.DTO.Refresh.Response;
|
||||||
|
using PyroFetes.Models;
|
||||||
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Specifications.Users;
|
||||||
|
|
||||||
|
namespace PyroFetes.Endpoints.Refresh;
|
||||||
|
|
||||||
|
public class RefreshTokenEndpoint(UsersRepository usersRepository) : Endpoint<RefreshTokenDto, GetRefreshTokenDto>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Post("/refresh");
|
||||||
|
AllowAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(RefreshTokenDto req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JwtSecurityTokenHandler handler = new();
|
||||||
|
JwtSecurityToken? token = handler.ReadJwtToken(req.Token);
|
||||||
|
string? username = token.Claims.FirstOrDefault(c => c.Type == "Name")?.Value;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(username))
|
||||||
|
{
|
||||||
|
await Send.UnauthorizedAsync(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
User? login = await usersRepository.SingleOrDefaultAsync(new GetUserByNameSpec(username), ct);
|
||||||
|
if (login == null)
|
||||||
|
{
|
||||||
|
await Send.UnauthorizedAsync(ct);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string jwtToken = JwtBearer.CreateToken(o =>
|
||||||
|
{
|
||||||
|
o.SigningKey = "v9!Qx7#Lk2@pZ8$wR6!tN5%uF3&cD9^mH1*eY4";
|
||||||
|
o.ExpireAt = DateTime.UtcNow.AddMinutes(15);
|
||||||
|
if (login.Fonction is not null) o.User.Roles.Add(login.Fonction);
|
||||||
|
o.User.Claims.Add(("Name", login.Name)!);
|
||||||
|
o.User.Claims.Add(("Id", login.Id.ToString())!);
|
||||||
|
});
|
||||||
|
|
||||||
|
GetRefreshTokenDto responseDto = new()
|
||||||
|
{
|
||||||
|
Token = jwtToken
|
||||||
|
};
|
||||||
|
|
||||||
|
await Send.OkAsync(responseDto, ct);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await Send.UnauthorizedAsync(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using PyroFetes.DTO.SettingDTO.Request;
|
|
||||||
using PyroFetes.Models;
|
|
||||||
using PyroFetes.Repositories;
|
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.Settings;
|
|
||||||
|
|
||||||
public class CreateSettingEndpoint(SettingsRepository settingsRepository) : Endpoint<CreateSettingDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/settings");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateSettingDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
// Encodage en base64
|
|
||||||
using MemoryStream memoryStream = new();
|
|
||||||
if (req.Logo != null) await req.Logo.CopyToAsync(memoryStream, ct);
|
|
||||||
byte[] logoBytes = memoryStream.ToArray();
|
|
||||||
|
|
||||||
if (req.ElectronicSignature != null) await req.ElectronicSignature.CopyToAsync(memoryStream, ct);
|
|
||||||
byte[] signatureBytes = memoryStream.ToArray();
|
|
||||||
|
|
||||||
Setting setting = new()
|
|
||||||
{
|
|
||||||
ElectronicSignature = Convert.ToBase64String(signatureBytes),
|
|
||||||
Logo = Convert.ToBase64String(logoBytes)
|
|
||||||
};
|
|
||||||
|
|
||||||
await settingsRepository.AddAsync(setting, ct);
|
|
||||||
await Send.NoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using PyroFetes.Models;
|
|
||||||
using PyroFetes.Repositories;
|
|
||||||
using PyroFetes.Specifications.Settings;
|
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.Settings;
|
|
||||||
|
|
||||||
public class DeleteSettingRequest
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DeleteSettingEndpoint(SettingsRepository settingsRepository) : Endpoint<DeleteSettingRequest>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Delete("/settings/{@Id}", x => new { x.Id });
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteSettingRequest req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Setting? setting = await settingsRepository.SingleOrDefaultAsync(new GetSettingByIdSpec(req.Id), ct);
|
|
||||||
|
|
||||||
if (setting is null)
|
|
||||||
{
|
|
||||||
await Send.NotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await settingsRepository.DeleteAsync(setting, ct);
|
|
||||||
await Send.NoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,28 +2,21 @@
|
|||||||
using PyroFetes.DTO.SettingDTO.Response;
|
using PyroFetes.DTO.SettingDTO.Response;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
using PyroFetes.Specifications.Settings;
|
using PyroFetes.Services;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.Settings;
|
namespace PyroFetes.Endpoints.Settings;
|
||||||
|
|
||||||
public class GetSettingRequest
|
public class GetSettingEndpoint(SettingsRepository settingsRepository, StorageService storageService) : EndpointWithoutRequest<GetSettingDto>
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GetSettingEndpoint(
|
|
||||||
SettingsRepository settingsRepository,
|
|
||||||
AutoMapper.IMapper mapper) : Endpoint<GetSettingRequest, GetSettingDto>
|
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/settings/{@Id}", x => new { x.Id });
|
Get("/settings/");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetSettingRequest req, CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
Setting? setting = await settingsRepository.SingleOrDefaultAsync(new GetSettingByIdSpec(req.Id), ct);
|
Setting? setting = await settingsRepository.FirstOrDefaultAsync(ct);
|
||||||
|
|
||||||
if (setting is null)
|
if (setting is null)
|
||||||
{
|
{
|
||||||
@@ -31,6 +24,13 @@ public class GetSettingEndpoint(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Send.OkAsync(mapper.Map<GetSettingDto>(setting), ct);
|
GetSettingDto settingDto = new()
|
||||||
|
{
|
||||||
|
Id = setting.Id,
|
||||||
|
ElectronicSignature = storageService.GetUrl(setting.ElectronicSignature!),
|
||||||
|
Logo = storageService.GetUrl(setting.Logo!)
|
||||||
|
};
|
||||||
|
|
||||||
|
await Send.OkAsync(settingDto, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,21 +2,23 @@
|
|||||||
using PyroFetes.DTO.SettingDTO.Request;
|
using PyroFetes.DTO.SettingDTO.Request;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
using PyroFetes.Specifications.Settings;
|
using PyroFetes.Services;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.Settings;
|
namespace PyroFetes.Endpoints.Settings;
|
||||||
|
|
||||||
public class PatchSettingElectronicSignatureEndpoint(SettingsRepository settingsRepository) : Endpoint<PatchSettingElectronicSignatureDto>
|
public class PatchSettingElectronicSignatureEndpoint(SettingsRepository settingsRepository, StorageService storageService) : Endpoint<PatchSettingElectronicSignatureDto>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/settings/{@Id}/ElectronicSignature", x => new { x.Id });
|
Patch("/settings/electronicSignature");
|
||||||
AllowAnonymous();
|
AllowFormData();
|
||||||
|
Roles("Admin");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchSettingElectronicSignatureDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchSettingElectronicSignatureDto req, CancellationToken ct)
|
||||||
{
|
{
|
||||||
Setting? setting = await settingsRepository.SingleOrDefaultAsync(new GetSettingByIdSpec(req.Id), ct);
|
Setting? setting = await settingsRepository.FirstOrDefaultAsync(ct);
|
||||||
|
|
||||||
if (setting is null)
|
if (setting is null)
|
||||||
{
|
{
|
||||||
@@ -24,12 +26,8 @@ public class PatchSettingElectronicSignatureEndpoint(SettingsRepository settings
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encodage en base64
|
string key = await storageService.UploadFile(req.ElectronicSignature!, "electronicSignature", ct);
|
||||||
using MemoryStream memoryStream = new();
|
setting.ElectronicSignature = key;
|
||||||
if (req.ElectronicSignature != null) await req.ElectronicSignature.CopyToAsync(memoryStream, ct);
|
|
||||||
byte[] signatureBytes = memoryStream.ToArray();
|
|
||||||
|
|
||||||
setting.ElectronicSignature = Convert.ToBase64String(signatureBytes);
|
|
||||||
|
|
||||||
await settingsRepository.SaveChangesAsync(ct);
|
await settingsRepository.SaveChangesAsync(ct);
|
||||||
await Send.NoContentAsync(ct);
|
await Send.NoContentAsync(ct);
|
||||||
|
|||||||
@@ -2,21 +2,22 @@
|
|||||||
using PyroFetes.DTO.SettingDTO.Request;
|
using PyroFetes.DTO.SettingDTO.Request;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
using PyroFetes.Specifications.Settings;
|
using PyroFetes.Services;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.Settings;
|
namespace PyroFetes.Endpoints.Settings;
|
||||||
|
|
||||||
public class PatchSettingLogoEndpoint(SettingsRepository settingsRepository) : Endpoint<PatchSettingLogoDto>
|
public class PatchSettingLogoEndpoint(SettingsRepository settingsRepository, StorageService storageService) : Endpoint<PatchSettingLogoDto>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/settings/{@Id}/logo", x => new { x.Id });
|
Patch("/settings/logo");
|
||||||
AllowAnonymous();
|
AllowFormData();
|
||||||
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchSettingLogoDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchSettingLogoDto req, CancellationToken ct)
|
||||||
{
|
{
|
||||||
Setting? setting = await settingsRepository.SingleOrDefaultAsync(new GetSettingByIdSpec(req.Id), ct);
|
Setting? setting = await settingsRepository.FirstOrDefaultAsync(ct);
|
||||||
|
|
||||||
if (setting is null)
|
if (setting is null)
|
||||||
{
|
{
|
||||||
@@ -24,12 +25,9 @@ public class PatchSettingLogoEndpoint(SettingsRepository settingsRepository) : E
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encodage en base64
|
string key = await storageService.UploadFile(req.Logo!, "logo", ct);
|
||||||
using MemoryStream memoryStream = new();
|
|
||||||
if (req.Logo != null) await req.Logo.CopyToAsync(memoryStream, ct);
|
|
||||||
byte[] logoBytes = memoryStream.ToArray();
|
|
||||||
|
|
||||||
setting.Logo = Convert.ToBase64String(logoBytes);
|
setting.Logo = key;
|
||||||
|
|
||||||
await settingsRepository.SaveChangesAsync(ct);
|
await settingsRepository.SaveChangesAsync(ct);
|
||||||
await Send.NoContentAsync(ct);
|
await Send.NoContentAsync(ct);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class AddProductToSupplierEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/suppliers/{@SupplierId}/{@ProductId}/", x => new { x.SupplierId, x.ProductId });
|
Post("/suppliers/{@SupplierId}/{@ProductId}/", x => new { x.SupplierId, x.ProductId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreatePriceDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreatePriceDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class CreateSupplierEndpoint(SuppliersRepository suppliersRepository, Aut
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/suppliers");
|
Post("/suppliers");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateSupplierDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreateSupplierDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class DeleteProductToSupplierEndpoint(PricesRepository pricesRepository)
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/suppliers/{@SupplierId}/{@Product}", x => new { x.SupplierId, x.ProductId });
|
Delete("/suppliers/{@SupplierId}/{@Product}", x => new { x.SupplierId, x.ProductId });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeletePriceRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeletePriceRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class DeleteSupplierEndpoint(SuppliersRepository suppliersRepository) : E
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/suppliers/{@Id}", x => new { x.Id });
|
Delete("/suppliers/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteSupplierRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeleteSupplierRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class GetAllSuppliersEndpoint(SuppliersRepository suppliersRepository) :
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/suppliers");
|
Get("/suppliers");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class GetSupplierEndpoint(SuppliersRepository suppliersRepository, AutoMa
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/suppliers/{@Id}", x => new { x.Id });
|
Get("/suppliers/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetSupplierRequest req, CancellationToken ct)
|
public override async Task HandleAsync(GetSupplierRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class PatchPriceEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/prices/{@ProductId}/{@SupplierId}/SellingPrice", x => new { x.ProductId, x.SupplierId });
|
Patch("/prices/{@ProductId}/{@SupplierId}/SellingPrice", x => new { x.ProductId, x.SupplierId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchPriceSellingPriceDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchPriceSellingPriceDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ public class PatchSupplierDeliveryDelayEndpoint(SuppliersRepository suppliersRep
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/suppliers/{@Id}/deliveryDelay", x => new { x.Id });
|
Patch("/suppliers/{@Id}/deliveryDelay", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchSupplierDeliveryDelayDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchSupplierDeliveryDelayDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class UpdateSupplierEndpoint(SuppliersRepository suppliersRepository, Aut
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Put("/suppliers/{@Id}", x => new { x.Id });
|
Put("/suppliers/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateSupplierDto req, CancellationToken ct)
|
public override async Task HandleAsync(UpdateSupplierDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class ConnectUserEndpoint(UsersRepository usersRepository) : Endpoint<Con
|
|||||||
{
|
{
|
||||||
string jwtToken = JwtBearer.CreateToken(o =>
|
string jwtToken = JwtBearer.CreateToken(o =>
|
||||||
{
|
{
|
||||||
o.SigningKey = "ThisIsASuperSecretJwtKeyThatIsAtLeast32CharsLong";
|
o.SigningKey = "v9!Qx7#Lk2@pZ8$wR6!tN5%uF3&cD9^mH1*eY4";
|
||||||
o.ExpireAt = DateTime.UtcNow.AddMinutes(15);
|
o.ExpireAt = DateTime.UtcNow.AddMinutes(15);
|
||||||
if (user.Fonction is not null) o.User.Roles.Add(user.Fonction);
|
if (user.Fonction is not null) o.User.Roles.Add(user.Fonction);
|
||||||
o.User.Claims.Add(("Name", user.Name)!);
|
o.User.Claims.Add(("Name", user.Name)!);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class CreateUserEndpoint(UsersRepository usersRepository) : Endpoint<Crea
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Post("/users");
|
Post("/users");
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateUserDto req, CancellationToken ct)
|
public override async Task HandleAsync(CreateUserDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class DeleteUserEndpoint(UsersRepository usersRepository) : Endpoint<Dele
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Delete("/users/{@Id}", x => new { x.Id });
|
Delete("/users/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteUserRequest req, CancellationToken ct)
|
public override async Task HandleAsync(DeleteUserRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class GetAllUsersEndpoint(UsersRepository usersRepository) : EndpointWith
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/users");
|
Get("/users");
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
|||||||
@@ -6,22 +6,18 @@ using PyroFetes.Specifications.Users;
|
|||||||
|
|
||||||
namespace PyroFetes.Endpoints.Users;
|
namespace PyroFetes.Endpoints.Users;
|
||||||
|
|
||||||
public class GetUserRequest
|
public class GetUserEndpoint(UsersRepository usersRepository, AutoMapper.IMapper mapper) : EndpointWithoutRequest<GetUserDto>
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GetUserEndpoint(UsersRepository usersRepository, AutoMapper.IMapper mapper) : Endpoint<GetUserRequest, GetUserDto>
|
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/users/{@Id}", x => new { x.Id });
|
Get("/user/");
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetUserRequest req, CancellationToken ct)
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(req.Id), ct);
|
int userId = int.Parse(User.FindFirst("Id")!.Value);
|
||||||
|
User? user = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(userId), ct);
|
||||||
|
|
||||||
if (user is null)
|
if (user is null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class PatchUserPasswordEndpoint(UsersRepository usersRepository, AutoMapp
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/users/{@Id}/password", x => new { x.Id });
|
Patch("/users/{@Id}/password", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchUserPasswordDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchUserPasswordDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class UpdateUserEndpoint(UsersRepository usersRepository) : Endpoint<Upda
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Put("/users/{@Id}", x => new { x.Id });
|
Put("/users/{@Id}", x => new { x.Id });
|
||||||
AllowAnonymous();
|
Roles("Admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateUserDto req, CancellationToken ct)
|
public override async Task HandleAsync(UpdateUserDto req, CancellationToken ct)
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using PyroFetes.DTO.WareHouse.Response;
|
||||||
|
using PyroFetes.Repositories;
|
||||||
|
|
||||||
|
namespace PyroFetes.Endpoints.WareHouse;
|
||||||
|
|
||||||
|
public class GetAllWarehouseEndpoint(WareHouseRepository wareHouseRepository, AutoMapper.IMapper mapper) : EndpointWithoutRequest<List<GetWareHouseDto>>
|
||||||
|
{
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Get("/wareHouses/");
|
||||||
|
Roles("Admin","Employe");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
{
|
||||||
|
await Send.OkAsync(await wareHouseRepository.ProjectToListAsync<GetWareHouseDto>(ct), ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ public class GetTotalQuantityEndpoint(
|
|||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Get("/wareHouseProducts/{@ProductId}", x => new { x.ProductId });
|
Get("/wareHouseProducts/{@ProductId}", x => new { x.ProductId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(GetTotalQuantityRequest req, CancellationToken ct)
|
public override async Task HandleAsync(GetTotalQuantityRequest req, CancellationToken ct)
|
||||||
|
|||||||
@@ -3,30 +3,36 @@ using PyroFetes.DTO.WareHouseProduct.Request;
|
|||||||
using PyroFetes.DTO.WareHouseProduct.Response;
|
using PyroFetes.DTO.WareHouseProduct.Response;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Specifications.WareHouse;
|
||||||
using PyroFetes.Specifications.WarehouseProducts;
|
using PyroFetes.Specifications.WarehouseProducts;
|
||||||
|
|
||||||
namespace PyroFetes.Endpoints.WareHouseProducts;
|
namespace PyroFetes.Endpoints.WareHouseProducts;
|
||||||
|
|
||||||
public class PatchWareHouseProductQuantityEndpoint(WarehouseProductsRepository warehouseProductsRepository) : Endpoint<PatchWareHouseProductQuantityDto, GetWareHouseProductDto>
|
public class PatchWareHouseProductQuantityEndpoint(WarehouseProductsRepository warehouseProductsRepository, WareHouseRepository wareHouseRepository , AutoMapper.IMapper mapper) : Endpoint<PatchWareHouseProductQuantityDto, GetWareHouseProductDto>
|
||||||
{
|
{
|
||||||
public override void Configure()
|
public override void Configure()
|
||||||
{
|
{
|
||||||
Patch("/wareHouseProducts/{@ProductId}/{@WareHouseId}/quantity", x => new { x.ProductId, x.WareHouseId });
|
Patch("/wareHouseProducts/{@ProductId}/{@WareHouseId}/quantity", x => new { x.ProductId, x.WareHouseId });
|
||||||
AllowAnonymous();
|
Roles("Admin","Employe");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task HandleAsync(PatchWareHouseProductQuantityDto req, CancellationToken ct)
|
public override async Task HandleAsync(PatchWareHouseProductQuantityDto req, CancellationToken ct)
|
||||||
{
|
{
|
||||||
WarehouseProduct? wareHouseProduct = await warehouseProductsRepository.FirstOrDefaultAsync(new GetWarehouseProductByProductIdSpec(req.ProductId, req.WareHouseId), ct);
|
WarehouseProduct? wareHouseProduct = await warehouseProductsRepository.FirstOrDefaultAsync(new GetWarehouseProductByProductIdSpec(req.ProductId, req.WareHouseId), ct);
|
||||||
|
Warehouse? warehouse = await wareHouseRepository.SingleOrDefaultAsync(new GetWareHouseByIdSpec(req.WareHouseId), ct);
|
||||||
|
|
||||||
if (wareHouseProduct is null)
|
if (warehouse is null)
|
||||||
{
|
{
|
||||||
await Send.NotFoundAsync(ct);
|
await Send.NotFoundAsync(ct);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wareHouseProduct.Quantity = req.Quantity;
|
if (wareHouseProduct is null) await warehouseProductsRepository.AddAsync(mapper.Map<WarehouseProduct>(req), ct);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wareHouseProduct.Quantity += req.Quantity;
|
||||||
await warehouseProductsRepository.SaveChangesAsync(ct);
|
await warehouseProductsRepository.SaveChangesAsync(ct);
|
||||||
|
}
|
||||||
|
|
||||||
await Send.NoContentAsync(ct);
|
await Send.NoContentAsync(ct);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public class DtoToEntityMappings : Profile
|
|||||||
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
||||||
|
|
||||||
CreateMap<CreatePurchaseProductDto, PurchaseProduct>();
|
CreateMap<CreatePurchaseProductDto, PurchaseProduct>();
|
||||||
|
CreateMap<CreatePurchaseOrderProductDto, PurchaseProduct>();
|
||||||
CreateMap<PatchPurchaseProductQuantityDto, PurchaseProduct>()
|
CreateMap<PatchPurchaseProductQuantityDto, PurchaseProduct>()
|
||||||
.ForMember(dest => dest.ProductId, opt => opt.Ignore())
|
.ForMember(dest => dest.ProductId, opt => opt.Ignore())
|
||||||
.ForMember(dest => dest.PurchaseOrderId, opt => opt.Ignore());
|
.ForMember(dest => dest.PurchaseOrderId, opt => opt.Ignore());
|
||||||
@@ -52,7 +53,10 @@ public class DtoToEntityMappings : Profile
|
|||||||
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
||||||
CreateMap<PatchQuotationMessageDto, Quotation>()
|
CreateMap<PatchQuotationMessageDto, Quotation>()
|
||||||
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
||||||
CreateMap<CreateProductQuotationDto, Quotation>();
|
CreateMap<CreateQuotationDto, Quotation>();
|
||||||
|
CreateMap<CreateProductQuotationDto, QuotationProduct>();
|
||||||
|
CreateMap<UpdateQuotationDto, Quotation>()
|
||||||
|
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
||||||
|
|
||||||
CreateMap<AddQuotationProductDto, QuotationProduct>();
|
CreateMap<AddQuotationProductDto, QuotationProduct>();
|
||||||
CreateMap<PatchQuotationProductQuantityDto, QuotationProduct>()
|
CreateMap<PatchQuotationProductQuantityDto, QuotationProduct>()
|
||||||
@@ -77,8 +81,6 @@ public class DtoToEntityMappings : Profile
|
|||||||
CreateMap<PatchUserPasswordDto, User>()
|
CreateMap<PatchUserPasswordDto, User>()
|
||||||
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
.ForMember(dest => dest.Id, opt => opt.Ignore());
|
||||||
|
|
||||||
CreateMap<PatchWareHouseProductQuantityDto, WarehouseProduct>()
|
CreateMap<PatchWareHouseProductQuantityDto, WarehouseProduct>();
|
||||||
.ForMember(dest => dest.ProductId, opt => opt.Ignore())
|
|
||||||
.ForMember(dest => dest.WarehouseId, opt => opt.Ignore());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
using PyroFetes.DTO.Customer.Response;
|
||||||
using PyroFetes.DTO.Deliverer.Response;
|
using PyroFetes.DTO.Deliverer.Response;
|
||||||
using PyroFetes.DTO.DeliveryNote.Response;
|
using PyroFetes.DTO.DeliveryNote.Response;
|
||||||
using PyroFetes.DTO.Price.Response;
|
using PyroFetes.DTO.Price.Response;
|
||||||
@@ -11,6 +12,7 @@ using PyroFetes.DTO.QuotationProduct.Response;
|
|||||||
using PyroFetes.DTO.SettingDTO.Response;
|
using PyroFetes.DTO.SettingDTO.Response;
|
||||||
using PyroFetes.DTO.Supplier.Response;
|
using PyroFetes.DTO.Supplier.Response;
|
||||||
using PyroFetes.DTO.User.Response;
|
using PyroFetes.DTO.User.Response;
|
||||||
|
using PyroFetes.DTO.WareHouse.Response;
|
||||||
using PyroFetes.DTO.WareHouseProduct.Response;
|
using PyroFetes.DTO.WareHouseProduct.Response;
|
||||||
using PyroFetes.Models;
|
using PyroFetes.Models;
|
||||||
|
|
||||||
@@ -35,19 +37,30 @@ public class EntityToDtoMappings : Profile
|
|||||||
CreateMap<ProductDelivery, GetProductDeliveryDto>();
|
CreateMap<ProductDelivery, GetProductDeliveryDto>();
|
||||||
|
|
||||||
CreateMap<PurchaseOrder, GetPurchaseOrderDto>()
|
CreateMap<PurchaseOrder, GetPurchaseOrderDto>()
|
||||||
|
.ForMember(dest => dest.SupplierName, opt => opt.MapFrom(src => src.Supplier!.Name))
|
||||||
.ForMember(dest => dest.Products, opt => opt.MapFrom(src => src.PurchaseProducts));
|
.ForMember(dest => dest.Products, opt => opt.MapFrom(src => src.PurchaseProducts));
|
||||||
|
|
||||||
CreateMap<PurchaseProduct, GetPurchaseProductDto>();
|
CreateMap<PurchaseProduct, GetPurchaseProductDto>()
|
||||||
|
.ForMember(dest => dest.ProductPrice,
|
||||||
|
opt => opt.MapFrom(src =>
|
||||||
|
src.Product!.Prices.Where(x => x.SupplierId == src.PurchaseOrder!.SupplierId && x.ProductId == src.ProductId).Select(x => x.SellingPrice).FirstOrDefault()));
|
||||||
|
|
||||||
CreateMap<Quotation, GetQuotationDto>()
|
CreateMap<Quotation, GetQuotationDto>()
|
||||||
.ForMember(dest => dest.Products, opt => opt.MapFrom(src => src.QuotationProducts));
|
.ForMember(dest => dest.Products, opt => opt.MapFrom(src => src.QuotationProducts));
|
||||||
|
|
||||||
CreateMap<QuotationProduct, GetQuotationProductDto>();
|
CreateMap<QuotationProduct, GetQuotationProductDto>()
|
||||||
|
.ForMember(dest => dest.ProductPrice,
|
||||||
|
opt => opt.MapFrom(src =>
|
||||||
|
src.Product!.Prices.Where(x => x.SupplierId == src.Quotation!.SupplierId && x.ProductId == src.ProductId).Select(x => x.SellingPrice).FirstOrDefault()));
|
||||||
|
|
||||||
CreateMap<Setting, GetSettingDto>();
|
CreateMap<Setting, GetSettingDto>();
|
||||||
|
|
||||||
CreateMap<User, GetUserDto>();
|
CreateMap<User, GetUserDto>();
|
||||||
|
|
||||||
CreateMap<WarehouseProduct, GetWareHouseProductDto>();
|
CreateMap<WarehouseProduct, GetWareHouseProductDto>();
|
||||||
|
|
||||||
|
CreateMap<Warehouse, GetWareHouseDto>();
|
||||||
|
|
||||||
|
CreateMap<Customer, GetCustomerDto>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2000
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PyroFetes.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddedMissingFieldForSupplierInDocuments : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "SupplierId",
|
||||||
|
table: "Quotations",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Quotations_SupplierId",
|
||||||
|
table: "Quotations",
|
||||||
|
column: "SupplierId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Quotations_Suppliers_SupplierId",
|
||||||
|
table: "Quotations",
|
||||||
|
column: "SupplierId",
|
||||||
|
principalTable: "Suppliers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Quotations_Suppliers_SupplierId",
|
||||||
|
table: "Quotations");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Quotations_SupplierId",
|
||||||
|
table: "Quotations");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "SupplierId",
|
||||||
|
table: "Quotations");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+2015
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PyroFetes.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddedMissingFieldForSupplierInDeliveryNote : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "SupplierId",
|
||||||
|
table: "DeliveryNotes",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_DeliveryNotes_SupplierId",
|
||||||
|
table: "DeliveryNotes",
|
||||||
|
column: "SupplierId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_DeliveryNotes_Suppliers_SupplierId",
|
||||||
|
table: "DeliveryNotes",
|
||||||
|
column: "SupplierId",
|
||||||
|
principalTable: "Suppliers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_DeliveryNotes_Suppliers_SupplierId",
|
||||||
|
table: "DeliveryNotes");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_DeliveryNotes_SupplierId",
|
||||||
|
table: "DeliveryNotes");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "SupplierId",
|
||||||
|
table: "DeliveryNotes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -329,6 +329,9 @@ namespace PyroFetes.Migrations
|
|||||||
b.Property<DateOnly?>("RealDeliveryDate")
|
b.Property<DateOnly?>("RealDeliveryDate")
|
||||||
.HasColumnType("date");
|
.HasColumnType("date");
|
||||||
|
|
||||||
|
b.Property<int>("SupplierId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("TrackingNumber")
|
b.Property<string>("TrackingNumber")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(100)
|
.HasMaxLength(100)
|
||||||
@@ -338,6 +341,8 @@ namespace PyroFetes.Migrations
|
|||||||
|
|
||||||
b.HasIndex("DelivererId");
|
b.HasIndex("DelivererId");
|
||||||
|
|
||||||
|
b.HasIndex("SupplierId");
|
||||||
|
|
||||||
b.ToTable("DeliveryNotes");
|
b.ToTable("DeliveryNotes");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -744,10 +749,15 @@ namespace PyroFetes.Migrations
|
|||||||
.HasMaxLength(200)
|
.HasMaxLength(200)
|
||||||
.HasColumnType("nvarchar(200)");
|
.HasColumnType("nvarchar(200)");
|
||||||
|
|
||||||
|
b.Property<int>("SupplierId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("CustomerId");
|
b.HasIndex("CustomerId");
|
||||||
|
|
||||||
|
b.HasIndex("SupplierId");
|
||||||
|
|
||||||
b.ToTable("Quotations");
|
b.ToTable("Quotations");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1348,7 +1358,15 @@ namespace PyroFetes.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("PyroFetes.Models.Supplier", "Supplier")
|
||||||
|
.WithMany("DeliveryNotes")
|
||||||
|
.HasForeignKey("SupplierId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("Deliverer");
|
b.Navigation("Deliverer");
|
||||||
|
|
||||||
|
b.Navigation("Supplier");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("PyroFetes.Models.ExperienceLevel", b =>
|
modelBuilder.Entity("PyroFetes.Models.ExperienceLevel", b =>
|
||||||
@@ -1553,7 +1571,7 @@ namespace PyroFetes.Migrations
|
|||||||
modelBuilder.Entity("PyroFetes.Models.PurchaseOrder", b =>
|
modelBuilder.Entity("PyroFetes.Models.PurchaseOrder", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("PyroFetes.Models.Supplier", "Supplier")
|
b.HasOne("PyroFetes.Models.Supplier", "Supplier")
|
||||||
.WithMany()
|
.WithMany("PurchaseOrders")
|
||||||
.HasForeignKey("SupplierId")
|
.HasForeignKey("SupplierId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
@@ -1588,7 +1606,15 @@ namespace PyroFetes.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("PyroFetes.Models.Supplier", "Supplier")
|
||||||
|
.WithMany("Quotations")
|
||||||
|
.HasForeignKey("SupplierId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("Customer");
|
b.Navigation("Customer");
|
||||||
|
|
||||||
|
b.Navigation("Supplier");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("PyroFetes.Models.QuotationProduct", b =>
|
modelBuilder.Entity("PyroFetes.Models.QuotationProduct", b =>
|
||||||
@@ -1956,7 +1982,13 @@ namespace PyroFetes.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("PyroFetes.Models.Supplier", b =>
|
modelBuilder.Entity("PyroFetes.Models.Supplier", b =>
|
||||||
{
|
{
|
||||||
|
b.Navigation("DeliveryNotes");
|
||||||
|
|
||||||
b.Navigation("Prices");
|
b.Navigation("Prices");
|
||||||
|
|
||||||
|
b.Navigation("PurchaseOrders");
|
||||||
|
|
||||||
|
b.Navigation("Quotations");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("PyroFetes.Models.Truck", b =>
|
modelBuilder.Entity("PyroFetes.Models.Truck", b =>
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ public class DeliveryNote
|
|||||||
[Key] public int Id { get; set; }
|
[Key] public int Id { get; set; }
|
||||||
[Required, MaxLength(100)] public string? TrackingNumber { get; set; }
|
[Required, MaxLength(100)] public string? TrackingNumber { get; set; }
|
||||||
public int DelivererId { get; set; }
|
public int DelivererId { get; set; }
|
||||||
|
public int SupplierId { get; set; }
|
||||||
[Required] public DateOnly EstimateDeliveryDate { get; set; }
|
[Required] public DateOnly EstimateDeliveryDate { get; set; }
|
||||||
[Required] public DateOnly ExpeditionDate { get; set; }
|
[Required] public DateOnly ExpeditionDate { get; set; }
|
||||||
public DateOnly? RealDeliveryDate { get; set; }
|
public DateOnly? RealDeliveryDate { get; set; }
|
||||||
|
|
||||||
public Deliverer? Deliverer { get; set; }
|
public Deliverer? Deliverer { get; set; }
|
||||||
|
public Supplier? Supplier { get; set; }
|
||||||
public List<ProductDelivery>? ProductDeliveries { get; set; }
|
public List<ProductDelivery>? ProductDeliveries { get; set; }
|
||||||
}
|
}
|
||||||
@@ -11,5 +11,8 @@ public class Quotation
|
|||||||
[Required] public int CustomerId { get; set; }
|
[Required] public int CustomerId { get; set; }
|
||||||
public Customer? Customer { get; set; }
|
public Customer? Customer { get; set; }
|
||||||
|
|
||||||
|
[Required] public int SupplierId { get; set; }
|
||||||
|
public Supplier? Supplier { get; set; }
|
||||||
|
|
||||||
public List<QuotationProduct>? QuotationProducts { get; set; }
|
public List<QuotationProduct>? QuotationProducts { get; set; }
|
||||||
}
|
}
|
||||||
@@ -14,4 +14,7 @@ public class Supplier
|
|||||||
[Required] public int DeliveryDelay { get; set; }
|
[Required] public int DeliveryDelay { get; set; }
|
||||||
|
|
||||||
public List<Price>? Prices { get; set; }
|
public List<Price>? Prices { get; set; }
|
||||||
|
public List<Quotation>? Quotations { get; set; }
|
||||||
|
public List<DeliveryNote>? DeliveryNotes { get; set; }
|
||||||
|
public List<PurchaseOrder>? PurchaseOrders { get; set; }
|
||||||
}
|
}
|
||||||
+35
-4
@@ -1,3 +1,5 @@
|
|||||||
|
using Amazon.S3;
|
||||||
|
using Amazon.S3.Model;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using AutoMapper.EquivalencyExpression;
|
using AutoMapper.EquivalencyExpression;
|
||||||
using PyroFetes;
|
using PyroFetes;
|
||||||
@@ -7,6 +9,7 @@ using FastEndpoints.Security;
|
|||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using PyroFetes.MappingProfiles;
|
using PyroFetes.MappingProfiles;
|
||||||
using PyroFetes.Repositories;
|
using PyroFetes.Repositories;
|
||||||
|
using PyroFetes.Services;
|
||||||
using PyroFetes.Services.Pdf;
|
using PyroFetes.Services.Pdf;
|
||||||
using QuestPDF.Infrastructure;
|
using QuestPDF.Infrastructure;
|
||||||
|
|
||||||
@@ -17,7 +20,7 @@ QuestPDF.Settings.License = LicenseType.Community;
|
|||||||
|
|
||||||
// On ajoute ici FastEndpoints, un framework REPR et Swagger aux services disponibles dans le projet
|
// On ajoute ici FastEndpoints, un framework REPR et Swagger aux services disponibles dans le projet
|
||||||
builder.Services
|
builder.Services
|
||||||
.AddAuthenticationJwtBearer(s => s.SigningKey = "ThisIsASuperSecretJwtKeyThatIsAtLeast32CharsLong")
|
.AddAuthenticationJwtBearer(s => s.SigningKey = "v9!Qx7#Lk2@pZ8$wR6!tN5%uF3&cD9^mH1*eY4")
|
||||||
.AddAuthorization()
|
.AddAuthorization()
|
||||||
.AddFastEndpoints()
|
.AddFastEndpoints()
|
||||||
.SwaggerDocument(options => { options.ShortSchemaNames = true; })
|
.SwaggerDocument(options => { options.ShortSchemaNames = true; })
|
||||||
@@ -49,11 +52,14 @@ builder.Services.AddScoped<SuppliersRepository>();
|
|||||||
builder.Services.AddScoped<SettingsRepository>();
|
builder.Services.AddScoped<SettingsRepository>();
|
||||||
builder.Services.AddScoped<UsersRepository>();
|
builder.Services.AddScoped<UsersRepository>();
|
||||||
builder.Services.AddScoped<WarehouseProductsRepository>();
|
builder.Services.AddScoped<WarehouseProductsRepository>();
|
||||||
|
builder.Services.AddScoped<WareHouseRepository>();
|
||||||
|
builder.Services.AddScoped<CustomersRepository>();
|
||||||
|
|
||||||
// Ajout des services
|
// Ajout des services
|
||||||
builder.Services.AddScoped<IDeliveryNotePdfService, DeliveryNotePdfService>();
|
builder.Services.AddScoped<DeliveryNotePdfService>();
|
||||||
builder.Services.AddScoped<IPurchaseOrderPdfService, PurchaseOrderPdfService>();
|
builder.Services.AddScoped<PurchaseOrderPdfService>();
|
||||||
builder.Services.AddScoped<IQuotationPdfService, QuotationPdfService>();
|
builder.Services.AddScoped<QuotationPdfService>();
|
||||||
|
builder.Services.AddScoped<StorageService>();
|
||||||
|
|
||||||
MapperConfiguration mappingConfig = new(mc =>
|
MapperConfiguration mappingConfig = new(mc =>
|
||||||
{
|
{
|
||||||
@@ -66,6 +72,31 @@ MapperConfiguration mappingConfig = new(mc =>
|
|||||||
AutoMapper.IMapper mapper = mappingConfig.CreateMapper();
|
AutoMapper.IMapper mapper = mappingConfig.CreateMapper();
|
||||||
builder.Services.AddSingleton(mapper);
|
builder.Services.AddSingleton(mapper);
|
||||||
|
|
||||||
|
// RUSTFS
|
||||||
|
IConfigurationSection config = builder.Configuration.GetSection("RustFS");
|
||||||
|
|
||||||
|
AmazonS3Client s3Client = new(
|
||||||
|
config["AccessKey"],
|
||||||
|
config["SecretKey"],
|
||||||
|
new AmazonS3Config
|
||||||
|
{
|
||||||
|
ServiceURL = config["ServiceUrl"],
|
||||||
|
ForcePathStyle = true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ListBucketsResponse? buckets = await s3Client.ListBucketsAsync();
|
||||||
|
bool exist = buckets?.Buckets?.Any(x => x.BucketName == config["BucketName"]) == true;
|
||||||
|
if (!exist)
|
||||||
|
{
|
||||||
|
await s3Client.PutBucketAsync(new PutBucketRequest
|
||||||
|
{
|
||||||
|
BucketName = config["BucketName"]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<IAmazonS3>(s3Client);
|
||||||
|
|
||||||
// On construit l'application en lui donnant vie
|
// On construit l'application en lui donnant vie
|
||||||
WebApplication app = builder.Build();
|
WebApplication app = builder.Build();
|
||||||
app.UseAuthentication()
|
app.UseAuthentication()
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" Version="9.3.1" />
|
<PackageReference Include="Ardalis.Specification.EntityFrameworkCore" Version="9.3.1" />
|
||||||
<PackageReference Include="AutoMapper" Version="15.0.1" />
|
<PackageReference Include="AutoMapper" Version="15.0.1" />
|
||||||
<PackageReference Include="AutoMapper.Collection" Version="11.0.0" />
|
<PackageReference Include="AutoMapper.Collection" Version="11.0.0" />
|
||||||
|
<PackageReference Include="AWSSDK.S3" Version="4.0.24" />
|
||||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||||
<PackageReference Include="FastEndpoints" Version="7.0.1" />
|
<PackageReference Include="FastEndpoints" Version="7.0.1" />
|
||||||
<PackageReference Include="FastEndpoints.Security" Version="7.0.1" />
|
<PackageReference Include="FastEndpoints.Security" Version="7.0.1" />
|
||||||
@@ -33,7 +34,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Migrations\" />
|
<Folder Include="Migrations\" />
|
||||||
<Folder Include="wwwroot\" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class PyroFetesDbContext : DbContext
|
|||||||
{
|
{
|
||||||
string connectionString =
|
string connectionString =
|
||||||
"Server=romaric-thibault.fr;" +
|
"Server=romaric-thibault.fr;" +
|
||||||
"Database=PyroFetes-Sujet2;" +
|
"Database=PyroFetes-Sujet2-Cristiano;" +
|
||||||
"User Id=pyrofetes;" +
|
"User Id=pyrofetes;" +
|
||||||
"Password=Crablike8-Fringe-Swimmable;" +
|
"Password=Crablike8-Fringe-Swimmable;" +
|
||||||
"TrustServerCertificate=true;";
|
"TrustServerCertificate=true;";
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
using PyroFetes.Models;
|
||||||
|
|
||||||
|
namespace PyroFetes.Repositories;
|
||||||
|
|
||||||
|
public class CustomersRepository(PyroFetesDbContext pyrofetesContext, AutoMapper.IMapper mapper) : PyrofetesRepository<Customer>(pyrofetesContext, mapper);
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
using PyroFetes.Models;
|
||||||
|
|
||||||
|
namespace PyroFetes.Repositories;
|
||||||
|
|
||||||
|
public class WareHouseRepository(PyroFetesDbContext pyrofetesContext, AutoMapper.IMapper mapper) : PyrofetesRepository<Warehouse>(pyrofetesContext, mapper);
|
||||||
@@ -5,18 +5,15 @@ using QuestPDF.Infrastructure;
|
|||||||
|
|
||||||
namespace PyroFetes.Services.Pdf;
|
namespace PyroFetes.Services.Pdf;
|
||||||
|
|
||||||
public interface IDeliveryNotePdfService
|
public class DeliveryNotePdfService
|
||||||
{
|
{
|
||||||
byte[] Generate(DeliveryNote deliveryNote, List<ProductDelivery> lignes, Setting setting);
|
private static readonly HttpClient HttpClient = new();
|
||||||
}
|
|
||||||
|
|
||||||
public class DeliveryNotePdfService : IDeliveryNotePdfService
|
public async Task<byte[]> Generate(DeliveryNote deliveryNote, Setting setting, StorageService storageService)
|
||||||
{
|
{
|
||||||
public byte[] Generate(DeliveryNote deliveryNote, List<ProductDelivery> lignes, Setting setting)
|
byte[] logoBytes = await HttpClient.GetByteArrayAsync(storageService.GetUrl(setting.Logo!));
|
||||||
{
|
byte[] signatureBytes = await HttpClient.GetByteArrayAsync(storageService.GetUrl(setting.ElectronicSignature!));
|
||||||
byte[] logo = Convert.FromBase64String(setting.Logo!);
|
decimal total = 0;
|
||||||
byte[] signature = Convert.FromBase64String(setting.ElectronicSignature!);
|
|
||||||
int total = 0;
|
|
||||||
int totalQuantity = 0;
|
int totalQuantity = 0;
|
||||||
Document document = Document.Create(container =>
|
Document document = Document.Create(container =>
|
||||||
{
|
{
|
||||||
@@ -42,13 +39,13 @@ public class DeliveryNotePdfService : IDeliveryNotePdfService
|
|||||||
col.Item().Height(5);
|
col.Item().Height(5);
|
||||||
col.Item().AlignLeft().Text($"Estimée au {deliveryNote.EstimateDeliveryDate}");
|
col.Item().AlignLeft().Text($"Estimée au {deliveryNote.EstimateDeliveryDate}");
|
||||||
col.Item().Height(5);
|
col.Item().Height(5);
|
||||||
col.Item().AlignLeft().Text($"Reçu le {deliveryNote.RealDeliveryDate}");
|
col.Item().AlignLeft().Text(deliveryNote.RealDeliveryDate is null ? "Pas encore arrivée à destination" : $"Reçu le {deliveryNote.RealDeliveryDate}");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Logo + société à droite
|
// Logo + société à droite
|
||||||
row.ConstantItem(200).Column(col =>
|
row.ConstantItem(200).Column(col =>
|
||||||
{
|
{
|
||||||
col.Item().AlignRight().Height(70).Image(logo, ImageScaling.FitArea);
|
col.Item().AlignRight().Height(70).Image(logoBytes, ImageScaling.FitArea);
|
||||||
col.Item().Height(20);
|
col.Item().Height(20);
|
||||||
col.Item().AlignRight().Text("Pyro-Fêtes").SemiBold();
|
col.Item().AlignRight().Text("Pyro-Fêtes").SemiBold();
|
||||||
col.Item().Height(5);
|
col.Item().Height(5);
|
||||||
@@ -93,15 +90,19 @@ public class DeliveryNotePdfService : IDeliveryNotePdfService
|
|||||||
header.Cell().Element(CellHeader).AlignRight().Text("Total");
|
header.Cell().Element(CellHeader).AlignRight().Text("Total");
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (ProductDelivery l in lignes)
|
foreach (ProductDelivery l in deliveryNote.ProductDeliveries!)
|
||||||
{
|
{
|
||||||
|
decimal price = l.Product!.Prices!
|
||||||
|
.FirstOrDefault(x => x.SupplierId == l.DeliveryNote!.SupplierId && x.ProductId == l.ProductId)
|
||||||
|
?.SellingPrice ?? 0;
|
||||||
|
|
||||||
table.Cell().Element(CellBody).Text(l.Product?.Name);
|
table.Cell().Element(CellBody).Text(l.Product?.Name);
|
||||||
table.Cell().Element(CellBody).AlignRight().Text(l.Quantity.ToString());
|
table.Cell().Element(CellBody).AlignRight().Text(l.Quantity.ToString());
|
||||||
table.Cell().Element(CellBody).AlignRight().Text($"{l.Quantity:n2} €");
|
table.Cell().Element(CellBody).AlignRight().Text($"{price:n2} €");
|
||||||
table.Cell().Element(CellBody).AlignRight().Text($"{l.Quantity * l.Quantity:n2} €");
|
table.Cell().Element(CellBody).AlignRight().Text($"{l.Quantity * price:n2} €");
|
||||||
|
|
||||||
totalQuantity += l.Quantity;
|
totalQuantity += l.Quantity;
|
||||||
total += l.Quantity * l.Quantity;
|
total += l.Quantity * price;
|
||||||
}
|
}
|
||||||
|
|
||||||
IContainer CellHeader(IContainer c) =>
|
IContainer CellHeader(IContainer c) =>
|
||||||
@@ -114,14 +115,14 @@ public class DeliveryNotePdfService : IDeliveryNotePdfService
|
|||||||
col.Item().LineHorizontal(1);
|
col.Item().LineHorizontal(1);
|
||||||
col.Item().Height(30);
|
col.Item().Height(30);
|
||||||
|
|
||||||
col.Item().AlignRight().Text($"Total: {totalQuantity:n2} produits");
|
col.Item().AlignRight().Text($"Total: {totalQuantity} produits");
|
||||||
col.Item().AlignRight().Text($"Total HT: {total:n2} €");
|
col.Item().AlignRight().Text($"Total HT: {total:n2} €");
|
||||||
col.Item().AlignRight().Text("Taxe : 20 %");
|
col.Item().AlignRight().Text("Taxe : 20 %");
|
||||||
col.Item().AlignRight().Text($"Total TTC: {(total * 1.2):n2} €");
|
col.Item().AlignRight().Text($"Total TTC: {total * (decimal)1.2:n2} €");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Signature en bas à droite
|
// Signature en bas à droite
|
||||||
page.Footer().AlignRight().Column(col => { col.Item().AlignRight().Height(100).Image(signature, ImageScaling.FitArea); });
|
page.Footer().AlignRight().Column(col => { col.Item().AlignRight().Height(100).Image(signatureBytes, ImageScaling.FitArea); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,17 +5,14 @@ using QuestPDF.Infrastructure;
|
|||||||
|
|
||||||
namespace PyroFetes.Services.Pdf;
|
namespace PyroFetes.Services.Pdf;
|
||||||
|
|
||||||
public interface IPurchaseOrderPdfService
|
public class PurchaseOrderPdfService
|
||||||
{
|
{
|
||||||
byte[] Generate(PurchaseOrder purchaseOrder, List<PurchaseProduct> lignes, Setting setting);
|
private static readonly HttpClient HttpClient = new();
|
||||||
}
|
|
||||||
|
|
||||||
public class PurchaseOrderPdfService : IPurchaseOrderPdfService
|
public async Task<byte[]> Generate(PurchaseOrder purchaseOrder, Setting setting, StorageService storageService)
|
||||||
{
|
{
|
||||||
public byte[] Generate(PurchaseOrder purchaseOrder, List<PurchaseProduct> lignes, Setting setting)
|
byte[] logoBytes = await HttpClient.GetByteArrayAsync(storageService.GetUrl(setting.Logo!));
|
||||||
{
|
byte[] signatureBytes = await HttpClient.GetByteArrayAsync(storageService.GetUrl(setting.ElectronicSignature!));
|
||||||
byte[] logo = Convert.FromBase64String(setting.Logo!);
|
|
||||||
byte[] signature = Convert.FromBase64String(setting.ElectronicSignature!);
|
|
||||||
int totalQuantity = 0;
|
int totalQuantity = 0;
|
||||||
decimal total = 0;
|
decimal total = 0;
|
||||||
Document document = Document.Create(container =>
|
Document document = Document.Create(container =>
|
||||||
@@ -35,14 +32,17 @@ public class PurchaseOrderPdfService : IPurchaseOrderPdfService
|
|||||||
col.Item().Text("");
|
col.Item().Text("");
|
||||||
col.Item().Text("");
|
col.Item().Text("");
|
||||||
col.Item().Text("");
|
col.Item().Text("");
|
||||||
col.Item().Text("Fournisseur").SemiBold().FontSize(12);
|
col.Item().Text("Fournisseur :").SemiBold().FontSize(12);
|
||||||
col.Item().Text("Mettre fournisseur ici");
|
col.Item().Text($"{purchaseOrder.Supplier?.Name}");
|
||||||
|
col.Item().Text($"{purchaseOrder.Supplier?.Address}");
|
||||||
|
col.Item().Text($"{purchaseOrder.Supplier?.ZipCode} {purchaseOrder.Supplier?.City}");
|
||||||
|
col.Item().Text($"{purchaseOrder.Supplier?.DeliveryDelay} jours de délai moyen de livraison");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Logo + société à droite
|
// Logo + société à droite
|
||||||
row.ConstantItem(200).Column(col =>
|
row.ConstantItem(200).Column(col =>
|
||||||
{
|
{
|
||||||
col.Item().AlignRight().Height(70).Image(logo, ImageScaling.FitArea);
|
col.Item().AlignRight().Height(70).Image(logoBytes, ImageScaling.FitArea);
|
||||||
col.Item().Height(20);
|
col.Item().Height(20);
|
||||||
col.Item().AlignRight().Text("Pyro-Fêtes").SemiBold();
|
col.Item().AlignRight().Text("Pyro-Fêtes").SemiBold();
|
||||||
col.Item().Height(5);
|
col.Item().Height(5);
|
||||||
@@ -90,10 +90,10 @@ public class PurchaseOrderPdfService : IPurchaseOrderPdfService
|
|||||||
header.Cell().Element(CellHeader).AlignRight().Text("Total");
|
header.Cell().Element(CellHeader).AlignRight().Text("Total");
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (PurchaseProduct l in lignes)
|
foreach (PurchaseProduct l in purchaseOrder.PurchaseProducts!)
|
||||||
{
|
{
|
||||||
decimal price = l.Product!.Prices!
|
decimal price = l.Product!.Prices!
|
||||||
.FirstOrDefault(p => p.SupplierId == l.PurchaseOrder!.SupplierId)
|
.FirstOrDefault(x => x.SupplierId == l.PurchaseOrder!.SupplierId && x.ProductId == l.ProductId)
|
||||||
?.SellingPrice ?? 0;
|
?.SellingPrice ?? 0;
|
||||||
|
|
||||||
table.Cell().Element(CellBody).Text(l.Product?.Name);
|
table.Cell().Element(CellBody).Text(l.Product?.Name);
|
||||||
@@ -129,16 +129,16 @@ public class PurchaseOrderPdfService : IPurchaseOrderPdfService
|
|||||||
// Colonne droite : totaux
|
// Colonne droite : totaux
|
||||||
row.ConstantItem(180).Column(right =>
|
row.ConstantItem(180).Column(right =>
|
||||||
{
|
{
|
||||||
right.Item().AlignRight().Text($"Total: {totalQuantity:n2} produits");
|
right.Item().AlignRight().Text($"Total: {totalQuantity} produits");
|
||||||
right.Item().AlignRight().Text($"Total HT: {total:n2} €");
|
right.Item().AlignRight().Text($"Total HT: {total:n2} €");
|
||||||
right.Item().AlignRight().Text("Taxe: 20 %");
|
right.Item().AlignRight().Text("Taxe: 20 %");
|
||||||
right.Item().AlignRight().Text($"Total TTC: {(total * 1, 2):n2} €");
|
right.Item().AlignRight().Text($"Total TTC: {total * (decimal)1.2:n2} €");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Signature en bas à droite
|
// Signature en bas à droite
|
||||||
page.Footer().AlignRight().Column(col => { col.Item().AlignRight().Height(100).Image(signature, ImageScaling.FitArea); });
|
page.Footer().AlignRight().Column(col => { col.Item().AlignRight().Height(100).Image(signatureBytes, ImageScaling.FitArea); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,18 +5,15 @@ using QuestPDF.Infrastructure;
|
|||||||
|
|
||||||
namespace PyroFetes.Services.Pdf;
|
namespace PyroFetes.Services.Pdf;
|
||||||
|
|
||||||
public interface IQuotationPdfService
|
public class QuotationPdfService
|
||||||
{
|
{
|
||||||
byte[] Generate(Quotation quotation, List<QuotationProduct> lignes, Setting setting);
|
private static readonly HttpClient HttpClient = new();
|
||||||
}
|
|
||||||
|
|
||||||
public class QuotationPdfService : IQuotationPdfService
|
public async Task<byte[]> Generate(Quotation quotation, Setting setting, StorageService storageService)
|
||||||
{
|
{
|
||||||
public byte[] Generate(Quotation quotation, List<QuotationProduct> lignes, Setting setting)
|
byte[] logoBytes = await HttpClient.GetByteArrayAsync(storageService.GetUrl(setting.Logo!));
|
||||||
{
|
byte[] signatureBytes = await HttpClient.GetByteArrayAsync(storageService.GetUrl(setting.ElectronicSignature!));
|
||||||
byte[] logo = Convert.FromBase64String(setting.Logo!);
|
decimal total = 0;
|
||||||
byte[] signature = Convert.FromBase64String(setting.ElectronicSignature!);
|
|
||||||
int total = 0;
|
|
||||||
Document document = Document.Create(container =>
|
Document document = Document.Create(container =>
|
||||||
{
|
{
|
||||||
container.Page(page =>
|
container.Page(page =>
|
||||||
@@ -35,13 +32,14 @@ public class QuotationPdfService : IQuotationPdfService
|
|||||||
col.Item().Text("");
|
col.Item().Text("");
|
||||||
col.Item().Text("");
|
col.Item().Text("");
|
||||||
col.Item().Text("Client").SemiBold().FontSize(12);
|
col.Item().Text("Client").SemiBold().FontSize(12);
|
||||||
col.Item().Text($"{quotation.Customer}");
|
col.Item().Text($"{quotation.Customer?.Note}");
|
||||||
|
col.Item().Text($"{quotation.Customer?.CustomerType?.Label}");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Logo + société à droite
|
// Logo + société à droite
|
||||||
row.ConstantItem(200).Column(col =>
|
row.ConstantItem(200).Column(col =>
|
||||||
{
|
{
|
||||||
col.Item().AlignRight().Height(70).Image(logo, ImageScaling.FitArea);
|
col.Item().AlignRight().Height(70).Image(logoBytes, ImageScaling.FitArea);
|
||||||
col.Item().Height(20);
|
col.Item().Height(20);
|
||||||
col.Item().AlignRight().Text("Pyro-Fêtes").SemiBold();
|
col.Item().AlignRight().Text("Pyro-Fêtes").SemiBold();
|
||||||
col.Item().Height(5);
|
col.Item().Height(5);
|
||||||
@@ -89,21 +87,23 @@ public class QuotationPdfService : IQuotationPdfService
|
|||||||
header.Cell().Element(CellHeader).AlignRight().Text("Total");
|
header.Cell().Element(CellHeader).AlignRight().Text("Total");
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (QuotationProduct l in lignes)
|
foreach (QuotationProduct l in quotation.QuotationProducts!)
|
||||||
{
|
{
|
||||||
|
decimal price = l.Product!.Prices!
|
||||||
|
.FirstOrDefault(x => x.SupplierId == l.Quotation!.SupplierId && x.ProductId == l.ProductId)
|
||||||
|
?.SellingPrice ?? 0;
|
||||||
|
|
||||||
table.Cell().Element(CellBody).Text(l.Product?.Name);
|
table.Cell().Element(CellBody).Text(l.Product?.Name);
|
||||||
table.Cell().Element(CellBody).AlignRight().Text(l.Quantity.ToString());
|
table.Cell().Element(CellBody).AlignRight().Text(l.Quantity.ToString());
|
||||||
table.Cell().Element(CellBody).AlignRight().Text($"{l.Quantity:n2} €");
|
table.Cell().Element(CellBody).AlignRight().Text($"{price:n2} €");
|
||||||
table.Cell().Element(CellBody).AlignRight().Text($"{l.Quantity * l.Quantity:n2} €");
|
table.Cell().Element(CellBody).AlignRight().Text($"{price * l.Quantity:n2} €");
|
||||||
|
|
||||||
total = total + l.Quantity * l.Quantity;
|
total += l.Quantity * price;
|
||||||
}
|
}
|
||||||
|
|
||||||
IContainer CellHeader(IContainer c) =>
|
IContainer CellHeader(IContainer c) => c.BorderBottom(1).PaddingVertical(5).DefaultTextStyle(x => x.SemiBold());
|
||||||
c.BorderBottom(1).PaddingVertical(5).DefaultTextStyle(x => x.SemiBold());
|
|
||||||
|
|
||||||
IContainer CellBody(IContainer c) =>
|
IContainer CellBody(IContainer c) => c.PaddingVertical(2);
|
||||||
c.PaddingVertical(2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
col.Item().LineHorizontal(1);
|
col.Item().LineHorizontal(1);
|
||||||
@@ -125,13 +125,13 @@ public class QuotationPdfService : IQuotationPdfService
|
|||||||
{
|
{
|
||||||
right.Item().AlignRight().Text($"Total HT : {total:n2} €");
|
right.Item().AlignRight().Text($"Total HT : {total:n2} €");
|
||||||
right.Item().AlignRight().Text("Taxe : 20 %");
|
right.Item().AlignRight().Text("Taxe : 20 %");
|
||||||
right.Item().AlignRight().Text($"Total TTC : {(total * 1.2):n2} €");
|
right.Item().AlignRight().Text($"Total TTC : {total * (decimal)1.2:n2} €");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Signature en bas à droite
|
// Signature en bas à droite
|
||||||
page.Footer().AlignRight().Column(col => { col.Item().AlignRight().Height(100).Image(signature, ImageScaling.FitArea); });
|
page.Footer().AlignRight().Column(col => { col.Item().AlignRight().Height(100).Image(signatureBytes, ImageScaling.FitArea); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using Amazon.S3;
|
||||||
|
using Amazon.S3.Model;
|
||||||
|
|
||||||
|
namespace PyroFetes.Services;
|
||||||
|
|
||||||
|
public class StorageService(IAmazonS3 amazonS3, IConfiguration config)
|
||||||
|
{
|
||||||
|
private readonly string _bucket = config["RustFs:BucketName"]!;
|
||||||
|
private readonly string _url = config["RustFs:ServiceUrl"]!;
|
||||||
|
|
||||||
|
public async Task<string> UploadFile(IFormFile file, string type, CancellationToken ct)
|
||||||
|
{
|
||||||
|
if (file.Length == 0) throw new Exception("Fichier vide");
|
||||||
|
|
||||||
|
string key = $"settings/{type}/{Guid.NewGuid()}";
|
||||||
|
|
||||||
|
using MemoryStream memoryStream = new();
|
||||||
|
await file.CopyToAsync(memoryStream, ct);
|
||||||
|
memoryStream.Position = 0;
|
||||||
|
|
||||||
|
PutObjectRequest uploadRequest = new()
|
||||||
|
{
|
||||||
|
BucketName = _bucket,
|
||||||
|
ContentType = file.ContentType,
|
||||||
|
InputStream = memoryStream,
|
||||||
|
Key = key,
|
||||||
|
};
|
||||||
|
|
||||||
|
await amazonS3.PutObjectAsync(uploadRequest, ct);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? GetUrl(string key)
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(key) ? null : $"{_url}/{_bucket}/{key}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ public class GetAllDeliveryNoteSpec : Specification<DeliveryNote>
|
|||||||
.Include(x => x.Deliverer)
|
.Include(x => x.Deliverer)
|
||||||
.Include(x => x.ProductDeliveries)!
|
.Include(x => x.ProductDeliveries)!
|
||||||
.ThenInclude(x => x.Product)
|
.ThenInclude(x => x.Product)
|
||||||
.Where(x => true);
|
.OrderBy(x => x.RealDeliveryDate)
|
||||||
|
.ThenByDescending(x => x.ExpeditionDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using Ardalis.Specification;
|
||||||
|
using PyroFetes.Models;
|
||||||
|
|
||||||
|
namespace PyroFetes.Specifications.DeliveryNotes;
|
||||||
|
|
||||||
|
public class GetAllDeliveryNotesByRealDateSpec : Specification<DeliveryNote>
|
||||||
|
{
|
||||||
|
public GetAllDeliveryNotesByRealDateSpec()
|
||||||
|
{
|
||||||
|
Query
|
||||||
|
.Include(x => x.Deliverer)
|
||||||
|
.Include(x => x.ProductDeliveries)!
|
||||||
|
.ThenInclude(x => x.Product)
|
||||||
|
.Where(x => x.RealDeliveryDate == null)
|
||||||
|
.OrderByDescending(x => x.ExpeditionDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user