public bool CheckApplicableToDetail <T> (IList <T> operationDetails, OperationDetail operationDetail) where T : OperationDetail
        {
            if (error)
            {
                return(false);
            }

            bool ret;

            switch (type)
            {
            case PriceRule.ConditionType.Good:
                ret = operationDetail.ItemId == Convert.ToInt64(values [0]);
                break;

            case PriceRule.ConditionType.GoodGroup:
                ItemsGroup itemsGroup = ItemsGroup.Cache.GetById(operationDetail.ItemGroupId);

                string groupCode = null;
                long?  intValue  = PriceRule.GetLongValue(formula);
                if (intValue != null)
                {
                    ItemsGroup byId = ItemsGroup.Cache.GetById(intValue.Value);
                    if (byId != null)
                    {
                        groupCode = byId.Code;
                    }
                }

                if (groupCode == null)
                {
                    groupCode = PriceRule.GetStringValue(formula);
                }

                ret = itemsGroup.Code.StartsWith(groupCode);
                break;

            case PriceRule.ConditionType.GoodQttySum:
                double from;
                double to;
                GetConditionNumericInterval(formula, out from, out to);
                double quantity = operationDetails
                                  .Where(detail => detail.ItemId == operationDetail.ItemId)
                                  .Select(detail => detail.Quantity)
                                  .Sum();
                ret = from <= quantity && quantity <= to;
                break;

            default:
                return(true);
            }

            return(ret != IsException);
        }
