diff --git a/SoftwareInstallation/SofrwareInstallationContracts/BindingModels/StoreBindingModel.cs b/SoftwareInstallation/SofrwareInstallationContracts/BindingModels/StoreBindingModel.cs index 27beff7..836e4f6 100644 --- a/SoftwareInstallation/SofrwareInstallationContracts/BindingModels/StoreBindingModel.cs +++ b/SoftwareInstallation/SofrwareInstallationContracts/BindingModels/StoreBindingModel.cs @@ -9,9 +9,10 @@ namespace SofrwareInstallationContracts.BindingModels public DateTime OpeningDate { get; set; } = DateTime.Now; - public Dictionary Packages { get; set; } = new (); + public Dictionary StorePackages { get; set; } = new (); public int Id { get; set; } + public int PackageMaxCount { get; set; } } } diff --git a/SoftwareInstallation/SofrwareInstallationContracts/BusinessLogicsContracts/IStoreLogic.cs b/SoftwareInstallation/SofrwareInstallationContracts/BusinessLogicsContracts/IStoreLogic.cs index 06f9a76..b161e04 100644 --- a/SoftwareInstallation/SofrwareInstallationContracts/BusinessLogicsContracts/IStoreLogic.cs +++ b/SoftwareInstallation/SofrwareInstallationContracts/BusinessLogicsContracts/IStoreLogic.cs @@ -13,5 +13,7 @@ namespace SofrwareInstallationContracts.BusinessLogicsContracts bool Update(StoreBindingModel model); bool Delete(StoreBindingModel model); bool AddPackage(StoreSearchModel model, IPackageModel package, int quantity); + bool AddPackage(IPackageModel package, int quantity); + bool SellPackage(IPackageModel package, int quantity); } } diff --git a/SoftwareInstallation/SofrwareInstallationContracts/StoragesContracts/IStoreStorage.cs b/SoftwareInstallation/SofrwareInstallationContracts/StoragesContracts/IStoreStorage.cs index c07f88f..d426c23 100644 --- a/SoftwareInstallation/SofrwareInstallationContracts/StoragesContracts/IStoreStorage.cs +++ b/SoftwareInstallation/SofrwareInstallationContracts/StoragesContracts/IStoreStorage.cs @@ -1,6 +1,7 @@ using SofrwareInstallationContracts.BindingModels; using SofrwareInstallationContracts.SearchModels; using SofrwareInstallationContracts.ViewModels; +using SoftwareInstallationDataModels.Models; namespace SofrwareInstallationContracts.StoragesContracts { @@ -12,5 +13,6 @@ namespace SofrwareInstallationContracts.StoragesContracts StoreViewModel? Insert(StoreBindingModel model); StoreViewModel? Update(StoreBindingModel model); StoreViewModel? Delete(StoreBindingModel model); + bool SellPackage(IPackageModel model, int quantity); } } diff --git a/SoftwareInstallation/SofrwareInstallationContracts/ViewModels/StoreViewModel.cs b/SoftwareInstallation/SofrwareInstallationContracts/ViewModels/StoreViewModel.cs index 87a7ff3..c94bbbf 100644 --- a/SoftwareInstallation/SofrwareInstallationContracts/ViewModels/StoreViewModel.cs +++ b/SoftwareInstallation/SofrwareInstallationContracts/ViewModels/StoreViewModel.cs @@ -5,7 +5,7 @@ namespace SofrwareInstallationContracts.ViewModels { public class StoreViewModel : IStoreModel { - public Dictionary Packages { get; set; } = new(); + public Dictionary StorePackages { get; set; } = new(); public int Id { get; set; } [DisplayName("Название магазина")] @@ -14,5 +14,7 @@ namespace SofrwareInstallationContracts.ViewModels public string StoreAdress { get; set; } = string.Empty; [DisplayName("Дата открытия")] public DateTime OpeningDate { get; set; } = DateTime.Now; + [DisplayName("Вместимость магазина")] + public int PackageMaxCount { get; set; } } } diff --git a/SoftwareInstallation/SoftwareInstallation/FormMain.Designer.cs b/SoftwareInstallation/SoftwareInstallation/FormMain.Designer.cs index d335d1b..bb419e6 100644 --- a/SoftwareInstallation/SoftwareInstallation/FormMain.Designer.cs +++ b/SoftwareInstallation/SoftwareInstallation/FormMain.Designer.cs @@ -40,6 +40,7 @@ this.IssuedOrderButton = new System.Windows.Forms.Button(); this.UpdateListButton = new System.Windows.Forms.Button(); this.StoreReplenishment = new System.Windows.Forms.Button(); + this.SellPackageButton = new System.Windows.Forms.Button(); this.MenuStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.DataGridView)).BeginInit(); this.SuspendLayout(); @@ -154,11 +155,22 @@ this.StoreReplenishment.UseVisualStyleBackColor = true; this.StoreReplenishment.Click += new System.EventHandler(this.StoreReplenishment_Click); // + // SellPackageButton + // + this.SellPackageButton.Location = new System.Drawing.Point(728, 385); + this.SellPackageButton.Name = "SellPackageButton"; + this.SellPackageButton.Size = new System.Drawing.Size(125, 31); + this.SellPackageButton.TabIndex = 8; + this.SellPackageButton.Text = "Продать изделие"; + this.SellPackageButton.UseVisualStyleBackColor = true; + this.SellPackageButton.Click += new System.EventHandler(this.SellPackageButton_Click); + // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(865, 450); + this.Controls.Add(this.SellPackageButton); this.Controls.Add(this.StoreReplenishment); this.Controls.Add(this.UpdateListButton); this.Controls.Add(this.IssuedOrderButton); @@ -192,5 +204,6 @@ private Button UpdateListButton; private ToolStripMenuItem StoreToolStripMenuItem; private Button StoreReplenishment; + private Button SellPackageButton; } } \ No newline at end of file diff --git a/SoftwareInstallation/SoftwareInstallation/FormMain.cs b/SoftwareInstallation/SoftwareInstallation/FormMain.cs index 3288f25..1a9d97b 100644 --- a/SoftwareInstallation/SoftwareInstallation/FormMain.cs +++ b/SoftwareInstallation/SoftwareInstallation/FormMain.cs @@ -208,5 +208,15 @@ namespace SoftwareInstallationView form.ShowDialog(); } } + + private void SellPackageButton_Click(object sender, EventArgs e) + { + var service = Program.ServiceProvider?.GetService(typeof(FormSellPackage)); + + if (service is FormSellPackage form) + { + form.ShowDialog(); + } + } } } diff --git a/SoftwareInstallation/SoftwareInstallation/FormSellPackage.Designer.cs b/SoftwareInstallation/SoftwareInstallation/FormSellPackage.Designer.cs new file mode 100644 index 0000000..993a11c --- /dev/null +++ b/SoftwareInstallation/SoftwareInstallation/FormSellPackage.Designer.cs @@ -0,0 +1,119 @@ +namespace SoftwareInstallationView +{ + partial class FormSellPackage + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.PackageLabel = new System.Windows.Forms.Label(); + this.QuantityLabel = new System.Windows.Forms.Label(); + this.PackageСomboBox = new System.Windows.Forms.ComboBox(); + this.QuantityTextBox = new System.Windows.Forms.TextBox(); + this.SaveButton = new System.Windows.Forms.Button(); + this.ButtonCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // PackageLabel + // + this.PackageLabel.AutoSize = true; + this.PackageLabel.Location = new System.Drawing.Point(12, 18); + this.PackageLabel.Name = "PackageLabel"; + this.PackageLabel.Size = new System.Drawing.Size(56, 15); + this.PackageLabel.TabIndex = 0; + this.PackageLabel.Text = "Изделие:"; + // + // QuantityLabel + // + this.QuantityLabel.AutoSize = true; + this.QuantityLabel.Location = new System.Drawing.Point(12, 51); + this.QuantityLabel.Name = "QuantityLabel"; + this.QuantityLabel.Size = new System.Drawing.Size(75, 15); + this.QuantityLabel.TabIndex = 1; + this.QuantityLabel.Text = "Количество:"; + // + // PackageСomboBox + // + this.PackageСomboBox.FormattingEnabled = true; + this.PackageСomboBox.Location = new System.Drawing.Point(88, 15); + this.PackageСomboBox.Name = "PackageСomboBox"; + this.PackageСomboBox.Size = new System.Drawing.Size(184, 23); + this.PackageСomboBox.TabIndex = 2; + // + // QuantityTextBox + // + this.QuantityTextBox.Location = new System.Drawing.Point(88, 48); + this.QuantityTextBox.Name = "QuantityTextBox"; + this.QuantityTextBox.Size = new System.Drawing.Size(184, 23); + this.QuantityTextBox.TabIndex = 3; + // + // SaveButton + // + this.SaveButton.Location = new System.Drawing.Point(72, 100); + this.SaveButton.Name = "SaveButton"; + this.SaveButton.Size = new System.Drawing.Size(97, 29); + this.SaveButton.TabIndex = 4; + this.SaveButton.Text = "Сохранить"; + this.SaveButton.UseVisualStyleBackColor = true; + this.SaveButton.Click += new System.EventHandler(this.SaveButton_Click); + // + // ButtonCancel + // + this.ButtonCancel.Location = new System.Drawing.Point(175, 100); + this.ButtonCancel.Name = "ButtonCancel"; + this.ButtonCancel.Size = new System.Drawing.Size(97, 29); + this.ButtonCancel.TabIndex = 5; + this.ButtonCancel.Text = "Отмена"; + this.ButtonCancel.UseVisualStyleBackColor = true; + this.ButtonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); + // + // FromSellPackage + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(284, 141); + this.Controls.Add(this.ButtonCancel); + this.Controls.Add(this.SaveButton); + this.Controls.Add(this.QuantityTextBox); + this.Controls.Add(this.PackageСomboBox); + this.Controls.Add(this.QuantityLabel); + this.Controls.Add(this.PackageLabel); + this.Name = "FromSellPackage"; + this.Text = "Продать Изделие"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private Label PackageLabel; + private Label QuantityLabel; + private ComboBox PackageСomboBox; + private TextBox QuantityTextBox; + private Button SaveButton; + private Button ButtonCancel; + } +} \ No newline at end of file diff --git a/SoftwareInstallation/SoftwareInstallation/FormSellPackage.cs b/SoftwareInstallation/SoftwareInstallation/FormSellPackage.cs new file mode 100644 index 0000000..83b7916 --- /dev/null +++ b/SoftwareInstallation/SoftwareInstallation/FormSellPackage.cs @@ -0,0 +1,94 @@ +using Microsoft.Extensions.Logging; +using SofrwareInstallationContracts.BusinessLogicsContracts; +using SofrwareInstallationContracts.SearchModels; + +namespace SoftwareInstallationView +{ + public partial class FormSellPackage : Form + { + private readonly ILogger _logger; + private readonly IPackageLogic _logicPackage; + private readonly IStoreLogic _logicStore; + public FormSellPackage(ILogger logger, IPackageLogic logicPackage, IStoreLogic logicStore) + { + InitializeComponent(); + _logger = logger; + _logicPackage = logicPackage; + _logicStore = logicStore; + LoadData(); + } + + private void FormSellPackage_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void LoadData() + { + _logger.LogInformation("Loading packages for sale."); + + try + { + var list = _logicPackage.ReadList(null); + if (list != null) + { + PackageСomboBox.DisplayMember = "PackageName"; + PackageСomboBox.ValueMember = "Id"; + PackageСomboBox.DataSource = list; + PackageСomboBox.SelectedItem = null; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "List loading error."); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void SaveButton_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(QuantityTextBox.Text)) + { + MessageBox.Show("Укажите количество", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (PackageСomboBox.SelectedValue == null) + { + MessageBox.Show("Выберите изделие", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + _logger.LogInformation("Product sale."); + + try + { + var operationResult = _logicStore.SellPackage(_logicPackage.ReadElement(new PackageSearchModel() + { + Id = Convert.ToInt32(PackageСomboBox.SelectedValue) + })!, Convert.ToInt32(QuantityTextBox.Text)); + + if (!operationResult) + { + throw new Exception("Ошибка при продаже изделия. Дополнительная информация в логах."); + } + + MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + DialogResult = DialogResult.OK; + + Close(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Product sale error."); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ButtonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + } +} diff --git a/SoftwareInstallation/SoftwareInstallation/FormSellPackage.resx b/SoftwareInstallation/SoftwareInstallation/FormSellPackage.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/SoftwareInstallation/SoftwareInstallation/FormSellPackage.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SoftwareInstallation/SoftwareInstallation/FormStore.Designer.cs b/SoftwareInstallation/SoftwareInstallation/FormStore.Designer.cs index 6b491f1..39d097d 100644 --- a/SoftwareInstallation/SoftwareInstallation/FormStore.Designer.cs +++ b/SoftwareInstallation/SoftwareInstallation/FormStore.Designer.cs @@ -40,7 +40,10 @@ this.SaveButton = new System.Windows.Forms.Button(); this.ButtonCancel = new System.Windows.Forms.Button(); this.OpeningDatePicker = new System.Windows.Forms.DateTimePicker(); + this.VolumeNumericUpDown = new System.Windows.Forms.NumericUpDown(); + this.PackageMaxCountLable = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.DataGridView)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.VolumeNumericUpDown)).BeginInit(); this.SuspendLayout(); // // StoreNameLabel @@ -142,11 +145,29 @@ this.OpeningDatePicker.Size = new System.Drawing.Size(174, 23); this.OpeningDatePicker.TabIndex = 9; // + // VolumeNumericUpDown + // + this.VolumeNumericUpDown.Location = new System.Drawing.Point(486, 7); + this.VolumeNumericUpDown.Name = "VolumeNumericUpDown"; + this.VolumeNumericUpDown.Size = new System.Drawing.Size(168, 23); + this.VolumeNumericUpDown.TabIndex = 10; + // + // PackageMaxCountLable + // + this.PackageMaxCountLable.AutoSize = true; + this.PackageMaxCountLable.Location = new System.Drawing.Point(340, 9); + this.PackageMaxCountLable.Name = "PackageMaxCountLable"; + this.PackageMaxCountLable.Size = new System.Drawing.Size(140, 15); + this.PackageMaxCountLable.TabIndex = 11; + this.PackageMaxCountLable.Text = "Вместимость магазина: "; + // // FormStore // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.PackageMaxCountLable); + this.Controls.Add(this.VolumeNumericUpDown); this.Controls.Add(this.OpeningDatePicker); this.Controls.Add(this.ButtonCancel); this.Controls.Add(this.SaveButton); @@ -160,6 +181,7 @@ this.Text = "Изделия магазина"; this.Load += new System.EventHandler(this.FormStore_Load); ((System.ComponentModel.ISupportInitialize)(this.DataGridView)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.VolumeNumericUpDown)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -179,5 +201,7 @@ private DataGridViewTextBoxColumn PackagePrice; private DataGridViewTextBoxColumn PackageCount; private DateTimePicker OpeningDatePicker; + private NumericUpDown VolumeNumericUpDown; + private Label PackageMaxCountLable; } } \ No newline at end of file diff --git a/SoftwareInstallation/SoftwareInstallation/FormStore.cs b/SoftwareInstallation/SoftwareInstallation/FormStore.cs index a790535..a4058b4 100644 --- a/SoftwareInstallation/SoftwareInstallation/FormStore.cs +++ b/SoftwareInstallation/SoftwareInstallation/FormStore.cs @@ -58,7 +58,7 @@ namespace SoftwareInstallationView return; } - _logger.LogInformation("Сохранение изделия"); + _logger.LogInformation("Сохранение магазина"); try { @@ -67,7 +67,8 @@ namespace SoftwareInstallationView { StoreName = NameComboBox.Text, StoreAdress = AdressTextBox.Text, - OpeningDate = dateTime + OpeningDate = dateTime, + PackageMaxCount = (int)VolumeNumericUpDown.Value }; var vmodel = GetStore(Id); bool operationResult = false; @@ -118,8 +119,9 @@ namespace SoftwareInstallationView NameComboBox.Text = model.StoreName; AdressTextBox.Text = model.StoreAdress; OpeningDatePicker.Text = Convert.ToString(model.OpeningDate); + VolumeNumericUpDown.Value = model.PackageMaxCount; DataGridView.Rows.Clear(); - foreach (var el in model.Packages.Values) + foreach (var el in model.StorePackages.Values) { DataGridView.Rows.Add(new object[] { el.Item1.PackageName, el.Item1.Price, el.Item2 }); } @@ -138,5 +140,6 @@ namespace SoftwareInstallationView { LoadData(false); } + } } diff --git a/SoftwareInstallation/SoftwareInstallation/FormStore.resx b/SoftwareInstallation/SoftwareInstallation/FormStore.resx index 7a40f39..eeed9d1 100644 --- a/SoftwareInstallation/SoftwareInstallation/FormStore.resx +++ b/SoftwareInstallation/SoftwareInstallation/FormStore.resx @@ -66,4 +66,13 @@ True + + True + + + True + + + True + \ No newline at end of file diff --git a/SoftwareInstallation/SoftwareInstallation/FormStores.cs b/SoftwareInstallation/SoftwareInstallation/FormStores.cs index b02fe4f..7c09a2d 100644 --- a/SoftwareInstallation/SoftwareInstallation/FormStores.cs +++ b/SoftwareInstallation/SoftwareInstallation/FormStores.cs @@ -31,7 +31,7 @@ namespace SoftwareInstallationView DataGridView.DataSource = list; DataGridView.Columns["Id"].Visible = false; DataGridView.Columns["StoreName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - DataGridView.Columns["Packages"].Visible = false; + DataGridView.Columns["StorePackages"].Visible = false; } _logger.LogInformation("Загрузка магазинов"); diff --git a/SoftwareInstallation/SoftwareInstallation/Program.cs b/SoftwareInstallation/SoftwareInstallation/Program.cs index 8bdce53..50bf6cc 100644 --- a/SoftwareInstallation/SoftwareInstallation/Program.cs +++ b/SoftwareInstallation/SoftwareInstallation/Program.cs @@ -49,6 +49,7 @@ namespace SoftwareInstallationView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } } } diff --git a/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/OrderLogic.cs b/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/OrderLogic.cs index b65e541..71e4e33 100644 --- a/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/OrderLogic.cs +++ b/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/OrderLogic.cs @@ -12,11 +12,15 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; + private readonly IStoreLogic _storeLogic; + private readonly IPackageStorage _packageStorage; - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IPackageStorage packageStorage,IStoreLogic storeLogic) { _logger = logger; _orderStorage = orderStorage; + _storeLogic = storeLogic; + _packageStorage = packageStorage; } public bool CreateOrder(OrderBindingModel model) @@ -43,9 +47,14 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic public bool StatusUpdate(OrderBindingModel model, OrderStatus newStatus) { - CheckModel(model); + var viewModel = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id }); - if (model.Status + 1 != newStatus) + if (viewModel == null) + { + throw new ArgumentNullException(nameof(model)); + } + + if (viewModel.Status + 1 != newStatus) { _logger.LogWarning("Status update to " + newStatus.ToString() + " operation failed. Order status incorrect."); return false; @@ -53,13 +62,34 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic model.Status = newStatus; - if (model.Status == OrderStatus.Выдан) + if (model.Status == OrderStatus.Готов) + { model.DateImplement = DateTime.Now; + var package = _packageStorage.GetElement(new() { Id = viewModel.PackageId }); + + if (package == null) + { + throw new ArgumentNullException(nameof(package)); + } + + if (!_storeLogic.AddPackage(package, viewModel.Count)) + { + throw new Exception($"AddPackage operation failed. Store is full."); + } + } + else + { + model.DateImplement = viewModel.DateImplement; + } + + CheckModel(model, false); + if (_orderStorage.Update(model) == null) { model.Status--; _logger.LogWarning("Update operation failed"); + return false; } diff --git a/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/StoreLogic.cs b/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/StoreLogic.cs index ef1a978..a3efd1d 100644 --- a/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/StoreLogic.cs +++ b/SoftwareInstallation/SoftwareInstallationBusinessLogic/BusinessLogic/StoreLogic.cs @@ -26,29 +26,34 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic if (quantity <= 0) { - throw new ArgumentException("Количество добавляемого изделия должно быть больше 0", nameof(quantity)); + throw new ArgumentException("Количество изделий должно быть больше 0", nameof(quantity)); } - _logger.LogInformation("AddPackageInStore. StoreName:{StoreName}.Id:{ Id}", model.StoreName, model.Id); + _logger.LogInformation("AddPackage. StoreName:{StoreName}.Id:{ Id}", model.StoreName, model.Id); var element = _storeStorage.GetElement(model); if (element == null) { - _logger.LogWarning("AddPackageInStore element not found"); + _logger.LogWarning("AddPackage element not found"); return false; } - _logger.LogInformation("AddPackageInStore find. Id:{Id}", element.Id); - - if (element.Packages.TryGetValue(package.Id, out var pair)) + if (element.PackageMaxCount - element.StorePackages.Select(x => x.Value.Item2).Sum() < quantity) { - element.Packages[package.Id] = (package, quantity + pair.Item2); - _logger.LogInformation("AddPackageInStore. Has been added {quantity} {package} in {StoreName}", quantity, package.PackageName, element.StoreName); + throw new ArgumentNullException("Магазин переполнен", nameof(quantity)); + } + + _logger.LogInformation("AddPackage find. Id:{Id}", element.Id); + + if (element.StorePackages.TryGetValue(package.Id, out var pair)) + { + element.StorePackages[package.Id] = (package, quantity + pair.Item2); + _logger.LogInformation("AddPackage. Added {quantity} {package} to '{StoreName}' store", quantity, package.PackageName, element.StoreName); } else { - element.Packages[package.Id] = (package, quantity); - _logger.LogInformation("AddPastryInShop. Has been added {quantity} new Package {package} in {StoreName}", quantity, package.PackageName, element.StoreName); + element.StorePackages[package.Id] = (package, quantity); + _logger.LogInformation("AddPackage. Added {quantity} new package {package} to '{StoreName}' store", quantity, package.PackageName, element.StoreName); } _storeStorage.Update(new() @@ -57,15 +62,64 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic StoreAdress = element.StoreAdress, StoreName = element.StoreName, OpeningDate = element.OpeningDate, - Packages = element.Packages + PackageMaxCount = element.PackageMaxCount, + StorePackages = element.StorePackages, }); + + return true; + } + + public bool AddPackage(IPackageModel package, int quantity) + { + if (package == null) + { + throw new ArgumentNullException(nameof(package)); + } + + if (quantity <= 0) + { + throw new ArgumentException("Количество добавляемого изделия должно быть больше 0", nameof(quantity)); + } + + var freePlaces = _storeStorage.GetFullList() + .Select(x => x.PackageMaxCount - x.StorePackages + .Select(p => p.Value.Item2).Sum()).Sum() - quantity; + + if (freePlaces < 0) + { + _logger.LogInformation("AddPackage. Failed to add package to store. It's full."); + return false; + } + + foreach (var store in _storeStorage.GetFullList()) + { + var temp = Math.Min(quantity, store.PackageMaxCount - store.StorePackages.Select(x => x.Value.Item2).Sum()); + + if (temp <= 0) + { + continue; + } + + if (!AddPackage(new() { Id = store.Id }, package, temp)) + { + _logger.LogWarning("An error occurred while adding package to stores"); + return false; + } + + quantity -= temp; + + if (quantity == 0) + { + return true; + } + } return true; } public bool Create(StoreBindingModel model) { CheckModel(model); - model.Packages = new(); + model.StorePackages = new(); if (_storeStorage.Insert(model) == null) { @@ -126,6 +180,11 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic return list; } + public bool SellPackage(IPackageModel package, int quantity) + { + return _storeStorage.SellPackage(package, quantity); + } + public bool Update(StoreBindingModel model) { CheckModel(model, false); @@ -160,7 +219,13 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic throw new ArgumentNullException("Нет названия магазина", nameof(model.StoreName)); } + if (model.PackageMaxCount < 0) + { + throw new ArgumentException("Максимальное количество изделий в магазине не может быть меньше нуля", nameof(model.PackageMaxCount)); + } + _logger.LogInformation("Store. StoreName:{0}.StoreAdress:{1}. Id: {2}", model.StoreName, model.StoreAdress, model.Id); + var element = _storeStorage.GetElement(new StoreSearchModel { StoreName = model.StoreName diff --git a/SoftwareInstallation/SoftwareInstallationDataModels/Models/IStoreModel.cs b/SoftwareInstallation/SoftwareInstallationDataModels/Models/IStoreModel.cs index 90e7e5f..adc1df6 100644 --- a/SoftwareInstallation/SoftwareInstallationDataModels/Models/IStoreModel.cs +++ b/SoftwareInstallation/SoftwareInstallationDataModels/Models/IStoreModel.cs @@ -5,6 +5,7 @@ public string StoreName { get; } public string StoreAdress { get; } DateTime OpeningDate { get; } - Dictionary Packages { get; } + Dictionary StorePackages { get; } + public int PackageMaxCount { get; } } } diff --git a/SoftwareInstallation/SoftwareInstallationFileImplement/DataFileSingleton.cs b/SoftwareInstallation/SoftwareInstallationFileImplement/DataFileSingleton.cs index 34b5748..aef922d 100644 --- a/SoftwareInstallation/SoftwareInstallationFileImplement/DataFileSingleton.cs +++ b/SoftwareInstallation/SoftwareInstallationFileImplement/DataFileSingleton.cs @@ -10,10 +10,12 @@ namespace SoftwareInstallationFileImplement private readonly string ComponentFileName = "Component.xml"; private readonly string OrderFileName = "Order.xml"; private readonly string PackageFileName = "Package.xml"; + private readonly string StoreFileName = "Store.xml"; public List Components { get; private set; } public List Orders { get; private set; } public List Packages { get; private set; } + public List Stores { get; private set; } public static DataFileSingleton GetInstance() { @@ -27,12 +29,14 @@ namespace SoftwareInstallationFileImplement public void SaveComponents() => SaveData(Components, ComponentFileName,"Components", x => x.GetXElement); public void SavePackages() => SaveData(Packages, PackageFileName, "Packages", x => x.GetXElement); public void SaveOrders() => SaveData(Orders, OrderFileName, "Orders", x => x.GetXElement); + public void SaveStores() => SaveData(Stores, StoreFileName, "Stores", x => x.GetXElement); private DataFileSingleton() { Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!; Packages = LoadData(PackageFileName, "Package", x => Package.Create(x)!)!; Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!; + Stores = LoadData(StoreFileName, "Store", x => Store.Create(x)!)!; } private static List? LoadData(string filename, string xmlNodeName, Func selectFunction) diff --git a/SoftwareInstallation/SoftwareInstallationFileImplement/Implements/StoreStorage.cs b/SoftwareInstallation/SoftwareInstallationFileImplement/Implements/StoreStorage.cs new file mode 100644 index 0000000..1ad24d5 --- /dev/null +++ b/SoftwareInstallation/SoftwareInstallationFileImplement/Implements/StoreStorage.cs @@ -0,0 +1,109 @@ +using SofrwareInstallationContracts.BindingModels; +using SofrwareInstallationContracts.SearchModels; +using SofrwareInstallationContracts.StoragesContracts; +using SofrwareInstallationContracts.ViewModels; +using SoftwareInstallationDataModels.Models; +using SoftwareInstallationFileImplement.Models; + +namespace SoftwareInstallationFileImplement.Implements +{ + public class StoreStorage : IStoreStorage + { + private readonly DataFileSingleton source; + + public StoreStorage() + { + source = DataFileSingleton.GetInstance(); + } + + public StoreViewModel? Delete(StoreBindingModel model) + { + var element = source.Stores.FirstOrDefault(x => x.Id == model.Id); + if (element != null) + { + source.Stores.Remove(element); + source.SaveStores(); + return element.GetViewModel; + } + return null; + } + + public StoreViewModel? GetElement(StoreSearchModel model) + { + if (string.IsNullOrEmpty(model.StoreName) && !model.Id.HasValue) + { + return null; + } + return source.Stores.FirstOrDefault(x => + (!string.IsNullOrEmpty(model.StoreName) && x.StoreName == + model.StoreName) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + } + + public List GetFilteredList(StoreSearchModel model) + { + if (string.IsNullOrEmpty(model.StoreName)) + { + return new(); + } + return source.Stores.Where(x => + x.StoreName.Contains(model.StoreName)).Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + return source.Stores.Select(x => x.GetViewModel).ToList(); + } + + public StoreViewModel? Insert(StoreBindingModel model) + { + model.Id = source.Stores.Count > 0 ? source.Stores.Max(x => x.Id) + 1 : 1; + var newStore = Store.Create(model); + if (newStore == null) + { + return null; + } + source.Stores.Add(newStore); + source.SaveStores(); + return newStore.GetViewModel; + } + + public bool SellPackage(IPackageModel model, int quantity) + { + if (source.Stores.Select(x => x.StorePackages.FirstOrDefault(y => y.Key == model.Id).Value.Item2).Sum() < quantity) + { + return false; + } + foreach (var store in source.Stores.Where(x => x.StorePackages.ContainsKey(model.Id))) + { + int QuantityInCurrentShop = store.StorePackages[model.Id].Item2; + if (QuantityInCurrentShop <= quantity) + { + store.StorePackages.Remove(model.Id); + quantity -= QuantityInCurrentShop; + } + else + { + store.StorePackages[model.Id] = (store.StorePackages[model.Id].Item1, QuantityInCurrentShop - quantity); + quantity = 0; + } + if (quantity == 0) + { + return true; + } + } + return false; + } + + public StoreViewModel? Update(StoreBindingModel model) + { + var store = source.Stores.FirstOrDefault(x => x.Id == model.Id); + if (store == null) + { + return null; + } + store.Update(model); + source.SaveStores(); + return store.GetViewModel; + } + } +} diff --git a/SoftwareInstallation/SoftwareInstallationFileImplement/Models/Store.cs b/SoftwareInstallation/SoftwareInstallationFileImplement/Models/Store.cs new file mode 100644 index 0000000..a81435b --- /dev/null +++ b/SoftwareInstallation/SoftwareInstallationFileImplement/Models/Store.cs @@ -0,0 +1,104 @@ +using SofrwareInstallationContracts.BindingModels; +using SofrwareInstallationContracts.ViewModels; +using SoftwareInstallationDataModels.Models; +using System.Xml.Linq; + +namespace SoftwareInstallationFileImplement.Models +{ + public class Store : IStoreModel + { + public string StoreName { get; private set; } = string.Empty; + public string StoreAdress { get; private set; } = string.Empty; + + public DateTime OpeningDate { get; private set; } + public Dictionary Packages { get; private set; } = new(); + + public Dictionary _storePackages = null; + public Dictionary StorePackages + { + get + { + if (_storePackages == null) + { + var source = DataFileSingleton.GetInstance(); + _storePackages = Packages.ToDictionary(x => x.Key, y => ((source.Packages.FirstOrDefault(z => z.Id == y.Key) as IPackageModel)!, y.Value)); + } + return _storePackages; + } + } + + public int Id { get; private set; } + + public int PackageMaxCount { get; private set; } + + public static Store? Create(StoreBindingModel? model) + { + if (model == null) + { + return null; + } + return new Store() + { + Id = model.Id, + StoreName = model.StoreName, + StoreAdress = model.StoreAdress, + PackageMaxCount = model.PackageMaxCount, + OpeningDate = model.OpeningDate, + Packages = model.StorePackages.ToDictionary(x => x.Key, x => x.Value.Item2) + }; + } + public static Store? Create(XElement element) + { + if (element == null) + { + return null; + } + return new() + { + Id = Convert.ToInt32(element.Attribute("Id")!.Value), + StoreName = element.Element("StoreName")!.Value, + StoreAdress = element.Element("StoreAdress")!.Value, + OpeningDate = Convert.ToDateTime(element.Element("OpeningDate")!.Value), + PackageMaxCount = Convert.ToInt32(element.Element("PackageMaxCount")!.Value), + Packages = element.Element("StorePackages")!.Elements("Package").ToDictionary( + x => Convert.ToInt32(x.Element("Key")?.Value), + x => Convert.ToInt32(x.Element("Value")?.Value)) + }; + } + public void Update(StoreBindingModel? model) + { + if (model == null) + { + return; + } + StoreName = model.StoreName; + StoreAdress = model.StoreAdress; + OpeningDate = model.OpeningDate; + PackageMaxCount = model.PackageMaxCount; + Packages = model.StorePackages.ToDictionary(x => x.Key, x => x.Value.Item2); + _storePackages = null; + } + public StoreViewModel GetViewModel => new() + { + Id = Id, + StoreName = StoreName, + StoreAdress = StoreAdress, + StorePackages = StorePackages, + OpeningDate = OpeningDate, + PackageMaxCount = PackageMaxCount, + }; + public XElement GetXElement => new("Store", + new XAttribute("Id", Id), + new XElement("StoreName", StoreName), + new XElement("StoreAdress", StoreAdress), + new XElement("OpeningDate", OpeningDate), + new XElement("PackageMaxCount", PackageMaxCount), + new XElement("StorePackages", Packages + .Select(x => new XElement("Package", + new XElement("Key", x.Key), + new XElement("Value", x.Value)) + ).ToArray())); + } + +} + diff --git a/SoftwareInstallation/SoftwareInstallationListImplement/Implements/StoreStorage.cs b/SoftwareInstallation/SoftwareInstallationListImplement/Implements/StoreStorage.cs index b30cf73..2cb7c5e 100644 --- a/SoftwareInstallation/SoftwareInstallationListImplement/Implements/StoreStorage.cs +++ b/SoftwareInstallation/SoftwareInstallationListImplement/Implements/StoreStorage.cs @@ -2,6 +2,7 @@ using SofrwareInstallationContracts.SearchModels; using SofrwareInstallationContracts.StoragesContracts; using SofrwareInstallationContracts.ViewModels; +using SoftwareInstallationDataModels.Models; using SoftwareInstallationListImplement.Models; namespace SoftwareInstallationListImplement.Implements @@ -101,6 +102,11 @@ namespace SoftwareInstallationListImplement.Implements return newStore.GetViewModel; } + public bool SellPackage(IPackageModel model, int quantity) + { + throw new NotImplementedException(); + } + public StoreViewModel? Update(StoreBindingModel model) { foreach (var store in _source.Stores) diff --git a/SoftwareInstallation/SoftwareInstallationListImplement/Models/Store.cs b/SoftwareInstallation/SoftwareInstallationListImplement/Models/Store.cs index cf6c3ac..7de228e 100644 --- a/SoftwareInstallation/SoftwareInstallationListImplement/Models/Store.cs +++ b/SoftwareInstallation/SoftwareInstallationListImplement/Models/Store.cs @@ -13,7 +13,7 @@ namespace SoftwareInstallationListImplement.Models public DateTime OpeningDate { get; private set; } - public Dictionary Packages { get; private set; } = new(); + public Dictionary StorePackages { get; private set; } = new(); public int Id { get; private set; } @@ -29,7 +29,7 @@ namespace SoftwareInstallationListImplement.Models StoreName = model.StoreName, StoreAdress = model.StoreAdress, OpeningDate = model.OpeningDate, - Packages=new() + StorePackages = new() }; } @@ -42,7 +42,7 @@ namespace SoftwareInstallationListImplement.Models StoreName = model.StoreName; StoreAdress = model.StoreAdress; OpeningDate = model.OpeningDate; - Packages = model.Packages; + StorePackages = model.StorePackages; } public StoreViewModel GetViewModel => new() @@ -51,7 +51,9 @@ namespace SoftwareInstallationListImplement.Models StoreName = StoreName, StoreAdress = StoreAdress, OpeningDate = OpeningDate, - Packages = Packages + StorePackages = StorePackages }; + + public int PackageMaxCount => throw new NotImplementedException(); } }