private Task <CustomerAccountResult> Deactivate(CustomerAccount account)
        {
            _logger.LogInformation(GetLogMessage("Acct: {0}"), account.Number);
            var retVal = new CustomerAccountResult
            {
                AccountManagerId             = account.AccountManagerId,
                AccountManagerOrganizationId = account.AccountManagerOrganizationId,
                CustomerId             = account.CustomerId,
                CustomerOrganizationId = account.CustomerOrganizationId,
                Number      = account.Number,
                BuyerNumber = account.BuyerNumber
            };

            account.ObjectState   = ObjectState.Modified;
            account.UpdatedById   = _userInfo.UserId;
            account.Updated       = DateTimeOffset.UtcNow;
            account.AccountStatus = AccountStatus.Inactive;

            account.StatusTransitions.Add(new CustomerAccountStatusTransition()
            {
                Status      = account.AccountStatus,
                ObjectState = ObjectState.Added
            });

            var records = Repository.InsertOrUpdateGraph(account, true);

            _logger.LogDebug(GetLogMessage("{0} records updated"));
            if (records > 0)
            {
                retVal.Succeeded = true;
            }

            return(Task.FromResult(retVal));
        }
예제 #2
0
        private async Task <CustomerAccountResult> Link(LinkCustomerWithCompanyInput input)
        {
            _logger.LogInformation(GetLogMessage(
                                       $@"Linking Account, Account Manager: {input.AccountManagerId}, Customer Lookup Info: {input.EmailAddress} ({input.CompanyName})"));

            CustomerAccountResult retVal = new CustomerAccountResult();


            var cu = _customerService.Repository.Queryable()
                     .FindByOrganizationNameAndEmail(input.EmailAddress, input.CompanyName).FirstOrDefaultAsync();

            await Task.WhenAll(cu);

            if (cu.Result == null)
            {
                retVal.ErrorMessage = "Customer not found";
                return(retVal);
            }

            var input2 = new CustomerAccountInput
            {
                CustomerId             = cu.Result.CustomerId,
                CustomerOrganizationId = cu.Result.OrganizationId,
                PaymentTermId          = input.PaymentTermId.GetValueOrDefault(1)
            };

            input2.InjectFrom(input);
            var output = await Create(input2);

            if (output.Succeeded)
            {
                await Task.Run(() =>
                {
                    retVal = new CustomerAccountResult()
                    {
                        AccountManagerId             = input.AccountManagerId,
                        AccountManagerOrganizationId = input.AccountManagerOrganizationId,
                        CustomerId             = cu.Result.CustomerId,
                        CustomerOrganizationId = cu.Result.OrganizationId,
                        Succeeded   = true,
                        BuyerNumber = output.BuyerNumber,
                        Number      = output.Number
                    };

                    RaiseEvent(new CustomerAccountLinkedEvent
                    {
                        AccountManagerId             = input.AccountManagerId,
                        AccountManagerOrganizationId = input.AccountManagerOrganizationId,
                        CustomerId             = cu.Result.CustomerId,
                        CustomerOrganizationId = cu.Result.OrganizationId
                    });
                });
            }


            return(retVal);
        }
예제 #3
0
        private async Task <CustomerAccountResult> Link(LinkCustomerInput input)
        {
            _logger.LogInformation(GetLogMessage(
                                       $@"Linking Account, Account Manager: {input.AccountManagerId}, Customer Lookup Info: {input.EmailAddress}"));

            CustomerAccountResult retVal = new CustomerAccountResult();

            var cu = await _customers.Queryable()
                     .Include(x => x.Person).ThenInclude(x => x.ApplicationUser)
                     .Include(x => x.OrganizationCustomers)
                     .Where(x => x.Person.ApplicationUser.Email == input.EmailAddress)
                     .FirstAsync();

            if (cu.OrganizationCustomers.Count > 0)
            {
                var orgCu = cu.OrganizationCustomers.First();

                var input2 = new CustomerAccountInput
                {
                    CustomerId             = cu.Id,
                    CustomerOrganizationId = orgCu.OrganizationId,
                    PaymentTermId          = input.PaymentTermId.GetValueOrDefault(1)
                };

                input2.InjectFrom(input);
                var output = await Create(input2);

                if (output.Succeeded)
                {
                    await Task.Run(() =>
                    {
                        retVal = new CustomerAccountResult()
                        {
                            AccountManagerId             = input.AccountManagerId,
                            AccountManagerOrganizationId = input.AccountManagerOrganizationId,
                            CustomerId             = orgCu.CustomerId,
                            CustomerOrganizationId = orgCu.OrganizationId,
                            Succeeded   = true,
                            BuyerNumber = output.BuyerNumber,
                            Number      = output.Number
                        };

                        RaiseEvent(new CustomerAccountLinkedEvent
                        {
                            AccountManagerId             = input.AccountManagerId,
                            AccountManagerOrganizationId = input.AccountManagerOrganizationId,
                            CustomerId             = orgCu.CustomerId,
                            CustomerOrganizationId = orgCu.OrganizationId
                        });
                    });
                }
            }


            return(retVal);
        }
