using Microsoft.AspNetCore.Mvc;
using Stl.Fusion.Authentication;
using System.Collections.Generic;
using System.Globalization;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
using System.Runtime.CompilerServices;
using HttpPostAttribute = Microsoft.AspNetCore.Mvc.HttpPostAttribute;
namespace Shakely.YahooApi.Server.Services;
public class WebService : ApiControllerAttribute, IWebService
private readonly string _xml;
private const string APPDBCONTEXT = "AppDbContext";
public const int BUFFER_LENGTH = 1024;
private readonly ILogger _log;
private readonly IAuth _auth;
private readonly IAuthBackend _authBackend;
private readonly DataStore _dataStore;
private readonly string _symbol;
private readonly DataUtil _dataUtil;
private LocalDate StartDate { get; set; } = new LocalDate(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
internal static CultureInfo DefaultCulture { get; set; } = new CultureInfo("en-US");
IAuthBackend authBackend,
ILogger<WebService>? log = null)
_log = log ??= NullLogger<WebService>.Instance;
_authBackend = authBackend;
_dataStore = new("Vic.ai");
[XmlAttribute("noNamespaceSchemaLocation", Namespace = XmlSchema.InstanceNamespace)]
public string YSITRANALLXSD = @"C:\Voyager\Thirdparty\708web_10954646\XSD\YsiTranAll.xsd";
public const string vbCrLf = "\r\n";
public async Task<string> GetRequestXml(string functionName, string database, string? propertyId = default, string? vendorId = default)
DataStore dataStore = new();
string baseXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" +
" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">" +
XDocument xml = XDocument.Parse(baseXml);
XElement envelope = xml.Root;
XNamespace soap12Ns = envelope.GetNamespaceOfPrefix("soap12");
vendorId = vendorId is null ? "": vendorId;
propertyId = propertyId is null ? "" : propertyId;
var b = "http://tempuri.org/YSI.Interfaces.WebServices/";
string UserSuffix = "Name";
string type = "ysiItfVendorInvoicing";
if (functionName == "RunScript")
b = "YSI.WebServices.SysSqlScript";
UserSuffix = functionName == "RunScript" ? "Code" : "Name";
var UserNameValue = database == "Vic.ai" ? _dataStore.UserName : "messi";
XElement body = new(soap12Ns + "Body");
XNamespace ns = $"{b}{type}";
XElement profile = new(ns + functionName);
var Server = functionName == "RunScript" ? "Server" : "ServerName";
profile.Add(new object[] {
new XElement(ns + $"User{UserSuffix}", UserNameValue),
new XElement(ns + "Password", database == "hiid_demo70" ? dataStore.Password : _dataStore.Password),
new XElement(ns + Server, database == "hiid_demo70" ? dataStore.ServerName : _dataStore.ServerName),
new XElement(ns + "Database", database == "hiid_demo70" ? dataStore.Database : _dataStore.Database),
new XElement(ns + "Platform", _dataStore.Platform),
if (functionName != "RunScript")
profile.Add(new object[] {
new XElement(ns + "InterfaceEntity", _dataStore.InterfaceEntity),
new XElement(ns + "InterfaceLicense", File.ReadAllText(_dataStore.LicenseFilePath).Replace(vbCrLf, "")),
if (functionName == "RunScript")
profile.Add(new object[] {
new XElement(ns + "ScriptFile", "rs_sql_Get_Table_Contents.txt"),
new XElement(ns + "URL", $"&objname=pmuser&WhereClause=uname='{UserNameValue}'"),
if (functionName == "GetPayables" || functionName == "GetPayables2")
new XElement(ns + "YardiPropertyId", propertyId),
new XElement(ns + "VendorId", vendorId),
new XElement(ns + "InvoicePostMonthFrom", DateTime.Now.AddYears(-5)),
new XElement(ns + "InvoicePostMonthTo", DateTime.Now),
new XElement(ns + "InvoiceFromDate", DateTime.Now.AddYears(-5)),
new XElement(ns + "InvoiceToDate", DateTime.Now),
new XElement(ns + "UnpaidOnly", false),
new XElement(ns + "CheckFromDate", DateTime.Now.AddYears(-5)),
new XElement(ns + "CheckToDate", DateTime.Now),
new XElement(ns + "InvoiceCreationFromDate", DateTime.Now.AddYears(-5)),
new XElement(ns + "InvoiceCreationToDate", DateTime.Now),
new XElement(ns + "No3rdPartyInv", false),
if (functionName == "GetPayables2")
new XElement(ns + "PayableId", "300330869"),
if (functionName == "ExportChartOfAccounts")
new XElement(ns + "PropertyId", propertyId)
if (functionName == "ReviewPayableBatch")
new XElement(ns + "BatchId", "")
if (functionName == "GetPayables2")
new XElement(ns + "BatchId", "")
if (functionName == "GetPayableByBatchId")
new XElement(ns + "BatchId", "1100011137")
if (functionName == "GetVendors_Login" || functionName == "GetVendor_Login")
new XElement(ns + "YardiPropertyId", propertyId),
new XElement(ns + "VendorId", vendorId),
Log(xml.ToString(), ConsoleColor.Green);
public virtual async Task<string> PostAsync(string functionName, string database = default, string? propertyId = default, string? vendorId = default, string baseAddress = "https://www.yardipcv.com/8223tp7s7dev/webservices/itfvendorinvoicing.asmx?op=", CancellationToken cancellationToken = default)
using var http = new HttpClient();
var b = "http://tempuri.org/YSI.Interfaces.WebServices/";
string type = "ysiItfVendorInvoicing";
if (database == "hiid_demo70")
baseAddress = Regex.Replace(baseAddress, @"(www\.yardipcv\.com\/8223tp7s7dev)", "localhost/VoyagerDev");
baseAddress = baseAddress.Replace("https", "http");
if (functionName == "RunScript")
baseAddress = baseAddress.Replace("itfvendorinvoicing", "SysSqlScript");
b = "http://tempuri.org/YSI.WebServices.SysSqlScript/";
var url = http.BaseAddress = new Uri($"{baseAddress}{functionName}");
http.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/soap+xml"));
var reqxml = await GetRequestXml(functionName, database, propertyId, vendorId);
HttpRequestMessage request = new(HttpMethod.Post, url)
Content = new StringContent(reqxml, Encoding.UTF8, "application/soap+xml")
HttpResponseMessage response = await http.SendAsync(request);
var responseMessage = await response.Content.ReadAsStreamAsync();
using (System.IO.StreamReader reader = new(responseMessage, Encoding.UTF8))
xml = await reader.ReadToEndAsync();
XDocument doc = XDocument.Parse(xml);
public virtual async Task<string> GetAsync(string functionName, string database, string baseAddress = "https://www.yardipcv.com/8223tp7s7dev/webservices/itfvendorinvoicing.asmx?op=", CancellationToken cancellationToken = default)
using var http = new HttpClient();
string result = string.Empty;
var b = "http://tempuri.org/YSI.Interfaces.WebServices/";
string type = "ysiItfVendorInvoicing";
if (database == "hiid_demo70")
baseAddress = Regex.Replace(baseAddress, @"(www\.yardipcv\.com\/8223tp7s7dev)", "localhost/VoyagerDev");
baseAddress = baseAddress.Replace("https", "http");
if (functionName == "RunScript")
baseAddress = baseAddress.Replace("itfvendorinvoicing", "SysSqlScript");
b = "http://tempuri.org/YSI.WebServices.SysSqlScript/";
var url = http.BaseAddress = new Uri($"{baseAddress}{functionName}");
http.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/soap+xml"));
var req = await GetRequestXml(functionName, database);
using HttpRequestMessage request = new(HttpMethod.Get, url)
Content = new StringContent(req, Encoding.UTF8, "application/soap+xml")
HttpResponseMessage response = await http.SendAsync(request, cancellationToken);
var responseMessage = await response.Content.ReadAsStreamAsync(cancellationToken);
using (System.IO.StreamReader reader = new(responseMessage, Encoding.UTF8))
xml = await reader.ReadToEndAsync();
var endText = "</soap12:Envelope>";
if (functionName == "RunScript")
var text = $"\"{b}{type}/{functionName}\"";
result = xml.ToString().Replace("\r\n\r\n", "\r\n").Replace(">", ">").Replace("<", "<").Trim();
start = result.IndexOf(text) >= 0 ? result.IndexOf(text) : 0;
if (!result.Contains(text))
if (!result.Contains(endText))
var end2 = result.IndexOf(endText);
end = result.Substring(start, result.Length - result.IndexOf(endText)).IndexOf(endText);
return result[start..end2];
Log(e.Message, ConsoleColor.DarkRed);
return result.ToString();
private static XmlDocument GetEmptyDoc()
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
XmlElement element1 = doc.CreateElement(string.Empty, "body", string.Empty);
doc.AppendChild(element1);
XmlElement element2 = doc.CreateElement(string.Empty, "level1", string.Empty);
element1.AppendChild(element2);
XmlElement element3 = doc.CreateElement(string.Empty, "level2", string.Empty);
XmlText text1 = doc.CreateTextNode("text");
element3.AppendChild(text1);
element2.AppendChild(element3);
XmlElement element4 = doc.CreateElement(string.Empty, "level2", string.Empty);
XmlText text2 = doc.CreateTextNode("other text");
element4.AppendChild(text2);
element2.AppendChild(element4);
private readonly DateTime _startTime = DateTime.UtcNow;
public virtual async Task<DateTime> GetTime(CancellationToken cancellationToken = default)
if (time.Second % 10 == 0)
await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
public interface IWebService
Task<string> PostAsync(string functionName, string database, string? vendorId = default, string? propertyId = default, string baseAddress = "https://www.yardipcv.com/8223tp7s7dev/webservices/itfvendorinvoicing.asmx?op=", CancellationToken cancellationToken = default);
Task<string> GetAsync(string functionName, string database, string baseAddress = "https://www.yardipcv.com/8223tp7s7dev/webservices/itfvendorinvoicing.asmx?op=", CancellationToken cancellationToken = default);
Task<DateTime> GetTime(CancellationToken cancellationToken = default);
Task<string> GetRequestXml(string functionName, string database, string? propertyId = default, string? vendorId = default);
private string AppSettings => GetAppSettingsFile();
public string Connection { get; protected set; }
public IDictionary<string, string> Connections { get; protected set; } = new Dictionary<string, string>();
public string UserName { get; set; }
public string UserCode { get; set; }
public string Password { get; set; }
public string ServerName { get; set; }
public string Database { get; set; }
public string Platform { get { return "SQL SERVER"; } }
public string InterfaceEntity { get; set; }
public string LicenseFilePath { get; set; } = @"D:\license\V100105956VP.lic";
public const string APPDBCONTEXT = "AppDbContext";
private string GetAppSettingsFile()
return @"D:\license\appsettings.json";
public DataStore(string database = "AppDbContext")
database = database == "hiid_demo70" ? "AppDbContext" : database;
Connection = GetConnectionString(database);
if (database != "AppDbContext")
UserName = GetField("UserName").Replace(":", "").Trim();
UserCode = GetField("UserCode").Replace(":", "").Trim();
Password = GetField("Password").Replace(":", "").Trim();
ServerName = GetField("ServerName").Replace(":", "").Trim();
Database = GetField("Database").Replace(":", "").Trim();
InterfaceEntity = GetField("InterfaceEntity").Replace(":", "").Trim();
else if (database == "AppDbContext")
var connArray = Connection.Split(";");
UserName = connArray[1].Replace("User ID=", "");
UserCode = connArray[1].Replace("User ID=", "");
Password = connArray[2].Replace("Password=", "");
ServerName = "MESSIDAGOD";
Database = "hiid_demo70";
private string GetConnectionString(string database)
List<string> list = new();
string connection = string.Empty;
string jsonString = File.ReadAllText(GetAppSettingsFile());
string pattern = $@"(\""{database}\"":)[\s]";
RegexOptions options = RegexOptions.Singleline | RegexOptions.Multiline;
foreach (Match m in Regex.Matches(jsonString, pattern, options))
var result = jsonString.Substring(m.Index, jsonString.IndexOf("},") + database.Length + pattern.Length).Split("\r\n")[0].ToString() + "$$";
var final = result.Split("$$").First().Replace(",", "").Replace(database, "").Replace(":", "").Replace("\"", "").Trim();
if (Environment.MachineName == "MESSIDAGOD")
final = final.Replace("DESKTOP-CMLV9G9", "MESSIDAGOD");
private string GetField(string value)
string connection = string.Empty;
foreach (var thisLine in File.ReadLines(AppSettings))
if (thisLine.Contains(value))
outputValue = thisLine.Replace(value, "").Trim().Replace(nameof(value), "").Replace("\"", "").Replace("\\\\", "\\");
if (outputValue[outputValue.Length - 1] == (char)44)
connection = outputValue[0..^1];
connection = outputValue;
public class MultipleRowsFoundException : ApplicationException
public MultipleRowsFoundException()
: base("Multiple rows found.")
public MultipleRowsFoundException(string Message)
public MultipleRowsFoundException(string Message, Exception Inner)
public class TransactionRollbackException : ApplicationException
public TransactionRollbackException()
: base("A Transaction Rollback has been executed. Your changes have not been posted.")
public TransactionRollbackException(string Message)
public TransactionRollbackException(string Message, Exception Inner)
public class DuplicateCodeException : ApplicationException
public DuplicateCodeException()
: base("Code duplicates one already in use.")
public class StoredProcedureNoRowException : ApplicationException
public StoredProcedureNoRowException(string Message)
public class StoredProcedureExecutionException : ApplicationException
public StoredProcedureExecutionException(string Message, Exception Inner)
public StoredProcedureExecutionException(string Message)
public object ToSQL(object Value)
if (Value == null || (object)Value.GetType() == typeof(DBNull))
string name = Value.GetType().Name;
if (Operators.CompareString(name, typeof(bool).Name, TextCompare: false) == 0)
return ToBoolean(Convert.ToBoolean(RuntimeHelpers.GetObjectValue(Value)));
if (Operators.CompareString(name, typeof(DateTime).Name, TextCompare: false) == 0)
return ToSQLDate(Convert.ToDateTime(RuntimeHelpers.GetObjectValue(Value)));
if (Operators.CompareString(name, typeof(DateTime).Name, TextCompare: false) == 0)
return ToSQLDate(Convert.ToDateTime(RuntimeHelpers.GetObjectValue(Value)));
if (Operators.CompareString(name, typeof(string).Name, TextCompare: false) == 0)
if (Operators.CompareString(Convert.ToString(RuntimeHelpers.GetObjectValue(Value)).ToUpper().Trim(), "NULL", TextCompare: false) == 0)
return ToSQLString(Convert.ToString(RuntimeHelpers.GetObjectValue(Value)));
if (Operators.CompareString(name, typeof(short).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(int).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(long).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(double).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(float).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(int).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(short).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(long).Name, TextCompare: false) == 0 || Operators.CompareString(name, typeof(decimal).Name, TextCompare: false) == 0)
if (Value.GetType().IsEnum)
return Convert.ToInt32(RuntimeHelpers.GetObjectValue(Value));
throw new ApplicationException($"Invalid type in DataUtil.toSQL : {Value.GetType().Name}");
public static string AddVersionToFileName(string fullpath)
string version = $"{suffix}{i}";
string newFieFull = Path.Combine(Path.GetDirectoryName(fullpath), Path.GetFileNameWithoutExtension(fullpath)) + version + Path.GetExtension(fullpath);
if (!File.Exists(newFieFull))
public static int ToBoolean(bool Value)
public string ToSQLString(string Input)
return string.Format("N'{0}'", Input.Replace("'", "''"));
public string ToSQLString(string[] Input)
int upperBound = Input.GetUpperBound(0);
for (int i = 0; i <= upperBound; i++)
Value = Value + ToSQLString(Input[i]) + ",";
return string.Concat(Value.AsSpan(0, Value.Length - 1), ")");
public string ToSQLDate(DateTime myDate)
if (myDate.ToOADate() == 0.0)
catch (OverflowException ex2)
ProjectData.SetProjectError(ex2);
OverflowException ex = ex2;
throw new ApplicationException($"Invalid date : {myDate}.", ex);
if (myDate.TimeOfDay.Ticks > 0)
return ToSQLDateTime(myDate);
return string.Format("convert(datetime, '{0}', 101)", Strings.Format(myDate, "MM/dd/yyyy"));
public string ToSQLDateTime(DateTime myDate)
if (myDate.ToOADate() == 0.0)
myDate = new DateTime(1899, 1, 1, myDate.Hour, myDate.Minute, myDate.Second);
return string.Format("convert(datetime, '{0}', 101)", Strings.Format(myDate, "MM/dd/yyyy hh:mm:sstt"));
public bool IsNullDate(DateTime Value)
if (DateTime.Compare(Value, DateTime.MinValue) == 0)
if (Value.Equals(DateTime.MinValue))
if (DateTime.Compare(Value, default(DateTime)) == 0)
public static void Log(dynamic message, ConsoleColor color = ConsoleColor.Cyan)
Console.ForegroundColor = color;