From 95af33640495aaf2bee80c69902079d78c1b4c33 Mon Sep 17 00:00:00 2001 From: Unai Date: Mon, 21 Nov 2016 12:41:36 +0100 Subject: [PATCH 01/10] Remove old code and projects. Add MediatR. Added first commands. Review Entities and domain. Create queries --- eShopOnContainers.sln | 80 +++++++---- src/Services/Catalog/Catalog.API/Startup.cs | 10 +- src/Services/Catalog/Catalog.API/project.json | 1 + .../Ordering/Ordering.API/.vscode/launch.json | 41 ------ .../Ordering/Ordering.API/.vscode/tasks.json | 16 --- .../Controllers/EnvironmentInfoController.cs | 23 ---- .../Controllers/OrderingController.cs | 129 ------------------ .../Controllers/OrdersController.cs | 97 +++++++++++++ .../20160913204939_Migration1.Designer.cs | 121 ---------------- .../Migrations/20160913204939_Migration1.cs | 123 ----------------- ...61005002014_Migration_Baseline.Designer.cs | 121 ---------------- .../20161005002014_Migration_Baseline.cs | 19 --- .../20161005003321_Migration_Cero.Designer.cs | 121 ---------------- .../20161005003321_Migration_Cero.cs | 19 --- .../20161011040943_Migration2.Designer.cs | 123 ----------------- .../Migrations/20161011040943_Migration2.cs | 24 ---- .../20161011041130_Migration3.Designer.cs | 123 ----------------- .../Migrations/20161011041130_Migration3.cs | 19 --- .../OrderingDbContextModelSnapshot.cs | 122 ----------------- src/Services/Ordering/Ordering.API/Startup.cs | 56 ++++---- .../Ordering/Ordering.API/project.json | 7 +- .../Commands/CancelOrderRequest.cs | 15 ++ .../Commands/CancelOrderRequestHandler.cs | 15 ++ .../Commands/NewOrderREquestHandler.cs | 15 ++ .../Commands/NewOrderRequest.cs | 12 ++ .../Ordering.Application.xproj | 19 +++ .../Properties/AssemblyInfo.cs | 19 +++ .../Queries/IOrderQueries.cs | 11 ++ .../Queries/OrderQueries.cs | 13 ++ .../Ordering.Application/project.json | 16 +++ .../Ordering/Ordering.Domain/Address.cs | 29 ++++ .../AggregatesModel/Buyer/Buyer.cs | 49 ------- .../AggregatesModel/Order/Address.cs | 70 ---------- .../AggregatesModel/Order/Order.cs | 112 --------------- .../AggregatesModel/Order/OrderItem.cs | 33 ----- .../AggregatesModel/Order/OrderStatus.cs | 18 --- .../Ordering/Ordering.Domain/Buyer.cs | 12 ++ .../Contracts/IBuyerRepository.cs | 15 -- .../Contracts/IOrderRepository.cs | 20 --- .../Ordering/Ordering.Domain/Order.cs | 30 ++++ .../Ordering/Ordering.Domain/OrderItem.cs | 25 ++++ .../Ordering/Ordering.Domain/OrderStatus.cs | 59 ++++++++ .../Ordering.Domain/SeedWork/Entity.cs | 74 ++-------- .../SeedWork/IdentityGenerator.cs | 47 ------- .../Ordering.Domain/SeedWork/ValueObject.cs | 50 ++----- .../Queries/IOrderdingQueries.cs | 24 ---- .../Queries/OrderingQueries.cs | 98 ------------- .../Repositories/OrderRepository.cs | 51 ------- 48 files changed, 503 insertions(+), 1843 deletions(-) delete mode 100644 src/Services/Ordering/Ordering.API/.vscode/launch.json delete mode 100644 src/Services/Ordering/Ordering.API/.vscode/tasks.json delete mode 100644 src/Services/Ordering/Ordering.API/Controllers/EnvironmentInfoController.cs delete mode 100644 src/Services/Ordering/Ordering.API/Controllers/OrderingController.cs create mode 100644 src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.Designer.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.Designer.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.Designer.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.Designer.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.Designer.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.cs delete mode 100644 src/Services/Ordering/Ordering.API/Migrations/OrderingDbContextModelSnapshot.cs create mode 100644 src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequest.cs create mode 100644 src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequestHandler.cs create mode 100644 src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs create mode 100644 src/Services/Ordering/Ordering.Application/Commands/NewOrderRequest.cs create mode 100644 src/Services/Ordering/Ordering.Application/Ordering.Application.xproj create mode 100644 src/Services/Ordering/Ordering.Application/Properties/AssemblyInfo.cs create mode 100644 src/Services/Ordering/Ordering.Application/Queries/IOrderQueries.cs create mode 100644 src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs create mode 100644 src/Services/Ordering/Ordering.Application/project.json create mode 100644 src/Services/Ordering/Ordering.Domain/Address.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/AggregatesModel/Buyer/Buyer.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Address.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Order.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderItem.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderStatus.cs create mode 100644 src/Services/Ordering/Ordering.Domain/Buyer.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/Contracts/IBuyerRepository.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/Contracts/IOrderRepository.cs create mode 100644 src/Services/Ordering/Ordering.Domain/Order.cs create mode 100644 src/Services/Ordering/Ordering.Domain/OrderItem.cs create mode 100644 src/Services/Ordering/Ordering.Domain/OrderStatus.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/SeedWork/IdentityGenerator.cs delete mode 100644 src/Services/Ordering/Ordering.SqlData/Queries/IOrderdingQueries.cs delete mode 100644 src/Services/Ordering/Ordering.SqlData/Queries/OrderingQueries.cs delete mode 100644 src/Services/Ordering/Ordering.SqlData/Repositories/OrderRepository.cs diff --git a/eShopOnContainers.sln b/eShopOnContainers.sln index 5fe74cfe3..f21b21491 100644 --- a/eShopOnContainers.sln +++ b/eShopOnContainers.sln @@ -32,8 +32,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.API", "src\Service EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Domain", "src\Services\Ordering\Ordering.Domain\Ordering.Domain.xproj", "{F5598DCB-6DDE-4661-AD9D-A55612DA7E76}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.SqlData", "src\Services\Ordering\Ordering.SqlData\Ordering.SqlData.xproj", "{5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A857AD10-40FF-4303-BEC2-FF1C58D5735E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{EF0337F2-ED00-4643-89FD-EE10863F1870}" @@ -60,6 +58,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{9CC7 EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "eShopOnContainers.WebSPA", "src\Web\WebSPA\eShopOnContainers.WebSPA\eShopOnContainers.WebSPA.xproj", "{9842DB3A-1391-48C7-A49C-2FABD0A18AC2}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Application", "src\Services\Ordering\Ordering.Application\Ordering.Application.xproj", "{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -192,32 +192,6 @@ Global {F5598DCB-6DDE-4661-AD9D-A55612DA7E76}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {F5598DCB-6DDE-4661-AD9D-A55612DA7E76}.Release|x64.ActiveCfg = Release|Any CPU {F5598DCB-6DDE-4661-AD9D-A55612DA7E76}.Release|x86.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|ARM.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|x64.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.AppStore|x86.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|ARM.ActiveCfg = Debug|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|x64.ActiveCfg = Debug|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Debug|x86.ActiveCfg = Debug|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|Any CPU.Build.0 = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|ARM.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|iPhone.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|x64.ActiveCfg = Release|Any CPU - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D}.Release|x86.ActiveCfg = Release|Any CPU {A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU {A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -556,6 +530,54 @@ Global {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x64.Build.0 = Release|Any CPU {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x86.ActiveCfg = Release|Any CPU {9842DB3A-1391-48C7-A49C-2FABD0A18AC2}.Release|x86.Build.0 = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|ARM.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhone.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x64.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x64.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x86.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.AppStore|x86.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|ARM.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|ARM.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhone.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x64.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x64.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x86.ActiveCfg = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Debug|x86.Build.0 = Debug|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|Any CPU.Build.0 = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|ARM.ActiveCfg = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|ARM.Build.0 = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhone.ActiveCfg = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhone.Build.0 = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x64.ActiveCfg = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x64.Build.0 = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.ActiveCfg = Release|Any CPU + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -571,7 +593,6 @@ Global {42681D9D-750A-4DF7-BD9F-9292CFD5C253} = {326A7FB3-5295-468C-A4FE-67DCB823E1E5} {231226CE-690B-4979-8870-9A79D80928E2} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {F5598DCB-6DDE-4661-AD9D-A55612DA7E76} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} - {5DA6EF13-C7E0-4EC4-8599-A61C6AC2628D} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {EF0337F2-ED00-4643-89FD-EE10863F1870} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E} {A0AFC432-3846-4B4E-BD8E-3C8C896F4967} = {EF0337F2-ED00-4643-89FD-EE10863F1870} {48FC45C5-223F-4B59-AC77-6CBB1C561E85} = {932D8224-11F6-4D07-B109-DA28AD288A63} @@ -584,5 +605,6 @@ Global {778289CA-31F7-4464-8C2A-612EE846F8A7} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8} {9CC7814B-72A6-465B-A61C-57B512DEE303} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8} {9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} + {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} EndGlobalSection EndGlobal diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index 58b5ac7df..53cf8bbc2 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -18,8 +18,14 @@ var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile($"settings.json", optional: false, reloadOnChange: true) - .AddJsonFile($"settings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables(); + .AddJsonFile($"settings.{env.EnvironmentName}.json", optional: true); + + if (env.IsDevelopment()) + { + builder.AddUserSecrets(); + } + + builder.AddEnvironmentVariables(); Configuration = builder.Build(); } diff --git a/src/Services/Catalog/Catalog.API/project.json b/src/Services/Catalog/Catalog.API/project.json index 813301bd7..d7e16be9e 100644 --- a/src/Services/Catalog/Catalog.API/project.json +++ b/src/Services/Catalog/Catalog.API/project.json @@ -10,6 +10,7 @@ "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", + "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", diff --git a/src/Services/Ordering/Ordering.API/.vscode/launch.json b/src/Services/Ordering/Ordering.API/.vscode/launch.json deleted file mode 100644 index b311e1323..000000000 --- a/src/Services/Ordering/Ordering.API/.vscode/launch.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": ".NET Core Launch (web)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceRoot}\\bin\\Debug\\netcoreapp1.0\\Ordering.API.dll", - "args": [], - "cwd": "${workspaceRoot}", - "stopAtEntry": false, - "launchBrowser": { - "enabled": true, - "args": "${auto-detect-url}", - "windows": { - "command": "cmd.exe", - "args": "/C start ${auto-detect-url}" - }, - "osx": { - "command": "open" - }, - "linux": { - "command": "xdg-open" - } - }, - "env": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "sourceFileMap": { - "/Views": "${workspaceRoot}/Views" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach", - "processId": "${command.pickProcess}" - } - ] -} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/.vscode/tasks.json b/src/Services/Ordering/Ordering.API/.vscode/tasks.json deleted file mode 100644 index 9cd37c150..000000000 --- a/src/Services/Ordering/Ordering.API/.vscode/tasks.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": "0.1.0", - "command": "dotnet", - "isShellCommand": true, - "args": [], - "tasks": [ - { - "taskName": "build", - "args": [ - "${workspaceRoot}\\project.json" - ], - "isBuildCommand": true, - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Controllers/EnvironmentInfoController.cs b/src/Services/Ordering/Ordering.API/Controllers/EnvironmentInfoController.cs deleted file mode 100644 index ba4d56509..000000000 --- a/src/Services/Ordering/Ordering.API/Controllers/EnvironmentInfoController.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; - -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers -{ - [Route("api/[controller]")] - public class EnvironmentInfoController : Controller - { - // GET api/environmentInfo/machinename - [HttpGet("machinename")] - public dynamic GetMachineName() - { - return new - { - InstanceName = Environment.MachineName - }; - } - - } -} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrderingController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrderingController.cs deleted file mode 100644 index 6b9c4b2f2..000000000 --- a/src/Services/Ordering/Ordering.API/Controllers/OrderingController.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; - -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; -using Microsoft.EntityFrameworkCore; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries; - -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers -{ - [Route("api/[controller]")] - public class OrderingController : Controller - { - private IOrderRepository _orderRepository; - private IOrderdingQueries _queries; - - //private OrderingDbContext _context; - - public OrderingController(IOrderRepository orderRepository, - IOrderdingQueries orderingQueries //, - //OrderingDbContext context - ) - { - //Injected objects from the IoC container - _orderRepository = orderRepository; - _queries = orderingQueries; - //_context = context; - } - - - // GET api/ordering/orders - [HttpGet("orders")] - public async Task GetAllOrders() - { - dynamic response = await _queries.GetAllOrdersIncludingValueObjectsAndChildEntities(); - return Ok(response); - } - - - // GET api/ordering/orders/xxxGUIDxxxx - [HttpGet("orders/{orderId:Guid}")] - public async Task GetOrderById(Guid orderId) - { - dynamic response = await _queries.GetOrderById(orderId); - return Ok(response); - } - - //(CDLTLL) - Using parameters - //Alternate method if using several parameters instead of part of the URL - // GET api/ordering/orders/?orderId=xxxGUIDxxx&otherParam=value - //[HttpGet("orders")] - //public Order GetOrderByGuid([FromUri] Guid orderId, [FromUri] string otherParam) - - - // POST api/ordering/orders/create - [HttpPut("orders/create")] - public async Task Post([FromBody]Order order) - { - _orderRepository.Add(order); - int numChanges = await _orderRepository.UnitOfWork.CommitAsync(); - return Ok(numChanges); - } - - // PUT api/ordering/orders/xxxOrderGUIDxxxx/update - [HttpPut("orders/{orderId:Guid}/update")] - public async Task UpdateOrder(Guid orderID, [FromBody] Order orderToUpdate) - { - _orderRepository.Update(orderToUpdate); - int numChanges = await _orderRepository.UnitOfWork.CommitAsync(); - return Ok(numChanges); - } - - // DELETE api/ordering/orders/xxxOrderGUIDxxxx - [HttpDelete("orders/{orderId:Guid}/remove")] - public async Task Remove(Guid id) - { - await _orderRepository.Remove(id); - int numChanges = await _orderRepository.UnitOfWork.CommitAsync(); - return Ok(numChanges); - } - - - // GET api/ordering/orders/add_test_data_and_get_all - [HttpGet("orders/add_test_data_and_get_all")] - public async Task AddTestDataAndGetAllOrders() - { - //TEST ADDING ORDERS ********************************* - //Create generic Address ValueObject - Address sampleAddress = new Address("15703 NE 61st Ct.", - "Redmond", - "Washington", - "WA", - "United States", - "US", - "98052", - 47.661492, - -122.131309 - ); - //Create sample Orders - Order order1 = new Order(Guid.NewGuid(), sampleAddress, sampleAddress); - - //Add a few OrderItems - order1.AddNewOrderItem(Guid.NewGuid(), 2, 25, 30); - order1.AddNewOrderItem(Guid.NewGuid(), 1, 58, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 1, 60, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 3, 12, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 5, 3, 0); - - _orderRepository.Add(order1); - int numRecs = await _orderRepository.UnitOfWork.CommitAsync(); - - //_context.Orders.Add(order1); - //_context.SaveChanges(); - - //***************************************************** - - dynamic response = await _queries.GetAllOrdersIncludingValueObjectsAndChildEntities(); - return Ok(response); - } - - } - -} - - diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs new file mode 100644 index 000000000..b0806f71c --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -0,0 +1,97 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers +{ + using Application.Commands; + using Application.Queries; + using MediatR; + using Microsoft.AspNetCore.Mvc; + using System; + using System.Threading.Tasks; + + [Route("api/v1/[controller]")] + public class OrdersController : Controller + { + private readonly IMediator _mediator; + private readonly IOrderQueries _orderQueries; + + public OrdersController(IMediator mediator,IOrderQueries orderQueries) + { + if (mediator == null) + { + throw new ArgumentNullException(nameof(mediator)); + } + + if (orderQueries == null) + { + throw new ArgumentNullException(nameof(orderQueries)); + } + + _mediator = mediator; + _orderQueries = orderQueries; + } + + [Route("new")] + [HttpPost] + public async Task AddOrder() + { + var newOrderRequest = new NewOrderRequest(); + + var added = await _mediator.SendAsync(newOrderRequest); + + if (added) + { + return Ok(); + } + + return BadRequest(); + } + + + [Route("cancel/{orderId:int}")] + [HttpPost] + public async Task CancelOrder(int orderId) + { + var cancelOrderRequest = new CancelOrderRequest(orderId); + + var cancelled = await _mediator.SendAsync(cancelOrderRequest); + + if (cancelled) + { + return Ok(); + } + + return BadRequest(); + } + + + [Route("{orderId:int}")] + [HttpGet] + public async Task GetOrder(int orderId) + { + var order = await _orderQueries.GetOrder(orderId); + + if ( order != null) + { + Ok(order); + } + + return NotFound(); + } + + [Route("pending")] + [HttpGet] + public async Task GetPendingOrders(int orderId) + { + var orders = await _orderQueries.GetPendingOrders(); + + if (orders.Any()) + { + Ok(orders); + } + + return NoContent(); + } + } + +} + + diff --git a/src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.Designer.cs b/src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.Designer.cs deleted file mode 100644 index 68d9f6d9e..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.Designer.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; - -namespace Ordering.API.Migrations -{ - [DbContext(typeof(OrderingDbContext))] - [Migration("20160913204939_Migration1")] - partial class Migration1 - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") - .HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("CountryCode"); - - b.Property("Latitude"); - - b.Property("Longitude"); - - b.Property("State"); - - b.Property("StateCode"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("Address"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BillingAddressId"); - - b.Property("BuyerId"); - - b.Property("OrderDate"); - - b.Property("SequenceNumber") - .ValueGeneratedOnAdd() - .HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); - - b.Property("ShippingAddressId"); - - b.Property("Status"); - - b.HasKey("Id"); - - b.HasIndex("BillingAddressId"); - - b.HasIndex("ShippingAddressId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Discount"); - - b.Property("FulfillmentRemaining"); - - b.Property("OrderId"); - - b.Property("ProductId"); - - b.Property("Quantity"); - - b.Property("UnitPrice"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItem"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") - .WithMany() - .HasForeignKey("BillingAddressId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") - .WithMany() - .HasForeignKey("ShippingAddressId"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade); - }); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.cs b/src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.cs deleted file mode 100644 index 1d9dcc444..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20160913204939_Migration1.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Ordering.API.Migrations -{ - public partial class Migration1 : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.EnsureSchema( - name: "shared"); - - migrationBuilder.CreateSequence( - name: "OrderSequences", - schema: "shared", - startValue: 1001L); - - migrationBuilder.CreateTable( - name: "Address", - columns: table => new - { - Id = table.Column(nullable: false), - City = table.Column(nullable: true), - Country = table.Column(nullable: true), - CountryCode = table.Column(nullable: true), - Latitude = table.Column(nullable: false), - Longitude = table.Column(nullable: false), - State = table.Column(nullable: true), - StateCode = table.Column(nullable: true), - Street = table.Column(nullable: true), - ZipCode = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Address", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Orders", - columns: table => new - { - Id = table.Column(nullable: false), - BillingAddressId = table.Column(nullable: true), - BuyerId = table.Column(nullable: false), - OrderDate = table.Column(nullable: false), - SequenceNumber = table.Column(nullable: false, defaultValueSql: "NEXT VALUE FOR shared.OrderSequences"), - ShippingAddressId = table.Column(nullable: true), - Status = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Orders", x => x.Id); - table.ForeignKey( - name: "FK_Orders_Address_BillingAddressId", - column: x => x.BillingAddressId, - principalTable: "Address", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_Orders_Address_ShippingAddressId", - column: x => x.ShippingAddressId, - principalTable: "Address", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "OrderItem", - columns: table => new - { - Id = table.Column(nullable: false), - Discount = table.Column(nullable: false), - FulfillmentRemaining = table.Column(nullable: false), - OrderId = table.Column(nullable: false), - ProductId = table.Column(nullable: false), - Quantity = table.Column(nullable: false), - UnitPrice = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_OrderItem", x => x.Id); - table.ForeignKey( - name: "FK_OrderItem_Orders_OrderId", - column: x => x.OrderId, - principalTable: "Orders", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_Orders_BillingAddressId", - table: "Orders", - column: "BillingAddressId"); - - migrationBuilder.CreateIndex( - name: "IX_Orders_ShippingAddressId", - table: "Orders", - column: "ShippingAddressId"); - - migrationBuilder.CreateIndex( - name: "IX_OrderItem_OrderId", - table: "OrderItem", - column: "OrderId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropSequence( - name: "OrderSequences", - schema: "shared"); - - migrationBuilder.DropTable( - name: "OrderItem"); - - migrationBuilder.DropTable( - name: "Orders"); - - migrationBuilder.DropTable( - name: "Address"); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.Designer.cs b/src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.Designer.cs deleted file mode 100644 index c1408c1a3..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.Designer.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; - -namespace Ordering.API.Migrations -{ - [DbContext(typeof(OrderingDbContext))] - [Migration("20161005002014_Migration_Baseline")] - partial class Migration_Baseline - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") - .HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("CountryCode"); - - b.Property("Latitude"); - - b.Property("Longitude"); - - b.Property("State"); - - b.Property("StateCode"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("Address"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BillingAddressId"); - - b.Property("BuyerId"); - - b.Property("OrderDate"); - - b.Property("SequenceNumber") - .ValueGeneratedOnAdd() - .HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); - - b.Property("ShippingAddressId"); - - b.Property("Status"); - - b.HasKey("Id"); - - b.HasIndex("BillingAddressId"); - - b.HasIndex("ShippingAddressId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Discount"); - - b.Property("FulfillmentRemaining"); - - b.Property("OrderId"); - - b.Property("ProductId"); - - b.Property("Quantity"); - - b.Property("UnitPrice"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItem"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") - .WithMany() - .HasForeignKey("BillingAddressId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") - .WithMany() - .HasForeignKey("ShippingAddressId"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade); - }); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.cs b/src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.cs deleted file mode 100644 index ab54ddc1c..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161005002014_Migration_Baseline.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Ordering.API.Migrations -{ - public partial class Migration_Baseline : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.Designer.cs b/src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.Designer.cs deleted file mode 100644 index 23b3007c4..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.Designer.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; - -namespace Ordering.API.Migrations -{ - [DbContext(typeof(OrderingDbContext))] - [Migration("20161005003321_Migration_Cero")] - partial class Migration_Cero - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") - .HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("CountryCode"); - - b.Property("Latitude"); - - b.Property("Longitude"); - - b.Property("State"); - - b.Property("StateCode"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("Address"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BillingAddressId"); - - b.Property("BuyerId"); - - b.Property("OrderDate"); - - b.Property("SequenceNumber") - .ValueGeneratedOnAdd() - .HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); - - b.Property("ShippingAddressId"); - - b.Property("Status"); - - b.HasKey("Id"); - - b.HasIndex("BillingAddressId"); - - b.HasIndex("ShippingAddressId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Discount"); - - b.Property("FulfillmentRemaining"); - - b.Property("OrderId"); - - b.Property("ProductId"); - - b.Property("Quantity"); - - b.Property("UnitPrice"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItem"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") - .WithMany() - .HasForeignKey("BillingAddressId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") - .WithMany() - .HasForeignKey("ShippingAddressId"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade); - }); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.cs b/src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.cs deleted file mode 100644 index aec42924e..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161005003321_Migration_Cero.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Ordering.API.Migrations -{ - public partial class Migration_Cero : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.Designer.cs b/src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.Designer.cs deleted file mode 100644 index 9728a1902..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.Designer.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; - -namespace Ordering.API.Migrations -{ - [DbContext(typeof(OrderingDbContext))] - [Migration("20161011040943_Migration2")] - partial class Migration2 - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") - .HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("CountryCode"); - - b.Property("Latitude"); - - b.Property("Longitude"); - - b.Property("State"); - - b.Property("StateCode"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("Address"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BillingAddressId"); - - b.Property("BuyerId"); - - b.Property("OrderDate"); - - b.Property("SequenceNumber") - .ValueGeneratedOnAdd() - .HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); - - b.Property("ShippingAddressId"); - - b.Property("Status"); - - b.HasKey("Id"); - - b.HasIndex("BillingAddressId"); - - b.HasIndex("ShippingAddressId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Discount"); - - b.Property("FulfillmentRemaining"); - - b.Property("OrderId"); - - b.Property("ProductId"); - - b.Property("ProductName"); - - b.Property("Quantity"); - - b.Property("UnitPrice"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItem"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") - .WithMany() - .HasForeignKey("BillingAddressId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") - .WithMany() - .HasForeignKey("ShippingAddressId"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade); - }); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.cs b/src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.cs deleted file mode 100644 index caf45e9c0..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161011040943_Migration2.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Ordering.API.Migrations -{ - public partial class Migration2 : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "ProductName", - table: "OrderItem", - nullable: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "ProductName", - table: "OrderItem"); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.Designer.cs b/src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.Designer.cs deleted file mode 100644 index f0d76e51f..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.Designer.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; - -namespace Ordering.API.Migrations -{ - [DbContext(typeof(OrderingDbContext))] - [Migration("20161011041130_Migration3")] - partial class Migration3 - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") - .HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("CountryCode"); - - b.Property("Latitude"); - - b.Property("Longitude"); - - b.Property("State"); - - b.Property("StateCode"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("Address"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BillingAddressId"); - - b.Property("BuyerId"); - - b.Property("OrderDate"); - - b.Property("SequenceNumber") - .ValueGeneratedOnAdd() - .HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); - - b.Property("ShippingAddressId"); - - b.Property("Status"); - - b.HasKey("Id"); - - b.HasIndex("BillingAddressId"); - - b.HasIndex("ShippingAddressId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Discount"); - - b.Property("FulfillmentRemaining"); - - b.Property("OrderId"); - - b.Property("ProductId"); - - b.Property("ProductName"); - - b.Property("Quantity"); - - b.Property("UnitPrice"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItem"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") - .WithMany() - .HasForeignKey("BillingAddressId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") - .WithMany() - .HasForeignKey("ShippingAddressId"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade); - }); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.cs b/src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.cs deleted file mode 100644 index 3b3ae2b73..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/20161011041130_Migration3.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Ordering.API.Migrations -{ - public partial class Migration3 : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Migrations/OrderingDbContextModelSnapshot.cs b/src/Services/Ordering/Ordering.API/Migrations/OrderingDbContextModelSnapshot.cs deleted file mode 100644 index e7b7b4aaf..000000000 --- a/src/Services/Ordering/Ordering.API/Migrations/OrderingDbContextModelSnapshot.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; - -namespace Ordering.API.Migrations -{ - [DbContext(typeof(OrderingDbContext))] - partial class OrderingDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") - .HasAnnotation("Relational:Sequence:shared.OrderSequences", "'OrderSequences', 'shared', '1001', '1', '', '', 'Int32', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("CountryCode"); - - b.Property("Latitude"); - - b.Property("Longitude"); - - b.Property("State"); - - b.Property("StateCode"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("Address"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BillingAddressId"); - - b.Property("BuyerId"); - - b.Property("OrderDate"); - - b.Property("SequenceNumber") - .ValueGeneratedOnAdd() - .HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); - - b.Property("ShippingAddressId"); - - b.Property("Status"); - - b.HasKey("Id"); - - b.HasIndex("BillingAddressId"); - - b.HasIndex("ShippingAddressId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Discount"); - - b.Property("FulfillmentRemaining"); - - b.Property("OrderId"); - - b.Property("ProductId"); - - b.Property("ProductName"); - - b.Property("Quantity"); - - b.Property("UnitPrice"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItem"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "BillingAddress") - .WithMany() - .HasForeignKey("BillingAddressId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Address", "ShippingAddress") - .WithMany() - .HasForeignKey("ShippingAddressId"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderItem", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade); - }); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs index 8e003d8e5..4b5009663 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -1,21 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; -using Microsoft.EntityFrameworkCore; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Repositories; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries; - -namespace Microsoft.eShopOnContainers.Services.Ordering.API +namespace Microsoft.eShopOnContainers.Services.Ordering.API { + using MediatR; + using Microsoft.AspNetCore.Builder; + using Microsoft.AspNetCore.Hosting; + using Microsoft.EntityFrameworkCore; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; + public class Startup { public Startup(IHostingEnvironment env) @@ -37,27 +29,34 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API public IConfigurationRoot Configuration { get; } - // This method gets called by the runtime. - // Use this method to add services to the IoC container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); + //services.AddEntityFrameworkSqlServer() + // .AddDbContext(options => + // { + // options.UseSqlServer(Configuration["ConnectionString"]); + // }); - var connString = Configuration["ConnectionString"]; - - services.AddDbContext(options => + services.AddSwaggerGen(); + services.ConfigureSwaggerGen(options => { - options.UseSqlServer(connString) - .UseSqlServer(connString, b => b.MigrationsAssembly("Ordering.API")); + options.DescribeAllEnumsAsStrings(); + options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info() + { + Title = "Ordering HTTP API", + Version = "v1", + Description = "The Ordering Service HTTP API", + TermsOfService = "Terms Of Service" + }); }); - services.AddTransient(); - services.AddTransient(); + services.AddMediatR(typeof(Startup)); //TODO:pending + } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); @@ -69,6 +68,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API } app.UseMvc(); + + app.UseSwagger() + .UseSwaggerUi(); } } } diff --git a/src/Services/Ordering/Ordering.API/project.json b/src/Services/Ordering/Ordering.API/project.json index d5b415b26..31217732b 100644 --- a/src/Services/Ordering/Ordering.API/project.json +++ b/src/Services/Ordering/Ordering.API/project.json @@ -4,6 +4,8 @@ "version": "1.0.0", "type": "platform" }, + "MediatR.Extensions.Microsoft.DependencyInjection": "1.0.1", + "Microsoft.Extensions.DependencyInjection": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", @@ -20,8 +22,11 @@ "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0", "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", "Microsoft.AspNetCore.Diagnostics": "1.0.0", + "Ordering.Application": "1.0.0-*", "Ordering.Domain": "1.0.0-*", - "Ordering.SqlData": "1.0.0-*" + "Ordering.SqlData": "1.0.0-*", + "Swashbuckle": "6.0.0-beta902", + "MediatR": "2.1.0" }, "tools": { "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", diff --git a/src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequest.cs b/src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequest.cs new file mode 100644 index 000000000..b68dbd375 --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequest.cs @@ -0,0 +1,15 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands +{ + using MediatR; + + public class CancelOrderRequest + : IAsyncRequest + { + public int OrderId { get; private set; } + + public CancelOrderRequest(int orderId) + { + OrderId = orderId; + } + } +} diff --git a/src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequestHandler.cs b/src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequestHandler.cs new file mode 100644 index 000000000..4874c178f --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Commands/CancelOrderRequestHandler.cs @@ -0,0 +1,15 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands +{ + using MediatR; + using System; + using System.Threading.Tasks; + + public class CancelOrderRequestHandler + : IAsyncRequestHandler + { + public Task Handle(CancelOrderRequest message) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs b/src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs new file mode 100644 index 000000000..fceb7ef41 --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs @@ -0,0 +1,15 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands +{ + using MediatR; + using System; + using System.Threading.Tasks; + + public class NewOrderREquestHandler + : IAsyncRequestHandler + { + public Task Handle(NewOrderRequest message) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Services/Ordering/Ordering.Application/Commands/NewOrderRequest.cs b/src/Services/Ordering/Ordering.Application/Commands/NewOrderRequest.cs new file mode 100644 index 000000000..4dd5ac5bc --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Commands/NewOrderRequest.cs @@ -0,0 +1,12 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Commands +{ + using MediatR; + + public class NewOrderRequest + :IAsyncRequest + { + public NewOrderRequest() + { + } + } +} diff --git a/src/Services/Ordering/Ordering.Application/Ordering.Application.xproj b/src/Services/Ordering/Ordering.Application/Ordering.Application.xproj new file mode 100644 index 000000000..2c6ff9897 --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Ordering.Application.xproj @@ -0,0 +1,19 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 4193caa3-a1c3-4818-a06f-a2d85fde77e7 + Microsoft.eShopOnContainers.Services.Ordering.Application + .\obj + .\bin\ + v4.5.1 + + + 2.0 + + + \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.Application/Properties/AssemblyInfo.cs b/src/Services/Ordering/Ordering.Application/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a38e1f35b --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Ordering.Application")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4193caa3-a1c3-4818-a06f-a2d85fde77e7")] diff --git a/src/Services/Ordering/Ordering.Application/Queries/IOrderQueries.cs b/src/Services/Ordering/Ordering.Application/Queries/IOrderQueries.cs new file mode 100644 index 000000000..6b364a569 --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Queries/IOrderQueries.cs @@ -0,0 +1,11 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries +{ + using System.Threading.Tasks; + + public interface IOrderQueries + { + Task GetOrder(int id); + + Task GetPendingOrders(); + } +} diff --git a/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs b/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs new file mode 100644 index 000000000..3c2412ebc --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs @@ -0,0 +1,13 @@ + + +namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + public class OrderQueries + { + } +} diff --git a/src/Services/Ordering/Ordering.Application/project.json b/src/Services/Ordering/Ordering.Application/project.json new file mode 100644 index 000000000..814573611 --- /dev/null +++ b/src/Services/Ordering/Ordering.Application/project.json @@ -0,0 +1,16 @@ +{ + "version": "1.0.0-*", + + "dependencies": { + "NETStandard.Library": "1.6.0", + "MediatR": "2.1.0", + "System.Dynamic.Runtime": "4.0.11", + "Microsoft.CSharp": "4.0.1" + }, + + "frameworks": { + "netstandard1.6": { + "imports": "dnxcore50" + } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/Address.cs b/src/Services/Ordering/Ordering.Domain/Address.cs new file mode 100644 index 000000000..19e62d9ca --- /dev/null +++ b/src/Services/Ordering/Ordering.Domain/Address.cs @@ -0,0 +1,29 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain +{ + using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; + using System; + + public class Address + : Entity + { + public String Street { get; private set; } + + public String City { get; private set; } + + public String State { get; private set; } + + public String StateCode { get; private set; } + + public String Country { get; private set; } + + public String CountryCode { get; private set; } + + public String ZipCode { get; private set; } + + public double Latitude { get; private set; } + + public double Longitude { get; private set; } + + protected Address() { } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Buyer/Buyer.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/Buyer/Buyer.cs deleted file mode 100644 index b10b087c4..000000000 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Buyer/Buyer.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel -{ - public class Buyer : Entity, IAggregateRoot - { - public Buyer(Guid buyerId, string name, string lastName, string email, Address address, string phoneNumber) - { - this.Id = buyerId; - this.Name = name; - this.LastName = lastName; - this.Email = email; - this.Address = address; - this.PhoneNumber = phoneNumber; - } - - - public virtual string Name - { - get; - private set; - } - - public virtual string LastName - { - get; - private set; - } - - public virtual string Email - { - get; - private set; - } - - public virtual Address Address - { - get; - private set; - } - - public virtual string PhoneNumber - { - get; - private set; - } - } -} diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Address.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Address.cs deleted file mode 100644 index 9114b2f93..000000000 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Address.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; - -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel -{ - public class Address : ValueObject
- { - public Address(string street, - string city, - string state, - string stateCode, - string country, - string countryCode, - string zipCode, - double latitude = 0, - double longitude = 0 - ) - { - if (street == null) - throw new ArgumentNullException("street"); - - if (city == null) - throw new ArgumentNullException("city"); - - if (state == null) - throw new ArgumentNullException("state"); - - if (stateCode == null) - throw new ArgumentNullException("stateCode"); - - if (country == null) - throw new ArgumentNullException("country"); - - if (countryCode == null) - throw new ArgumentNullException("countryCode"); - - if (zipCode == null) - throw new ArgumentNullException("zipCode"); - - //Generate the ID guid - Remove this when EF Core supports ValueObjects - // https://github.com/aspnet/EntityFramework/issues/246 - this.Id = Guid.NewGuid(); - - this.Street = street; - this.City = city; - this.State = state; - this.StateCode = stateCode; - this.Country = country; - this.CountryCode = countryCode; - this.ZipCode = zipCode; - this.Latitude = latitude; - this.Longitude = longitude; - } - - //Infrastructure requisite - Parameterless constructor needed by EF - Address() { } - - public virtual String Street { get; private set; } - public virtual String City { get; private set; } - public virtual String State { get; private set; } - public virtual String StateCode { get; private set; } - public virtual String Country { get; private set; } - public virtual String CountryCode { get; private set; } - public virtual String ZipCode { get; private set; } - public virtual double Latitude { get; private set; } - public virtual double Longitude { get; private set; } - } -} diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Order.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Order.cs deleted file mode 100644 index 069afa981..000000000 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/Order.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel -{ - public class Order : Entity, IAggregateRoot - { - public Order(Guid buyerId, Address shippingAddress, Address billingAddress) - : this(buyerId, shippingAddress, billingAddress, DateTime.UtcNow) - { - } - - public Order(Guid buyerId, Address shippingAddress, Address billingAddress, DateTime orderDate) - { - this.BuyerId = buyerId; - this.ShippingAddress = shippingAddress; - this.BillingAddress = billingAddress; - this.OrderDate = orderDate; - - this.Status = OrderStatus.New; - } - - //Infrastructure requisite - Parameterless constructor needed by EF - Order() { } - - //Order ID comes derived from the Entity base class - - List _orderItems; - public virtual List OrderItems - { - get - { - if (_orderItems == null) - _orderItems = new List(); - - return _orderItems; - } - - private set - { - _orderItems = value; - } - } - - public string OrderNumber - { - get - { - return string.Format("{0}/{1}-{2}", OrderDate.Year, OrderDate.Month, SequenceNumber); - } - } - - public int SequenceNumber { get; set; } - - public virtual Guid BuyerId { get; private set; } - - public virtual Address ShippingAddress { get; private set; } - - public virtual Address BillingAddress { get; private set; } - - public virtual DateTime OrderDate { get; private set; } - - public virtual OrderStatus Status { get; private set; } - - //////////////////////////////////////////////////////////////////////////////////////// - //Domain Rules and Logic in Order Aggregate-Root (Sample of a "NO ANEMIC DOMAIN MODEL" ) - //////////////////////////////////////////////////////////////////////////////////////// - - public OrderItem AddNewOrderItem(Guid productId, int quantity, decimal unitPrice, decimal discount) - { - //check preconditions - if (productId == Guid.Empty) - throw new ArgumentNullException("productId"); - - if (quantity <= 0) - { - throw new ArgumentException("The quantity of Product in an Order cannot be equal or less than cero"); - } - - //check discount values - if (discount < 0) - discount = 0; - - if (discount > 100) - discount = 100; - - //create new order line - var newOrderItem = new OrderItem() - { - OrderId = this.Id, - ProductId = productId, - Quantity = quantity, - FulfillmentRemaining = quantity, - Discount = discount, - UnitPrice = unitPrice - }; - - //set identity - newOrderItem.GenerateNewIdentity(); - - //add order item - this.OrderItems.Add(newOrderItem); - - //return added orderline - return newOrderItem; - } - } -} diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderItem.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderItem.cs deleted file mode 100644 index e993f7117..000000000 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderItem.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Runtime.Serialization; - -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel -{ - public class OrderItem : Entity - { - public OrderItem() { } // Infrastructure. EF might need a plain constructor. Do not use. - - //NOTE: The OrderItem Id (Id) comes from the Entity base class - - public Guid ProductId { get; set; } - - public Guid OrderId { get; set; } - - public decimal UnitPrice { get; set; } - - public string ProductName { get; set; } - - public int Quantity { get; set; } - - public decimal Discount { get; set; } - - public int FulfillmentRemaining { get; set; } - - public override string ToString() - { - return String.Format("Product Id: {0}, Quantity: {1}, Fulfillment Remaing: {2}", this.Id, this.Quantity, this.FulfillmentRemaining); - } - } -} diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderStatus.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderStatus.cs deleted file mode 100644 index e48aaaaf1..000000000 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/Order/OrderStatus.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel -{ - public enum OrderStatus - { - Unknown, - New, - Submitted, - InProcess, - Backordered, - Shipped, - Canceled, - } -} diff --git a/src/Services/Ordering/Ordering.Domain/Buyer.cs b/src/Services/Ordering/Ordering.Domain/Buyer.cs new file mode 100644 index 000000000..40bb11499 --- /dev/null +++ b/src/Services/Ordering/Ordering.Domain/Buyer.cs @@ -0,0 +1,12 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain +{ + using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; + + public class Buyer + :Entity,IAggregateRoot + { + public string FullName { get; private set; } + + protected Buyer() { } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/Contracts/IBuyerRepository.cs b/src/Services/Ordering/Ordering.Domain/Contracts/IBuyerRepository.cs deleted file mode 100644 index fb5848ea8..000000000 --- a/src/Services/Ordering/Ordering.Domain/Contracts/IBuyerRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts -{ - public interface IBuyerRepository : IRepository - { - //TBD - To define Specific Actions Not In Base Repo - } -} diff --git a/src/Services/Ordering/Ordering.Domain/Contracts/IOrderRepository.cs b/src/Services/Ordering/Ordering.Domain/Contracts/IOrderRepository.cs deleted file mode 100644 index 7e30b3dc7..000000000 --- a/src/Services/Ordering/Ordering.Domain/Contracts/IOrderRepository.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts -{ - public interface IOrderRepository : IRepository - { - void Add(Order order); - void Update(Order order); - Task Remove(Guid id); - Task FindAsync(Guid id); - } -} - diff --git a/src/Services/Ordering/Ordering.Domain/Order.cs b/src/Services/Ordering/Ordering.Domain/Order.cs new file mode 100644 index 000000000..547d44148 --- /dev/null +++ b/src/Services/Ordering/Ordering.Domain/Order.cs @@ -0,0 +1,30 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain +{ + using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; + using System; + using System.Collections.Generic; + + public class Order + :Entity, IAggregateRoot + { + public int BuyerId { get; private set; } + + public Buyer Buyer { get; private set; } + + public DateTime OrderDate { get; private set; } + + public OrderStatus Status { get; private set; } + + public ICollection OrderItems { get; set; } + + public int ShippingAddressId { get; private set; } + + public Address ShippingAddress { get; private set; } + + public int BillingAddressId { get; private set; } + + public Address BillingAddress { get; private set; } + + protected Order() { } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/OrderItem.cs b/src/Services/Ordering/Ordering.Domain/OrderItem.cs new file mode 100644 index 000000000..2701ad9af --- /dev/null +++ b/src/Services/Ordering/Ordering.Domain/OrderItem.cs @@ -0,0 +1,25 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain +{ + using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; + + + public class OrderItem + :Entity + { + public int ProductId { get; private set; } + + public string ProductName { get; private set; } + + public int OrderId { get; private set; } + + public decimal UnitPrice { get; private set; } + + public decimal Discount { get; private set; } + + public int Units { get; private set; } + + protected OrderItem() + { + } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/OrderStatus.cs b/src/Services/Ordering/Ordering.Domain/OrderStatus.cs new file mode 100644 index 000000000..8a9faa511 --- /dev/null +++ b/src/Services/Ordering/Ordering.Domain/OrderStatus.cs @@ -0,0 +1,59 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain +{ + using SeedWork; + using System; + using System.Collections.Generic; + using System.Linq; + + public class OrderStatus + :Entity + { + public string Name { get; private set; } + + public static OrderStatus New = new OrderStatus(1, nameof(New).ToLowerInvariant()); + public static OrderStatus Submitted = new OrderStatus(1, nameof(Submitted).ToLowerInvariant()); + public static OrderStatus InProcess = new OrderStatus(1, nameof(InProcess).ToLowerInvariant()); + public static OrderStatus Shipped = new OrderStatus(1, nameof(Shipped).ToLowerInvariant()); + public static OrderStatus Canceled = new OrderStatus(1, nameof(Canceled).ToLowerInvariant()); + + protected OrderStatus() + { + } + + public OrderStatus(int id, string name) + { + Id = id; + Name = name; + } + + public static IEnumerable List() + { + return new[] { New, Submitted, InProcess, Shipped, Canceled }; + } + + public static OrderStatus FromName(string name) + { + var state = List() + .SingleOrDefault(s => String.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase)); + + if (state == null) + { + throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}"); + } + + return state; + } + + public static OrderStatus From(int id) + { + var state = List().SingleOrDefault(s => s.Id == id); + + if (state == null) + { + throw new ArgumentException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}"); + } + + return state; + } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs b/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs index 258b364e5..e5653ad28 100644 --- a/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs +++ b/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs @@ -1,24 +1,15 @@ -using System; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork { - /// - /// Base class for entities - /// + using System; + + public abstract class Entity { - //Members int? _requestedHashCode; - Guid _Id; - + int _Id; - //Properties - - /// - /// Get the persisten object identifier - /// - public virtual Guid Id + public virtual int Id { get { @@ -30,44 +21,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork } } - //Public Methods - - /// - /// Check if this entity is transient, ie, without identity at this moment - /// - /// True if entity is transient, else false public bool IsTransient() { - return this.Id == Guid.Empty; - } - - /// - /// Generate identity for this entity - /// - public void GenerateNewIdentity() - { - if ( IsTransient()) - this.Id = IdentityGenerator.NewSequentialGuid(); - } - - /// - /// Change current identity for a new non transient identity - /// - /// the new identity - public void ChangeCurrentIdentity(Guid identity) - { - if ( identity != Guid.Empty) - this.Id = identity; + return this.Id == default(Int32); } - - //Overrides Methods - - /// - /// - /// - /// - /// public override bool Equals(object obj) { if (obj == null || !(obj is Entity)) @@ -84,10 +42,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork return item.Id == this.Id; } - /// - /// - /// - /// public override int GetHashCode() { if (!IsTransient()) @@ -101,12 +55,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork return base.GetHashCode(); } - /// - /// equals operator - /// - /// left parameter - /// right parameter - /// true if equals + public static bool operator ==(Entity left, Entity right) { if (Object.Equals(left, null)) @@ -115,16 +64,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork return left.Equals(right); } - /// - /// Distinct operator - /// - /// left parameter - /// right parameter - /// True if different public static bool operator !=(Entity left, Entity right) { return !(left == right); } - } } diff --git a/src/Services/Ordering/Ordering.Domain/SeedWork/IdentityGenerator.cs b/src/Services/Ordering/Ordering.Domain/SeedWork/IdentityGenerator.cs deleted file mode 100644 index bc880ed78..000000000 --- a/src/Services/Ordering/Ordering.Domain/SeedWork/IdentityGenerator.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork -{ - internal static class IdentityGenerator - { - /// - /// This algorithm generates secuential GUIDs across system boundaries, ideal for databases - /// - /// - public static Guid NewSequentialGuid() - { - byte[] uid = Guid.NewGuid().ToByteArray(); - byte[] binDate = BitConverter.GetBytes(DateTime.UtcNow.Ticks); - - byte[] secuentialGuid = new byte[uid.Length]; - - secuentialGuid[0] = uid[0]; - secuentialGuid[1] = uid[1]; - secuentialGuid[2] = uid[2]; - secuentialGuid[3] = uid[3]; - secuentialGuid[4] = uid[4]; - secuentialGuid[5] = uid[5]; - secuentialGuid[6] = uid[6]; - // set the first part of the 8th byte to '1100' so - // later we'll be able to validate it was generated by us - - secuentialGuid[7] = (byte)(0xc0 | (0xf & uid[7])); - - // the last 8 bytes are sequential, - // it minimizes index fragmentation - // to a degree as long as there are not a large - // number of Secuential-Guids generated per millisecond - - secuentialGuid[9] = binDate[0]; - secuentialGuid[8] = binDate[1]; - secuentialGuid[15] = binDate[2]; - secuentialGuid[14] = binDate[3]; - secuentialGuid[13] = binDate[4]; - secuentialGuid[12] = binDate[5]; - secuentialGuid[11] = binDate[6]; - secuentialGuid[10] = binDate[7]; - - return new Guid(secuentialGuid); - } - } -} diff --git a/src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs b/src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs index 43b377183..3dc5fc4cd 100644 --- a/src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs +++ b/src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs @@ -1,16 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.Reflection; - + namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork { - /// - /// Base class for value objects in domain. - /// Value - /// - /// The type of this value object + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using System.Reflection; + + public class ValueObject : IEquatable where TValueObject : ValueObject { @@ -22,11 +19,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork //IEquatable and Override Equals operators - /// - /// - /// - /// - /// + public bool Equals(TValueObject other) { if ((object)other == null) @@ -62,11 +55,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork else return true; } - /// - /// - /// - /// - /// + public override bool Equals(object obj) { if ((object)obj == null) @@ -83,10 +72,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork return false; } - /// - /// - /// - /// + public override int GetHashCode() { int hashCode = 31; @@ -119,12 +105,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork return hashCode; } - /// - /// - /// - /// - /// - /// + public static bool operator ==(ValueObject left, ValueObject right) { if (Object.Equals(left, null)) @@ -133,12 +114,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork return left.Equals(right); } - /// - /// - /// - /// - /// - /// + public static bool operator !=(ValueObject left, ValueObject right) { return !(left == right); diff --git a/src/Services/Ordering/Ordering.SqlData/Queries/IOrderdingQueries.cs b/src/Services/Ordering/Ordering.SqlData/Queries/IOrderdingQueries.cs deleted file mode 100644 index 783cf7a47..000000000 --- a/src/Services/Ordering/Ordering.SqlData/Queries/IOrderdingQueries.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries -{ - //The OrderingQueries Contracts/Interfaces could be moved to a third assembly - //We're not putting this contract in the Domain layer assembly because - //queries/joins are just Application's needs and should not be limited - //to the Domain Model restrictions (Aggregates and Repositories restrictions). - // - //In this case we're using the same EF Context but another good approach - //is also to simply use SQL sentences for the queries with any Micro-ORM (like Dapper) or even just ADO.NET - // - //The point is that Queries are IDEMPOTENT and don't need to commit to DDD Domain restrictions - //so could be implemented in a completely orthogonal way in regards the Domain Layer (à la CQRS) - - public interface IOrderdingQueries - { - Task GetAllOrdersIncludingValueObjectsAndChildEntities(); - Task GetOrderById(Guid orderId); - } -} diff --git a/src/Services/Ordering/Ordering.SqlData/Queries/OrderingQueries.cs b/src/Services/Ordering/Ordering.SqlData/Queries/OrderingQueries.cs deleted file mode 100644 index c097acd82..000000000 --- a/src/Services/Ordering/Ordering.SqlData/Queries/OrderingQueries.cs +++ /dev/null @@ -1,98 +0,0 @@ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -using Microsoft.EntityFrameworkCore; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries; - -namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Queries -{ - //In this case, for the Application queries, we're using the same EF Context but another good approach - //is also to simply use SQL sentences for the queries with any Micro-ORM (like Dapper) or even just ADO.NET - // - //The point is that Queries are IDEMPOTENT and don't need to commit to DDD Domain restrictions - //so could be implemented in a completely orthogonal way in regards the Domain Layer (à la CQRS) - - public class OrderingQueries : IOrderdingQueries - { - private OrderingDbContext _dbContext; - - public OrderingQueries(OrderingDbContext orderingDbContext) - { - _dbContext = orderingDbContext; - } - - public async Task GetAllOrdersIncludingValueObjectsAndChildEntities() - { - var orders = await _dbContext.Orders - .Include(o => o.ShippingAddress) - .Include(o => o.BillingAddress) - .Include(o => o.OrderItems) - .ToListAsync(); - - // Dynamically generated a Response-Model that includes only the fields you need in the response. - // This keeps the JSON response minimal. - // Could also use var - dynamic response = orders.Select(o => new - { - id = o.Id, - orderNumber = o.OrderNumber, - buyerId = o.BuyerId, - orderDate = o.OrderDate, - status = o.Status, - shippingAddress = o.ShippingAddress, - billingAddress = o.BillingAddress, - orderItems = o.OrderItems.Select(i => new - { - id = i.Id, - productId = i.ProductId, - unitPrice = i.UnitPrice, - quantity = i.Quantity, - discount = i.Discount - } - ) - }); - - return response; - } - - public async Task GetOrderById(Guid orderId) - { - var order = await _dbContext.Orders - .Include(o => o.ShippingAddress) - .Include(o => o.BillingAddress) - .Include(o => o.OrderItems) - .Where(o => o.Id == orderId) - .SingleOrDefaultAsync(); - - // Dynamically generated a Response-Model that includes only the fields you need in the response. - // This keeps the JSON response minimal. - // Could also use var - dynamic response = new - { - id = order.Id, - orderNumber = order.OrderNumber, - buyerId = order.BuyerId, - orderDate = order.OrderDate, - status = order.Status, - shippingAddress = order.ShippingAddress, - billingAddress = order.BillingAddress, - orderItems = order.OrderItems.Select(i => new - { - id = i.Id, - productId = i.ProductId, - unitPrice = i.UnitPrice, - quantity = i.Quantity, - discount = i.Discount - } - ) - }; - - return response; - } - } -} diff --git a/src/Services/Ordering/Ordering.SqlData/Repositories/OrderRepository.cs b/src/Services/Ordering/Ordering.SqlData/Repositories/OrderRepository.cs deleted file mode 100644 index 7c8140d06..000000000 --- a/src/Services/Ordering/Ordering.SqlData/Repositories/OrderRepository.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; -using Microsoft.EntityFrameworkCore; - -namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.Repositories -{ - //1:1 relationship between Repository and Aggregate (i.e. OrderRepository and Order) - public class OrderRepository : IOrderRepository - { - private readonly OrderingDbContext _context; - - public IUnitOfWork UnitOfWork => _context; - - public OrderRepository(OrderingDbContext orderingDbContext) - { - _context = orderingDbContext; - } - - public void Add(Order order) - { - _context.Orders.Add(order); - } - - public void Update(Order order) - { - _context.Orders.Update(order); - } - - public async Task Remove(Guid orderId) - { - var orderToRemove = await _context.Orders.Where(o => o.Id == orderId).SingleOrDefaultAsync(); - _context.Orders.Remove(orderToRemove); - } - - public async Task FindAsync(Guid id) - { - if (id != Guid.Empty) - return await _context.Set().FirstOrDefaultAsync(o => o.Id == id); - else - return null; - } - } - -} From 1ae4d01f825d37755fa6edaeaa465a782717d374 Mon Sep 17 00:00:00 2001 From: Unai Date: Tue, 22 Nov 2016 18:40:47 +0100 Subject: [PATCH 02/10] More iteration on Ordering Refactoring --- eShopOnContainers.sln | 83 ++++-- global.json | 2 +- src/Console/eShopConsole/Program.cs | 88 +++--- src/Console/eShopConsole/project.json | 2 - src/Services/Catalog/Catalog.API/project.json | 3 +- .../20161122162602_initial.Designer.cs | 227 ++++++++++++++ .../Migrations/20161122162602_initial.cs | 282 ++++++++++++++++++ .../OrderingContextModelSnapshot.cs | 226 ++++++++++++++ .../Infrastructure/OrderingContextSeed.cs | 26 ++ src/Services/Ordering/Ordering.API/Startup.cs | 19 +- .../Ordering/Ordering.API/project.json | 24 +- .../Ordering/Ordering.API/settings.json | 2 +- .../Commands/NewOrderREquestHandler.cs | 2 +- .../Queries/OrderQueries.cs | 37 ++- .../Ordering.Application/project.json | 5 +- .../Ordering/Ordering.Domain/CardType.cs | 57 ++++ .../Ordering/Ordering.Domain/Order.cs | 10 +- .../Ordering/Ordering.Domain/Payment.cs | 27 ++ .../Ordering.Domain/SeedWork/ValueObject.cs | 126 -------- .../Ordering/Ordering.Domain/project.json | 4 +- .../Ordering.Infrastructure.xproj} | 6 +- .../OrderingContext.cs | 138 +++++++++ .../Properties/AssemblyInfo.cs | 4 +- .../Ordering.Infrastructure/project.json | 16 + .../UnitOfWork/DBContextUtil.cs | 50 ---- .../UnitOfWork/OrderingDbContext.cs | 82 ----- .../Ordering/Ordering.SqlData/project.json | 19 -- .../Ordering.Test/DataIntegrationTests.cs | 86 ------ test/Services/Ordering.Test/project.json | 8 +- 29 files changed, 1172 insertions(+), 489 deletions(-) create mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.Designer.cs create mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.cs create mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs create mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs create mode 100644 src/Services/Ordering/Ordering.Domain/CardType.cs create mode 100644 src/Services/Ordering/Ordering.Domain/Payment.cs delete mode 100644 src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs rename src/Services/Ordering/{Ordering.SqlData/Ordering.SqlData.xproj => Ordering.Infrastructure/Ordering.Infrastructure.xproj} (85%) create mode 100644 src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs rename src/Services/Ordering/{Ordering.SqlData => Ordering.Infrastructure}/Properties/AssemblyInfo.cs (82%) create mode 100644 src/Services/Ordering/Ordering.Infrastructure/project.json delete mode 100644 src/Services/Ordering/Ordering.SqlData/UnitOfWork/DBContextUtil.cs delete mode 100644 src/Services/Ordering/Ordering.SqlData/UnitOfWork/OrderingDbContext.cs delete mode 100644 src/Services/Ordering/Ordering.SqlData/project.json delete mode 100644 test/Services/Ordering.Test/DataIntegrationTests.cs diff --git a/eShopOnContainers.sln b/eShopOnContainers.sln index f21b21491..1097f51d2 100644 --- a/eShopOnContainers.sln +++ b/eShopOnContainers.sln @@ -38,10 +38,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{EF EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Test", "test\Services\Ordering.Test\Ordering.Test.xproj", "{A0AFC432-3846-4B4E-BD8E-3C8C896F4967}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Console App", "Console App", "{48FC45C5-223F-4B59-AC77-6CBB1C561E85}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "eShopConsole", "src\Console\eShopConsole\eShopConsole.xproj", "{C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "eShopOnContainers.WebMVC", "src\Web\WebMVC\eShopOnContainers.WebMVC.xproj", "{F0333D8E-0B27-42B7-B2C6-78F3657624E2}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "src\Mobile\eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{65116D1C-145B-4693-ABDA-F0FB6F425191}" @@ -60,6 +56,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "eShopOnContainers.WebSPA", EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Application", "src\Services\Ordering\Ordering.Application\Ordering.Application.xproj", "{4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ordering.Infrastructure", "src\Services\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.xproj", "{95F1F07C-4D92-4742-BD07-E5B805AAB651}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -218,32 +216,6 @@ Global {A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Release|x64.ActiveCfg = Release|Any CPU {A0AFC432-3846-4B4E-BD8E-3C8C896F4967}.Release|x86.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.AppStore|ARM.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.AppStore|x64.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.AppStore|x86.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Debug|ARM.ActiveCfg = Debug|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Debug|x64.ActiveCfg = Debug|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Debug|x86.ActiveCfg = Debug|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Release|Any CPU.Build.0 = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Release|ARM.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Release|iPhone.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Release|x64.ActiveCfg = Release|Any CPU - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7}.Release|x86.ActiveCfg = Release|Any CPU {F0333D8E-0B27-42B7-B2C6-78F3657624E2}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU {F0333D8E-0B27-42B7-B2C6-78F3657624E2}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU {F0333D8E-0B27-42B7-B2C6-78F3657624E2}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU @@ -578,6 +550,54 @@ Global {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x64.Build.0 = Release|Any CPU {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.ActiveCfg = Release|Any CPU {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7}.Release|x86.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|ARM.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhone.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x64.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x64.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x86.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.AppStore|x86.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|ARM.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|ARM.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhone.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x64.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x64.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x86.ActiveCfg = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Debug|x86.Build.0 = Debug|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|Any CPU.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|ARM.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|ARM.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhone.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhone.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x64.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x64.Build.0 = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x86.ActiveCfg = Release|Any CPU + {95F1F07C-4D92-4742-BD07-E5B805AAB651}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -595,8 +615,6 @@ Global {F5598DCB-6DDE-4661-AD9D-A55612DA7E76} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} {EF0337F2-ED00-4643-89FD-EE10863F1870} = {A857AD10-40FF-4303-BEC2-FF1C58D5735E} {A0AFC432-3846-4B4E-BD8E-3C8C896F4967} = {EF0337F2-ED00-4643-89FD-EE10863F1870} - {48FC45C5-223F-4B59-AC77-6CBB1C561E85} = {932D8224-11F6-4D07-B109-DA28AD288A63} - {C10C7B69-CE4F-4167-928E-33B7FA1DFFC7} = {48FC45C5-223F-4B59-AC77-6CBB1C561E85} {F0333D8E-0B27-42B7-B2C6-78F3657624E2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} {65116D1C-145B-4693-ABDA-F0FB6F425191} = {778289CA-31F7-4464-8C2A-612EE846F8A7} {62DBB163-9CA9-4818-B48B-13233DF37C24} = {9CC7814B-72A6-465B-A61C-57B512DEE303} @@ -606,5 +624,6 @@ Global {9CC7814B-72A6-465B-A61C-57B512DEE303} = {F61357CE-1CC2-410E-8776-B16EEBC98EB8} {9842DB3A-1391-48C7-A49C-2FABD0A18AC2} = {E279BF0F-7F66-4F3A-A3AB-2CDA66C1CD04} {4193CAA3-A1C3-4818-A06F-A2D85FDE77E7} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} + {95F1F07C-4D92-4742-BD07-E5B805AAB651} = {0BD0DB92-2D98-44D9-9AC0-C59186D59B0B} EndGlobalSection EndGlobal diff --git a/global.json b/global.json index bf6ec0487..c5112dcd4 100644 --- a/global.json +++ b/global.json @@ -7,6 +7,6 @@ ], "sdk": { - "version": "1.0.0-preview2-003121" + "version": "1.0.0-preview2-003131" } } diff --git a/src/Console/eShopConsole/Program.cs b/src/Console/eShopConsole/Program.cs index 7a97661a0..f647bc2d5 100644 --- a/src/Console/eShopConsole/Program.cs +++ b/src/Console/eShopConsole/Program.cs @@ -12,60 +12,60 @@ namespace eShopConsole { public static void Main(string[] args) { - // All contexts that share the same service provider will share the same database + //// All contexts that share the same service provider will share the same database - //Using InMemory DB - //var options = DbContextUtil.CreateNewContextOptionsForInMemoryDB(); + ////Using InMemory DB + ////var options = DbContextUtil.CreateNewContextOptionsForInMemoryDB(); - //Using Sql Server - var options = DbContextUtil.CreateNewContextOptionsForSqlDb(); + ////Using Sql Server + //var options = DbContextUtil.CreateNewContextOptionsForSqlDb(); - // Run the test against one instance of the context - using (var context = new OrderingDbContext(options)) - { - IOrderRepository orderRepository = new OrderRepository(context); + //// Run the test against one instance of the context + //using (var context = new OrderingDbContext(options)) + //{ + // IOrderRepository orderRepository = new OrderRepository(context); - //Create generic Address ValueObject - Address sampleAddress = new Address("15703 NE 61st Ct.", - "Redmond", - "Washington", - "WA", - "United States", - "US", - "98052", - 47.661492, - -122.131309 - ); - //Create sample Orders - Order order1 = new Order(Guid.NewGuid(), sampleAddress, sampleAddress); + // //Create generic Address ValueObject + // Address sampleAddress = new Address("15703 NE 61st Ct.", + // "Redmond", + // "Washington", + // "WA", + // "United States", + // "US", + // "98052", + // 47.661492, + // -122.131309 + // ); + // //Create sample Orders + // Order order1 = new Order(Guid.NewGuid(), sampleAddress, sampleAddress); - //Add a few OrderItems - order1.AddNewOrderItem(Guid.NewGuid(), 2, 25, 30); - order1.AddNewOrderItem(Guid.NewGuid(), 1, 58, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 1, 60, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 3, 12, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 5, 3, 0); + // //Add a few OrderItems + // order1.AddNewOrderItem(Guid.NewGuid(), 2, 25, 30); + // order1.AddNewOrderItem(Guid.NewGuid(), 1, 58, 0); + // order1.AddNewOrderItem(Guid.NewGuid(), 1, 60, 0); + // order1.AddNewOrderItem(Guid.NewGuid(), 3, 12, 0); + // order1.AddNewOrderItem(Guid.NewGuid(), 5, 3, 0); - orderRepository.Add(order1); - orderRepository.UnitOfWork.CommitAsync(); + // orderRepository.Add(order1); + // orderRepository.UnitOfWork.CommitAsync(); - //With no Async Repository - //context.Orders.Add(order1); - //context.SaveChanges(); + // //With no Async Repository + // //context.Orders.Add(order1); + // //context.SaveChanges(); - } + //} - //// Use a separate instance of the context to verify correct data was saved to database - using (var context = new OrderingDbContext(options)) - { - var orders = context.Orders - .Include(o => o.ShippingAddress) - .Include(o => o.BillingAddress) - .ToList(); + ////// Use a separate instance of the context to verify correct data was saved to database + //using (var context = new OrderingDbContext(options)) + //{ + // var orders = context.Orders + // .Include(o => o.ShippingAddress) + // .Include(o => o.BillingAddress) + // .ToList(); - string cityName = orders.First().ShippingAddress.City; - Console.WriteLine("City name retreived from SQL Server: "+cityName); - } + // string cityName = orders.First().ShippingAddress.City; + // Console.WriteLine("City name retreived from SQL Server: "+cityName); + //} } } } diff --git a/src/Console/eShopConsole/project.json b/src/Console/eShopConsole/project.json index 1b299277a..f953c60fe 100644 --- a/src/Console/eShopConsole/project.json +++ b/src/Console/eShopConsole/project.json @@ -10,9 +10,7 @@ "type": "platform", "version": "1.0.0" }, - "Ordering.API": "1.0.0-*", "Ordering.Domain": "1.0.0-*", - "Ordering.SqlData": "1.0.0-*" }, "frameworks": { "netcoreapp1.0": { diff --git a/src/Services/Catalog/Catalog.API/project.json b/src/Services/Catalog/Catalog.API/project.json index d7e16be9e..8297fb35b 100644 --- a/src/Services/Catalog/Catalog.API/project.json +++ b/src/Services/Catalog/Catalog.API/project.json @@ -54,5 +54,6 @@ "Dockerfile" ] }, - "scripts": {} + "scripts": {}, + "userSecretsId": "aspnet-Catalog.API-20161122013618" } \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.Designer.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.Designer.cs new file mode 100644 index 000000000..bc974dd75 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.Designer.cs @@ -0,0 +1,227 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; + +namespace Ordering.API.Infrastructure.Migrations +{ + [DbContext(typeof(OrderingContext))] + [Migration("20161122162602_initial")] + partial class initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.0.1") + .HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("City"); + + b.Property("Country"); + + b.Property("CountryCode"); + + b.Property("Latitude"); + + b.Property("Longitude"); + + b.Property("State"); + + b.Property("StateCode"); + + b.Property("Street"); + + b.Property("ZipCode"); + + b.HasKey("Id"); + + b.ToTable("address","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq") + .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("FullName") + .IsRequired() + .HasAnnotation("MaxLength", 200); + + b.HasKey("Id"); + + b.ToTable("buyers","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("cardtypes","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "orderseq") + .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("BillingAddressId"); + + b.Property("BuyerId"); + + b.Property("OrderDate"); + + b.Property("PaymentId"); + + b.Property("ShippingAddressId"); + + b.Property("StatusId"); + + b.HasKey("Id"); + + b.HasIndex("BillingAddressId"); + + b.HasIndex("BuyerId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("ShippingAddressId"); + + b.HasIndex("StatusId"); + + b.ToTable("orders","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Discount"); + + b.Property("OrderId"); + + b.Property("ProductId"); + + b.Property("ProductName") + .IsRequired(); + + b.Property("UnitPrice"); + + b.Property("Units") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:DefaultValue", 1); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("orderItems","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("orderstatus","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq") + .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CardHolderName") + .IsRequired() + .HasAnnotation("MaxLength", 200); + + b.Property("CardNumber") + .IsRequired() + .HasAnnotation("MaxLength", 25); + + b.Property("CardTypeId"); + + b.Property("Expiration"); + + b.Property("SecurityNumber"); + + b.HasKey("Id"); + + b.HasIndex("CardTypeId"); + + b.ToTable("payments","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => + { + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", "BillingAddress") + .WithMany() + .HasForeignKey("BillingAddressId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", "Buyer") + .WithMany() + .HasForeignKey("BuyerId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", "ShippingAddress") + .WithMany() + .HasForeignKey("ShippingAddressId"); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => + { + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order") + .WithMany("OrderItems") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => + { + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", "CardType") + .WithMany() + .HasForeignKey("CardTypeId") + .OnDelete(DeleteBehavior.Cascade); + }); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.cs new file mode 100644 index 000000000..b64a9b570 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161122162602_initial.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Metadata; + +namespace Ordering.API.Infrastructure.Migrations +{ + public partial class initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "ordering"); + + migrationBuilder.CreateSequence( + name: "buyerseq", + schema: "ordering", + incrementBy: 10); + + migrationBuilder.CreateSequence( + name: "orderseq", + schema: "ordering", + incrementBy: 10); + + migrationBuilder.CreateSequence( + name: "paymentseq", + schema: "ordering", + incrementBy: 10); + + migrationBuilder.CreateTable( + name: "address", + schema: "ordering", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + City = table.Column(nullable: true), + Country = table.Column(nullable: true), + CountryCode = table.Column(nullable: true), + Latitude = table.Column(nullable: false), + Longitude = table.Column(nullable: false), + State = table.Column(nullable: true), + StateCode = table.Column(nullable: true), + Street = table.Column(nullable: true), + ZipCode = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_address", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "buyers", + schema: "ordering", + columns: table => new + { + Id = table.Column(nullable: false), + FullName = table.Column(maxLength: 200, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_buyers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "cardtypes", + schema: "ordering", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + Name = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_cardtypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "orderstatus", + schema: "ordering", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + Name = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_orderstatus", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "payments", + schema: "ordering", + columns: table => new + { + Id = table.Column(nullable: false), + CardHolderName = table.Column(maxLength: 200, nullable: false), + CardNumber = table.Column(maxLength: 25, nullable: false), + CardTypeId = table.Column(nullable: false), + Expiration = table.Column(nullable: false), + SecurityNumber = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_payments", x => x.Id); + table.ForeignKey( + name: "FK_payments_cardtypes_CardTypeId", + column: x => x.CardTypeId, + principalSchema: "ordering", + principalTable: "cardtypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "orders", + schema: "ordering", + columns: table => new + { + Id = table.Column(nullable: false), + BillingAddressId = table.Column(nullable: true), + BuyerId = table.Column(nullable: false), + OrderDate = table.Column(nullable: false), + PaymentId = table.Column(nullable: false), + ShippingAddressId = table.Column(nullable: true), + StatusId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_orders", x => x.Id); + table.ForeignKey( + name: "FK_orders_address_BillingAddressId", + column: x => x.BillingAddressId, + principalSchema: "ordering", + principalTable: "address", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "FK_orders_buyers_BuyerId", + column: x => x.BuyerId, + principalSchema: "ordering", + principalTable: "buyers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_orders_payments_PaymentId", + column: x => x.PaymentId, + principalSchema: "ordering", + principalTable: "payments", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_orders_address_ShippingAddressId", + column: x => x.ShippingAddressId, + principalSchema: "ordering", + principalTable: "address", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_orders_orderstatus_StatusId", + column: x => x.StatusId, + principalSchema: "ordering", + principalTable: "orderstatus", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "orderItems", + schema: "ordering", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + Discount = table.Column(nullable: false), + OrderId = table.Column(nullable: false), + ProductId = table.Column(nullable: false), + ProductName = table.Column(nullable: false), + UnitPrice = table.Column(nullable: false), + Units = table.Column(nullable: false, defaultValue: 1) + }, + constraints: table => + { + table.PrimaryKey("PK_orderItems", x => x.Id); + table.ForeignKey( + name: "FK_orderItems_orders_OrderId", + column: x => x.OrderId, + principalSchema: "ordering", + principalTable: "orders", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_orders_BillingAddressId", + schema: "ordering", + table: "orders", + column: "BillingAddressId"); + + migrationBuilder.CreateIndex( + name: "IX_orders_BuyerId", + schema: "ordering", + table: "orders", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_orders_PaymentId", + schema: "ordering", + table: "orders", + column: "PaymentId"); + + migrationBuilder.CreateIndex( + name: "IX_orders_ShippingAddressId", + schema: "ordering", + table: "orders", + column: "ShippingAddressId"); + + migrationBuilder.CreateIndex( + name: "IX_orders_StatusId", + schema: "ordering", + table: "orders", + column: "StatusId"); + + migrationBuilder.CreateIndex( + name: "IX_orderItems_OrderId", + schema: "ordering", + table: "orderItems", + column: "OrderId"); + + migrationBuilder.CreateIndex( + name: "IX_payments_CardTypeId", + schema: "ordering", + table: "payments", + column: "CardTypeId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropSequence( + name: "buyerseq", + schema: "ordering"); + + migrationBuilder.DropSequence( + name: "orderseq", + schema: "ordering"); + + migrationBuilder.DropSequence( + name: "paymentseq", + schema: "ordering"); + + migrationBuilder.DropTable( + name: "orderItems", + schema: "ordering"); + + migrationBuilder.DropTable( + name: "orders", + schema: "ordering"); + + migrationBuilder.DropTable( + name: "address", + schema: "ordering"); + + migrationBuilder.DropTable( + name: "buyers", + schema: "ordering"); + + migrationBuilder.DropTable( + name: "payments", + schema: "ordering"); + + migrationBuilder.DropTable( + name: "orderstatus", + schema: "ordering"); + + migrationBuilder.DropTable( + name: "cardtypes", + schema: "ordering"); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs new file mode 100644 index 000000000..ac998114d --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs @@ -0,0 +1,226 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; + +namespace Ordering.API.Infrastructure.Migrations +{ + [DbContext(typeof(OrderingContext))] + partial class OrderingContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.0.1") + .HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("City"); + + b.Property("Country"); + + b.Property("CountryCode"); + + b.Property("Latitude"); + + b.Property("Longitude"); + + b.Property("State"); + + b.Property("StateCode"); + + b.Property("Street"); + + b.Property("ZipCode"); + + b.HasKey("Id"); + + b.ToTable("address","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq") + .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("FullName") + .IsRequired() + .HasAnnotation("MaxLength", 200); + + b.HasKey("Id"); + + b.ToTable("buyers","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("cardtypes","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "orderseq") + .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("BillingAddressId"); + + b.Property("BuyerId"); + + b.Property("OrderDate"); + + b.Property("PaymentId"); + + b.Property("ShippingAddressId"); + + b.Property("StatusId"); + + b.HasKey("Id"); + + b.HasIndex("BillingAddressId"); + + b.HasIndex("BuyerId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("ShippingAddressId"); + + b.HasIndex("StatusId"); + + b.ToTable("orders","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Discount"); + + b.Property("OrderId"); + + b.Property("ProductId"); + + b.Property("ProductName") + .IsRequired(); + + b.Property("UnitPrice"); + + b.Property("Units") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:DefaultValue", 1); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("orderItems","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("orderstatus","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq") + .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CardHolderName") + .IsRequired() + .HasAnnotation("MaxLength", 200); + + b.Property("CardNumber") + .IsRequired() + .HasAnnotation("MaxLength", 25); + + b.Property("CardTypeId"); + + b.Property("Expiration"); + + b.Property("SecurityNumber"); + + b.HasKey("Id"); + + b.HasIndex("CardTypeId"); + + b.ToTable("payments","ordering"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => + { + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", "BillingAddress") + .WithMany() + .HasForeignKey("BillingAddressId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", "Buyer") + .WithMany() + .HasForeignKey("BuyerId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", "ShippingAddress") + .WithMany() + .HasForeignKey("ShippingAddressId"); + + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => + { + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order") + .WithMany("OrderItems") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => + { + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", "CardType") + .WithMany() + .HasForeignKey("CardTypeId") + .OnDelete(DeleteBehavior.Cascade); + }); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs b/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs new file mode 100644 index 000000000..f16427b7a --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs @@ -0,0 +1,26 @@ + +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure +{ + using AspNetCore.Builder; + using Microsoft.EntityFrameworkCore; + using Ordering.Infrastructure; + using System.Threading.Tasks; + + + public class OrderingContextSeed + { + public static async Task SeedAsync(IApplicationBuilder applicationBuilder) + { + var context = (OrderingContext)applicationBuilder + .ApplicationServices.GetService(typeof(OrderingContext)); + + using (context) + { + context.Database.Migrate(); + + await context.SaveChangesAsync(); + } + } + + } +} diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs index 4b5009663..fe8d01f6e 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -7,6 +7,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; + using Ordering.Infrastructure; + using System.Reflection; public class Startup { @@ -14,8 +16,8 @@ { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); + .AddJsonFile("settings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"settings.{env.EnvironmentName}.json", optional: true); if (env.IsDevelopment()) { @@ -34,12 +36,13 @@ // Add framework services. services.AddMvc(); - //services.AddEntityFrameworkSqlServer() - // .AddDbContext(options => - // { - // options.UseSqlServer(Configuration["ConnectionString"]); - // }); - + services.AddEntityFrameworkSqlServer() + .AddDbContext(options => + { + options.UseSqlServer(Configuration["ConnectionString"], + sqlop=>sqlop.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name)); + }); + services.AddSwaggerGen(); services.ConfigureSwaggerGen(options => { diff --git a/src/Services/Ordering/Ordering.API/project.json b/src/Services/Ordering/Ordering.API/project.json index 31217732b..46249899f 100644 --- a/src/Services/Ordering/Ordering.API/project.json +++ b/src/Services/Ordering/Ordering.API/project.json @@ -1,11 +1,10 @@ { "dependencies": { "Microsoft.NETCore.App": { - "version": "1.0.0", + "version": "1.0.1", "type": "platform" }, "MediatR.Extensions.Microsoft.DependencyInjection": "1.0.1", - "Microsoft.Extensions.DependencyInjection": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", @@ -13,20 +12,20 @@ "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", - "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", - "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0", - "Microsoft.EntityFrameworkCore": "1.0.0", - "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0", - "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", + "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", + "Microsoft.EntityFrameworkCore": "1.0.1", + "Microsoft.EntityFrameworkCore.Design" : "1.0.0-preview2-final", + "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1", "Microsoft.AspNetCore.Diagnostics": "1.0.0", - "Ordering.Application": "1.0.0-*", - "Ordering.Domain": "1.0.0-*", - "Ordering.SqlData": "1.0.0-*", "Swashbuckle": "6.0.0-beta902", - "MediatR": "2.1.0" + "MediatR": "2.1.0", + "Ordering.Domain": "1.0.0-*", + "Ordering.Application": "1.0.0-*", + "Ordering.Infrastructure": "1.0.0-*", + "System.Reflection": "4.3.0" }, "tools": { "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", @@ -68,5 +67,6 @@ "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] - } + }, + "userSecretsId": "aspnet-Ordering.API-20161122013547" } \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/settings.json b/src/Services/Ordering/Ordering.API/settings.json index da778d1c4..a95b8262f 100644 --- a/src/Services/Ordering/Ordering.API/settings.json +++ b/src/Services/Ordering/Ordering.API/settings.json @@ -1,3 +1,3 @@ { - "ConnectionString": "Server=127.0.0.1;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;" + "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;" } diff --git a/src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs b/src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs index fceb7ef41..466f42ac6 100644 --- a/src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs +++ b/src/Services/Ordering/Ordering.Application/Commands/NewOrderREquestHandler.cs @@ -4,7 +4,7 @@ using System; using System.Threading.Tasks; - public class NewOrderREquestHandler + public class NewOrderRequestHandler : IAsyncRequestHandler { public Task Handle(NewOrderRequest message) diff --git a/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs b/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs index 3c2412ebc..0ab74090a 100644 --- a/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs +++ b/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs @@ -1,13 +1,38 @@ - - -namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries +namespace Microsoft.eShopOnContainers.Services.Ordering.Application.Queries { - using System; - using System.Collections.Generic; - using System.Linq; + using Dapper; + using Microsoft.Extensions.Configuration; + using System.Data.SqlClient; using System.Threading.Tasks; public class OrderQueries + :IOrderQueries { + private string _connectionString = string.Empty; + + public OrderQueries(IConfiguration configuration) + { + _connectionString = configuration["ConnectionString"]; + } + + public async Task GetOrder(int id) + { + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + return await connection.QueryAsync("SELECT * FROM ordering.Orders where Id=@id",new { id }); + } + } + + public async Task GetPendingOrders() + { + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + return await connection.QueryAsync("SELECT * FROM ordering.Orders"); + } + } } } diff --git a/src/Services/Ordering/Ordering.Application/project.json b/src/Services/Ordering/Ordering.Application/project.json index 814573611..c6531feaf 100644 --- a/src/Services/Ordering/Ordering.Application/project.json +++ b/src/Services/Ordering/Ordering.Application/project.json @@ -4,8 +4,11 @@ "dependencies": { "NETStandard.Library": "1.6.0", "MediatR": "2.1.0", + "Dapper": "1.50.2", "System.Dynamic.Runtime": "4.0.11", - "Microsoft.CSharp": "4.0.1" + "Microsoft.CSharp": "4.0.1", + "Microsoft.Extensions.Configuration": "1.0.0", + "System.Data.SqlClient": "4.1.0" }, "frameworks": { diff --git a/src/Services/Ordering/Ordering.Domain/CardType.cs b/src/Services/Ordering/Ordering.Domain/CardType.cs new file mode 100644 index 000000000..ca875321c --- /dev/null +++ b/src/Services/Ordering/Ordering.Domain/CardType.cs @@ -0,0 +1,57 @@ + + +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain +{ + using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; + using System; + using System.Collections.Generic; + using System.Linq; + + public class CardType + : Entity + { + public static CardType Amex = new CardType(1, "Amex"); + public static CardType Visa = new CardType(1, "Visa"); + public static CardType MasterCard = new CardType(1, "MasterCard"); + + public string Name { get; private set; } + + protected CardType() { } + + public CardType(int id, string name) + { + Id = id; + Name = name; + } + + public static IEnumerable List() + { + return new[] { Amex, Visa, MasterCard }; + } + + public static CardType FromName(string name) + { + var state = List() + .SingleOrDefault(s => String.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase)); + + if (state == null) + { + throw new ArgumentException($"Possible values for CardType: {String.Join(",", List().Select(s => s.Name))}"); + } + + return state; + } + + public static CardType From(int id) + { + var state = List().SingleOrDefault(s => s.Id == id); + + if (state == null) + { + throw new ArgumentException($"Possible values for CardType: {String.Join(",", List().Select(s => s.Name))}"); + } + + return state; + } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/Order.cs b/src/Services/Ordering/Ordering.Domain/Order.cs index 547d44148..e7bbefce5 100644 --- a/src/Services/Ordering/Ordering.Domain/Order.cs +++ b/src/Services/Ordering/Ordering.Domain/Order.cs @@ -13,18 +13,24 @@ public DateTime OrderDate { get; private set; } + public int StatusId { get; private set; } + public OrderStatus Status { get; private set; } public ICollection OrderItems { get; set; } - public int ShippingAddressId { get; private set; } + public int? ShippingAddressId { get; private set; } public Address ShippingAddress { get; private set; } - public int BillingAddressId { get; private set; } + public int? BillingAddressId { get; private set; } public Address BillingAddress { get; private set; } + public int PaymentId { get; private set; } + + public Payment Payment { get; private set; } + protected Order() { } } } diff --git a/src/Services/Ordering/Ordering.Domain/Payment.cs b/src/Services/Ordering/Ordering.Domain/Payment.cs new file mode 100644 index 000000000..ccf35e133 --- /dev/null +++ b/src/Services/Ordering/Ordering.Domain/Payment.cs @@ -0,0 +1,27 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain +{ + using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + + public class Payment + : Entity, IAggregateRoot + { + public string CardNumber { get; private set; } + + public string SecurityNumber { get; private set; } + + public string CardHolderName { get; private set; } + + public int CardTypeId { get; private set; } + + public CardType CardType { get; private set; } + + public DateTime Expiration { get; private set; } + + protected Payment() { } + } +} diff --git a/src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs b/src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs deleted file mode 100644 index 3dc5fc4cd..000000000 --- a/src/Services/Ordering/Ordering.Domain/SeedWork/ValueObject.cs +++ /dev/null @@ -1,126 +0,0 @@ - -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading.Tasks; - using System.Reflection; - - - public class ValueObject : IEquatable - where TValueObject : ValueObject - { - //A ValueObject doesn't have Identity, but we just need an Id/key so EF knows how to persist - //becuase in EF Core it still doesn't support ValueObjects or ComplexTypes - //This should be changed when EF Core supports any of those. - // https://github.com/aspnet/EntityFramework/issues/246 - public virtual Guid Id { get; protected set; } - - //IEquatable and Override Equals operators - - - public bool Equals(TValueObject other) - { - if ((object)other == null) - return false; - - if (Object.ReferenceEquals(this, other)) - return true; - - //compare all public properties - PropertyInfo[] publicProperties = this.GetType().GetProperties(); - - if ((object)publicProperties != null - && - publicProperties.Any()) - { - return publicProperties.All(p => - { - var left = p.GetValue(this, null); - var right = p.GetValue(other, null); - - - if (typeof(TValueObject).IsAssignableFrom(left.GetType())) - { - //check not self-references... - return Object.ReferenceEquals(left, right); - } - else - return left.Equals(right); - - - }); - } - else - return true; - } - - public override bool Equals(object obj) - { - if ((object)obj == null) - return false; - - if (Object.ReferenceEquals(this, obj)) - return true; - - ValueObject item = obj as ValueObject; - - if ((object)item != null) - return Equals((TValueObject)item); - else - return false; - - } - - public override int GetHashCode() - { - int hashCode = 31; - bool changeMultiplier = false; - int index = 1; - - //compare all public properties - PropertyInfo[] publicProperties = this.GetType().GetProperties(); - - - if ((object)publicProperties != null - && - publicProperties.Any()) - { - foreach (var item in publicProperties) - { - object value = item.GetValue(this, null); - - if ((object)value != null) - { - - hashCode = hashCode * ((changeMultiplier) ? 59 : 114) + value.GetHashCode(); - - changeMultiplier = !changeMultiplier; - } - else - hashCode = hashCode ^ (index * 13);//only for support {"a",null,null,"a"} <> {null,"a","a",null} - } - } - - return hashCode; - } - - public static bool operator ==(ValueObject left, ValueObject right) - { - if (Object.Equals(left, null)) - return (Object.Equals(right, null)) ? true : false; - else - return left.Equals(right); - - } - - public static bool operator !=(ValueObject left, ValueObject right) - { - return !(left == right); - } - - - } -} - diff --git a/src/Services/Ordering/Ordering.Domain/project.json b/src/Services/Ordering/Ordering.Domain/project.json index bcfd892ef..db56591f2 100644 --- a/src/Services/Ordering/Ordering.Domain/project.json +++ b/src/Services/Ordering/Ordering.Domain/project.json @@ -2,9 +2,7 @@ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.6.0", - "System.Reflection.TypeExtensions": "4.1.0", - "System.Runtime.Serialization.Primitives": "4.1.1" + "NETStandard.Library": "1.6" }, "frameworks": { diff --git a/src/Services/Ordering/Ordering.SqlData/Ordering.SqlData.xproj b/src/Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.xproj similarity index 85% rename from src/Services/Ordering/Ordering.SqlData/Ordering.SqlData.xproj rename to src/Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.xproj index 5f9c67bd6..21d5cdd3f 100644 --- a/src/Services/Ordering/Ordering.SqlData/Ordering.SqlData.xproj +++ b/src/Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.xproj @@ -6,11 +6,11 @@ - 5da6ef13-c7e0-4ec4-8599-a61c6ac2628d - Microsoft.eShopOnContainers.Services.Ordering.SqlData + 95f1f07c-4d92-4742-bd07-e5b805aab651 + Microsoft.eShopOnContainers.Services.Ordering.Infrastructure .\obj .\bin\ - v4.6 + v4.5.1 2.0 diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs new file mode 100644 index 000000000..d766bd6d0 --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs @@ -0,0 +1,138 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure +{ + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Metadata.Builders; + using Microsoft.eShopOnContainers.Services.Ordering.Domain; + + public class OrderingContext + : DbContext + + { + const string DEFAULT_SCHEMA = "ordering"; + + public DbSet Orders { get; set; } + + public DbSet OrderItems { get; set; } + + public DbSet Payments { get; set; } + + public DbSet Buyers { get; set; } + + public DbSet Cards { get; set; } + + public DbSet OrderStatus { get; set; } + + public DbSet
Addresses { get; set; } + + public OrderingContext(DbContextOptions options) : base(options) { } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(ConfigureBuyer); + modelBuilder.Entity(ConfigurePayment); + modelBuilder.Entity(ConfigureOrder); + modelBuilder.Entity(ConfigureOrderItems); + + modelBuilder.Entity() + .ToTable("orderstatus", DEFAULT_SCHEMA); + + modelBuilder.Entity() + .ToTable("cardtypes", DEFAULT_SCHEMA); + + modelBuilder.Entity
() + .ToTable("address", DEFAULT_SCHEMA); + } + + void ConfigureBuyer(EntityTypeBuilder buyerConfiguration) + { + buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA); + + buyerConfiguration.HasKey(b => b.Id); + + buyerConfiguration.Property(b => b.Id) + .ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA); + + buyerConfiguration.Property(b => b.FullName) + .HasMaxLength(200) + .IsRequired(); + } + + void ConfigurePayment(EntityTypeBuilder paymentConfiguration) + { + paymentConfiguration.ToTable("payments", DEFAULT_SCHEMA); + + paymentConfiguration.HasKey(b => b.Id); + + paymentConfiguration.Property(b => b.Id) + .ForSqlServerUseSequenceHiLo("paymentseq", DEFAULT_SCHEMA); + + paymentConfiguration.Property(p => p.CardHolderName) + .HasMaxLength(200) + .IsRequired(); + + paymentConfiguration.Property(p => p.CardNumber) + .HasMaxLength(25) + .IsRequired(); + + paymentConfiguration.Property(p => p.Expiration) + .IsRequired(); + + paymentConfiguration.HasOne(p => p.CardType) + .WithMany() + .HasForeignKey(p => p.CardTypeId); + } + + void ConfigureOrder(EntityTypeBuilder orderConfiguration) + { + orderConfiguration.ToTable("orders", DEFAULT_SCHEMA); + + orderConfiguration.HasKey(o => o.Id); + + orderConfiguration.Property(o => o.Id) + .ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA); + + orderConfiguration.Property(o => o.OrderDate) + .IsRequired(); + + orderConfiguration.HasOne(o => o.Payment) + .WithMany() + .HasForeignKey(o => o.PaymentId); + + orderConfiguration.HasOne(o => o.BillingAddress) + .WithMany() + .HasForeignKey(o => o.BillingAddressId) + .OnDelete(EntityFrameworkCore.Metadata.DeleteBehavior.SetNull); + + orderConfiguration.HasOne(o => o.Buyer) + .WithMany() + .HasForeignKey(o => o.BuyerId); + + orderConfiguration.HasOne(o => o.Status) + .WithMany() + .HasForeignKey(o => o.StatusId); + } + + void ConfigureOrderItems(EntityTypeBuilder orderItemConfiguration) + { + orderItemConfiguration.ToTable("orderItems", DEFAULT_SCHEMA); + + orderItemConfiguration.HasKey(o => o.Id); + + orderItemConfiguration.Property(o => o.Discount) + .IsRequired(); + + orderItemConfiguration.Property(o => o.ProductId) + .IsRequired(); + + orderItemConfiguration.Property(o => o.ProductName) + .IsRequired(); + + orderItemConfiguration.Property(o => o.UnitPrice) + .IsRequired(); + + orderItemConfiguration.Property(o => o.Units) + .ForSqlServerHasDefaultValue(1) + .IsRequired(); + } + } +} diff --git a/src/Services/Ordering/Ordering.SqlData/Properties/AssemblyInfo.cs b/src/Services/Ordering/Ordering.Infrastructure/Properties/AssemblyInfo.cs similarity index 82% rename from src/Services/Ordering/Ordering.SqlData/Properties/AssemblyInfo.cs rename to src/Services/Ordering/Ordering.Infrastructure/Properties/AssemblyInfo.cs index 322d94a72..00732b2ad 100644 --- a/src/Services/Ordering/Ordering.SqlData/Properties/AssemblyInfo.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/Properties/AssemblyInfo.cs @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; // associated with an assembly. [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Microsoft.eShopOnContainers.Services.Ordering.Infrastructure")] +[assembly: AssemblyProduct("Ordering.Infrastructure")] [assembly: AssemblyTrademark("")] // Setting ComVisible to false makes the types in this assembly not visible @@ -16,4 +16,4 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5da6ef13-c7e0-4ec4-8599-a61c6ac2628d")] +[assembly: Guid("95f1f07c-4d92-4742-bd07-e5b805aab651")] diff --git a/src/Services/Ordering/Ordering.Infrastructure/project.json b/src/Services/Ordering/Ordering.Infrastructure/project.json new file mode 100644 index 000000000..03c2eeef4 --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/project.json @@ -0,0 +1,16 @@ +{ + "version": "1.0.0-*", + + "dependencies": { + "NETStandard.Library": "1.6.0", + "Microsoft.EntityFrameworkCore": "1.0.1", + "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", + "Ordering.Domain": "1.0.0-*" + }, + + "frameworks": { + "netstandard1.6": { + "imports": "dnxcore50" + } + } +} diff --git a/src/Services/Ordering/Ordering.SqlData/UnitOfWork/DBContextUtil.cs b/src/Services/Ordering/Ordering.SqlData/UnitOfWork/DBContextUtil.cs deleted file mode 100644 index 3672653f2..000000000 --- a/src/Services/Ordering/Ordering.SqlData/UnitOfWork/DBContextUtil.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork -{ - public class DbContextUtil - { - public static DbContextOptions CreateNewContextOptionsForInMemoryDB() - { - // Create a fresh service provider, and therefore a fresh - // InMemory database instance. - var serviceProvider = new ServiceCollection() - .AddEntityFrameworkInMemoryDatabase() - .BuildServiceProvider(); - - // Create a new options instance telling the context to use an - // InMemory database and the new service provider. - var builder = new DbContextOptionsBuilder(); - builder.UseInMemoryDatabase() - .UseInternalServiceProvider(serviceProvider); - - return builder.Options; - } - - public static DbContextOptions CreateNewContextOptionsForSqlDb() - { - // Create a new options instance telling the context to use a Sql database - var builder = new DbContextOptionsBuilder(); - - //SQL LocalDB - //var connString = @"Server=(localdb)\mssqllocaldb;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; - - //SQL SERVER on-premises - - //(Integrated Security) var connString = @"Server=CESARDLBOOKVHD;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; - - //(SQL Server Authentication) - var connString = @"Server=10.0.75.1;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;"; - - //SQL LOCALDB - builder.UseSqlServer(connString); - - return builder.Options; - } - } -} diff --git a/src/Services/Ordering/Ordering.SqlData/UnitOfWork/OrderingDbContext.cs b/src/Services/Ordering/Ordering.SqlData/UnitOfWork/OrderingDbContext.cs deleted file mode 100644 index e35c3e540..000000000 --- a/src/Services/Ordering/Ordering.SqlData/UnitOfWork/OrderingDbContext.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - -namespace Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork -{ - public class OrderingDbContext : DbContext, IUnitOfWork - { - public OrderingDbContext(DbContextOptions options) - : base(options) - { } - - public DbSet Orders { get; set; } - - //(CDLTLL) - /* - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - //If running from ASP.NET Core, config is done at StartUp.cs --> ConfigureServices() outside - //and injected through DI later on. The following config is used when running Tests or similar contexts - if (!optionsBuilder.IsConfigured) - { - //SQL LocalDB - //var connString = @"Server=(localdb)\mssqllocaldb;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; - - //SQL SERVER on-premises - - //(Integrated Security) - //var connString = @"Server=CESARDLBOOKVHD;Database=Microsoft.eShopOnContainers.Services.OrderingDb;Trusted_Connection=True;"; - - //(SQL Server Authentication) - var connString = @"Server=10.0.75.1;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;"; - - //SQL LOCALDB - optionsBuilder.UseSqlServer(connString); - - } - } - */ - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - // Add your customizations after calling base.OnModelCreating(builder); - - //Sequence to be used as part of the OrderNumber - modelBuilder.HasSequence("OrderSequences", schema: "shared") - .StartsAt(1001) - .IncrementsBy(1); - - modelBuilder.Entity() - .Property(o => o.SequenceNumber) - .HasDefaultValueSql("NEXT VALUE FOR shared.OrderSequences"); - - } - - public async Task CommitAsync() - { - int changes = 0; - - try - { - //(CDLTLL) TBD - //RemoveOrphanedChilds(); - - changes = await base.SaveChangesAsync(); - } - catch (Exception ex) - { - //(CDLTLL) TBD - //RejectChanges(); - throw ex; - } - - return changes; - } - } -} diff --git a/src/Services/Ordering/Ordering.SqlData/project.json b/src/Services/Ordering/Ordering.SqlData/project.json deleted file mode 100644 index 8ede54bb4..000000000 --- a/src/Services/Ordering/Ordering.SqlData/project.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": "1.0.0-*", - - "dependencies": { - "Microsoft.EntityFrameworkCore": "1.0.0", - "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0", - "NETStandard.Library": "1.6.0", - "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0", - "Ordering.Domain": "1.0.0-*", - "Microsoft.EntityFrameworkCore.InMemory": "1.0.0" - }, - - "frameworks": { - "netstandard1.6": { - "imports": [ "dnxcore50", "portable-net451+win8" ] - } - - } -} diff --git a/test/Services/Ordering.Test/DataIntegrationTests.cs b/test/Services/Ordering.Test/DataIntegrationTests.cs deleted file mode 100644 index ff0c93f65..000000000 --- a/test/Services/Ordering.Test/DataIntegrationTests.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Linq; -using Xunit; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.UnitOfWork; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.Contracts; -using Microsoft.eShopOnContainers.Services.Ordering.SqlData.Repositories; -using Microsoft.EntityFrameworkCore; - -namespace DataIntegrationTests -{ - //Basic documentation for Testing EF Core classes - // http://ef.readthedocs.io/en/latest/miscellaneous/testing.html - public class Tests - { - [Fact] - public async void Add_order_to_data_model() - { - // All contexts that share the same service provider will share the same database - - //Using InMemory DB - //var options = DbContextUtil.CreateNewContextOptionsForInMemoryDB(); - - //Using Sql Server - var options = DbContextUtil.CreateNewContextOptionsForSqlDb(); - - // Run the test against one instance of the context - using (var context = new OrderingDbContext(options)) - { - IOrderRepository orderRepository = new OrderRepository(context); - - //Create generic Address ValueObject - Address sampleAddress = new Address("15703 NE 61st Ct.", - "Redmond", - "Washington", - "WA", - "United States", - "US", - "98052", - 47.661492, - -122.131309 - ); - //Create sample Orders - Order order1 = new Order(Guid.NewGuid(), sampleAddress, sampleAddress); - - //Add a few OrderItems - order1.AddNewOrderItem(Guid.NewGuid(), 2, 25, 30); - order1.AddNewOrderItem(Guid.NewGuid(), 1, 58, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 1, 60, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 3, 12, 0); - order1.AddNewOrderItem(Guid.NewGuid(), 5, 3, 0); - - orderRepository.Add(order1); - int numChanges = await orderRepository.UnitOfWork.CommitAsync(); - - //With no Async Repository - //context.Orders.Add(order1); - //context.SaveChanges(); - - } - - //// Use a separate instance of the context to verify correct data was saved to database - using (var context = new OrderingDbContext(options)) - { - var orders = context.Orders - .Include(o => o.ShippingAddress) - .Include(o => o.BillingAddress) - .ToList(); - //Could be using .Load() if you don't want to create a List - - //OTHER SAMPLE - //var company = context.Companies - // .Include(co => co.Employees).ThenInclude(emp => emp.Employee_Car) - // .Include(co => co.Employees).ThenInclude(emp => emp.Employee_Country) - // .FirstOrDefault(co => co.companyID == companyID); - - //Assert when running test with a clean In-Memory DB - //Assert.Equal(1, context.Orders.Count()); - - string cityName = orders.First().ShippingAddress.City; - Assert.Equal("Redmond", cityName); - } - } - - } -} diff --git a/test/Services/Ordering.Test/project.json b/test/Services/Ordering.Test/project.json index ab108e9cd..ca7f87942 100644 --- a/test/Services/Ordering.Test/project.json +++ b/test/Services/Ordering.Test/project.json @@ -4,13 +4,7 @@ "debugType": "portable" }, "dependencies": { - "System.Runtime.Serialization.Primitives": "4.1.1", - "xunit": "2.1.0", - "dotnet-test-xunit": "2.2.0-preview2-build1029", - "Ordering.Domain": "1.0.0-*", - "Ordering.SqlData": "1.0.0-*", - "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0", - "Microsoft.EntityFrameworkCore.InMemory": "1.0.0" + }, "testRunner": "xunit", "frameworks": { From 78f11524760447b3d23834ae0b30b2065d842f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Su=C3=A1rez=20Ruiz?= Date: Wed, 23 Nov 2016 08:25:49 +0100 Subject: [PATCH 03/10] Changes in main solution configuration --- eShopOnContainers.sln | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eShopOnContainers.sln b/eShopOnContainers.sln index f8d0a28df..883ded9bc 100644 --- a/eShopOnContainers.sln +++ b/eShopOnContainers.sln @@ -499,6 +499,8 @@ Global {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Build.0 = Debug|ARM {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Deploy.0 = Debug|ARM {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.ActiveCfg = Debug|x86 + {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Build.0 = Debug|x86 + {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.Deploy.0 = Debug|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.ActiveCfg = Debug|x64 {C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Build.0 = Debug|x64 @@ -727,6 +729,8 @@ Global {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Build.0 = Debug|ARM {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|ARM.Deploy.0 = Debug|ARM {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.ActiveCfg = Debug|x86 + {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Build.0 = Debug|x86 + {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhone.Deploy.0 = Debug|x86 {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.ActiveCfg = Debug|x64 {02680C26-CA1D-4D9D-A7E3-D66AF5BE6F2F}.Debug|x64.Build.0 = Debug|x64 From 872ee450adcec04d835f71a5183cc4573a340441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Su=C3=A1rez=20Ruiz?= Date: Wed, 23 Nov 2016 13:45:47 +0100 Subject: [PATCH 04/10] Integrated Basket API service --- .../{CartButton.xaml => AddBasketButton.xaml} | 2 +- ...Button.xaml.cs => AddBasketButton.xaml.cs} | 6 +- .../eShopOnContainers.Core/GlobalSettings.cs | 2 + .../Models/Basket/BasketItem.cs | 100 ++++++++++++ .../Models/Basket/CustomerBasket.cs | 10 ++ .../Models/Orders/OrderItem.cs | 4 +- .../Models/User/User.cs | 5 +- .../Services/Basket/BasketMockService.cs | 42 +++++ .../Services/Basket/BasketService.cs | 53 +++++++ .../Services/Basket/IBasketService.cs | 11 ++ .../Services/Navigation/NavigationService.cs | 2 +- .../Services/Orders/IOrdersService.cs | 13 -- .../Services/Orders/OrdersMockService.cs | 39 ----- .../RequestProvider/RequestProvider.cs | 4 +- .../Services/User/IUserService.cs | 7 +- .../Services/User/UserMockService.cs | 26 ++- .../ViewModels/Base/MessengerKeys.cs | 7 +- .../ViewModels/Base/ViewModelLocator.cs | 10 +- .../ViewModels/BasketViewModel.cs | 150 ++++++++++++++++++ .../ViewModels/CartViewModel.cs | 117 -------------- .../ViewModels/CatalogViewModel.cs | 22 ++- .../ViewModels/CheckoutViewModel.cs | 31 +++- .../ViewModels/MainViewModel.cs | 2 +- .../ViewModels/OrderDetailViewModel.cs | 6 +- .../ViewModels/ProfileViewModel.cs | 14 +- .../Views/{CartView.xaml => BasketView.xaml} | 10 +- .../{CartView.xaml.cs => BasketView.xaml.cs} | 4 +- .../Views/MainView.xaml | 10 +- .../Views/MainView.xaml.cs | 11 +- ...mTemplate.xaml => BasketItemTemplate.xaml} | 4 +- ...ate.xaml.cs => BasketItemTemplate.xaml.cs} | 4 +- .../Views/Templates/ProductTemplate.xaml | 2 +- .../eShopOnContainers.Core.csproj | 29 ++-- .../eShopOnContainers.Core/packages.config | 1 - .../eShopOnContainers.Droid.csproj | 2 - .../eShopOnContainers.Droid/packages.config | 1 - .../eShopOnContainers.Windows/project.json | 1 - .../eShopOnContainers.iOS.csproj | 2 - .../eShopOnContainers.iOS/packages.config | 1 - 39 files changed, 519 insertions(+), 248 deletions(-) rename src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/{CartButton.xaml => AddBasketButton.xaml} (97%) rename src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/{CartButton.xaml.cs => AddBasketButton.xaml.cs} (60%) create mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/BasketItem.cs create mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/CustomerBasket.cs create mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketMockService.cs create mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs create mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/IBasketService.cs delete mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/IOrdersService.cs delete mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/OrdersMockService.cs create mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs delete mode 100644 src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CartViewModel.cs rename src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/{CartView.xaml => BasketView.xaml} (92%) rename src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/{CartView.xaml.cs => BasketView.xaml.cs} (62%) rename src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/Templates/{CartOrderItemTemplate.xaml => BasketItemTemplate.xaml} (96%) rename src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/Templates/{CartOrderItemTemplate.xaml.cs => BasketItemTemplate.xaml.cs} (58%) diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/CartButton.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/AddBasketButton.xaml similarity index 97% rename from src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/CartButton.xaml rename to src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/AddBasketButton.xaml index 0235d1d19..0cf83094c 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/CartButton.xaml +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/AddBasketButton.xaml @@ -2,7 +2,7 @@ + x:Class="eShopOnContainers.Core.Controls.AddBasketButton"> diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/CartButton.xaml.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/AddBasketButton.xaml.cs similarity index 60% rename from src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/CartButton.xaml.cs rename to src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/AddBasketButton.xaml.cs index b46235a66..caa4839ac 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/CartButton.xaml.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Controls/AddBasketButton.xaml.cs @@ -2,11 +2,11 @@ namespace eShopOnContainers.Core.Controls { - public partial class CartButton : ContentView + public partial class AddBasketButton : ContentView { - public CartButton() + public AddBasketButton() { InitializeComponent(); } } -} +} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs index 551e94c96..d942bc439 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/GlobalSettings.cs @@ -5,5 +5,7 @@ public const string RegisterWebsite = "http://104.40.62.65/Account/Register"; public const string CatalogEndpoint = "http://104.40.62.65:5101/"; + + public const string BasketEndpoint = "http://104.40.62.65:5103/"; } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/BasketItem.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/BasketItem.cs new file mode 100644 index 000000000..2edfd198b --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/BasketItem.cs @@ -0,0 +1,100 @@ +using eShopOnContainers.Core.Helpers; +using eShopOnContainers.ViewModels.Base; +using System; +using System.Collections.ObjectModel; + +namespace eShopOnContainers.Core.Models.Basket +{ + public class BasketItem : ExtendedBindableObject + { + private string _id; + private string _productId; + private string _productName; + private decimal _unitPrice; + private int _quantity; + private string _pictureUrl; + private ObservableCollection _numbers; + + public BasketItem() + { + Numbers = NumericHelper.GetNumericList(); + } + + public string Id + { + get { return _id; } + set + { + _id = value; + RaisePropertyChanged(() => Id); + } + } + + public string ProductId + { + get { return _productId; } + set + { + _productId = value; + RaisePropertyChanged(() => ProductId); + } + } + + public string ProductName + { + get { return _productName; } + set + { + _productName = value; + RaisePropertyChanged(() => ProductName); + } + } + + public decimal UnitPrice + { + get { return _unitPrice; } + set + { + _unitPrice = value; + RaisePropertyChanged(() => UnitPrice); + } + } + + public int Quantity + { + get { return _quantity; } + set + { + _quantity = value; + RaisePropertyChanged(() => Quantity); + } + } + + public string PictureUrl + { + get { return _pictureUrl; } + set + { + _pictureUrl = value; + RaisePropertyChanged(() => PictureUrl); + } + } + + public decimal Total { get { return Quantity * UnitPrice; } } + + public ObservableCollection Numbers + { + get { return _numbers; } + set + { + _numbers = value; + RaisePropertyChanged(() => Numbers); + } + } + + public override string ToString() + { + return String.Format("Product Id: {0}, Quantity: {1}", ProductId, Quantity); + } + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/CustomerBasket.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/CustomerBasket.cs new file mode 100644 index 000000000..66afa7f9a --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Basket/CustomerBasket.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace eShopOnContainers.Core.Models.Basket +{ + public class CustomerBasket + { + public string BuyerId { get; set; } + public List Items { get; set; } + } +} diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Orders/OrderItem.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Orders/OrderItem.cs index ada28ef5f..10712da68 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Orders/OrderItem.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/Orders/OrderItem.cs @@ -10,7 +10,7 @@ namespace eShopOnContainers.Core.Models.Orders public class OrderItem : ExtendedBindableObject { private string _productImage; - private int _productId; + private string _productId; private Guid _orderId; private string _productName; private decimal _unitPrice; @@ -23,7 +23,7 @@ namespace eShopOnContainers.Core.Models.Orders Numbers = NumericHelper.GetNumericList(); } - public int ProductId + public string ProductId { get { return _productId; } set diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/User/User.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/User/User.cs index 7bae593d4..30f133226 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/User/User.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Models/User/User.cs @@ -1,7 +1,10 @@ -namespace eShopOnContainers.Core.Models.User +using System; + +namespace eShopOnContainers.Core.Models.User { public class User { + public string GuidUser { get; set; } public string Name { get; set; } public string LastName { get; set; } public string CardNumber { get; set; } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketMockService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketMockService.cs new file mode 100644 index 000000000..6bdcf0df5 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketMockService.cs @@ -0,0 +1,42 @@ +using eShopOnContainers.Core.Models.Basket; +using System.Collections.Generic; +using System.Threading.Tasks; +using Xamarin.Forms; +using System; + +namespace eShopOnContainers.Core.Services.Basket +{ + public class BasketMockService : IBasketService + { + private CustomerBasket MockCustomBasket = new CustomerBasket + { + BuyerId = "9245fe4a-d402-451c-b9ed-9c1a04247482", + Items = new List + { + new BasketItem { Id = "1", PictureUrl = Device.OS != TargetPlatform.Windows ? "fake_product_01.png" : "Assets/fake_product_01.png", ProductId = "1", ProductName = ".NET Bot Blue Sweatshirt (M)", Quantity = 1, UnitPrice = 19.50M }, + new BasketItem { Id = "2", PictureUrl = Device.OS != TargetPlatform.Windows ? "fake_product_04.png" : "Assets/fake_product_04.png", ProductId = "4", ProductName = ".NET Black Cupt", Quantity = 1, UnitPrice = 17.00M } + } + }; + + public async Task GetBasketAsync(string guidUser) + { + await Task.Delay(500); + + if(string.IsNullOrEmpty(guidUser)) + { + return new CustomerBasket(); + } + + return MockCustomBasket; + } + + public async Task UpdateBasketAsync(CustomerBasket customerBasket) + { + await Task.Delay(500); + + MockCustomBasket = customerBasket; + + return MockCustomBasket; + } + } +} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs new file mode 100644 index 000000000..52553ab02 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/BasketService.cs @@ -0,0 +1,53 @@ +using System; +using System.Threading.Tasks; +using eShopOnContainers.Core.Services.RequestProvider; +using eShopOnContainers.Core.Models.Basket; + +namespace eShopOnContainers.Core.Services.Basket +{ + public class BasketService : IBasketService + { + private readonly IRequestProvider _requestProvider; + + public BasketService(IRequestProvider requestProvider) + { + _requestProvider = requestProvider; + } + + public async Task GetBasketAsync(string guidUser) + { + try + { + UriBuilder builder = new UriBuilder(GlobalSetting.CatalogEndpoint); + + builder.Path = guidUser; + + string uri = builder.ToString(); + + CustomerBasket basket = + await _requestProvider.GetAsync(uri); + + return basket; + } + catch + { + return new CustomerBasket + { + BuyerId = guidUser, + Items = new System.Collections.Generic.List() + }; + } + } + + public async Task UpdateBasketAsync(CustomerBasket customerBasket) + { + UriBuilder builder = new UriBuilder(GlobalSetting.CatalogEndpoint); + + string uri = builder.ToString(); + + var result = await _requestProvider.PostAsync(uri, customerBasket); + + return result; + } + } +} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/IBasketService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/IBasketService.cs new file mode 100644 index 000000000..356eb40f7 --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Basket/IBasketService.cs @@ -0,0 +1,11 @@ +using eShopOnContainers.Core.Models.Basket; +using System.Threading.Tasks; + +namespace eShopOnContainers.Core.Services.Basket +{ + public interface IBasketService + { + Task GetBasketAsync(string guidUser); + Task UpdateBasketAsync(CustomerBasket customerBasket); + } +} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs index aacae349b..66a723baf 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Navigation/NavigationService.cs @@ -147,7 +147,7 @@ namespace eShopOnContainers.Services private void CreatePageViewModelMappings() { - _mappings.Add(typeof(CartViewModel), typeof(CartView)); + _mappings.Add(typeof(BasketViewModel), typeof(BasketView)); _mappings.Add(typeof(CatalogViewModel), typeof(CatalogView)); _mappings.Add(typeof(CheckoutViewModel), typeof(CheckoutView)); _mappings.Add(typeof(LoginViewModel), typeof(LoginView)); diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/IOrdersService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/IOrdersService.cs deleted file mode 100644 index 39536bc8e..000000000 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/IOrdersService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using eShopOnContainers.Core.Models.Orders; -using System.Collections.ObjectModel; -using System.Threading.Tasks; - -namespace eShopOnContainers.Core.Services.Orders -{ - public interface IOrdersService - { - Task> GetOrdersAsync(); - - Task GetCartAsync(); - } -} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/OrdersMockService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/OrdersMockService.cs deleted file mode 100644 index 9c4a7b42c..000000000 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/Orders/OrdersMockService.cs +++ /dev/null @@ -1,39 +0,0 @@ -using eShopOnContainers.Core.Models.Orders; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Threading.Tasks; - -namespace eShopOnContainers.Core.Services.Orders -{ - public class OrdersMockService : IOrdersService - { - public async Task> GetOrdersAsync() - { - await Task.Delay(500); - - return new ObservableCollection - { - new Order { SequenceNumber = 123, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = GetOrderItems() }, - new Order { SequenceNumber = 132, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = GetOrderItems() }, - new Order { SequenceNumber = 231, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = GetOrderItems() }, - }; - } - - public async Task GetCartAsync() - { - await Task.Delay(500); - - return new Order { SequenceNumber = 0123456789, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Pending, OrderItems = GetOrderItems() }; - } - - private List GetOrderItems() - { - return new List - { - new OrderItem { OrderId = Guid.NewGuid(), ProductId = 1, Discount = 15, ProductName = ".NET Bot Blue Sweatshirt (M)", Quantity = 1, UnitPrice = 16.50M }, - new OrderItem { OrderId = Guid.NewGuid(), ProductId = 3, Discount = 0, ProductName = ".NET Bot Black Sweatshirt (M)", Quantity = 2, UnitPrice = 19.95M } - }; - } - } -} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/RequestProvider.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/RequestProvider.cs index 75a92ad12..dd6a1bce5 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/RequestProvider.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/RequestProvider/RequestProvider.cs @@ -34,6 +34,7 @@ namespace eShopOnContainers.Core.Services.RequestProvider await HandleResponse(response); string serialized = await response.Content.ReadAsStringAsync(); + TResult result = await Task.Run(() => JsonConvert.DeserializeObject(serialized, _serializerSettings)); @@ -91,7 +92,8 @@ namespace eShopOnContainers.Core.Services.RequestProvider { var content = await response.Content.ReadAsStringAsync(); - if (response.StatusCode == HttpStatusCode.Forbidden || response.StatusCode == HttpStatusCode.Unauthorized) + if (response.StatusCode == HttpStatusCode.Forbidden + || response.StatusCode == HttpStatusCode.Unauthorized) { throw new ServiceAuthenticationException(content); } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/IUserService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/IUserService.cs index 4ed3e5755..fac0a47a1 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/IUserService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/IUserService.cs @@ -1,9 +1,12 @@ -using System.Threading.Tasks; +using eShopOnContainers.Core.Models.Orders; +using System.Collections.Generic; +using System.Threading.Tasks; namespace eShopOnContainers.Core.Services.User { public interface IUserService { Task GetUserAsync(); + Task> GetOrdersAsync(); } -} +} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserMockService.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserMockService.cs index 67f7a0bb1..12c3f8e60 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserMockService.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Services/User/UserMockService.cs @@ -1,4 +1,7 @@ -using System.Threading.Tasks; +using eShopOnContainers.Core.Models.Orders; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; namespace eShopOnContainers.Core.Services.User { @@ -6,6 +9,7 @@ namespace eShopOnContainers.Core.Services.User { private Models.User.User MockUser = new Models.User.User { + GuidUser = "9245fe4a-d402-451c-b9ed-9c1a04247482", Name = "Jhon", LastName = "Doe", City = "Seattle, WA", @@ -14,11 +18,31 @@ namespace eShopOnContainers.Core.Services.User Country = "United States" }; + private List MockOrders = new List() + { + new Order { SequenceNumber = 123, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = MockOrderItems }, + new Order { SequenceNumber = 132, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = MockOrderItems }, + new Order { SequenceNumber = 231, Total = 56.40M, OrderDate = DateTime.Now, Status = OrderStatus.Delivered, OrderItems = MockOrderItems }, + }; + + private static List MockOrderItems = new List() + { + new OrderItem { OrderId = Guid.NewGuid(), ProductId = "1", Discount = 15, ProductName = ".NET Bot Blue Sweatshirt (M)", Quantity = 1, UnitPrice = 16.50M }, + new OrderItem { OrderId = Guid.NewGuid(), ProductId = "3", Discount = 0, ProductName = ".NET Bot Black Sweatshirt (M)", Quantity = 2, UnitPrice = 19.95M } + }; + public async Task GetUserAsync() { await Task.Delay(500); return MockUser; } + + public async Task> GetOrdersAsync() + { + await Task.Delay(500); + + return MockOrders; + } } } \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/MessengerKeys.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/MessengerKeys.cs index ec49e8802..25fd28be6 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/MessengerKeys.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/MessengerKeys.cs @@ -2,10 +2,13 @@ { public class MessengerKeys { - // Add product to cart + // Add product to basket public const string AddProduct = "AddProduct"; - // Update product cart + // Update Basket + public const string UpdateBasket = "UpdateBasket"; + + // Update product basket public const string UpdateProduct = "UpdateProduct"; // Filter diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs index 46b01ba55..e1c28642a 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/Base/ViewModelLocator.cs @@ -1,5 +1,4 @@ using Microsoft.Practices.Unity; -using eShopOnContainers.Core.Services.Orders; using eShopOnContainers.Core.ViewModels; using eShopOnContainers.Services; using System; @@ -7,6 +6,7 @@ using eShopOnContainers.Core.Services.Catalog; using eShopOnContainers.Core.Services.OpenUrl; using eShopOnContainers.Core.Services.User; using eShopOnContainers.Core.Services.RequestProvider; +using eShopOnContainers.Core.Services.Basket; namespace eShopOnContainers.ViewModels.Base { @@ -39,11 +39,11 @@ namespace eShopOnContainers.ViewModels.Base _unityContainer.RegisterType(); _unityContainer.RegisterType(); - _unityContainer.RegisterType(); + _unityContainer.RegisterType(); _unityContainer.RegisterType(); // View models - _unityContainer.RegisterType(); + _unityContainer.RegisterType(); _unityContainer.RegisterType(); _unityContainer.RegisterType(); _unityContainer.RegisterType(); @@ -58,7 +58,7 @@ namespace eShopOnContainers.ViewModels.Base if (!useMockServices) { _unityContainer.RegisterInstance(new CatalogMockService()); - _unityContainer.RegisterInstance(new OrdersMockService()); + _unityContainer.RegisterInstance(new BasketMockService()); _unityContainer.RegisterInstance(new UserMockService()); UseMockService = false; @@ -67,6 +67,8 @@ namespace eShopOnContainers.ViewModels.Base { var requestProvider = Resolve(); _unityContainer.RegisterInstance(new CatalogService(requestProvider)); + _unityContainer.RegisterInstance(new BasketService(requestProvider)); + _unityContainer.RegisterInstance(new UserMockService()); UseMockService = true; } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs new file mode 100644 index 000000000..0ffea52ad --- /dev/null +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/BasketViewModel.cs @@ -0,0 +1,150 @@ +using eShopOnContainers.Core.Models.Basket; +using eShopOnContainers.Core.Models.Catalog; +using eShopOnContainers.Core.Models.Orders; +using eShopOnContainers.Core.Models.User; +using eShopOnContainers.Core.Services.Basket; +using eShopOnContainers.Core.Services.User; +using eShopOnContainers.Core.ViewModels.Base; +using eShopOnContainers.ViewModels.Base; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Input; +using Xamarin.Forms; + +namespace eShopOnContainers.Core.ViewModels +{ + public class BasketViewModel : ViewModelBase + { + private User _user; + private int _badgeCount; + private ObservableCollection _basketItems; + private decimal _total; + + private IUserService _userService; + private IBasketService _basketService; + + public BasketViewModel(IUserService userService, + IBasketService basketService) + { + _userService = userService; + _basketService = basketService; + } + + public int BadgeCount + { + get { return _badgeCount; } + set + { + _badgeCount = value; + RaisePropertyChanged(() => BadgeCount); + } + } + + public ObservableCollection BasketItems + { + get { return _basketItems; } + set + { + _basketItems = value; + RaisePropertyChanged(() => BasketItems); + } + } + + public decimal Total + { + get { return _total; } + set + { + _total = value; + RaisePropertyChanged(() => Total); + } + } + + public ICommand CheckoutCommand => new Command(Checkout); + + public override async Task InitializeAsync(object navigationData) + { + MessagingCenter.Subscribe>(this, MessengerKeys.UpdateBasket, (sender, arg) => + { + BadgeCount = arg.Count; + + foreach (var basketItem in arg) + { + AddBasketItem(basketItem); + } + }); + + MessagingCenter.Subscribe(this, MessengerKeys.AddProduct, (sender, arg) => + { + BadgeCount++; + + AddCatalogItem(arg); + }); + + MessagingCenter.Subscribe(this, MessengerKeys.UpdateProduct, (sender) => + { + ReCalculateTotal(); + }); + + _user = await _userService.GetUserAsync(); + BasketItems = new ObservableCollection(); + } + + private void AddCatalogItem(CatalogItem item) + { + if (BasketItems.Any(o => o.ProductId.Equals(item.Id, StringComparison.CurrentCultureIgnoreCase))) + { + var orderItem = BasketItems.First(o => o.ProductId.Equals(item.Id, StringComparison.CurrentCultureIgnoreCase)); + orderItem.Quantity++; + } + else + { + BasketItems.Add(new BasketItem + { + ProductId = item.Id, + ProductName = item.Name, + PictureUrl = item.PictureUri, + UnitPrice = item.Price, + Quantity = 1 + }); + } + + ReCalculateTotal(); + } + + private void AddBasketItem(BasketItem item) + { + BasketItems.Add(item); + + ReCalculateTotal(); + } + + private void ReCalculateTotal() + { + Total = 0; + + foreach (var orderItem in BasketItems) + { + Total += (orderItem.Quantity * orderItem.UnitPrice); + } + + + _basketService.UpdateBasketAsync(new CustomerBasket + { + BuyerId = _user.GuidUser, + Items = BasketItems.ToList() + }); + } + + private void Checkout() + { + if (BasketItems.Any()) + { + NavigationService.NavigateToAsync(BasketItems); + } + } + } +} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CartViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CartViewModel.cs deleted file mode 100644 index 8001fa834..000000000 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CartViewModel.cs +++ /dev/null @@ -1,117 +0,0 @@ -using eShopOnContainers.Core.Helpers; -using eShopOnContainers.Core.Models.Catalog; -using eShopOnContainers.Core.Models.Orders; -using eShopOnContainers.Core.Services.Orders; -using eShopOnContainers.Core.ViewModels.Base; -using eShopOnContainers.ViewModels.Base; -using System; -using System.Collections.ObjectModel; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Input; -using Xamarin.Forms; - -namespace eShopOnContainers.Core.ViewModels -{ - public class CartViewModel : ViewModelBase - { - private int _badgeCount; - private ObservableCollection _orderItems; - private decimal _total; - - private IOrdersService _orderService; - - public CartViewModel(IOrdersService orderService) - { - _orderService = orderService; - } - - public int BadgeCount - { - get { return _badgeCount; } - set - { - _badgeCount = value; - RaisePropertyChanged(() => BadgeCount); - } - } - - public ObservableCollection OrderItems - { - get { return _orderItems; } - set - { - _orderItems = value; - RaisePropertyChanged(() => OrderItems); - } - } - - public decimal Total - { - get { return _total; } - set - { - _total = value; - RaisePropertyChanged(() => Total); - } - } - - public ICommand CheckoutCommand => new Command(Checkout); - - public override Task InitializeAsync(object navigationData) - { - MessagingCenter.Subscribe(this, MessengerKeys.AddProduct, (sender, arg) => - { - BadgeCount++; - - AddCartItem(arg); - }); - - MessagingCenter.Subscribe(this, MessengerKeys.UpdateProduct, (sender) => - { - ReCalculateTotal(); - }); - - OrderItems = new ObservableCollection(); - - return base.InitializeAsync(navigationData); - } - - private void AddCartItem(CatalogItem item) - { - if (OrderItems.Any(o => o.ProductId == Convert.ToInt32(item.Id))) - { - var orderItem = OrderItems.First(o => o.ProductId == Convert.ToInt32(item.Id)); - orderItem.Quantity++; - } - else - { - OrderItems.Add(new OrderItem - { - ProductId = Convert.ToInt32(item.Id), - ProductName = item.Name, - ProductImage = item.PictureUri, - UnitPrice = item.Price, - Quantity = 1 - }); - } - - ReCalculateTotal(); - } - - private void ReCalculateTotal() - { - Total = 0; - - foreach (var orderItem in OrderItems) - { - Total += orderItem.Total; - } - } - - private void Checkout() - { - NavigationService.NavigateToAsync(OrderItems); - } - } -} \ No newline at end of file diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs index 05e2b461a..5735c5633 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CatalogViewModel.cs @@ -6,6 +6,9 @@ using eShopOnContainers.Core.ViewModels.Base; using eShopOnContainers.Core.Models.Catalog; using eShopOnContainers.Core.Services.Catalog; using System.Windows.Input; +using eShopOnContainers.Core.Services.User; +using System.Linq; +using eShopOnContainers.Core.Services.Basket; namespace eShopOnContainers.Core.ViewModels { @@ -17,10 +20,16 @@ namespace eShopOnContainers.Core.ViewModels private ObservableCollection _types; private CatalogType _type; + private IUserService _userService; + private IBasketService _basketService; private ICatalogService _productsService; - public CatalogViewModel(ICatalogService productsService) + public CatalogViewModel(IUserService userService, + IBasketService basketService, + ICatalogService productsService) { + _userService = userService; + _basketService = basketService; _productsService = productsService; } @@ -92,6 +101,15 @@ namespace eShopOnContainers.Core.ViewModels Brands = await _productsService.GetCatalogBrandAsync(); Types = await _productsService.GetCatalogTypeAsync(); + var user = await _userService.GetUserAsync(); + var basket = await _basketService.GetBasketAsync(user.GuidUser); + + if (basket != null && basket.Items.Any()) + { + System.Diagnostics.Debug.WriteLine(basket.Items.Count); + MessagingCenter.Send(this, MessengerKeys.UpdateBasket, basket.Items); + } + IsBusy = false; } @@ -102,7 +120,7 @@ namespace eShopOnContainers.Core.ViewModels private async void Filter() { - if(Brand == null && Type == null) + if (Brand == null && Type == null) { return; } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs index 938170d6a..e842f310f 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs @@ -9,12 +9,14 @@ using eShopOnContainers.Core.Models.Orders; using System; using System.Collections.ObjectModel; using System.Linq; +using eShopOnContainers.Core.Models.Basket; +using System.Collections.Generic; namespace eShopOnContainers.Core.ViewModels { public class CheckoutViewModel : ViewModelBase { - private ObservableCollection _orderItems; + private ObservableCollection _orderItems; private Order _order; private User _user; @@ -25,7 +27,7 @@ namespace eShopOnContainers.Core.ViewModels _userService = userService; } - public ObservableCollection OrderItems + public ObservableCollection OrderItems { get { return _orderItems; } set @@ -59,11 +61,11 @@ namespace eShopOnContainers.Core.ViewModels public override async Task InitializeAsync(object navigationData) { - if (navigationData is ObservableCollection) + if (navigationData is ObservableCollection) { IsBusy = true; - var orderItems = ((ObservableCollection)navigationData); + var orderItems = ((ObservableCollection)navigationData); OrderItems = orderItems; @@ -72,7 +74,7 @@ namespace eShopOnContainers.Core.ViewModels Order = new Order { ShippingAddress = User, - OrderItems = orderItems.ToList(), + OrderItems = CreateOrderItems(orderItems.ToList()), Status = OrderStatus.Pending, OrderDate = DateTime.Now, Total = GetOrderTotal() @@ -91,6 +93,25 @@ namespace eShopOnContainers.Core.ViewModels await NavigationService.RemoveLastFromBackStackAsync(); } + private List CreateOrderItems(List basketItems) + { + var orderItems = new List(); + + foreach (var basketItem in basketItems) + { + orderItems.Add(new OrderItem + { + ProductId = basketItem.ProductId, + ProductName = basketItem.ProductName, + ProductImage = basketItem.PictureUrl, + Quantity = basketItem.Quantity, + UnitPrice = basketItem.UnitPrice + }); + } + + return orderItems; + } + private decimal GetOrderTotal() { decimal total = 0; diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs index 2cc8a9585..08dd09798 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/MainViewModel.cs @@ -8,7 +8,7 @@ using System.Windows.Input; namespace eShopOnContainers.Core.ViewModels { public class MainViewModel : ViewModelBase - { + { public ICommand SettingsCommand => new Command(Settings); public override Task InitializeAsync(object navigationData) diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs index 9d63851f6..f363c200b 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/OrderDetailViewModel.cs @@ -1,10 +1,10 @@ using System.Threading.Tasks; using eShopOnContainers.Core.Models.Orders; using eShopOnContainers.ViewModels.Base; -using eShopOnContainers.Core.Services.Orders; using eShopOnContainers.Core.Services.Catalog; using eShopOnContainers.Core.Services.User; using eShopOnContainers.Core.Models.User; +using eShopOnContainers.Core.Services.Basket; namespace eShopOnContainers.Core.ViewModels { @@ -13,11 +13,11 @@ namespace eShopOnContainers.Core.ViewModels private Order _order; private User _user; - private IOrdersService _orderService; + private IBasketService _orderService; private ICatalogService _catalogService; private IUserService _userService; - public OrderDetailViewModel(IOrdersService orderService, + public OrderDetailViewModel(IBasketService orderService, ICatalogService catalogService, IUserService userService) { diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs index 1c454db31..fe69f36a4 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/ProfileViewModel.cs @@ -1,5 +1,6 @@ -using eShopOnContainers.Core.Models.Orders; -using eShopOnContainers.Core.Services.Orders; +using eShopOnContainers.Core.Extensions; +using eShopOnContainers.Core.Models.Orders; +using eShopOnContainers.Core.Services.User; using eShopOnContainers.ViewModels.Base; using System.Collections.ObjectModel; using System.Threading.Tasks; @@ -12,11 +13,11 @@ namespace eShopOnContainers.Core.ViewModels { private ObservableCollection _orders; - private IOrdersService _ordersService; + private IUserService _userService; - public ProfileViewModel(IOrdersService ordersService) + public ProfileViewModel(IUserService userService) { - _ordersService = ordersService; + _userService = userService; } public ObservableCollection Orders @@ -37,7 +38,8 @@ namespace eShopOnContainers.Core.ViewModels { IsBusy = true; - Orders = await _ordersService.GetOrdersAsync(); + var orders = await _userService.GetOrdersAsync(); + Orders = orders.ToObservableCollection(); IsBusy = false; } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CartView.xaml b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/BasketView.xaml similarity index 92% rename from src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CartView.xaml rename to src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/BasketView.xaml index c3c127656..c95d9d562 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/CartView.xaml +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/Views/BasketView.xaml @@ -1,7 +1,7 @@  @@ -49,7 +49,7 @@ BackgroundColor="{StaticResource BackgroundColor}"> + IsVisible="{Binding BasketItems.Count, Converter={StaticResource CountToBoolConverter}}"> @@ -73,7 +73,7 @@ - + @@ -122,7 +122,7 @@ + IsVisible="{Binding BasketItems.Count, Converter={StaticResource InverseCountToBoolConverter}}">