CustomerService.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. using Microsoft.Extensions.Logging;
  2. using Quadarax.Application.QLiberace.Base.Dtos;
  3. using Quadarax.Application.QLiberace.Base.Entities;
  4. using Quadarax.Application.QLiberace.Base.Mapper;
  5. using Quadarax.Application.QLiberace.Base.Repositories;
  6. using Quadarax.Application.QLiberace.Common;
  7. using Quadarax.Application.QLiberace.Common.Domain;
  8. using Quadarax.Application.QLiberace.Customer.Dtos;
  9. using Quadarax.Application.QLiberace.Customer.Dtos.Validators;
  10. using Quadarax.Application.QLiberace.Customer.Entities;
  11. using Quadarax.Application.QLiberace.Customer.Enums;
  12. using Quadarax.Application.QLiberace.Customer.Repositories;
  13. using Quadarax.Foundation.Core.Business;
  14. using Quadarax.Foundation.Core.Data.Interface.Domain;
  15. using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
  16. using Quadarax.Foundation.Core.Exceptions;
  17. using Quadarax.Foundation.Core.Logging;
  18. using Quadarax.Foundation.Core.Value;
  19. namespace Quadarax.Application.QLiberace.Customer.Services
  20. {
  21. public class CustomerService : AbstractMultiRepositoryService<RepoCustomer,RepoContact, RepoUser, RepoCountry>
  22. {
  23. #region *** Constructor ***
  24. public CustomerService(RepoCustomer repository1, RepoContact repository2, RepoUser repository3, RepoCountry repository4, IContext currentContext, IQLogger logger) : base(repository1, repository2, repository3, repository4, currentContext, logger)
  25. {
  26. }
  27. #endregion
  28. #region *** Public operations ***
  29. #region **** Customer ****
  30. public ResultValueDto<CustomerRDto?> CreateCustomer(CustomerWDto customer)
  31. {
  32. if (customer==null) throw new ArgumentNullException(nameof(customer));
  33. return TryCatchBlock(() =>
  34. {
  35. ValidateWDto(customer);
  36. var customerDao = Repository1.New();
  37. customer.CopyToDto(customerDao);
  38. return new ResultValueDto<CustomerRDto?>(customerDao.Map<Entities.Customer, CustomerRDto>());
  39. });
  40. }
  41. public ResultDto UpdateCustomer(string customerCode, CustomerWDto customer)
  42. {
  43. if (customer==null) throw new ArgumentNullException(nameof(customer));
  44. return TryCatchBlock(() =>
  45. {
  46. ValidateWDto(customer);
  47. var customerDao = FetchCustomer(customerCode);
  48. customer.CopyToDto(customerDao);
  49. return new ResultValueDto<CustomerRDto?>(customerDao.Map<Entities.Customer, CustomerRDto>());
  50. });
  51. }
  52. public ResultDto DeleteCustomer(long customerId)
  53. {
  54. return TryCatchBlock(() =>
  55. {
  56. var result = FetchCustomer(customerId);
  57. Repository1.Remove(customerId);
  58. return new ResultPlain();
  59. });
  60. }
  61. public ResultValueDto<CustomerRDto?> GetCustomer(string customerCode)
  62. {
  63. return TryCatchBlock(() =>
  64. {
  65. var customerDao = FetchCustomer(customerCode);
  66. return new ResultValueDto<CustomerRDto?>(customerDao.Map<Entities.Customer, CustomerRDto>());
  67. });
  68. }
  69. public ResultValueDto<CustomerRDto?> GetCustomer(long customerId)
  70. {
  71. return TryCatchBlock(() =>
  72. {
  73. var customerDao = FetchCustomer(customerId);
  74. return new ResultValueDto<CustomerRDto?>(customerDao.Map<Entities.Customer, CustomerRDto>());
  75. });
  76. }
  77. public ResultBoolDto ExistsCustomer(string customerCode)
  78. {
  79. return TryCatchBlock(() => new ResultBoolDto(FetchCustomer(customerCode)!=null));
  80. }
  81. #endregion
  82. #region **** User Assignments ****
  83. public ResultDto AssignUser(string customerCode, string userLogin)
  84. {
  85. return TryCatchBlock(() =>
  86. {
  87. var customerDao = FetchCustomer(customerCode);
  88. FetchUser(userLogin);
  89. if (customerDao!.Users.Any(x=>string.Equals(x.UserLoginName, userLogin)))
  90. throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerUserAlreadyAssignedCode, "code",customerCode, userLogin);
  91. customerDao.Users.Add(new CustomerUser()
  92. {
  93. CustomerId = customerDao.Id,
  94. UserLoginName = userLogin
  95. });
  96. return new ResultPlain();
  97. });
  98. }
  99. public ResultDto UnAssignUser(string customerCode, string userLogin)
  100. {
  101. return TryCatchBlock(() =>
  102. {
  103. var customerDao = FetchCustomer(customerCode);
  104. FetchUser(userLogin);
  105. var customerUser = customerDao!.Users.FirstOrDefault(x => string.Equals(x.UserLoginName, userLogin));
  106. if (customerUser == null)
  107. throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerUserNotFoundAssignedCode, "code",customerCode, userLogin);
  108. customerDao.Users.Remove(customerUser);
  109. return new ResultPlain();
  110. });
  111. }
  112. #endregion
  113. #region **** Customer Constacts ****
  114. public ResultValueDto<ContactRDto?> CreateContact(string customerCode, ContactWDto contact)
  115. {
  116. if (contact==null) throw new ArgumentNullException(nameof(contact));
  117. return TryCatchBlock(() =>
  118. {
  119. var customerDao = FetchCustomer(customerCode);
  120. ValidateWDto(contact);
  121. var contactDao = Repository2.New();
  122. contactDao.Customer = customerDao!;
  123. contact.CopyToDto(contactDao);
  124. return new ResultValueDto<ContactRDto?>(contactDao.Map<Contact, ContactRDto>());
  125. });
  126. }
  127. public ResultDto UpdateContact(long contactId, ContactWDto contact)
  128. {
  129. if (contact==null) throw new ArgumentNullException(nameof(contact));
  130. return TryCatchBlock(() =>
  131. {
  132. var contactDao = FetchContact(contactId);
  133. ValidateWDto(contact);
  134. contact.CopyToDto(contactDao);
  135. return new ResultValueDto<ContactRDto?>(contactDao.Map<Contact, ContactRDto>());
  136. });
  137. }
  138. public ResultDto DeleteContact(long contactId)
  139. {
  140. return TryCatchBlock(() =>
  141. {
  142. Repository2.Remove(contactId);
  143. return new ResultPlain();
  144. });
  145. }
  146. public ResultValueDto<ContactRDto?> GetContact(long contactId)
  147. {
  148. return TryCatchBlock(() =>
  149. {
  150. var contactDao = FetchContact(contactId);
  151. return new ResultValueDto<ContactRDto?>(contactDao.Map<Contact, ContactRDto>());
  152. });
  153. }
  154. public ResultsValueDto<ContactRDto?> GetContacts(string customerCode)
  155. {
  156. return TryCatchBlock(() =>
  157. {
  158. var customerDao = FetchCustomer(customerCode);
  159. return new ResultsValueDto<ContactRDto?>(customerDao!.Contacts.MapList<Contact, ContactRDto>());
  160. });
  161. }
  162. public ResultsValueDto<ContactRDto?> GetPreferredContacts(string customerCode, params ContactTypeEnum[] contactTypes)
  163. {
  164. if (contactTypes == null || contactTypes.Length == 0) throw new ArgumentNullException(nameof(contactTypes));
  165. return TryCatchBlock(() =>
  166. {
  167. var customerDao = FetchCustomer(customerCode);
  168. return new ResultsValueDto<ContactRDto?>(customerDao!.Contacts.Where(x=>x.IsPreferred && contactTypes.Contains(x.Type)).MapList<Contact, ContactRDto>());
  169. });
  170. }
  171. public ResultDto ValidateContacts(string customerCode)
  172. {
  173. return TryCatchBlock(() =>
  174. {
  175. var customerDao = FetchCustomer(customerCode);
  176. var contactTypes = new List<ContactTypeEnum>(new[]
  177. { ContactTypeEnum.Address, ContactTypeEnum.Email, ContactTypeEnum.Phone });
  178. var contacts = customerDao!.Contacts.Where(x => x.IsPreferred && contactTypes.Contains(x.Type)).ToArray();
  179. if (contacts!=null && !contacts.Any())
  180. throw ExceptionFactory.CreateException(
  181. ExceptionLibrary.ExceptionsCodes.CustomerMissingContactCode, "code", customerCode);
  182. var elist = new List<CodeException>();
  183. if (contacts?.Count(x=>x.IsPreferred && x.Type == ContactTypeEnum.Address) != 1) elist.Add(ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerMissingAddressCode, "code",customerCode));
  184. if (contacts?.Count(x=>x.IsPreferred && x.Type == ContactTypeEnum.Phone) != 1) elist.Add(ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerMissingPhoneCode, "code",customerCode));
  185. if (contacts?.Count(x=>x.IsPreferred && x.Type == ContactTypeEnum.Email) != 1) elist.Add(ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerMissingEmailCode, "code",customerCode));
  186. if (elist.Count > 0)
  187. throw new AggregateException(elist);
  188. return new ResultPlain();
  189. });
  190. }
  191. #endregion
  192. #endregion
  193. #region *** Private Operations ***
  194. private void ValidateWDto(CustomerWDto customer)
  195. {
  196. if (customer == null) throw new ArgumentNullException(nameof(customer));
  197. var validator = new CustomerValidator();
  198. validator.Validate(customer, new ValidatorContext(new KeyValuePair<string, object>[]{ new("RepoCountry", Repository4)}));
  199. if (!validator.IsSuccess) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.ValidationErrorsCode, validator.ToAggregateException());
  200. }
  201. private void ValidateWDto(ContactWDto contact)
  202. {
  203. if (contact == null) throw new ArgumentNullException(nameof(contact));
  204. var validator = new ContactValidator();
  205. validator.Validate(contact, new ValidatorContext(new KeyValuePair<string, object>[]{ new("RepoCountry", Repository4)}));
  206. if (!validator.IsSuccess) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.ValidationErrorsCode, validator.ToAggregateException());
  207. }
  208. private void ValidateSameTenant(TenantWDto tenant)
  209. {
  210. if (tenant == null) throw new ArgumentNullException(nameof(tenant));
  211. var currentTenantCode = CurrentContext.GetContext<QlbrcContext>().TenantCode;
  212. if (!string.Equals(currentTenantCode, tenant.Code, StringComparison.InvariantCulture))
  213. throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.TenantDifferentContextCode, tenant.Code, currentTenantCode!);
  214. }
  215. private Entities.Customer? FetchCustomer(string customerCode)
  216. {
  217. if (string.IsNullOrEmpty(customerCode)) throw new ArgumentNullException(nameof(customerCode));
  218. var exists = Repository1.GetByCode(customerCode);
  219. if (exists != null) throw
  220. ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerNotFoundCode, "code", customerCode);
  221. return exists;
  222. }
  223. private User? FetchUser(string userLogin)
  224. {
  225. if (string.IsNullOrEmpty(userLogin)) throw new ArgumentNullException(nameof(userLogin));
  226. var exists = Repository3.GetByLoginName(userLogin);
  227. if (exists != null) throw
  228. ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.UserNotFoundCode, "loginName", userLogin);
  229. return exists;
  230. }
  231. private Entities.Customer? FetchCustomer(long customerId)
  232. {
  233. var exists = Repository1.Get(customerId);
  234. if (exists != null) throw
  235. ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerNotFoundCode, "id", customerId.ToString());
  236. return exists;
  237. }
  238. private Contact? FetchContact(long contactId)
  239. {
  240. var exists = Repository2.Get(contactId);
  241. if (exists != null) throw
  242. ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.ContactNotFoundCode, "id", contactId.ToString());
  243. return exists;
  244. }
  245. #endregion
  246. }
  247. }