Как получить обновленное поле, используя сообщение об обновлении контекста - PullRequest
0 голосов
/ 21 декабря 2018

Я не знаю, как получить максимальную сумму после обновления максимального значения.

enter image description here, когда я создал новую максимальную сумму, 0,01 автоматически обновит следующую минимальную сумму.

enter image description here Когда я обновляю максимальную сумму, минимальная сумма не обновляется новой минимальной суммой, которая составляет 25 000,01

if (context.MessageName == "Create") {
    Guid RebateLevelsId = new Guid();
    RebateLevelsId = targetEntity.Id;

    if (targetEntity.Attributes.Contains("new_usagerebate")) {
        EntityReference usageRebateEnt = (EntityReference) targetEntity.Attributes["new_usagerebate"];
        Guid usageRebateId = usageRebateEnt.Id;

        EntityCollection rebateLevelEnt = GetEntityCollectionRebateLevel(service, "new_rebatelevels", "new_usagerebate", usageRebateId, new ColumnSet(true));

        Entity rebateLevelEntity = new Entity("new_rebatelevels", RebateLevelsId);
        attributes A = new attributes();

        if (rebateLevelEnt.Entities.Count > 0) {
            for (int i = 0; i < rebateLevelEnt.Entities.Count; i++) {
                if (i == rebateLevelEnt.Entities.Count - 1) {
                    A.level = i + 1;
                }
                if (i == rebateLevelEnt.Entities.Count - 2) {
                    A.Max_Amount = rebateLevelEnt.Entities[i].GetAttributeValue < decimal > ("new_maxamount");
                }
            }

            rebateLevelEntity["new_level"] = A.level.ToString();
            rebateLevelEntity["new_minamount"] = A.Max_Amount + 0.01 m;
            service.Update(rebateLevelEntity);
        } else {
            rebateLevelEntity["new_level"] = 1. ToString();
            service.Update(rebateLevelEntity);
        }
    }
}

1 Ответ

0 голосов
/ 22 декабря 2018

Я немного подумал над этой проблемой и написал пример того, как я мог бы с ней справиться.

Я искал надежное решение, которое позволило бы корректировать как уровень выше, так и уровень ниже уровня, который мы создаем или обновляем.В этих случаях это решение включает в себя:

  1. Начните с 0 записей уровня и добавьте по мере того, как мы идем
  2. Мин может быть ниже, чем максимум предыдущего уровня - в этом случае мы настраиваем максимум предыдущего уровня.
  3. Мин может быть ниже, чем минимум предыдущего уровня - в этом случае мы генерируем исключение.
  4. Макс может быть выше, чем минимум следующего уровня - в этом случае мы корректируем мин следующего уровня.
  5. Макс может быть выше, чем максимум следующего уровня - в этом случае мы выбрасываем исключение.
  6. Мин может быть ниже, чем максимум предыдущего уровня И максимум может быть выше, чем минимум следующего уровня, в этом случае мы корректируемкак предыдущий уровень, так и следующий уровень.
  7. Минимум может быть ниже, чем минимум предыдущего уровня И максимум может быть выше, чем максимум следующего уровня, и в этом случае мы генерируем исключение, содержащее информацию об обеих проблемах.
  8. Возможность иметь более 3 уровней.
  9. Обрабатывать события Create и Update.

Единственное, чего не хватает, так это логики, гарантирующей, что пользователи некип уровняДругой - обработка удалений.

Вместо того, чтобы создавать сущности в системе D365, я построил это для запуска с фиктивными данными в консольном приложении, и IOrganizationService комментарии закомментированы.Тем не менее, он использует классы EntityCollection и Entity, так что вы сможете легко подключать живые данные.

Я выбрал объектно-ориентированный подход.Класс Level начинался как оболочка для предоставления данных new_rebatelevel's без необходимости постоянного использования GetAttributeValue<>.Он превратился в устойчивый класс, который несет большую часть нагрузки.

target представляет уровень, который был создан или обновлен.

Вот основной:

class Program
{
    static void Main(string[] args)
    {
        var app = new App_CalcMinMax();
        app.Run();
        if (System.Diagnostics.Debugger.IsAttached)
        {
            Console.WriteLine("\nPress <Enter> to continue...");
            Console.ReadLine();                
        }
    }
}

