5 Commits

Author SHA1 Message Date
f8ca672bc6 feat:Category 2025-11-29 20:52:45 +04:00
e3f223751d Merge pull request 'feat:Product' (#1) from feat/Product into main
Reviewed-on: #1
Reviewed-by: SajjadDoosty <sajjad.doosty.83@gmail.com>
2025-11-29 10:22:26 +00:00
207d402c66 Merge pull request 'fix:bog store' (#3) from fix/bog-store into main
Reviewed-on: #3
Reviewed-by: SajjadDoosty <sajjad.doosty.83@gmail.com>
2025-11-29 10:10:36 +00:00
5680ae8265 fix:Product 2025-11-28 16:23:07 +04:00
574f498975 feat:Product 2025-11-26 12:35:09 +04:00
33 changed files with 1075 additions and 0 deletions

View File

@ -0,0 +1,94 @@
using Application.Aggregates.Categorys.ViewModels;
using Domain.Aggregates.Categorys;
using Domain.Aggregates.Categorys.Data;
using Mapster;
using Resources.Messages;
namespace Application.Aggregates.Categorys;
public class CategorysApplication(ICategoryRepository categoryRepository)
{
public async Task<CategoryViewModel> CreateAsync(CreateCategoryViewModel categoryViewModel)
{
var category = Category.Create(
name: categoryViewModel.Name,
description: categoryViewModel.Description);
if (categoryViewModel.IsActive == true)
{
category.Activate();
}
await categoryRepository.AddAsync(category);
await categoryRepository.SaveChangesAsync();
return category.Adapt<CategoryViewModel>();
}
public async Task<List<CategoryViewModel>> GetAllAsync()
{
var category =
await categoryRepository.GetAllAsync();
return category.Adapt<List<CategoryViewModel>>();
}
public async Task<CategoryViewModel> GetAsync(Guid categoryId)
{
var category =
await categoryRepository.GetAsync(categoryId);
return category.Adapt<CategoryViewModel>();
}
public async Task<CategoryViewModel> UpdateAsync(UpdateCategoryViewModel updateCategoryView)
{
var update =
await categoryRepository.GetAsync(updateCategoryView.Id);
if (update == null || updateCategoryView.Id == Guid.Empty)
{
var error =
string.Format(Errors.NotFound, Resources.DataDictionary.Store);
throw new Exception(error);
}
update.Update(
name: updateCategoryView.Name,
description: updateCategoryView.Description);
if (updateCategoryView.IsActive == true)
{
update.Activate();
}
else
{
update.Deactivate();
}
await categoryRepository.SaveChangesAsync();
return update.Adapt<CategoryViewModel>();
}
public async Task DeleteAsync(Guid categoryId)
{
var delete =
await categoryRepository.GetAsync(categoryId);
if (delete == null || delete.Id == Guid.Empty)
{
var error =
string.Format(Errors.NotFound, Resources.DataDictionary.Store);
throw new Exception(error);
}
categoryRepository.Remove(delete);
await categoryRepository.SaveChangesAsync();
}
}

View File

@ -0,0 +1,6 @@
namespace Application.Aggregates.Categorys.ViewModels;
public class CategoryViewModel : UpdateCategoryViewModel
{
}

View File

@ -0,0 +1,13 @@
namespace Application.Aggregates.Categorys.ViewModels;
public class CreateCategoryViewModel
{
public CreateCategoryViewModel()
{
}
public string Name { get; set; }
public string Description { get; set; }
public bool IsActive { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace Application.Aggregates.Categorys.ViewModels;
public class UpdateCategoryViewModel : CreateCategoryViewModel
{
public Guid Id { get; set; }
}

View File

@ -0,0 +1,104 @@
using Application.Aggregates.Products.ViewModels;
using Application.Aggregates.Stores.ViewModels;
using Domain.Aggregates.Products;
using Domain.Aggregates.Products.Data;
using Domain.Aggregates.Stores;
using Mapster;
using Persistence.Repositories.Aggregates.Stores;
using Resources.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Application.Aggregates.Products;
public class ProductsApplication(IProductRepository productRepository)
{
public async Task<ProductViewModel> CreateAsync(CreateProductViewModel productViewModel)
{
var product = Product.Create(
name: productViewModel.Name,
description: productViewModel.Description,
price: productViewModel.Price,
quantity: productViewModel.Quantity);
if (productViewModel.IsActive == true)
{
product.Activate();
}
await productRepository.AddAsync(product);
await productRepository.SaveChangesAsync();
return product.Adapt<ProductViewModel>();
}
public async Task<List<ProductViewModel>> GetStors()
{
var products =
await productRepository.GetAllAsync();
return products.Adapt<List<ProductViewModel>>();
}
public async Task<ProductViewModel> GetAsync(Guid productId)
{
var product =
await productRepository.GetAsync(productId);
return product.Adapt<ProductViewModel>();
}
public async Task<ProductViewModel> UpdateAsync(UpdateProductViewModel updateProductView)
{
var update =
await productRepository.GetAsync(updateProductView.Id);
if (update == null || updateProductView.Id == Guid.Empty)
{
var error =
string.Format(Errors.NotFound, Resources.DataDictionary.Store);
throw new Exception(error);
}
update.Update(
name: updateProductView.Name,
description: updateProductView.Description,
price: updateProductView.Price,
quantity: updateProductView.Quantity);
if (updateProductView.IsActive == true)
{
update.Activate();
}
else
{
update.Deactivate();
}
await productRepository.SaveChangesAsync();
return update.Adapt<ProductViewModel>();
}
public async Task DeleteAsync(Guid productId)
{
var delete =
await productRepository.GetAsync(productId);
if (delete == null || delete.Id == Guid.Empty)
{
var error =
string.Format(Errors.NotFound, Resources.DataDictionary.Store);
throw new Exception(error);
}
productRepository.Remove(delete);
await productRepository.SaveChangesAsync();
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Application.Aggregates.Products.ViewModels;
public class CreateProductViewModel
{
public CreateProductViewModel()
{
}
public string Name { get; set; }
public string Description { get; set; }
public int Price { get; set; }
public int Quantity { get; set; }
public bool IsActive { get; set; }
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Application.Aggregates.Products.ViewModels;
public class ProductViewModel : UpdateProductViewModel
{
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Application.Aggregates.Products.ViewModels;
public class UpdateProductViewModel:CreateProductViewModel
{
public Guid Id { get; set; }
}

View File

@ -0,0 +1,46 @@
using Domain.Aggregates.Categorys;
using Domain.SeedWork;
using Framework.DataType;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Domain.Aggregates.Categorys
{
public class Category : Entity
{
public Category()
{
////**********
}
private Category(string name,string description)
{
Name = name;
Description = description;
}
public string Name { get; set; }
public string Description { get; set; }
public static Category Create(string name,string description)
{
var category = new Category(
name: name.Fix() ?? "",
description: description.Fix() ?? "");
return category;
}
public void Update(string name, string description)
{
Name = name.Fix() ?? "";
Description = description.Fix() ?? "";
SetUpdateDateTime();
}
}
}

View File

@ -0,0 +1,10 @@
namespace Domain.Aggregates.Categorys.Data;
public interface ICategoryRepository
{
Task AddAsync(Category category);
Task<List<Category>> GetAllAsync();
Task<Category?> GetAsync(Guid categoryId);
void Remove(Category category);
Task SaveChangesAsync();
}

View File

@ -0,0 +1,17 @@
using Domain.Aggregates.Stores;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Domain.Aggregates.Products.Data;
public interface IProductRepository
{
Task AddAsync(Product product);
Task<List<Product>> GetAllAsync();
Task<Product?> GetAsync(Guid productId);
void Remove(Product product);
Task SaveChangesAsync();
}

View File

@ -0,0 +1,54 @@
using Domain.Aggregates.Stores;
using Domain.SeedWork;
using Framework.DataType;
using Resources.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Domain.Aggregates.Products;
public class Product : Entity
{
public Product()
{
////**********
}
private Product(string name, string description, int price, int quantity)
{
Name = name;
Description = description;
Price = price;
Quantity = quantity;
}
public string Name { get; set; }
public string Description { get; set; }
public int Price { get; set; }
public int Quantity { get; set; }
public static Product Create(string name, string description, int price, int quantity)
{
var store = new Product(
name: name.Fix() ?? "",
description: description.Fix() ?? "",
price: price,
quantity: quantity);
return store;
}
public void Update(string name, string description, int price, int quantity)
{
Name = name.Fix() ?? "";
Description = description.Fix() ?? "";
Price = price;
Quantity = quantity;
SetUpdateDateTime();
}
}

View File

@ -1,6 +1,8 @@
using Domain.Aggregates.Stores;
using Domain.Aggregates.Users;
using Domain.Aggregates.Products;
using Microsoft.EntityFrameworkCore;
using Domain.Aggregates.Categorys;
namespace Persistence;
@ -14,5 +16,7 @@ public class DatabaseContext: DbContext
public DbSet<User> Users { get; set; }
public DbSet<Store> Stores { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Category> Category { get; set; }
}

View File

@ -0,0 +1,51 @@
using Domain.Aggregates.Categorys;
using Domain.Aggregates.Categorys.Data;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Persistence.Repositories.Aggregates.Categorys;
public class CategoryRepository(DatabaseContext databaseContext) : ICategoryRepository
{
public async Task AddAsync(Category categorys)
{
await databaseContext.AddAsync(categorys);
}
public async Task<List<Category>> GetAllAsync()
{
var category =
await databaseContext.Category
.Where(x => x.IsDeleted == false)
.ToListAsync();
return category;
}
public async Task<Category?> GetAsync(Guid categoryId)
{
var category =
await databaseContext.Category
.Where(x => x.IsDeleted == false)
.Where(x => x.Id == categoryId)
.FirstOrDefaultAsync();
return category;
}
public void Remove(Category category)
{
category.Delete();
}
public async Task SaveChangesAsync()
{
await databaseContext.SaveChangesAsync();
}
}

View File

@ -0,0 +1,50 @@
using Domain.Aggregates.Products.Data;
using Domain.Aggregates.Stores;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Domain.Aggregates.Products;
using Microsoft.EntityFrameworkCore;
namespace Persistence.Repositories.Aggregates.Products;
public class ProductRepository(DatabaseContext databaseContext):IProductRepository
{
public async Task AddAsync(Product product)
{
await databaseContext.AddAsync(product);
}
public async Task<List<Product>> GetAllAsync()
{
var products =
await databaseContext.Products
.Where(x => x.IsDeleted == false)
.ToListAsync();
return products;
}
public async Task<Product?> GetAsync(Guid productId)
{
var product =
await databaseContext.Products
.Where(x => x.IsDeleted == false)
.Where(x => x.Id == productId)
.FirstOrDefaultAsync();
return product;
}
public void Remove(Product product)
{
product.Delete();
}
public async Task SaveChangesAsync()
{
await databaseContext.SaveChangesAsync();
}
}

View File

@ -8,4 +8,6 @@
<h2 class="text-start">Pages</h2>
<a class="btn btn-secondary my-2" asp-page="Panel/Users/Index">[ Users ]</a>
<a class="btn btn-secondary my-2" asp-page="Panel/Stores/Index">[ Stores ]</a>
<a class="btn btn-secondary my-2" asp-page="Panel/Products/Index">[ Products ]</a>
<a class="btn btn-secondary my-2" asp-page="Panel/Category/Index">[ Category ]</a>
</div>

View File

@ -0,0 +1,37 @@
@page
@model Server.Pages.Panel.Category.CreateModel
@{
var pageTitle =
$"{Resources.DataDictionary.CreateOf} {Resources.DataDictionary.Category}";
ViewData[Constants.ViewDataKeyName.PageTitle] = pageTitle;
}
<form method="post">
<section-form>
<fieldset>
<section-form-header>
@(pageTitle)
</section-form-header>
<partial name="PartialViews/_DisplayPageMessages" />
<ub-full-input asp-for="categoryViewModel.Name" />
<ub-full-input asp-for="categoryViewModel.Description" />
<ub-full-checkbox asp-for="categoryViewModel.IsActive" />
</fieldset>
<section-form-buttons>
<button-create />
<button-reset />
</section-form-buttons>
</section-form>
</form>

View File

@ -0,0 +1,28 @@
using Application.Aggregates.Categorys;
using Application.Aggregates.Categorys.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Category;
public class CreateModel(CategorysApplication categorysApplication) : PageModel
{
[BindProperty]
public CreateCategoryViewModel categoryViewModel { get; set; }
public void OnGet()
{
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
await categorysApplication.CreateAsync(categoryViewModel);
return RedirectToPage("Index");
}
}

View File

@ -0,0 +1,37 @@
@page
@model Server.Pages.Panel.Category.DeleteModel
@{
var pageTitle =
$"{Resources.DataDictionary.CreateOf} {Resources.DataDictionary.Category}";
ViewData[Constants.ViewDataKeyName.PageTitle] = pageTitle;
}
<form method="post">
<section-form>
<input hidden asp-for="DeleteViewModel.Id" dir="ltr" />
<fieldset disabled>
<section-form-header>
@(pageTitle)
</section-form-header>
<partial name="PartialViews/_DisplayPageMessages" />
<ub-full-input asp-for="DeleteViewModel.Name" />
<ub-full-input asp-for="DeleteViewModel.Description" />
<ub-full-checkbox asp-for="DeleteViewModel.IsActive" />
</fieldset>
<section-form-buttons>
<button-delete />
</section-form-buttons>
</section-form>
</form>

View File

@ -0,0 +1,37 @@
using Application.Aggregates.Categorys;
using Application.Aggregates.Categorys.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Category;
public class DeleteModel(CategorysApplication categorysApplication) : PageModel
{
[BindProperty]
public CategoryViewModel DeleteViewModel { get; set; } = new();
public async Task<IActionResult> OnGetAsync(Guid id)
{
if (id == Guid.Empty)
{
return RedirectToPage("Index");
}
DeleteViewModel =
await categorysApplication.GetAsync(id);
if (DeleteViewModel == null)
{
return RedirectToPage("Index");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
await categorysApplication.DeleteAsync(DeleteViewModel.Id);
return RedirectToPage("Index");
}
}

View File

@ -0,0 +1,33 @@
@page
@model Server.Pages.Panel.Category.IndexModel
@{
}
<div class="my-2 float-end">
<a class="btn btn-primary" asp-page="Create">@(Resources.ButtonCaptions.Create)</a>
</div>
<table class="table table-hover">
<thead>
<tr>
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.Name))
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.Description))
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.IsActive))
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.category)
{
<tr>
@(Html.Ub_DisplayStringWithTd(item.Name))
@(Html.Ub_DisplayStringWithTd(item.Description))
@(Html.Ub_DisplayBooleanWithTd(item.IsActive))
<td>
<div class="btn-group" role="group" aria-label="Basic example">
<a asp-page="Update" asp-route-Id="@(item.Id)" class="btn btn-warning">@(Resources.ButtonCaptions.Edit)</a>
<a asp-page="Delete" asp-route-Id="@(item.Id)" class="btn btn-danger">@(Resources.ButtonCaptions.Delete)</a>
</div>
</td>
</tr>
}
</tbody>
</table>

View File

@ -0,0 +1,15 @@
using Application.Aggregates.Categorys;
using Application.Aggregates.Categorys.ViewModels;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Category;
public class IndexModel(CategorysApplication categorysApplication) : PageModel
{
public List<CategoryViewModel> category { get; set; } = new();
public async Task OnGetAsync()
{
category = await categorysApplication.GetAllAsync();
}
}

View File

@ -0,0 +1,38 @@
@page
@model Server.Pages.Panel.Category.UpdateModel
@{
var pageTitle =
$"{Resources.DataDictionary.CreateOf} {Resources.DataDictionary.Category}";
ViewData[Constants.ViewDataKeyName.PageTitle] = pageTitle;
}
<form method="post">
<section-form>
<fieldset>
<section-form-header>
@(pageTitle)
</section-form-header>
<partial name="PartialViews/_DisplayPageMessages" />
<input hidden asp-for="UpdateViewModel.Id" />
<ub-full-input asp-for="UpdateViewModel.Name" />
<ub-full-input asp-for="UpdateViewModel.Description" />
<ub-full-checkbox asp-for="UpdateViewModel.IsActive" />
</fieldset>
<section-form-buttons>
<button-save />
<button-reset />
</section-form-buttons>
</section-form>
</form>

View File

@ -0,0 +1,43 @@
using Application.Aggregates.Categorys;
using Application.Aggregates.Categorys.ViewModels;
using Application.Aggregates.Products;
using Application.Aggregates.Products.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Category;
public class UpdateModel(CategorysApplication categorysApplication) : PageModel
{
[BindProperty]
public CategoryViewModel UpdateViewModel { get; set; }
public async Task<IActionResult> OnGetAsync(Guid id)
{
if (id == Guid.Empty)
{
return RedirectToPage("Index");
}
UpdateViewModel =
await categorysApplication.GetAsync(id);
if (UpdateViewModel == null)
{
return RedirectToPage("Index");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (ModelState.IsValid)
{
await categorysApplication.UpdateAsync(UpdateViewModel);
}
return RedirectToPage("Index");
}
}

View File

@ -0,0 +1,42 @@
@page
@model Server.Pages.Panel.Products.CreateModel
@{
var pageTitle =
$"{Resources.DataDictionary.CreateOf} {Resources.DataDictionary.Product}";
ViewData[Constants.ViewDataKeyName.PageTitle] = pageTitle;
}
}
<form method="post">
<section-form>
<fieldset>
<section-form-header>
@(pageTitle)
</section-form-header>
<partial name="PartialViews/_DisplayPageMessages" />
<ub-full-input asp-for="createProductView.Name" />
<ub-full-input asp-for="createProductView.Description" />
<ub-full-input asp-for="createProductView.Price" />
<ub-full-input asp-for="createProductView.Quantity" />
<ub-full-checkbox asp-for="createProductView.IsActive" />
</fieldset>
<section-form-buttons>
<button-create />
<button-reset />
</section-form-buttons>
</section-form>
</form>

View File

@ -0,0 +1,30 @@
using Application.Aggregates.Products;
using Application.Aggregates.Products.ViewModels;
using Application.Aggregates.Stores;
using Application.Aggregates.Stores.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Products;
public class CreateModel(ProductsApplication productsApplication) : PageModel
{
[BindProperty]
public CreateProductViewModel createProductView { get; set; }
public void OnGet()
{
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
await productsApplication.CreateAsync(createProductView);
return RedirectToPage("Index");
}
}

View File

@ -0,0 +1,41 @@
@page
@model Server.Pages.Panel.Products.DeleteModel
@{
var pageTitle =
$"{Resources.DataDictionary.CreateOf} {Resources.DataDictionary.Product}";
ViewData[Constants.ViewDataKeyName.PageTitle] = pageTitle;
}
<form method="post">
<section-form>
<input hidden asp-for="DeleteViewModel.Id" dir="ltr" />
<fieldset disabled>
<section-form-header>
@(pageTitle)
</section-form-header>
<partial name="PartialViews/_DisplayPageMessages" />
<ub-full-input asp-for="DeleteViewModel.Name" />
<ub-full-input asp-for="DeleteViewModel.Description" />
<ub-full-input asp-for="DeleteViewModel.Price" />
<ub-full-input asp-for="DeleteViewModel.Quantity" />
<ub-full-checkbox asp-for="DeleteViewModel.IsActive" />
</fieldset>
<section-form-buttons>
<button-delete />
</section-form-buttons>
</section-form>
</form>

View File

@ -0,0 +1,39 @@
using Application.Aggregates.Products;
using Application.Aggregates.Products.ViewModels;
using Application.Aggregates.Stores;
using Application.Aggregates.Stores.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Products;
public class DeleteModel(ProductsApplication productsApplication) : PageModel
{
[BindProperty]
public ProductViewModel DeleteViewModel { get; set; } = new();
public async Task<IActionResult> OnGetAsync(Guid id)
{
if (id == Guid.Empty)
{
return RedirectToPage("Index");
}
DeleteViewModel =
await productsApplication.GetAsync(id);
if (DeleteViewModel == null)
{
return RedirectToPage("Index");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
await productsApplication.DeleteAsync(DeleteViewModel.Id);
return RedirectToPage("Index");
}
}

View File

@ -0,0 +1,37 @@
@page
@model Server.Pages.Panel.Products.IndexModel
@{
}
<div class="my-2 float-end">
<a class="btn btn-primary" asp-page="Create">@(Resources.ButtonCaptions.Create)</a>
</div>
<table class="table table-hover">
<thead>
<tr>
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.Name))
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.Description))
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.Price))
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.Quantity))
@(Html.Ub_DisplayStringWithTh(Resources.DataDictionary.IsActive))
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.product)
{
<tr>
@(Html.Ub_DisplayStringWithTd(item.Name))
@(Html.Ub_DisplayStringWithTd(item.Description))
@(Html.Ub_DisplayIntegerWithTd(item.Price))
@(Html.Ub_DisplayIntegerWithTd(item.Quantity))
@(Html.Ub_DisplayBooleanWithTd(item.IsActive))
<td>
<div class="btn-group" role="group" aria-label="Basic example">
<a asp-page="Update" asp-route-Id="@(item.Id)" class="btn btn-warning">@(Resources.ButtonCaptions.Edit)</a>
<a asp-page="Delete" asp-route-Id="@(item.Id)" class="btn btn-danger">@(Resources.ButtonCaptions.Delete)</a>
</div>
</td>
</tr>
}
</tbody>
</table>