예제 #4
0
        public async Task <CustomerAccountResult> LinkOrganizationCustomer(IOrganizationCustomer customer)
        {
            _logger.LogInformation(GetLogMessage("Customer: {0}; Organization: {1}"), customer.CustomerId, customer.OrganizationId);
            var retVal = new CustomerAccountResult()
            {
                CustomerId             = customer.CustomerId,
                CustomerOrganizationId = customer.OrganizationId
            };

            var customerOrganization = await _organizations
                                       .Queryable()
                                       .Include(x => x.Customer)
                                       .ThenInclude(x => x.OrganizationMarketer)
                                       .ThenInclude(x => x.Organization)
                                       .ThenInclude(x => x.ProviderOrganization)
                                       .FirstAsync();

            var agencyOrganization = customerOrganization.Customer.OrganizationMarketer.Organization;

            _logger.LogDebug(GetLogMessage("Agency Organization Id: {0}"), agencyOrganization.Id);
            if (agencyOrganization.ProviderOrganization != null)
            {
                _logger.LogDebug(GetLogMessage("Provider Agency found"));

                var c = _customers
                        .Queryable().Include(x => x.Person).ThenInclude(x => x.ApplicationUser)
                        .First(x => x.Id == customer.CustomerId);

                retVal.AccountManagerOrganizationId = agencyOrganization.Id;
                retVal.AccountManagerId             = agencyOrganization.ProviderOrganization.DefaultAccountManagerId;

                var input = new LinkCustomerInput()
                {
                    AccountManagerId             = agencyOrganization.ProviderOrganization.DefaultAccountManagerId,
                    AccountManagerOrganizationId = agencyOrganization.Id,
                    EmailAddress = c.Person.ApplicationUser.Email,
                };

                _logger.LogDebug(GetLogMessage("Linking {@input}"), input);

                retVal = await Link(input);

                _logger.LogDebug(GetLogMessage("Response {@retVal}"), retVal);
            }
            else
            {
                retVal.Succeeded = true;
                _logger.LogDebug(GetLogMessage("Referrer Provider Organization not found," +
                                               " it shouldn't happen but it's not the end of the world"));
            }

            return(retVal);
        }
예제 #5
0
        //public async Task<T> Update<T>(IOrganizationAccountManager am, int id, CustomerAccountInput model)
        //    where T : AccountManagerCustomerAccountOutput
        //{
        //    var account = await GetAccount(am, id);
        //    account.InjectFrom(model);

        //    await Repository.UpdateAsync(account, true);

        //    var output = await GetAccount<T>(am, id);

        //    await Task.Run(() =>
        //    {
        //        RaiseEvent(new CustomerAccountUpdatedEvent()
        //        {
        //            Account = output
        //        });
        //    });

        //    return output;
        //}

        public async Task <CustomerAccountResult> Update(IProviderAgencyOwner ao, int id, CustomerAccountInput model)
        {
            var retVal = new  CustomerAccountResult();

            var am = await _accountManagerService
                     .Get(model.AccountManagerId, model.AccountManagerOrganizationId);

            var cu = await _customerService
                     .Get(model.CustomerId, model.CustomerOrganizationId);

            var isValid = am != null && cu != null;

            if (isValid)
            {
                retVal.CustomerId                   = cu.CustomerId;
                retVal.AccountManagerId             = am.AccountManagerId;
                retVal.CustomerOrganizationId       = cu.OrganizationId;
                retVal.AccountManagerOrganizationId = am.OrganizationId;

                var account = await GetAccount(ao, id);

                account.InjectFrom(model);

                if (model.PaymentTermId.HasValue)
                {
                    account.PaymentTermId = model.PaymentTermId.GetValueOrDefault(1);
                }

                var result = await Repository.UpdateAsync(account, true);

                _logger.LogDebug(GetLogMessage("{0} records updated"));

                if (result > 0)
                {
                    retVal.Succeeded = true;
                    await Task.Run(() =>
                    {
                        RaiseEvent(new CustomerAccountUpdatedEvent()
                        {
                            CustomerId                   = retVal.CustomerId.Value,
                            CustomerOrganizationId       = retVal.CustomerOrganizationId.Value,
                            AccountManagerId             = retVal.AccountManagerId.Value,
                            AccountManagerOrganizationId = retVal.AccountManagerOrganizationId.Value
                        });
                    });
                }
            }

            return(retVal);
        }
