/// <summary>
        /// Removes all material and production details which use the specified recipe.
        /// </summary>
        /// <param name="recipe">The recipe that marks the details to remove.</param>
        public void RemoveRecipe(ComplexRecipe recipe)
        {
            for (int i = DetailsMat.Count - 1; i >= 0; i--)
            {
                if (DetailsMat [i].SourceRecipe.Id == recipe.Id)
                {
                    DetailsMat.RemoveAt(i);
                }
            }

            for (int i = DetailsProd.Count - 1; i >= 0; i--)
            {
                if (DetailsProd [i].SourceRecipe.Id == recipe.Id)
                {
                    DetailsProd.RemoveAt(i);
                }
            }
        }
        public override void ClearDetails(bool logChange = true)
        {
            if (State == OperationState.Saved || State == OperationState.Draft)
            {
                foreach (ComplexProductionDetail detail in DetailsMat)
                {
                    detail.Quantity = 0;
                }

                foreach (ComplexProductionDetail detail in DetailsProd)
                {
                    detail.Quantity = 0;
                }
            }
            else
            {
                DetailsMat.Clear();
                DetailsProd.Clear();
            }
        }
        public override void ClearDetails(bool logChange = true)
        {
            if (id < 0)
            {
                DetailsMat.Clear();
                DetailsProd.Clear();
            }
            else
            {
                foreach (ComplexRecipeDetail detail in DetailsMat)
                {
                    detail.Quantity = 0;
                }

                foreach (ComplexRecipeDetail detail in DetailsProd)
                {
                    detail.Quantity = 0;
                }
            }
        }
        public void RecalculatePrices()
        {
            if (DetailsMat.Any(d => d.SourceRecipe != null))
            {
                foreach (var materials in DetailsMat.ToLookup(d => d.SourceRecipe, d => d))
                {
                    var g        = materials;
                    var products = DetailsProd.Where(d => ReferenceEquals(g.Key, d.SourceRecipe)).ToList();

                    RecalculateProductPrices(materials, products);
                }
            }
            else
            {
                foreach (var materials in DetailsMat.ToLookup(d => d.Note, d => d))
                {
                    var g        = materials;
                    var products = DetailsProd.Where(d => g.Key == d.Note).ToList();

                    RecalculateProductPrices(materials, products);
                }
            }
        }
        public override void Commit()
        {
            bool editMode = true;

            using (DbTransaction transaction = new DbTransaction(BusinessDomain.DataAccessProvider)) {
                transaction.SnapshotObject(this);
                if (BusinessDomain.AppConfiguration.AutoProduction)
                {
                    if (AutomaticProduction())
                    {
                        RecalculatePrices();
                    }
                }

                // Create a new operation Id if needed);
                OperationState operationState = State;
                if (operationState == OperationState.New || operationState == OperationState.NewDraft || operationState == OperationState.NewPending)
                {
                    id       = CreateNewId();
                    editMode = false;

                    if (BusinessDomain.AppConfiguration.ItemsManagementUseLots)
                    {
                        foreach (ComplexProductionDetail detail in DetailsProd)
                        {
                            if (detail.ProductionDate == null)
                            {
                                detail.ProductionDate = Date;
                            }
                        }
                    }
                }

                LotsEvaluate(DetailsMat);

                // Save the output ComplexProduction in the database
                OperationType = OperationType.ComplexProductionMaterial;
                foreach (ComplexProductionDetail detail in DetailsMat)
                {
                    detail.ReferenceDocumentId = id;
                    detail.ResetSign(-1);
                }
                BusinessDomain.DataAccessProvider.AddUpdateComplexProductionMat(this, DetailsMat.ToArray(), BusinessDomain.AppConfiguration.AllowNegativeAvailability);

                // Save the input ComplexProduction in the database
                OperationType = OperationType.ComplexProductionProduct;
                foreach (ComplexProductionDetail detail in DetailsProd)
                {
                    detail.ReferenceDocumentId = id;
                    detail.ResetSign(1);
                }
                BusinessDomain.DataAccessProvider.AddUpdateComplexProductionProd(this, DetailsProd.ToArray(), BusinessDomain.AppConfiguration.AllowNegativeAvailability);
                Item.Cache.Clear(DetailsProd.Select(d => d.ItemId));

                if (editMode && Total.IsZero())
                {
                    BusinessDomain.DataAccessProvider.DeleteOperationId(OperationType.ComplexProductionMaterial, id);

                    ApplicationLogEntry.AddNew(string.Format(Translator.GetString("Void production No.{0} from {1}"), GetFormattedOperationNumber(id), BusinessDomain.GetFormattedDate(date)));
                }
                else if (editMode)
                {
                    ApplicationLogEntry.AddNew(string.Format(Translator.GetString("Edit production No.{0} from {1}"), GetFormattedOperationNumber(id), BusinessDomain.GetFormattedDate(date)));
                }

                if (editMode)
                {
                    RemoveAllEmptyDetails();
                }

                transaction.Complete();
            }
        }
 public override ComplexRecipeDetail AddNewAdditionalDetail()
 {
     return((ComplexRecipeDetail)DetailsProd.AddNew());
 }
        public ComplexRecipe CommitChanges()
        {
            bool editMode = true;

            try {
                using (DbTransaction transaction = new DbTransaction(BusinessDomain.DataAccessProvider)) {
                    // Create a new operation Id if needed
                    if (State == OperationState.New || State == OperationState.NewDraft)
                    {
                        id       = CreateNewId();
                        editMode = false;
                    }

                    // Save the output ComplexRecipe in the database
                    OperationType = OperationType.ComplexRecipeMaterial;
                    foreach (ComplexRecipeDetail detail in DetailsMat)
                    {
                        detail.Note = name;
                    }
                    BusinessDomain.DataAccessProvider.AddUpdateComplexRecipeMat(this, DetailsMat.ToArray());

                    // Save the input ComplexRecipe in the database
                    OperationType = OperationType.ComplexRecipeProduct;
                    foreach (ComplexRecipeDetail detail in DetailsProd)
                    {
                        detail.Note = name;
                    }
                    BusinessDomain.DataAccessProvider.AddUpdateComplexRecipeProd(this, DetailsProd.ToArray());

                    if (editMode && Total.IsZero())
                    {
                        BusinessDomain.DataAccessProvider.DeleteOperationId(OperationType.ComplexRecipeMaterial, id);

                        string format = Translator.GetString("Void recipe No.{0} from {1}");
                        ApplicationLogEntry.AddNew(string.Format(format, GetFormattedOperationNumber(id),
                                                                 BusinessDomain.GetFormattedDate(date)));
                    }
                    else if (editMode)
                    {
                        string format = Translator.GetString("Edit recipe No.{0} from {1}");
                        ApplicationLogEntry.AddNew(string.Format(format, GetFormattedOperationNumber(id),
                                                                 BusinessDomain.GetFormattedDate(date)));
                    }

                    if (editMode)
                    {
                        RemoveAllEmptyDetails();
                    }

                    transaction.Complete();
                }
            } catch {
                if (!editMode)
                {
                    id = -1;
                }

                throw;
            }

            return(this);
        }