PIbd-22_Chernyshev_G.Y._LabWork05_Hard #13

Closed
ujijrujijr wants to merge 23 commits from LabWork05_Hard into LabWork05
3 changed files with 406 additions and 0 deletions
Showing only changes of commit 82f417b9c3 - Show all commits

View File

@ -0,0 +1,243 @@
using GarmentFactoryContracts.SearchModels;
using GarmentFactoryContracts.StoragesContracts;
using GarmentFactoryContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryDatabaseImplement.Models;
namespace GarmentFactoryDatabaseImplement.Implements
{
public class ShopStorage : IShopStorage
{
public List<ShopViewModel> GetFullList()
{
using var context = new GarmentFactoryDatabase();
return context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public List<ShopViewModel> GetFilteredList(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName))
{
return new();
}
using var context = new GarmentFactoryDatabase();
return context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.Where(x => x.ShopName.Contains(model.ShopName))
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public ShopViewModel? GetElement(ShopSearchModel model)
{
if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue)
{
return new();
}
using var context = new GarmentFactoryDatabase();
return context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName)
|| (model.Id.HasValue && x.Id == model.Id))?.GetViewModel;
}
public ShopViewModel? Insert(ShopBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var newShop = Shop.Create(context, model);
if (newShop == null)
{
return null;
}
context.Shops.Add(newShop);
context.SaveChanges();
return newShop.GetViewModel;
}
public ShopViewModel? Update(ShopBindingModel model)
{
using var context = new GarmentFactoryDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
var shop = context.Shops.FirstOrDefault(x => x.Id == model.Id);
if (shop == null)
return null;
shop.Update(model);
context.SaveChanges();
shop.UpdateTextiles(context, model);
transaction.Commit();
return shop.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
public ShopViewModel? Delete(ShopBindingModel model)
{
using var context = new GarmentFactoryDatabase();
var element = context.Shops
.Include(x => x.Textiles)
.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Shops.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
//продажа текстиля из магазинов
public bool Sell(SupplySearchModel model)
{
using var context = new GarmentFactoryDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
//поиск всех магаз-ов, в кот. есть нужный текстиль (сортировка: сначала те, где его больше)
var shopsWithThisTextile = context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.ToList()
.Where(x => x.ShopTextiles.ContainsKey(model.TextileId.Value))
.OrderByDescending(x => x.ShopTextiles[model.TextileId.Value].Item2)
.ToList();
foreach (var shop in shopsWithThisTextile)
{
//сколько надо будет этого текстиля, если продать все из текущего магазина
int thisTextileNeeded = model.Count.Value - shop.ShopTextiles[model.TextileId.Value].Item2;
//если ещё надо будет
if (thisTextileNeeded > 0)
{
//полное удаление этого текстиля из этого магазина
shop.ShopTextiles.Remove(model.TextileId.Value);
shop.DictionaryTextilesUpdate(context);
context.SaveChanges();
model.Count = thisTextileNeeded;
}
else
{
//если в этом магазине ровно столько, сколько надо
if (thisTextileNeeded == 0)
{
shop.ShopTextiles.Remove(model.TextileId.Value);
}
//если в этом магазине больше, чем надо
else
{
//уменьшение в этом магазине этого текстиля на нужное кол-во
var textileAndCount = shop.ShopTextiles[model.TextileId.Value];
textileAndCount.Item2 = -thisTextileNeeded;
shop.ShopTextiles[model.TextileId.Value] = textileAndCount;
}
shop.DictionaryTextilesUpdate(context);
transaction.Commit();
return true;
}
}
transaction.Rollback();
return false;
}
catch
{
transaction.Rollback();
throw;
}
}
//пополнение магазинов текстилем
public bool RestockShops(SupplyBindingModel model)
{
using var context = new GarmentFactoryDatabase();
using var transaction = context.Database.BeginTransaction();
//все магазины, где ещё есть свободное место (занятое кол-во < максимально допустимого)
var shops = context.Shops
.Include(x => x.Textiles)
.ThenInclude(x => x.Textile)
.ToList()
.Where(x => x.ShopTextiles.Select(x => x.Value.Item2).Sum() < x.TextileMaxCount)
.ToList();
try
{
foreach (Shop shop in shops)
{
//свободное место в этом магазине
int freeSpace = shop.TextileMaxCount - shop.ShopTextiles.Select(x => x.Value.Item2).Sum();
//кол-во кот. надо для этого магазина (либо до макс. кол-ва, либо кол-во, кот. осталось в "поставке" (что меньше))
int restock = Math.Min(freeSpace, model.Count);
model.Count -= restock;
//если в этом магазине есть этот текстиль, то изменение его кол-ва
if (shop.ShopTextiles.ContainsKey(model.TextileId))
{
var textileAndCount = shop.ShopTextiles[model.TextileId];
textileAndCount.Item2 += restock;
shop.ShopTextiles[model.TextileId] = textileAndCount;
}
//если нет, то добавление в этом кол-ве
else
{
var textile = context.Textiles.First(x => x.Id == model.TextileId);
shop.ShopTextiles.Add(model.TextileId, (textile, restock));
}
shop.DictionaryTextilesUpdate(context);
//если в "поставке" закончились товары, то всё ок
if (model.Count == 0)
{
transaction.Commit();
return true;
}
}
transaction.Rollback();
return false;
}
catch
{
transaction.Rollback();
throw;
}
}
}
}