예제 #6
0
        public async Task <CustomerAccountResult> CreateInternalAccount(IOrganizationAccountManager am)
        {
            _logger.LogInformation(GetLogMessage("AM: {0}"), am.OrganizationId);

            var retVal = new CustomerAccountResult();

            var providerOrganization = _organizations
                                       .Queryable()
                                       .Include(x => x.ProviderOrganization)
                                       .Include(x => x.BuyerCustomerAccounts)
                                       .First(x => x.Id == am.OrganizationId);

            if (!providerOrganization.BuyerCustomerAccounts.Any(x => x.AccountManagerId == am.AccountManagerId &&
                                                                x.AccountManagerOrganizationId == am.AccountManagerId))
            {
                _logger.LogWarning(GetLogMessage("Internal account doesn't exist"));

                retVal = await Create(new CustomerAccountInput()
                {
                    AccountManagerId             = am.AccountManagerId,
                    AutoApproveTimeEntries       = providerOrganization.ProviderOrganization.AutoApproveTimeEntries,
                    AccountManagerOrganizationId = am.OrganizationId,
                    CustomerId             = providerOrganization.CustomerId,
                    CustomerOrganizationId = providerOrganization.Id,
                    PaymentTermId          = null
                });
            }
            else
            {
                retVal.AccountManagerId             = am.AccountManagerId;
                retVal.AccountManagerOrganizationId = am.OrganizationId;
                retVal.CustomerId             = am.AccountManagerId;
                retVal.CustomerOrganizationId = am.OrganizationId;
                retVal.Succeeded    = false;
                retVal.ErrorMessage = "Internal account already exists";

                _logger.LogWarning(GetLogMessage("Internal account already exists"));
            }

            return(retVal);
        }
