From 58ffa651f7acbd30c4049874a3b6bd0c0b9a9dc4 Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 05:35:15 +0200 Subject: [PATCH 01/11] Reorganized objects into different Repositories, Models and Service folders and namespaces for simpler management. --- TechTest/AnyCompany/AnyCompany.csproj | 10 +++++----- TechTest/AnyCompany/{ => Models}/Customer.cs | 2 +- TechTest/AnyCompany/{ => Models}/Order.cs | 2 +- .../{ => Repositories}/CustomerRepository.cs | 5 +++-- .../AnyCompany/{ => Repositories}/OrderRepository.cs | 5 +++-- TechTest/AnyCompany/{ => Services}/OrderService.cs | 5 ++++- 6 files changed, 17 insertions(+), 12 deletions(-) rename TechTest/AnyCompany/{ => Models}/Customer.cs (87%) rename TechTest/AnyCompany/{ => Models}/Order.cs (84%) rename TechTest/AnyCompany/{ => Repositories}/CustomerRepository.cs (92%) rename TechTest/AnyCompany/{ => Repositories}/OrderRepository.cs (89%) rename TechTest/AnyCompany/{ => Services}/OrderService.cs (85%) diff --git a/TechTest/AnyCompany/AnyCompany.csproj b/TechTest/AnyCompany/AnyCompany.csproj index 5b0498d..9c7823a 100644 --- a/TechTest/AnyCompany/AnyCompany.csproj +++ b/TechTest/AnyCompany/AnyCompany.csproj @@ -40,11 +40,11 @@ - - - - - + + + + + diff --git a/TechTest/AnyCompany/Customer.cs b/TechTest/AnyCompany/Models/Customer.cs similarity index 87% rename from TechTest/AnyCompany/Customer.cs rename to TechTest/AnyCompany/Models/Customer.cs index aa994b6..08e21f8 100644 --- a/TechTest/AnyCompany/Customer.cs +++ b/TechTest/AnyCompany/Models/Customer.cs @@ -1,6 +1,6 @@ using System; -namespace AnyCompany +namespace AnyCompany.Models { public class Customer { diff --git a/TechTest/AnyCompany/Order.cs b/TechTest/AnyCompany/Models/Order.cs similarity index 84% rename from TechTest/AnyCompany/Order.cs rename to TechTest/AnyCompany/Models/Order.cs index fec8e7b..8887aa7 100644 --- a/TechTest/AnyCompany/Order.cs +++ b/TechTest/AnyCompany/Models/Order.cs @@ -1,4 +1,4 @@ -namespace AnyCompany +namespace AnyCompany.Models { public class Order { diff --git a/TechTest/AnyCompany/CustomerRepository.cs b/TechTest/AnyCompany/Repositories/CustomerRepository.cs similarity index 92% rename from TechTest/AnyCompany/CustomerRepository.cs rename to TechTest/AnyCompany/Repositories/CustomerRepository.cs index e3de9b7..25ada2c 100644 --- a/TechTest/AnyCompany/CustomerRepository.cs +++ b/TechTest/AnyCompany/Repositories/CustomerRepository.cs @@ -1,7 +1,8 @@ -using System; +using AnyCompany.Models; +using System; using System.Data.SqlClient; -namespace AnyCompany +namespace AnyCompany.Repositories { public static class CustomerRepository { diff --git a/TechTest/AnyCompany/OrderRepository.cs b/TechTest/AnyCompany/Repositories/OrderRepository.cs similarity index 89% rename from TechTest/AnyCompany/OrderRepository.cs rename to TechTest/AnyCompany/Repositories/OrderRepository.cs index 3229885..508520a 100644 --- a/TechTest/AnyCompany/OrderRepository.cs +++ b/TechTest/AnyCompany/Repositories/OrderRepository.cs @@ -1,6 +1,7 @@ -using System.Data.SqlClient; +using AnyCompany.Models; +using System.Data.SqlClient; -namespace AnyCompany +namespace AnyCompany.Repositories { internal class OrderRepository { diff --git a/TechTest/AnyCompany/OrderService.cs b/TechTest/AnyCompany/Services/OrderService.cs similarity index 85% rename from TechTest/AnyCompany/OrderService.cs rename to TechTest/AnyCompany/Services/OrderService.cs index ebfb103..51b6fed 100644 --- a/TechTest/AnyCompany/OrderService.cs +++ b/TechTest/AnyCompany/Services/OrderService.cs @@ -1,4 +1,7 @@ -namespace AnyCompany +using AnyCompany.Models; +using AnyCompany.Repositories; + +namespace AnyCompany.Services { public class OrderService { From 41b5af911920caf33060aa17a613de1bec550c3c Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 05:44:33 +0200 Subject: [PATCH 02/11] Moved connectionstrings for different databases out of source code to settings file. --- TechTest/AnyCompany/AnyCompany.csproj | 12 +++++ .../Properties/Settings.Designer.cs | 47 +++++++++++++++++++ .../AnyCompany/Properties/Settings.settings | 12 +++++ .../Repositories/CustomerRepository.cs | 4 +- .../Repositories/OrderRepository.cs | 4 +- TechTest/AnyCompany/app.config | 25 ++++++++++ 6 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 TechTest/AnyCompany/Properties/Settings.Designer.cs create mode 100644 TechTest/AnyCompany/Properties/Settings.settings create mode 100644 TechTest/AnyCompany/app.config diff --git a/TechTest/AnyCompany/AnyCompany.csproj b/TechTest/AnyCompany/AnyCompany.csproj index 9c7823a..8b88e39 100644 --- a/TechTest/AnyCompany/AnyCompany.csproj +++ b/TechTest/AnyCompany/AnyCompany.csproj @@ -41,11 +41,23 @@ + + True + True + Settings.settings + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + \ No newline at end of file diff --git a/TechTest/AnyCompany/Properties/Settings.Designer.cs b/TechTest/AnyCompany/Properties/Settings.Designer.cs new file mode 100644 index 0000000..15a8c67 --- /dev/null +++ b/TechTest/AnyCompany/Properties/Settings.Designer.cs @@ -0,0 +1,47 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AnyCompany.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Data Source=(local);Database=Orders;User Id=admin;Password=password;")] + public string OrderConnectionString { + get { + return ((string)(this["OrderConnectionString"])); + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Data Source=(local);Database=Customers;User Id=admin;Password=password;")] + public string CustomerConnectionString { + get { + return ((string)(this["CustomerConnectionString"])); + } + set { + this["CustomerConnectionString"] = value; + } + } + } +} diff --git a/TechTest/AnyCompany/Properties/Settings.settings b/TechTest/AnyCompany/Properties/Settings.settings new file mode 100644 index 0000000..6ac0c01 --- /dev/null +++ b/TechTest/AnyCompany/Properties/Settings.settings @@ -0,0 +1,12 @@ + + + + + + Data Source=(local);Database=Orders;User Id=admin;Password=password; + + + Data Source=(local);Database=Customers;User Id=admin;Password=password; + + + \ No newline at end of file diff --git a/TechTest/AnyCompany/Repositories/CustomerRepository.cs b/TechTest/AnyCompany/Repositories/CustomerRepository.cs index 25ada2c..ddd824f 100644 --- a/TechTest/AnyCompany/Repositories/CustomerRepository.cs +++ b/TechTest/AnyCompany/Repositories/CustomerRepository.cs @@ -6,13 +6,11 @@ namespace AnyCompany.Repositories { public static class CustomerRepository { - private static string ConnectionString = @"Data Source=(local);Database=Customers;User Id=admin;Password=password;"; - public static Customer Load(int customerId) { Customer customer = new Customer(); - SqlConnection connection = new SqlConnection(ConnectionString); + SqlConnection connection = new SqlConnection(Properties.Settings.Default.CustomerConnectionString); connection.Open(); SqlCommand command = new SqlCommand("SELECT * FROM Customer WHERE CustomerId = " + customerId, diff --git a/TechTest/AnyCompany/Repositories/OrderRepository.cs b/TechTest/AnyCompany/Repositories/OrderRepository.cs index 508520a..1626750 100644 --- a/TechTest/AnyCompany/Repositories/OrderRepository.cs +++ b/TechTest/AnyCompany/Repositories/OrderRepository.cs @@ -5,11 +5,9 @@ namespace AnyCompany.Repositories { internal class OrderRepository { - private static string ConnectionString = @"Data Source=(local);Database=Orders;User Id=admin;Password=password;"; - public void Save(Order order) { - SqlConnection connection = new SqlConnection(ConnectionString); + SqlConnection connection = new SqlConnection(Properties.Settings.Default.OrderConnectionString); connection.Open(); SqlCommand command = new SqlCommand("INSERT INTO Orders VALUES (@OrderId, @Amount, @VAT)", connection); diff --git a/TechTest/AnyCompany/app.config b/TechTest/AnyCompany/app.config new file mode 100644 index 0000000..22d08aa --- /dev/null +++ b/TechTest/AnyCompany/app.config @@ -0,0 +1,25 @@ + + + + +
+ + +
+ + + + + + Data Source=(local);Database=Orders;User Id=admin;Password=password; + + + + + + + Data Source=(local);Database=Customers;User Id=admin;Password=password; + + + + \ No newline at end of file From 0e4ca604bffa7d3d8a4c59c8d9dd930f69f66abc Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 05:47:36 +0200 Subject: [PATCH 03/11] Implemented @CustomerId parameters for CustomerRepository in order to implement sanitized inputs. --- TechTest/AnyCompany/Repositories/CustomerRepository.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/TechTest/AnyCompany/Repositories/CustomerRepository.cs b/TechTest/AnyCompany/Repositories/CustomerRepository.cs index ddd824f..d47704e 100644 --- a/TechTest/AnyCompany/Repositories/CustomerRepository.cs +++ b/TechTest/AnyCompany/Repositories/CustomerRepository.cs @@ -13,8 +13,10 @@ public static Customer Load(int customerId) SqlConnection connection = new SqlConnection(Properties.Settings.Default.CustomerConnectionString); connection.Open(); - SqlCommand command = new SqlCommand("SELECT * FROM Customer WHERE CustomerId = " + customerId, - connection); + SqlCommand command = new SqlCommand("SELECT * FROM Customer WHERE CustomerId = @CustomerId", connection); + + command.Parameters.AddWithValue("@CustomerId", customerId); + var reader = command.ExecuteReader(); while (reader.Read()) From 769ba0fd629094090e6b79f62ca69ee51d21cb48 Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:09:40 +0200 Subject: [PATCH 04/11] Moved VAT information into settings, and implemented a VatHelper with lookup function to easily fetch the VAT value. --- TechTest/AnyCompany/AnyCompany.csproj | 1 + TechTest/AnyCompany/Helpers/VatHelper.cs | 42 +++++++++++++++++++ .../Properties/Settings.Designer.cs | 14 +++++-- .../AnyCompany/Properties/Settings.settings | 8 +++- TechTest/AnyCompany/Services/OrderService.cs | 8 ++-- TechTest/AnyCompany/app.config | 17 ++++---- 6 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 TechTest/AnyCompany/Helpers/VatHelper.cs diff --git a/TechTest/AnyCompany/AnyCompany.csproj b/TechTest/AnyCompany/AnyCompany.csproj index 8b88e39..fcb208e 100644 --- a/TechTest/AnyCompany/AnyCompany.csproj +++ b/TechTest/AnyCompany/AnyCompany.csproj @@ -40,6 +40,7 @@ + True diff --git a/TechTest/AnyCompany/Helpers/VatHelper.cs b/TechTest/AnyCompany/Helpers/VatHelper.cs new file mode 100644 index 0000000..d473d5c --- /dev/null +++ b/TechTest/AnyCompany/Helpers/VatHelper.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Specialized; + +namespace AnyCompany.Helpers +{ + /// + /// This class contains VAT helper functions. + /// + public static class VatHelper + { + + /// + /// Finds the correct VAT rate in settings based on the given country. + /// + /// The country code to use for the VAT lookup. + public static double GetVatRateByCountry(string countryCode) + { + StringCollection vatSettings = Properties.Settings.Default.VatSettings; + + foreach (string setting in vatSettings) + { + // Confirm that this settings matches the 'CountryCode:Rate' pattern, split into an array, and confirm the second array element is indeed double compatible. + if (setting.Contains(":")) + { + string[] settingsPart = setting.Split(':'); + + if (settingsPart.Length == 2 && settingsPart[0].Equals(countryCode, StringComparison.OrdinalIgnoreCase)) + { + double testVal = 0; + + if (double.TryParse(settingsPart[1], out testVal)) + { + return testVal; + } + } + } + } + + return 0; + } + } +} diff --git a/TechTest/AnyCompany/Properties/Settings.Designer.cs b/TechTest/AnyCompany/Properties/Settings.Designer.cs index 15a8c67..e563077 100644 --- a/TechTest/AnyCompany/Properties/Settings.Designer.cs +++ b/TechTest/AnyCompany/Properties/Settings.Designer.cs @@ -32,15 +32,23 @@ public string OrderConnectionString { } } - [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Data Source=(local);Database=Customers;User Id=admin;Password=password;")] public string CustomerConnectionString { get { return ((string)(this["CustomerConnectionString"])); } - set { - this["CustomerConnectionString"] = value; + } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("\r\n\r\n UK: 0.2\r\n")] + public global::System.Collections.Specialized.StringCollection VatSettings { + get { + return ((global::System.Collections.Specialized.StringCollection)(this["VatSettings"])); } } } diff --git a/TechTest/AnyCompany/Properties/Settings.settings b/TechTest/AnyCompany/Properties/Settings.settings index 6ac0c01..715ce80 100644 --- a/TechTest/AnyCompany/Properties/Settings.settings +++ b/TechTest/AnyCompany/Properties/Settings.settings @@ -5,8 +5,14 @@ Data Source=(local);Database=Orders;User Id=admin;Password=password; - + Data Source=(local);Database=Customers;User Id=admin;Password=password; + + <?xml version="1.0" encoding="utf-16"?> +<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <string>UK:0.2</string> +</ArrayOfString> + \ No newline at end of file diff --git a/TechTest/AnyCompany/Services/OrderService.cs b/TechTest/AnyCompany/Services/OrderService.cs index 51b6fed..c596349 100644 --- a/TechTest/AnyCompany/Services/OrderService.cs +++ b/TechTest/AnyCompany/Services/OrderService.cs @@ -1,4 +1,5 @@ -using AnyCompany.Models; +using AnyCompany.Helpers; +using AnyCompany.Models; using AnyCompany.Repositories; namespace AnyCompany.Services @@ -14,10 +15,7 @@ public bool PlaceOrder(Order order, int customerId) if (order.Amount == 0) return false; - if (customer.Country == "UK") - order.VAT = 0.2d; - else - order.VAT = 0; + order.VAT = VatHelper.GetVatRateByCountry(customer.Country); orderRepository.Save(order); diff --git a/TechTest/AnyCompany/app.config b/TechTest/AnyCompany/app.config index 22d08aa..1f98457 100644 --- a/TechTest/AnyCompany/app.config +++ b/TechTest/AnyCompany/app.config @@ -4,22 +4,23 @@
- -
- Data Source=(local);Database=Orders;User Id=admin;Password=password; - - - - Data Source=(local);Database=Customers;User Id=admin;Password=password; + + + + UK: 0.2 + + + - + \ No newline at end of file From 4441d4ca72ad6804958b0facc0eec384409369e7 Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:14:30 +0200 Subject: [PATCH 05/11] Implemented class comments for simplification of class and method intention especially since this is a class library that will be used by other projects. --- TechTest/AnyCompany/Models/Customer.cs | 3 +++ TechTest/AnyCompany/Models/Order.cs | 3 +++ TechTest/AnyCompany/Repositories/CustomerRepository.cs | 7 +++++++ TechTest/AnyCompany/Repositories/OrderRepository.cs | 7 +++++++ TechTest/AnyCompany/Services/OrderService.cs | 8 ++++++++ 5 files changed, 28 insertions(+) diff --git a/TechTest/AnyCompany/Models/Customer.cs b/TechTest/AnyCompany/Models/Customer.cs index 08e21f8..d1259d6 100644 --- a/TechTest/AnyCompany/Models/Customer.cs +++ b/TechTest/AnyCompany/Models/Customer.cs @@ -2,6 +2,9 @@ namespace AnyCompany.Models { + /// + /// This is the Customer Model + /// public class Customer { public string Country { get; set; } diff --git a/TechTest/AnyCompany/Models/Order.cs b/TechTest/AnyCompany/Models/Order.cs index 8887aa7..5807dd9 100644 --- a/TechTest/AnyCompany/Models/Order.cs +++ b/TechTest/AnyCompany/Models/Order.cs @@ -1,5 +1,8 @@ namespace AnyCompany.Models { + /// + /// This is the Order Model + /// public class Order { public int OrderId { get; set; } diff --git a/TechTest/AnyCompany/Repositories/CustomerRepository.cs b/TechTest/AnyCompany/Repositories/CustomerRepository.cs index d47704e..02b10ff 100644 --- a/TechTest/AnyCompany/Repositories/CustomerRepository.cs +++ b/TechTest/AnyCompany/Repositories/CustomerRepository.cs @@ -4,8 +4,15 @@ namespace AnyCompany.Repositories { + /// + /// This is the Customer Repository, responsible for managing customer persistance and retrieval. + /// public static class CustomerRepository { + /// + /// This loads a Customer object. + /// + /// The Id of the customer this order is placed agains. public static Customer Load(int customerId) { Customer customer = new Customer(); diff --git a/TechTest/AnyCompany/Repositories/OrderRepository.cs b/TechTest/AnyCompany/Repositories/OrderRepository.cs index 1626750..4c74fae 100644 --- a/TechTest/AnyCompany/Repositories/OrderRepository.cs +++ b/TechTest/AnyCompany/Repositories/OrderRepository.cs @@ -3,8 +3,15 @@ namespace AnyCompany.Repositories { + /// + /// This is the OrderRepository Repository, responsible for managing customer persistance and retrieval. + /// internal class OrderRepository { + /// + /// This stores an Order object. + /// + /// The order information. public void Save(Order order) { SqlConnection connection = new SqlConnection(Properties.Settings.Default.OrderConnectionString); diff --git a/TechTest/AnyCompany/Services/OrderService.cs b/TechTest/AnyCompany/Services/OrderService.cs index c596349..19f2a86 100644 --- a/TechTest/AnyCompany/Services/OrderService.cs +++ b/TechTest/AnyCompany/Services/OrderService.cs @@ -4,10 +4,18 @@ namespace AnyCompany.Services { + /// + /// This is the Order Service, and main entry point for this library. Orders are managed from here. + /// public class OrderService { private readonly OrderRepository orderRepository = new OrderRepository(); + /// + /// This places and persists an order. + /// + /// The order information. + /// The Id of the customer this order is placed agains. public bool PlaceOrder(Order order, int customerId) { Customer customer = CustomerRepository.Load(customerId); From f2c76325a31cd3d231df7364c53acdd116784e46 Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:18:20 +0200 Subject: [PATCH 06/11] Implemented linking code between Customers and Orders. --- TechTest/AnyCompany/Models/Customer.cs | 2 ++ TechTest/AnyCompany/Models/Order.cs | 2 ++ TechTest/AnyCompany/Repositories/CustomerRepository.cs | 1 + TechTest/AnyCompany/Services/OrderService.cs | 6 +++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/TechTest/AnyCompany/Models/Customer.cs b/TechTest/AnyCompany/Models/Customer.cs index d1259d6..047d3a3 100644 --- a/TechTest/AnyCompany/Models/Customer.cs +++ b/TechTest/AnyCompany/Models/Customer.cs @@ -7,6 +7,8 @@ namespace AnyCompany.Models /// public class Customer { + public int CustomerId { get; set; } + public string Country { get; set; } public DateTime DateOfBirth { get; set; } diff --git a/TechTest/AnyCompany/Models/Order.cs b/TechTest/AnyCompany/Models/Order.cs index 5807dd9..d48ae45 100644 --- a/TechTest/AnyCompany/Models/Order.cs +++ b/TechTest/AnyCompany/Models/Order.cs @@ -8,5 +8,7 @@ public class Order public int OrderId { get; set; } public double Amount { get; set; } public double VAT { get; set; } + + public int CustomerId { get; set; } } } diff --git a/TechTest/AnyCompany/Repositories/CustomerRepository.cs b/TechTest/AnyCompany/Repositories/CustomerRepository.cs index 02b10ff..245f76c 100644 --- a/TechTest/AnyCompany/Repositories/CustomerRepository.cs +++ b/TechTest/AnyCompany/Repositories/CustomerRepository.cs @@ -28,6 +28,7 @@ public static Customer Load(int customerId) while (reader.Read()) { + customer.CustomerId = int.Parse(reader["CustomerId"].ToString()); customer.Name = reader["Name"].ToString(); customer.DateOfBirth = DateTime.Parse(reader["DateOfBirth"].ToString()); customer.Country = reader["Country"].ToString(); diff --git a/TechTest/AnyCompany/Services/OrderService.cs b/TechTest/AnyCompany/Services/OrderService.cs index 19f2a86..7a13bcb 100644 --- a/TechTest/AnyCompany/Services/OrderService.cs +++ b/TechTest/AnyCompany/Services/OrderService.cs @@ -1,6 +1,7 @@ using AnyCompany.Helpers; using AnyCompany.Models; using AnyCompany.Repositories; +using System; namespace AnyCompany.Services { @@ -20,11 +21,14 @@ public bool PlaceOrder(Order order, int customerId) { Customer customer = CustomerRepository.Load(customerId); + if (customer == null) + throw new ArgumentException("Customer could not be loaded. Invalid customer Id."); + if (order.Amount == 0) return false; order.VAT = VatHelper.GetVatRateByCountry(customer.Country); - + order.CustomerId = customer.CustomerId; orderRepository.Save(order); return true; From 30e973b075236946ca8ec928ba080b00e373022b Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:33:31 +0200 Subject: [PATCH 07/11] Implemented customer orders sublist. --- TechTest/AnyCompany/Models/Customer.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/TechTest/AnyCompany/Models/Customer.cs b/TechTest/AnyCompany/Models/Customer.cs index 047d3a3..a7cadc3 100644 --- a/TechTest/AnyCompany/Models/Customer.cs +++ b/TechTest/AnyCompany/Models/Customer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace AnyCompany.Models { @@ -14,5 +15,12 @@ public class Customer public DateTime DateOfBirth { get; set; } public string Name { get; set; } + + public List Orders { get; set; } + + public Customer() + { + Orders = new List(); + } } } From bc33d4b532c85ca6d777acae441edac8c247e618 Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:33:55 +0200 Subject: [PATCH 08/11] Implemented customer GetAll functionality. --- .../Repositories/CustomerRepository.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/TechTest/AnyCompany/Repositories/CustomerRepository.cs b/TechTest/AnyCompany/Repositories/CustomerRepository.cs index 245f76c..dc275b2 100644 --- a/TechTest/AnyCompany/Repositories/CustomerRepository.cs +++ b/TechTest/AnyCompany/Repositories/CustomerRepository.cs @@ -1,5 +1,6 @@ using AnyCompany.Models; using System; +using System.Collections.Generic; using System.Data.SqlClient; namespace AnyCompany.Repositories @@ -38,5 +39,32 @@ public static Customer Load(int customerId) return customer; } + + public static List GetAll() + { + List customers = new List(); + + SqlConnection connection = new SqlConnection(Properties.Settings.Default.CustomerConnectionString); + connection.Open(); + + SqlCommand command = new SqlCommand("SELECT * FROM Customer", connection); + + var reader = command.ExecuteReader(); + + while (reader.Read()) + { + customers.Add(new Customer() + { + CustomerId = int.Parse(reader["CustomerId"].ToString()), + Name = reader["Name"].ToString(), + DateOfBirth = DateTime.Parse(reader["DateOfBirth"].ToString()), + Country = reader["Country"].ToString() + }); + } + + connection.Close(); + + return customers; + } } } From 6e20f147ac7712c81df011fc4d6966a2a76cb52a Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:34:26 +0200 Subject: [PATCH 09/11] Implemented order GetByCustomerId functionality. --- .../Repositories/OrderRepository.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/TechTest/AnyCompany/Repositories/OrderRepository.cs b/TechTest/AnyCompany/Repositories/OrderRepository.cs index 4c74fae..b1a498b 100644 --- a/TechTest/AnyCompany/Repositories/OrderRepository.cs +++ b/TechTest/AnyCompany/Repositories/OrderRepository.cs @@ -1,4 +1,5 @@ using AnyCompany.Models; +using System.Collections.Generic; using System.Data.SqlClient; namespace AnyCompany.Repositories @@ -17,15 +18,45 @@ public void Save(Order order) SqlConnection connection = new SqlConnection(Properties.Settings.Default.OrderConnectionString); connection.Open(); - SqlCommand command = new SqlCommand("INSERT INTO Orders VALUES (@OrderId, @Amount, @VAT)", connection); + SqlCommand command = new SqlCommand("INSERT INTO Orders VALUES (@OrderId, @Amount, @VAT, @CustomerId)", connection); command.Parameters.AddWithValue("@OrderId", order.OrderId); command.Parameters.AddWithValue("@Amount", order.Amount); command.Parameters.AddWithValue("@VAT", order.VAT); + command.Parameters.AddWithValue("@CustomerId", order.CustomerId); command.ExecuteNonQuery(); connection.Close(); } + + public List GetAllByCustomerId(int customerId) + { + List orders = new List(); + + SqlConnection connection = new SqlConnection(Properties.Settings.Default.CustomerConnectionString); + connection.Open(); + + SqlCommand command = new SqlCommand("SELECT * FROM Orders WHERE CustomerId = @CustomerId", connection); + + command.Parameters.AddWithValue("@CustomerId", customerId); + + var reader = command.ExecuteReader(); + + while (reader.Read()) + { + orders.Add(new Order() + { + OrderId = int.Parse(reader["OrderId"].ToString()), + Amount = double.Parse(reader["Amount"].ToString()), + VAT = double.Parse(reader["VAT"].ToString()), + CustomerId = int.Parse(reader["CustomerId"].ToString()) + }); + } + + connection.Close(); + + return orders; + } } } From 496882b5a720bfcd15534ed66d95aaa11ee346dc Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:34:46 +0200 Subject: [PATCH 10/11] Implemented ListCustomers() service functionality. --- TechTest/AnyCompany/Services/OrderService.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/TechTest/AnyCompany/Services/OrderService.cs b/TechTest/AnyCompany/Services/OrderService.cs index 7a13bcb..6093c48 100644 --- a/TechTest/AnyCompany/Services/OrderService.cs +++ b/TechTest/AnyCompany/Services/OrderService.cs @@ -2,6 +2,7 @@ using AnyCompany.Models; using AnyCompany.Repositories; using System; +using System.Collections.Generic; namespace AnyCompany.Services { @@ -33,5 +34,20 @@ public bool PlaceOrder(Order order, int customerId) return true; } + + public List ListCustomers() + { + // Fetch all customers from the customer database + List customers = CustomerRepository.GetAll(); + + // Now, fetch all orders for each customer from the orders database + // This method is slow due to a unique call per customer. A future update should perhaps investigate passing a list of customers, and splitting in memory after retrieval. + foreach (Customer customer in customers) + { + customer.Orders = orderRepository.GetAllByCustomerId(customer.CustomerId); + } + + return customers; + } } } From 2b2e5ac7b181b76b12d5fc70e967d1a4e522781b Mon Sep 17 00:00:00 2001 From: Paul van Coller Date: Tue, 28 Jan 2020 06:39:43 +0200 Subject: [PATCH 11/11] Made order loading optional on customer list. --- TechTest/AnyCompany/Services/OrderService.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/TechTest/AnyCompany/Services/OrderService.cs b/TechTest/AnyCompany/Services/OrderService.cs index 6093c48..3154455 100644 --- a/TechTest/AnyCompany/Services/OrderService.cs +++ b/TechTest/AnyCompany/Services/OrderService.cs @@ -35,16 +35,19 @@ public bool PlaceOrder(Order order, int customerId) return true; } - public List ListCustomers() + public List ListCustomers(bool includeOrders) { // Fetch all customers from the customer database List customers = CustomerRepository.GetAll(); // Now, fetch all orders for each customer from the orders database // This method is slow due to a unique call per customer. A future update should perhaps investigate passing a list of customers, and splitting in memory after retrieval. - foreach (Customer customer in customers) + if (includeOrders) { - customer.Orders = orderRepository.GetAllByCustomerId(customer.CustomerId); + foreach (Customer customer in customers) + { + customer.Orders = orderRepository.GetAllByCustomerId(customer.CustomerId); + } } return customers;