CustomerService.cs 13 KB

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