добавил count для добавления нескольких продаж сотруднику, а также реализовал CRUD операции для сотрудника и продаж

This commit is contained in:
Stepan 2024-05-28 20:07:08 +04:00
parent 80973fc18d
commit b19595c0c1
29 changed files with 866 additions and 247 deletions

View File

@ -2,7 +2,6 @@ using CarCenterBusinessLogic.BusinessLogics;
using CarCenterContracts.BusinessLogicsContracts;
using CarCenterContracts.StoragesContracts;
using CarCenterDataBaseImplement.Implements;
using CarCenterDataBaseImplement.Implemets;
using AdministratorApp;
using Microsoft.Extensions.Options;

View File

@ -145,7 +145,7 @@
var totalcars = $('#carsTable tbody tr').length;
if (totalcars == 0) {
alert('Пожалуйста, добавьте хотя бы одну деталь.');
alert('Пожалуйста, добавьте хотя бы одну машину.');
isValid = false;
}

View File

@ -14,6 +14,6 @@ namespace CarCenterContracts.BindingModels
public int ManagerId { get; set; }
public Dictionary<int, ISaleModel> EmployeeSales { get; set; } = new();
public Dictionary<int, (ISaleModel, int)>? EmployeeSales { get; set; } = new();
}
}

View File

@ -19,6 +19,6 @@ namespace CarCenterContracts.ViewModels
public int ManagerId { get; set; }
public Dictionary<int, ISaleModel> EmployeeSales { get; set; } = new();
public Dictionary<int, (ISaleModel, int)>? EmployeeSales { get; set; } = new();
}
}

View File

@ -14,7 +14,7 @@ namespace CarCenterContracts.ViewModels
public double SalePrice { get; set; }
[DisplayName("Дата продажи")]
public DateTime DateCreate { get; set; }
public DateTime DateCreate { get; set; } = DateTime.Now;
public int ManagerId { get; set; }
}

View File