И «приложение»:

using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class App_CalcMinMax 
{
    public void Run()
    {            
        var rebates = new UsageRebate(toCollection(new List<Entity>())); //start with an empty list
        //process various level create and update events
        //and display the results of each event
        //.Process() takes the level #, the min, and the max
        rebates.Process(1, 0, 10000);
        rebates.Process(2, 11000.01m, 20000);
        rebates.Process(3, 21000.01m, 30000);          
        rebates.Process(1, 0, 9000);            
        rebates.Process(2, 10000, 15000);            
        rebates.Process(3, 17000, 35000);
        rebates.Process(3, 12000, 24000);
        rebates.Process(2, 8000, 20000);
        rebates.Process(1, 0, 25000);
        rebates.Process(2, 14000, 19000);
    }

    private class Level
    {
        private Entity e;
        private Level lower;
        private Level upper;
        public int Num => e.GetAttributeValue<int>("new_level");
        public decimal Min => e.GetAttributeValue<Money>("new_minamount").Value;
        public decimal Max => e.GetAttributeValue<Money>("new_maxamount").Value;
        public bool IsValidLower => lower == null ? true : Min > lower.Min;
        public bool IsValidUpper => upper == null ? true : Max < upper.Max;
        public bool IsValid => IsValidLower && IsValidUpper;
        public bool AdjustLower => lower == null ? false : Min - 0.01m != lower.Max;
        public bool AdjustUpper => upper == null ? false : Max + 0.01m != upper.Min;

        public Level(Entity e)
        {
            this.e = e;
        }
        public void ValidateLower(Level lower)
        {
            this.lower = lower;
        }
        public void ValidateUpper(Level upper)
        {
            this.upper = upper;
        }
        public void SetMin(decimal value, IOrganizationService service = null)
        {
            e["new_minamount"] = new Money(value);
            //service.Update(e);
        }
        public void SetMax(decimal value, IOrganizationService service = null)
        {
            e["new_maxamount"] = new Money(value);
            //service.Update(e)
        }
        public override string ToString()
        {
            return $" Level: {Num}\tmin: { Min.ToString("N2"),9}\tmax: { Max.ToString("N2"),9}";
        }
    }

    private class UsageRebate
    {
        private IOrganizationService service;
        private EntityCollection ec;
        private IEnumerable<int> levelNums => Levels.Select(l => l.Num);
        public IEnumerable<Entity> Entities => ec.Entities;
        public IEnumerable<Level> Levels => Entities.Select(e => new Level(e));
        public UsageRebate(EntityCollection ec, IOrganizationService service = null)
        {
            this.ec = ec;
            this.service = service;
        }

        public void Process(int num, decimal min, decimal max)
        {
            var target = toEntity(num, min, max);
            var level = new Level(target);                
            Level prior = null;
            Level next = null;
            Console.WriteLine($"Target: {level.ToString()}");

            if (tryGetLevel(level.Num-1,out prior))
            {
                level.ValidateLower(prior);
            }

            if (tryGetLevel(level.Num + 1, out next))
            {
                level.ValidateUpper(next);
            }

            if (level.IsValid)
            {
                if (exists(level.Num))
                {
                    update(target);
                }
                else
                {
                    add(target);
                }
                if (level.AdjustLower)
                {
                    prior.SetMax(level.Min - 0.01m);
                }
                if (level.AdjustUpper)
                {
                    next.SetMin(level.Max + 0.01m);
                }
            }
            else
            {
                string message = "Exception: ";
                if (!level.IsValidLower)
                {
                    message += $"Level {level.Num} Min is less than Level {prior.Num} Min\n";
                }
                if (!level.IsValidUpper)
                {
                    message += $"Level {level.Num} Max exceeds Level {next.Num} Max";                        
                }
                Console.WriteLine(message);
                //throw new Exception(message);
            }

            Console.WriteLine($"Results:\n{ToString()}");
        }

        private bool tryGetLevel(int num, out Level level)
        {
            var ex = exists(num);
            level = ex ? get(num) : null;                
            return ex;
        }

        private void add(Entity entity)
        {
            ec.Entities.Add(entity);
            //service.Create(entity);
        }

        private void update(Entity entity)
        {
            var e = get(entity);
            e["new_minamount"] = entity["new_minamount"];
            e["new_maxamount"] = entity["new_maxamount"];
            //service.Update(entity);
        }

        private bool exists(int num)
        {
            return levelNums.Contains(num);
        }

        private Level get(int num)
        {
            return Levels.Where(l => l.Num == num).Single();
        }

        private Entity get(Entity entity)
        {
            return Entities.Where(e => new Level(e).Num == new Level(entity).Num).Single();
        }

        private Entity toEntity(int level, decimal min, decimal max)
        {
            return new Entity
            {
                LogicalName = "new_rebatelevel",
                Id = Guid.NewGuid(),
                Attributes =
                {
                    new KeyValuePair<string, object>("new_level", level),
                    new KeyValuePair<string, object>("new_minamount", new Money(min)),
                    new KeyValuePair<string, object>("new_maxamount", new Money(max))
                }
            };
        }

        public override string ToString()
        {
            var sb = new StringBuilder();
            Levels.ToList().ForEach(l => sb.AppendLine(l.ToString()));
            return sb.ToString();
        }
    }

    private EntityCollection toCollection(List<Entity> list)
    {
        var ec = new EntityCollection();
        ec.EntityName = "new_rebatelevel";
        ec.Entities.AddRange(list);
        return ec;
    }
}

