/SSL.Application/StorePersistenceService.cs

http://smartshoppinglist.codeplex.com · C# · 269 lines · 233 code · 35 blank · 1 comment · 53 complexity · 1e762df4f2841d614069eb55875824e3 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using CBSI.SSL.Domain;
  6. using CBSI.DataAccess;
  7. using CBSI.Common;
  8. using System.Linq.Expressions;
  9. using CBSI.SSL.Commands;
  10. using CBSI.Common.Application;
  11. using CBSI.SSL.Rules;
  12. namespace CBSI.SSL.Application
  13. {
  14. [UnitOfWorkConversation]
  15. public class StorePersistenceService : PersistenceService, IStorePersistenceService
  16. {
  17. readonly IStoreRepository _StoreRepository;
  18. public StorePersistenceService(IStoreRepository storeRepository)
  19. {
  20. if (storeRepository == null)
  21. throw new ArgumentNullException("storeRepository", "StoreRepository is required!");
  22. _StoreRepository = storeRepository;
  23. }
  24. [UnitOfWorkConversationPart]
  25. public IList<Store> GetList(Expression<Func<Store, bool>> expression)
  26. {
  27. return _StoreRepository.GetAll(expression);
  28. }
  29. [UnitOfWorkConversationPart]
  30. public Store GetSingle(Expression<Func<Store, bool>> expression)
  31. {
  32. return _StoreRepository.Get(expression);
  33. }
  34. [UnitOfWorkConversationPart]
  35. public long Count(Shopper shopper)
  36. {
  37. return _StoreRepository.Count(s => s.Shopper.ID == shopper.ID);
  38. }
  39. [UnitOfWorkConversationPart]
  40. public IList<Store> GetPage(Shopper shopper, int page, int pageSize)
  41. {
  42. return _StoreRepository.GetPage(shopper, page, pageSize);
  43. }
  44. #region Product Categories
  45. [UnitOfWorkConversationPart]
  46. public ProductCategory Handle(AddNewProductCategory commandMessage)
  47. {
  48. var store = GetSingle(g => g.ID== commandMessage.StoreID);
  49. if (store == null)
  50. throw new ApplicationException(string.Format("Could not retrieve Store with ID = '{0}'", commandMessage.StoreID));
  51. ProductCategory superCategory = null;
  52. if (commandMessage.SuperCategoryID != Guid.Empty)
  53. superCategory = GetCategory(store, commandMessage.SuperCategoryID);
  54. var category = new ProductCategory(store, commandMessage, superCategory);
  55. Validate(store, category);
  56. store.AddProductCategory(category);
  57. store = _StoreRepository.Modify(store);
  58. return GetCategory(store, commandMessage.Name);
  59. }
  60. [UnitOfWorkConversationPart]
  61. public void Handle(ChangeProductCategory commandMessage)
  62. {
  63. var store = GetStore(commandMessage.StoreID);
  64. var category = GetCategory(store, commandMessage.ID);
  65. ProductCategory superCategory = null;
  66. if (commandMessage.SuperCategoryID != Guid.Empty)
  67. superCategory = GetCategory(store, commandMessage.SuperCategoryID);
  68. category.Change(commandMessage, superCategory);
  69. Validate(store, category);
  70. _StoreRepository.Modify(store);
  71. }
  72. [UnitOfWorkConversationPart]
  73. public void Handle(DeleteProductCategory commandMessage)
  74. {
  75. var store = GetStore(commandMessage.StoreID);
  76. var category = GetCategory(store, commandMessage.ID);
  77. var products = store.Products.Where(p => p.Category.ID==category.ID).ToList();
  78. if (products.Count > 0)
  79. throw new ApplicationException(string.Format("Can not delete {0} because it has product dependencies!", category.Name));
  80. store.RemoveProductCategory(category);
  81. _StoreRepository.Modify(store);
  82. }
  83. [UnitOfWorkConversationPart]
  84. public long Handle(ImportProductCategories commandMessage)
  85. {
  86. if (commandMessage.SelectedProductCategories == null | commandMessage.SelectedProductCategories.Length <= 0)
  87. throw new ApplicationException("There are no Product Categories to import!");
  88. long count = 0;
  89. var store = GetStore(commandMessage.ID);
  90. var systemStore = GetSystemStore();
  91. foreach (var guid in commandMessage.SelectedProductCategories)
  92. {
  93. var systemProductCategory = GetCategory(systemStore, guid);
  94. var productCategory = store.Categories.Where(pc => pc.Name == systemProductCategory.Name).SingleOrDefault();
  95. if (productCategory==null)
  96. {
  97. var productCategoryCommand = new AddNewProductCategory { StoreID = store.ID, Name = systemProductCategory.Name, IsActive=true };
  98. productCategory = new ProductCategory(store, productCategoryCommand, systemProductCategory.SuperCategory);
  99. store.AddProductCategory(productCategory);
  100. count++;
  101. }
  102. if (commandMessage.IsImportProducts)
  103. {
  104. // Get all product available for this "System Defined" Store for this product category
  105. foreach (var systemProduct in systemStore.Products.Where(p=>p.Category.ID==systemProductCategory.ID))
  106. {
  107. var product = store.Products.Where(p => p.Name == systemProduct.Name).SingleOrDefault();
  108. if (product == null)
  109. {
  110. var productCommand = new AddNewProduct { StoreID = store.ID, Name = systemProduct.Name, ProductCategoryID = productCategory.ID };
  111. product = new Product(store, productCategory, productCommand);
  112. store.AddProduct(product);
  113. }
  114. }
  115. }
  116. }
  117. store = _StoreRepository.Modify(store);
  118. return count;
  119. }
  120. #endregion Product Categories
  121. #region Products
  122. [UnitOfWorkConversationPart]
  123. public Product Handle(AddNewProduct commandMessage)
  124. {
  125. var store = GetSingle(g => g.ID == commandMessage.StoreID);
  126. if (store == null)
  127. throw new ApplicationException(string.Format("Could not retrieve Store with ID = '{0}'", commandMessage.StoreID));
  128. ProductCategory productCategory = GetCategory(store, commandMessage.ProductCategoryID);
  129. var product = new Product(store, productCategory, commandMessage);
  130. Validate(store, product);
  131. store.AddProduct(product);
  132. store = _StoreRepository.Modify(store);
  133. return GetProduct(store, commandMessage.Name);
  134. }
  135. [UnitOfWorkConversationPart]
  136. public void Handle(ChangeProduct commandMessage)
  137. {
  138. var store = GetStore(commandMessage.StoreID);
  139. var product = GetProduct(store, commandMessage.ID);
  140. ProductCategory productCategory = GetCategory(store, commandMessage.ProductCategoryID);
  141. product.Change(commandMessage, productCategory);
  142. Validate(store, product);
  143. _StoreRepository.Modify(store);
  144. }
  145. [UnitOfWorkConversationPart]
  146. public void Handle(DeleteProduct commandMessage)
  147. {
  148. var store = GetStore(commandMessage.StoreID);
  149. var product = GetProduct(store, commandMessage.ID);
  150. var shoppingLists = store.Shopper.ShoppingLists;
  151. foreach (var sl in shoppingLists)
  152. {
  153. foreach (var sld in sl.Detail)
  154. {
  155. if (sld.Product.ID == product.ID)
  156. {
  157. throw new ApplicationException(string.Format("Can not delete {0} because it has Shopping List dependencies!", product.Name));
  158. }
  159. }
  160. }
  161. store.RemoveProduct(product);
  162. _StoreRepository.Modify(store);
  163. }
  164. #endregion Products
  165. Store GetStore(Guid storeID)
  166. {
  167. var store = GetSingle(s => s.ID == storeID);
  168. if (store == null)
  169. throw new ApplicationException(string.Format("Could not retrieve Store with ID = '{0}'", storeID));
  170. return store;
  171. }
  172. Store GetSystemStore()
  173. {
  174. var store = GetSingle(s => s.Name == "System Defined");
  175. if (store == null)
  176. throw new ApplicationException("Could not retrieve System Store!");
  177. return store;
  178. }
  179. ProductCategory GetCategory(Store store, Guid pcID)
  180. {
  181. var category = store.Categories.Where(s => s.ID == pcID).SingleOrDefault();
  182. if (category == null)
  183. throw new ApplicationException(string.Format("Could not retrieve Product Category with ID = '{0}'", pcID));
  184. return category;
  185. }
  186. ProductCategory GetCategory(Store store, string name)
  187. {
  188. var category = store.Categories.Where(s => s.Name == name).SingleOrDefault();
  189. if (category == null)
  190. throw new ApplicationException(string.Format("Could not retrieve Product Category with Name = '{0}'", name));
  191. return category;
  192. }
  193. void Validate(Store store, ProductCategory category)
  194. {
  195. CheckIfAlreadyExists(store, category);
  196. string validationErrors = EntityValidatorService<ProductCategory>.Validate(new ProductCategoryRules(), category);
  197. if (!string.IsNullOrEmpty(validationErrors))
  198. throw new ApplicationException(validationErrors);
  199. }
  200. void CheckIfAlreadyExists(Store store, ProductCategory category)
  201. {
  202. var p = store.Categories.Where(c => c.Name == category.Name).SingleOrDefault();
  203. if (p != null && category.ID != p.ID)
  204. throw new ApplicationException(string.Format("There is already a Category with name '{0}' in '{1}'!", category.Name, store.Name));
  205. }
  206. void Validate(Store store, Product product)
  207. {
  208. CheckIfAlreadyExists(store, product);
  209. string validationErrors = EntityValidatorService<Product>.Validate(new ProductRules(), product);
  210. if (!string.IsNullOrEmpty(validationErrors))
  211. throw new ApplicationException(validationErrors);
  212. }
  213. void CheckIfAlreadyExists(Store store, Product product)
  214. {
  215. var p = store.Products.Where(c => c.Name == product.Name).SingleOrDefault();
  216. if (p != null && product.ID != p.ID)
  217. throw new ApplicationException(string.Format("There is already a Product with name '{0}' in '{1}'!", product.Name, store.Name));
  218. }
  219. Product GetProduct(Store store, string name)
  220. {
  221. var product = store.Products.Where(s => s.Name == name).SingleOrDefault();
  222. if (product == null)
  223. throw new ApplicationException(string.Format("Could not retrieve Product with Name = '{0}'", name));
  224. return product;
  225. }
  226. Product GetProduct(Store store, Guid pcID)
  227. {
  228. var product = store.Products.Where(s => s.ID == pcID).SingleOrDefault();
  229. if (product == null)
  230. throw new ApplicationException(string.Format("Could not retrieve Product with ID = '{0}'", pcID));
  231. return product;
  232. }
  233. }
  234. }