public void HandleEventInstance(InterestPaid eventInstance)
 {
     if (null != eventInstance)
     {
         currentBalance += eventInstance.AmountPaid;
     }
 }
 public void HandleEventInstance(InterestPaid eventInstance)
 {
     if (null != eventInstance)
     {
         _interestDue -= eventInstance.AmountPaid;
     }
 }
 public ClassificationResponse.ClassificationResults ClassifyEventInstance(InterestPaid eventInstance)
 {
     if (null != eventInstance)
     {
         currentBalance += eventInstance.AmountPaid;
     }
     if (currentBalance >= threshold)
     {
         // Balance is above threshold
         return(ClassificationResponse.ClassificationResults.Exclude);
     }
     else
     {
         return(ClassificationResponse.ClassificationResults.Include);
     }
 }
        public static async Task PayInterestForSpecificAccount
            ([ActivityTrigger] IDurableActivityContext payInterestContext)
        {
            string accountNumber = payInterestContext.GetInput <string>();

            #region Tracing telemetry
            Activity.Current.AddTag("Account Number", accountNumber);
            #endregion

            Command cmdPayInterest = new Command(
                new CommandAttribute("Bank",
                                     "Pay Interest",
                                     payInterestContext.InstanceId)
                );

            if (!string.IsNullOrWhiteSpace(accountNumber))
            {
                string result = "";

                await cmdPayInterest.InitiateStep(AccountCommands.COMMAND_STEP_PAY_INTEREST,
                                                  "Bank",
                                                  "Account",
                                                  accountNumber);

                // 1- Get interest due...
                Projection prjInterestDue = new Projection(
                    new ProjectionAttribute(
                        "Bank",
                        "Account",
                        accountNumber,
                        nameof(InterestDue)
                        )
                    );

                // get the interest owed / due as now
                InterestDue interestDue = await prjInterestDue.Process <InterestDue>();

                if (null != interestDue)
                {
                    // pay the interest
                    decimal amountToPay = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero);
                    if (amountToPay != 0.00M)
                    {
                        EventStream bankAccountEvents = new EventStream(
                            new EventStreamAttribute(
                                "Bank",
                                "Account",
                                accountNumber
                                )
                            );

                        InterestPaid evInterestPaid = new InterestPaid()
                        {
                            AmountPaid = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero),
                            Commentary = $"Interest due {interestDue.Due} as at {interestDue.CurrentSequenceNumber}"
                        };
                        await bankAccountEvents.AppendEvent(evInterestPaid);

                        result = $"Interest paid: {evInterestPaid.AmountPaid} ({evInterestPaid.Commentary})";
                    }
                }

                await cmdPayInterest.StepCompleted(AccountCommands.COMMAND_STEP_PAY_INTEREST,
                                                   result,
                                                   "Bank",
                                                   "Account",
                                                   accountNumber);
            }
        }