И вывод:


Цель: Уровень: 1 мин: 0,00 макс: 10 000,00
Результаты:
Уровень: 1 мин: 0,00 макс: 10 000,00

Цель: Уровень: 2 мин: 11 000,01 макс: 20 000,00
Результаты:
Уровень: 1 мин: 0,00 макс: 11 000,00
Уровень: 2 мин:11 000,01 макс .: 20 000,00

Цель: Уровень: 3 мин.: 21 000,01 макс .: 30 000,00
Результаты:
Уровень: 1 мин.: 0,00 макс .: 11 000,00
Уровень: 2 мин.: 11 000,01 макс .: 21 000,00
Уровень: 3 мин: 21 000,01 макс: 30 000,00

Цель: Уровень: 1 мин: 0,00 макс: 9 000,00
Результаты:
Уровень: 1 мин: 0,00 макс: 9 000,00
Уровень: 2 мин: 9 000,01 макс: 21 000,00
Уровень: 3 мин: 21 000,01 макс: 30 000,00

Цель: Уровень: 2 мин: 10 000,00 макс: 15 000,00
Результаты:
Уровеньл: 1 мин: 0,00 макс: 9 999,99
уровень: 2 мин: 10 000,00 макс: 15 000,00
уровень: 3 мин: 15 000,01 макс: 30 000,00

Цель: уровень: 3 мин: 17 000,00 макс: 35 000,00
Результаты:
Уровень: 1 мин: 0,00 макс: 9 999,99
Уровень: 2 мин: 10 000,00 макс: 16 999,99
Уровень: 3 мин: 17 000,00 макс: 35 000,00

Цель: уровень: 3 мин: 12 000,00 макс: 24 000,00
Результаты:
Уровень: 1 мин: 0,00 макс: 9 999,99
Уровень: 2 мин: 10 000,00 макс: 11 999,99
Уровень: 3 мин: 12 000,00 макс: 24 000,00

Цель: Уровень: 2 мин: 8 000,00 макс: 20 000,00
Результаты:
Уровень: 1 мин: 0,00 макс: 7 999,99
Уровень: 2 мин: 8 000,00 макс: 20 000,00
Уровень:3 мин: 20 000,01 макс: 24 000,00

Цель: Уровень: 1 мин: 0,00 макс: 25 000,00
Исключение: Макс. Уровень 1 превышает Уровень 2 Макс
Результаты:
Уровень: 1 мин: 0,00макс: 7 999,99
уровень: 2 мин: 8 000,00 макс: 20 000,00
Уровень: 3 мин: 20 000,01 макс .: 24 000,00

Цель: Уровень: 2 мин: 14 000,00 макс: 19 000,00
Результаты:
Уровень: 1 мин: 0,00 макс: 13 999,99
Уровень: 2 мин: 14 000,00 макс .: 19 000,00
уровень: 3 мин.: 19 000,01 макс .: 24 000,00

Нажмите клавишу Enter, чтобы продолжить ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...