Beispiel #1
0
        /// <summary>
        /// Adds the device to merchant.
        /// </summary>
        /// <param name="estateId">The estate identifier.</param>
        /// <param name="merchantId">The merchant identifier.</param>
        /// <param name="deviceId">The device identifier.</param>
        /// <param name="deviceIdentifier">The device identifier.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task AddDeviceToMerchant(Guid estateId,
                                              Guid merchantId,
                                              Guid deviceId,
                                              String deviceIdentifier,
                                              CancellationToken cancellationToken)
        {
            MerchantAggregate merchantAggregate = await this.MerchantAggregateRepository.GetLatestVersion(merchantId, cancellationToken);

            // Check merchant has been created
            if (merchantAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Merchant Id {merchantId} has not been created");
            }

            // Estate Id is a valid estate
            EstateAggregate estateAggregate = await this.EstateAggregateRepository.GetLatestVersion(estateId, cancellationToken);

            if (estateAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Estate Id {estateId} has not been created");
            }

            merchantAggregate.AddDevice(deviceId, deviceIdentifier);

            await this.MerchantAggregateRepository.SaveChanges(merchantAggregate, cancellationToken);
        }
Beispiel #2
0
        public void MerchantAggregate_CanBeCreated_IsCreated()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.AggregateId.ShouldBe(TestData.MerchantId);
            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.ShouldBeNull();
        }
Beispiel #3
0
        public void MerchantAggregate_AddDevice_MerchantNotCreated_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.AddDevice(TestData.DeviceId, TestData.DeviceIdentifier);
            });
        }
Beispiel #4
0
        public void MerchantAggregate_MakeDeposit_MerchantNotCreated_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, TestData.DepositReference, TestData.DepositDateTime, TestData.DepositAmount);
            });
        }
Beispiel #5
0
        public void MerchantAggregate_AssignOperator_MerchantNotCreated_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.AssignOperator(TestData.OperatorId, TestData.OperatorName, TestData.OperatorMerchantNumber, TestData.OperatorTerminalNumber);
            });
        }
Beispiel #6
0
        public async Task AssignOperatorToMerchant(Guid estateId,
                                                   Guid merchantId,
                                                   Guid operatorId,
                                                   String merchantNumber,
                                                   String terminalNumber,
                                                   CancellationToken cancellationToken)
        {
            MerchantAggregate merchantAggregate = await this.MerchantAggregateRepository.GetLatestVersion(merchantId, cancellationToken);

            // Check merchant has been created
            if (merchantAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Merchant Id {merchantId} has not been created");
            }

            // Estate Id is a valid estate
            EstateAggregate estateAggregate = await this.EstateAggregateRepository.GetLatestVersion(estateId, cancellationToken);

            if (estateAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Estate Id {estateId} has not been created");
            }

            // Is the operator valid for this estate
            Estate   estate    = estateAggregate.GetEstate();
            Operator @operator = estate.Operators?.SingleOrDefault(o => o.OperatorId == operatorId);

            if (@operator == null)
            {
                throw new InvalidOperationException($"Operator Id {operatorId} is not supported on Estate [{estate.Name}]");
            }

            // Operator has been validated, now check the rules of the operator against the passed in data
            if (@operator.RequireCustomMerchantNumber)
            {
                // requested addition must have a merchant number supplied
                if (String.IsNullOrEmpty(merchantNumber))
                {
                    throw new InvalidOperationException($"Operator Id {operatorId} requires that a merchant number is provided");
                }
            }

            if (@operator.RequireCustomTerminalNumber)
            {
                // requested addition must have a terminal number supplied
                if (String.IsNullOrEmpty(terminalNumber))
                {
                    throw new InvalidOperationException($"Operator Id {operatorId} requires that a terminal number is provided");
                }
            }

            // Assign the operator
            merchantAggregate.AssignOperator(operatorId, @operator.Name, merchantNumber, terminalNumber);

            await this.MerchantAggregateRepository.SaveChanges(merchantAggregate, cancellationToken);
        }
