diff --git a/.gitignore b/.gitignore index 588699f..62113a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,320 @@ -/vendor/ -composer.lock -.DS_Store -._* -Thumbs.db -Desktop.ini -sftp-config.json \ No newline at end of file +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog diff --git a/Moltin.v11.suo b/Moltin.v11.suo deleted file mode 100644 index 5bb5aaf..0000000 Binary files a/Moltin.v11.suo and /dev/null differ diff --git a/Moltin/Authenticate.cs b/Moltin/Authenticate.cs deleted file mode 100644 index 587bac1..0000000 --- a/Moltin/Authenticate.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Moltin -{ - public interface Authenticate - { - void authenticate(Dictionary args); - - void refresh(Dictionary args); - - string get(string key); - } -} diff --git a/Moltin/Authenticate/ClientCredentials.cs b/Moltin/Authenticate/ClientCredentials.cs deleted file mode 100644 index 5c10d08..0000000 --- a/Moltin/Authenticate/ClientCredentials.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Web.Helpers; -using System.Web.Script.Serialization; - -namespace Moltin -{ - class ClientCredentials : Authenticate - { - protected Dictionary _data = new Dictionary(){ - {"token", null}, - {"refresh", null}, - {"expires", null} - }; - - public void authenticate(Dictionary args) - { - // Variables - string url = SDK.url + "oauth/access_token"; - Dictionary data = new Dictionary() { - {"grant_type", "client_credentials"}, - {"client_id", args["client_id"]}, - {"client_secret", args["client_secret"]} - }; - - // Make request - SDK.request.setup(url, "POST", data); - string result = SDK.request.make().Replace("\\\"", "'"); - - // Check response - JavaScriptSerializer jss = new JavaScriptSerializer(); - Dictionary json = jss.Deserialize>(result); - - // Check JSON for errors - if (json.ContainsKey("error")) - { - throw new System.ArgumentException(json["error"].ToString()); - } - - // Set data - data["token"] = json["token"].ToString(); - data["refresh"] = json["refresh"].ToString(); - data["expires"] = json["expires"].ToString(); - } - - public void refresh(Dictionary args) - { - authenticate(args); - } - - public string get(string key) - { - if (!_data.ContainsKey(key)) { return null; } - return _data[key]; - } - - } -} diff --git a/Moltin/Models/IModels.cs b/Moltin/Models/IModels.cs new file mode 100644 index 0000000..2d6c89a --- /dev/null +++ b/Moltin/Models/IModels.cs @@ -0,0 +1,43 @@ +namespace Moltin.Models +{ + internal interface IMoltinCheckoutBindingModel + { + string Cart_id { get; set; } + string Gateway { get; set; } + string Shipping { get; set; } + MoltinCustomerBindingModel Customer { get; set; } + } + + internal interface ICheckoutBindingModel + { + string CartId { get; set; } + string Gateway { get; set; } + string Shipping { get; set; } + CustomerBindingModel Customer { get; set; } + AddressBindingModel ShipTo { get; set; } + AddressBindingModel BillTo { get; set; } + } + + internal interface ICustomerBindingModel + { + string Id { get; set; } + string FirstName { get; set; } + string LastName { get; set; } + string Email { get; set; } + } + + internal interface IAddressBindingModel + { + string Id { get; set; } + string FirstName { get; set; } + string LastName { get; set; } + string Phone { get; set; } + string SaveAs { get; set; } + string Address1 { get; set; } + string Address2 { get; set; } + string City { get; set; } + string County { get; set; } + string PostCode { get; set; } + string Country { get; set; } + } +} \ No newline at end of file diff --git a/Moltin/Models/ModelFactory.cs b/Moltin/Models/ModelFactory.cs new file mode 100644 index 0000000..24e9b47 --- /dev/null +++ b/Moltin/Models/ModelFactory.cs @@ -0,0 +1,106 @@ +namespace Moltin.Models +{ + /// + /// Factory classes for factorizing models into moltin models + /// + internal static class ModelFactory + { + /// + /// Creates the moltin specific checkout model + /// + /// The default c# request model + /// The output model + /// + public static IMoltinCheckoutBindingModel Create(ICheckoutBindingModel model) + { + // Get the billing and shipping ids + var billingId = model.BillTo.Id; + var shippingId = model.ShipTo.Id; + + // If we have both shipping and billing + if (!string.IsNullOrEmpty(billingId) && !string.IsNullOrEmpty(shippingId)) + return new MoltinCheckoutBothAddressesBindingModel + { + Cart_id = model.CartId, + Gateway = model.Gateway, + Shipping = model.Shipping, + + Customer = Create(model.Customer), + Ship_to = model.ShipTo.Id, + Bill_to = model.BillTo.Id + }; + + // If we only have the billing id + if (!string.IsNullOrEmpty(billingId) && string.IsNullOrEmpty(shippingId)) + return new MoltinCheckoutBillingAddressOnlyBindingModel + { + Cart_id = model.CartId, + Gateway = model.Gateway, + Shipping = model.Shipping, + + Customer = Create(model.Customer), + Ship_to = Create(model.ShipTo), + Bill_to = model.BillTo.Id + }; + + // If we only have the shipping id + if (string.IsNullOrEmpty(billingId) && !string.IsNullOrEmpty(shippingId)) + return new MoltinCheckoutShippingAddressOnlyBindingModel + { + Cart_id = model.CartId, + Gateway = model.Gateway, + Shipping = model.Shipping, + + Customer = Create(model.Customer), + Ship_to = model.ShipTo.Id, + Bill_to = Create(model.BillTo) + }; + + // Return the moltin model + return new MoltinCheckoutBindingModel + { + Cart_id = model.CartId, + Gateway = model.Gateway, + Shipping = model.Shipping, + + Customer = Create(model.Customer), + Ship_to = Create(model.ShipTo), + Bill_to = Create(model.BillTo) + }; + } + + /// + /// Creates the moltin specific customer model + /// + /// The default c# request model + /// + public static MoltinCustomerBindingModel Create(ICustomerBindingModel model) => new MoltinCustomerBindingModel + { + Id = model.Id, + First_name = model.FirstName, + Last_name = model.LastName, + Email = model.Email + }; + + /// + /// Creates the moltin specific address model + /// + /// The default c# request model + /// + public static MoltinAddressBindingModel Create(IAddressBindingModel model) => new MoltinAddressBindingModel + { + Id = model.Id, + First_name = model.FirstName, + Last_name = model.LastName, + Phone = model.Phone, + + Save_as = model.SaveAs, + Address_1 = model.Address1, + Address_2 = model.Address2, + City = model.City, + County = model.County, + Country = model.Country, + Postcode = model.PostCode + }; + } +} \ No newline at end of file diff --git a/Moltin/Models/Models.cs b/Moltin/Models/Models.cs new file mode 100644 index 0000000..71eb2ea --- /dev/null +++ b/Moltin/Models/Models.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Moltin.Models +{ + public class CheckoutBindingModel : ICheckoutBindingModel + { + [Required] public string CartId { get; set; } + [Required] public string Gateway { get; set; } + [Required] public string Shipping { get; set; } + [Required] public CustomerBindingModel Customer { get; set; } + [Required] public AddressBindingModel ShipTo { get; set; } + [Required] public AddressBindingModel BillTo { get; set; } + } + + public class CustomerBindingModel : ICustomerBindingModel + { + public string Id { get; set; } + + [Required] public string FirstName { get; set; } + [Required] public string LastName { get; set; } + [Required] public string Email { get; set; } + } + + public class AddressBindingModel : IAddressBindingModel + { + public string Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Phone { get; set; } + public string Address2 { get; set; } + public string SaveAs { get; set; } + + [Required] public string Address1 { get; set; } + [Required] public string City { get; set; } + [Required] public string County { get; set; } + [Required] public string PostCode { get; set; } + [Required] public string Country { get; set; } + } + + [JsonConverter(typeof(CartModifierSerializer))] public class MoltinModifierModel + { + public MoltinModifierModel() => Values = new Dictionary(); + + public Dictionary Values { get; set; } + } + + public class CartModifierSerializer : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var modifier = value as MoltinModifierModel; + writer.WriteStartObject(); + foreach (var pair in modifier.Values) + { + writer.WritePropertyName(pair.Key); + writer.WriteValue(pair.Value); + } + writer.WriteEndObject(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var jsonObject = JObject.Load(reader); + var properties = jsonObject.Properties().ToList(); + return new MoltinModifierModel + { + Values = properties.ToDictionary(x => x.Name, x => x.Value.ToString()) + }; + } + + public override bool CanConvert(Type objectType) => typeof(MoltinModifierModel).IsAssignableFrom(objectType); + } + + #region Private + + internal class MoltinCheckoutBothAddressesBindingModel : IMoltinCheckoutBindingModel + { + public string Ship_to { get; set; } + public string Bill_to { get; set; } + public string Cart_id { get; set; } + public string Gateway { get; set; } + public string Shipping { get; set; } + public MoltinCustomerBindingModel Customer { get; set; } + } + + internal class MoltinCheckoutShippingAddressOnlyBindingModel : IMoltinCheckoutBindingModel + { + public string Ship_to { get; set; } + public MoltinAddressBindingModel Bill_to { get; set; } + public string Cart_id { get; set; } + public string Gateway { get; set; } + public string Shipping { get; set; } + public MoltinCustomerBindingModel Customer { get; set; } + } + + internal class MoltinCheckoutBillingAddressOnlyBindingModel : IMoltinCheckoutBindingModel + { + public MoltinAddressBindingModel Ship_to { get; set; } + public string Bill_to { get; set; } + public string Cart_id { get; set; } + public string Gateway { get; set; } + public string Shipping { get; set; } + public MoltinCustomerBindingModel Customer { get; set; } + } + + internal class MoltinCheckoutBindingModel : IMoltinCheckoutBindingModel + { + public MoltinAddressBindingModel Ship_to { get; set; } + public MoltinAddressBindingModel Bill_to { get; set; } + public string Cart_id { get; set; } + public string Gateway { get; set; } + public string Shipping { get; set; } + public MoltinCustomerBindingModel Customer { get; set; } + } + + internal class MoltinCustomerBindingModel + { + public string Id { get; set; } + public string First_name { get; set; } + public string Last_name { get; set; } + public string Email { get; set; } + } + + internal class MoltinAddressBindingModel + { + public string Id { get; set; } + public string First_name { get; set; } + public string Last_name { get; set; } + public string Phone { get; set; } + public string Save_as { get; set; } + public string Address_1 { get; set; } + public string Address_2 { get; set; } + public string City { get; set; } + public string County { get; set; } + public string Postcode { get; set; } + public string Country { get; set; } + } + + #endregion +} \ No newline at end of file diff --git a/Moltin/Moltin.csproj b/Moltin/Moltin.csproj index d019280..ff0bb01 100644 --- a/Moltin/Moltin.csproj +++ b/Moltin/Moltin.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,8 +9,9 @@ Properties Moltin Moltin - v4.5 + v4.6.2 512 + true @@ -30,14 +31,21 @@ 4 + + ..\..\Kudos.Api\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + + + + ..\..\Kudos.Api\packages\Microsoft.AspNet.WebApi.Client.5.2.6\lib\net45\System.Net.Http.Formatting.dll + + - @@ -45,13 +53,18 @@ - - - - - + + + + + + + Designer + + +