Beispiel #1
0
        protected override bool ItemColumnEvaluate(int row, Item item, bool updatePrice)
        {
            if (item == null)
            {
                return(false);
            }

            StockTakingDetail detail = operation.Details [row];
            Item oldItem             = (detail.ItemId >= 0) ? Item.GetById(detail.ItemId) : null;
            bool ret = detail.ItemEvaluate(item, GetOperationPriceGroup(), updatePrice);

            if (ret && (oldItem == null || item.Id != oldItem.Id))
            {
                if (operation.LocationId >= 0 && !editMode)
                {
                    double qtty = useCalculatedAvailability ?
                                  Item.GetAvailabilityAtDate(item.Id, operation.LocationId, date) :
                                  Item.GetAvailability(item.Id, operation.LocationId);
                    detail.EnteredQuantity  = qtty;
                    detail.ExpectedQuantity = qtty;
                    if (qtty > 0)
                    {
                        LotsEvaluate(operation.Details, detail);
                    }
                }
            }
            foreach (StockTakingDetail stockTakingDetail in operation.Details)
            {
                stockTakingDetail.OldPriceIn  = stockTakingDetail.PriceIn * 100 / (100 - stockTakingDetail.Discount);
                stockTakingDetail.OldPriceOut = stockTakingDetail.PriceOut * 100 / (100 - stockTakingDetail.Discount);
            }

            return(ret);
        }
        protected void LoadOperationDetailInfo(IEnumerable <OperationDetail> operationDetails)
        {
            int i = 1;

            foreach (OperationDetail detail in operationDetails)
            {
                Item item = Item.GetById(detail.ItemId);

                details.Add(new TDetail
                {
                    Number         = i.ToString(CultureInfo.InvariantCulture),
                    DetailId       = detail.DetailId,
                    ItemId         = item.Id,
                    ItemCode       = item.Code,
                    ItemName       = item.Name2,
                    MUnitName      = detail.MUnitName,
                    Quantity       = detail.Quantity,
                    LotId          = detail.LotId,
                    Lot            = detail.Lot,
                    SerialNumber   = detail.SerialNumber,
                    ExpirationDate = detail.ExpirationDate,
                    ProductionDate = detail.ProductionDate,
                    LotLocation    = detail.LotLocation,
                    PriceIn        = detail.PriceInDB,
                    VATIn          = detail.VATIn,
                    PriceOut       = detail.PriceOutDB,
                    VATOut         = detail.VATOut,
                    Discount       = detail.Discount,
                    DiscountValue  = detail.DiscountValue,
                    Total          = detail.Total
                });

                i++;
            }
        }
Beispiel #3
0
        private void AddItemShortcut(IntPtr data, string accelPath, uint accelKey, ModifierType accelMods, bool changed)
        {
            long itemId;

            if (IsKeyForItem(accelPath, out itemId) && accelKey != 0 && accelKey != (uint)Key.VoidSymbol)
            {
                ItemShortcut itemShortcut = new ItemShortcut();
                if (!itemShortcut.ItemEvaluate(Item.GetById(itemId), PriceGroup.RegularPrice))
                {
                    return;
                }

                itemShortcut.Shortcut = new AccelKey((Key)accelKey, KeyShortcuts.GetAllowedModifier(accelMods), AccelFlags.Visible);
                itemShortcuts.Add(itemShortcut);
            }
        }
