public string GetLookupFetch(LookupRollup rollup, Guid id)
        {
            string RollupFieldNode;

            switch (rollup.RollupType)
            {
            case RollupType.Exists:
            {
                RollupFieldNode = "<attribute name=\"" + rollup.FieldRolledup +
                                  "\" aggregate=\"count\" distinct = \"true\" alias=\"" + FetchAlias + "\"/>";
                break;
            }

            case RollupType.Count:
            {
                RollupFieldNode = "<attribute name=\"" + rollup.FieldRolledup + "\" aggregate=\"count\" alias=\"" +
                                  FetchAlias + "\"/>";
                break;
            }

            case RollupType.Sum:
            {
                RollupFieldNode = "<attribute name=\"" + rollup.FieldRolledup + "\" aggregate=\"sum\" alias=\"" +
                                  FetchAlias + "\"/>";
                break;
            }

            case RollupType.Mean:
            {
                RollupFieldNode = "<attribute name=\"" + rollup.FieldRolledup + "\" aggregate=\"avg\" alias=\"" +
                                  FetchAlias + "\"/>";
                break;
            }

            default:
            {
                throw new ArgumentOutOfRangeException("Fetch Rollup not implemented for " + rollup.RollupType);
            }
            }
            return
                ("<fetch version=\"1.0\" aggregate=\"true\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"false\">"
                 + "<entity name=\"" + rollup.RecordTypeRolledup + "\">"
                 + RollupFieldNode
                 + "<filter type=\"and\">"
                 + "<condition attribute=\"" + rollup.LookupName + "\" operator=\"eq\" uiname=\"\" uitype=\"" + rollup.RecordTypeWithRollup +
                 "\" value=\"" + id + "\" />"
                 + (rollup.FieldRolledup != null ? GetConditionFetchNode(new ConditionExpression(rollup.FieldRolledup, ConditionOperator.NotNull)) : null)
                 + rollup.FilterXml
                 + "</filter>"
                 + "</entity>"
                 + "</fetch>");
        }
        private QueryExpression GetRollupQueryForLookup(LookupRollup rollup, Guid id)
        {
            var query = new QueryExpression(rollup.RecordTypeRolledup);

            query.Criteria = new FilterExpression(LogicalOperator.And);
            query.Criteria.AddCondition(rollup.LookupName, ConditionOperator.Equal, id);
            if (rollup.Filter != null)
            {
                query.Criteria.AddFilter(rollup.Filter);
            }
            query.ColumnSet.AddColumn(rollup.LookupName);
            if (rollup.FieldRolledup != null)
            {
                query.ColumnSet.AddColumn(rollup.FieldRolledup);
                query.Criteria.AddCondition(new ConditionExpression(rollup.FieldRolledup, ConditionOperator.NotNull));
            }
            return(query);
        }
        public void RefreshRollup(Guid id, LookupRollup rollup)
        {
            var newValue = GetRollup(rollup, id);

            XrmService.SetFieldIfChanging(rollup.RecordTypeWithRollup, id, rollup.RollupField, newValue);
        }
        public object GetRollup(LookupRollup rollup, Guid id)
        {
            object newValue = null;

            switch (rollup.RollupType)
            {
            case RollupType.Exists:
            {
                //if the Rollup returns a result > 0 then one exists
                var fetch  = GetLookupFetch(rollup, id);
                var result = XrmService.Fetch(fetch);
                newValue = result.Any() &&
                           XrmEntity.GetInt(result.First().GetField(FetchAlias)) > 0;
                break;
            }

            case RollupType.Count:
            {
                var result = XrmService.Fetch(GetLookupFetch(rollup, id));
                if (result.Any())
                {
                    newValue = result.ElementAt(0).GetField(FetchAlias);
                }
                break;
            }

            case RollupType.Sum:
            {
                var result = XrmService.Fetch(GetLookupFetch(rollup, id));
                if (result.Any())
                {
                    newValue = result.ElementAt(0).GetField(FetchAlias);
                }
                break;
            }

            case RollupType.Min:
            {
                var query = GetRollupQueryForLookup(rollup, id);
                query.AddOrder(rollup.FieldRolledup, OrderType.Ascending);
                var minRecord = XrmService.RetrieveFirst(query);
                newValue = minRecord.GetField(rollup.FieldRolledup);
                break;
            }

            case RollupType.Max:
            {
                var query = GetRollupQueryForLookup(rollup, id);
                query.AddOrder(rollup.FieldRolledup, OrderType.Descending);
                var maxRecord = XrmService.RetrieveFirst(query);
                newValue = maxRecord.GetField(rollup.FieldRolledup);
                break;
            }

            case RollupType.Mean:
            {
                var result = XrmService.Fetch(GetLookupFetch(rollup, id));
                if (result.Any())
                {
                    newValue = result.ElementAt(0).GetField(FetchAlias);
                }
                break;
            }

            case RollupType.SeparatedStrings:
            {
                var query = GetRollupQueryForLookup(rollup, id);

                query.AddOrder(rollup.FieldRolledup, OrderType.Ascending);
                var records = XrmService.RetrieveAll(query);
                var labels  =
                    records.Select(e => e.GetField(rollup.FieldRolledup)).
                    ToArray();
                newValue = string.Join(rollup.SeparatorString, labels);
                break;
            }

            case RollupType.First:
            {
                var query = GetRollupQueryForLookup(rollup, id);
                query.AddOrder(rollup.OrderByField, rollup.OrderType);
                if (rollup.OrderByField != "createdon")
                {
                    query.AddOrder("createdon", OrderType.Descending);
                }
                var record = XrmService.RetrieveFirst(query);
                newValue = record.GetField(rollup.FieldRolledup);
                if (newValue is Guid g && rollup.ObjectType == typeof(EntityReference))
                {
                    newValue = new EntityReference(rollup.RecordTypeRolledup, g);
                }
                break;
            }
            }
            if (newValue == null && rollup.NullAmount != null)
            {
                newValue = rollup.NullAmount;
            }
            if (newValue != null && rollup.ObjectType != null)
            {
                if (rollup.ObjectType == typeof(decimal))
                {
                    newValue = Convert.ToDecimal(newValue.ToString());
                }
            }
            return(newValue);
        }
 public UpdateMeta(string field, LookupRollup rollup, object differenceValue)
 {
     FieldName       = field;
     DifferenceValue = differenceValue;
     Rollup          = rollup;
 }