using Microsoft.Extensions.Logging; using Quadarax.Application.QLiberace.Base.Dtos; using Quadarax.Application.QLiberace.Base.Entities; using Quadarax.Application.QLiberace.Base.Mapper; using Quadarax.Application.QLiberace.Base.Repositories; using Quadarax.Application.QLiberace.Common; using Quadarax.Application.QLiberace.Common.Domain; using Quadarax.Application.QLiberace.Customer.Dtos; using Quadarax.Application.QLiberace.Customer.Dtos.Validators; using Quadarax.Application.QLiberace.Customer.Entities; using Quadarax.Application.QLiberace.Customer.Enums; using Quadarax.Application.QLiberace.Customer.Repositories; using Quadarax.Foundation.Core.Business; using Quadarax.Foundation.Core.Data.Interface.Domain; using Quadarax.Foundation.Core.Data.Interface.Entity.Dto; using Quadarax.Foundation.Core.Value; namespace Quadarax.Application.QLiberace.Customer.Services { public class CustomerService : AbstractMultiRepositoryService { #region *** Constructor *** public CustomerService(RepoCustomer repository1, RepoContact repository2, RepoUser repository3, RepoCountry repository4, IContext currentContext, ILoggerFactory logger) : base(repository1, repository2, repository3, repository4, currentContext, logger) { } #endregion #region *** Public operations *** #region **** Customer **** public ResultValueDto CreateCustomer(CustomerWDto customer) { if (customer==null) throw new ArgumentNullException(nameof(customer)); return TryCatchBlock(() => { ValidateWDto(customer); var customerDao = Repository1.New(); customer.CopyToDto(customerDao); return new ResultValueDto(customerDao.Map()); }); } public ResultDto UpdateCustomer(string customerCode, CustomerWDto customer) { if (customer==null) throw new ArgumentNullException(nameof(customer)); return TryCatchBlock(() => { ValidateWDto(customer); var customerDao = FetchCustomer(customerCode); customer.CopyToDto(customerDao); return new ResultValueDto(customerDao.Map()); }); } public ResultDto DeleteCustomer(long customerId) { return TryCatchBlock(() => { var result = FetchCustomer(customerId); Repository1.Remove(customerId); return new ResultPlain(); }); } public ResultValueDto GetCustomer(string customerCode) { return TryCatchBlock(() => { var customerDao = FetchCustomer(customerCode); return new ResultValueDto(customerDao.Map()); }); } public ResultValueDto GetCustomer(long customerId) { return TryCatchBlock(() => { var customerDao = FetchCustomer(customerId); return new ResultValueDto(customerDao.Map()); }); } public ResultBoolDto ExistsCustomer(string customerCode) { return TryCatchBlock(() => new ResultBoolDto(FetchCustomer(customerCode)!=null)); } #endregion #region **** User Assignments **** public ResultDto AssignUser(string customerCode, string userLogin) { return TryCatchBlock(() => { var customerDao = FetchCustomer(customerCode); FetchUser(userLogin); if (customerDao!.Users.Any(x=>string.Equals(x.UserLoginName, userLogin))) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerUserAlreadyAssignedCode, "code",customerCode, userLogin); customerDao.Users.Add(new CustomerUser() { CustomerId = customerDao.Id, UserLoginName = userLogin }); return new ResultPlain(); }); } public ResultDto UnAssignUser(string customerCode, string userLogin) { return TryCatchBlock(() => { var customerDao = FetchCustomer(customerCode); FetchUser(userLogin); var customerUser = customerDao!.Users.FirstOrDefault(x => string.Equals(x.UserLoginName, userLogin)); if (customerUser == null) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerUserNotFoundAssignedCode, "code",customerCode, userLogin); customerDao.Users.Remove(customerUser); return new ResultPlain(); }); } #endregion #region **** Customer Constacts **** public ResultValueDto CreateContact(string customerCode, ContactWDto contact) { if (contact==null) throw new ArgumentNullException(nameof(contact)); return TryCatchBlock(() => { var customerDao = FetchCustomer(customerCode); ValidateWDto(contact); var contactDao = Repository2.New(); contact.CopyToDto(contactDao); return new ResultValueDto(contactDao.Map()); }); } public ResultDto UpdateContact(string customerCode, ContactWDto contact) { throw new NotImplementedException(); } public ResultDto DeleteContact(long contactId) { throw new NotImplementedException(); } public ResultValueDto GetContact(long contactId) { throw new NotImplementedException(); } public ResultsValueDto GetContacts(string customerCode) { throw new NotImplementedException(); } public ResultsValueDto GetPreferredContacts(string customerCode, params ContactTypeEnum[] contactTypes) { throw new NotImplementedException(); } public ResultDto ValidateContacts(string customerCode) { throw new NotImplementedException(); } #endregion #endregion #region *** Private Operations *** private void ValidateWDto(CustomerWDto customer) { if (customer == null) throw new ArgumentNullException(nameof(customer)); var validator = new CustomerValidator(); validator.Validate(customer, new ValidatorContext(new KeyValuePair[]{ new("RepoCountry", Repository4)})); if (!validator.IsSuccess) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.ValidationErrorsCode, validator.ToAggregateException()); } private void ValidateWDto(ContactWDto contact) { if (contact == null) throw new ArgumentNullException(nameof(contact)); var validator = new ContactValidator(); validator.Validate(contact, new ValidatorContext(new KeyValuePair[]{ new("RepoCountry", Repository4)})); if (!validator.IsSuccess) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.ValidationErrorsCode, validator.ToAggregateException()); } private void ValidateSameTenant(TenantWDto tenant) { if (tenant == null) throw new ArgumentNullException(nameof(tenant)); var currentTenantCode = CurrentContext.GetContext().TenantCode; if (!string.Equals(currentTenantCode, tenant.Code, StringComparison.InvariantCulture)) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.TenantDifferentContextCode, tenant.Code, currentTenantCode!); } private Entities.Customer? FetchCustomer(string customerCode) { if (string.IsNullOrEmpty(customerCode)) throw new ArgumentNullException(nameof(customerCode)); var exists = Repository1.GetByCode(customerCode); if (exists != null) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerNotFoundCode, "code", customerCode); return exists; } private User? FetchUser(string userLogin) { if (string.IsNullOrEmpty(userLogin)) throw new ArgumentNullException(nameof(userLogin)); var exists = Repository3.GetByLoginName(userLogin); if (exists != null) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.UserNotFoundCode, "loginName", userLogin); return exists; } private Entities.Customer? FetchCustomer(long customerId) { var exists = Repository1.Get(customerId); if (exists != null) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.CustomerNotFoundCode, "id", customerId.ToString()); return exists; } #endregion } }