public static async Task <Tuple <string, bool> > AccrueInterestForSpecificAccount
            ([ActivityTrigger] IDurableActivityContext accrueInterestContext)
        {
            const decimal DEBIT_INTEREST_RATE  = 0.001M;
            const decimal CREDIT_INTEREST_RATE = 0.0005M;

            string accountNumber = accrueInterestContext.GetInput <string>();

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

            if (!string.IsNullOrEmpty(accountNumber))
            {
                EventStream bankAccountEvents = new EventStream(new EventStreamAttribute("Bank", "Account", accountNumber));
                if (await bankAccountEvents.Exists())
                {
                    // Has the accrual been done today for this account?
                    Classification         clsAccruedToday = new Classification(new ClassificationAttribute("Bank", "Account", accountNumber, nameof(InterestAccruedToday)));
                    ClassificationResponse isAccrued       = await clsAccruedToday.Classify <InterestAccruedToday>();

                    if (isAccrued.Result != ClassificationResponse.ClassificationResults.Include)
                    {
                        // Get the account balance
                        Projection prjBankAccountBalance = new Projection(new ProjectionAttribute("Bank", "Account", accountNumber, nameof(Balance)));

                        // Get the current account balance, as at midnight
                        Balance projectedBalance = await prjBankAccountBalance.Process <Balance>(DateTime.Today);

                        if (null != projectedBalance)
                        {
                            Account.Events.InterestAccrued evAccrued = new Account.Events.InterestAccrued()
                            {
                                Commentary           = $"Daily scheduled interest accrual",
                                AccrualEffectiveDate = DateTime.Today  // set the accrual to midnight today
                            };
                            // calculate the accrual amount
                            if (projectedBalance.CurrentBalance >= 0)
                            {
                                // Using the credit rate
                                evAccrued.AmountAccrued        = CREDIT_INTEREST_RATE * projectedBalance.CurrentBalance;
                                evAccrued.InterestRateInEffect = CREDIT_INTEREST_RATE;
                            }
                            else
                            {
                                // Use the debit rate
                                evAccrued.AmountAccrued        = DEBIT_INTEREST_RATE * projectedBalance.CurrentBalance;
                                evAccrued.InterestRateInEffect = DEBIT_INTEREST_RATE;
                            }

                            try
                            {
                                await bankAccountEvents.AppendEvent(evAccrued, isAccrued.AsOfSequence);
                            }
                            catch (EventSourcingOnAzureFunctions.Common.EventSourcing.Exceptions.EventStreamWriteException)
                            {
                                // We can't be sure this hasn't already run...
                                return(new Tuple <string, bool>(accountNumber, false));
                            }
                        }
                    }
                }
            }
            return(new Tuple <string, bool>(accountNumber, true));
        }
        public static async Task <HttpResponseMessage> AccrueInterestRun(
            [HttpTrigger(AuthorizationLevel.Function, "POST", Route = @"AccrueInterest/{accountnumber}")] HttpRequestMessage req,
            string accountnumber,
            [EventStream("Bank", "Account", "{accountnumber}")]  EventStream bankAccountEvents,
            [Projection("Bank", "Account", "{accountnumber}", nameof(Balance))] Projection prjBankAccountBalance,
            [Classification("Bank", "Account", "{accountnumber}", nameof(InterestAccruedToday))] Classification clsAccruedToday)
        {
            // Set the start time for how long it took to process the message
            DateTime startTime = DateTime.UtcNow;

            if (!await bankAccountEvents.Exists())
            {
                // You cannot accrue 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)));
            }

            ClassificationResponse isAccrued = await clsAccruedToday.Classify <InterestAccruedToday>();

            if (isAccrued.Result == ClassificationResponse.ClassificationResults.Include)
            {
                // The accrual for today has been performed for this account
                return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.Forbidden,
                                                                       ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                 true,
                                                                                                                 $"Interest accrual already done on account {accountnumber} today",
                                                                                                                 isAccrued.AsOfSequence),
                                                                       FunctionResponse.MEDIA_TYPE
                                                                       ));
            }


            // get the request body...
            InterestAccrualData data = await req.Content.ReadAsAsync <InterestAccrualData>();

            // Get the current account balance, as at midnight
            Balance projectedBalance = await prjBankAccountBalance.Process <Balance>(DateTime.Today);

            if (null != projectedBalance)
            {
                Account.Events.InterestAccrued evAccrued = new Account.Events.InterestAccrued()
                {
                    Commentary           = data.Commentary,
                    AccrualEffectiveDate = DateTime.Today  // set the accrual to midnight today
                };

                if (projectedBalance.CurrentBalance >= 0)
                {
                    // Using the credit rate
                    evAccrued.AmountAccrued = data.CreditInterestRate * projectedBalance.CurrentBalance;
                }
                else
                {
                    // Use the debit rate
                    evAccrued.AmountAccrued = data.DebitInterestRate * projectedBalance.CurrentBalance;
                }

                try
                {
                    await bankAccountEvents.AppendEvent(evAccrued, isAccrued.AsOfSequence);
                }
                catch (EventSourcingOnAzureFunctions.Common.EventSourcing.Exceptions.EventStreamWriteException exWrite)
                {
                    return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.Forbidden,
                                                                           ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                     true,
                                                                                                                     $"Failed to write interest accrual event {exWrite.Message}",
                                                                                                                     projectedBalance.CurrentSequenceNumber),
                                                                           FunctionResponse.MEDIA_TYPE));
                }

                return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.OK,
                                                                       ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                 false,
                                                                                                                 $"Interest accrued for account {accountnumber} is {evAccrued.AmountAccrued}",
                                                                                                                 projectedBalance.CurrentSequenceNumber),
                                                                       FunctionResponse.MEDIA_TYPE));
            }
            else
            {
                return(req.CreateResponse <ProjectionFunctionResponse>(System.Net.HttpStatusCode.Forbidden,
                                                                       ProjectionFunctionResponse.CreateResponse(startTime,
                                                                                                                 true,
                                                                                                                 $"Unable to get current balance for account {accountnumber} for interest accrual",
                                                                                                                 0),
                                                                       FunctionResponse.MEDIA_TYPE
                                                                       ));
            }
        }