using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace C968Project.Views { public partial class AddModifyProductScreen : Form { private ScreenOption _screenOption; private Product? _currentProduct; private bool _isNameValid = false; private bool _isInventoryValid = false; private bool _isPriceValid = false; private bool _isMinValid = false; private bool _isMaxValid = false; private int _validatedMin = 0; private int _validatedMax = 0; public AddModifyProductScreen(ScreenOption screenOption, Product? product = null) { InitializeComponent(); this._screenOption = screenOption; _currentProduct = product; if (_screenOption is ScreenOption.ADD) { screenLabel.Text = "Add Product"; _currentProduct = new(); associatedPartsDataGridView.DataSource = _currentProduct.AssociatedParts; } if (_screenOption is ScreenOption.MODIFY) { screenLabel.Text = "Modify Product"; PopulateProductData(_currentProduct); } allPartsDataGridView.DataSource = Program.Inventory.Parts; ValidateInputs(true); } private void PopulateProductData(Product product) { idTextBox.Text = product.ProductId.ToString(); nameTextBox.Text = product.Name; inventoryTextBox.Text = product.InStock.ToString(); priceTextBox.Text = product.Price.ToString(); minTextBox.Text = product.Min.ToString(); maxTextBox.Text = product.Max.ToString(); associatedPartsDataGridView.DataSource = product.AssociatedParts; } private Product CreateProduct(int productId) { Product product = new(); product.ProductId = productId; product.Name = nameTextBox.Text; product.InStock = int.Parse(inventoryTextBox.Text); product.Price = float.Parse(priceTextBox.Text); product.Min = int.Parse(minTextBox.Text); product.Max = int.Parse(maxTextBox.Text); var dataGridViewData = associatedPartsDataGridView.DataSource; if (dataGridViewData != null) { if (dataGridViewData is BindingList partsList) { product.AssociatedParts = partsList; } else { MessageBox.Show("Error generating Associated Parts: DataGridView DataSource is not of type BindingList somehow. Defaulting to an empty list.", "Data Type Error", MessageBoxButtons.OK, MessageBoxIcon.Error); product.AssociatedParts = new(); } } else { product.AssociatedParts = new(); } return product; } private void AddProduct() { int newId = Program.CreateNewProductId(); Program.Inventory.AddProduct(CreateProduct(newId)); } private void ModifyProduct() { int productIndex = 0; if (_currentProduct != null && Program.Inventory.Products.Contains(_currentProduct)) { productIndex = Program.Inventory.Products.IndexOf(_currentProduct); } else { MessageBox.Show("Error modifying product: Could not find product index", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } var oldProduct = Program.Inventory.Products[productIndex]; var oldProductId = oldProduct.ProductId; var modifiedProduct = CreateProduct(oldProductId); Program.Inventory.Products[productIndex] = modifiedProduct; } private void saveButton_Click(object sender, EventArgs e) { if (ValidateInputs()) { if (_screenOption is ScreenOption.ADD) { AddProduct(); Close(); } if (_screenOption is ScreenOption.MODIFY) { ModifyProduct(); Close(); } } } private void cancelButton_Click(object sender, EventArgs e) { Close(); } private void addButton_Click(object sender, EventArgs e) { if (allPartsDataGridView.CurrentCell is null) { MessageBox.Show("No part selected", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } Part part = Program.Inventory.LookupPart(allPartsDataGridView.CurrentCell.RowIndex); if (part is null) return; if (_currentProduct.AssociatedParts.Contains(part)) { MessageBox.Show("Part already added", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } _currentProduct.AddAssociatedPart(part); } private void deleteButton_Click(object sender, EventArgs e) { if (associatedPartsDataGridView.CurrentCell is null) { MessageBox.Show("No part selected", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } if (!Helpers.ConfirmDelete()) return; Part part = _currentProduct.LookupAssociatedPart(associatedPartsDataGridView.CurrentCell.RowIndex); if (part is null || !_currentProduct.AssociatedParts.Contains(part)) { MessageBox.Show("Error finding associated part from selection", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } _currentProduct.RemoveAssociatedPart(_currentProduct.AssociatedParts.IndexOf(part)); } private void nameTextBox_TextChanged(object sender, EventArgs e) { ValidateName(); } private string ValidateName() { string err = string.Empty; if (nameTextBox.Text == string.Empty) { err = "Must have a product name\n"; errorProvider1.SetError(nameTextBox, "Must have a product name"); _isNameValid = false; } else { errorProvider1.SetError(nameTextBox, ""); _isNameValid = true; } Helpers.SetTextBoxValidationState(nameTextBox, _isNameValid); return err; } private void inventoryTextBox_TextChanged(object sender, EventArgs e) { ValidateInventory(); } private string ValidateInventory() { string err = string.Empty; int inventory = 0; if (inventoryTextBox.Text != string.Empty && int.TryParse(inventoryTextBox.Text, out inventory)) { if (_isMinValid && _isMaxValid) { if (inventory > _validatedMax) { err = $"Inventory must be less than Max: {_validatedMax}\n"; errorProvider1.SetError(inventoryTextBox, $"Must be less than Max: {_validatedMax}"); _isInventoryValid = false; } else if (inventory < _validatedMin) { err = $"Inventory must be greater than Min: {_validatedMin}\n"; errorProvider1.SetError(inventoryTextBox, $"Must be greater than Min: {_validatedMin}"); _isInventoryValid = false; } else { errorProvider1.SetError(inventoryTextBox, ""); _isInventoryValid = true; } } else { err = $"Inventory can't be set without valid Min and Max values\n"; errorProvider1.SetError(inventoryTextBox, $"Min and Max values must be set"); _isInventoryValid = false; } } else { err = $"Inventory must contain an integer\n"; _isInventoryValid = false; errorProvider1.SetError(inventoryTextBox, "Field must contain an integer value"); } Helpers.SetTextBoxValidationState(inventoryTextBox, _isInventoryValid); return err; } private void priceTextBox_TextChanged(object sender, EventArgs e) { ValidatePrice(); } private string ValidatePrice() { string err = string.Empty; float price = 0f; if (priceTextBox.Text != string.Empty && float.TryParse(priceTextBox.Text, out price)) { _isPriceValid = true; errorProvider1.SetError(priceTextBox, ""); } else { _isPriceValid = false; err = "Price must contain a decimal value\n"; errorProvider1.SetError(priceTextBox, "Field must contain a decimal value"); } Helpers.SetTextBoxValidationState(priceTextBox, _isPriceValid); return err; } private void maxTextBox_TextChanged(object sender, EventArgs e) { ValidateMax(); } private string ValidateMax() { string err = string.Empty; int max = 0; if (maxTextBox.Text != string.Empty && int.TryParse(maxTextBox.Text, out max)) { _isMaxValid = true; errorProvider1.SetError(maxTextBox, ""); _validatedMax = max; } else { _isMaxValid = false; errorProvider1.SetError(maxTextBox, "Field must contain an integer value"); err = "Max must be an integer value\n"; } if (_isMinValid && _isMaxValid && _validatedMax < _validatedMin) { _isMaxValid = false; err = $"Max cannot be less than Min: {_validatedMin}\n"; errorProvider1.SetError(maxTextBox, $"Max cannot be less than Min: {_validatedMin}"); } ValidateInventory(); Helpers.SetTextBoxValidationState(maxTextBox, _isMaxValid); return err; } private void minTextBox_TextChanged(object sender, EventArgs e) { ValidateMin(); } private string ValidateMin() { string err = string.Empty; int min = 0; if (minTextBox.Text != string.Empty && int.TryParse(minTextBox.Text, out min)) { _isMinValid = true; errorProvider1.SetError(minTextBox, ""); _validatedMin = min; } else { _isMinValid = false; errorProvider1.SetError(minTextBox, "Field must contain an integer value"); err = "Min must be an integer value\n"; } if (_isMinValid && _isMaxValid && _validatedMin > _validatedMax) { _isMinValid = false; err = $"Min cannot be more than Max: {_validatedMax}\n"; errorProvider1.SetError(maxTextBox, $"Min cannot be more than Max: {_validatedMax}"); } ValidateInventory(); Helpers.SetTextBoxValidationState(minTextBox, _isMinValid); return err; } private bool ValidateInputs(bool initial = false) { bool valid = false; string err = string.Empty; err += ValidateName(); err += ValidateInventory(); err += ValidatePrice(); err += ValidateMin(); err += ValidateMax(); valid = _isNameValid && _isInventoryValid && _isPriceValid && _isMinValid && _isMaxValid; if (!valid && !initial) { Helpers.ShowErrorMessage(err, "Validation error"); } return valid; } private void searchButton_Click(object sender, EventArgs e) { Helpers.SearchDataGridView(allPartsDataGridView, searchTextBox.Text); } } }