/// <summary>
 /// Initializes a new instance of the <see cref="AnalysedProduct"/> class.
 /// </summary>
 /// <param name="projProd">The proj product.</param>
 /// Erstellt von Joshua Frey, am 20.01.2016
 public AnalysedProduct(ProjectProduct projProd)
 {
     this.ProjProd = projProd;
     this.ProjCritContr = new ProjectCriterionController();
     this.FulFillContr = new FulfillmentController();
     this.AnalysisResultCrits = new List<AnalysisResultCrit>();
     this.ProjectId = this.ProjProd.Project_Id;
     CalculateAnalysedProductResult();
 }
        /// <summary>
        /// Gets the project product by line from import file.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns></returns>
        /// Erstellt von Joshua Frey, am 26.01.2016
        private ProjectProduct GetProjectProductByLineFromImportFile(string projectProductImportLine)
        {
            ProjectProduct importProjectProduct;
            // Project_Id|Product_Id
            var lineAsArray = projectProductImportLine.Split(this._delimiter);

            int projectId;
            int productId;
            try
            {
                projectId = Convert.ToInt32(lineAsArray[0]);
                productId = Convert.ToInt32(lineAsArray[1]);
            }
            catch (FormatException formatException)
            {
                throw new NWATException(String.Format("{0}\n\n{1}",
                    formatException, MessageWrongDatatypeInExportedLine("ProjectProduct", projectProductImportLine, "int|int")));
            }

            importProjectProduct = new ProjectProduct()
            {
                Project_Id = projectId,
                Product_Id = productId
            };
            return importProjectProduct;
        }
 partial void DeleteProjectProduct(ProjectProduct instance);
 partial void UpdateProjectProduct(ProjectProduct instance);
 partial void InsertProjectProduct(ProjectProduct instance);
		private void detach_ProjectProduct(ProjectProduct entity)
		{
			this.SendPropertyChanging();
			entity.Project = null;
		}
		private void attach_ProjectProduct(ProjectProduct entity)
		{
			this.SendPropertyChanging();
			entity.Project = this;
		}
        /// <summary>
        /// Handles the Click event of the btn_ProdToProj control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        /// Erstellt von Veit Berg, am 27.01.16
        private void btn_ProdToProj_Click(object sender, EventArgs e)
        {
            try
            {
                DataGridViewRow row = dataGridView_prodAvail.SelectedRows[0];
                int ProdId = (int)row.Cells[0].Value;
                string ProdName = (string)row.Cells[1].Value;
                int index = dataGridView_prodAvail.CurrentCell.RowIndex;

                ProjectProduct projProdToAllocate = new ProjectProduct()
                {
                    Project_Id = ProjectId,
                    Product_Id = ProdId,
                };
                AllProds.RemoveAt(index);
                ProjProds.Add(projProdToAllocate);

                dataGridView_prodAvail.DataSource = null;
                dataGridView_prodAvail.DataSource = AllProds;
                dataGridView_ProjProd.DataSource = null;
                using (ProductController prodCon = new ProductController())
                {
                    foreach (ProjectProduct projProd in ProjProds)
                    {
                        var singleProdId = prodCon.GetProductById(projProd.Product_Id);
                        projProd.Name = singleProdId.Name.ToString();
                    }
                }

                dataGridView_ProjProd.DataSource = ProjProds;
                dataGridView_ProjProd.Columns.Remove("Project_Id");
                dataGridView_ProjProd.Columns.Remove("Product");
                dataGridView_ProjProd.Columns.Remove("Project");
                dataGridView_ProjProd.Columns[1].Width = 200;
                projProdCont.ChangeAllocationOfProjectProducstListInDb(ProjectId, ProjProds);
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message);
            }
        }
 /// <summary>
 /// Checks if same project product.
 /// </summary>
 /// <param name="projProdOne">The proj product one.</param>
 /// <param name="projProdTwo">The proj product two.</param>
 /// <returns>
 /// boolean if given project products are the same.
 /// </returns>
 /// Erstellt von Joshua Frey, am 12.01.2016
 public bool CheckIfSameProjectProduct(ProjectProduct projProdOne, ProjectProduct projProdTwo)
 {
     bool sameProjectId = projProdOne.Project_Id == projProdTwo.Project_Id;
     bool sameProductId = projProdOne.Product_Id == projProdTwo.Product_Id;
     return sameProductId && sameProjectId;
 }
        /// <summary>
        /// Insertts the project product into database.
        /// </summary>
        /// <param name="newProjectProduct">The new project product.</param>
        /// <returns>
        /// true if insertion was successful
        /// </returns>
        /// Erstellt von Joshua Frey, am 12.01.2016
        /// <exception cref="NWATException">
        /// </exception>
        private bool InsertProjectProductIntoDb(ProjectProduct newProjectProduct)
        {
            if (newProjectProduct != null)
            {
                int newProjectId = newProjectProduct.Project_Id;
                int newProductId = newProjectProduct.Product_Id;

                if (!CheckIfProjectProductAlreadyExists(newProjectId, newProductId))
                {
                    base.DataContext.ProjectProduct.InsertOnSubmit(newProjectProduct);
                    base.DataContext.SubmitChanges();
                }
                else
                {
                    ProjectProduct alreadyExistingProjectProduct = GetProjectProductByIds(newProjectId, newProductId);
                    string existingProjectName = alreadyExistingProjectProduct.Project.Name;
                    string existingProductName = alreadyExistingProjectProduct.Product.Name;
                    throw new NWATException(MessageProductIsAlreadyAllocatedToProject(existingProjectName, existingProductName));
                }
                return CheckIfSameProjectProduct(newProjectProduct, GetProjectProductByIds(newProjectId, newProductId));
            }
            else
            {
                throw new NWATException(MessageProjectProductCouldNotBeSavedEmptyObject());
            }
        }
        /*
         * Private section
         */
        /// <summary>
        /// Deallocates the product from project and deletes all allocated fulfillment entries
        /// </summary>
        /// <param name="projectId">The project identifier.</param>
        /// <param name="productToDeallocate">The product to deallocate.</param>
        /// <returns>
        /// boolean, if deallocation was successful and all allocated fulfillment entries were delted successfully
        /// </returns>
        /// Erstellt von Joshua Frey, am 12.01.2016
        private bool DeallocateProductFromProject(int projectId, ProjectProduct productToDeallocate)
        {
            bool fulfillmentDeletionSuccessful;
            int idOfProductToDeallocate = productToDeallocate.Product_Id;
            string nameOfProductToDeallocate = productToDeallocate.Product.Name;
            using (FulfillmentController fulfillContr = new FulfillmentController())
            {
                fulfillmentDeletionSuccessful = fulfillContr.DeleteAllFulfillmentsForOneProductInOneProject(projectId, idOfProductToDeallocate);
            }

            if (fulfillmentDeletionSuccessful && DeleteProjectProductFromDb(projectId, idOfProductToDeallocate))
            {
                return true;
            }
            else
            {
                MessageBox.Show(String.Format(@"Bei dem Entkoppeln des Produkts {0} ist ein Fehler aufgetreten."), nameOfProductToDeallocate);
                return false;
            }
        }
        /// <summary>
        /// Allocates the product.
        /// </summary>
        /// <param name="projectId">The project identifier.</param>
        /// <param name="projProd">The proj product.</param>
        /// <returns>
        /// boolean, if allocation to ProjectProduct and Fulfillment table was successful
        /// </returns>
        /// Erstellt von Joshua Frey, am 12.01.2016
        /// <exception cref="NWATException"></exception>
        private bool AllocateProduct(int projectId, ProjectProduct projProd)
        {
            bool insertionProjectProductSuccessful = true;
            bool insertionFulfillmentSuccessful = true;

            int productId = projProd.Product_Id;

            if (productId != 0 && projProd.Project_Id != 0)
            {
                insertionProjectProductSuccessful = InsertProjectProductIntoDb(projProd);

                // get all project criterions to create new fulfillment entries
                List<ProjectCriterion> allProjectCriterions;
                using (ProjectCriterionController projCritCont = new ProjectCriterionController())
                {
                    allProjectCriterions = projCritCont.GetAllProjectCriterionsForOneProject(projectId);
                }

                // create fulfillment entry for this product and each project criterion
                using (FulfillmentController fulfillCont = new FulfillmentController())
                {
                    foreach (ProjectCriterion projCrit in allProjectCriterions)
                    {
                        int criterionId = projCrit.Criterion_Id;

                        // new fulfillment which will be inserted into fulfillment table.
                        // default values for Fulfilled and Comment (false and null)
                        Fulfillment newFulfillment = new Fulfillment()
                        {
                            Project_Id = projectId,
                            Product_Id = productId,
                            Criterion_Id = criterionId,
                            Fulfilled = false,
                            Comment = null
                        };

                        if (!fulfillCont.InsertFullfillmentInDb(newFulfillment))
                        {
                            insertionFulfillmentSuccessful = false;
                            throw (new NWATException(CommonMethods.MessageInsertionToFulFillmentTableFailed(productId, criterionId)));
                        }
                    }
                }
            }
            return insertionFulfillmentSuccessful && insertionProjectProductSuccessful;
        }
 /// <summary>
 /// Imports the project product into database.
 /// </summary>
 /// <param name="importProjProd">The import proj product.</param>
 /// <returns></returns>
 /// Erstellt von Joshua Frey, am 26.01.2016
 public bool ImportProjectProductIntoDb(ProjectProduct importProjProd)
 {
     return InsertProjectProductIntoDb(importProjProd);
 }