Beispiel #1
0
        /// <summary>
        /// Redeems the voucher.
        /// </summary>
        /// <param name="estateId">The estate identifier.</param>
        /// <param name="voucherCode">The voucher code.</param>
        /// <param name="redeemedDateTime">The redeemed date time.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        /// <exception cref="NotFoundException">No voucher found with voucher code [{voucherCode}]</exception>
        public async Task <RedeemVoucherResponse> RedeemVoucher(Guid estateId,
                                                                String voucherCode,
                                                                DateTime redeemedDateTime,
                                                                CancellationToken cancellationToken)
        {
            await this.ValidateVoucherRedemption(estateId, cancellationToken);

            // Find the voucher based on the voucher code
            EstateReportingGenericContext context = await this.DbContextFactory.GetContext(estateId, cancellationToken);

            var voucher = await context.Vouchers.SingleOrDefaultAsync(v => v.VoucherCode == voucherCode, cancellationToken);

            if (voucher == null)
            {
                throw new NotFoundException($"No voucher found with voucher code [{voucherCode}]");
            }

            // Now get the aggregate
            VoucherAggregate voucherAggregate = await this.VoucherAggregateRepository.GetLatestVersion(voucher.VoucherId, cancellationToken);

            // Redeem the voucher
            voucherAggregate.Redeem(redeemedDateTime);

            // Save the changes
            await this.VoucherAggregateRepository.SaveChanges(voucherAggregate, cancellationToken);

            Voucher voucherModel = voucherAggregate.GetVoucher();

            return(new RedeemVoucherResponse
            {
                RemainingBalance = voucherModel.Balance,
                ExpiryDate = voucherModel.ExpiryDate,
                VoucherCode = voucherModel.VoucherCode
            });
        }
Beispiel #2
0
        /// <summary>
        /// Issues the voucher.
        /// </summary>
        /// <param name="voucherId">The voucher identifier.</param>
        /// <param name="operatorId">The operator identifier.</param>
        /// <param name="estateId">The estate identifier.</param>
        /// <param name="transactionId">The transaction identifier.</param>
        /// <param name="issuedDateTime">The issued date time.</param>
        /// <param name="value">The value.</param>
        /// <param name="recipientEmail">The recipient email.</param>
        /// <param name="recipientMobile">The recipient mobile.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task <IssueVoucherResponse> IssueVoucher(Guid voucherId, String operatorId, Guid estateId,
                                                              Guid transactionId,
                                                              DateTime issuedDateTime,
                                                              Decimal value,
                                                              String recipientEmail, String recipientMobile, CancellationToken cancellationToken)
        {
            await this.ValidateVoucherIssue(estateId, operatorId, cancellationToken);

            VoucherAggregate voucher = await this.VoucherAggregateRepository.GetLatestVersion(voucherId, cancellationToken);

            voucher.Generate(operatorId, estateId, transactionId, issuedDateTime, value);

            var voucherModel = voucher.GetVoucher();

            // Generate the barcode
            Barcode barcode = new Barcode(voucherModel.VoucherCode);

            voucher.AddBarcode(barcode.GetBase64Image());
            voucher.Issue(recipientEmail, recipientMobile, issuedDateTime);

            await this.VoucherAggregateRepository.SaveChanges(voucher, cancellationToken);

            return(new IssueVoucherResponse
            {
                ExpiryDate = voucherModel.ExpiryDate,
                Message = voucherModel.Message,
                VoucherCode = voucherModel.VoucherCode,
                VoucherId = voucherId
            });
        }
Beispiel #3
0
        public void VoucherAggregate_Issue_VoucherNotGenerated_ErrorThrown()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.Issue(TestData.RecipientEmail, TestData.RecipientMobile, TestData.IssuedDateTime);
            });
        }
Beispiel #4
0
        public void VoucherAggregate_Redeem_VoucherNotGenerated_ErrorThrown()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.Redeem(TestData.RedeemedDateTime);
            });
        }
Beispiel #5
0
        public void VoucherAggregate_Generate_InvalidEstateId_ErrorIsThrown()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            Should.Throw <ArgumentNullException>(() =>
            {
                aggregate.Generate(TestData.OperatorIdentifier, Guid.Empty, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);
            });
        }
Beispiel #6
0
        public void VoucherAggregate_Generate_InvalidValue_ErrorIsThrown(Decimal value)
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            Should.Throw <ArgumentOutOfRangeException>(() =>
            {
                aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, value);
            });
        }
Beispiel #7
0
        public void VoucherAggregate_AddBarcode_VoucherNotGenerated_ErrorThrown()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.AddBarcode(TestData.Barcode);
            });
        }
Beispiel #8
0
        public void VoucherAggregate_Issue_VoucherIsIssued()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);
            aggregate.Issue(TestData.RecipientEmail, TestData.RecipientMobile, TestData.IssuedDateTime);
            var voucher = aggregate.GetVoucher();

            voucher.IsIssued.ShouldBeTrue();
        }
        public static VoucherAggregate GetVoucherAggregateWithRecipientMobile()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);
            aggregate.AddBarcode(TestData.Barcode);
            aggregate.Issue(null, TestData.RecipientMobile, TestData.IssuedDateTime);

            return(aggregate);
        }