View File

@ -0,0 +1,20 @@
using Application.Aggregates.Products;
using Application.Aggregates.Products.ViewModels;
using Application.Aggregates.Stores;
using Application.Aggregates.Stores.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Products
{
public class IndexModel(ProductsApplication productsApplication) : PageModel
{
public List<ProductViewModel> product { get; set; } = new();
public async Task OnGetAsync()
{
product = await productsApplication.GetStors();
}
}
}

View File

@ -0,0 +1,42 @@
@page
@model Server.Pages.Panel.Products.UpdateModel
@{
var pageTitle =
$"{Resources.DataDictionary.CreateOf} {Resources.DataDictionary.Product}";
ViewData[Constants.ViewDataKeyName.PageTitle] = pageTitle;
}
<form method="post">
<section-form>
<fieldset>
<section-form-header>
@(pageTitle)
</section-form-header>
<partial name="PartialViews/_DisplayPageMessages" />
<input hidden asp-for="UpdateViewModel.Id" />
<ub-full-input asp-for="UpdateViewModel.Name" />
<ub-full-input asp-for="UpdateViewModel.Description" />
<ub-full-input asp-for="UpdateViewModel.Price" />
<ub-full-input asp-for="UpdateViewModel.Quantity" />
<ub-full-checkbox asp-for="UpdateViewModel.IsActive" />
</fieldset>
<section-form-buttons>
<button-save />
<button-reset />
</section-form-buttons>
</section-form>
</form>