Beispiel #7
0
        /// <summary>
        /// Gets the merchant.
        /// </summary>
        /// <param name="estateId">The estate identifier.</param>
        /// <param name="merchantId">The merchant identifier.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task <Merchant> GetMerchant(Guid estateId,
                                                 Guid merchantId,
                                                 CancellationToken cancellationToken)
        {
            MerchantAggregate merchantAggregate = await this.MerchantAggregateRepository.GetLatestVersion(merchantId, cancellationToken);

            Merchant merchantModel = merchantAggregate.GetMerchant();

            return(merchantModel);
        }
Beispiel #8
0
        public async Task MerchantAggregate_Create_MerchantAlreadyCreated_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            InvalidOperationException exception = Should.Throw <InvalidOperationException>(() => { aggregate.Create(TestData.MerchantId, TestData.MerchantName, TestData.DateMerchantCreated); });

            exception.Message.ShouldContain($"Merchant {TestData.MerchantName} is already created");
        }
Beispiel #9
0
        public async Task <Guid> CreateMerchantUser(Guid estateId,
                                                    Guid merchantId,
                                                    String emailAddress,
                                                    String password,
                                                    String givenName,
                                                    String middleName,
                                                    String familyName,
                                                    CancellationToken cancellationToken)
        {
            MerchantAggregate merchantAggregate = await this.MerchantAggregateRepository.GetLatestVersion(merchantId, cancellationToken);

            // Check merchant has been created
            if (merchantAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Merchant Id {merchantId} has not been created");
            }

            // Estate Id is a valid estate
            EstateAggregate estateAggregate = await this.EstateAggregateRepository.GetLatestVersion(estateId, cancellationToken);

            if (estateAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Estate Id {estateId} has not been created");
            }

            CreateUserRequest createUserRequest = new CreateUserRequest
            {
                EmailAddress = emailAddress,
                FamilyName   = familyName,
                GivenName    = givenName,
                MiddleName   = middleName,
                Password     = password,
                PhoneNumber  = "123456",                                      // Is this really needed :|
                Roles        = new List <String>(),
                Claims       = new Dictionary <String, String>()
            };

            String merchantRoleName = Environment.GetEnvironmentVariable("MerchantRoleName");

            createUserRequest.Roles.Add(String.IsNullOrEmpty(merchantRoleName) ? "Merchant" : merchantRoleName);
            createUserRequest.Claims.Add("estateId", estateId.ToString());
            createUserRequest.Claims.Add("merchantId", merchantId.ToString());

            CreateUserResponse createUserResponse = await this.SecurityServiceClient.CreateUser(createUserRequest, cancellationToken);

            // Add the user to the aggregate
            merchantAggregate.AddSecurityUser(createUserResponse.UserId, emailAddress);

            // TODO: add a delete user here in case the aggregate add fails...

            await this.MerchantAggregateRepository.SaveChanges(merchantAggregate, cancellationToken);

            return(createUserResponse.UserId);
        }
Beispiel #10
0
        public void MerchantAggregate_MakeDeposit_DepositSourceNotSet_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.MakeDeposit(MerchantDepositSource.NotSet, TestData.DepositReference, TestData.DepositDateTime, TestData.DepositAmount);
            });
        }
Beispiel #11
0
        public void MerchantAggregate_AddSecurityUserToMerchant_MerchantNotCreated_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            InvalidOperationException exception = Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.AddSecurityUser(TestData.SecurityUserId, TestData.EstateUserEmailAddress);
            });

            exception.Message.ShouldContain("Merchant has not been created");
        }
Beispiel #12
0
        public void MerchantAggregate_MakeDeposit_AutomaticDepositSource_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            Should.Throw <NotSupportedException>(() =>
            {
                aggregate.MakeDeposit(TestData.MerchantDepositSourceAutomatic, TestData.DepositReference, TestData.DepositDateTime, TestData.DepositAmount);
            });
        }
Beispiel #13
0
        public void MerchantAggregate_AddDevice_DeviceIdentifierInvalid_ErrorThrown(String deviceIdentifier)
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            Should.Throw <ArgumentNullException>(() =>
            {
                aggregate.AddDevice(TestData.DeviceId, deviceIdentifier);
            });
        }