예제 #7
0
        private async Task <CustomerAccountResult> Create(CustomerAccountInput input)
        {
            _logger.LogInformation(GetLogMessage(
                                       $@"Creating Account, Account Manager: {input.AccountManagerId}, Customer: {input.CustomerId}"));

            var retVal = new CustomerAccountResult()
            {
                CustomerOrganizationId       = input.CustomerOrganizationId,
                CustomerId                   = input.CustomerId,
                AccountManagerOrganizationId = input.AccountManagerOrganizationId,
                AccountManagerId             = input.AccountManagerId
            };

            var cu = await
                     _customerService.Repository.Queryable()
                     .Where(x => x.OrganizationId == input.CustomerOrganizationId && x.CustomerId == input.CustomerId)
                     .Include(x => x.Customer)
                     .ThenInclude(x => x.OrganizationMarketer)
                     .FirstAsync();

            var am = await
                     _accountManagerService.Repository.Queryable().Where(x => x.AccountManagerId == input.AccountManagerId && x.OrganizationId == input.AccountManagerOrganizationId)
                     .FirstOrDefaultAsync();

            var acctCandidate = await Repository.Queryable().Where(
                x => x.AccountManagerOrganizationId == input.AccountManagerOrganizationId &&
                x.AccountManagerId == input.AccountManagerId &&
                x.CustomerId == input.CustomerId && x.CustomerOrganizationId == input.CustomerOrganizationId)
                                .IgnoreQueryFilters()
                                .FirstOrDefaultAsync();



            if (cu == null)
            {
                _logger.LogInformation(GetLogMessage("Customer not found"));
                retVal.ErrorMessage = "Customer not found";
                return(retVal);
            }

            if (am == null)
            {
                _logger.LogInformation(GetLogMessage("Account manager not found"));
                retVal.ErrorMessage = "Account manager not found";
                return(retVal);
            }

            // todo: this value could come from somewhere else if it's a repeat customer
            var marketerStream        = cu.Customer.OrganizationMarketer.MarketerStream;
            var marketingAgencyStream = cu.Customer.OrganizationMarketer.MarketerBonus;

            var marketingAgreement = await _marketingAgreements.Queryable()
                                     .Where(x => x.MarketingOrganizationId == cu.Customer.MarketerOrganizationId &&
                                            x.ProviderOrganizationId == am.OrganizationId)
                                     .FirstOrDefaultAsync();

            if (marketingAgreement != null)
            {
                marketerStream        = marketingAgreement.MarketerStream;
                marketingAgencyStream = marketingAgreement.MarketingAgencyStream;
            }


            var entity = new CustomerAccount
            {
                AccountStatus = AccountStatus.Active,
                ObjectState   = ObjectState.Added,
                AccountManagerOrganizationId = input.AccountManagerOrganizationId,
                AccountManagerId             = input.AccountManagerId,
                CustomerId             = input.CustomerId,
                CreatedById            = _userInfo.UserId,
                UpdatedById            = _userInfo.UserId,
                MarketerStream         = marketerStream,
                MarketingAgencyStream  = marketingAgencyStream,
                CustomerOrganizationId = input.CustomerOrganizationId,
                PaymentTermId          = input.PaymentTermId.GetValueOrDefault(1),
                AutoApproveTimeEntries = input.AutoApproveTimeEntries
            }.InjectFrom(input) as CustomerAccount;

            entity.StatusTransitions.Add(new CustomerAccountStatusTransition()
            {
                Status      = entity.AccountStatus,
                ObjectState = ObjectState.Added
            });

            var records = 0;

            if (acctCandidate != null)
            {
                _logger.LogDebug(GetLogMessage("Existing customer account found already, was deleted: {0}"),
                                 acctCandidate.IsDeleted);

                // there is an existing account already
                entity = await Get(
                    input.AccountManagerOrganizationId,
                    input.AccountManagerId,
                    input.CustomerOrganizationId,
                    input.CustomerId);

                entity.ObjectState = ObjectState.Modified;
                entity.UpdatedById = _userInfo.UserId;
                entity.Updated     = DateTimeOffset.UtcNow;
                entity.IsDeleted   = false;
                records            = await Repository.UpdateAsync(entity, true);
            }
            else
            {
                _logger.LogDebug(GetLogMessage("Ready to create new customer"));

                // create a new account
                entity.Number =
                    await GetNextAccountId(input.AccountManagerOrganizationId);

                entity.BuyerNumber =
                    await GetNextBuyerAccountId(input.CustomerOrganizationId);

                entity.ObjectState = ObjectState.Added;
                records            = await Repository.InsertAsync(entity, true);
            }
            _logger.LogDebug(GetLogMessage("{0} customer account records updated"), records);

            if (records > 0)
            {
                retVal.Succeeded   = true;
                retVal.BuyerNumber = entity.BuyerNumber;
                retVal.Number      = entity.Number;

                await Task.Run(() =>
                {
                    RaiseEvent(new CustomerAccountCreatedEvent
                    {
                        CustomerId                   = retVal.CustomerId.Value,
                        AccountManagerId             = retVal.AccountManagerId.Value,
                        AccountManagerOrganizationId = retVal.AccountManagerOrganizationId.Value,
                        CustomerOrganizationId       = retVal.CustomerOrganizationId.Value,
                    });
                });
            }
            else
            {
                _logger.LogWarning(GetLogMessage("Unable to create customer account"));
                retVal.ErrorMessage = "Unable to create customer account";
            }


            return(retVal);
        }
