Base.Net classes & Accounts module added

This commit is contained in:
2021-05-05 18:47:31 +01:00
parent ca7ab3e64a
commit 9940fabdc1
21 changed files with 13472 additions and 0 deletions
+2
View File
@@ -8,6 +8,8 @@
* Base class library. .Net Standard 2.1. C#.
* SACS Standard Dbas
* Base database interface library. .Net Standard 2.1. C#.
* SACS Standard Accounts
* Base Acounts system interface library. .Net Standard 2.1. C#.
* SACS Standard Mob
* Base Mobile application library. .Net Standard 2.1. C#.
* SACS Core Web
+6
View File
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution files", "Solution
ReadMe.md = ReadMe.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SacsStandardAccounts", "SacsStandardAccounts\SacsStandardAccounts.csproj", "{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -44,6 +46,10 @@ Global
{70F1302F-E8F2-49CB-A09D-889DA59681DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70F1302F-E8F2-49CB-A09D-889DA59681DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70F1302F-E8F2-49CB-A09D-889DA59681DD}.Release|Any CPU.Build.0 = Release|Any CPU
{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -16,8 +16,10 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SacsStandardAccounts\SacsStandardAccounts.csproj" />
<ProjectReference Include="..\SacsStandardBase\SacsStandardBase.csproj" />
<ProjectReference Include="..\SacsStandardDbas\SacsStandardDbas.csproj" />
<ProjectReference Include="..\SacsStandardMob\SacsStandardMob.csproj" />
</ItemGroup>
<ItemGroup>
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.OpenAuth
{
//=======================================================================
internal class SaOpenAuth
{
}
//=======================================================================
}
@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.QuickBooks.App
{
//=======================================================================
public static class Qbk
{
//-------------------------------------------------------------------
// QuickBooks version.
public enum Version
{
Unknown = 0,
Local2008 = 2008
};
//-------------------------------------------------------------------
public enum ConnectionType
{
Unknown = 0,
/// <summary>Local QuickBooks</summary>
LocalQBD = 1,
/// <summary>RDS connection</summary>
RemoteQBD = 2,
/// <summary>SDK application launched QuickBooks in interactive mode</summary>
LocalQBDLaunchUI = 3,
/// <summary>Online edition</summary>
RemoteQBOE = 4,
};
//-------------------------------------------------------------------
// Jul2016 Online configuration.
public enum OnlineInstance
{
Unknown = 0,
Sandbox = 10,
Production = 20,
};
public enum OnlineProduct
{
Unknown = 0,
Accounts,
Payments,
};
//-------------------------------------------------------------------
// QBooks Online.
public enum OnlineRequestType
{
Unknown = 0,
Query,
CompanyInfo,
Vendor,
Customer,
Item,
Invoice,
};
//-------------------------------------------------------------------
// QBooks reference types.
public enum ReferenceDataType
{
Unknown = 0,
CustomerType = 10,
ShipMethod,
};
//-------------------------------------------------------------------
// QBooks item types.
public enum EntityType
{
Unknown = 0,
// Reference data types.
CustomerType = 100,
// Primary data types.
Company = 200,
Account,
Vendor,
Customer,
Item,
PurchaseOrder,
SalesOrder,
Invoice_Product,
Invoice_Service,
// Internal.
Invoice_Header,
Invoice_Line,
};
//-------------------------------------------------------------------
// Financial year.
public enum FinancialYear
{
Current,
Prior1,
Prior2,
Prior3,
Prior4,
Prior5
};
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,97 @@
using Sarand.Net.Standard.Accounts.QuickBooks.Base;
using Sarand.Net.Standard.Accounts.QuickBooks.Local;
using Sarand.Net.Standard.Accounts.QuickBooks.Online;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.IO;
using System;
using System.Collections.Generic;
using System.Text;
using Sarand.Net.Standard.Base.Utils;
namespace Sarand.Net.Standard.Accounts.QuickBooks.App
{
//=======================================================================
public class SaQuickBooksConsole : SaErrorStateItem
{
//-------------------------------------------------------------------
// Data members.
private static readonly List<TypeCodeDesc> qbkEntityTypes = new List<TypeCodeDesc>();
//-------------------------------------------------------------------
// Static initialisation.
static SaQuickBooksConsole ()
{
// QuickBooks data types:
qbkEntityTypes.Add(Qbk.EntityType.Account, "ACCNT", "Account");
qbkEntityTypes.Add(Qbk.EntityType.Vendor, "VEND", "Vendor");
qbkEntityTypes.Add(Qbk.EntityType.Customer, "CUST", "Customer");
qbkEntityTypes.Add(Qbk.EntityType.Item, "ITEM", "Item");
qbkEntityTypes.Add(Qbk.EntityType.PurchaseOrder, "PURO", "Purchase order");
qbkEntityTypes.Add(Qbk.EntityType.SalesOrder, "SALO", "Sales order");
qbkEntityTypes.Add(Qbk.EntityType.Invoice_Product, "INVPRD", "Product invoice");
qbkEntityTypes.Add(Qbk.EntityType.Invoice_Service, "INVSRV", "Service invoice");
}
//-------------------------------------------------------------------
// Construction.
protected SaQuickBooksConsole ()
{
}
public static SaQuickBooksConsole CreateConsole ()
{
return new SaQuickBooksConsole();
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
public static List<TypeCodeDesc> EntityTypeCodes { get { return new List<TypeCodeDesc>(qbkEntityTypes); } }
//-------------------------------------------------------------------
// QuickBooks API.
public SaQuickBooksApiConsole CreateApiConsole (SaQuickBooksParams prmQbk)
{
ClearErrorState();
if (prmQbk.ConnectionType == Qbk.ConnectionType.LocalQBD)
{
if (!HasErrorState() && StringUtil.IsEmpty(prmQbk.CompanyFilePath)) SetErrorState("QuickBooks company file must be specified.");
if (!HasErrorState() && !FileUtil.IsFile(prmQbk.CompanyFilePath)) SetErrorState("QuickBooks company file does not exist.");
if (!HasErrorState())
return new SaQuickBooksApiConsole_Local(prmQbk);
}
else if (prmQbk.ConnectionType == Qbk.ConnectionType.RemoteQBOE)
{
if (!HasErrorState() && (int)prmQbk.OnlineInstance < 1) SetErrorState("QuickBooks instance must be specified.");
//if (!HasErrorState() && StringUtil.IsEmpty(prmQbk.CompanyId)) SetErrorState("QuickBooks company Id must be specified.");
if (!HasErrorState())
return new SaQuickBooksApiConsole_Online(prmQbk);
}
else
{
String sMsg = "Unsupported connection type: "+prmQbk.ConnectionType.ToString();
SetErrorState(sMsg);
if (SacsSystem.DebugMode)
SaLogger.Debug(GetType().Name + ".CreateApiConsole " + sMsg);
}
return null;
}
//-------------------------------------------------------------------
// QuickBooks API.
public bool TestInterface (SaQuickBooksParams prmQbk)
{
return false;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.QuickBooks.App
{
//=======================================================================
public class SaQuickBooksParams
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public SaQuickBooksParams ()
{
}
//-------------------------------------------------------------------
// Properties.
/// <summary>LocalQBD, RemoteQBD etc.</summary>
public Qbk.ConnectionType ConnectionType { get; set; } = Qbk.ConnectionType.Unknown;
public String AppId { get; set; } = "";
public String AppName { get; set; } = "";
public String CompanyFilePath { get; set; } = "";
public String Username { get; set; } = "";
public String Password { get; set; } = "";
/// <summary>QBFileMode: qbFileOpenSingleUser, qbFileOpen, qbFileOpenDoNotCare</summary>
public int OpenFileMode { get; set; } = 0;
// Jul2016 Online configuration.
public Qbk.OnlineInstance OnlineInstance { get; set; } = Qbk.OnlineInstance.Unknown;
public DateTime OnlineAuthorisedOn { get; set; } = DateTime.MinValue;
public String CompanyId { get; set; } = "";
public String AppToken { get; set; } = "";
public String AppTokenSecret { get; set; } = "";
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,50 @@
using Sarand.Net.Standard.Accounts.QuickBooks.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.QuickBooks.Base
{
//=======================================================================
public abstract class SaQuickBooksApiConsole : SaErrorStateItem
{
//-------------------------------------------------------------------
// Data members.
private readonly SaQuickBooksParams prmQbk;
//-------------------------------------------------------------------
// Static initialisation.
static SaQuickBooksApiConsole ()
{
}
//-------------------------------------------------------------------
// Construction.
protected SaQuickBooksApiConsole (SaQuickBooksParams prmQbk)
{
this.prmQbk = prmQbk;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// D a t a I t e m s
//-------------------------------------------------------------------
public abstract SaQuickBooksDataItem CreateDataItem (Qbk.EntityType entityType);
/// <summary>Create data item iterator (to retrieve list of data items of specific type).</summary>
public abstract SaQuickBooksDataItem.Iterator CreateItemIterator (Qbk.EntityType entityType);
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,199 @@
using Sarand.Net.Standard.Accounts.QuickBooks.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.QuickBooks.Base
{
//=======================================================================
public class SaQuickBooksDataItem : SacsDisposable
{
//-------------------------------------------------------------------
// Data members.
private readonly NamedValue.Map values = new NamedValue.Map();
//-------------------------------------------------------------------
// Static initialisation.
static SaQuickBooksDataItem ()
{
}
//-------------------------------------------------------------------
// Construction.
protected SaQuickBooksDataItem (Qbk.EntityType entityType)
{
EntityType = entityType;
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
}
//-------------------------------------------------------------------
// Properties.
public Qbk.EntityType EntityType { get; }
//-------------------------------------------------------------------
// Field values.
public bool HasValue (String name)
{
return values.HasValue(name);
}
public DataValue.DataType GetValueType (String name)
{
DataValue value = GetValue(name);
return value?.GetDataType() ?? DataValue.DataType.Unknown;
}
public DataValue GetValue (String name)
{
return values.GetValue(name);
}
public NamedValue.Map GetValues ()
{
return new NamedValue.Map(values.Values);
}
//-------------------------------------------------------------------
// Update attributes.
public bool SetValue (String name, DataValue value)
{
return values.AddValue(name, value);
}
public bool SetValue (String name, String value)
{
return SetValue(name, new DataValue(value));
}
public bool SetValue (String name, bool value)
{
return SetValue(name, new DataValue(value));
}
public bool SetValue (String name, long value)
{
return SetValue(name, new DataValue(value));
}
public bool SetValue (String name, double value)
{
return SetValue(name, new DataValue(value));
}
//-------------------------------------------------------------------
// P a r a m e t e r s
//-------------------------------------------------------------------
/// <summary>Data item parameters.</summary>
public class Params
{
/// <summary>Online: EntityId.</summary>
public String EntityListId { get; set; } = "";
/// <summary>Item identifier (ListId etc, partial = 'starts with').</summary>
public String ItemId { get; set; } = "";
/// <summary>Item identifier (ListId etc, partial = 'starts with').</summary>
public String ItemIdPartial { get; set; } = "";
public String EntityCode { get; set; } = "";
/// <summary>Item name or description (partial = 'starts with').</summary>
public String EntityName { get; set; } = "";
/// <summary>Item name or description (partial = 'starts with').</summary>
public String EntityNamePartial { get; set; } = "";
/// <summary>FOB (invoice) filter.</summary>
public String Fob { get; set; } = "";
/// <summary>Avoid processing older items (orders etc.).</summary>
public DateTime EarliestDate { get; set; } = DateTime.MinValue;
public int MaxItems { get; set; } = 0;
}
//-------------------------------------------------------------------
// I t e r a t o r
//-------------------------------------------------------------------
public abstract class Iterator : SaErrorStateItem
{
//---------------------------------------------------------------
// Data members.
private SaQuickBooksDataItem.Params prmQbk;
private int itemCount = 0;
//---------------------------------------------------------------
// Construction.
protected Iterator (Qbk.EntityType entityType)
{
EntityType = entityType;
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//---------------------------------------------------------------
// Properties.
public Qbk.EntityType EntityType { get; }
public SaQuickBooksDataItem.Params Params { get { return prmQbk; } }
public static int PageLengthDefault { get; } = 20;
public int ItemsFound { get; protected set; }
public bool AtStart { get; protected set; }
//---------------------------------------------------------------
// Data items.
/// <summary>Total number of items (do this after GotoStart).</summary>
public virtual int GetItemCount ()
{
ClearErrorState();
if (itemCount < 0 && AtStart)
{
// Retrieve and discard the first item in the list.
SaQuickBooksDataItem item = GetNextItem();
if (item != null) item.Dispose();
// Reset to start of list.
ItemsFound = 0;
}
return 0;
}
/// <summary>Reset the item iteration.</summary>
public virtual void GotoStart (SaQuickBooksDataItem.Params prmQbk)
{
ClearErrorState();
this.prmQbk = prmQbk;
AtStart = true;
ItemsFound = 0;
}
public abstract SaQuickBooksDataItem GetNextItem ();
/// <summary>Retrieve specific item (exception if more than one found).</summary>
public SaQuickBooksDataItem GetItem (SaQuickBooksDataItem.Params prmQbk)
{
ClearErrorState();
Iterator iterator = Clone();
iterator.GotoStart(prmQbk);
SaQuickBooksDataItem item1 = iterator.GetNextItem();
SaQuickBooksDataItem item2 = iterator.GetNextItem();
if (item2 != null)
{
// Only 1 item expected.
if (item1 != null) item1.Dispose(); item1 = null;
if (item2 != null) item2.Dispose(); item2 = null;
SetErrorState("Multiple items found");
}
return item1;
}
/// <summary>List of matching items (use where volume is limited).</summary>
public List<SaQuickBooksDataItem> GetItems (SaQuickBooksDataItem.Params prmQbk)
{
ClearErrorState();
List<SaQuickBooksDataItem> items = new List<SaQuickBooksDataItem>();
Iterator iterator = Clone();
iterator.GotoStart(prmQbk);
SaQuickBooksDataItem item = null;
while ((item = iterator.GetNextItem()) != null)
items.Add(item);
return items;
}
//---------------------------------------------------------------
// Utilities.
protected abstract Iterator Clone ();
//---------------------------------------------------------------
}
//-------------------------------------------------------------------
}
//=======================================================================
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
using Sarand.Net.Standard.Accounts.QuickBooks.App;
using Sarand.Net.Standard.Accounts.QuickBooks.Base;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.QuickBooks.Internal
{
//=======================================================================
public abstract class SaQuickBooksDataItem_Internal : SaQuickBooksDataItem
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
protected SaQuickBooksDataItem_Internal (Qbk.EntityType entityType) : base(entityType)
{
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// I t e r a t o r
//-------------------------------------------------------------------
public new abstract class Iterator : SaQuickBooksDataItem.Iterator
{
//---------------------------------------------------------------
// Data members.
//---------------------------------------------------------------
// Construction.
protected Iterator (Qbk.EntityType entityType) : base(entityType)
{
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//---------------------------------------------------------------
// Properties.
//---------------------------------------------------------------
// Database.
protected String GetPrimaryTableName ()
{
// ToDo return dfnDb.GetTableName(GetPrimaryTable());
return "";
}
/*
protected eQBooksDbTable GetPrimaryTable (Qbk.EntityType entityType)
{
switch (entityType)
{
// Contacts:
case Qbk.EntityType.Vendor: return eQBooksDbTblVendor;
case Qbk.EntityType.Customer: return eQBooksDbTblCustomer;
case Qbk.EntityType.Item: return eQBooksDbTblItem;
}
return eQBooksDbTblUnknown;
}
*/
//---------------------------------------------------------------
// Utilities.
//---------------------------------------------------------------
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,54 @@
using Sarand.Net.Standard.Accounts.QuickBooks.App;
using Sarand.Net.Standard.Accounts.QuickBooks.Base;
using Sarand.Net.Standard.Base.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.QuickBooks.Local
{
//=======================================================================
internal class SaQuickBooksApiConsole_Local : SaQuickBooksApiConsole
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Static initialisation.
static SaQuickBooksApiConsole_Local ()
{
}
//-------------------------------------------------------------------
// Construction.
internal SaQuickBooksApiConsole_Local (SaQuickBooksParams prmQbk) :base(prmQbk)
{
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// D a t a I t e m s
//-------------------------------------------------------------------
public override SaQuickBooksDataItem CreateDataItem (Qbk.EntityType entityType)
{
return null;
}
/// <summary>Create data item iterator (to retrieve list of data items of specific type).</summary>
public override SaQuickBooksDataItem.Iterator CreateItemIterator (Qbk.EntityType entityType)
{
return null;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,135 @@
using Sarand.Net.Standard.Accounts.QuickBooks.App;
using Sarand.Net.Standard.Accounts.QuickBooks.Base;
using Sarand.Net.Standard.Base.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.QuickBooks.Online
{
//=======================================================================
internal class SaQuickBooksApiConsole_Online : SaQuickBooksApiConsole
{
//-------------------------------------------------------------------
// D e f i n i t i o n s
//-------------------------------------------------------------------
// Keys.
// Sarand Sandbox company:
// CompanyId 193514292338962
// AppToken lvprdXEkhkqdCXgTfYJxhwFj1CdB3fXIeTs5eGx8TE8U7qGy
// AppTokenSecret U8IgODOQa4Rl9KEMbQhgimoQi5nbgLi4XlQU4xiB
// BPE Live Company
// CompanyId 193514324299222
// AppToken qyprdb7VvoOivRV7mARrb5I0VVT1caG0f1c0AVVgbhxt36bv
// AppTokenSecret boGLa6B5RwayoYs1KlDEGk64Rjl0UUsF6By7rvBR
private static String kpcAppToken_Dev = "0c7f73fdb65efb4033b8a12b61fb01aa3ce9";
private static String kpcConsumerKey_Dev = "lvprd9HvNstK5yTszldscZ2PBgNGMu";
private static String kpcConsumerSecret_Dev = "F6IQwnEhJqpoOdTmfXBgt1iq6SDWJ40clxl1xvQR";
private static String kpcAppToken_Prod = "c0d15b4fbcad2b4cfcb96f9bcdbd2bf7b03d";
private static String kpcConsumerKey_Prod = "lvprdwLCQdAhuiLtueFpZ7LVG4R6Ir";
private static String kpcConsumerSecret_Prod = "9j1RBTaHbpTZEA0yUlDINYoAhX8Mt6PfOdAl2YIz";
// Online API.
// Intuit Developer: https://developer.intuit.com/
private static String kpcServer_QBD_Prod = "quickbooks.api.intuit.com"; // QuickBooks Desktop Rest Service - production.
private static String kpcServer_QBO_Prod = "quickbooks.api.intuit.com"; // QuickBooks Online Rest Service - production.
private static String kpcServer_QBO_Sand = "sandbox-quickbooks.api.intuit.com"; // QuickBooks Online Rest Service - sandbox.
private static String kpcServer_IPP_Prod = "appcenter.intuit.com"; // Platform Rest Service - production.
private static String kpcBaseUrl_QBD = "https://quickbooks.api.intuit.com/"; // QuickBooks Desktop Rest Service.
private static String kpcBaseUrl_QBO = "https://quickbooks.api.intuit.com/"; // QuickBooks Online Rest Service.
private static String kpcBaseUrl_IPP = "https://appcenter.intuit.com/api/"; // Platform Rest Service.
private static String kpcUrlAccounting_Production = "https://quickbooks.api.intuit.com/"; // Accounting API base URL to use with production keys.
private static String kpcUrlAccounting_Sandbox = "https://sandbox-quickbooks.api.intuit.com/"; // Accounting API—Sandbox base URL to use with development keys.
private static String kpcUrlPayments_Production = "https://api.intuit.com/"; // Payments API base URL to use with production keys.
private static String kpcUrlPayments_Sandbox = "https://sandbox.api.intuit.com/"; // Payments API—Sandbox base URL to use with development keys.
// Core constants.
private static String kpcSlash = "/"; // Slash character.
private static String kpcVersion = "v3"; // Intuit Services Version.
private static String kpcResource = "resource";
private static String kpcUrlVersionCompany = "v3/company/";
// Content types.
private static String kpcContentType_TextAny = "text/*";
private static String kpcContentType_TextHtml = "text/html";
private static String kpcContentType_TextXml = "text/xml";
private static String kpcContentType_TextPlain = "text/plain";
private static String kpcContentType_ApplicationText = "application/text";
private static String kpcContentType_ApplicationXml = "application/xml";
private static String kpcContentType_ApplicationJson = "application/json";
private static String kpcContentType_UrlFormEncoded = "application/x-www-form-urlencoded";
private static String kpcContentType_OctetStream = "application/octet-stream";
private static String kpcContentType_ApplicationPdf = "application/pdf";
// Parameter names.
private static String kpcParam_Id = "Id";
private static String kpcParam_SyncToken = "SyncToken";
private static String kpcParam_Domain = "domain";
private static String kpcParam_MetaData = "MetaData";
private static String kpcParam_Sparse = "sparse";
private static String kpcParam_Status = "status";
private static String kpcParam_IdDomainQuery = "?idDomain=";
private static String kpcAUTHORIZATIONSTRING_FORHEADER = "Authorization"; // Authorization String For Header.
private static String kpcREQUESTFILENAME_FORMAT = "{0}{1}Request-{2}.txt"; // Request File Name Format.
private static String kpcRESPONSEFILENAME_FORMAT = "{0}{1}Response-{2}.txt"; // Response File Name Format.
private static String kpcERRORRESPONSEFILENAME_FORMAT = "{0}{1}Error-Response-{2}.txt"; // Error Response File Name Format.
private static String kpcCONTENTENCODING = "Content-Encoding"; // The Compression format of the request data.
private static String kpcACCEPTENCODING = "Accept-Encoding"; // The Compression format of the response data.
private static String kpcUSERAGENT = "V3PHPSDK2.4.1"; // The Request source header value.
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Static initialisation.
static SaQuickBooksApiConsole_Online ()
{
}
//-------------------------------------------------------------------
// Construction.
internal SaQuickBooksApiConsole_Online (SaQuickBooksParams prmQbk) : base(prmQbk)
{
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// D a t a I t e m s
//-------------------------------------------------------------------
public override SaQuickBooksDataItem CreateDataItem (Qbk.EntityType entityType)
{
return new SaQuickBooksDataItem_Online(entityType);
}
/// <summary>Create data item iterator (to retrieve list of data items of specific type).</summary>
public override SaQuickBooksDataItem.Iterator CreateItemIterator (Qbk.EntityType entityType)
{
return new SaQuickBooksDataItem_Online.Iterator(this, entityType);
}
//---------------------------------------------------------------
// Online Authorisation.
public SaQuickBooksRequest_Online.AuthorisationData DoQBooksOnlineAuthorisation ()
{
SaQuickBooksRequest_Online.AuthorisationData authData = new SaQuickBooksRequest_Online.AuthorisationData();
return authData;
}
//---------------------------------------------------------------
// QBO interface.
public bool DoQBooksRequest (SaQuickBooksRequest_Online qboRequest)
{
ClearErrorState();
return !HasErrorState();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,510 @@
using Sarand.Net.Standard.Accounts.QuickBooks.App;
using Sarand.Net.Standard.Accounts.QuickBooks.Base;
using Sarand.Net.Standard.Accounts.QuickBooks.Dbas;
using Sarand.Net.Standard.Accounts.QuickBooks.Internal;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Xml;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
using Sarand.Net.Standard.Base.Utils;
namespace Sarand.Net.Standard.Accounts.QuickBooks.Online
{
//=======================================================================
public class SaQuickBooksDataItem_Online : SaQuickBooksDataItem_Internal
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Static initialisation.
static SaQuickBooksDataItem_Online ()
{
}
//-------------------------------------------------------------------
// Construction.
public SaQuickBooksDataItem_Online (Qbk.EntityType entityType) : base(entityType)
{
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// I t e r a t o r
//-------------------------------------------------------------------
public new class Iterator : SaQuickBooksDataItem_Internal.Iterator
{
//---------------------------------------------------------------
// Data members.
SaQuickBooksApiConsole_Online qbkConsole;
internal class NextItemData
{
public int EntityCount { get; set; } = -1;
public int PageLength { get; set; } = PageLengthDefault;
public int PageNumber { get; set; } = 1;
public XDocument QueryResponseDoc { get; set; }
public XElement QueryResponseNode { get; set; }
public XElement EntityNode { get; set; }
}
private readonly NextItemData nextItem = new NextItemData ();
//---------------------------------------------------------------
// Construction.
internal Iterator (SaQuickBooksApiConsole_Online qbkConsole, Qbk.EntityType entityType) : base(entityType)
{
this.qbkConsole = qbkConsole;
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
qbkConsole = null;
}
base.Dispose(disposing);
}
//---------------------------------------------------------------
// Properties.
//---------------------------------------------------------------
// Utilities.
protected override SaQuickBooksDataItem.Iterator Clone ()
{
return new Iterator(qbkConsole, EntityType);
}
public String GetWhereClause ()
{
List<String> whereClauses = new List<string>();
SaQuickBooksDataItem_Internal.Params prm = Params;
if (EntityType == Qbk.EntityType.Vendor)
{
if (!StringUtil.IsEmpty(prm.EntityListId))
whereClauses.Add("Id='" + prm.EntityListId + "'");
}
else if (EntityType == Qbk.EntityType.Customer)
{
if (!StringUtil.IsEmpty(prm.EntityListId))
whereClauses.Add("Id='" + prm.EntityListId + "'");
}
else if (EntityType == Qbk.EntityType.Item)
{
if (!StringUtil.IsEmpty(prm.EntityListId))
whereClauses.Add("Id='" + prm.EntityListId + "'");
if (!StringUtil.IsEmpty(prm.EntityCode))
whereClauses.Add("Sku='" + prm.EntityCode + "'");
}
return (!whereClauses.IsEmpty() ? " Where " : "") + whereClauses.Concat(" And ");
}
String GetOrderByClause ()
{
String orderBy = "";
return (!orderBy.IsEmpty() ? " OrderBy " : "") + orderBy;
}
bool IsPaginationCompleted (bool incrementPageNumber)
{
if (incrementPageNumber)
nextItem.PageNumber++;
// Last page of data?
GetItemCount(); // Force count.
return (nextItem.PageNumber - 1) * nextItem.PageLength >= nextItem.EntityCount;
}
String GetPaginationClause ()
{
String sPagination = "";
if (nextItem.EntityCount > nextItem.PageLength)
{
sPagination = " StartPosition " + (((nextItem.PageNumber - 1) * nextItem.PageLength) + 1).ToString() + " MaxResults " + (nextItem.PageLength).ToString();
}
return sPagination;
}
//---------------------------------------------------------------
// Data items.
/// <summary>Total number of items (do this after GotoStart).</summary>
public override int GetItemCount ()
{
ClearErrorState();
if (nextItem.EntityCount < 0)
{
SaQuickBooksDataItem_Internal.Params prm = Params;
SaQuickBooksRequest_Online qboRequest = new SaQuickBooksRequest_Online();
bool validRequest = false;
if (EntityType == Qbk.EntityType.Vendor)
{
qboRequest.RequestType = Qbk.OnlineRequestType.Query;
qboRequest.DataQuery = "Select Count(*) From Vendor" + GetWhereClause();
validRequest = true;
}
else if (EntityType == Qbk.EntityType.Customer)
{
qboRequest.RequestType = Qbk.OnlineRequestType.Query;
qboRequest.DataQuery = "Select Count(*) From Customer" + GetWhereClause();
validRequest = true;
}
else if (EntityType == Qbk.EntityType.Item)
{
qboRequest.RequestType = Qbk.OnlineRequestType.Query;
qboRequest.DataQuery = "Select Count(*) From Item" + GetWhereClause();
validRequest = true;
}
if (validRequest)
{
// <IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2016-11-12T06:53:41.666-08:00">
// <QueryResponse totalCount="29" />
// </IntuitResponse>
if (qbkConsole.DoQBooksRequest(qboRequest))
{
// Retrieve company info.
XElement nodeRoot = qboRequest.ResponseDoc.Root;
XElement nodeQueryResponse = nodeRoot.GetFirstChildElement("QueryResponse");
nextItem.EntityCount = StringUtil.ToInt(nodeQueryResponse.GetAttributeValue("totalCount"));
}
}
}
return nextItem.EntityCount;
}
public override void GotoStart (SaQuickBooksDataItem_Internal.Params prmQbk)
{
base.GotoStart(prmQbk);
// Reset next item.
nextItem.EntityNode = null;
nextItem.QueryResponseNode = null;
nextItem.QueryResponseDoc = null;
nextItem.EntityCount = -1;
nextItem.PageLength = PageLengthDefault;
nextItem.PageNumber = 1;
}
//---------------------------------------------------------------
// N e x t I t e m
//---------------------------------------------------------------
// QuickBooks reference.
// Case
// In the query language, reserved words, entity names, and property names
// are case insensitive. However, property values are case sensitive.
// Maximum number of entities in a response
// The maximum number of entities that can be returned in a response is 1000.
// If the result size is not specified, the default number is 100.
// If a query returns many entities, fetch the entities in chunks, as described in Pagination.
// To determine the number of entities that a particular query returns,
// probe by using the COUNT keyword in the query. See Count for details.
// Escape Character
// Use backslash (\) to escape special characters like apostrophe (').
// For example, to find a Cuatomer object whose company name is "Adam's Candy Shop", submit the following query:
// SELECT * FROM Customer WHERE CompanyName= ‘Adam\’s Candy Shop’
// Filters
// The filter in the WHERE clause determines which entities are returned by a query.
// The filter criteria is based on the value of a property.
// Multiple filters are AND'd together. The OR operation is not supported.
// For example:
// SELECT * FROM Customer WHERE Active IN (true, false)
// SELECT * FROM Customer WHERE active = true
// SELECT * FROM Customer WHERE GivenName LIKE 'K%h' AND FamilyName LIKE 'Palm%'
// SELECT * FROM Invoice WHERE CustomerRef = '123'
// SELECT * FROM Invoice WHERE CustomerId IN ('12')
// SELECT * FROM Invoice WHERE TotalAmt > '1000.0'
// SELECT * FROM Invoice WHERE TxnDate > '2011-01-01' AND TxnDate <= CURRENT_DATE
// Sorting
// To sort the results of a query, include the ORDERBY clause, specifying a property as the sort field.
// Note that not all properties can be used for sorting.
// To see which properties can be sorted on, go to the entity's reference page and check the Sort Support column of the Properties table.
// The default sort order is ascending. To indicate descending sort order, include DESC.
// For example:
// SELECT * FROM Customer ORDERBY FamilyName
// SELECT * FROM Customer ORDERBY FamilyName DESC
// Pagination
// To page through the results, specify STARTPOSITION (position of the entity in the query results) and MAXRESULTS (maximum number of entities in the result).
// For example, suppose you have 25 invoices. The following queries each get 10 invoices per page:
// SELECT * FROM Invoice STARTPOSITION 1 MAXRESULTS 10
// SELECT * FROM Invoice STARTPOSITION 11 MAXRESULTS 10
// SELECT * FROM Invoice STARTPOSITION 21 MAXRESULTS 10
// Count
// To find out how many entites will be returned by a query, specify the COUNT keyword.
// The number of entities is returned in the totalCount attribute of the <QueryResponse> element.
// The QuickBooks Online data objects, such as Customer, are not in the response.
// SELECT COUNT(*)FROM Customer
//---------------------------------------------------------------
public override SaQuickBooksDataItem GetNextItem ()
{
SaQuickBooksDataItem_Internal.Params prm = Params;
if (AtStart || (nextItem.EntityNode == null && !IsPaginationCompleted(true)))
{
// Construct request.
SaQuickBooksRequest_Online qboRequest = new SaQuickBooksRequest_Online(Qbk.OnlineRequestType.Query);
bool validRequest = false;
if (EntityType == Qbk.EntityType.Vendor)
{
qboRequest.DataQuery = "Select * From Vendor" + GetWhereClause() + GetOrderByClause() + GetPaginationClause();
validRequest = true;
}
else if (EntityType == Qbk.EntityType.Customer)
{
qboRequest.DataQuery = "Select * From Customer" + GetWhereClause() + GetOrderByClause() + GetPaginationClause();
validRequest = true;
}
else if (EntityType == Qbk.EntityType.Item)
{
qboRequest.DataQuery = "Select * From Item" + GetWhereClause() + GetOrderByClause() + GetPaginationClause();
validRequest = true;
}
if (validRequest)
{
// <IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2016-11-12T06:53:41.666-08:00">
// <QueryResponse totalCount="29" />
// </IntuitResponse>
if (qbkConsole.DoQBooksRequest(qboRequest))
{
nextItem.QueryResponseDoc = qboRequest.ResponseDoc;
XElement nodeRoot = nextItem.QueryResponseDoc.Root;
nextItem.QueryResponseNode = nodeRoot.GetFirstChildElement("QueryResponse");
nextItem.EntityNode = nextItem.QueryResponseNode.GetFirstChildElement(GetPrimaryTableName());
}
}
AtStart = false;
}
// Retrieve info for next company.
SaQuickBooksDataItem_Online item = null;
if (nextItem.EntityNode != null)
{
if (EntityType == Qbk.EntityType.Vendor)
{
item = GetVendorFrom(nextItem.EntityNode);
}
else if (EntityType == Qbk.EntityType.Customer)
{
item = GetCustomerFrom(nextItem.EntityNode);
}
else if (EntityType == Qbk.EntityType.Item)
{
item = GetItemFrom(nextItem.EntityNode);
}
// Move to next item.
nextItem.EntityNode = nextItem.EntityNode.GetNextSiblingElement(GetPrimaryTableName());
}
if (item == null || nextItem.EntityNode == null)
{
// Clear next item info.
nextItem.EntityNode = null;
nextItem.QueryResponseNode = null;
nextItem.QueryResponseDoc = null;
}
return item;
}
//---------------------------------------------------------------
// E x t r a c t V e n d o r
//---------------------------------------------------------------
SaQuickBooksDataItem_Online GetVendorFrom (XElement nodeVendor)
{
if (nodeVendor == null || !nodeVendor.GetLocalName().EqualsCI("Vendor")) return null;
SaQuickBooksDataItem_Online vendorItem = new SaQuickBooksDataItem_Online(Qbk.EntityType.Vendor);
// Vendor attributes.
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_ListID), nodeVendor.GetChildText("Id"));
// Company name.
String sFullName = nodeVendor.GetChildText("FullName");
String sCompanyName = nodeVendor.GetChildText("CompanyName");
String sDisplayName = nodeVendor.GetChildText("DisplayName");
if (sCompanyName.IsEmpty())
sCompanyName = sDisplayName;
if (!sCompanyName.IsEmpty())
{
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_Name), sCompanyName);
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_CompanyName), sCompanyName);
//pVendor.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_FullName),sCompanyName);
}
if (!sDisplayName.IsEmpty())
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_Name), sDisplayName);
//if (!sFullName.IsEmpty())
// pVendor.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_FullName),sFullName);
// Only populate attributes if present in data.
// Active.
XElement nodeActive = nodeVendor.GetFirstChildElement("Active");
if (nodeActive != null)
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_IsActive), nodeActive.Value.ToBool());
// Balance
XElement nodeBalance = nodeVendor.GetFirstChildElement("Balance");
if (nodeBalance == null)
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_Balance), nodeBalance.Value.ToDouble());
// Credit limit.
XElement nodeCreditLimit = nodeVendor.GetFirstChildElement("CreditLimit");
if (nodeCreditLimit == null)
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_CreditLimit), nodeCreditLimit.Value.ToDouble());
// Phone numbers and email address.
XElement nodePrimaryPhone = nodeVendor.GetFirstChildElement("PrimaryPhone");
if (nodePrimaryPhone == null)
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_Phone), nodePrimaryPhone.GetChildText("FreeFormNumber"));
XElement nodeAlternatePhone = nodeVendor.GetFirstChildElement("AlternatePhone");
if (nodeAlternatePhone == null)
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_AltPhone), nodeAlternatePhone.GetChildText("FreeFormNumber"));
XElement nodePrimaryEmailAddr = nodeVendor.GetFirstChildElement("PrimaryEmailAddr");
if (nodePrimaryEmailAddr == null)
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_Email), nodePrimaryEmailAddr.GetChildText("Address"));
// Vendor address.
XElement nodeVendorAddr = nodeVendor.GetFirstChildElement("VendorAddr");
if (nodeVendorAddr == null)
{
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressAddr1), nodeVendorAddr.GetChildText("Line1"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressAddr2), nodeVendorAddr.GetChildText("Line2"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressAddr3), nodeVendorAddr.GetChildText("Line3"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressAddr4), nodeVendorAddr.GetChildText("Line4"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressAddr5), nodeVendorAddr.GetChildText("Line5"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressCity), nodeVendorAddr.GetChildText("City"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressCounty), nodeVendorAddr.GetChildText("CountrySubDivisionCode"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressPostalCode), nodeVendorAddr.GetChildText("PostalCode"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressCountry), nodeVendorAddr.GetChildText("Country"));
vendorItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Vendor_VendorAddressNote), nodeVendorAddr.GetChildText("Note"));
}
return vendorItem;
}
//===========================================================================
// E x t r a c t C u s t o m e r
//===========================================================================
SaQuickBooksDataItem_Online GetCustomerFrom (XElement nodeCustomer)
{
if (nodeCustomer == null || !nodeCustomer.GetLocalName().EqualsCI("Customer")) return null;
SaQuickBooksDataItem_Online customerItem = new SaQuickBooksDataItem_Online(Qbk.EntityType.Customer);
// Customer attributes.
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ListID), nodeCustomer.GetChildText("Id"));
// Company name.
String sFullName = nodeCustomer.GetChildText("FullName");
String sCompanyName = nodeCustomer.GetChildText("CompanyName");
String sDisplayName = nodeCustomer.GetChildText("DisplayName");
if (sCompanyName.IsEmpty())
sCompanyName = sDisplayName;
if (!sCompanyName.IsEmpty())
{
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_Name), sCompanyName);
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_CompanyName), sCompanyName);
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_FullName), sCompanyName);
}
if (!sDisplayName.IsEmpty())
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_Name), sDisplayName);
if (!sFullName.IsEmpty())
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_FullName), sFullName);
// Only populate attributes if present in data.
// Active.
XElement nodeActive = nodeCustomer.GetFirstChildElement("Active");
if (nodeActive == null)
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_IsActive), nodeActive.Value.ToBool());
// Balance.
XElement nodeBalance = nodeCustomer.GetFirstChildElement("Balance");
if (nodeBalance == null)
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_Balance), nodeBalance.Value.ToDouble());
// Credit limit.
XElement nodeCreditLimit = nodeCustomer.GetFirstChildElement("CreditLimit");
if (nodeCreditLimit == null)
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_CreditLimit), nodeCreditLimit.Value.ToDouble());
// Phone numbers and email address.
XElement nodePrimaryPhone = nodeCustomer.GetFirstChildElement("PrimaryPhone");
if (nodePrimaryPhone == null)
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_Phone), nodePrimaryPhone.GetChildText("FreeFormNumber"));
XElement nodeAlternatePhone = nodeCustomer.GetFirstChildElement("AlternatePhone");
if (nodeAlternatePhone == null)
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_AltPhone), nodeAlternatePhone.GetChildText("FreeFormNumber"));
XElement nodePrimaryEmailAddr = nodeCustomer.GetFirstChildElement("PrimaryEmailAddr");
if (nodePrimaryEmailAddr == null)
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_Email), nodePrimaryEmailAddr.GetChildText("Address"));
// Billing address.
XElement nodeBillAddr = nodeCustomer.GetFirstChildElement("BillAddr");
if (nodeBillAddr == null)
{
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressAddr1), nodeBillAddr.GetChildText("Line1"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressAddr2), nodeBillAddr.GetChildText("Line2"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressAddr3), nodeBillAddr.GetChildText("Line3"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressAddr4), nodeBillAddr.GetChildText("Line4"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressAddr5), nodeBillAddr.GetChildText("Line5"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressCity), nodeBillAddr.GetChildText("City"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressCounty), nodeBillAddr.GetChildText("CountrySubDivisionCode"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressPostalCode), nodeBillAddr.GetChildText("PostalCode"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressCountry), nodeBillAddr.GetChildText("Country"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_BillAddressNote), nodeBillAddr.GetChildText("Note"));
}
// Shipping address.
XElement nodeShipAddr = nodeCustomer.GetFirstChildElement("ShipAddr");
if (nodeShipAddr == null)
{
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressAddr1), nodeShipAddr.GetChildText("Line1"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressAddr2), nodeShipAddr.GetChildText("Line2"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressAddr3), nodeShipAddr.GetChildText("Line3"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressAddr4), nodeShipAddr.GetChildText("Line4"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressAddr5), nodeShipAddr.GetChildText("Line5"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressCity), nodeShipAddr.GetChildText("City"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressCounty), nodeShipAddr.GetChildText("CountrySubDivisionCode"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressPostalCode), nodeShipAddr.GetChildText("PostalCode"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressCountry), nodeShipAddr.GetChildText("Country"));
customerItem.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Customer_ShipAddressNote), nodeShipAddr.GetChildText("Note"));
}
return customerItem;
}
//===========================================================================
// E x t r a c t I t e m
//===========================================================================
SaQuickBooksDataItem_Online GetItemFrom (XElement nodeItem)
{
if (nodeItem == null || !nodeItem.GetLocalName().EqualsCI("Item")) return null;
SaQuickBooksDataItem_Online item = new SaQuickBooksDataItem_Online(Qbk.EntityType.Item);
// Item attributes.
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_ListID), nodeItem.GetChildText("Id"));
// Active.
XElement nodeActive = nodeItem.GetFirstChildElement("Active");
if (nodeActive == null)
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_IsActive), nodeActive.Value.ToBool());
// Name.
XElement nodeName = nodeItem.GetFirstChildElement("Name");
if (nodeName == null)
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_Name), nodeName.Value);
// Description - use name as default.
XElement nodeDescription = nodeItem.GetFirstChildElement("Description");
if (nodeDescription == null)
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_Description), nodeDescription.Value);
else if (nodeName == null)
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_Description), nodeName.Value);
//#######################################################################
// Sku - Use 'Name' field for now (until SKU available in schema).
XElement nodeSku = nodeItem.GetFirstChildElement("Sku");
if (nodeSku == null)
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_Name), nodeSku.Value);
// Unit price.
XElement nodeUnitPrice = nodeItem.GetFirstChildElement("UnitPrice");
if (nodeUnitPrice == null)
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_SalesPrice), nodeUnitPrice.Value.ToDouble());
// Purchase code.
XElement nodePurchaseCost = nodeItem.GetFirstChildElement("PurchaseCost");
if (nodePurchaseCost == null)
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_PurchaseCost), nodePurchaseCost.Value.ToDouble());
// Sales tax code ref.
XElement nodeSalesTaxCodeRef = nodeItem.GetFirstChildElement("SalesTaxCodeRef");
if (nodeSalesTaxCodeRef == null)
{
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_SalesTaxCodeRefListID), nodeSalesTaxCodeRef.Value.ToLong());
item.SetValue(QBooksDbDfn.GetColumnName(QBooksDbDfn.ColumnIdx.Item_SalesTaxCodeRefFullName), nodeSalesTaxCodeRef.GetAttributeValue("name"));
}
return item;
}
//---------------------------------------------------------------
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,70 @@
using Sarand.Net.Standard.Accounts.QuickBooks.App;
using Sarand.Net.Standard.Accounts.QuickBooks.Base;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Bus;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
namespace Sarand.Net.Standard.Accounts.QuickBooks.Online
{
//=======================================================================
internal class SaQuickBooksRequest_Online : SaErrorStateItem
{
//-------------------------------------------------------------------
// Data members.
internal class AuthorisationData
{
public String CompanyId { get; set; } = "";
public String AppToken { get; set; } = "";
public String AppTokenSecret { get; set; } = "";
public String DataSource { get; set; } = "";
public bool Success { get; set; } = false;
};
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
internal SaQuickBooksRequest_Online (Qbk.OnlineRequestType requestType = Qbk.OnlineRequestType.Unknown)
{
RequestType = requestType;
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
public Qbk.OnlineRequestType RequestType { get; set; }
// Request parameters.
public bool Debug { get; set; } = false;
/// <summary>For error messages.</summary>
public String RequestTypeDesc { get; set; } = "request";
public int MinorVersion { get; set; } = 4;
public String EntityId { get; set; } = "";
public String DataQuery { get; set; } = "";
public String IntuitTid { get; set; } = "";
public String FileData { get; set; } = "";
// Response.
public bool ValidResponse { get; set; } = false;
public long HttpStatus { get; set; } = 0;
public String FileResponse { get; set; } = "";
public XDocument ResponseDoc { get; set; } = null;
// Fault response.
public String ResponseFaultType { get; set; } = "";
public String ResponseErrorCode { get; set; } = "";
public String ResponseErrorElement { get; set; } = "";
public String ResponseErrorMessage { get; set; } = "";
public String ResponseErrorDetail { get; set; } = "";
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.Sage.App
{
//=======================================================================
public static class Sage
{
//-------------------------------------------------------------------
// Sage database version.
public enum DbVersion
{
Unknown = 0,
// Line 50.
Line50V08 = 508,
Line50V09 = 509,
Line50V10 = 510,
Line50V11 = 511,
Line50V12 = 512,
Line50V13 = 513,
/// <summary>Sage Line 50 v14, 2008</summary>
Line50V14 = 514,
/// <summary>Sage Line 50 v15, 2009</summary>
Line50V15 = 515,
/// <summary>Sage Line 50 v16, 2010</summary>
Line50V16 = 516,
/// <summary>Sage Line 50 v17, 2011</summary>
Line50V17 = 517,
/// <summary>Sage Line 50 v18, 2012</summary>
Line50V18 = 518,
/// <summary>Sage Line 50 v19, 2013</summary>
Line50V19 = 519,
/// <summary>Sage Line 50 v20, 2014</summary>
Line50V20 = 520,
/// <summary>Sage Line 50 v21, 2015</summary>
Line50V21 = 521,
/// <summary>Sage Line 50 v22, 2016</summary>
Line50V22 = 522,
/// <summary>Sage Line 50 v23, 2017</summary>
Line50V23 = 523,
/// <summary>Sage Line 50 v24, 2018</summary>
Line50V24 = 524,
};
//-----------------------------------------------------------------------
// Sage reference types.
public enum ReferenceDataType
{
Unknown = 0,
Department = 1,
Country,
Currency,
TaxCode,
StockCategory,
FixedAssetCategory,
AccountStatus,
DisputeReason,
};
//-----------------------------------------------------------------------
// Sage item types.
public enum ItemType
{
Unknown = 0,
/// <summary>Sales Ledger</summary>
Customer = 10,
SalesDeliveryAddress,
/// <summary>Purchase Ledger</summary>
Supplier,
/// <summary>Stock</summary>
Product = 20,
/// <summary>Current stock level</summary>
StockLevel,
/// <summary>Latest stock take on Stock record</summary>
StockTake,
StockBom,
StockCategory,
StockTransfer,
PriceList,
Price,
/// <summary>Purchase Order</summary>
PurchaseOrder = 30,
/// <summary>POP Item</summary>
PurchaseOrderItem,
/// <summary>POP Item movement</summary>
PopItemAllocation,
/// <summary>Sales Order</summary>
SalesOrder = 40,
/// <summary>SOP Item</summary>
SalesOrderItem,
/// <summary>SOP Item movement</summary>
SopItemAllocation,
/// <summary>Invoice type 0</summary>
Invoice_Product = 50,
/// <summary>No sales order available - must be allocated directly</summary>
Invoice_Product_Allocation,
/// <summary>Invoice type 1</summary>
Invoice_SalesOrder,
/// <summary>Invoice type 2</summary>
Invoice_Service,
/// <summary>No sales order available - must be allocated directly</summary>
Invoice_Service_Allocation,
InvoiceItem,
};
//-----------------------------------------------------------------------
// Sage invoice types.
public enum InvoiceType
{
Unknown = -1,
Product = 0, // Invoice
ProductFromSalesOrder = 1, // Invoice
Service = 2, // Invoice
ProductCreditNote = 3, // Credit note
ServiceCreditNote = 4, // Credit note
ProductProForma = 5, // Pro-forma
ProductQuote = 6, // Quote
ServiceProForma = 7, // Pro-forma
ServiceQuote = 8, // Quote
};
//-----------------------------------------------------------------------
// Sage Reserved Stock codes.
public enum StockCode
{
Unknown = 0,
/// <summary>"M"</summary>
Memo,
/// <summary>"S1"</summary>
PrdTax,
/// <summary>"S2"</summary>
PrdZero,
/// <summary>"S3"</summary>
SrvTax,
};
//-------------------------------------------------------------------
// Financial year.
public enum FinancialYear
{
Unknown = 0,
Current,
Prior1,
Prior2,
Prior3,
Prior4,
Prior5
};
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,49 @@
using Sarand.Net.Standard.Base.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace Sarand.Net.Standard.Accounts.Sage.App
{
//=======================================================================
public static class SageConsole
{
//-------------------------------------------------------------------
// Data members.
private static readonly List<TypeCodeDesc> sageItemTypes = new List<TypeCodeDesc>();
//-------------------------------------------------------------------
// Static initialisation.
static SageConsole ()
{
// Sage item types.
// NB Don't change the codes - these are used on the database:
sageItemTypes.Add(Sage.ItemType.Customer, "CUST", "Customers");
sageItemTypes.Add(Sage.ItemType.Supplier, "SUPP", "Suppliers");
sageItemTypes.Add(Sage.ItemType.Product, "PROD", "Products");
sageItemTypes.Add(Sage.ItemType.PriceList, "PRCLST", "Pricing");
sageItemTypes.Add(Sage.ItemType.StockLevel, "STKLVL", "Stock levels");
sageItemTypes.Add(Sage.ItemType.StockTake, "STKTAK", "Stock takes");
sageItemTypes.Add(Sage.ItemType.StockBom, "STKBOM", "Stock BOM");
sageItemTypes.Add(Sage.ItemType.StockCategory, "STKCAT", "Stock categories");
sageItemTypes.Add(Sage.ItemType.StockTransfer, "STKTRA", "Stock transfers");
sageItemTypes.Add(Sage.ItemType.PurchaseOrder, "PURO", "Purchase orders");
sageItemTypes.Add(Sage.ItemType.PopItemAllocation, "PURALL", "POP allocations");
sageItemTypes.Add(Sage.ItemType.SalesOrder, "SALO", "Sales orders");
sageItemTypes.Add(Sage.ItemType.SopItemAllocation, "SALALL", "SOP allocations");
sageItemTypes.Add(Sage.ItemType.Invoice_Product, "INVPRD", "Product invoice");
sageItemTypes.Add(Sage.ItemType.Invoice_Product_Allocation, "PRIALL", "Product invoice allocation");
sageItemTypes.Add(Sage.ItemType.Invoice_SalesOrder, "INVSAL", "Sales order invoice");
sageItemTypes.Add(Sage.ItemType.Invoice_Service, "INVSRV", "Service invoice");
sageItemTypes.Add(Sage.ItemType.Invoice_Service_Allocation, "SRIALL", "Service invoice allocation");
sageItemTypes.Add(Sage.ItemType.InvoiceItem, "INVITM", "Invoice item");
}
//-------------------------------------------------------------------
// Properties.
public static List<TypeCodeDesc> ItemTypeCodes { get { return new List<TypeCodeDesc>(sageItemTypes); } }
//-------------------------------------------------------------------
}
//=======================================================================
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>Sarand.Net.Standard</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SacsStandardBase\SacsStandardBase.csproj" />
</ItemGroup>
</Project>
+246
View File
@@ -0,0 +1,246 @@
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Tasks;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Sarand.Net.Standard.Base.Net
{
//=======================================================================
public class SacsHttpRequestData : SacsTaskData
{
public SacsHttpRequestData (CancellationToken? cancellationToken) : base(cancellationToken) { }
/// <summary>URL to send request to.</summary>
public String Url { get; set; }
/// <summary>
/// Request timeout. Default: 5 secs.
/// <para>NB Not currently supported as can only be changed when static HTTP Client not in use.</para>
/// </summary>
public int TimeoutSecs { get; set; } = SacsHttpClient.RequestTimeoutSecs_Default;
/// <summary>
/// Headers to send with request.
/// <para>Accept, Accept-Charset, Accept-Encoding, Accept-Language, User-Agent, Transfer-Encoding, Pragma, Expect etc.</para>
/// </summary>
public Dictionary<String, List<String>> RequestHeaders { get; } = new Dictionary<String, List<String>>();
/// <summary>
/// Content Headers to send with request.
/// <para>Content-Length (bytes), Content-Type (media type), Content-Encoding (compression algorithm), Content-Language etc.</para>
/// <para>Content-Type header is defaulted for POST request if not specified.</para>
/// </summary>
public Dictionary<String, List<String>> ContentHeaders { get; } = new Dictionary<String, List<String>>();
/// <summary>
/// Form values to post as 'URL Encoded'.
/// <para>Content-Type defaults to 'application/x-www-form-urlencoded; charset=utf-8'.</para>
/// </summary>
public List<KeyValuePair<string, string>> FormData { get; } = new List<KeyValuePair<string, string>>();
/// <summary>
/// Data to POST. Ignored if FormData populated.
/// <para>Content-Type defaults to 'text/plain; charset=utf-8'.</para>
/// </summary>
public String PostData { get; set; }
/// <summary>Use POST request rather than GET even if no data to post.</summary>
public bool ForcePost { get; set; }
}
//=======================================================================
public class SacsHttpResponseData
{
public DateTime RequestStarted { get; set; }
public DateTime RequestCompleted { get; set; }
/// <summary>Response headers.</summary>
public Dictionary<String, IEnumerable<String>> ResponseHeaders { get; } = new Dictionary<String, IEnumerable<String>>();
/// <summary>Response content headers.</summary>
public Dictionary<String, IEnumerable<String>> ContentHeaders { get; } = new Dictionary<String, IEnumerable<String>>();
/// <summary>Indicates whether Status Code represents success.</summary>
public bool Success { get; set; }
/// <summary>HTTP Status Code.</summary>
public HttpStatusCode StatusCode { get; set; }
/// <summary>HTTP Reason Code.</summary>
public String ReasonPhrase { get; set; } = "";
/// <summary>Response data.</summary>
public String Data { get; set; } = "";
/// <summary>Elapsed time for request.</summary>
public TimeSpan Elapsed { get; set; }
/// <summary>Exception thrown during handling of request.</summary>
public Exception Exception { get; set; }
/// <summary>Error state message - generally exception type and message.</summary>
public String ErrorStateMessage { get; set; }
}
//=======================================================================
public static class SacsHttpClient
{
//-------------------------------------------------------------------
// Data members.
private static readonly HttpClient client;
//-------------------------------------------------------------------
// Static initialisation.
static SacsHttpClient ()
{
// Configure client.
client = new HttpClient();
client.Timeout = new TimeSpan(0, 0, RequestTimeoutSecs_Default);
}
//-------------------------------------------------------------------
// Properties.
public static int RequestTimeoutSecs_Default { get; } = 5;
public static String HeaderName_ContentType { get; } = "Content-Type";
//-------------------------------------------------------------------
public static async Task<SacsHttpResponseData> DoRequest (SacsHttpRequestData requestData)
{
String fn = "SacsHttpClient.DoRequest";
SacsHttpResponseData responseData = new SacsHttpResponseData();
requestData.ThrowIfCancellationRequested();
// Construct content to post.
HttpContent postContent = null;
if (requestData.FormData.Count > 0)
{
postContent = new FormUrlEncodedContent(requestData.FormData);
if (!requestData.ContentHeaders.ContainsKey(HeaderName_ContentType))
requestData.ContentHeaders.Add(HeaderName_ContentType,"application/x-www-form-urlencoded; charset=utf-8");
}
else if (!StringUtil.IsEmpty(requestData.PostData) || requestData.ForcePost)
{
postContent = new StringContent(StringUtil.EmptyOnNull(requestData.PostData), Encoding.UTF8);
if (!requestData.ContentHeaders.ContainsKey(HeaderName_ContentType))
requestData.ContentHeaders.Add(HeaderName_ContentType,"text/plain; charset=utf-8");
}
requestData.ThrowIfCancellationRequested();
// Make request.
DateTime startedAt = DateTime.Now;
try
{
// Request.
using (HttpRequestMessage request = new HttpRequestMessage())
{
request.RequestUri = new Uri(requestData.Url);
// Request headers.
foreach (String headerName in requestData.RequestHeaders.Keys)
{
if (request.Headers.Contains(headerName))
request.Headers.Remove(headerName);
request.Headers.Add(headerName, requestData.RequestHeaders[headerName]);
}
// Default request headers.
if (client.DefaultRequestHeaders.Accept.Count == 0 && request.Headers.Accept.Count == 0)
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/*"));
// Configure request.
HttpResponseMessage response = null;
// Send request.
if (postContent != null)
{
// POST.
request.Method = HttpMethod.Post;
request.Content = postContent;
// Content headers.
foreach (String headerName in requestData.ContentHeaders.Keys)
{
if (request.Content.Headers.Contains(headerName))
request.Content.Headers.Remove(headerName);
request.Content.Headers.Add(headerName, requestData.ContentHeaders[headerName]);
}
// Send request.
responseData.RequestStarted = DateTime.Now;
response = await client.SendAsync(request, requestData.CancellationToken);
responseData.RequestCompleted = DateTime.Now;
}
else
{
// GET.
request.Method = HttpMethod.Get;
responseData.RequestStarted = DateTime.Now;
response = await client.SendAsync(request, requestData.CancellationToken);
responseData.RequestCompleted = DateTime.Now;
}
// Extract resopnse data.
responseData.Success = response.IsSuccessStatusCode;
responseData.StatusCode = response.StatusCode;
responseData.ReasonPhrase = response.ReasonPhrase;
if (response.Headers != null)
{
foreach (var header in response.Headers)
responseData.ResponseHeaders[header.Key] = new List<String>(header.Value);
}
if (response.Content != null && response.Content.Headers != null)
{
foreach (var header in response.Content.Headers)
responseData.ContentHeaders[header.Key] = new List<String>(header.Value);
}
responseData.Data = await response.Content.ReadAsStringAsync();
if (response != null) response.Dispose();
}
}
catch (Exception exc)
{
// Ignore if task has been cancelled.
if (requestData.IsCancellationRequested) throw exc;
// Record exception.
responseData.Exception = exc;
if (exc.InnerException != null)
{
exc = exc.InnerException;
}
String msg = exc.GetType().Name + ": " + exc.Message;
SaLogger.Warn(fn + " " + msg + ExceptionUtil.GetStackEntries(exc, 6).Concat("", "\n\t"));
responseData.ErrorStateMessage = msg;
}
requestData.ThrowIfCancellationRequested();
// Complete response data.
responseData.Elapsed = DateTime.Now - startedAt;
return responseData;
}
//-------------------------------------------------------------------
// R e s p o n s e S t a t u s D e s c r i p t i o n
//-------------------------------------------------------------------
public static String GetResponseStatusDescription (HttpStatusCode httpStatus)
{
// Ref. https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
switch (httpStatus)
{
// 1xx: Informational - Request received, continuing process.
case HttpStatusCode.Continue: return "Continue";
// 2xx: Success - The action was successfully received, understood, and accepted.
case HttpStatusCode.OK: return "OK";
case HttpStatusCode.Created: return "Created";
case HttpStatusCode.Accepted: return "Accepted";
// 3xx: Redirection - Further action must be taken in order to complete the request.
case HttpStatusCode.MultipleChoices: return "Multiple choices";
case HttpStatusCode.MovedPermanently: return "Moved permanently";
case HttpStatusCode.Found: return "Found";
// 4xx: Client Error -The request contains bad syntax or cannot be fulfilled.
case HttpStatusCode.BadRequest: return "Bad request";
case HttpStatusCode.Unauthorized: return "Unauthorized";
case HttpStatusCode.PaymentRequired: return "Payment required";
case HttpStatusCode.Forbidden: return "Forbidden";
case HttpStatusCode.NotFound: return "Not found";
case HttpStatusCode.MethodNotAllowed: return "Method not allowed";
case HttpStatusCode.NotAcceptable: return "Not acceptable";
// 5xx: Server Error -The server failed to fulfill an apparently valid request.
case HttpStatusCode.InternalServerError: return "Internal server error";
}
return httpStatus.ToString();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
+46
View File
@@ -0,0 +1,46 @@
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
namespace Sarand.Net.Standard.Base.Net
{
public static class WebUtil
{
//-------------------------------------------------------------------
// H T M L E n c o d i n g
//-------------------------------------------------------------------
/// <summary>Converts a string to an HTML-encoded string.</summary>
public static String HtmlEncode (this String value)
{
if (StringUtil.IsEmpty(value)) return value;
return WebUtility.HtmlEncode(value);
}
/// <summary>Converts a string that has been HTML-encoded for HTTP transmission into a decoded string.</summary>
public static String HtmlDecode (this String value)
{
if (StringUtil.IsEmpty(value)) return value;
return WebUtility.HtmlDecode(value);
}
//-------------------------------------------------------------------
// U R L E n c o d i n g
//-------------------------------------------------------------------
/// <summary>Converts a string to an HTML-encoded string.</summary>
public static String UrlEncode (this String value)
{
if (StringUtil.IsEmpty(value)) return value;
return WebUtility.UrlEncode(value);
}
/// <summary>Converts a string that has been HTML-encoded for HTTP transmission into a decoded string.</summary>
public static String UrlDecode (this String value)
{
if (StringUtil.IsEmpty(value)) return value;
return WebUtility.UrlDecode(value);
}
//-------------------------------------------------------------------
}
}