Beispiel #14
0
        public void MerchantAggregate_AddContact_MerchantNotCreated_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            InvalidOperationException exception = Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.AddContact(TestData.MerchantContactId, TestData.MerchantContactName, TestData.MerchantContactPhoneNumber,
                                     TestData.MerchantContactEmailAddress);
            });

            exception.Message.ShouldContain($"Merchant has not been created");
        }
Beispiel #15
0
        public void MerchantAggregate_Create_IsCreated()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            aggregate.AggregateId.ShouldBe(TestData.MerchantId);
            aggregate.EstateId.ShouldBe(TestData.EstateId);
            aggregate.Name.ShouldBe(TestData.MerchantName);
            aggregate.DateCreated.ShouldBe(TestData.DateMerchantCreated);
            aggregate.IsCreated.ShouldBeTrue();
        }
Beispiel #16
0
        public void MerchantAggregate_MakeDeposit_TwoDeposits_BothDepositsMade()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, TestData.DepositReference, TestData.DepositDateTime, TestData.DepositAmount);
            aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, TestData.DepositReference2, TestData.DepositDateTime2, TestData.DepositAmount2);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Deposits.Count.ShouldBe(2);
        }
Beispiel #17
0
        public void MerchantAggregate_MakeDeposit_TwoDepositsOneMonthApartSameDetails_BothDepositsMade()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, "Test Data Gen Deposit", new DateTime(2021, 1, 1, 0, 0, 0), 650.00m);
            aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, "Test Data Gen Deposit", new DateTime(2021, 2, 1, 0, 0, 0), 650.00m);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Deposits.Count.ShouldBe(2);
        }
Beispiel #18
0
        public void MerchantAggregate_AddDevice_DeviceAdded()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            aggregate.AddDevice(TestData.DeviceId, TestData.DeviceIdentifier);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Devices.ShouldHaveSingleItem();
            merchantModel.Devices.Single().Key.ShouldBe(TestData.DeviceId);
            merchantModel.Devices.Single().Value.ShouldBe(TestData.DeviceIdentifier);
        }
Beispiel #19
0
        public void MerchantAggregate_AddSecurityUserToMerchant_SecurityUserIsAdded()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);
            aggregate.AddSecurityUser(TestData.SecurityUserId, TestData.MerchantUserEmailAddress);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.SecurityUsers.ShouldHaveSingleItem();
            SecurityUser securityUser = merchantModel.SecurityUsers.Single();

            securityUser.EmailAddress.ShouldBe(TestData.MerchantUserEmailAddress);
            securityUser.SecurityUserId.ShouldBe(TestData.SecurityUserId);
        }
Beispiel #20
0
        public void MerchantAggregate_MakeDeposit_DuplicateDeposit_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);
            aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, TestData.DepositReference, TestData.DepositDateTime, TestData.DepositAmount);
            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Deposits.ShouldHaveSingleItem();

            Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, TestData.DepositReference, TestData.DepositDateTime, TestData.DepositAmount);
            });
        }
Beispiel #21
0
        public void MerchantAggregate_AssignOperator_OperatorIsAssigned()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);
            aggregate.AssignOperator(TestData.OperatorId, TestData.OperatorName, TestData.OperatorMerchantNumber, TestData.OperatorTerminalNumber);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Operators.ShouldHaveSingleItem();
            Models.Merchant.Operator operatorModel = merchantModel.Operators.Single();
            operatorModel.OperatorId.ShouldBe(TestData.OperatorId);
            operatorModel.Name.ShouldBe(TestData.OperatorName);
            operatorModel.MerchantNumber.ShouldBe(TestData.OperatorMerchantNumber);
            operatorModel.TerminalNumber.ShouldBe(TestData.OperatorTerminalNumber);
        }
