Base solution for your next web application

Activities of "datalab"

Hi @ismcagdas Thanks You di solution work fine. I'have add _abpsession.using in BackgroundJob how in example. Best Regards

Hi Zony TenatId is null :-(

Hi zony i have try your solution but it not work, i have also try to resolve instance of EMail Sender inside the using block, but how you see in follow image it is not resolved by tenant.

Hello When i try to send email whit method SendCourseEnrollementEmail the emailSender use host configuration and not tenant configuration, if i use the test email from tenant ui Smtp Settings it work fine.

Best Regards

Prerequisites

se answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.

  • What is your product version? Module Zero 8.4.0
  • What is your product type (Angular or MVC)? angular
  • What is product framework type (.net framework or .net core)? .net Core 3.1

AllowTenantsToChangeEmailSettings = true* ` public class EcoSectConsts { public const string LocalizationSourceName = "EcoSect";

    public const string ConnectionStringName = "Default";

    public const bool MultiTenancyEnabled = true;

    public const bool AllowTenantsToChangeEmailSettings = true;

    public const string Currency = "EUR";

    public const string CurrencySign = "€";

    public const string AbpApiClientUserAgent = "AbpApiClient";

    // Note:
    // Minimum accepted payment amount. If a payment amount is less then that minimum value payment progress will continue without charging payment
    // Even though we can use multiple payment methods, users always can go and use the highest accepted payment amount.
    //For example, you use Stripe and PayPal. Let say that stripe accepts min 5$ and PayPal accepts min 3$. If your payment amount is 4$.
    // User will prefer to use a payment method with the highest accept value which is a Stripe in this case.
    public const decimal MinimumUpgradePaymentAmount = 1M;
}`

Application Service Method call Job
` [AbpAuthorize(AppPermissions.Pages_CourseLeads_SendEmail)]
    public async Task SendCourseEnrollementEmail(SendCourseEnrollementEmailInput input)
    {          
        using(CurrentUnitOfWork.SetTenantId(AbpSession.TenantId))
        { 
        await _backgroundJobManager.EnqueueAsync<SendCourseEnrollementEmailJob, SendCourseEnrollementEmailJobArgs>(
               new SendCourseEnrollementEmailJobArgs
               {
                   CourseId = input.CourseId,
                   CustomersIds = input.CustomersIds,
                   User = AbpSession.ToUserIdentifier(),
                   TenantId = AbpSession.TenantId
               });
        }
    }`
    
    Job Worker Code
    ` public override void Execute(SendCourseEnrollementEmailJobArgs args)
    {

        var courseLeads = _courseLeadRepository.GetAll()
                              .Include(e => e.Course)
                              .ThenInclude(e => e.CourseCategory)
                              .Include(e => e.Course)
                              .ThenInclude(e => e.CourseLocation)
                              .Include(e => e.Course)
                              .ThenInclude(e => e.CourseLessons)
                              .ThenInclude(e => e.Teacher)
                              .Include(e => e.Customer)
                              .Include(e => e.CourseLeadEmployees)
                              .ThenInclude(e => e.Employee)
                              .Where(e => e.CourseId == args.CourseId)
                              .WhereIf(args.CustomersIds.Count > 0, e => args.CustomersIds.Any(id => id == e.CustomerId))
                              .ToList();

        string courseName = courseLeads.FirstOrDefault()?.Course.Name;

        string invalidSendMessage = "Non è stato possibile inviare il messaggio al seguente destinatario {0} per il seguente motivo: {1}";

        foreach (var courseLead in courseLeads)
        {
            try
            {
                if (string.IsNullOrEmpty(courseLead.Customer?.MarketingEmail))
                {
                    AsyncHelper.RunSync(() => SendInvalidEmailNotification(args, string.Format(invalidSendMessage, courseLead.Customer.Name, "Al cliente non è stato impostato l'indirizzo Email Marketing.")));
                }
                else
                {
                    TryToSendCourseEnrollementEmailInput tryToSendCourseEnrollementEmailInput = new TryToSendCourseEnrollementEmailInput();
                    tryToSendCourseEnrollementEmailInput.TenantId = args.TenantId;
                    tryToSendCourseEnrollementEmailInput.CourseLead = courseLead;

                    AsyncHelper.RunSync(() => _courseEmailer.TryToSendCourseEnrollementEmail(tryToSendCourseEnrollementEmailInput));

                    courseLead.Status = CourseLeadStatus.SendedComunication;

                }

            }
            catch (UserFriendlyException exception)
            {
                AsyncHelper.RunSync(() => SendInvalidEmailNotification(args, string.Format(invalidSendMessage, courseLead.Customer.Name, exception.Message)));
            }
            catch (Exception exception)
            {
                AsyncHelper.RunSync(() => SendInvalidEmailNotification(args, string.Format(invalidSendMessage, courseLead.Customer.Name, exception.ToString())));
            }
        }

        AsyncHelper.RunSync(() => SendSurveyCompletedNotification(args, string.Format("L'invio delle email per il corso {0} è stato avviato.", courseName)));

    }`
    
    Course Emailer code TryToSendCourseEnrollementEmail
    `public async Task TryToSendCourseEnrollementEmail(TryToSendCourseEnrollementEmailInput input)
    {
        
        var emailTemplate = new StringBuilder(_emailTemplateProvider.GetCourseEnrollementTemplate(input.TenantId));
        var emailTransformed = TransformEmail(emailTemplate, input.CourseLead);

        await _emailSender.SendAsync(new MailMessage
        {
            To = { input.CourseLead.Customer.MarketingEmail },
            Subject = "Certificazioni in Scadenza",
            Body = emailTransformed,
            IsBodyHtml = true, 
            CC = { _ecoSectSmtpEmailSenderConfiguration.DefaultFromAddress },
        });
    }`
    
    

Tanks i found the switchToAccount function, that resolve my problem.

Best Regards Dennis Bellancini

Prerequisites

Please answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.

  • What is your product version?
  • Module zero 8.4
  • What is your product type (Angular or MVC)?
  • Angular
  • What is product framework type (.net framework or .net core)? .net core 3.1

Hello I have a specific user that is created for each tenant with the same username and password who must be able to manage tasks that i asigned from different tenants. Each time the user login to a tenant is shown a table with the tasks that the various tenants have assigned to him, I get this data using a query filtered data by username and disabling the filter for tenant using (CurrentUnitOfWork.DisableFilter (AbpDataFilters.MustHaveTenant) ) However, whenever the user has need to update the task data, he must log out and log in again on the specific tenant, it is possible to create a script that allows the user to connect to the specified tenant by clicking to a link or button ?. I have this information in task data TenantId, TenancyName, UserId, Username.

Tankyou

Tank you very mutch.

Hello I need to add a custom field CustomerId to Abp Session , what is the best way to extend AbpSession? Then I need to use this field to filter the data. this is a correct solution https://docs.microsoft.com/en-us/ef/core/querying/filters ?.

I have AspNet Zero 8.1, Angular, .Net Core.

Best Regards Dennis Bellancini

Tankyou i have revolded add my custom check here https://github.com/aspnetzero/aspnet-zero-core/blob/51233d56669623ad85186cb80371489ed15ea5c1/angular/src/app/shared/common/auth/auth-route-guard.ts#L94

Showing 1 to 10 of 23 entries