예제 #2
0
        private void SetFormula(string value)
        {
            if (formula == value)
            {
                return;
            }

            formula = value;
            values  = null;
            string stringValue;

            switch (Type)
            {
            case PriceRule.ActionType.Stop:
            case PriceRule.ActionType.Exit:
            case PriceRule.ActionType.Message:
                values = new object [] { PriceRule.GetStringValue(formula, ' ') };
                break;

            case PriceRule.ActionType.Email:
                stringValue = PriceRule.GetStringValue(formula, ' ');
                if (stringValue == null)
                {
                    break;
                }

                int lastIndexOf = stringValue.LastIndexOf('|');
                if (lastIndexOf < 0)
                {
                    break;
                }

                values = new object [] { stringValue.Substring(lastIndexOf + 1), stringValue.Substring(0, lastIndexOf) };
                break;

            case PriceRule.ActionType.AddGood:
            case PriceRule.ActionType.AddGlobalGood:
                List <SaleDetail> details = GetDetailsForPromotionalItems <SaleDetail> (formula);
                if (details != null)
                {
                    values = details.Cast <object> ().ToArray();
                }
                break;

            case PriceRule.ActionType.Price:
                PriceGroup priceGroup;
                string []  priceParts = GetPriceExpressionParts(formula, out priceGroup);
                if (priceParts == null || priceParts.Length == 0)
                {
                    break;
                }

                double price;
                if (priceParts.Length > 1)
                {
                    OperatorType operatorType;
                    switch (priceParts [1].ToLowerInvariant())
                    {
                    case "+":
                    case "plus":
                        operatorType = OperatorType.Plus;
                        break;

                    case "-":
                    case "minus":
                        operatorType = OperatorType.Minus;
                        break;

                    case "*":
                        operatorType = OperatorType.Multiply;
                        break;

                    case "/":
                        operatorType = OperatorType.Divide;
                        break;

                    default:
                        operatorType = OperatorType.Unknown;
                        break;
                    }
                    if (operatorType == OperatorType.Unknown)
                    {
                        break;
                    }

                    if (Double.TryParse(priceParts [2], NumberStyles.Any, CultureInfo.InvariantCulture, out price))
                    {
                        values = new object [] { priceGroup, operatorType, price }
                    }
                    ;
                }
                else
                if (Double.TryParse(priceParts [0], NumberStyles.Any, CultureInfo.InvariantCulture, out price))
                {
                    values = new object [] { price }
                }
                ;
                break;

            case PriceRule.ActionType.Discount:
                values = new object [] { PriceRule.GetDoubleValue(formula) };
                break;

            case PriceRule.ActionType.ServiceCharge:
                string [] itemWithPercent = formula.Split(';');
                if (itemWithPercent.Length < 2)
                {
                    break;
                }

                long?itemId = PriceRule.GetLongValue(itemWithPercent [0]);
                if (itemId == null)
                {
                    break;
                }

                Item item = Item.Cache.GetById(itemId.Value);
                if (item == null)
                {
                    break;
                }

                string s = PriceRule.GetStringValue(itemWithPercent [1]);
                if (s == null)
                {
                    break;
                }

                double result;
                values = new [] { item,
                                  Double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result) ? (object)result : s };
                break;

            case PriceRule.ActionType.Payment:
            case PriceRule.ActionType.AskAdvancePayment:
                stringValue = PriceRule.GetStringValue(formula, ' ');
                if (stringValue == null)
                {
                    break;
                }

                try {
                    List <Token> tokens = RPNCalculator.ParseTokens(stringValue);
                    if (tokens.Count > 0)
                    {
                        values = new object [] { ((Operand)tokens [0]).Value }
                    }
                    ;
                } catch (Exception ex) {
                    ErrorHandling.LogException(ex);
                }
                break;
            }

            error = values == null || values.All(v => v == null);
        }
        private void SetFormula(string value)
        {
            if (formula == value)
            {
                return;
            }

            formula = value;
            values  = null;
            switch (type)
            {
            case PriceRule.ConditionType.Partner:
            case PriceRule.ConditionType.Object:
            case PriceRule.ConditionType.User:
            case PriceRule.ConditionType.Good:
            case PriceRule.ConditionType.ContainsGood:
                values = new object [] { PriceRule.GetLongValue(formula) };
                break;

            case PriceRule.ConditionType.PartnerGroup:
            case PriceRule.ConditionType.ObjectGroup:
            case PriceRule.ConditionType.UserGroup:
            case PriceRule.ConditionType.GoodGroup:
            case PriceRule.ConditionType.ContainsGGroup:
                values = new object [] { PriceRule.GetStringValue(formula) };
                break;

            case PriceRule.ConditionType.Time:
            case PriceRule.ConditionType.Date:
                DateTime dateTimeFrom;
                DateTime dateTimeTo;
                GetConditionDateTimeInterval(formula, out dateTimeFrom, out dateTimeTo);
                values = new object [] { dateTimeFrom, dateTimeTo };
                break;

            case PriceRule.ConditionType.DocumentSum:
            case PriceRule.ConditionType.TurnoverSum:
            case PriceRule.ConditionType.GoodQttySum:
            case PriceRule.ConditionType.PaymentSum:
            case PriceRule.ConditionType.UnpaidDocumentsSum:
                double from;
                double to;
                GetConditionNumericInterval(formula, out from, out to);
                values = new [] { from.IsEqualTo(Double.MinValue) ? (object)null : from, to.IsEqualTo(Double.MaxValue) ? (object)null : to };
                break;

            case PriceRule.ConditionType.Weekdays:
                values = new object [] { GetRuleWeekDays() };
                break;

            case PriceRule.ConditionType.PaymentTypeUsed:
                values = new object [] { GetConditionPaymentTypes() };
                break;

            case PriceRule.ConditionType.DatabaseUpdated:
                values = new object [] { 30 };
                break;
            }

            error = values == null || values.All(v => v == null);
        }
        public bool CheckApplicableToOperation <T> (Operation <T> operation) where T : OperationDetail
        {
            if (error)
            {
                return(false);
            }

            DateTime dateFrom;
            DateTime dateTo;
            double   @from;
            double   to;
            bool     ret;
            string   groupCode = null;
            long?    intValue;

            switch (type)
            {
            case PriceRule.ConditionType.Partner:
                ret = operation.PartnerId == Convert.ToInt64(values [0]);
                break;

            case PriceRule.ConditionType.PartnerGroup:
                intValue = PriceRule.GetLongValue(formula);
                if (intValue != null)
                {
                    PartnersGroup byId = PartnersGroup.Cache.GetById(intValue.Value);
                    if (byId != null)
                    {
                        groupCode = byId.Code;
                    }
                }

                if (groupCode == null)
                {
                    groupCode = PriceRule.GetStringValue(formula);
                }

                Partner partner = Partner.Cache.GetById(operation.PartnerId);
                ret = PartnersGroup.Cache.GetById(partner.GroupId).Code.StartsWith(groupCode);
                break;

            case PriceRule.ConditionType.Object:
                ret = operation.LocationId == Convert.ToInt64(values [0]);
                break;

            case PriceRule.ConditionType.ObjectGroup:
                intValue = PriceRule.GetLongValue(formula);
                if (intValue != null)
                {
                    LocationsGroup byId = LocationsGroup.Cache.GetById(intValue.Value);
                    if (byId != null)
                    {
                        groupCode = byId.Code;
                    }
                }

                if (groupCode == null)
                {
                    groupCode = PriceRule.GetStringValue(formula);
                }

                Location location = Location.Cache.GetById(operation.LocationId);
                ret = LocationsGroup.Cache.GetById(location.GroupId).Code.StartsWith(groupCode);
                break;

            case PriceRule.ConditionType.User:
                ret = operation.UserId == Convert.ToInt64(values [0]);
                break;

            case PriceRule.ConditionType.UserGroup:
                intValue = PriceRule.GetLongValue(formula);
                if (intValue != null)
                {
                    UsersGroup byId = UsersGroup.Cache.GetById(intValue.Value);
                    if (byId != null)
                    {
                        groupCode = byId.Code;
                    }
                }

                if (groupCode == null)
                {
                    groupCode = PriceRule.GetStringValue(formula);
                }

                User user = User.Cache.GetById(operation.UserId);
                ret = UsersGroup.Cache.GetById(user.GroupId).Code.StartsWith(groupCode);
                break;

            case PriceRule.ConditionType.Time:
                GetConditionDateTimeInterval(formula, out dateFrom, out dateTo);
                DateTime now = BusinessDomain.Now;
                if (dateFrom.TimeOfDay < dateTo.TimeOfDay)
                {
                    ret = dateFrom.TimeOfDay <= now.TimeOfDay && now.TimeOfDay <= dateTo.TimeOfDay;
                }
                else
                {
                    ret = dateFrom.TimeOfDay <= now.TimeOfDay || now.TimeOfDay <= dateTo.TimeOfDay;
                }
                break;

            case PriceRule.ConditionType.Date:
                GetConditionDateTimeInterval(formula, out dateFrom, out dateTo);
                ret = dateFrom <= operation.Date && operation.Date <= dateTo;
                break;

            case PriceRule.ConditionType.DocumentSum:
                GetConditionNumericInterval(formula, out from, out to);
                ret = from <= operation.Total && operation.Total <= to;
                break;

            case PriceRule.ConditionType.TurnoverSum:
                GetConditionNumericInterval(formula, out from, out to);
                double turnover = Partner.GetTurnover(operation.PartnerId);
                ret = from <= turnover && turnover <= to;
                break;

            case PriceRule.ConditionType.PaymentSum:
                GetConditionNumericInterval(formula, out from, out to);
                double debt = Partner.GetDebt(operation.PartnerId);
                ret = from <= debt && debt <= to;
                break;

            case PriceRule.ConditionType.Weekdays:
                List <DayOfWeek> ruleWeekDays = GetRuleWeekDays();
                ret = ruleWeekDays.Contains(operation.Date.DayOfWeek);
                break;

            case PriceRule.ConditionType.UnpaidDocumentsSum:
                GetConditionNumericInterval(formula, out from, out to);
                double sum = Partner.GetUnpaidAmountWithExpiredDueDate(operation.PartnerId, operation.Date);
                ret = from <= sum && sum <= to;
                break;

            case PriceRule.ConditionType.ContainsGood:
                intValue = Convert.ToInt64(values [0]);
                ret      = operation.Details.Any(d => d.ItemId == intValue) ||
                           operation.AdditionalDetails.Any(d => d.ItemId == intValue);
                break;

            case PriceRule.ConditionType.GoodGroup:
            case PriceRule.ConditionType.ContainsGGroup:
                Dictionary <long, string> codes = new Dictionary <long, string> ();

                foreach (T detail in operation.Details)
                {
                    AddGroupCode(codes, detail.ItemGroupId);
                }

                foreach (T additionalDetail in operation.AdditionalDetails)
                {
                    AddGroupCode(codes, additionalDetail.ItemGroupId);
                }

                intValue = PriceRule.GetLongValue(formula);
                if (intValue != null)
                {
                    ItemsGroup byId = ItemsGroup.Cache.GetById(intValue.Value);
                    if (byId != null)
                    {
                        groupCode = byId.Code;
                    }
                }

                if (groupCode == null)
                {
                    groupCode = PriceRule.GetStringValue(formula);
                }

                ret = codes.Values.Any(c => c.StartsWith(groupCode));
                break;

            case PriceRule.ConditionType.PaymentTypeUsed:
                List <BasePaymentType> paymentTypes = GetConditionPaymentTypes();
                ret = operation.Payments.Any(payment => paymentTypes.Contains(payment.Type.BaseType));
                break;

            case PriceRule.ConditionType.DatabaseUpdated:
                ret = BusinessDomain.GetDatabaseLastUpdate().AddMinutes(30) > DateTime.Now;
                break;

            default:
                return(true);
            }

            return(ret != IsException);
        }