Beispiel #22
0
        public void MerchantAggregate_MakeDeposit_DepositMade()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);

            aggregate.MakeDeposit(TestData.MerchantDepositSourceManual, TestData.DepositReference, TestData.DepositDateTime, TestData.DepositAmount);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Deposits.ShouldHaveSingleItem();
            merchantModel.Deposits.Single().Source.ShouldBe(TestData.MerchantDepositSourceManual);
            //merchantModel.Deposits.Single().DepositId.ShouldNotBe(TestData.DepositId);
            merchantModel.Deposits.Single().DepositDateTime.ShouldBe(TestData.DepositDateTime);
            merchantModel.Deposits.Single().Reference.ShouldBe(TestData.DepositReference);
            merchantModel.Deposits.Single().Amount.ShouldBe(TestData.DepositAmount);
        }
Beispiel #23
0
        public void MerchantAggregate_AddContact_ContactIsAdded()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);
            aggregate.AddContact(TestData.MerchantContactId, TestData.MerchantContactName, TestData.MerchantContactPhoneNumber,
                                 TestData.MerchantContactEmailAddress);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Contacts.ShouldHaveSingleItem();
            Contact contactModel = merchantModel.Contacts.Single();

            contactModel.ContactId.ShouldBe(TestData.MerchantContactId);
            contactModel.ContactName.ShouldBe(TestData.MerchantContactName);
            contactModel.ContactEmailAddress.ShouldBe(TestData.MerchantContactEmailAddress);
            contactModel.ContactPhoneNumber.ShouldBe(TestData.MerchantContactPhoneNumber);
        }
Beispiel #24
0
        public void MerchantAggregate_AddAddress_MerchantNotCreated_ErrorThrown()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            InvalidOperationException exception = Should.Throw <InvalidOperationException>(() =>
            {
                aggregate.AddAddress(TestData.MerchantAddressId,
                                     TestData.MerchantAddressLine1,
                                     TestData.MerchantAddressLine2,
                                     TestData.MerchantAddressLine3,
                                     TestData.MerchantAddressLine4,
                                     TestData.MerchantTown,
                                     TestData.MerchantRegion,
                                     TestData.MerchantPostalCode,
                                     TestData.MerchantCountry);
            });

            exception.Message.ShouldContain($"Merchant has not been created");
        }
Beispiel #25
0
        /// <summary>
        /// Creates the merchant.
        /// </summary>
        /// <param name="estateId">The estate identifier.</param>
        /// <param name="merchantId">The merchant identifier.</param>
        /// <param name="name">The name.</param>
        /// <param name="addressId">The address identifier.</param>
        /// <param name="addressLine1">The address line1.</param>
        /// <param name="addressLine2">The address line2.</param>
        /// <param name="addressLine3">The address line3.</param>
        /// <param name="addressLine4">The address line4.</param>
        /// <param name="town">The town.</param>
        /// <param name="region">The region.</param>
        /// <param name="postalCode">The postal code.</param>
        /// <param name="country">The country.</param>
        /// <param name="contactId">The contact identifier.</param>
        /// <param name="contactName">Name of the contact.</param>
        /// <param name="contactPhoneNumber">The contact phone number.</param>
        /// <param name="contactEmailAddress">The contact email address.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <exception cref="System.InvalidOperationException">Estate Id {estateId} has not been created</exception>
        public async Task CreateMerchant(Guid estateId,
                                         Guid merchantId,
                                         String name,
                                         Guid addressId,
                                         String addressLine1,
                                         String addressLine2,
                                         String addressLine3,
                                         String addressLine4,
                                         String town,
                                         String region,
                                         String postalCode,
                                         String country,
                                         Guid contactId,
                                         String contactName,
                                         String contactPhoneNumber,
                                         String contactEmailAddress,
                                         CancellationToken cancellationToken)
        {
            MerchantAggregate merchantAggregate = await this.MerchantAggregateRepository.GetLatestVersion(merchantId, cancellationToken);

            // Estate Id is a valid estate
            EstateAggregate estateAggregate = await this.EstateAggregateRepository.GetLatestVersion(estateId, cancellationToken);

            if (estateAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Estate Id {estateId} has not been created");
            }

            // Reject Duplicate Merchant Names... is this needed ?

            // Create the merchant
            merchantAggregate.Create(estateId, name, DateTime.Now);

            // Add the address
            merchantAggregate.AddAddress(addressId, addressLine1, addressLine2, addressLine3, addressLine4, town, region, postalCode, country);

            // Add the contact
            merchantAggregate.AddContact(contactId, contactName, contactPhoneNumber, contactEmailAddress);

            await this.MerchantAggregateRepository.SaveChanges(merchantAggregate, cancellationToken);
        }