Beispiel #10
0
        public void VoucherAggregate_Redeem_VoucherNotIssued_ErrorThrown()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);
            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.Redeem(TestData.RedeemedDateTime);
            });
        }
Beispiel #11
0
        public void VoucherAggregate_AddBarcode_BarcodeIsAdded()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);
            aggregate.AddBarcode(TestData.Barcode);
            var voucher = aggregate.GetVoucher();

            voucher.Barcode.ShouldBe(TestData.Barcode);
        }
Beispiel #12
0
        public void VoucherAggregate_Issue_EitherEmailOrMobileIsRequired_ErrorThrown(String recipientEmail, String recipientMobile)
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);
            Should.Throw <ArgumentNullException>(() =>
            {
                aggregate.Issue(recipientEmail, recipientMobile, TestData.IssuedDateTime);
            });
        }
Beispiel #13
0
        public void VoucherAggregate_Generate_VoucherAlreadyIssued_ErrorThrown()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);
            aggregate.Issue(TestData.RecipientEmail, TestData.RecipientMobile, TestData.IssuedDateTime);
            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.IssuedDateTime, TestData.Value);
            });
        }
Beispiel #14
0
        public void VoucherAggregate_AddBarcode_InvalidBarcode_ErrorThrown(String barcode)
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);

            Should.Throw <ArgumentException>(() =>
            {
                aggregate.AddBarcode(barcode);
            });
        }
Beispiel #15
0
        public void VoucherAggregate_Generate_VoucherIsGenerated()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.Generate(TestData.OperatorIdentifier, TestData.EstateId, TestData.TransactionId, TestData.GeneratedDateTime, TestData.Value);

            var voucher = aggregate.GetVoucher();

            voucher.IsGenerated.ShouldBeTrue();
            voucher.EstateId.ShouldBe(TestData.EstateId);
            voucher.IsIssued.ShouldBeFalse();
            voucher.GeneratedDateTime.ShouldBe(TestData.GeneratedDateTime);
            voucher.VoucherCode.ShouldNotBeNullOrEmpty();
            voucher.TransactionId.ShouldBe(TestData.TransactionId);
        }
        /// <summary>
        /// Handles the specific domain event.
        /// </summary>
        /// <param name="domainEvent">The domain event.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        private async Task HandleSpecificDomainEvent(VoucherIssuedEvent domainEvent,
                                                     CancellationToken cancellationToken)
        {
            // Get the voucher aggregate
            VoucherAggregate voucherAggregate = await this.VoucherAggregateRepository.GetLatestVersion(domainEvent.AggregateId, cancellationToken);

            Voucher voucherModel = voucherAggregate.GetVoucher();

            this.TokenResponse = await this.GetToken(cancellationToken);

            if (string.IsNullOrEmpty(voucherModel.RecipientEmail) == false)
            {
                String message = await this.GetEmailVoucherMessage(voucherModel, cancellationToken);

                SendEmailRequest request = new SendEmailRequest
                {
                    Body = message,
                    ConnectionIdentifier = domainEvent.EstateId,
                    FromAddress          = "*****@*****.**",                   // TODO: lookup from config
                    IsHtml      = true,
                    MessageId   = domainEvent.EventId,
                    Subject     = "Voucher Issue",
                    ToAddresses = new List <String>
                    {
                        voucherModel.RecipientEmail
                    }
                };

                await this.MessagingServiceClient.SendEmail(this.TokenResponse.AccessToken, request, cancellationToken);
            }

            if (String.IsNullOrEmpty(voucherModel.RecipientMobile) == false)
            {
                String message = await this.GetSMSVoucherMessage(voucherModel, cancellationToken);

                SendSMSRequest request = new SendSMSRequest
                {
                    ConnectionIdentifier = domainEvent.EstateId,
                    Destination          = domainEvent.RecipientMobile,
                    Message   = message,
                    MessageId = domainEvent.EventId,
                    Sender    = "Your Voucher"
                };

                await this.MessagingServiceClient.SendSMS(this.TokenResponse.AccessToken, request, cancellationToken);
            }
        }
        /// <summary>
        /// Gets the voucher by code.
        /// </summary>
        /// <param name="estateId">The estate identifier.</param>
        /// <param name="voucherCode">The voucher code.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        /// <exception cref="NotFoundException">Voucher not found with Voucher Code [{voucherCode}]</exception>
        public async Task <Voucher> GetVoucherByCode(Guid estateId,
                                                     String voucherCode,
                                                     CancellationToken cancellationToken)
        {
            EstateReportingGenericContext context = await this.DbContextFactory.GetContext(estateId, cancellationToken);

            EstateReporting.Database.Entities.Voucher voucher = await context.Vouchers.SingleOrDefaultAsync(v => v.VoucherCode == voucherCode, cancellationToken);

            if (voucher == null)
            {
                throw new NotFoundException($"Voucher not found with Voucher Code [{voucherCode}]");
            }

            // Get the aggregate
            VoucherAggregate voucherAggregate = await this.VoucherAggregateRepository.GetLatestVersion(voucher.VoucherId, cancellationToken);

            return(voucherAggregate.GetVoucher());
        }
Beispiel #18
0
        public void VoucherAggregate_CanBeCreated_IsCreated()
        {
            VoucherAggregate aggregate = VoucherAggregate.Create(TestData.VoucherId);

            aggregate.AggregateId.ShouldBe(TestData.VoucherId);
        }