public async Task <string> Seed(EnvironmentSeed seed)
        {
            if (string.IsNullOrEmpty(_settings.OrderCloudSettings.ApiUrl))
            {
                throw new Exception("Missing required app setting OrderCloudSettings:ApiUrl");
            }
            if (string.IsNullOrEmpty(_settings.OrderCloudSettings.WebhookHashKey))
            {
                throw new Exception("Missing required app setting OrderCloudSettings:WebhookHashKey");
            }
            if (string.IsNullOrEmpty(_settings.EnvironmentSettings.BaseUrl))
            {
                throw new Exception("Missing required app setting EnvironmentSettings:BaseUrl");
            }

            var portalUserToken = await _portal.Login(seed.PortalUsername, seed.PortalPassword);

            await VerifyOrgExists(seed.SellerOrgID, portalUserToken);

            var orgToken = await _portal.GetOrgToken(seed.SellerOrgID, portalUserToken);

            await CreateDefaultSellerUser(orgToken);
            await CreateApiClients(orgToken);
            await CreateSecurityProfiles(seed, orgToken);
            await AssignSecurityProfiles(seed, orgToken);

            var apiClients = await GetApiClients(orgToken);

            await CreateWebhooks(new string[] { apiClients.BuyerUiApiClient.ID }, apiClients.AdminUiApiClient.ID, orgToken);
            await CreateMessageSenders(orgToken);
            await CreateIncrementors(orgToken);             // must be before CreateBuyers

            var userContext = await GetVerifiedUserContext(apiClients.MiddlewareApiClient);

            await CreateBuyers(seed, userContext);
            await CreateXPIndices(orgToken);
            await CreateAndAssignIntegrationEvents(new string[] { apiClients.BuyerUiApiClient.ID }, apiClients.BuyerLocalUiApiClient.ID, orgToken);
            await CreateSuppliers(userContext, seed, orgToken);
            await CreateContentDocSchemas(userContext);
            await CreateDefaultContentDocs(userContext);

            return(orgToken);
        }
        public async Task <EnvironmentSeedResponse> Seed(EnvironmentSeed seed)
        {
            OcEnv requestedEnv = validateEnvironment(seed.OrderCloudSettings.Environment);

            if (requestedEnv.environmentName == OrderCloudEnvironments.Production.environmentName && seed.SellerOrgID == null)
            {
                throw new Exception("Cannot create a production environment via the environment seed endpoint. Please contact an OrderCloud Developer to create a production org.");
            }

            // lets us handle requests to multiple api environments
            _oc = new OrderCloudClient(new OrderCloudClientConfig
            {
                ApiUrl  = requestedEnv.apiUrl,
                AuthUrl = requestedEnv.apiUrl
            });

            var portalUserToken = await _portal.Login(seed.PortalUsername, seed.PortalPassword);

            var sellerOrg = await GetOrCreateOrg(portalUserToken, requestedEnv.environmentName, seed.SellerOrgName, seed.SellerOrgID);

            var orgToken = await _portal.GetOrgToken(sellerOrg.Id, portalUserToken);

            await CreateDefaultSellerUsers(seed, orgToken);

            await CreateIncrementors(orgToken);         // must be before CreateBuyers
            await CreateMessageSenders(seed, orgToken); // must be before CreateBuyers and CreateSuppliers

            await CreateSecurityProfiles(orgToken);
            await CreateBuyers(seed, orgToken);
            await CreateConfigureAnonBuyer(seed, orgToken);

            await CreateApiClients(orgToken);
            await AssignSecurityProfiles(seed, orgToken);

            var apiClients = await GetApiClients(orgToken);

            await CreateXPIndices(orgToken);
            await CreateAndAssignIntegrationEvents(new string[] { apiClients.BuyerUiApiClient.ID }, apiClients.BuyerLocalUiApiClient.ID, orgToken, seed);
            await CreateSuppliers(seed, orgToken);

            // populate default english translations into blob container name: settings.BlobSettings.ContainerNameTranslations or "ngx-translate" if setting is not defined
            // provide other language files to support multiple languages

            var englishTranslationsPath = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "Assets", "english-translations.json"));

            if (seed?.BlobSettings?.ConnectionString != null && seed?.BlobSettings?.ContainerNameTranslations != null)
            {
                var translationsConfig = new BlobServiceConfig()
                {
                    ConnectionString = seed.BlobSettings.ConnectionString,
                    Container        = seed.BlobSettings.ContainerNameTranslations,
                    AccessType       = BlobContainerPublicAccessType.Container
                };
                var translationsBlob = new OrderCloudIntegrationsBlobService(translationsConfig);
                await translationsBlob.Save("i18n/en.json", File.ReadAllText(englishTranslationsPath));
            }

            return(new EnvironmentSeedResponse
            {
                Comments = "Success! Your environment is now seeded. The following clientIDs & secrets should be used to finalize the configuration of your application. The initial admin username and password can be used to sign into your admin application",
                OrganizationName = sellerOrg.Name,
                OrganizationID = sellerOrg.Id,
                OrderCloudEnvironment = requestedEnv.environmentName,
                ApiClients = new Dictionary <string, dynamic>
                {
                    ["Middleware"] = new
                    {
                        ClientID = apiClients.MiddlewareApiClient.ID,
                        ClientSecret = apiClients.MiddlewareApiClient.ClientSecret
                    },
                    ["Seller"] = new
                    {
                        ClientID = apiClients.AdminUiApiClient.ID
                    },
                    ["Buyer"] = new
                    {
                        ClientID = apiClients.BuyerUiApiClient.ID
                    }
                }
            });
        }
        public async Task <EnvironmentSeedResponse> Seed(EnvironmentSeed seed)
        {
            if (string.IsNullOrEmpty(_settings.OrderCloudSettings.ApiUrl))
            {
                throw new Exception("Missing required app setting OrderCloudSettings:ApiUrl");
            }
            if (string.IsNullOrEmpty(_settings.OrderCloudSettings.WebhookHashKey))
            {
                throw new Exception("Missing required app setting OrderCloudSettings:WebhookHashKey");
            }
            if (string.IsNullOrEmpty(_settings.EnvironmentSettings.MiddlewareBaseUrl))
            {
                throw new Exception("Missing required app setting EnvironmentSettings:MiddlewareBaseUrl");
            }

            var portalUserToken = await _portal.Login(seed.PortalUsername, seed.PortalPassword);

            await VerifyOrgExists(seed.SellerOrgID, portalUserToken);

            var orgToken = await _portal.GetOrgToken(seed.SellerOrgID, portalUserToken);

            await CreateDefaultSellerUsers(seed, orgToken);

            await CreateIncrementors(orgToken);         // must be before CreateBuyers
            await CreateMessageSenders(seed, orgToken); // must be before CreateBuyers and CreateSuppliers

            await CreateSecurityProfiles(orgToken);
            await CreateBuyers(seed, orgToken);
            await CreateConfigureAnonBuyer(seed, orgToken);

            await CreateApiClients(orgToken);
            await AssignSecurityProfiles(seed, orgToken);

            var apiClients = await GetApiClients(orgToken);

            await CreateXPIndices(orgToken);
            await CreateAndAssignIntegrationEvents(new string[] { apiClients.BuyerUiApiClient.ID }, apiClients.BuyerLocalUiApiClient.ID, orgToken);
            await CreateSuppliers(seed, orgToken);

            // populates exchange rates into blob container name: settings.BlobSettings.ContainerNameExchangeRates or "currency" if setting is not defined
            await _exhangeRates.Update();

            // populate default english translations into blob container name: settings.BlobSettings.ContainerNameTranslations or "ngx-translate" if setting is not defined
            // provide other language files to support multiple languages
            var currentDirectory        = Directory.GetCurrentDirectory();
            var englishTranslationsPath = Path.GetFullPath(Path.Combine(currentDirectory, @"..\Headstart.Common\Assets\english-translations.json"));
            await _translationsBlob.Save("i18n/en.json", File.ReadAllText(englishTranslationsPath));

            return(new EnvironmentSeedResponse
            {
                Comments = "Success! Your environment is now seeded. The following clientIDs & secrets should be used to finalize the configuration of your application. The initial admin username and password can be used to sign into your admin application",
                ApiClients = new Dictionary <string, dynamic>
                {
                    ["Middleware"] = new
                    {
                        ClientID = apiClients.MiddlewareApiClient.ID,
                        ClientSecret = apiClients.MiddlewareApiClient.ClientSecret
                    },
                    ["Seller"] = new
                    {
                        ClientID = apiClients.AdminUiApiClient.ID
                    },
                    ["Buyer"] = new
                    {
                        ClientID = apiClients.BuyerUiApiClient.ID
                    }
                }
            });
        }