public void ExceptionGenerationWithNumber()
        {
            var ex = ErrorCode.Exception(9999, "full test");

            Assert.AreEqual("Testing... full test", ex.Message);
            Assert.AreEqual(9999, ex.ErrorCode);
        }
        public void ExceptionGenerationWithEnumAndStatus()
        {
            var ex = ErrorCode.Exception(OperationStatus.Failed, ErrorCodes.TestError, "full test");

            Assert.AreEqual("Testing... full test", ex.Message);
            Assert.AreEqual(9999, ex.ErrorCode);
            Assert.AreEqual(OperationStatus.Failed, ex.Status);
        }
        public void ExceptionGenerationNullTarget1615WithEnum()
        {
            var ex = ErrorCode.Exception(ErrorCodes.NullTarget);

            Assert.AreNotEqual(INVALIDMESSAGE, ex.Message);
            Assert.AreEqual("Target was null.", ex.Message);
            Assert.AreEqual(1615, ex.ErrorCode);
        }
        /// <summary>
        ///     Get the target entity reference.
        /// </summary>
        /// <param name="context">
        ///     The context.
        /// </param>
        /// <returns>
        ///     The <see cref="EntityReference" /> target.
        /// </returns>
        /// <exception cref="InvalidPluginExecutionException">
        /// </exception>
        public static EntityReference GetTargetEntityReference(ILocalPluginContext context)
        {
            if (!context.PluginExecutionContext.InputParameters.ContainsKey("Target") ||
                !(context.PluginExecutionContext.InputParameters["Target"] is EntityReference target))
            { // this should not be possible.
                throw ErrorCode.Exception(ErrorCodes.NullTarget);
            }

            return(target);
        }
        public override void Execute(ILocalPluginContext context)
        {
            // Step 1: Get the status code
            context.Trace($"Depth: {context.PluginExecutionContext.Depth}");
            //if (context.PluginExecutionContext.Depth > 10) return;

            context.Trace("Step 1");
            var status = context.GetAttributeValue <OptionSetValue>("statuscode");

            // Step 2: Check to see if statuscode is run
            context.Trace("Step 2");
            if (status == null || status.Value != 2 /* Run */)
            {
                context.Trace("Status Reason is not set to 2 'Run'.");
                return; // abort plugin execution
            }

            // Update run to complete: 3
            var actionUpdate = new Entity(context.PluginExecutionContext.PrimaryEntityName);

            actionUpdate.Id            = context.PluginExecutionContext.PrimaryEntityId;
            actionUpdate["statuscode"] = new OptionSetValue(3);
            context.OrganizationService.Update(actionUpdate);

            // Step 3: Set ActionTaken on Approval Request
            context.Trace("Step 3");
            var approvalrequestReference = context.GetAttributeValue <EntityReference>(ApprovalRequestLogicalName);

            if (approvalrequestReference == null)
            {
                throw ErrorCode.Exception(ErrorCodes.NoApprovalRequestOnAction);
            }

            // Step 4: Has a valid reference, perform the update.
            context.Trace("Step 4");
            var actionTaken = context.GetInputParameter <Entity>("Target").ToEntityReference();

            UpdateApprovalRequest(context, approvalrequestReference, actionTaken);


            // TODO: Evaluate if this is necessary with the rollup action below?
            if (ApprovalRequestHasAtleastOneChild(context, approvalrequestReference))
            {
                context.Trace("Approval Request has at least 1 child, aborting...");
                // nothing to check / update because the action was taken on an approval with children.
                // actions should only be *run* on approval requests without children.

                // It is the action on the nth child level that causes the recursive checks to fire back up the tree.
                return;
            }

            // Approval Request has no children, update the parent action count and run the approval request status check on the ar.

            var rollupAction = GetRollupAction(context, actionTaken);

            if (rollupAction != null)
            {
                context.Trace("Rollup Action Found");
                // Update Parent Approval Request Action Count
                IncrementActionCount(context, rollupAction);

                // Run Parent Approval Request Status Check
                CheckApprovalRequestStatus(context, rollupAction.GetAttributeValue <EntityReference>("fdbzap_ar_approvalrequest"));
            }

            // TODO: Run  action to update regarding object for approvalrequest (approvalrequestReference)
            UpdateRegardingObject(context, approvalrequestReference);
        }