From 1cfd6a540ee383d0d98c8689dd470a5fd3834ab1 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Wed, 21 May 2025 00:01:34 +0000 Subject: [PATCH] =?UTF-8?q?Implementaci=C3=B3n=20de=20funcionalidad=20de?= =?UTF-8?q?=20remitos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PetFinder/Migrations/AddDeliveryModels.cs | 108 ++++++++++ PetFinder/Models/Delivery.cs | 42 ++++ PetFinder/Models/DeliveryEquipment.cs | 20 ++ PetFinder/Models/DeliveryProduct.cs | 18 ++ PetFinder/Models/PetFinderContext.cs | 17 +- PetFinder/Pages/DeliveryPages/Create.cshtml | 187 +++++++++++++++++ .../Pages/DeliveryPages/Create.cshtml.cs | 128 ++++++++++++ PetFinder/Pages/DeliveryPages/Delete.cshtml | 52 +++++ .../Pages/DeliveryPages/Delete.cshtml.cs | 52 +++++ PetFinder/Pages/DeliveryPages/Details.cshtml | 165 +++++++++++++++ .../Pages/DeliveryPages/Details.cshtml.cs | 54 +++++ PetFinder/Pages/DeliveryPages/Edit.cshtml | 193 ++++++++++++++++++ PetFinder/Pages/DeliveryPages/Edit.cshtml.cs | 183 +++++++++++++++++ PetFinder/Pages/DeliveryPages/Index.cshtml | 42 ++++ PetFinder/Pages/DeliveryPages/Index.cshtml.cs | 28 +++ PetFinder/Pages/DeliveryPages/Print.cshtml | 140 +++++++++++++ PetFinder/Pages/DeliveryPages/Print.cshtml.cs | 40 ++++ PetFinder/Pages/Shared/_PrintLayout.cshtml | 93 +++++++++ PetFinder/Services/DeliveryService.cs | 91 +++++++++ PetFinder/Shared/NavBar.razor | 7 +- PetFinder/Startup.cs | 6 +- PetFinder/ViewModels/DeliveryViewModel.cs | 113 ++++++++++ 22 files changed, 1775 insertions(+), 4 deletions(-) create mode 100644 PetFinder/Migrations/AddDeliveryModels.cs create mode 100644 PetFinder/Models/Delivery.cs create mode 100644 PetFinder/Models/DeliveryEquipment.cs create mode 100644 PetFinder/Models/DeliveryProduct.cs create mode 100644 PetFinder/Pages/DeliveryPages/Create.cshtml create mode 100644 PetFinder/Pages/DeliveryPages/Create.cshtml.cs create mode 100644 PetFinder/Pages/DeliveryPages/Delete.cshtml create mode 100644 PetFinder/Pages/DeliveryPages/Delete.cshtml.cs create mode 100644 PetFinder/Pages/DeliveryPages/Details.cshtml create mode 100644 PetFinder/Pages/DeliveryPages/Details.cshtml.cs create mode 100644 PetFinder/Pages/DeliveryPages/Edit.cshtml create mode 100644 PetFinder/Pages/DeliveryPages/Edit.cshtml.cs create mode 100644 PetFinder/Pages/DeliveryPages/Index.cshtml create mode 100644 PetFinder/Pages/DeliveryPages/Index.cshtml.cs create mode 100644 PetFinder/Pages/DeliveryPages/Print.cshtml create mode 100644 PetFinder/Pages/DeliveryPages/Print.cshtml.cs create mode 100644 PetFinder/Pages/Shared/_PrintLayout.cshtml create mode 100644 PetFinder/Services/DeliveryService.cs create mode 100644 PetFinder/ViewModels/DeliveryViewModel.cs diff --git a/PetFinder/Migrations/AddDeliveryModels.cs b/PetFinder/Migrations/AddDeliveryModels.cs new file mode 100644 index 0000000..8172896 --- /dev/null +++ b/PetFinder/Migrations/AddDeliveryModels.cs @@ -0,0 +1,108 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace PetFinder.Migrations +{ + public partial class AddDeliveryModels : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Deliveries", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DeliveryNumber = table.Column(type: "nvarchar(max)", nullable: true), + Date = table.Column(type: "datetime2", nullable: false), + ClientName = table.Column(type: "nvarchar(max)", nullable: true), + Address = table.Column(type: "nvarchar(max)", nullable: true), + City = table.Column(type: "nvarchar(max)", nullable: true), + CUIT = table.Column(type: "nvarchar(max)", nullable: true), + IVAStatus = table.Column(type: "nvarchar(max)", nullable: true), + SentBy = table.Column(type: "nvarchar(max)", nullable: true), + ReceivedBy = table.Column(type: "nvarchar(max)", nullable: true), + Transport = table.Column(type: "nvarchar(max)", nullable: true), + DeclaredValue = table.Column(type: "decimal(18,2)", nullable: true), + Observations = table.Column(type: "nvarchar(max)", nullable: true), + Packages = table.Column(type: "int", nullable: true), + Signature = table.Column(type: "nvarchar(max)", nullable: true), + Status = table.Column(type: "nvarchar(max)", nullable: true), + AcceptedDate = table.Column(type: "datetime2", nullable: true), + UserSends = table.Column(type: "nvarchar(max)", nullable: true), + UserReceives = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Deliveries", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "DeliveryEquipments", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DeliveryId = table.Column(type: "int", nullable: false), + Description = table.Column(type: "nvarchar(max)", nullable: true), + MAC = table.Column(type: "nvarchar(max)", nullable: true), + SerialNumber = table.Column(type: "nvarchar(max)", nullable: true), + SoftwareId = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DeliveryEquipments", x => x.Id); + table.ForeignKey( + name: "FK_DeliveryEquipments_Deliveries_DeliveryId", + column: x => x.DeliveryId, + principalTable: "Deliveries", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "DeliveryProducts", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DeliveryId = table.Column(type: "int", nullable: false), + Description = table.Column(type: "nvarchar(max)", nullable: true), + Quantity = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DeliveryProducts", x => x.Id); + table.ForeignKey( + name: "FK_DeliveryProducts_Deliveries_DeliveryId", + column: x => x.DeliveryId, + principalTable: "Deliveries", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_DeliveryEquipments_DeliveryId", + table: "DeliveryEquipments", + column: "DeliveryId"); + + migrationBuilder.CreateIndex( + name: "IX_DeliveryProducts_DeliveryId", + table: "DeliveryProducts", + column: "DeliveryId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DeliveryEquipments"); + + migrationBuilder.DropTable( + name: "DeliveryProducts"); + + migrationBuilder.DropTable( + name: "Deliveries"); + } + } +} + diff --git a/PetFinder/Models/Delivery.cs b/PetFinder/Models/Delivery.cs new file mode 100644 index 0000000..dd8da52 --- /dev/null +++ b/PetFinder/Models/Delivery.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using PetFinder.Areas.Identity; + +#nullable disable + +namespace PetFinder.Models +{ + public class Delivery + { + public Delivery() + { + DeliveryProducts = new HashSet(); + DeliveryEquipments = new HashSet(); + } + + public int Id { get; set; } + public string DeliveryNumber { get; set; } + public DateTime Date { get; set; } + public string ClientName { get; set; } + public string Address { get; set; } + public string City { get; set; } + public string CUIT { get; set; } + public string IVAStatus { get; set; } + public string SentBy { get; set; } + public string ReceivedBy { get; set; } + public string Transport { get; set; } + public decimal? DeclaredValue { get; set; } + public string Observations { get; set; } + public int? Packages { get; set; } + public string Signature { get; set; } + public string Status { get; set; } + public DateTime? AcceptedDate { get; set; } + public string UserSends { get; set; } + public string UserReceives { get; set; } + + // Relaciones + public virtual ICollection DeliveryProducts { get; set; } + public virtual ICollection DeliveryEquipments { get; set; } + } +} + diff --git a/PetFinder/Models/DeliveryEquipment.cs b/PetFinder/Models/DeliveryEquipment.cs new file mode 100644 index 0000000..9946b2b --- /dev/null +++ b/PetFinder/Models/DeliveryEquipment.cs @@ -0,0 +1,20 @@ +using System; + +#nullable disable + +namespace PetFinder.Models +{ + public class DeliveryEquipment + { + public int Id { get; set; } + public int DeliveryId { get; set; } + public string Description { get; set; } + public string MAC { get; set; } + public string SerialNumber { get; set; } + public string SoftwareId { get; set; } + + // Relación con el remito + public virtual Delivery Delivery { get; set; } + } +} + diff --git a/PetFinder/Models/DeliveryProduct.cs b/PetFinder/Models/DeliveryProduct.cs new file mode 100644 index 0000000..8959c3c --- /dev/null +++ b/PetFinder/Models/DeliveryProduct.cs @@ -0,0 +1,18 @@ +using System; + +#nullable disable + +namespace PetFinder.Models +{ + public class DeliveryProduct + { + public int Id { get; set; } + public int DeliveryId { get; set; } + public string Description { get; set; } + public int Quantity { get; set; } + + // Relación con el remito + public virtual Delivery Delivery { get; set; } + } +} + diff --git a/PetFinder/Models/PetFinderContext.cs b/PetFinder/Models/PetFinderContext.cs index cd2266e..1863fb4 100644 --- a/PetFinder/Models/PetFinderContext.cs +++ b/PetFinder/Models/PetFinderContext.cs @@ -23,6 +23,9 @@ public PetFinderContext(DbContextOptions options) public DbSet Genders { get; set; } public DbSet Pets { get; set; } public DbSet Comments { get; set; } + public DbSet Deliveries { get; set; } + public DbSet DeliveryProducts { get; set; } + public DbSet DeliveryEquipments { get; set; } // Creo los generos por defecto ya que no disponen de un CRUD protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -30,7 +33,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) var gender1 = new Gender {Id = 1, Name = "Macho", SerializedName = "MACHO"}; var gender2 = new Gender {Id = 2, Name = "Hembra", SerializedName = "HEMBRA"}; modelBuilder.Entity().HasData(gender1, gender2); + + // Configuración de relaciones para Delivery + modelBuilder.Entity() + .HasMany(d => d.DeliveryProducts) + .WithOne(p => p.Delivery) + .HasForeignKey(p => p.DeliveryId); + + modelBuilder.Entity() + .HasMany(d => d.DeliveryEquipments) + .WithOne(e => e.Delivery) + .HasForeignKey(e => e.DeliveryId); + base.OnModelCreating(modelBuilder); } } -} \ No newline at end of file +} diff --git a/PetFinder/Pages/DeliveryPages/Create.cshtml b/PetFinder/Pages/DeliveryPages/Create.cshtml new file mode 100644 index 0000000..dc74bba --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Create.cshtml @@ -0,0 +1,187 @@ +@page +@model PetFinder.Pages.DeliveryPages.CreateModel +@{ + ViewData["Title"] = "Crear Remito"; +} + +

Crear Remito

+ +
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+ +

Productos

+
+
+ @for (int i = 0; i < Model.DeliveryVM.Products.Count; i++) + { +
+
+
+ + + +
+
+
+
+ + + +
+
+
+ +
+
+ } +
+
+ +
+ +

Equipos (Opcional)

+
+ @for (int i = 0; i < Model.DeliveryVM.Equipments.Count; i++) + { +
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+ +
+
+ } +
+
+ +
+ +
+ + Cancelar +
+
+ +@section Scripts { + +} + diff --git a/PetFinder/Pages/DeliveryPages/Create.cshtml.cs b/PetFinder/Pages/DeliveryPages/Create.cshtml.cs new file mode 100644 index 0000000..5952108 --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Create.cshtml.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using PetFinder.Models; +using PetFinder.Services; +using PetFinder.ViewModels; +using System.Linq; + +namespace PetFinder.Pages.DeliveryPages +{ + public class CreateModel : PageModel + { + private readonly DeliveryService _deliveryService; + + public CreateModel(DeliveryService deliveryService) + { + _deliveryService = deliveryService; + } + + [BindProperty] + public DeliveryViewModel DeliveryVM { get; set; } + + public IActionResult OnGet() + { + DeliveryVM = new DeliveryViewModel + { + Date = DateTime.Now, + Status = "Pending", + Products = new List { new DeliveryProductViewModel() }, + Equipments = new List() + }; + + return Page(); + } + + public async Task OnPostAsync() + { + if (!ModelState.IsValid) + { + return Page(); + } + + // Validar que haya al menos un producto + if (DeliveryVM.Products == null || !DeliveryVM.Products.Any(p => !string.IsNullOrEmpty(p.Description))) + { + ModelState.AddModelError("DeliveryVM.Products", "Debe ingresar al menos un producto"); + return Page(); + } + + // Crear el remito + var delivery = new Delivery + { + DeliveryNumber = DeliveryVM.DeliveryNumber, + Date = DeliveryVM.Date, + ClientName = DeliveryVM.ClientName, + Address = DeliveryVM.Address, + City = DeliveryVM.City, + CUIT = DeliveryVM.CUIT, + IVAStatus = DeliveryVM.IVAStatus, + SentBy = DeliveryVM.SentBy, + ReceivedBy = DeliveryVM.ReceivedBy, + Transport = DeliveryVM.Transport, + DeclaredValue = DeliveryVM.DeclaredValue, + Observations = DeliveryVM.Observations, + Packages = DeliveryVM.Packages, + Status = "Pending", + UserSends = DeliveryVM.UserSends + }; + + // Agregar productos + if (DeliveryVM.Products != null) + { + foreach (var productVM in DeliveryVM.Products.Where(p => !string.IsNullOrEmpty(p.Description))) + { + delivery.DeliveryProducts.Add(new DeliveryProduct + { + Description = productVM.Description, + Quantity = productVM.Quantity + }); + } + } + + // Agregar equipos + if (DeliveryVM.Equipments != null) + { + foreach (var equipmentVM in DeliveryVM.Equipments.Where(e => !string.IsNullOrEmpty(e.Description))) + { + delivery.DeliveryEquipments.Add(new DeliveryEquipment + { + Description = equipmentVM.Description, + MAC = equipmentVM.MAC, + SerialNumber = equipmentVM.SerialNumber, + SoftwareId = equipmentVM.SoftwareId + }); + } + } + + await _deliveryService.CreateDeliveryAsync(delivery); + + return RedirectToPage("./Index"); + } + + public IActionResult OnPostAddProduct() + { + if (DeliveryVM.Products == null) + { + DeliveryVM.Products = new List(); + } + + DeliveryVM.Products.Add(new DeliveryProductViewModel()); + return Page(); + } + + public IActionResult OnPostAddEquipment() + { + if (DeliveryVM.Equipments == null) + { + DeliveryVM.Equipments = new List(); + } + + DeliveryVM.Equipments.Add(new DeliveryEquipmentViewModel()); + return Page(); + } + } +} + diff --git a/PetFinder/Pages/DeliveryPages/Delete.cshtml b/PetFinder/Pages/DeliveryPages/Delete.cshtml new file mode 100644 index 0000000..acc9b5a --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Delete.cshtml @@ -0,0 +1,52 @@ +@page +@model PetFinder.Pages.DeliveryPages.DeleteModel +@{ + ViewData["Title"] = "Eliminar Remito"; +} + +

Eliminar Remito

+ +
+

¿Está seguro de que desea eliminar este remito?

+

Esta acción no se puede deshacer.

+
+ +
+
+
+
+ +

@Model.Delivery.DeliveryNumber

+
+
+ +

@Model.Delivery.Date.ToString("dd/MM/yyyy")

+
+
+ +

@Model.Delivery.ClientName

+
+
+
+
+ +

@Model.Delivery.SentBy

+
+
+ +

@Model.Delivery.ReceivedBy

+
+
+ +

@Model.Delivery.Status

+
+
+
+ +
+ + + Cancelar +
+
+ diff --git a/PetFinder/Pages/DeliveryPages/Delete.cshtml.cs b/PetFinder/Pages/DeliveryPages/Delete.cshtml.cs new file mode 100644 index 0000000..8b3ecb1 --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Delete.cshtml.cs @@ -0,0 +1,52 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using PetFinder.Models; +using PetFinder.Services; + +namespace PetFinder.Pages.DeliveryPages +{ + public class DeleteModel : PageModel + { + private readonly DeliveryService _deliveryService; + + public DeleteModel(DeliveryService deliveryService) + { + _deliveryService = deliveryService; + } + + [BindProperty] + public Delivery Delivery { get; set; } + + public async Task OnGetAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + Delivery = await _deliveryService.GetDeliveryByIdAsync(id.Value); + + if (Delivery == null) + { + return NotFound(); + } + + return Page(); + } + + public async Task OnPostAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + await _deliveryService.DeleteDeliveryAsync(id.Value); + + return RedirectToPage("./Index"); + } + } +} + diff --git a/PetFinder/Pages/DeliveryPages/Details.cshtml b/PetFinder/Pages/DeliveryPages/Details.cshtml new file mode 100644 index 0000000..6ca93b2 --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Details.cshtml @@ -0,0 +1,165 @@ +@page +@model PetFinder.Pages.DeliveryPages.DetailsModel +@{ + ViewData["Title"] = "Detalles del Remito"; +} + +

Remito N° @Model.Delivery.DeliveryNumber

+ +
+
+
+
+ +

@Model.Delivery.Date.ToString("dd/MM/yyyy")

+
+
+ +

@Model.Delivery.ClientName

+
+
+ +

@Model.Delivery.Address

+
+
+ +

@Model.Delivery.City

+
+
+ +

@Model.Delivery.CUIT

+
+
+ +

@Model.Delivery.IVAStatus

+
+
+
+
+ +

@Model.Delivery.SentBy

+
+
+ +

@Model.Delivery.ReceivedBy

+
+
+ +

@Model.Delivery.Transport

+
+ @if (Model.Delivery.DeclaredValue.HasValue) + { +
+ +

@Model.Delivery.DeclaredValue.Value.ToString("C")

+
+ } + @if (!string.IsNullOrEmpty(Model.Delivery.Observations)) + { +
+ +

@Model.Delivery.Observations

+
+ } + @if (Model.Delivery.Packages.HasValue) + { +
+ +

@Model.Delivery.Packages

+
+ } +
+
+ +

Productos

+ + + + + + + + + @foreach (var product in Model.Delivery.DeliveryProducts) + { + + + + + } + +
DescripciónCantidad
@product.Description@product.Quantity
+ + @if (Model.HasEquipments) + { +

Equipos

+ + + + + + + + + + + @foreach (var equipment in Model.Delivery.DeliveryEquipments) + { + + + + + + + } + +
DescripciónMACN° SerieSoftware Id
@equipment.Description@equipment.MAC@equipment.SerialNumber@equipment.SoftwareId
+ } + +
+ +

@Model.Delivery.Status

+
+ + @if (!string.IsNullOrEmpty(Model.Delivery.Signature)) + { +
+ +

@Model.Delivery.Signature

+
+ } + + @if (string.IsNullOrEmpty(Model.Delivery.Signature)) + { +
+
+
+ +
+ + +
+ +
+
+
+
+ +
+ + +
+ +
+
+
+ } + + +
+ diff --git a/PetFinder/Pages/DeliveryPages/Details.cshtml.cs b/PetFinder/Pages/DeliveryPages/Details.cshtml.cs new file mode 100644 index 0000000..cb78984 --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Details.cshtml.cs @@ -0,0 +1,54 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using PetFinder.Models; +using PetFinder.Services; +using PetFinder.ViewModels; +using System.Linq; + +namespace PetFinder.Pages.DeliveryPages +{ + public class DetailsModel : PageModel + { + private readonly DeliveryService _deliveryService; + + public DetailsModel(DeliveryService deliveryService) + { + _deliveryService = deliveryService; + } + + public Delivery Delivery { get; set; } + public bool HasEquipments => Delivery?.DeliveryEquipments?.Any() == true; + + public async Task OnGetAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + Delivery = await _deliveryService.GetDeliveryByIdAsync(id.Value); + + if (Delivery == null) + { + return NotFound(); + } + + return Page(); + } + + public async Task OnPostAcceptAsync(int id, string userReceives) + { + await _deliveryService.AcceptDeliveryAsync(id, userReceives); + return RedirectToPage("./Details", new { id }); + } + + public async Task OnPostRejectAsync(int id, string userReceives) + { + await _deliveryService.RejectDeliveryAsync(id, userReceives); + return RedirectToPage("./Details", new { id }); + } + } +} + diff --git a/PetFinder/Pages/DeliveryPages/Edit.cshtml b/PetFinder/Pages/DeliveryPages/Edit.cshtml new file mode 100644 index 0000000..46912f4 --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Edit.cshtml @@ -0,0 +1,193 @@ +@page +@model PetFinder.Pages.DeliveryPages.EditModel +@{ + ViewData["Title"] = "Editar Remito"; +} + +

Editar Remito

+ +
+ + + + + + +
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+ +

Productos

+
+
+ @for (int i = 0; i < Model.DeliveryVM.Products.Count; i++) + { +
+
+
+ + + +
+
+
+
+ + + +
+
+
+ +
+
+ } +
+
+ +
+ +

Equipos (Opcional)

+
+ @for (int i = 0; i < Model.DeliveryVM.Equipments.Count; i++) + { +
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+ +
+
+ } +
+
+ +
+ +
+ + Cancelar +
+
+ +@section Scripts { + +} + diff --git a/PetFinder/Pages/DeliveryPages/Edit.cshtml.cs b/PetFinder/Pages/DeliveryPages/Edit.cshtml.cs new file mode 100644 index 0000000..c26acc1 --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Edit.cshtml.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using PetFinder.Models; +using PetFinder.Services; +using PetFinder.ViewModels; + +namespace PetFinder.Pages.DeliveryPages +{ + public class EditModel : PageModel + { + private readonly DeliveryService _deliveryService; + + public EditModel(DeliveryService deliveryService) + { + _deliveryService = deliveryService; + } + + [BindProperty] + public DeliveryViewModel DeliveryVM { get; set; } + + public async Task OnGetAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + var delivery = await _deliveryService.GetDeliveryByIdAsync(id.Value); + + if (delivery == null) + { + return NotFound(); + } + + // Mapear el modelo a ViewModel + DeliveryVM = new DeliveryViewModel + { + Id = delivery.Id, + DeliveryNumber = delivery.DeliveryNumber, + Date = delivery.Date, + ClientName = delivery.ClientName, + Address = delivery.Address, + City = delivery.City, + CUIT = delivery.CUIT, + IVAStatus = delivery.IVAStatus, + SentBy = delivery.SentBy, + ReceivedBy = delivery.ReceivedBy, + Transport = delivery.Transport, + DeclaredValue = delivery.DeclaredValue, + Observations = delivery.Observations, + Packages = delivery.Packages, + Status = delivery.Status, + Signature = delivery.Signature, + AcceptedDate = delivery.AcceptedDate, + UserSends = delivery.UserSends, + UserReceives = delivery.UserReceives, + Products = delivery.DeliveryProducts.Select(p => new DeliveryProductViewModel + { + Id = p.Id, + DeliveryId = p.DeliveryId, + Description = p.Description, + Quantity = p.Quantity + }).ToList(), + Equipments = delivery.DeliveryEquipments.Select(e => new DeliveryEquipmentViewModel + { + Id = e.Id, + DeliveryId = e.DeliveryId, + Description = e.Description, + MAC = e.MAC, + SerialNumber = e.SerialNumber, + SoftwareId = e.SoftwareId + }).ToList() + }; + + // Asegurar que siempre haya al menos un producto vacío para agregar + if (DeliveryVM.Products.Count == 0) + { + DeliveryVM.Products.Add(new DeliveryProductViewModel()); + } + + return Page(); + } + + public async Task OnPostAsync() + { + if (!ModelState.IsValid) + { + return Page(); + } + + // Validar que haya al menos un producto + if (DeliveryVM.Products == null || !DeliveryVM.Products.Any(p => !string.IsNullOrEmpty(p.Description))) + { + ModelState.AddModelError("DeliveryVM.Products", "Debe ingresar al menos un producto"); + return Page(); + } + + // Obtener el remito existente + var delivery = await _deliveryService.GetDeliveryByIdAsync(DeliveryVM.Id); + if (delivery == null) + { + return NotFound(); + } + + // Actualizar propiedades del remito + delivery.DeliveryNumber = DeliveryVM.DeliveryNumber; + delivery.Date = DeliveryVM.Date; + delivery.ClientName = DeliveryVM.ClientName; + delivery.Address = DeliveryVM.Address; + delivery.City = DeliveryVM.City; + delivery.CUIT = DeliveryVM.CUIT; + delivery.IVAStatus = DeliveryVM.IVAStatus; + delivery.SentBy = DeliveryVM.SentBy; + delivery.ReceivedBy = DeliveryVM.ReceivedBy; + delivery.Transport = DeliveryVM.Transport; + delivery.DeclaredValue = DeliveryVM.DeclaredValue; + delivery.Observations = DeliveryVM.Observations; + delivery.Packages = DeliveryVM.Packages; + delivery.UserSends = DeliveryVM.UserSends; + + // Limpiar productos existentes y agregar los nuevos + delivery.DeliveryProducts.Clear(); + if (DeliveryVM.Products != null) + { + foreach (var productVM in DeliveryVM.Products.Where(p => !string.IsNullOrEmpty(p.Description))) + { + delivery.DeliveryProducts.Add(new DeliveryProduct + { + Description = productVM.Description, + Quantity = productVM.Quantity + }); + } + } + + // Limpiar equipos existentes y agregar los nuevos + delivery.DeliveryEquipments.Clear(); + if (DeliveryVM.Equipments != null) + { + foreach (var equipmentVM in DeliveryVM.Equipments.Where(e => !string.IsNullOrEmpty(e.Description))) + { + delivery.DeliveryEquipments.Add(new DeliveryEquipment + { + Description = equipmentVM.Description, + MAC = equipmentVM.MAC, + SerialNumber = equipmentVM.SerialNumber, + SoftwareId = equipmentVM.SoftwareId + }); + } + } + + await _deliveryService.UpdateDeliveryAsync(delivery); + + return RedirectToPage("./Index"); + } + + public IActionResult OnPostAddProduct() + { + if (DeliveryVM.Products == null) + { + DeliveryVM.Products = new List(); + } + + DeliveryVM.Products.Add(new DeliveryProductViewModel()); + return Page(); + } + + public IActionResult OnPostAddEquipment() + { + if (DeliveryVM.Equipments == null) + { + DeliveryVM.Equipments = new List(); + } + + DeliveryVM.Equipments.Add(new DeliveryEquipmentViewModel()); + return Page(); + } + } +} + diff --git a/PetFinder/Pages/DeliveryPages/Index.cshtml b/PetFinder/Pages/DeliveryPages/Index.cshtml new file mode 100644 index 0000000..9478c5c --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Index.cshtml @@ -0,0 +1,42 @@ +@page +@model PetFinder.Pages.DeliveryPages.IndexModel +@{ + ViewData["Title"] = "Remitos"; +} + +

Remitos

+ +

+ Crear Nuevo Remito +

+ + + + + + + + + + + + + + @foreach (var item in Model.Deliveries) + { + + + + + + + + + } + +
N° RemitoFechaCliente / DestinoTransporteEstadoAcciones
@item.DeliveryNumber@item.Date.ToString("dd/MM/yyyy")@item.ClientName@item.Transport@item.Status + Detalles + Editar + Eliminar +
+ diff --git a/PetFinder/Pages/DeliveryPages/Index.cshtml.cs b/PetFinder/Pages/DeliveryPages/Index.cshtml.cs new file mode 100644 index 0000000..af3c88a --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Index.cshtml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using PetFinder.Models; +using PetFinder.Services; + +namespace PetFinder.Pages.DeliveryPages +{ + public class IndexModel : PageModel + { + private readonly DeliveryService _deliveryService; + + public IndexModel(DeliveryService deliveryService) + { + _deliveryService = deliveryService; + } + + public IList Deliveries { get; set; } + + public async Task OnGetAsync() + { + Deliveries = await _deliveryService.GetAllDeliveriesAsync(); + } + } +} + diff --git a/PetFinder/Pages/DeliveryPages/Print.cshtml b/PetFinder/Pages/DeliveryPages/Print.cshtml new file mode 100644 index 0000000..0f8e4bd --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Print.cshtml @@ -0,0 +1,140 @@ +@page +@model PetFinder.Pages.DeliveryPages.PrintModel +@{ + ViewData["Title"] = "Imprimir Remito"; + Layout = "_PrintLayout"; +} + + + +@if (Model.HasEquipments) +{ +
+ +} + diff --git a/PetFinder/Pages/DeliveryPages/Print.cshtml.cs b/PetFinder/Pages/DeliveryPages/Print.cshtml.cs new file mode 100644 index 0000000..51c9e13 --- /dev/null +++ b/PetFinder/Pages/DeliveryPages/Print.cshtml.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using PetFinder.Models; +using PetFinder.Services; + +namespace PetFinder.Pages.DeliveryPages +{ + public class PrintModel : PageModel + { + private readonly DeliveryService _deliveryService; + + public PrintModel(DeliveryService deliveryService) + { + _deliveryService = deliveryService; + } + + public Delivery Delivery { get; set; } + public bool HasEquipments => Delivery?.DeliveryEquipments?.Count > 0; + + public async Task OnGetAsync(int? id) + { + if (id == null) + { + return NotFound(); + } + + Delivery = await _deliveryService.GetDeliveryByIdAsync(id.Value); + + if (Delivery == null) + { + return NotFound(); + } + + return Page(); + } + } +} + diff --git a/PetFinder/Pages/Shared/_PrintLayout.cshtml b/PetFinder/Pages/Shared/_PrintLayout.cshtml new file mode 100644 index 0000000..664e0a7 --- /dev/null +++ b/PetFinder/Pages/Shared/_PrintLayout.cshtml @@ -0,0 +1,93 @@ + + + + + + @ViewData["Title"] - PetFinder + + + + +
+ + Volver +
+ + @RenderBody() + + + + @RenderSection("Scripts", required: false) + + + diff --git a/PetFinder/Services/DeliveryService.cs b/PetFinder/Services/DeliveryService.cs new file mode 100644 index 0000000..cecb3f4 --- /dev/null +++ b/PetFinder/Services/DeliveryService.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using PetFinder.Models; + +namespace PetFinder.Services +{ + public class DeliveryService + { + private readonly PetFinderContext _context; + + public DeliveryService(PetFinderContext context) + { + _context = context; + } + + public async Task GetDeliveryByIdAsync(int deliveryId) + { + return await _context.Deliveries + .Include(d => d.DeliveryProducts) + .Include(d => d.DeliveryEquipments) + .FirstOrDefaultAsync(d => d.Id == deliveryId); + } + + public async Task> GetAllDeliveriesAsync() + { + return await _context.Deliveries + .Include(d => d.DeliveryProducts) + .OrderByDescending(d => d.Date) + .ToListAsync(); + } + + public async Task CreateDeliveryAsync(Delivery delivery) + { + _context.Deliveries.Add(delivery); + await _context.SaveChangesAsync(); + return delivery; + } + + public async Task UpdateDeliveryAsync(Delivery delivery) + { + _context.Entry(delivery).State = EntityState.Modified; + await _context.SaveChangesAsync(); + return delivery; + } + + public async Task DeleteDeliveryAsync(int deliveryId) + { + var delivery = await _context.Deliveries.FindAsync(deliveryId); + if (delivery == null) + return false; + + _context.Deliveries.Remove(delivery); + await _context.SaveChangesAsync(); + return true; + } + + public async Task AcceptDeliveryAsync(int deliveryId, string userReceives) + { + var delivery = await _context.Deliveries.FindAsync(deliveryId); + if (delivery == null) + return null; + + delivery.Status = "Accepted"; + delivery.AcceptedDate = DateTime.Now; + delivery.UserReceives = userReceives; + delivery.Signature = $"Aceptado por {userReceives} el dia {DateTime.Now:dd/MM/yyyy}"; + + await _context.SaveChangesAsync(); + return delivery; + } + + public async Task RejectDeliveryAsync(int deliveryId, string userReceives) + { + var delivery = await _context.Deliveries.FindAsync(deliveryId); + if (delivery == null) + return null; + + delivery.Status = "Rejected"; + delivery.AcceptedDate = DateTime.Now; + delivery.UserReceives = userReceives; + delivery.Signature = $"Rechazado por {userReceives} el dia {DateTime.Now:dd/MM/yyyy}"; + + await _context.SaveChangesAsync(); + return delivery; + } + } +} + diff --git a/PetFinder/Shared/NavBar.razor b/PetFinder/Shared/NavBar.razor index 36fed38..f5f4d60 100644 --- a/PetFinder/Shared/NavBar.razor +++ b/PetFinder/Shared/NavBar.razor @@ -1,4 +1,4 @@ -@using PetFinder.Areas.Identity.Extensions +@using PetFinder.Areas.Identity.Extensions @using PetFinder.Areas.Identity @using Microsoft.AspNetCore.Identity @inject SignInManager SignInManager @@ -20,6 +20,9 @@ + @@ -51,4 +54,4 @@ @code { -} \ No newline at end of file +} diff --git a/PetFinder/Startup.cs b/PetFinder/Startup.cs index 0a36750..848514c 100644 --- a/PetFinder/Startup.cs +++ b/PetFinder/Startup.cs @@ -11,6 +11,7 @@ using PetFinder.Areas.Identity.Helper; using PetFinder.Data; using PetFinder.Models; +using PetFinder.Services; using Serilog; using Serilog.Sinks.MSSqlServer; using Serilog.Ui.MsSqlServerProvider; @@ -84,6 +85,9 @@ public void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddScoped(); + // Registrar el servicio de remitos + services.AddScoped(); + services.AddHttpContextAccessor(); services.AddControllers(); @@ -118,4 +122,4 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) }); } } -} \ No newline at end of file +} diff --git a/PetFinder/ViewModels/DeliveryViewModel.cs b/PetFinder/ViewModels/DeliveryViewModel.cs new file mode 100644 index 0000000..a94f0b7 --- /dev/null +++ b/PetFinder/ViewModels/DeliveryViewModel.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using PetFinder.Models; + +namespace PetFinder.ViewModels +{ + public class DeliveryViewModel + { + public int Id { get; set; } + + [Required(ErrorMessage = "El número de remito es obligatorio")] + [Display(Name = "N° Remito")] + public string DeliveryNumber { get; set; } + + [Required(ErrorMessage = "La fecha es obligatoria")] + [Display(Name = "Fecha")] + [DataType(DataType.Date)] + public DateTime Date { get; set; } + + [Required(ErrorMessage = "El nombre del cliente/destino es obligatorio")] + [Display(Name = "Cliente / Destino")] + public string ClientName { get; set; } + + [Required(ErrorMessage = "El domicilio es obligatorio")] + [Display(Name = "Domicilio")] + public string Address { get; set; } + + [Required(ErrorMessage = "La localidad es obligatoria")] + [Display(Name = "Localidad")] + public string City { get; set; } + + [Required(ErrorMessage = "El CUIT es obligatorio")] + [Display(Name = "CUIT")] + public string CUIT { get; set; } + + [Required(ErrorMessage = "La situación fiscal es obligatoria")] + [Display(Name = "I.V.A")] + public string IVAStatus { get; set; } + + [Required(ErrorMessage = "El remitente es obligatorio")] + [Display(Name = "Envía")] + public string SentBy { get; set; } + + [Required(ErrorMessage = "El destinatario es obligatorio")] + [Display(Name = "Recibe")] + public string ReceivedBy { get; set; } + + [Required(ErrorMessage = "El transporte es obligatorio")] + [Display(Name = "Transporte")] + public string Transport { get; set; } + + [Display(Name = "Valor Declarado")] + [DataType(DataType.Currency)] + public decimal? DeclaredValue { get; set; } + + [Display(Name = "Observaciones")] + public string Observations { get; set; } + + [Display(Name = "Bultos")] + public int? Packages { get; set; } + + [Display(Name = "Firma")] + public string Signature { get; set; } + + [Display(Name = "Estado")] + public string Status { get; set; } + + public DateTime? AcceptedDate { get; set; } + public string UserSends { get; set; } + public string UserReceives { get; set; } + + [Display(Name = "Productos")] + public List Products { get; set; } = new List(); + + [Display(Name = "Equipos")] + public List Equipments { get; set; } = new List(); + } + + public class DeliveryProductViewModel + { + public int Id { get; set; } + public int DeliveryId { get; set; } + + [Required(ErrorMessage = "La descripción del producto es obligatoria")] + [Display(Name = "Descripción")] + public string Description { get; set; } + + [Required(ErrorMessage = "La cantidad es obligatoria")] + [Display(Name = "Cantidad")] + public int Quantity { get; set; } + } + + public class DeliveryEquipmentViewModel + { + public int Id { get; set; } + public int DeliveryId { get; set; } + + [Required(ErrorMessage = "La descripción del equipo es obligatoria")] + [Display(Name = "Descripción")] + public string Description { get; set; } + + [Display(Name = "MAC")] + public string MAC { get; set; } + + [Display(Name = "N° Serie")] + public string SerialNumber { get; set; } + + [Display(Name = "Software Id")] + public string SoftwareId { get; set; } + } +} +