예제 #8
0
        private async Task <CustomerAccountResult> CreateInternal(IOrganizationAccountManager am,
                                                                  NewCustomerAccountInput model)
        {
            var retVal = new CustomerAccountResult();

            _logger.LogInformation(GetLogMessage("AM: {0}; Input: {@input};"), am.OrganizationId, model);

            model.AccountManagerId = am.AccountManagerId;

            var person = await _personService
                         .CreatePerson(model, null, model.MarketerId, model.MarketerOrganizationId ?? am.OrganizationId);

            if (person.Succeeded)
            {
                _logger.LogDebug(GetLogMessage("Person was created successfully"));

                var result = await _organizationService.CreateOrganization(am, new OrganizationCreateInput()
                {
                    Name          = model.OrganizationName,
                    Description   = string.Empty,
                    Iso2          = model.Iso2,
                    ProvinceState = model.ProvinceState,
                }, person.PersonId.Value);

                if (result.Succeeded)
                {
                    _logger.LogWarning(GetLogMessage("Organization was created successfully"));

                    retVal.Succeeded                    = true;
                    retVal.AccountManagerId             = model.AccountManagerId;
                    retVal.AccountManagerOrganizationId = am.OrganizationId;
                    retVal.CustomerId                   = person.PersonId.Value;
                    retVal.CustomerOrganizationId       = result.OrganizationId.Value;

                    if (result?.OrganizationId != null)
                    {
                        var m = new CustomerAccountInput()
                        {
                            PaymentTermId                = model.PaymentTermId.GetValueOrDefault(1),
                            AccountManagerId             = am.AccountManagerId,
                            AccountManagerOrganizationId = am.OrganizationId,
                            CustomerId             = person.PersonId.Value,
                            CustomerOrganizationId = result.OrganizationId.Value,
                            AutoApproveTimeEntries = model.AutoApproveTimeEntries,
                        };



                        return(await Create(m));
                    }
                }
                else
                {
                    retVal.ErrorMessage = result.ErrorMessage;
                    _logger.LogWarning(GetLogMessage("unable to create organization"));
                }
            }
            else
            {
                retVal.ErrorMessage = person.ErrorMessage;
                _logger.LogWarning(GetLogMessage("unable to create person"));
            }

            return(retVal);
        }
예제 #9
0
        private async Task <CustomerAccountResult> DeleteAccount(Guid providerOrganizationId, int accountId)
        {
            _logger.LogTrace(
                GetLogMessage($@"Deleting account {accountId} from Organization {providerOrganizationId}"));

            var retVal = new CustomerAccountResult();

            var a = await Repository.Queryable()
                    .Include(x => x.Projects)
                    .ThenInclude(x => x.Contracts)
                    .ThenInclude(x => x.TimeEntries)
                    .Where(x => x.AccountManagerOrganizationId == providerOrganizationId && x.Number == accountId)
                    .IgnoreQueryFilters()
                    .FirstOrDefaultAsync();

            if (a == null)
            {
                return new CustomerAccountResult()
                       {
                           Succeeded = false
                       }
            }
            ;

            retVal.InjectFrom(a);

            a.IsDeleted   = true;
            a.UpdatedById = _userInfo.UserId;
            a.Updated     = DateTimeOffset.UtcNow;
            a.ObjectState = ObjectState.Modified;

            foreach (var p in a.Projects)
            {
                p.UpdatedById = _userInfo.UserId;

                p.IsDeleted   = true;
                p.Updated     = DateTimeOffset.UtcNow;
                p.ObjectState = ObjectState.Modified;

                foreach (var contract in p.Contracts)
                {
                    contract.Updated     = DateTimeOffset.UtcNow;
                    contract.UpdatedById = _userInfo.UserId;
                    contract.IsDeleted   = true;
                    contract.ObjectState = ObjectState.Modified;

                    foreach (var e in contract.TimeEntries)
                    {
                        e.Updated     = DateTimeOffset.UtcNow;
                        e.UpdatedById = _userInfo.UserId;
                        e.IsDeleted   = true;
                        e.ObjectState = ObjectState.Modified;
                    }
                }
            }

            var result = Repository.InsertOrUpdateGraph(a, true);

            _logger.LogDebug(GetLogMessage("{0} records updated"));
            if (result > 0)
            {
                retVal.Succeeded = true;
                var evt = new CustomerAccountDeletedEvent().InjectFrom(retVal) as CustomerAccountDeletedEvent;
                await Task.Run(() =>
                {
                    RaiseEvent(evt);
                });
            }

            return(retVal);
        }
    }