View File

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using GarmentFactoryDataModels.Models;
using GarmentFactoryContracts.BindingModels;
using GarmentFactoryContracts.ViewModels;
namespace GarmentFactoryDatabaseImplement.Models
{
public class Shop : IShopModel
{
public int Id { get; set; }
[Required]
public string ShopName { get; set; } = string.Empty;
[Required]
public string Address { get; set; } = string.Empty;
[Required]
public DateTime DateOpen { get; set; }
[Required]
public int TextileMaxCount { get; set; }
[ForeignKey("ShopId")]
public List<ShopTextile> Textiles { get; set; } = new();
private Dictionary<int, (ITextileModel, int)>? _shopTextiles = null;
[NotMapped]
public Dictionary<int, (ITextileModel, int)> ShopTextiles
{
get
{
if (_shopTextiles == null)
{
if (_shopTextiles == null)
{
_shopTextiles = Textiles.ToDictionary(x => x.TextileId, y => (y.Textile as ITextileModel, y.Count));
}
return _shopTextiles;
}
return _shopTextiles;
}
}
public static Shop Create(GarmentFactoryDatabase context, ShopBindingModel model)
{
return new Shop()
{
Id = model.Id,
ShopName = model.ShopName,
Address = model.Address,
DateOpen = model.DateOpen,
TextileMaxCount = model.TextileMaxCount,
Textiles = model.ShopTextiles.Select(x => new ShopTextile
{
Textile = context.Textiles.First(y => y.Id == x.Key),
Count = x.Value.Item2
}).ToList(),
};
}
public void Update(ShopBindingModel model)
{
ShopName = model.ShopName;
Address = model.Address;
DateOpen = model.DateOpen;
TextileMaxCount = model.TextileMaxCount;
}
public ShopViewModel GetViewModel => new()
{
Id = Id,
ShopName = ShopName,
Address = Address,
DateOpen = DateOpen,
ShopTextiles = ShopTextiles,
TextileMaxCount = TextileMaxCount
};
public void UpdateTextiles(GarmentFactoryDatabase context, ShopBindingModel model)
{
var ShopTextiles = context.ShopTextiles
.Where(rec => rec.ShopId == model.Id)
.ToList();
if (ShopTextiles != null && ShopTextiles.Count > 0)
{
context.ShopTextiles.RemoveRange(ShopTextiles.Where(rec => !model.ShopTextiles.ContainsKey(rec.TextileId)));
context.SaveChanges();
ShopTextiles = context.ShopTextiles.Where(rec => rec.ShopId == model.Id).ToList();
foreach (var textileToUpdate in ShopTextiles)
{
textileToUpdate.Count = model.ShopTextiles[textileToUpdate.TextileId].Item2;
model.ShopTextiles.Remove(textileToUpdate.TextileId);
}
context.SaveChanges();
}
var Shop = context.Shops.First(x => x.Id == Id);
foreach (var ShopTextile in model.ShopTextiles)
{
context.ShopTextiles.Add(new ShopTextile
{
Shop = Shop,
Textile = context.Textiles.First(x => x.Id == ShopTextile.Key),
Count = ShopTextile.Value.Item2
});
context.SaveChanges();
}
_shopTextiles = null;
}
public void DictionaryTextilesUpdate(GarmentFactoryDatabase context)
{
UpdateTextiles(context, new ShopBindingModel
{
Id = Id,
ShopTextiles = ShopTextiles
});
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GarmentFactoryDatabaseImplement.Models
{
public class ShopTextile
{
public int Id { get; set; }
[Required]
public int TextileId { get; set; }
[Required]
public int ShopId { get; set; }
[Required]
public int Count { get; set; }
public virtual Shop Shop { get; set; } = new();
public virtual Textile Textile { get; set; } = new();
}
}