Beispiel #26
0
        public void MerchantAggregate_AddAddress_AddressIsAdded()
        {
            MerchantAggregate aggregate = MerchantAggregate.Create(TestData.MerchantId);

            aggregate.Create(TestData.EstateId, TestData.MerchantName, TestData.DateMerchantCreated);
            aggregate.AddAddress(TestData.MerchantAddressId, TestData.MerchantAddressLine1, TestData.MerchantAddressLine2,
                                 TestData.MerchantAddressLine3, TestData.MerchantAddressLine4, TestData.MerchantTown,
                                 TestData.MerchantRegion, TestData.MerchantPostalCode, TestData.MerchantCountry);

            Merchant merchantModel = aggregate.GetMerchant();

            merchantModel.Addresses.ShouldHaveSingleItem();
            Address addressModel = merchantModel.Addresses.Single();

            addressModel.AddressId.ShouldBe(TestData.MerchantAddressId);
            addressModel.AddressLine1.ShouldBe(TestData.MerchantAddressLine1);
            addressModel.AddressLine2.ShouldBe(TestData.MerchantAddressLine2);
            addressModel.AddressLine3.ShouldBe(TestData.MerchantAddressLine3);
            addressModel.AddressLine4.ShouldBe(TestData.MerchantAddressLine4);
            addressModel.Town.ShouldBe(TestData.MerchantTown);
            addressModel.Region.ShouldBe(TestData.MerchantRegion);
            addressModel.PostalCode.ShouldBe(TestData.MerchantPostalCode);
            addressModel.Country.ShouldBe(TestData.MerchantCountry);
        }
Beispiel #27
0
        /// <summary>
        /// Makes the merchant deposit.
        /// </summary>
        /// <param name="estateId">The estate identifier.</param>
        /// <param name="merchantId">The merchant identifier.</param>
        /// <param name="source">The source.</param>
        /// <param name="reference">The reference.</param>
        /// <param name="depositDateTime">The deposit date time.</param>
        /// <param name="amount">The amount.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException">
        /// Merchant Id {merchantId} has not been created
        /// or
        /// Estate Id {estateId} has not been created
        /// </exception>
        public async Task <Guid> MakeMerchantDeposit(Guid estateId,
                                                     Guid merchantId,
                                                     Models.MerchantDepositSource source,
                                                     String reference,
                                                     DateTime depositDateTime,
                                                     Decimal amount,
                                                     CancellationToken cancellationToken)
        {
            MerchantAggregate merchantAggregate = await this.MerchantAggregateRepository.GetLatestVersion(merchantId, cancellationToken);

            // Check merchant has been created
            if (merchantAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Merchant Id {merchantId} has not been created");
            }

            // Estate Id is a valid estate
            EstateAggregate estateAggregate = await this.EstateAggregateRepository.GetLatestVersion(estateId, cancellationToken);

            if (estateAggregate.IsCreated == false)
            {
                throw new InvalidOperationException($"Estate Id {estateId} has not been created");
            }

            merchantAggregate.MakeDeposit(source, reference, depositDateTime, amount);

            await this.MerchantAggregateRepository.SaveChanges(merchantAggregate, cancellationToken);

            Merchant merchant = merchantAggregate.GetMerchant();

            // Find the deposit
            Deposit deposit = merchant.Deposits.Single(d => d.Reference == reference && d.DepositDateTime == depositDateTime && d.Source == source &&
                                                       d.Amount == amount);

            return(deposit.DepositId);
        }