@ -5,7 +5,7 @@ using CarCenterContracts.ViewModels;
using CarCenterDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace CarCenterDataBaseImplement.Implemets
namespace CarCenterDataBaseImplement.Implements
{
public class EmployeeStorage : IEmployeeStorage
{

View File

@ -5,7 +5,7 @@ using CarCenterContracts.ViewModels;
using CarCenterDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace CarCenterDataBaseImplement.Implemets
namespace CarCenterDataBaseImplement.Implements
{
public class ManagerStorage : IManagerStorage
{

View File

@ -5,7 +5,7 @@ using CarCenterContracts.ViewModels;
using CarCenterDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace CarCenterDataBaseImplement.Implemets
namespace CarCenterDataBaseImplement.Implements
{
public class PreSaleWorkStorage : IPreSaleWorkStorage
{

View File

@ -5,7 +5,7 @@ using CarCenterContracts.ViewModels;
using CarCenterDataBaseImplement.Models;
using Microsoft.EntityFrameworkCore;
namespace CarCenterDataBaseImplement.Implemets
namespace CarCenterDataBaseImplement.Implements
{
public class SaleStorage : ISaleStorage
{

View File

@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace CarCenterDataBaseImplement.Migrations
{
[DbContext(typeof(CarCenterDataBase))]
[Migration("20240528110830_InitialCreate")]
[Migration("20240528154442_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
@ -179,6 +179,9 @@ namespace CarCenterDataBaseImplement.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("EmployeeId")
.HasColumnType("int");

View File

@ -223,7 +223,8 @@ namespace CarCenterDataBaseImplement.Migrations
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
SaleId = table.Column<int>(type: "int", nullable: false),
EmployeeId = table.Column<int>(type: "int", nullable: false)
EmployeeId = table.Column<int>(type: "int", nullable: false),
Count = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{

View File

@ -176,6 +176,9 @@ namespace CarCenterDataBaseImplement.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("EmployeeId")
.HasColumnType("int");

View File

@ -3,6 +3,7 @@ using CarCenterContracts.ViewModels;
using CarCenterDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Intrinsics.Arm;
using System.Text.Json.Serialization;
namespace CarCenterDataBaseImplement.Models
@ -26,16 +27,16 @@ namespace CarCenterDataBaseImplement.Models
[ForeignKey("EmployeeId")]
public virtual List<EmployeeSale> Sales { get; set; } = new();
private Dictionary<int, ISaleModel> _employeeSales = null;
private Dictionary<int, (ISaleModel , int)>? _employeeSales = null;
[NotMapped]
public Dictionary<int, ISaleModel> EmployeeSales
public Dictionary<int, (ISaleModel, int)>? EmployeeSales
{
get
{
if (_employeeSales == null)
{
_employeeSales = Sales.ToDictionary(recDP => recDP.SaleId, recDp => recDp.Sale as ISaleModel);
_employeeSales = Sales.ToDictionary(recDP => recDP.SaleId, recDp => (recDp.Sale as ISaleModel, recDp.Count));
}
return _employeeSales;
}
@ -53,6 +54,7 @@ namespace CarCenterDataBaseImplement.Models
Sales = model.EmployeeSales.Select(x => new EmployeeSale
{
Sale = context.Sales.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList()
};
}
@ -85,7 +87,11 @@ namespace CarCenterDataBaseImplement.Models
foreach (var updateSale in EmployeeSales)
{
model.EmployeeSales.Remove(updateSale.SaleId);
if (model.EmployeeSales.ContainsKey(updateSale.SaleId))
{
updateSale.Count = model.EmployeeSales[updateSale.SaleId].Item2;
model.EmployeeSales.Remove(updateSale.SaleId);
}
}
context.SaveChanges();
}
@ -97,6 +103,7 @@ namespace CarCenterDataBaseImplement.Models
{
Employee = Employee,
Sale = context.Sales.First(x => x.Id == cm.Key),
Count = cm.Value.Item2
});
context.SaveChanges();
}

View File

@ -11,6 +11,8 @@ namespace CarCenterDataBaseImplement.Models
[Required]
public int EmployeeId { get; set; }
[Required]
public int Count { get; set; }
public virtual Employee Employee { get; set; } = new();
public virtual Sale Sale { get; set; } = new();

View File

@ -6,6 +6,12 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.26" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CarCenterBusinessLogic\CarCenterBusinessLogic.csproj" />
<ProjectReference Include="..\CarCenterContracts\CarCenterContracts.csproj" />

View File

@ -1,200 +1,358 @@
using CarCenterManagerAPP.Models;
using ManagerApp.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using CarCenterBusinessLogic.BusinessLogics;
using CarCenterContracts.BusinessLogicsContracts;
using CarCenterContracts.ViewModels;
using CarCenterDataModels.Models;
using CarCenterContracts.BindingModels;
using CarCenterDataBaseImplement.Models;
namespace ImplementerApp.Controllers
namespace ManagerApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IEmployeeLogic _employeeLogic;
private readonly IManagerLogic _managerLogic;
private readonly IPreSaleWorkLogic _presaleworkLogic;
private readonly ISaleLogic _saleLogic;
public HomeController(ILogger<HomeController> logger)
private readonly ManagerData _data;
public HomeController(ILogger<HomeController> logger, ManagerData data)
{
_logger = logger;
_data = data;
}
private bool IsLoggedIn { get { return UserManager.manager != null; } }
private int ManagerId { get { return UserManager.manager!.Id; } }
public IActionResult IndexNonReg()
{
if (!IsLoggedIn)
return View();
return RedirectToAction("Index");
}
public IActionResult Index()
{
if (!IsLoggedIn)
return RedirectToAction("IndexNonReg");
return View();
}
[HttpGet]
public IActionResult Enter()
{
return View();
if (!IsLoggedIn)
return View();
return RedirectToAction("Index");
}
[HttpPost]
public void Enter(string login, string password)
{
var Manager = _data.Login(login, password);
if (Manager != null)
{
UserManager.manager = Manager;
Response.Redirect("Index");
}
}
[HttpGet]
public IActionResult Register()
{
return View();
}
public IActionResult IndexEmployee()
public IActionResult Logout()
{
List<EmployeeViewModel> Employee = new List<EmployeeViewModel>();
Employee.Add(new EmployeeViewModel
{
Id = 1,
EmployeeFIO = "EmployeeFIO1",
EmployeePost = "EmployeePost1",
EmployeeSalary = 500.0,
ManagerId = 1,
EmployeeSales = new()
});
Employee.Add(new EmployeeViewModel
{
Id = 2,
EmployeeFIO = "EmployeeFIO2",
EmployeePost = "EmployeePost2",
EmployeeSalary = 5100.0,
ManagerId = 2,
EmployeeSales = new()
});
return View(Employee);
UserManager.manager = null;
return RedirectToAction("IndexNonReg");
}
public IActionResult CreateEmployee()
[HttpPost]
public void Register(string fio, string login, string email, string number, string password1, string password2)
{
List<SaleViewModel> Sales = new List<SaleViewModel>();
Sales.Add(new SaleViewModel
if (password1 == password2 && _data.Register(new() { ManagerEmail = email, ManagerLogin = login, ManagerFIO = fio, ManagerNumber = number, ManagerPassword = password1 }))
{
Id = 1,
SaleName = "Sale1",
SalePrice = 100.5,
DateCreate = DateTime.Now,
ManagerId = 1,
});
Sales.Add(new SaleViewModel
{
Id = 2,
SaleName = "Sale2",
SalePrice = 600.0,
DateCreate = DateTime.Now,
ManagerId = 2,
});
return View(Sales);
}
public IActionResult IndexPreSaleWork()
{
List<PreSaleWorkViewModel> work = new List<PreSaleWorkViewModel>();
work.Add(new PreSaleWorkViewModel
{
Id = 1,
PreSaleWorkType = "PreSaleWork1",
PreSaleWorkDate = DateTime.Now,
PreSaleWorkPrice = 50000.9,
ManagerId = 1,
CompletionsId = 1,
PreSaleWorkSales = new()
});
work.Add(new PreSaleWorkViewModel
{
Id = 2,
PreSaleWorkType = "PreSaleWork2",
PreSaleWorkDate = DateTime.Now,
PreSaleWorkPrice = 100000.9,
ManagerId = 2,
CompletionsId = 2,
PreSaleWorkSales = new()
});
return View(work);
}
public IActionResult CreatePreSaleWork()
{
List<SaleViewModel> Sales = new List<SaleViewModel>();
Sales.Add(new SaleViewModel
{
Id = 1,
SaleName = "Sale1",
SalePrice = 100.5,
DateCreate = DateTime.Now,
ManagerId = 1,
});
Sales.Add(new SaleViewModel
{
Id = 2,
SaleName = "Sale2",
SalePrice = 600.0,
DateCreate = DateTime.Now,
ManagerId = 2,
});
return View(Sales);
Response.Redirect("Index");
}
}
[HttpGet]
public IActionResult IndexSale()
{
List<SaleViewModel> Sales = new List<SaleViewModel>();
Sales.Add(new SaleViewModel
if (UserManager.manager != null)
{
Id = 1,
SaleName = "Sale1",
SalePrice = 100.5,
DateCreate = DateTime.Now,
ManagerId = 1,
});
Sales.Add(new SaleViewModel
var list = _data.GetSales(UserManager.manager.Id);
if (list != null)
return View(list);
return View(new List<SaleViewModel>());
}
return RedirectToAction("IndexNonReg");
}
[HttpPost]
public void IndexSale(int id)
{
if (UserManager.manager != null)
{
Id = 2,
SaleName = "Sale2",
SalePrice = 600.0,
DateCreate = DateTime.Now,
ManagerId = 2,
});
return View(Sales);
_data.DeleteSale(id);
}
Response.Redirect("IndexSale");
}
public IActionResult CreateSale()
[HttpGet]
public IActionResult CreateSale(int id)
{
return View();
}
public IActionResult Privacy()
{
return View();
if (id != 0)
{
var value = _data.GetSale(id);
if (value != null)
return View(value);
}
return View(new SaleViewModel());
}
[HttpPost]
public IActionResult CreateSale(SaleBindingModel model)
{
if (ModelState.IsValid)
{
if (model.Id == 0)
{
model.DateCreate = DateTime.Now;
model.ManagerId = UserManager.manager!.Id;
if (_data.CreateSale(model))
return RedirectToAction("IndexSale");
}
else
{
if (_data.UpdateSale(model))
return RedirectToAction("IndexSale");
}
}
return View(model);
}
[HttpGet]
public IActionResult IndexPreSaleWork()
{
if (IsLoggedIn)
{
var PreSaleWorks = _data.GetPreSaleWorks(UserManager.manager!.Id);
return View(PreSaleWorks);
}
return RedirectToAction("IndexNonReg");
}
[HttpPost]
public IActionResult IndexPreSaleWork(int id)
{
_data.DeletePreSaleWork(id);
return RedirectToAction("IndexPreSaleWork");
}
[HttpGet]
public IActionResult CreatePreSaleWork(int id)
{
var Sale = _data.GetSale(UserManager.manager!.Id);
ViewBag.AllSale = Sale;
if (id != 0)
{
var value = _data.GetPreSaleWork(id);
if (value != null)
return View(value);
}
return View(new PreSaleWorkViewModel());
}
[HttpPost]
public IActionResult CreatePreSaleWork(int id, string type, DateTime date, int[] SaleIds)
{
PreSaleWorkBindingModel model = new PreSaleWorkBindingModel();
model.Id = id;
model.PreSaleWorkType = type;
model.PreSaleWorkDate = date;
model.ManagerId = UserManager.manager!.Id;
var Sale = _data.GetSales(UserManager.manager!.Id);
double sum = 0;
for (int i = 0; i < SaleIds.Length; i++)
{
var sale = Sale!.FirstOrDefault(x => x.Id == SaleIds[i])!;
model.PreSaleWorkSales[SaleIds[i]] = (sale);
sum += sale.SalePrice;
}
model.PreSaleWorkPrice = sum;
if (id != 0)
{
_data.UpdatePreSaleWork(model);
}
else
{
_data.CreatePreSaleWork(model);
}
return RedirectToAction("IndexPreSaleWork");
}
[HttpGet]
public IActionResult IndexEmployee()
{
if (UserManager.manager != null)
{
var Employees = _data.GetEmployees(UserManager.manager.Id);
return View(Employees);
}
return RedirectToAction("IndexNonReg");
}
[HttpPost]
public IActionResult IndexEmployee(int id)
{
_data.DeleteEmployee(id);
return RedirectToAction("IndexEmployee");
}
[HttpGet]
public IActionResult CreateEmployee(int id)
{
var Sale = _data.GetSales(UserManager.manager!.Id);
ViewBag.AllSale = Sale;
if (id != 0)
{
var value = _data.GetEmployee(id);
if (value != null)
{
return View(value);
}
}
return View(new EmployeeViewModel());
}
[HttpPost]
public IActionResult CreateEmployee(int id, string fio, string post, int[] SaleIds, int[] counts)
{
EmployeeBindingModel model = new EmployeeBindingModel();
model.Id = id;
model.EmployeeFIO = fio;
model.EmployeePost = post;
model.ManagerId = UserManager.manager!.Id;
var Sale = _data.GetSales(UserManager.manager!.Id);
double sum = 0;
for (int i = 0; i < SaleIds.Length; i++)
{
var sale = Sale!.FirstOrDefault(x => x.Id == SaleIds[i])!;
if (counts[i] <= 0)
continue;
model.EmployeeSales[SaleIds[i]] = (sale, counts[i]);
sum += sale.SalePrice * counts[i];
}
model.EmployeeSalary = sum;
bool changed = false;
if (model.EmployeeSales.Count > 0)
{
if (id != 0)
{
changed = _data.UpdateEmployee(model);
}
else
{
changed = _data.CreateEmployee(model);
}
}
if (changed)
return RedirectToAction("IndexEmployee");
else
{
ViewBag.AllSale = Sale;
return RedirectToAction("IndexEmployee");
}
}
[HttpGet]
public IActionResult Privacy()
{
if (IsLoggedIn)
return View(UserManager.manager);
return RedirectToAction("IndexNonReg");
}
[HttpPost]
public IActionResult Privacy(int id, string login, string email, string password, string fio, string number)
{
if (!IsLoggedIn)
return RedirectToAction("IndexNonReg");
ManagerBindingModel user = new() { Id = id, ManagerLogin = login, ManagerEmail = email, ManagerPassword = password, ManagerFIO = fio, ManagerNumber = number };
if (_data.UpdateUser(user))
{
UserManager.manager = new ManagerViewModel { Id = id, ManagerLogin = login, ManagerPassword = password, ManagerFIO = fio, ManagerEmail = email, ManagerNumber = number };
}
return View(user);
}
[HttpGet]
public IActionResult SaleDateChoose()
{
if (!IsLoggedIn)
return RedirectToAction("IndexNonReg");
return View();
}
[HttpPost]
public IActionResult SendReport(DateTime startDate, DateTime endDate)
{
return Ok();
}
[HttpPost]
public IActionResult TimeReportWeb(DateTime startDate, DateTime endDate)
{
if (!IsLoggedIn)
return RedirectToAction("IndexNonReg");
HttpContext.Session.SetString("StartDate", startDate.ToString());
HttpContext.Session.SetString("EndDate", endDate.ToString());
return RedirectToAction("CarsPeriodReport");
}
[HttpGet]
public IActionResult SalesPeriodReport()
{
var startDateStr = HttpContext.Session.GetString("StartDate");
var endDateStr = HttpContext.Session.GetString("EndDate");
var startDate = DateTime.Parse(startDateStr);
var endDate = DateTime.Parse(endDateStr).AddDays(1);
var values = _data.GetTimeReport(startDate, endDate, ManagerId);
ViewBag.StartDate = startDate;
ViewBag.EndDate = endDate;
return View(values);
}
public IActionResult SalesInspectionsReport()
{
List<SalesInspectionsReportViewModel> SalesInspectionsReport = new List<SalesInspectionsReportViewModel>
{
new SalesInspectionsReportViewModel
{
SaleName = "продажа 1",
Inspections = new List<string> { "Осмотр 1", "Осмотр 2" }
},
new SalesInspectionsReportViewModel
{
SaleName = "продажа 2",
Inspections = new List<string> { "Осмотр 3", "Осмотр 4" }
}
};
return View(SalesInspectionsReport);
}
public IActionResult ReportsMenu()
{
return View();
}
public IActionResult SalesInspectionsReport()
[HttpGet]
public IActionResult PreSaleWorkCompletionsAdd(int id)
{
List<SalesInspectionsReportViewModel> SaleInspectionReports = new List<SalesInspectionsReportViewModel>
{
new SalesInspectionsReportViewModel
{
SaleName = "SaleName1",
Inspections = new List<string> { "Inspections1", "Inspections2" },
},
new SalesInspectionsReportViewModel
{
SaleName = "SaleName2",
Inspections = new List<string> { "Inspections3", "Inspections4" },
}
};
return View(SaleInspectionReports);
if (!IsLoggedIn)
return RedirectToAction("IndexNonReg");
var PreSaleWork = _data.GetPreSaleWork(id);
ViewBag.PreSaleWork = PreSaleWork;
var Completions = _data.GetCompletions();
return View(Completions);
}
public IActionResult SalesPeriodReport()
[HttpPost]
public IActionResult PreSaleWorkCompletionsAdd(int PreSaleWorkId, int CompletionsId)
{
List<SalesPeriodReportViewModel> SalePeriodReports = new List<SalesPeriodReportViewModel>
{
new SalesPeriodReportViewModel
{
SaleName = "SaleName1",
Employee = new List<string> { "Employee1", "Employee2"},
},
new SalesPeriodReportViewModel
{
SaleName = "SaleName2",
Employee = new List<string> { "Employee3", "Employee4"},
}
};
return View(SalePeriodReports);
if (!IsLoggedIn)
return RedirectToAction("IndexNonReg");
var PreSaleWork = _data.GetPreSaleWork(PreSaleWorkId);
if (PreSaleWork == null)
return RedirectToAction("Index");
PreSaleWorkBindingModel PreSaleWorkBinding = new() { Id = PreSaleWorkId, PreSaleWorkPrice = PreSaleWork.PreSaleWorkPrice, PreSaleWorkType = PreSaleWork.PreSaleWorkType, ManagerId = PreSaleWork.ManagerId, PreSaleWorkSales = PreSaleWork.PreSaleWorkSales, CompletionsId = CompletionsId };
_data.UpdatePreSaleWork(PreSaleWorkBinding);
return RedirectToAction("IndexPreSaleWork");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]

View File

@ -0,0 +1,135 @@
using CarCenterContracts.BusinessLogicsContracts;
using CarCenterContracts.ViewModels;
using CarCenterContracts.BindingModels;
using CarCenterContracts.StoragesContracts;
using CarCenterContracts.SearchModels;
using CarCenterDataBaseImplement.Models;
namespace ManagerApp
{
public class ManagerData
{
private readonly ILogger _logger;
private readonly IManagerLogic _ManagerLogic;
private readonly ISaleLogic _SaleLogic;
private readonly ICompletionsLogic _completionsLogic;
private readonly IPreSaleWorkLogic _PreSaleWorkLogic;
private readonly IEmployeeLogic _employeeLogic;
public ManagerData(ILogger<ManagerData> logger, IManagerLogic ManagerLogic, ISaleLogic SaleLogic, ICompletionsLogic CompletionsLogic, IPreSaleWorkLogic PreSaleWorkLogic, IEmployeeLogic EmployeeLogic)
{
_logger = logger;
_ManagerLogic = ManagerLogic;
_SaleLogic = SaleLogic;
_completionsLogic = CompletionsLogic;
_PreSaleWorkLogic = PreSaleWorkLogic;
_employeeLogic = EmployeeLogic;
}
public ManagerViewModel? Login(string login, string password)
{
return _ManagerLogic.ReadElement(new()
{
ManagerLogin = login,
ManagerPassword = password
});
}
public bool Register(ManagerBindingModel model)
{
return _ManagerLogic.Create(model);
}
public bool UpdateUser(ManagerBindingModel model)
{
return _ManagerLogic.Update(model);
}
public List<SaleViewModel>? GetSales(int ManagerId)
{
return _SaleLogic.ReadList(new SaleSearchModel() { ManagerId = ManagerId });
}
public bool DeleteSale(int SaleId)
{
return _SaleLogic.Delete(new() { Id = SaleId });
}
public bool CreateSale(SaleBindingModel model)
{
return _SaleLogic.Create(model);
}
public bool UpdateSale(SaleBindingModel model)
{
return _SaleLogic.Update(model);
}
public SaleViewModel? GetSale(int id)
{
return _SaleLogic.ReadElement(new() { Id= id });
}
public List<PreSaleWorkViewModel>? GetPreSaleWorks(int ManagerId)
{
return _PreSaleWorkLogic.ReadList(new PreSaleWorkSearchModel() { ManagerId = ManagerId });
}
public PreSaleWorkViewModel? GetPreSaleWork(int id)
{
return _PreSaleWorkLogic.ReadElement(new() { Id = id });
}
public bool UpdatePreSaleWork(PreSaleWorkBindingModel model)
{
return _PreSaleWorkLogic.Update(model);
}
public bool DeletePreSaleWork(int PreSaleWorkId)
{
return _PreSaleWorkLogic.Delete(new() { Id = PreSaleWorkId });
}
public bool CreatePreSaleWork(PreSaleWorkBindingModel model)
{
return _PreSaleWorkLogic.Create(model);
}
public List<EmployeeViewModel>? GetEmployees(int ManagerId)
{
return _employeeLogic.ReadList(new() { ManagerId = ManagerId });
}
public EmployeeViewModel? GetEmployee(int id)
{
return _employeeLogic.ReadElement(new() { Id = id });
}
public bool CreateEmployee(EmployeeBindingModel model)
{
return _employeeLogic.Create(model);
}
public bool UpdateEmployee(EmployeeBindingModel model)
{
return _employeeLogic.Update(model);
}
public bool DeleteEmployee(int EmployeeId)
{
return _employeeLogic.Delete(new() { Id = EmployeeId });
}
public List<CompletionsViewModel>? GetCompletions()
{
return _completionsLogic.ReadList(null);
}
public List<SalesPeriodReportViewModel> GetTimeReport(DateTime? startDate, DateTime? endDate, int ManagerId)
{
var Sale = _SaleLogic.ReadList(new() { DateFrom = startDate, DateTo = endDate, ManagerId = ManagerId });
if (Sale == null)
return new();
List<SalesPeriodReportViewModel> SalePeriodReports = new List<SalesPeriodReportViewModel>();
foreach (var sale in Sale)
{
var report = new SalesPeriodReportViewModel();
report.SaleName = sale.SaleName;
var PreSaleWorks = _PreSaleWorkLogic.ReadList(new() { SalesId = sale.Id, ManagerId = ManagerId });
if (PreSaleWorks != null)
report.PreSaleWork = PreSaleWorks.Select(p => p.PreSaleWorkType).ToList();
var Employee = _employeeLogic.ReadList(new() { SaleId = sale.Id, ManagerId = ManagerId });
if (Employee != null)
report.Employee = Employee.Select(p => p.EmployeeFIO).ToList();
SalePeriodReports.Add(report);
}
return SalePeriodReports;
}
}
}

View File

@ -1,4 +1,4 @@
namespace CarCenterManagerAPP.Models
namespace ManagerApp.Models
{
public class ErrorViewModel
{

View File

@ -1,27 +1,53 @@
using CarCenterBusinessLogic.BusinessLogics;
using CarCenterContracts.BusinessLogicsContracts;
using CarCenterContracts.StoragesContracts;
using CarCenterDataBaseImplement.Implements;
using ManagerApp;
using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config");
builder.Services.AddTransient<IManagerStorage, ManagerStorage>();
builder.Services.AddTransient<ISaleStorage, SaleStorage>();
builder.Services.AddTransient<IPreSaleWorkStorage, PreSaleWorkStorage>();
builder.Services.AddTransient<ICompletionsStorage, CompletionsStorage>();
builder.Services.AddTransient<IEmployeeStorage, EmployeeStorage>();
builder.Services.AddTransient<IManagerLogic, ManagerLogic>();
builder.Services.AddTransient<ISaleLogic, SaleLogic>();
builder.Services.AddTransient<IPreSaleWorkLogic, PreSaleWorkLogic>();
builder.Services.AddTransient<ICompletionsLogic, CompletionsLogic>();
builder.Services.AddTransient<IEmployeeLogic, EmployeeLogic>();
builder.Services.AddTransient<ManagerData>();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseSession();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
app.Run();

View File

@ -0,0 +1,9 @@
using CarCenterContracts.ViewModels;
namespace ManagerApp
{
public static class UserManager
{
public static ManagerViewModel? manager { get; set; }
}
}

View File

@ -1,49 +1,71 @@
@using CarCenterContracts.ViewModels
@model List<SaleViewModel>
@model EmployeeViewModel
@{
ViewData["Title"] = "CreateEmployee";
ViewBag.Sales = Model.EmployeeSales;
}
<div class="text-center">
<h2 class="display-4">Создание сотрудника</h2>
</div>
<form method="post">
<div class="row mb-3">
<form id="EmployeeForm" method="post">
<div class="row">
<div class="col-4">ФИО сотрудника:</div>
<div class="col-8"><input type="text" name="employeefio" id="employeefio" /></div>
</div>
<div class="row mb-3">
<div class="col-8">
<input type="text" name="fio" id="fio" value="@Model.EmployeeFIO" />
<span id="titleError" class="text-danger"></span>
</div>
<div class="col-4">Должность сотрудника:</div>
<div class="col-8"><input type="text" name="employeepost" id="employeepost" /></div>
</div>
<div class="row mb-3">
<div class="col-4">Заработная плата:</div>
<div class="col-8"><input type="text" name="employeesalary" id="employeesalary" /></div>
<div class="col-8">
<input type="text" name="post" id="post" value="@Model.EmployeePost" />
<span id="titleError" class="text-danger"></span>
</div>
</div>
<div class="container">
<div>Sales</div>
<div>Продажи</div>
<div class="table-responsive-lg">
<table id="SaleTable" class="display">
<table id="SalesTable" class="display">
<thead>
<tr>
<th>Выбор</th>
<th>Название</th>
<th>Количество</th>
<th>Стоимость</th>
<th>Удалить</th>
</tr>
</thead>
<tbody>
@foreach (var sales in Model)
@foreach (var Sale in ViewBag.Sales)
{
<tr>
<tr data-Sale-id="@Sale.Value.Item1.Id">
<td>
<input type="checkbox" name="sale" value="@sales.Id" />
<input type="hidden" name="SaleIds" value="@Sale.Key" />
@Sale.Value.Item1.SaleName
</td>
<td>
<input type="number" name="counts" value="@Sale.Value.Item2" min="0" class="form-control sale-count" data-cost="@Sale.Value.Item1.SalePrice" />
</td>
<td>@Sale.Value.Item1.SalePrice</td>
<td>
<button type="button" class="deleteSale" data-Sale-id="@Sale.Value.Item1.Id">Удалить</button>
</td>
<td>@sales.SaleName</td>
</tr>
}
</tbody>
</table>
</div>
<select id="SaleSelect" class="form-control">
<option value="">Выберите продажу</option>
@foreach (var Sale in ViewBag.AllSale)
{
<option value="@Sale.Id" data-cost="@Sale.SalePrice">@Sale.SaleName</option>
}
</select>
<button type="button" id="addSale" class="btn btn-secondary">Добавить продажу</button>
</div>
<div class="row">
<div class="col-4">Сумма:</div>
<div class="col-8"><input type="text" id="sum" name="sum" readonly /></div>
</div>
<div class="row">
<div class="col-8"></div>
@ -55,6 +77,100 @@
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.js"></script>
<script>
$(document).ready(function () {
$('#SaleTable').DataTable();
function updateSum() {
var sum = 0;
$('#SalesTable tbody tr').each(function () {
var count = $(this).find('input[name="counts"]').val();
var cost = $(this).find('input[name="counts"]').data('cost');
sum += count * cost;
});
$('#sum').val(sum.toFixed(2));
}
$(document).on('click', '.deleteSale', function () {
var row = $(this).closest('tr');
row.remove();
updateSum();
});
$(document).on('change', '.sale-count', function () {
updateSum();
});
$('#addSale').click(function () {
var selectedSale = $('#SaleSelect option:selected');
if (selectedSale.val()) {
var SaleId = selectedSale.val();
var SaleName = selectedSale.text();
var SaleCost = selectedSale.data('cost');
var exists = $('#SalesTable tbody tr[data-Sale-id="' + SaleId + '"]').length > 0;
if (exists) {
alert('Эта продажа уже добавлена.');
return;
}
if (exists) {
alert('Эта машина уже добавлена.');
return;
}
var newRow = `
<tr data-Sale-id="${SaleId}">
<td>
<input type="hidden" name="SaleIds" value="${SaleId}" />
${SaleName}
</td>
<td><input type="number" name="counts" value="0" min="1" class="form-control sale-count" data-cost="${SaleCost}" /></td>
<td>${SaleCost}</td>
<td><button type="button" class="deleteSale" data-Sale-id="${SaleId}">Удалить</button></td>
</tr>
`;
$('#SalesTable tbody').append(newRow);
$('.deleteSale').off('click').on('click', function () {
var row = $(this).closest('tr');
row.remove();
updateSum();
});
updateSum();
$('#SaleSelect').val('');
} else {
alert('Выберите продажу для добавления');
}
});
$('#EmployeeForm').submit(function (event) {
var title = $('#title').val();
var isValid = true;
$('#titleError').text('');
if (title.length < 2 || title.length > 50) {
$('#titleError').text('Название должно быть от 2 до 50 символов.');
isValid = false;
}
var totalSales = $('#SalesTable tbody tr').length;
if (totalSales == 0) {
alert('Пожалуйста, добавьте хотя бы одну продажу.');
isValid = false;
}
$('#SalesTable tbody tr').each(function () {
var count = $(this).find('input[name="counts"]').val();
if (count < 1) {
alert('Количество каждой продажи должно быть не менее 1.');
isValid = false;
return false;
}
});
if (!isValid) {
event.preventDefault();
}
});
updateSum();
});
</script>
</script>

View File

@ -1,25 +1,57 @@

@using CarCenterContracts.ViewModels;
@{
ViewData["Title"] = "CreateSale";
ViewData["Title"] = "CreateSale";
}
@model SaleViewModel;
<div class="text-center">
<h2 class="display-4">Создание продажи</h2>
<h2 class="display-4">Продажа</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Название продажи:</div>
<div class="col-8"><input type="text" name="salename" id="salename" /></div>
</div>
<div class="row">
<div class="col-4">Стоимость продажи:</div>
<div class="col-8"><input type="text" name="saleprice" id="saleprice" /></div>
</div>
<div class="row">
<div class="col-4">Дата продажи:</div>
<div class="col-8"><input type="date" name="DateCreate" id="DateCreate" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
</div>
</form>
<form id="SaleForm" method="post">
<input type="text" name="id" id="id" value="@Model.Id" hidden="hidden" />
<div class="row">
<div class="col-4">Название продажи:</div>
<div class="col-8">
<input type="text" name="salename" id="salename" value="@Model.SaleName" />
<span id="nameError" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-4">Стоимость:</div>
<div class="col-8">
<input type="text" name="saleprice" id="saleprice" value="@Model.SalePrice" />
<span id="costError" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
</div>
</form>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function () {
$('#SaleForm').submit(function (event) {
var brand = $('#salename').val();
var cost = $('#saleprice').val();
var isValid = true;
$('#nameError').text('');
$('#costError').text('');
if (brand.length < 2 || brand.length > 50) {
$('#nameError').text('Название должно быть от 2 до 50 символов.');
isValid = false;
}
if (isNaN(cost) || cost <= 0) {
$('#costError').text('Цена должна быть положительным числом.');
isValid = false;
}
if (!isValid) {
event.preventDefault();
}
});
});
</script>

View File

@ -5,9 +5,9 @@
<div class="text-center">
<h1 class="display-4">Приложение "Автоцентр "Корыто". Исполнитель"</h1>
<div class="list-group">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="IndexSale">Продажи</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="IndexEmployee">Сотрудники</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="IndexPreSaleWork">Предпродажные работы</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="IndexSale">Продажи</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="ReportsMenu">Список отчетов</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>

View File

@ -64,7 +64,10 @@
<a asp-action="CreateEmployee" asp-route-id="@item.Id" class="btn btn-primary">Изменить</a>
</td>
<td>
<a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Удалить</a>
<form method="post">
<input type="text" title="id" name="id" value="@item.Id" hidden="hidden" />
<input type="submit" class="btn btn-danger" value="Удалить" />
</form>
</td>
</tr>
}

View File

@ -0,0 +1,10 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<div class="list-group">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Register">Регистрация</a>
</div>
</div>

View File

@ -64,7 +64,10 @@
<a asp-action="CreateSale" asp-route-id="@item.Id" class="btn btn-primary">Изменить</a>
</td>
<td>
<a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Удалить</a>
<form method="post">
<input type="text" title="id" name="id" value="@item.Id" hidden="hidden" />
<input type="submit" class="btn btn-danger" value="Удалить" />
</form>
</td>
</tr>
}

View File

@ -1,29 +1,119 @@
@{
ViewData["Title"] = "Register";
ViewData["Title"] = "Register";
}
<div class="text-center">
<h2 class="display-4">Регистрация</h2>
<h2 class="display-4">Регистрация</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8"><input type="text" name="name" /></div>
</div>
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Почта:</div>
<div class="col-8"><input type="email" name="email" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Регистрация" class="btn btn-primary" /></div>
</div>
</form>
<form id="registerForm" method="post">
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8">
<input type="text" name="fio" id="fio" />
<span id="nameError" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8">
<input type="text" name="login" id="login" />
<span id="loginError" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-4">Почта:</div>
<div class="col-8">
<input type="email" name="email" id="email" />
<span id="emailError" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-4">Номер телефона:</div>
<div class="col-8">
<input type="text" name="number" id="number" />
<span id="numberError" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8">
<input type="password" name="password1" id="password1" />
<span id="password1Error" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-4">Повтор пароля:</div>
<div class="col-8">
<input type="password" name="password2" id="password2" />
<span id="password2Error" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Регистрация" class="btn btn-primary" /></div>
</div>
</form>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function () {
$('#registerForm').submit(function (event) {
var fio = $('#fio').val();
var login = $('#login').val();
var email = $('#email').val();
var number = $('#number').val();
var password1 = $('#password1').val();
var password2 = $('#password2').val();
var isValid = true;
$('#fioError').text('');
$('#loginError').text('');
$('#emailError').text('');
$('#numberError').text('');
$('#password1Error').text('');
$('#password2Error').text('');
// Валидация имени
if (fio.length < 2 || fio.length > 30) {
$('#fioError').text('ФИО должно быть от 2 до 30 символов.');
isValid = false;
}
// Валидация логина
if (login.length < 5 || login.length > 50) {
$('#loginError').text('Логин должен быть от 5 до 50 символов.');
isValid = false;
}
// Валидация почты
var emailPattern = /^[a-zA-Z0-9._-]+@@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
if (!emailPattern.test(email)) {
$('#emailError').text('Неверный формат почты.');
isValid = false;
}
// Валидация номера телефона
var numberPattern = /^\d{11}$/;
if (!numberPattern.test(number)) {
$('#numberError').text('Неверный формат номера телефона.');
isValid = false;
}
// Валидация пароля
if (password1.length < 8 || password1.length > 20) {
$('#password1Error').text('Пароль должен быть от 8 до 20 символов.');
isValid = false;
}
// Проверка совпадения паролей
if (password1 !== password2) {
$('#password2Error').text('Пароли не совпадают.');
isValid = false;
}
if (!isValid) {
event.preventDefault();
}
});
});
</script>

View File

@ -1,3 +1,3 @@
@using CarCenterManagerAPP
@using CarCenterManagerAPP.Models
@using ManagerApp
@using ManagerApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:/temp/GoWorkCourse.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
</layout>
</appender>
<root>
<level value="TRACE" />
<appender-ref ref="RollingFile" />
</root>
</log4net>