View File

@ -0,0 +1,42 @@
using Application.Aggregates.Products;
using Application.Aggregates.Products.ViewModels;
using Application.Aggregates.Stores;
using Application.Aggregates.Stores.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Server.Pages.Panel.Products;
public class UpdateModel(ProductsApplication productsApplication) : PageModel
{
[BindProperty]
public ProductViewModel UpdateViewModel { get; set; }
public async Task<IActionResult> OnGetAsync(Guid id)
{
if (id == Guid.Empty)
{
return RedirectToPage("Index");
}
UpdateViewModel =
await productsApplication.GetAsync(id);
if (UpdateViewModel == null)
{
return RedirectToPage("Index");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (ModelState.IsValid)
{
await productsApplication.UpdateAsync(UpdateViewModel);
}
return RedirectToPage("Index");
}
}

View File

@ -1,9 +1,15 @@
using Application.Aggregates.Categorys;
using Application.Aggregates.Products;
using Application.Aggregates.Stores;
using Application.Aggregates.Users;
using Domain.Aggregates.Categorys.Data;
using Domain.Aggregates.Products.Data;
using Domain.Aggregates.Stores.Data;
using Domain.Aggregates.Users.Data;
using Microsoft.EntityFrameworkCore;
using Persistence;
using Persistence.Repositories.Aggregates.Categorys;
using Persistence.Repositories.Aggregates.Products;
using Persistence.Repositories.Aggregates.Stores;
using Persistence.Repositories.Aggregates.Users;
using Server.Infrastructure.Extensions.ServiceCollections;
@ -34,6 +40,12 @@ public class Program
builder.Services.AddScoped<IStoreRepository, StoreRepository>();
builder.Services.AddScoped<StoresApplication>();
builder.Services.AddScoped<IProductRepository, ProductRepository>();
builder.Services.AddScoped<ProductsApplication>();
builder.Services.AddScoped<ICategoryRepository, CategoryRepository>();
builder.Services.AddScoped<CategorysApplication>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())