示例#5
0
        public static async void PayInterestCommandStep
            ([EventGridTrigger] EventGridEvent egStepTriggered)
        {
            // Get the parameters from the event grid trigger
            // (Payload is a Command Step Initiated)
            Command cmdApplyAccruedInterest = new Command(egStepTriggered);

            if (null != cmdApplyAccruedInterest)
            {
                string result = $"No accrued interest paid";

                if (cmdApplyAccruedInterest.CommandName == COMMAND_STEP_PAY_INTEREST)
                {
                    // Get the parameter for account number
                    string accountNumber = (string)(await cmdApplyAccruedInterest.GetParameterValue("Account Number"));
                    if (!string.IsNullOrWhiteSpace(accountNumber))
                    {
                        // 1- Get interest due...
                        Projection prjInterestDue = new Projection(
                            new ProjectionAttribute(
                                "Bank",
                                "Account",
                                accountNumber,
                                nameof(InterestDue)
                                )
                            );

                        // get the interest owed / due as now
                        InterestDue interestDue = await prjInterestDue.Process <InterestDue>();

                        if (null != interestDue)
                        {
                            // pay the interest
                            decimal amountToPay = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero);
                            if (amountToPay != 0.00M)
                            {
                                EventStream bankAccountEvents = new EventStream(
                                    new EventStreamAttribute(
                                        "Bank",
                                        "Account",
                                        accountNumber
                                        )
                                    );

                                InterestPaid evInterestPaid = new InterestPaid()
                                {
                                    AmountPaid = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero),
                                    Commentary = $"Interest due {interestDue.Due} as at {interestDue.CurrentSequenceNumber}"
                                };
                                await bankAccountEvents.AppendEvent(evInterestPaid);

                                result = $"Interest of {evInterestPaid.AmountPaid} paid for account {accountNumber} ";
                            }
                        }
                    }
                }

                // mark this step as complete
                await cmdApplyAccruedInterest.StepCompleted(COMMAND_STEP_PAY_INTEREST, result);
            }
        }
        public static async Task <bool> PayInterestCommandStep
            ([ActivityTrigger] IDurableActivityContext setOverdraftContext)
        {
            string result = "";

            CommandAttribute payload = setOverdraftContext.GetInput <CommandAttribute>();

            Command cmdApplyAccruedInterest = null;

            if (payload == null)
            {
                cmdApplyAccruedInterest = new Command(payload);
            }
            else
            {
                cmdApplyAccruedInterest = new Command(new CommandAttribute("Bank", "Apply Accrued Interest"));
            }

            string accountNumber           = (string)(await cmdApplyAccruedInterest.GetParameterValue("Account Number"));
            int    overdraftSequenceNumber = 0;

            var overdraftSeqNoParam = await cmdApplyAccruedInterest.GetParameterValue("Overdraft Event Sequence Number");

            if (overdraftSeqNoParam != null)
            {
                overdraftSequenceNumber = (int)(overdraftSeqNoParam);
            }

            if (!string.IsNullOrWhiteSpace(accountNumber))
            {
                // 1- Get interest due...
                Projection prjInterestDue = new Projection(
                    new ProjectionAttribute(
                        "Bank",
                        "Account",
                        accountNumber,
                        nameof(InterestDue)
                        )
                    );

                // get the interest owed / due as now
                InterestDue interestDue = await prjInterestDue.Process <InterestDue>();

                if (null != interestDue)
                {
                    // pay the interest
                    decimal amountToPay = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero);
                    if (amountToPay != 0.00M)
                    {
                        EventStream bankAccountEvents = new EventStream(
                            new EventStreamAttribute(
                                "Bank",
                                "Account",
                                accountNumber
                                )
                            );

                        InterestPaid evInterestPaid = new InterestPaid()
                        {
                            AmountPaid = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero),
                            Commentary = $"Interest due {interestDue.Due} as at {interestDue.CurrentSequenceNumber}"
                        };
                        await bankAccountEvents.AppendEvent(evInterestPaid);

                        result = $"Interest of {evInterestPaid.AmountPaid} paid for account {accountNumber} ";
                    }

                    if (interestDue.CurrentSequenceNumber > overdraftSequenceNumber)
                    {
                        // May indicate a concurrency issue
                        return(false);
                    }
                }
            }

            return(true);
        }
        public static async Task <HttpResponseMessage> PayInterestRun(
            [HttpTrigger(AuthorizationLevel.Function, "POST", Route = @"PayInterest/{accountnumber}")] HttpRequestMessage req,
            string accountnumber,
            [EventStream("Bank", "Account", "{accountnumber}")]  EventStream bankAccountEvents,
            [Projection("Bank", "Account", "{accountnumber}", nameof(InterestDue))] Projection prjInterestDue,
            [Projection("Bank", "Account", "{accountnumber}", nameof(Balance))] Projection prjBankAccountBalance,
            [Projection("Bank", "Account", "{accountnumber}", nameof(OverdraftLimit))] Projection prjBankAccountOverdraft)
        {
            // Set the start time for how long it took to process the message
            DateTime startTime = DateTime.UtcNow;

            if (!await bankAccountEvents.Exists())
            {
                // You cannot pay interest if the account does not exist
                return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.Forbidden,
                                                                       ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                 true,
                                                                                                                 $"Account {accountnumber} does not exist",
                                                                                                                 0),
                                                                       FunctionResponse.MEDIA_TYPE));
            }

            // get the interest owed / due as now
            InterestDue interestDue = await prjInterestDue.Process <InterestDue>();

            if (null != interestDue)
            {
                // if the interest due is negative we need to make sure the account has sufficient balance
                if (interestDue.Due < 0.00M)
                {
                    Balance balance = await prjBankAccountBalance.Process <Balance>();

                    if (null != balance)
                    {
                        decimal availableBalance = balance.CurrentBalance;

                        // is there an overdraft?
                        OverdraftLimit overdraft = await prjBankAccountOverdraft.Process <OverdraftLimit>();

                        if (null != overdraft)
                        {
                            availableBalance += overdraft.CurrentOverdraftLimit;
                        }

                        if (availableBalance < interestDue.Due)
                        {
                            // can't pay the interest
                            return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.Forbidden,
                                                                                   ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                             true,
                                                                                                                             $"Unable to pay interest of {interestDue.Due} as available balance is only {availableBalance}",
                                                                                                                             interestDue.CurrentSequenceNumber),
                                                                                   FunctionResponse.MEDIA_TYPE));
                        }
                    }
                }

                // pay the interest
                decimal amountToPay = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero);
                if (amountToPay != 0.00M)
                {
                    InterestPaid evInterestPaid = new InterestPaid()
                    {
                        AmountPaid = decimal.Round(interestDue.Due, 2, MidpointRounding.AwayFromZero),
                        Commentary = $"Interest due {interestDue.Due} as at {interestDue.CurrentSequenceNumber}"
                    };
                    await bankAccountEvents.AppendEvent(evInterestPaid);

                    return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.OK,
                                                                           ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                     false,
                                                                                                                     evInterestPaid.Commentary,
                                                                                                                     interestDue.CurrentSequenceNumber),
                                                                           FunctionResponse.MEDIA_TYPE));
                }
                else
                {
                    return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.OK,
                                                                           ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                     false,
                                                                                                                     $"No interest due so none was paid out",
                                                                                                                     interestDue.CurrentSequenceNumber),
                                                                           FunctionResponse.MEDIA_TYPE));
                }
            }
            else
            {
                return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.Forbidden,
                                                                       ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                 true,
                                                                                                                 $"Unable to get interest due for account {accountnumber} for interest payment",
                                                                                                                 0),
                                                                       FunctionResponse.MEDIA_TYPE
                                                                       ));
            }
        }