Beispiel #4
0
        protected DocumentDetail(int detailNumber, OperationDetail detail, bool usePriceIn = true)
        {
            this.usePriceIn = usePriceIn;
            Number          = Data.Number.ToEditString(detailNumber);

            Item item = Item.GetById(detail.ItemId);

            ItemCode      = item.Code;
            ItemName      = item.Name2;
            MUnit         = detail.MUnitName;
            Quantity      = Entities.Quantity.ToString(detail.Quantity);
            Discount      = Percent.ToString(detail.Discount);
            DiscountValue = Entities.Currency.ToString(detail.DiscountValue);
            Price         = Entities.Currency.ToString(usePriceIn ? detail.PriceIn : detail.PriceOut, usePriceIn ? PriceType.Purchase : PriceType.Sale);
            Total         = Entities.Currency.ToString(detail.Total, usePriceIn ? PriceType.Purchase : PriceType.Sale);

            Lot            = detail.Lot;
            SerialNumber   = detail.SerialNumber;
            ExpirationDate = detail.ExpirationDate.HasValue ? BusinessDomain.GetFormattedDate(detail.ExpirationDate.Value) : String.Empty;
            ProductionDate = detail.ProductionDate.HasValue ? BusinessDomain.GetFormattedDate(detail.ProductionDate.Value) : String.Empty;
            LotLocation    = detail.LotLocation;
            Note           = detail.Note;
        }
        public void Apply <T> (T operationDetail, Operation <T> operation) where T : OperationDetail
        {
            if (error)
            {
                return;
            }

            switch (Type)
            {
            case PriceRule.ActionType.AddGood:
                if (operation != null)
                {
                    foreach (T detail in GetDetailsForPromotionalItems <T> (formula))
                    {
                        if (operation.OperationType == OperationType.RestaurantOrder)
                        {
                            detail.LotId = Int32.MinValue;
                        }
                        detail.PromotionForDetailHashCode = operationDetail.GetHashCode();
                        operation.Details.Add(detail);
                        operationDetail.AppliedPriceRules |= PriceRule.AppliedActions.PromotionalItemSource;
                    }
                }
                break;

            case PriceRule.ActionType.Price:
                PriceGroup priceGroup;
                string []  parts = GetPriceExpressionParts(formula, out priceGroup);
                if (parts.Length > 1)
                {
                    double price;
                    switch (priceGroup)
                    {
                    case PriceGroup.TradeInPrice:
                        price = operationDetail.OriginalPriceIn;
                        break;

                    case PriceGroup.RegularPriceInOperation:
                        price = operationDetail.OriginalPriceOut;
                        break;

                    default:
                        Item item = Item.GetById(operationDetail.ItemId);
                        price = item.GetPriceGroupPrice(priceGroup);
                        break;
                    }

                    try {
                        operationDetail.OriginalPriceOut = RPNCalculator.EvaluateExpression(price + parts [1] + parts [2]);
                    } catch (Exception ex) {
                        ErrorHandling.LogException(ex);
                        break;
                    }
                }
                else
                {
                    operationDetail.OriginalPriceOut = Double.Parse(parts [0], CultureInfo.InvariantCulture);
                }

                operationDetail.PriceOutEvaluate();
                operationDetail.AppliedPriceRules |= PriceRule.AppliedActions.PriceChanged;
                break;

            case PriceRule.ActionType.Discount:
                operationDetail.DiscountEvaluate((double)values [0]);
                operationDetail.AppliedPriceRules |= PriceRule.AppliedActions.DiscountChanged;
                break;
            }
        }
        protected override bool OperationDetailsValidate(bool showWarning)
        {
            if (operation.DetailsMat.Count == 0)
            {
                return(false);
            }

            CurrentColumnEvaluate();
            bool hasValidMaterialQuantities = false;

            for (int i = operation.DetailsMat.Count - 1; i >= 0; i--)
            {
                try {
                    // Validate Item
                    string itemName = operation.DetailsMat [i].ItemName;
                    // If the gooods field is empty then this line has to be skipped
                    if (itemName.Length == 0)
                    {
                        // If this is not the first line then delete it
                        if (i > 0)
                        {
                            operation.DetailsMat.RemoveAt(i);
                            continue;
                        }

                        OperationDetailValidationWarning(Translator.GetString("There are no valid materials in the production document!"), showWarning);
                        EditGridField(0, colItem.Index);
                        return(false);
                    }

                    Item item = Item.GetById(operation.DetailsMat [i].ItemId);
                    if (item == null || item.Name != itemName)
                    {
                        OperationDetailValidationWarning(string.Format(Translator.GetString("Invalid material at row {0}!"), i + 1), showWarning);
                        EditGridField(i, operation.DetailsMat [i].SourceRecipe != null ? colQuantity.Index : colItem.Index);
                        return(false);
                    }

                    // Validate quantity
                    double qty = operation.DetailsMat [i].Quantity;
                    if ((!editMode && qty <= 0) || (editMode && qty < 0))
                    {
                        OperationDetailValidationWarning(string.Format(Translator.GetString("Invalid quantity of material \"{0}\"!"), item.Name), showWarning);
                        EditGridField(i, colQuantity.Index);
                        return(false);
                    }
                    if (operation.DetailsMat [i].SourceRecipe == null &&
                        !BusinessDomain.AppConfiguration.AutoProduction &&
                        BusinessDomain.AppConfiguration.ItemsManagementUseLots &&
                        operation.DetailsMat [i].LotId <= 0)
                    {
                        OperationDetailValidationWarning(string.Format(Translator.GetString("The sale cannot be saved due to insufficient quantity of item \"{0}\"."), item.Name), showWarning);
                        EditGridField(i, colQuantity.Index);
                        return(false);
                    }

                    if (qty > 0)
                    {
                        hasValidMaterialQuantities = true;
                    }
                } catch {
                    OperationDetailValidationWarning(string.Format(Translator.GetString("Error at row {0}!"), i + 1), showWarning);
                    EditGridField(i, operation.DetailsMat [i].SourceRecipe != null ? colQuantity.Index : colItem.Index);
                    return(false);
                }
            }

            if (!hasValidMaterialQuantities)
            {
                if (editMode)
                {
                    ResponseType ret = OperationDetailValidationQuestion(Translator.GetString("There are no materials with quantities greater than 0! The production will be deleted. Are you sure?"), showWarning);
                    if (ret == ResponseType.No)
                    {
                        return(false);
                    }
                }
                else
                {
                    OperationDetailValidationWarning(Translator.GetString("The production must contain at least one material with quantity greater than 0."), showWarning);
                    return(false);
                }
            }

            bool hasValidProductQuantities = false;

            for (int i = operation.DetailsProd.Count - 1; i >= 0; i--)
            {
                try {
                    // Validate Item
                    string itemName = operation.DetailsProd [i].ItemName;
                    // If the gooods field is empty then this line has to be skipped
                    if (itemName.Length == 0)
                    {
                        // If this is not the first line then delete it
                        if (i > 0)
                        {
                            operation.DetailsProd.RemoveAt(i);
                            continue;
                        }

                        OperationDetailValidationWarning(Translator.GetString("There are no valid products in the production document!"), showWarning);
                        EditSecondGridField(0, colItem.Index);
                        return(false);
                    }

                    Item item = Item.GetById(operation.DetailsProd [i].ItemId);
                    if (item == null || item.Name != itemName)
                    {
                        OperationDetailValidationWarning(string.Format(Translator.GetString("Invalid product at row {0}!"), i + 1), showWarning);
                        EditSecondGridField(i, operation.DetailsMat [i].SourceRecipe != null ? colSecondQuantity.Index : colSecondItem.Index);
                        return(false);
                    }

                    // Validate quantity
                    double qty = operation.DetailsProd [i].Quantity;
                    if ((!editMode && qty <= 0) || (editMode && qty < 0))
                    {
                        OperationDetailValidationWarning(string.Format(Translator.GetString("Invalid quantity of product \"{0}\"!"), item.Name), showWarning);
                        EditSecondGridField(i, colQuantity.Index);
                        return(false);
                    }

                    if (qty > 0)
                    {
                        hasValidProductQuantities = true;
                    }
                } catch {
                    OperationDetailValidationWarning(string.Format(Translator.GetString("Error at row {0}!"), i + 1), showWarning);
                    EditSecondGridField(i, operation.DetailsMat [i].SourceRecipe != null ? colSecondQuantity.Index : colSecondItem.Index);
                    return(false);
                }
            }

            if (!hasValidProductQuantities)
            {
                if (editMode)
                {
                    ResponseType ret = OperationDetailValidationQuestion(Translator.GetString("There are no products with quantities greater than 0! The recipe will be deleted. Are you sure?"), showWarning);
                    if (ret == ResponseType.No)
                    {
                        return(false);
                    }
                }
                else
                {
                    OperationDetailValidationWarning(Translator.GetString("The recipe must contain at least one product with quantity greater than 0."), showWarning);
                    return(false);
                }
            }

            for (int i = 0; i < operation.DetailsMat.Count; i++)
            {
                ComplexProductionDetail detMat = operation.DetailsMat [i];
                if (operation.DetailsProd.All(detProd => detMat.ItemId != detProd.ItemId))
                {
                    continue;
                }

                OperationDetailValidationWarning(string.Format(Translator.GetString("The item \"{0}\" is used as a material and as a product!"), detMat.ItemName), showWarning);
                EditGridField(i, colItem.Index);
                return(false);
            }

            if (!hasValidMaterialQuantities || !hasValidProductQuantities)
            {
                operation.ClearDetails();
            }

            CancelEditing();
            return(true);
        }
        public static void OpenEntityForEdit(SourceItemId entity)
        {
            object id;
            long   intId;
            object type;

            switch (entity.Table)
            {
            case DbTable.Unknown:
                break;

            case DbTable.ApplicationLog:
                break;

            case DbTable.Cashbook:
                break;

            case DbTable.Configuration:
                break;

            case DbTable.Currencies:
                break;

            case DbTable.CurrenciesHistory:
                break;

            case DbTable.Documents:
                id   = entity [DataField.DocumentOperationNumber];
                type = entity [DataField.DocumentType];
                if (type == null)
                {
                    break;
                }

                try {
                    type  = Enum.ToObject(typeof(OperationType), type);
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                FormHelper.EditOperation((OperationType)type, intId);
                break;

            case DbTable.EcrReceipts:
                break;

            case DbTable.Items:
                id = entity [DataField.ItemId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditGoodsbtnEdit") != UserRestrictionState.Allowed)
                {
                    break;
                }

                using (EditNewItem dialog = new EditNewItem(Item.GetById(intId)))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetItem().CommitChanges();
                    }
                break;

            case DbTable.ItemsGroups:
                id = entity [DataField.ItemGroupId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditGoodsbtnEdit") != UserRestrictionState.Allowed)
                {
                    break;
                }

                using (EditNewGroup <ItemsGroup> dialog = new EditNewGroup <ItemsGroup> (ItemsGroup.GetById(intId), ItemsGroup.GetAll()))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetGroup().CommitChanges();
                    }
                break;

            case DbTable.InternalLog:
                break;

            case DbTable.Lots:
                break;

            case DbTable.Network:
                break;

            case DbTable.NextAcct:
                break;

            case DbTable.Objects:
                id = entity [DataField.LocationId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditObjectsbtnEdit") != UserRestrictionState.Allowed)
                {
                    break;
                }

                using (EditNewLocation dialog = new EditNewLocation(Location.GetById(intId)))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetLocation().CommitChanges();
                    }
                break;

            case DbTable.ObjectsGroups:
                id = entity [DataField.LocationsGroupsId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditObjectsbtnEdit") != UserRestrictionState.Allowed)
                {
                    break;
                }

                using (EditNewGroup <LocationsGroup> dialog = new EditNewGroup <LocationsGroup> (LocationsGroup.GetById(intId), LocationsGroup.GetAll()))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetGroup().CommitChanges();
                    }
                break;

            case DbTable.Operations:
                type = entity [DataField.OperationType];
                if (type == null)
                {
                    break;
                }

                id = entity [DataField.OperationNumber];
                try {
                    type  = Enum.ToObject(typeof(OperationType), type);
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                FormHelper.EditOperation((OperationType)type, intId);
                break;

            case DbTable.OperationDetails:
                break;

            case DbTable.OperationType:
                break;

            case DbTable.Partners:
                id = entity [DataField.PartnerId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditPartnersbtnEdit") != UserRestrictionState.Allowed)
                {
                    break;
                }

                using (EditNewPartner dialog = new EditNewPartner(Partner.GetById(intId)))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetPartner().CommitChanges();
                    }
                break;

            case DbTable.PartnersGroups:
                id = entity [DataField.PartnersGroupsId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditPartnersbtnEdit") != UserRestrictionState.Allowed)
                {
                    break;
                }

                using (EditNewGroup <PartnersGroup> dialog = new EditNewGroup <PartnersGroup> (PartnersGroup.GetById(intId), PartnersGroup.GetAll()))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetGroup().CommitChanges();
                    }
                break;

            case DbTable.Payments:
                type = entity [DataField.PaymentOperationType];
                if (type == null)
                {
                    break;
                }

                id = entity [DataField.PaymentOperationId];
                try {
                    type  = Enum.ToObject(typeof(OperationType), type);
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditPaysPaymentsbtnEdit") != UserRestrictionState.Allowed)
                {
                    break;
                }

                Operation oper = Operation.GetById((OperationType)type, intId);
                if (oper == null)
                {
                    break;
                }

                using (EditNewPayment dialog = new EditNewPayment(oper))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            oper.CommitPayments();
                    }
                break;

            case DbTable.PaymentTypes:
                id = entity [DataField.PaymentTypesId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                using (EditNewPaymentType dialog = new EditNewPaymentType(PaymentType.GetById(intId)))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetPaymentType().CommitChanges();
                    }
                break;

            case DbTable.PriceRules:
                break;

            case DbTable.Registration:
                break;

            case DbTable.Store:
                break;

            case DbTable.System:
                break;

            case DbTable.Transformations:
                break;

            case DbTable.Users:
                EditUser(entity [DataField.UserId]);
                break;

            case DbTable.OperationUsers:
                EditUser(entity [DataField.OperationsUserId]);
                break;

            case DbTable.OperationOperators:
                EditUser(entity [DataField.OperationsOperatorId]);
                break;

            case DbTable.UsersGroup:
                EditUserGroup(entity [DataField.UsersGroupsId]);
                break;

            case DbTable.OperationUsersGroup:
                EditUserGroup(entity [DataField.OperationsUsersGroupsId]);
                break;

            case DbTable.OperationOperatorsGroup:
                EditUserGroup(entity [DataField.OperationsOperatorsGroupsId]);
                break;

            case DbTable.UsersSecurity:
                break;

            case DbTable.VatGroups:
                id = entity [DataField.VATGroupId];
                try {
                    intId = Convert.ToInt64(id);
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                    break;
                }

                if (BusinessDomain.RestrictionTree.GetRestriction("mnuEditVATGroupsbtnEdit") != UserRestrictionState.Allowed)
                {
                    return;
                }

                using (EditNewVATGroup dialog = new EditNewVATGroup(VATGroup.GetById(intId)))
                    if (dialog.Run() == ResponseType.Ok)
                    {
                        using (new DbMasterScope(BusinessDomain.DataAccessProvider))
                            dialog.GetVATGroup().CommitChanges();
                    }
                break;
            }
        }
        private bool OperationDetailsValidate()
        {
            #region Validate materials

            if (recipe.DetailsMat.Count == 0)
            {
                return(false);
            }

            MatCurrentColumnEvaluate();
            bool hasValidMaterialQuantities = false;

            for (int i = recipe.DetailsMat.Count - 1; i >= 0; i--)
            {
                try {
                    // Validate Item
                    string itemName = recipe.DetailsMat [i].ItemName.Trim();
                    // If the gooods field is empty then this line has to be skipped
                    if (itemName.Length == 0)
                    {
                        // If this is not the first line then delete it
                        if (i > 0)
                        {
                            recipe.DetailsMat.RemoveAt(i);
                            continue;
                        }

                        DetailsValidationWarning(Translator.GetString("There are no valid materials!"));
                        MatEditGridField(0, colItem.Index);
                        return(false);
                    }

                    Item item = Item.GetById(recipe.DetailsMat [i].ItemId);
                    if (item == null || item.Name != itemName)
                    {
                        DetailsValidationWarning(string.Format(Translator.GetString("Invalid item at row {0}!"), i + 1));
                        MatEditGridField(i, colItem.Index);
                        return(false);
                    }

                    // Validate quantity
                    double qty = recipe.DetailsMat [i].Quantity;
                    if ((!editMode && qty <= 0) || (editMode && qty < 0))
                    {
                        DetailsValidationWarning(string.Format(Translator.GetString("Invalid quantity of item \"{0}\"!"), item.Name));
                        MatEditGridField(i, colQuantity.Index);
                        return(false);
                    }

                    if (qty > 0)
                    {
                        hasValidMaterialQuantities = true;
                    }
                } catch {
                    DetailsValidationWarning(string.Format(Translator.GetString("Error at row {0}!"), i + 1));
                    MatEditGridField(i, colItem.Index);
                    return(false);
                }
            }

            if (!hasValidMaterialQuantities)
            {
                if (editMode)
                {
                    ResponseType ret = DetailsValidationQuestion(Translator.GetString("There are no materials with quantities greater than 0! The recipe will be deleted. Are you sure?"));
                    if (ret == ResponseType.No)
                    {
                        return(false);
                    }
                }
                else
                {
                    DetailsValidationWarning(Translator.GetString("The recipe must contain at least one material with quantity greater than 0."));
                    return(false);
                }
            }


            #endregion

            #region Validate products

            if (recipe.DetailsProd.Count == 0)
            {
                return(false);
            }

            ProdCurrentColumnEvaluate();
            bool hasValidProductQuantities = false;

            for (int i = recipe.DetailsProd.Count - 1; i >= 0; i--)
            {
                try {
                    // Validate Item
                    string itemName = recipe.DetailsProd [i].ItemName.Trim();
                    // If the gooods field is empty then this line has to be skipped
                    if (itemName.Length == 0)
                    {
                        // If this is not the first line then delete it
                        if (i > 0)
                        {
                            recipe.DetailsProd.RemoveAt(i);
                            continue;
                        }

                        DetailsValidationWarning(Translator.GetString("There are no valid products!"));
                        ProdEditGridField(0, colSecondItem.Index);
                        return(false);
                    }

                    Item item = Item.GetById(recipe.DetailsProd [i].ItemId);
                    if (item == null || item.Name != itemName)
                    {
                        DetailsValidationWarning(string.Format(Translator.GetString("Invalid item at row {0}!"), i + 1));
                        ProdEditGridField(i, colSecondItem.Index);
                        return(false);
                    }

                    // Validate quantity
                    double qty = recipe.DetailsProd [i].Quantity;
                    if ((!editMode && qty <= 0) || (editMode && qty < 0))
                    {
                        DetailsValidationWarning(string.Format(Translator.GetString("Invalid quantity of item \"{0}\"!"), item.Name));
                        ProdEditGridField(i, colSecondQuantity.Index);
                        return(false);
                    }

                    if (qty > 0)
                    {
                        hasValidProductQuantities = true;
                    }
                } catch {
                    DetailsValidationWarning(string.Format(Translator.GetString("Error at row {0}!"), i + 1));
                    ProdEditGridField(i, colSecondItem.Index);
                    return(false);
                }
            }

            if (hasValidMaterialQuantities && !hasValidProductQuantities)
            {
                if (editMode)
                {
                    ResponseType ret = DetailsValidationQuestion(Translator.GetString("There are no products with quantities greater than 0! The recipe will be deleted. Are you sure?"));
                    if (ret == ResponseType.No)
                    {
                        return(false);
                    }
                }
                else
                {
                    DetailsValidationWarning(Translator.GetString("The recipe must contain at least one product with quantity greater than 0."));
                    return(false);
                }
            }

            #endregion

            for (int i = 0; i < recipe.DetailsMat.Count; i++)
            {
                ComplexRecipeDetail detMat = recipe.DetailsMat [i];
                foreach (ComplexRecipeDetail detProd in recipe.DetailsProd)
                {
                    if (detMat.ItemId != detProd.ItemId)
                    {
                        continue;
                    }

                    DetailsValidationWarning(string.Format(Translator.GetString("The item \"{0}\" is used as a material and as a product!"), detMat.ItemName));
                    MatEditGridField(i, colItem.Index);
                    return(false);
                }
            }

            if (!hasValidMaterialQuantities || !hasValidProductQuantities)
            {
                recipe.ClearDetails();
            }

            return(true);
        }