Hourly inventory updates
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using PartSource.Automation.Models.Configuration;
|
using PartSource.Automation.Models.Configuration;
|
||||||
using PartSource.Automation.Models.Ftp;
|
using PartSource.Automation.Models.Ftp;
|
||||||
using PartSource.Automation.Services;
|
using PartSource.Automation.Services;
|
||||||
@@ -18,36 +19,50 @@ namespace PartSource.Automation.Jobs.POC
|
|||||||
public class BulkUpdateInventory : IAutomationJob
|
public class BulkUpdateInventory : IAutomationJob
|
||||||
{
|
{
|
||||||
private readonly FtpService _ftpService;
|
private readonly FtpService _ftpService;
|
||||||
|
private readonly ILogger<BulkUpdateInventory> _logger;
|
||||||
|
|
||||||
public BulkUpdateInventory(IConfiguration configuration)
|
public BulkUpdateInventory(IConfiguration configuration, ILogger<BulkUpdateInventory> logger)
|
||||||
{
|
{
|
||||||
FtpConfiguration ftpConfiguration = configuration.GetSection("FtpServers:AzureConfiguration").Get<FtpConfiguration>();
|
FtpConfiguration ftpConfiguration = configuration.GetSection("FtpServers:AutomationConfiguration").Get<FtpConfiguration>();
|
||||||
_ftpService = new FtpService(ftpConfiguration);
|
_ftpService = new FtpService(ftpConfiguration);
|
||||||
|
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Run(CancellationToken token, params string[] arguments)
|
public async Task Run(CancellationToken token, params string[] arguments)
|
||||||
{
|
{
|
||||||
FtpFileInfo lastUploadedFile = _ftpService.ListFilesExtended()
|
FtpFileInfo lastUploadedFile = _ftpService.ListFilesExtended()
|
||||||
.Where(f => f.FileType == FtpFileType.File && f.Filename.IndexOf("Availability") > -1)
|
.Where(f => f.FileType == FtpFileType.File && f.Filename.IndexOf("Availability Full") > -1)
|
||||||
.OrderByDescending(f => f.Modified)
|
.OrderByDescending(f => f.Modified)
|
||||||
.First();
|
.FirstOrDefault();
|
||||||
|
|
||||||
string file = _ftpService.Download(lastUploadedFile.Filename, Path.GetTempPath());
|
if (lastUploadedFile == null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"No full inventory file available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string file = _ftpService.Download(lastUploadedFile.Filename);
|
||||||
|
|
||||||
DataTable dataTable = GetDataTable(file);
|
DataTable dataTable = GetDataTable(file);
|
||||||
|
|
||||||
using SqlConnection connection = new SqlConnection("Server=tcp:ps-automation-stage.eastus2.cloudapp.azure.com,1433;Initial Catalog=ps-whi-stage;Persist Security Info=False;User ID=stageuser;Password=]FXepK^cFYS|[H<;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;");
|
using SqlConnection connection = new SqlConnection("Server=tcp:ps-whi.database.windows.net,1433;Initial Catalog=ps-whi-test;Persist Security Info=False;User ID=ps-whi;Password=9-^*N5dw!6:|.5Q;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;");
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
|
using SqlCommand command = new SqlCommand("TRUNCATE TABLE PartAvailability", connection);
|
||||||
|
await command.ExecuteNonQueryAsync();
|
||||||
|
|
||||||
using SqlBulkCopy bulk = new SqlBulkCopy(connection)
|
using SqlBulkCopy bulk = new SqlBulkCopy(connection)
|
||||||
{
|
{
|
||||||
DestinationTableName = $"PartAvailability",
|
DestinationTableName = "PartAvailability",
|
||||||
BulkCopyTimeout = 14400
|
BulkCopyTimeout = 14400
|
||||||
};
|
};
|
||||||
|
|
||||||
bulk.WriteToServer(dataTable);
|
bulk.WriteToServer(dataTable);
|
||||||
|
|
||||||
return;
|
_ftpService.Delete(lastUploadedFile.Filename);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataTable GetDataTable(string filename)
|
private DataTable GetDataTable(string filename)
|
||||||
|
|||||||
@@ -32,20 +32,21 @@ namespace PartSource.Automation.Jobs.POC
|
|||||||
public async Task Run(CancellationToken token, params string[] arguments)
|
public async Task Run(CancellationToken token, params string[] arguments)
|
||||||
{
|
{
|
||||||
FtpFileInfo lastUploadedFile = _ftpService.ListFilesExtended()
|
FtpFileInfo lastUploadedFile = _ftpService.ListFilesExtended()
|
||||||
.Where(f => f.FileType == FtpFileType.File && f.Modified >= DateTime.Now.AddHours(-24) && f.Filename.IndexOf("Availability Partial") > -1)
|
.Where(f => f.FileType == FtpFileType.File && f.Filename.IndexOf("Availability Partial") > -1)
|
||||||
.OrderByDescending(f => f.Modified)
|
.OrderByDescending(f => f.Modified)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
if (lastUploadedFile == null)
|
if (lastUploadedFile == null)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"No partial inventory file available for the time period {DateTime.Now.AddHours(-24)} - {DateTime.Now}");
|
_logger.LogInformation($"No partial inventory file available.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string file = _ftpService.Download($"{lastUploadedFile.Filename}", "C:\\Users\\Tom\\Desktop");
|
_logger.LogInformation("Processing {filename}", lastUploadedFile.Filename);
|
||||||
|
|
||||||
|
string file = _ftpService.Download($"{lastUploadedFile.Filename}");
|
||||||
|
|
||||||
using SqlConnection connection = new SqlConnection("Server=tcp:ps-automation-stage.eastus2.cloudapp.azure.com,1433;Initial Catalog=ps-whi-stage;Persist Security Info=False;User ID=stageuser;Password=]FXepK^cFYS|[H<;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;");
|
using SqlConnection connection = new SqlConnection("Server=tcp:ps-whi.database.windows.net,1433;Initial Catalog=ps-whi-test;Persist Security Info=False;User ID=ps-whi;Password=9-^*N5dw!6:|.5Q;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;");
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
using StreamReader reader = new StreamReader(file);
|
using StreamReader reader = new StreamReader(file);
|
||||||
@@ -55,17 +56,17 @@ namespace PartSource.Automation.Jobs.POC
|
|||||||
{
|
{
|
||||||
line = reader.ReadLine();
|
line = reader.ReadLine();
|
||||||
|
|
||||||
string[] columns = line.Split(",");
|
string[] columns = line.Split("|");
|
||||||
for (int i = 0; i < columns.Length; i++)
|
for (int i = 0; i < columns.Length; i++)
|
||||||
{
|
{
|
||||||
columns[i] = columns[i].Replace("\"", string.Empty);
|
columns[i] = columns[i].Replace("\"", string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int.TryParse(columns[0], out int store)
|
if (int.TryParse(columns[0], out int store)
|
||||||
&& int.TryParse(columns[1], out int quantity)
|
&& int.TryParse(columns[1], out int sku)
|
||||||
&& int.TryParse(columns[2], out int sku))
|
&& int.TryParse(columns[2], out int quantity))
|
||||||
{
|
{
|
||||||
using SqlCommand sqlCommand = new SqlCommand("UPDATE Inventory SET QTY = @qty WHERE SKU = @sku AND Store = @store", connection);
|
using SqlCommand sqlCommand = new SqlCommand("UPDATE PartAvailability SET QTY = @qty WHERE SKU = @sku AND Store = @store", connection);
|
||||||
sqlCommand.Parameters.Add(new SqlParameter("qty", quantity));
|
sqlCommand.Parameters.Add(new SqlParameter("qty", quantity));
|
||||||
sqlCommand.Parameters.Add(new SqlParameter("sku", sku));
|
sqlCommand.Parameters.Add(new SqlParameter("sku", sku));
|
||||||
sqlCommand.Parameters.Add(new SqlParameter("store", store));
|
sqlCommand.Parameters.Add(new SqlParameter("store", store));
|
||||||
@@ -74,7 +75,9 @@ namespace PartSource.Automation.Jobs.POC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
_ftpService.Delete(lastUploadedFile.Filename);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using AutoMapper;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
@@ -7,12 +6,10 @@ using Microsoft.Extensions.Logging;
|
|||||||
using PartSource.Automation.Jobs;
|
using PartSource.Automation.Jobs;
|
||||||
using PartSource.Automation.Jobs.POC;
|
using PartSource.Automation.Jobs.POC;
|
||||||
using PartSource.Automation.Services;
|
using PartSource.Automation.Services;
|
||||||
using PartSource.Data;
|
|
||||||
using PartSource.Data.AutoMapper;
|
using PartSource.Data.AutoMapper;
|
||||||
using PartSource.Data.Contexts;
|
using PartSource.Data.Contexts;
|
||||||
using PartSource.Services;
|
using PartSource.Services;
|
||||||
using Ratermania.Automation.DependencyInjection;
|
using Ratermania.Automation.DependencyInjection;
|
||||||
using Ratermania.Automation.Logging;
|
|
||||||
using Ratermania.Shopify.DependencyInjection;
|
using Ratermania.Shopify.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -20,111 +17,116 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace PartSource.Automation
|
namespace PartSource.Automation
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static async Task Main(string[] args){
|
static async Task Main(string[] args)
|
||||||
try
|
{
|
||||||
{
|
try
|
||||||
using IHost host = CreateHostBuilder().Build();
|
{
|
||||||
|
using IHost host = CreateHostBuilder().Build();
|
||||||
|
|
||||||
await host.StartAsync();
|
await host.StartAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine(ex.ToString());
|
Console.WriteLine(ex.ToString());
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IHostBuilder CreateHostBuilder()
|
private static IHostBuilder CreateHostBuilder()
|
||||||
{
|
{
|
||||||
return Host.CreateDefaultBuilder()
|
return Host.CreateDefaultBuilder()
|
||||||
.ConfigureAppConfiguration(builder =>
|
.ConfigureAppConfiguration(builder =>
|
||||||
{
|
{
|
||||||
string environment = Environment.GetEnvironmentVariable("AUTOMATION_ENVIRONMENT");
|
string environment = Environment.GetEnvironmentVariable("AUTOMATION_ENVIRONMENT");
|
||||||
|
|
||||||
builder.SetBasePath(Directory.GetCurrentDirectory())
|
builder.SetBasePath(Directory.GetCurrentDirectory())
|
||||||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||||
.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true);
|
||||||
})
|
})
|
||||||
.ConfigureServices((builder, services) =>
|
.ConfigureServices((builder, services) =>
|
||||||
{
|
{
|
||||||
services.AddDbContext<PartSourceContext>(options =>
|
services.AddDbContext<PartSourceContext>(options =>
|
||||||
options.UseSqlServer(builder.Configuration.GetConnectionString("PartSourceDatabase"), opts => opts.EnableRetryOnFailure())
|
options.UseSqlServer(builder.Configuration.GetConnectionString("PartSourceDatabase"), opts => opts.EnableRetryOnFailure())
|
||||||
)
|
)
|
||||||
|
|
||||||
.AddDbContext<FitmentContext>(options =>
|
.AddDbContext<FitmentContext>(options =>
|
||||||
options.UseSqlServer(builder.Configuration.GetConnectionString("FitmentDatabase"), opts =>
|
options.UseSqlServer(builder.Configuration.GetConnectionString("FitmentDatabase"), opts =>
|
||||||
{
|
{
|
||||||
opts.EnableRetryOnFailure();
|
opts.EnableRetryOnFailure();
|
||||||
opts.CommandTimeout(600);
|
opts.CommandTimeout(600);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
.AddShopify(options =>
|
.AddShopify(options =>
|
||||||
{
|
{
|
||||||
options.ApiKey = builder.Configuration["Shopify:ApiKey"];
|
options.ApiKey = builder.Configuration["Shopify:ApiKey"];
|
||||||
options.ApiSecret = builder.Configuration["Shopify:ApiSecret"];
|
options.ApiSecret = builder.Configuration["Shopify:ApiSecret"];
|
||||||
options.ApiVersion = "2022-10";
|
options.ApiVersion = "2022-10";
|
||||||
options.ShopDomain = builder.Configuration["Shopify:ShopDomain"];
|
options.ShopDomain = builder.Configuration["Shopify:ShopDomain"];
|
||||||
|
|
||||||
//options.ApiKey = "9a533dad460321c6ce8f30bf5b8691ed";
|
//options.ApiKey = "9a533dad460321c6ce8f30bf5b8691ed";
|
||||||
//options.ApiSecret = "dc9e28365d9858e544d57ac7af43fee7";
|
//options.ApiSecret = "dc9e28365d9858e544d57ac7af43fee7";
|
||||||
//options.ApiVersion = "2022-10";
|
//options.ApiVersion = "2022-10";
|
||||||
//options.ShopDomain = "dev-partsource.myshopify.com";
|
//options.ShopDomain = "dev-partsource.myshopify.com";
|
||||||
})
|
})
|
||||||
|
|
||||||
.AddAutomation(options =>
|
.AddAutomation(options =>
|
||||||
{
|
{
|
||||||
options.HasBaseInterval(new TimeSpan(0, 5, 0))
|
options.HasBaseInterval(new TimeSpan(0, 5, 0))
|
||||||
.HasMaxFailures(1)
|
.HasMaxFailures(1)
|
||||||
//.HasJob<TestJob>(options => options.HasInterval(new TimeSpan(7, 0, 0, 0)));
|
//.HasJob<TestJob>(options => options.HasInterval(new TimeSpan(7, 0, 0, 0)));
|
||||||
//
|
//
|
||||||
//.HasJob<SyncronizeProducts>(options => options.HasInterval(new TimeSpan(24, 0, 0)))
|
//.HasJob<SyncronizeProducts>(options => options.HasInterval(new TimeSpan(24, 0, 0)))
|
||||||
// .HasJob<ProcessWhiFitment>(options => options.HasInterval(new TimeSpan(24, 0, 0)));
|
// .HasJob<ProcessWhiFitment>(options => options.HasInterval(new TimeSpan(24, 0, 0)));
|
||||||
//.HasJob<ProcessWhiVehicles>(options => options.HasInterval(new TimeSpan(24, 0, 0))
|
//.HasJob<ProcessWhiVehicles>(options => options.HasInterval(new TimeSpan(24, 0, 0))
|
||||||
//.HasDependency<SyncronizeProducts>()
|
//.HasDependency<SyncronizeProducts>()
|
||||||
//.HasJob<UpdateFitment>(options => options.HasInterval(new TimeSpan(24, 0, 0)));
|
//.HasJob<UpdateFitment>(options => options.HasInterval(new TimeSpan(24, 0, 0)));
|
||||||
//.HasJob<UpdatePositioning>(options => options.HasInterval(new TimeSpan(24, 0, 0))
|
//.HasJob<UpdatePositioning>(options => options.HasInterval(new TimeSpan(24, 0, 0))
|
||||||
// .HasDependency<UpdateFitment>()
|
// .HasDependency<UpdateFitment>()
|
||||||
// .HasDependency<ProcessWhiFitment>()
|
// .HasDependency<ProcessWhiFitment>()
|
||||||
// .HasDependency<SyncronizeProducts>()
|
// .HasDependency<SyncronizeProducts>()
|
||||||
// .StartsAt(DateTime.Today.AddHours(8))
|
// .StartsAt(DateTime.Today.AddHours(8))
|
||||||
//) ;
|
//) ;
|
||||||
//.HasJob<StatusCheck>(options => options.HasInterval(new TimeSpan(24, 0, 0))
|
//.HasJob<StatusCheck>(options => options.HasInterval(new TimeSpan(24, 0, 0))
|
||||||
// .StartsAt(DateTime.Parse("2021-04-01 08:00:00"))
|
// .StartsAt(DateTime.Parse("2021-04-01 08:00:00"))
|
||||||
//)
|
//)
|
||||||
.HasJob<ProcessWhiVehicles>(options =>
|
.HasJob<BulkUpdateInventory>(options =>
|
||||||
options.HasInterval(new TimeSpan(24, 0, 0))
|
options.HasInterval(new TimeSpan(1, 0, 0))
|
||||||
.StartsAt(DateTime.Today)
|
.StartsAt(DateTime.Today.AddHours(-27))
|
||||||
);
|
)
|
||||||
|
.HasJob<PartialInventoryUpdate>(options =>
|
||||||
|
options.HasInterval(new TimeSpan(1, 0, 0))
|
||||||
|
.StartsAt(DateTime.Today.AddHours(-27).AddMinutes(30))
|
||||||
|
);
|
||||||
|
|
||||||
//.HasJob<PartialInventoryUpdate>(options => options.HasInterval(new TimeSpan(1, 0, 0))
|
//.HasJob<PartialInventoryUpdate>(options => options.HasInterval(new TimeSpan(1, 0, 0))
|
||||||
//.HasDependency<ExecuteSsisPackages>()
|
//.HasDependency<ExecuteSsisPackages>()
|
||||||
// .StartsAt(DateTime.Today)
|
// .StartsAt(DateTime.Today)
|
||||||
//);
|
//);
|
||||||
//);
|
//);
|
||||||
//.AddApiServer();
|
//.AddApiServer();
|
||||||
})
|
})
|
||||||
|
|
||||||
.AddSingleton<EmailService>()
|
.AddSingleton<EmailService>()
|
||||||
.AddSingleton<SsisService>()
|
.AddSingleton<SsisService>()
|
||||||
.AddSingleton<WhiSeoService>()
|
.AddSingleton<WhiSeoService>()
|
||||||
.AddSingleton<VehicleService>()
|
.AddSingleton<VehicleService>()
|
||||||
.AddSingleton<VehicleFitmentService>()
|
.AddSingleton<VehicleFitmentService>()
|
||||||
.AddSingleton<NexpartService>()
|
.AddSingleton<NexpartService>()
|
||||||
.AddSingleton<PartService>()
|
.AddSingleton<PartService>()
|
||||||
|
|
||||||
.AddAutoMapper(typeof(PartSourceProfile));
|
.AddAutoMapper(typeof(PartSourceProfile));
|
||||||
})
|
})
|
||||||
.ConfigureLogging((builder, logging) =>
|
.ConfigureLogging((builder, logging) =>
|
||||||
{
|
{
|
||||||
logging.AddEventLog();
|
logging.AddEventLog();
|
||||||
logging.AddConsole();
|
logging.AddConsole();
|
||||||
|
|
||||||
// logging.AddProvider(new AutomationLoggerProvider());
|
// logging.AddProvider(new AutomationLoggerProvider());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ namespace PartSource.Automation.Services
|
|||||||
|
|
||||||
public string Download(string filename, string destination = null)
|
public string Download(string filename, string destination = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri($"{_ftpConfiguration.Url}/{filename}"));
|
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri($"{_ftpConfiguration.Url}/{filename}"));
|
||||||
request.Credentials = new NetworkCredential(_ftpConfiguration.Username, _ftpConfiguration.Password);
|
request.Credentials = new NetworkCredential(_ftpConfiguration.Username, _ftpConfiguration.Password);
|
||||||
request.Method = WebRequestMethods.Ftp.DownloadFile;
|
request.Method = WebRequestMethods.Ftp.DownloadFile;
|
||||||
@@ -116,5 +114,15 @@ namespace PartSource.Automation.Services
|
|||||||
|
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Delete(string filename)
|
||||||
|
{
|
||||||
|
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri($"{_ftpConfiguration.Url}/{filename}"));
|
||||||
|
request.Credentials = new NetworkCredential(_ftpConfiguration.Username, _ftpConfiguration.Password);
|
||||||
|
request.Method = WebRequestMethods.Ftp.DeleteFile;
|
||||||
|
|
||||||
|
|
||||||
|
using FtpWebResponse response = (FtpWebResponse)request.GetResponse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;Integrated Security=true;TrustServerCertificate=True",
|
//"FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;Integrated Security=true;TrustServerCertificate=True",
|
||||||
|
//"FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;User ID=stageuser;Password=FXepK^cFYS|[H<;Encrypt=True;TrustServerCertificate=True;Connection Timeout=300",
|
||||||
|
"FitmentDatabase": "Data Source=localhost;User ID=stageuser;Password=FXepK^cFYS|[H<;Connect Timeout=30;Encrypt=True;Trust Server Certificate=True;Application Intent=ReadWrite;Multi Subnet Failover=False",
|
||||||
"PartSourceDatabase": "Server=tcp:ps-whi.database.windows.net,1433;Initial Catalog=ps-whi-stage;Persist Security Info=False;User ID=ps-whi;Password=9-^*N5dw!6:|.5Q;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
|
"PartSourceDatabase": "Server=tcp:ps-whi.database.windows.net,1433;Initial Catalog=ps-whi-stage;Persist Security Info=False;User ID=ps-whi;Password=9-^*N5dw!6:|.5Q;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
|
||||||
},
|
},
|
||||||
"emailConfiguration": {
|
"emailConfiguration": {
|
||||||
|
|||||||
Reference in New Issue
Block a user