Esempio n. 1
0
def thankyou(request, *args, **kwargs):
    dara_list = Dara.objects.all()
    participant_list = Participant.objects.all()
    dara_email_list = []

    sender = 'ikwen Daraja <*****@*****.**>'

    for dara in dara_list:
        dara_lang = dara.member.language

        if dara_lang == 'en':
            cta_url = 'https://blog.ikwen.com/from-social-network-to-daraja/'
        else:
            cta_url = 'https://blog.ikwen.com/des-reseaux-sociaux-a-daraja/'

        activate(dara_lang)
        dara_name = dara.member.first_name
        dara_email = dara.member.email
        subject = _("Start making money now !")
        html_content = get_mail_content(
            subject,
            template_name='smartevent/mails/thank-you.html',
            extra_context={
                'dara_name': dara_name,
                'cta_url': cta_url
            })
        msg = EmailMessage(subject, html_content, sender, [dara_email])
        msg.content_subtype = "html"
        msg.extra_headers = {'Reply-To': '*****@*****.**'}
        Thread(target=lambda m: m.send(), args=(msg, )).start()
        dara_email_list.append(dara_email)

    for participant in participant_list:
        cta_url = 'https://blog.ikwen.com/des-reseaux-sociaux-a-daraja/'
        if participant.email in dara_email_list:
            continue
        lang = 'fr'
        activate(lang)
        dara_name = participant.first_name
        dara_email = participant.email
        subject = _("Start making money now !")
        html_content = get_mail_content(
            subject,
            template_name='smartevent/mails/thank-you.html',
            extra_context={
                'dara_name': dara_name,
                'cta_url': cta_url,
            })
        msg = EmailMessage(subject, html_content, sender, [dara_email])
        msg.content_subtype = "html"
        msg.extra_headers = {'Reply-To': '*****@*****.**'}
        Thread(target=lambda m: m.send(), args=(msg, )).start()

    response = {"success": True}
    return HttpResponse(json.dumps(response), 'content-type: text/json')
def notify_staff(backup):
    # now = datetime.now()
    # start = now - timedelta(days=7)
    # for backup in Backup.objects.order_by('-id').filter(status=FAILED):
    sender = 'ikwen DBBACKUP <*****@*****.**>'
    subject = _("New failed backup")
    recipient_list = [get_service_instance().member.email]
    staff_list = [
        staff.email for staff in Member.objects.filter(is_staff=True)
    ]
    job_config = backup.job_config
    extra_context = {
        'hostname': job_config.hostname,
        'db_name': job_config.db_name,
        'db_type': job_config.db_type,
        'status': backup.status,
        'start_time': backup.created_on,
        'file_size_hr': backup.file_size_hr,
        'error_messages': backup.error_messages
    }
    activate('en')
    try:
        html_content = get_mail_content(
            subject,
            template_name='dbbackup/mails/failed_backup_notification.html',
            extra_context=extra_context)
    except:
        logger.error("Could not generate HTML content from template",
                     exc_info=True)
        return
    msg = EmailMessage(subject, html_content, sender, recipient_list)
    msg.content_subtype = "html"
    msg.bcc = staff_list
    msg.send()
Esempio n. 3
0
def confirm_bundle_payment(request, *args, **kwargs):
    """
    This function has no URL associated with it.
    It serves as ikwen setting "MOMO_AFTER_CHECKOUT"
    """
    service = get_service_instance()
    config = service.config
    refill_id = request.session['object_id']

    member = request.user
    if member.email:
        try:
            subject = _("Get your support code")
            html_content = get_mail_content(
                subject,
                template_name='echo/mails/successful_refill.html',
                extra_context={'member_name': member.first_name})
            sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
            msg = EmailMessage(subject, html_content, sender, [member.email])
            msg.content_subtype = "html"
            if member != service.member:
                msg.cc = [service.member.email]
            Thread(target=lambda m: m.send(), args=(msg, )).start()
        except:
            pass
    return HttpResponseRedirect(request.session['return_url'])
Esempio n. 4
0
def send_dara_notification_email(dara_service, order):
    service = get_service_instance()
    config = service.config
    template_name = 'daraja/mails/new_transaction.html'

    activate(dara_service.member.language)
    subject = _("New transaction on %s" % config.company_name)
    try:
        dashboard_url = 'http://daraja.ikwen.com' + reverse('daraja:dashboard')
        extra_context = {'currency_symbol': config.currency_symbol, 'amount': order.items_cost,
                         'dara_earnings': order.referrer_earnings,
                         'tx_date': order.updated_on.strftime('%Y-%m-%d'),
                         'tx_time': order.updated_on.strftime('%H:%M:%S'),
                         'account_balance': dara_service.balance,
                         'dashboard_url': dashboard_url}
        try:
            dara = Dara.objects.using(UMBRELLA).get(member=dara_service.member)
            extra_context['dara'] = dara
        except:
            pass
        html_content = get_mail_content(subject, template_name=template_name, extra_context=extra_context)
        sender = 'ikwen Daraja <*****@*****.**>'
        msg = XEmailMessage(subject, html_content, sender, [dara_service.member.email])
        msg.content_subtype = "html"
        Thread(target=lambda m: m.send(), args=(msg,)).start()
    except:
        logger.error("Failed to notify %s Dara after follower purchase." % service, exc_info=True)
Esempio n. 5
0
    def after_save(self, request, obj, *args, **kwargs):
        """"
        Notify the teacher when a student send his homework
        """
        try:
            foulassi = Service.objects.using(UMBRELLA).get(project_name_slug='foulassi')
        except:
            foulassi = None
        student = obj.student
        service = student.school
        db = service.database
        add_database(db)
        classroom = student.classroom
        assignment_id = request.POST['assignment']
        try:
            assignment = Assignment.objects.using(db).get(pk=assignment_id)
        except:
            raise Http404("Data have been altered")
        assignment_subject = assignment.subject
        teacher = assignment_subject.get_teacher(classroom)  # Retrieve the teacher who gives assignment
        school_config = service.config
        company_name = school_config.company_name
        classroom_name = classroom.name
        sender = '%s via ikwen Foulassi <*****@*****.**>' % student
        # try:
        #     # cta_url = 'https://go.ikwen.com' + reverse('foulassi:change_homework', args=(
        #     #     school_config.company_name_slug, student.pk, assignment.pk))
        # except:
        #     cta_url = ''

        if teacher.member:
            activate(teacher.member.language)
        student_name = student.first_name
        cta_url = service.url + reverse('school:assignment_reply_list', args=(classroom.pk, assignment.pk))
        subject = _(" New homework sent")
        extra_context = {'subject': subject, 'teacher': teacher, 'school_name': company_name, 'cta_url': cta_url,
                         'student_name': student_name, 'assignment': assignment, 'classroom': classroom_name}

        try:
            html_content = get_mail_content(subject,
                                            template_name='foulassi/mails/submitted_homework.html',
                                            extra_context=extra_context)
            teacher_email = teacher.member.email
            msg = EmailMessage(subject, html_content, sender,
                               [teacher_email, '*****@*****.**', '*****@*****.**'])
            msg.content_subtype = "html"
            try:
                msg.send()
            except Exception as e:
                logger.debug(e.message)
        except:
            logger.error("Could not generate HTML content from template", exc_info=True)

        body = _("%(student_name)s from %(classroom)s sent his assignment of %(subject)s about %(assignment_name)s"
                 % {'student_name': student_name, 'classroom': classroom_name,
                    'subject': assignment_subject, 'assignment_name': assignment.title})
        send_push(foulassi, teacher.member, subject, body)

        return HttpResponseRedirect(reverse("foulassi:kid_detail", args=(kwargs['ikwen_name'], student.pk)) +
                                    "?showTab=assignments")
Esempio n. 6
0
 def save_model(self, request, obj, form, change):
     # Send e-mail for manually generated Invoice upon creation
     if change:
         super(InvoiceAdmin, self).save_model(request, obj, form, change)
         return
     obj.number = get_next_invoice_number(auto=False)
     super(InvoiceAdmin, self).save_model(request, obj, form, change)
     member = obj.subscription.member
     service = get_service_instance()
     config = service.config
     subject, message, sms_text = get_invoice_generated_message(obj)
     if member.email:
         add_event(service, NEW_INVOICE_EVENT, member=member, object_id=obj.id)
         invoice_url = service.url + reverse('billing:invoice_detail', args=(obj.id,))
         html_content = get_mail_content(subject, message, template_name='billing/mails/notice.html',
                                         extra_context={'invoice_url': invoice_url})
         # Sender is simulated as being no-reply@company_name_slug.com to avoid the mail
         # to be delivered to Spams because of origin check.
         sender = '%s <no-reply@%s>' % (service.project_name, service.domain)
         msg = EmailMessage(subject, html_content, sender, [member.email])
         msg.content_subtype = "html"
         if msg.send(fail_silently=True):
             obj.reminders_sent = 1
             obj.last_reminder = timezone.now()
     if sms_text:
         if member.phone:
             if config.sms_sending_method == Config.HTTP_API:
                 send_sms(member.phone, sms_text)
             else:
                 QueuedSMS.objects.create(recipient=member.phone, text=sms_text)
def notify_staff():
    now = datetime.now()
    weblet = get_service_instance()
    config = weblet.config
    for obj in PaymentOrder.objects.filter(due_date__lt=now.date()):
        print "Processing notification of payment %f of ref %s\n" % (
            obj.amount, obj.reference_id)
        if obj.last_notice_date:
            diff = now - obj.last_notice_date
            if diff.total_seconds() < 86400:
                print "Skipping Payment of ref: %s\n" % obj.reference_id
                continue
        # Send notification here by email
        subject = _("Outdated Payment Order")
        html_content = get_mail_content(
            subject,
            template_name='council/mails/outdate_payment_orders_notice.html',
            extra_context={
                'currency_symbol': config.currency_symbol,
                'payment_order': obj,
                'ref_id': obj.reference_id,
                'provider': obj.provider,
                'due_date': obj.due_date.strftime('%Y-%m-%d'),
                'issue_date': obj.created_on.strftime('%Y-%m-%d')
            })
        sender = '%s <no-reply@%s>' % (weblet.project_name, weblet.domain)
        msg = EmailMessage(subject, html_content, sender,
                           [config.contact_email])
        msg.content_subtype = "html"
        if getattr(settings, 'UNIT_TESTING', False):
            msg.send()
        else:
            Thread(target=lambda m: m.send(), args=(msg, )).start()
            print "Sending email of outdated payment order to %s\n" % config.contact_email
Esempio n. 8
0
def render_suggest_create_account_mail(target, service, revival, **kwargs):
    if not target.member.is_ghost:
        return None, None, None
    sender = '%s <no-reply@%s>' % (service.project_name, service.domain)
    config = service.config
    try:
        invitation_message = config.__getattribute__('invitation_message')
    except AttributeError:
        return None, None, None
    template_name = 'revival/mails/suggest_create_account.html'
    join_reward_pack_list = kwargs.pop('reward_pack_list', None)
    if join_reward_pack_list:
        subject = _("Join us on ikwen and earn free coupons." %
                    service.project_name)
    else:
        subject = _("Join our community on ikwen.")
    if invitation_message or join_reward_pack_list:
        extra_context = {
            'member_name': target.member.first_name,
            'join_reward_pack_list': join_reward_pack_list,
            'invitation_message': invitation_message
        }
        html_content = get_mail_content(subject,
                                        service=service,
                                        template_name=template_name,
                                        extra_context=extra_context)
    else:
        html_content = None
    return sender, subject, html_content
Esempio n. 9
0
def notify_payment(payment):
    invoice = payment.invoice
    member = invoice.member
    service = get_service_instance()
    config = service.config

    invoicing_config = get_invoicing_config_instance()
    try:
        invoice_pdf_file = generate_pdf_invoice(invoicing_config, invoice)
    except:
        invoice_pdf_file = None

    if member.email:
        invoice_url = service.url + reverse('billing:invoice_detail',
                                            args=(invoice.id, ))
        subject, message, sms_text = get_payment_confirmation_message(
            payment, member)
        html_content = get_mail_content(
            subject,
            message,
            template_name='billing/mails/notice.html',
            extra_context={
                'member_name': member.first_name,
                'invoice': invoice,
                'cta': _("View invoice"),
                'invoice_url': invoice_url
            })
        sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
        msg = XEmailMessage(subject, html_content, sender, [member.email])
        if invoice_pdf_file:
            msg.attach_file(invoice_pdf_file)
        msg.content_subtype = "html"
        Thread(target=lambda m: m.send(), args=(msg, )).start()
Esempio n. 10
0
    def save_model(self, request, obj, form, change):
        # Send e-mail for manually generated Invoice upon creation
        super(SubscriptionAdmin, self).save_model(request, obj, form, change)
        if change:
            return

        # Send e-mail only if e-mail is a valid one. It will be agreed that if a client
        # does not have an e-mail. we create a fake e-mail that contains his phone number.
        # So e-mail containing phone number are invalid.
        member = obj.member
        service = get_service_instance()
        config = service.config
        subject, message, sms_text = get_subscription_registered_message(obj)

        # This helps differentiates from fake email accounts created as [email protected]
        if member.email.find(member.phone) < 0:
            add_event(service, SUBSCRIPTION_EVENT, member=member, object_id=obj.id, model=subscription_model_name)
            html_content = get_mail_content(subject, message, template_name='billing/mails/notice.html')
            # Sender is simulated as being no-reply@company_name_slug.com to avoid the mail
            # to be delivered to Spams because of origin check.
            sender = '%s <no-reply@%s>' % (service.project_name, service.domain)
            msg = EmailMessage(subject, html_content, sender, [member.email])
            msg.content_subtype = "html"
            Thread(target=lambda m: m.send(), args=(msg,)).start()
        if sms_text:
            if member.phone:
                if config.sms_sending_method == Config.HTTP_API:
                    send_sms(member.phone, sms_text)
                else:
                    QueuedSMS.objects.create(recipient=member.phone, text=sms_text)
Esempio n. 11
0
 def save(self, use_https=False, request=None):
     """
     Generates a one-use only link for resetting password and sends to the user.
     """
     service = get_service_instance()
     email = self.cleaned_data["email"]
     active_users = Member.objects.filter(email__iexact=email,
                                          is_active=True)
     for member in active_users:
         # Make sure that no email is sent to a user that actually has
         # a password marked as unusable
         if not member.has_usable_password():
             continue
         current_site = get_current_site(request)
         domain = current_site.domain
         c = {
             'domain': domain,
             'uid': urlsafe_base64_encode(force_bytes(member.pk)),
             'member': member,
             'token': default_token_generator.make_token(member),
             'protocol': 'https' if use_https else 'http',
         }
         subject = _("Password reset instructions")
         html_content = get_mail_content(
             subject,
             template_name=
             'accesscontrol/mails/password_reset_instructions.html',
             extra_context=c)
         sender = '%s <no-reply@%s>' % (service.project_name,
                                        service.domain)
         msg = EmailMessage(subject, html_content, sender, [member.email])
         msg.content_subtype = "html"
         msg.send()
Esempio n. 12
0
def suspend_customers_services():
    """
    This cron task shuts down service and sends notice of Service suspension
    for Invoices which tolerance is exceeded.
    """
    service = get_service_instance()
    config = service.config
    now = timezone.now()
    invoicing_config = InvoicingConfig.objects.all()[0]
    connection = mail.get_connection()
    try:
        connection.open()
    except:
        logger.error(u"Connexion error", exc_info=True)
    count, total_amount = 0, 0
    deadline = now - timedelta(days=invoicing_config.tolerance)
    invoice_qs = Invoice.objects.filter(due_date__lte=deadline, status=Invoice.OVERDUE)
    logger.debug("%d invoice(s) candidate for service suspension." % invoice_qs.count())
    for invoice in invoice_qs:
        subscription = invoice.subscription
        if subscription.plan.raw_monthly_cost == 0:
            continue
        invoice.status = Invoice.EXCEEDED
        invoice.save()
        count += 1
        total_amount += invoice.amount
        try:
            subscription.is_active = False
            subscription.save()
        except:
            logger.error("Error while processing subscription %s" % str(subscription), exc_info=True)
            continue
        member = subscription.service.member
        add_event(service, SERVICE_SUSPENDED_EVENT, member=member, object_id=invoice.id)
        logger.debug("Event posted to %s's Console" % member.username)
        subject, message, sms_text = get_service_suspension_message(invoice)
        if member.email:
            invoice_url = service.url + reverse('billing:invoice_detail', args=(invoice.id,))
            html_content = get_mail_content(subject, message, template_name='billing/mails/notice.html',
                                            extra_context={'invoice_url': invoice_url, 'cta': _("Pay now")})
            # Sender is simulated as being no-reply@company_name_slug.com to avoid the mail
            # to be delivered to Spams because of origin check.
            sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
            msg = EmailMessage(subject, html_content, sender, [member.email])
            msg.content_subtype = "html"
            logger.debug("Sending mail to %s" % member.email)
            try:
                if msg.send():
                    logger.debug("Mail sent to %s" % member.email)
                else:
                    logger.error(u"Notice of suspension for Invoice #%s not sent to %s" % (invoice.number, member.email), exc_info=True)
            except:
                logger.error(u"Connexion error on Invoice #%s to %s" % (invoice.number, member.email), exc_info=True)
    try:
        connection.close()
    finally:
        pass
Esempio n. 13
0
def send_invoice_overdue_notices():
    """
    This cron task sends notice of Invoice overdue
    """
    service = get_service_instance()
    config = service.config
    now = timezone.now()
    invoicing_config = InvoicingConfig.objects.all()[0]
    connection = mail.get_connection()
    try:
        connection.open()
    except:
        logger.error(u"Connexion error", exc_info=True)
    count, total_amount = 0, 0
    invoice_qs = Invoice.objects.filter(Q(status=Invoice.PENDING) | Q(status=Invoice.OVERDUE),
                                        due_date__lt=now, overdue_notices_sent__lt=3)
    logger.debug("%d invoice(s) candidate for overdue notice." % invoice_qs.count())
    for invoice in invoice_qs:
        subscription = invoice.subscription
        if subscription.plan.raw_monthly_cost == 0:
            continue
        if invoice.last_overdue_notice:
            diff = now - invoice.last_overdue_notice
        else:
            invoice.status = Invoice.OVERDUE
            invoice.save()
        if not invoice.last_overdue_notice or diff.days == invoicing_config.overdue_delay:
            count += 1
            total_amount += invoice.amount
            member = subscription.service.member
            add_event(service, OVERDUE_NOTICE_EVENT, member=member, object_id=invoice.id)
            logger.debug("Event posted to %s's Console" % member.username)
            subject, message, sms_text = get_invoice_overdue_message(invoice)
            if member.email:
                invoice_url = service.url + reverse('billing:invoice_detail', args=(invoice.id,))
                html_content = get_mail_content(subject, message, template_name='billing/mails/notice.html',
                                                extra_context={'invoice_url': invoice_url, 'cta': _("Pay now")})
                # Sender is simulated as being no-reply@company_name_slug.com to avoid the mail
                # to be delivered to Spams because of origin check.
                sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
                msg = EmailMessage(subject, html_content, sender, [member.email])
                msg.content_subtype = "html"
                invoice.last_overdue_notice = timezone.now()
                logger.debug("Sending mail to %s" % member.email)
                try:
                    if msg.send():
                        logger.debug("Mail sent to %s" % member.email)
                        invoice.overdue_notices_sent += 1
                    else:
                        logger.error(u"Overdue notice for Invoice #%s not sent to %s" % (invoice.number, member.email), exc_info=True)
                except:
                    logger.error(u"Connexion error on Invoice #%s to %s" % (invoice.number, member.email), exc_info=True)
                invoice.save()
    try:
        connection.close()
    finally:
        pass
Esempio n. 14
0
def submit_cashout_request_for_manual_processing(**kwargs):
    tx = kwargs.get('transaction')
    if tx:
        cashout_request = CashOutRequest.objects.using('wallets').get(
            pk=tx.object_id)
        weblet = Service.objects.using(UMBRELLA).get(pk=tx.service_id)
        wallet = OperatorWallet.objects.using('wallets').get(
            nonrel_id=weblet.id, provider=tx.wallet)
        config = get_config_model().objects.using(UMBRELLA).get(service=weblet)
    else:
        config = kwargs['config']
        wallet = kwargs['wallet']
        cashout_request = kwargs['cashout_request']
        weblet = config.service
    iao = weblet.member
    if getattr(settings, 'TESTING', False):
        IKWEN_SERVICE_ID = getattr(settings, 'IKWEN_ID')
        ikwen_service = Service.objects.get(pk=IKWEN_SERVICE_ID)
    else:
        from ikwen.conf.settings import IKWEN_SERVICE_ID
        ikwen_service = Service.objects.using(UMBRELLA).get(
            pk=IKWEN_SERVICE_ID)
    retailer = weblet.retailer
    if retailer:
        vendor = retailer
    else:
        vendor = ikwen_service
    vendor_config = Config.objects.using(UMBRELLA).get(service=vendor)
    sender = '%s <no-reply@%s>' % (vendor_config.company_name, vendor.domain)

    add_event(vendor,
              CASH_OUT_REQUEST_EVENT,
              member=iao,
              object_id=cashout_request.id)
    subject = _("Cash-out request on %s" % weblet.project_name)
    html_content = get_mail_content(
        subject,
        '',
        template_name='cashout/mails/request_notice.html',
        extra_context={
            'cash_out_request': cashout_request,
            'weblet': weblet,
            'service': vendor,
            'config': vendor_config,
            'iao': iao,
            'wallet': wallet,
            'iao_profile': config
        })
    msg = EmailMessage(subject, html_content, sender, [iao.email])
    msg.bcc = ['*****@*****.**', '*****@*****.**']
    msg.content_subtype = "html"
    Thread(target=lambda m: m.send(), args=(msg, )).start()
    return HttpResponse(
        json.dumps({
            'success': True,
            'manual_processing': True
        }), 'content-type: text/json')
Esempio n. 15
0
def put_product_in_trash(request, *args, **kwargs):
    # TODO: Implement Trash view itself so that people can view and restore the content of the trash
    config = get_service_instance().config
    selection = request.GET['selection'].split(',')
    deleted = []
    for product_id in selection:
        try:
            product = Product.objects.get(pk=product_id)
            product.in_trash = True
            product.visible = False
            product.save()
            deleted.append(product_id)
            if getattr(settings, 'IS_PROVIDER', False):
                connection = mail.get_connection()
                try:
                    connection.open()
                    connection_opened = True
                except:
                    connection_opened = False
                for retailer_profile in OperatorProfile.objects.filter(business_type=OperatorProfile.RETAILER):
                    member = retailer_profile.service.member
                    service = retailer_profile.service
                    db = service.database
                    add_database_to_settings(db)
                    Product.objects.using(db).get(pk=product_id).delete()
                    ProductCategory.objects.using(db).filter(pk=product.category.id).update(items_count=F('items_count')-1)
                    if product.is_retailed:
                        add_event(service, PROVIDER_REMOVED_PRODUCT_EVENT, member=member, object_id=product_id)
                        if connection_opened:
                            # TODO: Verify what mail looks like after tests once UIs are implemented
                            subject = _("Product taken out by %s" % config.company_name)
                            message = _("Hi %(member_name)s,<br/> The product below was"
                                        "removed by <strong>%(company_name)s.</strong> "
                                        "It won't appear on your website anymore." % {'member_name': member.first_name,
                                                                                      'company_name': config.company_name})
                            html_content = get_mail_content(subject, message,
                                                            template_name='kako/retailer/mails/product_removed.html',
                                                            extra_context={'product': product, 'service': service,
                                                                           'provider_id': config.id})
                            sender = '%s <no-reply@%s.com>' % (service.project_name, service.project_name_slug)
                            msg = EmailMessage(subject, html_content, sender, [member.email])
                            msg.content_subtype = "html"
                            Thread(target=lambda m: m.send(), args=(msg,)).start()

                try:
                    connection.close()
                except:
                    pass
        except Product.DoesNotExist:
            message = "Product %s was not found."
            break
    else:
        message = "%d product(s) moved to trash." % len(selection)
    response = {'message': message, 'deleted': deleted}
    return HttpResponse(json.dumps(response), 'content-type: text/json')
Esempio n. 16
0
    def save_model(self, request, obj, form, change):
        if obj.status == CashOutRequest.PAID:
            if not obj.reference:
                self.message_user(request, "Reference number missing",
                                  messages.ERROR)
                return
            obj.teller_username = request.user.username
            service = Service.objects.get(pk=obj.service_id)
            wallet = OperatorWallet.objects.using('wallets').get(
                nonrel_id=service.id, provider=obj.provider)
            with transaction.atomic(using='wallets'):
                wallet.balance -= obj.amount_paid
                wallet.save(using='wallets')
                iao = service.member
                if getattr(settings, 'TESTING', False):
                    IKWEN_SERVICE_ID = getattr(settings, 'IKWEN_ID')
                    ikwen_service = Service.objects.get(pk=IKWEN_SERVICE_ID)
                else:
                    from ikwen.conf.settings import IKWEN_SERVICE_ID
                    ikwen_service = Service.objects.get(pk=IKWEN_SERVICE_ID)
                retailer = service.retailer
                if retailer:
                    retailer_config = Config.objects.get(service=retailer)
                    sender = '%s <no-reply@%s>' % (
                        retailer_config.company_name, retailer.domain)
                    event_originator = retailer
                else:
                    sender = 'ikwen <*****@*****.**>'
                    event_originator = ikwen_service

                add_event(event_originator,
                          CASH_OUT_REQUEST_PAID,
                          member=iao,
                          object_id=obj.id)

                subject = _("Money transfer confirmation")
                html_content = get_mail_content(
                    subject,
                    '',
                    template_name='cashout/mails/payment_notice.html',
                    extra_context={
                        'cash_out_request': obj,
                        'business': service,
                        'service': event_originator
                    })
                msg = EmailMessage(subject, html_content, sender, [iao.email])
                msg.content_subtype = "html"
                Thread(target=lambda m: m.send(), args=(msg, )).start()

                set_counters(ikwen_service)
                increment_history_field(ikwen_service, 'cash_out_history',
                                        obj.amount)
                increment_history_field(ikwen_service,
                                        'cash_out_count_history')
        super(CashOutRequestAdmin, self).save_model(request, obj, form, change)
Esempio n. 17
0
 def reject_coupons(self, request, queryset):
     email = queryset[0].service.member.email
     template_name = 'rewarding/mails/coupon_rejected.html'
     subject = _("Your coupons were rejected")
     html_content = get_mail_content(subject, template_name=template_name,
                                     extra_context={'coupon_list': queryset})
     sender = 'ikwen <*****@*****.**>'
     msg = EmailMessage(subject, html_content, sender, [email])
     msg.content_subtype = "html"
     msg.bcc = ['*****@*****.**']
     Thread(target=lambda m: m.send(), args=(msg,)).start()
Esempio n. 18
0
def reward_referrer(request, *args, **kwargs):
    referrer_id = request.GET['referrer_id']
    member = request.user
    service = get_service_instance()
    if referrer_id:
        referrer = Member.objects.get(pk=referrer_id)
        referrer_profile, update = MemberProfile.objects.get_or_create(
            member=referrer)
        men_tag, update = ProfileTag.objects.get_or_create(name='Men',
                                                           slug='men',
                                                           is_reserved=True)
        women_tag, update = ProfileTag.objects.get_or_create(name='Women',
                                                             slug='women',
                                                             is_reserved=True)

        referrer_tag_fk_list = referrer_profile.tag_fk_list
        if men_tag.id in referrer_tag_fk_list:
            referrer_tag_fk_list.remove(men_tag.id)
        if women_tag.id in referrer_tag_fk_list:
            referrer_tag_fk_list.remove(women_tag.id)
        member_profile, update = MemberProfile.objects.get_or_create(
            member=member)
        member_profile.tag_fk_list.extend(referrer_tag_fk_list)
        if member.gender == MALE:
            member_profile.tag_fk_list.append(men_tag.id)
        elif member.gender == FEMALE:
            member_profile.tag_fk_list.append(women_tag.id)
        member_profile.save()
        referral_pack_list, coupon_count = reward_member(
            service, referrer, Reward.REFERRAL)
        if referral_pack_list:
            sender = 'Tchopetyamo <*****@*****.**>'
            referrer_subject = _(
                "%s is offering you %d coupons for your referral to %s" %
                (service.project_name, coupon_count, member.full_name))
            template_name = 'rewarding/mails/referral_reward.html'
            CouponSummary.objects.using(UMBRELLA).get(service=service,
                                                      member=referrer)
            html_content = get_mail_content(referrer_subject,
                                            template_name=template_name,
                                            extra_context={
                                                'referral_pack_list':
                                                referral_pack_list,
                                                'coupon_count': coupon_count,
                                                'joined_service': service,
                                                'referee_name':
                                                member.full_name,
                                                'joined_logo':
                                                service.config.logo
                                            })
            msg = EmailMessage(referrer_subject, html_content, sender,
                               [referrer.email])
            msg.content_subtype = "html"
            Thread(target=lambda m: m.send(), args=(msg, )).start()
Esempio n. 19
0
def set_customer_dara(service, referrer, member):
    """
    Binds referrer to member referred.
    :param service: Referred Service
    :param referrer: Member who referred (The Dara)
    :param member: Referred Member
    :return:
    """
    try:
        db = service.database
        add_database(db)
        app = Application.objects.using(db).get(slug=DARAJA)
        dara_service = Service.objects.using(db).get(app=app, member=referrer)
        customer, change = Customer.objects.using(db).get_or_create(member=member)
        if customer.referrer:
            return

        dara_umbrella = Dara.objects.using(UMBRELLA).get(member=referrer)
        if dara_umbrella.level == 1 and dara_umbrella.xp == 1:
            dara_umbrella.xp = 2
            dara_umbrella.raise_bonus_cash(100)
            dara_umbrella.save()

        customer.referrer = dara_service
        customer.save()

        dara_db = dara_service.database
        add_database(dara_db)
        member.save(using=dara_db)
        customer.save(using=dara_db)
        service_mirror = Service.objects.using(dara_db).get(pk=service.id)
        set_counters(service_mirror)
        increment_history_field(service_mirror, 'community_history')

        add_event(service, REFEREE_JOINED_EVENT, member)

        diff = datetime.now() - member.date_joined

        activate(referrer.language)
        sender = "%s via Playground <*****@*****.**>" % member.full_name
        if diff.days > 1:
            subject = _("I'm back on %s !" % service.project_name)
        else:
            subject = _("I just joined %s !" % service.project_name)
        html_content = get_mail_content(subject, template_name='playground/mails/referee_joined.html',
                                        extra_context={'referred_service_name': service.project_name, 'referee': member,
                                                       'dara': dara_umbrella, 'cta_url': 'https://daraja.ikwen.com/'
                                                       })
        msg = EmailMessage(subject, html_content, sender, [referrer.email])
        msg.content_subtype = "html"
        Thread(target=lambda m: m.send(), args=(msg, )).start()
    except:
        logger.error("%s - Error while setting Customer Dara", exc_info=True)
Esempio n. 20
0
 def get(self, request, *args, **kwargs):
     action = request.GET.get('action')
     if action == 'update_domain':
         new_domain = request.GET['new_domain']
         is_naked_domain = True if request.GET[
             'type'] == Service.MAIN else False
         try:
             service = get_service_instance(using=UMBRELLA)
             service.update_domain(new_domain, is_naked_domain)
         except:
             logger.error("Failed to update domain to %s" % new_domain)
             response = {'error': _("Unknown error occured.")}
             return HttpResponse(json.dumps(response),
                                 'content-type: text/json')
     elif action == 'invite_to_transfer_ownership':
         if not request.user.is_bao:
             response = {'error': _("You are not allowed here.")}
             return HttpResponse(json.dumps(response),
                                 'content-type: text/json')
         email = request.GET['email']
         try:
             member = Member.objects.using(UMBRELLA).get(email=email)
             service = get_service_instance(using=UMBRELLA)
             transfer = OwnershipTransfer.objects.create(
                 sender=request.user, target_id=member.id)
             subject = _("Ownership transfer invitation")
             transfer_url = reverse('ikwen:transfer_ownership',
                                    args=(transfer.id, ))
             transfer_url = service.url + strip_base_alias(transfer_url)
             html_content = get_mail_content(
                 subject,
                 template_name='core/mails/ownership_transfer.html',
                 extra_context={
                     'owner_name': request.user.full_name,
                     'transfer_url': transfer_url,
                     'member': member
                 })
             sender = '%s <no-reply@%s>' % (service.project_name,
                                            service.domain)
             msg = EmailMessage(subject, html_content, sender,
                                [member.email])
             msg.content_subtype = "html"
             Thread(target=lambda m: m.send(), args=(msg, )).start()
             response = {'success': True, 'transfer_id': transfer.id}
             return HttpResponse(json.dumps(response),
                                 'content-type: text/json')
         except Member.DoesNotExist:
             response = {
                 'error': _("%s does not have an account on ikwen." % email)
             }
             return HttpResponse(json.dumps(response),
                                 'content-type: text/json')
     return super(ServiceDetail, self).get(request, *args, **kwargs)
Esempio n. 21
0
    def save_model(self, request, obj, form, change):
        if obj.status == CashOutRequest.PAID:
            if not obj.reference:
                self.message_user(request, "Reference number missing", messages.ERROR)
                return
            obj.teller_username = request.user.username
            charges = obj.amount * obj.rate / 100
            obj.amount_paid = obj.amount * (100 - obj.rate) / 100
            service = Service.objects.get(pk=obj.service_id)
            wallet = OperatorWallet.objects.using('wallets').get(nonrel_id=service.id, provider=obj.provider)
            method = CashOutMethod.objects.get(slug=obj.provider)
            address = CashOutAddress.objects.using(UMBRELLA).get(service=service, method=method)
            with transaction.atomic(using='wallets'):
                queryset = MoMoTransaction.objects.using('wallets') \
                    .filter(service_id=service.id, created_on__gt=obj.paid_on,
                            is_running=False, status=MoMoTransaction.SUCCESS, wallet=obj.provider)
                aggr = queryset.aggregate(Sum('amount'))
                aggr_fees = queryset.aggregate(Sum('fees'))
                aggr_dara_fees = queryset.aggregate(Sum('dara_fees'))
                amount_successful = 0
                if aggr['amount__sum']:
                    amount_successful = aggr['amount__sum'] - aggr_fees['fees__sum'] - aggr_dara_fees['dara_fees__sum']
                wallet.balance = amount_successful
                wallet.save(using='wallets')
                iao = service.member
                if getattr(settings, 'TESTING', False):
                    IKWEN_SERVICE_ID = getattr(settings, 'IKWEN_ID')
                    ikwen_service = Service.objects.get(pk=IKWEN_SERVICE_ID)
                else:
                    from ikwen.conf.settings import IKWEN_SERVICE_ID
                    ikwen_service = Service.objects.get(pk=IKWEN_SERVICE_ID)
                sender = 'ikwen <*****@*****.**>'
                event_originator = ikwen_service

                add_event(event_originator, CASH_OUT_REQUEST_PAID, member=iao, object_id=obj.id)

                subject = _("Money transfer confirmation")
                html_content = get_mail_content(subject, '', template_name='cashout/mails/payment_notice.html',
                                                extra_context={'cash_out_request': obj, 'charges': charges,
                                                               'weblet': service, 'address': address,
                                                               'service': event_originator})
                msg = EmailMessage(subject, html_content, sender, [iao.email])
                msg.bcc = ['*****@*****.**']
                msg.content_subtype = "html"
                Thread(target=lambda m: m.send(), args=(msg,)).start()

                set_counters(ikwen_service)
                increment_history_field(ikwen_service, 'cash_out_history', obj.amount)
                increment_history_field(ikwen_service, 'cash_out_count_history')
        super(CashOutRequestAdmin, self).save_model(request, obj, form, change)
Esempio n. 22
0
def product_do_checkout(request, *args, **kwargs):
    from echo.models import Balance
    from echo.utils import LOW_MAIL_LIMIT, notify_for_low_messaging_credit, notify_for_empty_messaging_credit
    tx = kwargs['tx']
    invoice = Invoice.objects.get(pk=tx.object_id)
    member = invoice.member
    subscription = invoice.subscription
    subscription.status = Subscription.ACTIVE
    subscription.save()
    invoice.status = Invoice.PAID
    invoice.save()
    payment = Payment.objects.create(invoice=invoice,
                                     method=Payment.MOBILE_MONEY,
                                     amount=invoice.amount,
                                     processor_tx_id=tx.processor_tx_id)
    share_payment_and_set_stats(invoice, payment_mean_slug=tx.wallet)
    service = get_service_instance()
    config = service.config

    balance, update = Balance.objects.using(WALLETS_DB_ALIAS).get_or_create(
        service_id=service.id)
    if member and member.email:
        if 0 < balance.mail_count < LOW_MAIL_LIMIT:
            notify_for_low_messaging_credit(service, balance)
        if balance.mail_count <= 0 and not getattr(settings, 'UNIT_TESTING',
                                                   False):
            notify_for_empty_messaging_credit(service, balance)
        else:
            invoice_url = service.url + reverse('billing:invoice_detail',
                                                args=(invoice.id, ))
            subject, message, sms_text = get_payment_confirmation_message(
                payment, member)
            html_content = get_mail_content(
                subject,
                message,
                template_name='billing/mails/notice.html',
                extra_context={
                    'member_name': member.first_name,
                    'invoice': invoice,
                    'cta': _("View invoice"),
                    'invoice_url': invoice_url
                })
            sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
            msg = EmailMessage(subject, html_content, sender, [member.email])
            msg.content_subtype = "html"
            Thread(target=lambda m: m.send(), args=(msg, )).start()
    messages.success(request,
                     _("Successful payment. Your subscription is now active."))
    return HttpResponseRedirect(request.session['return_url'])
Esempio n. 23
0
 def get(self, request, *args, **kwargs):
     action = request.GET.get('action')
     if action == 'invite_school':  # Send a request to see his children online to the school
         service = get_service_instance()
         member = request.user
         school_id = request.GET['school_id']
         kids_details = request.GET['kids_details']
         school = Service.objects.get(pk=school_id)
         db = school.database
         add_database(db)
         event_type, change = EventType.objects.using(db) \
             .get_or_create(codename=PARENT_REQUEST_KID, renderer='ikwen_foulassi.foulassi.events.render_parent_request_kid')
         kid_request = KidRequest.objects.using(db).create(parent=member, kids_details=kids_details)
         Event.objects.using(db).create(type=event_type, object_id_list=[kid_request.id])
         try:
             if member.gender == FEMALE:
                 parent_name = _("Mrs %s" % member.full_name)
             elif member.gender == MALE:
                 parent_name = _("Mr %s" % member.full_name)
             else:  # Unknown gender
                 parent_name = _("The parent %s" % member.full_name)
             subject = _("I would like to follow my kids in your school on Foulassi.")
             cta_url = school.url + reverse('foulassi:event_list')
             html_content = get_mail_content(subject, template_name='foulassi/mails/invite_school.html',
                                             extra_context={'parent': member, 'kids_details': kids_details,
                                                            'IKWEN_MEDIA_URL': MEDIA_URL, 'MEMBER_AVATAR': MEMBER_AVATAR,
                                                            'cta_url': cta_url})
             sender = '%s via ikwen Foulassi <no-reply@%s>' % (parent_name, service.domain)
             msg = EmailMessage(subject, html_content, sender, [school.config.contact_email.strip()])
             msg.content_subtype = "html"
             msg.cc = ["*****@*****.**"]
             if member.email:
                 msg.extra_headers = {'Reply-To': member.email}
             Thread(target=lambda m: m.send(), args=(msg,)).start()
             sms_text = _("%(parent_name)s would like to follow his kid(s) below on ikwen Foulassi:\n"
                          "%(kids_details)s" % {'parent_name': parent_name, 'kids_details': kids_details})
             if member.phone:
                 if len(member.phone) == 9:
                     member.phone = '237' + member.phone
                 send_sms(member.phone, sms_text)
         except:
             pass
         return HttpResponse(json.dumps({'success': True}, 'content-type: text/json'))
     return super(SearchSchool, self).get(request, *args, **kwargs)
Esempio n. 24
0
def notify_staff():
    now = datetime.now()
    start = now - timedelta(days=7)
    sender = 'ikwen DBBACKUP <*****@*****.**>'
    subject = _("Succeeded Backups Report")
    recipient_list = [get_service_instance().member.email]
    staff_list = [
        staff.email for staff in Member.objects.filter(is_staff=True)
    ]
    backup_list = [
        backup
        for backup in Backup.objects.order_by('-id').filter(status=SUCCESS)
    ]
    job_config_list = [backup.job_config for backup in backup_list]
    total_size = sum([backup.file_size for backup in backup_list])
    s, unit = find_file_size(
        total_size)  # s is a constant that equals to 2 power the

    extra_context = {
        'job_config_list':
        list(set(job_config_list)),
        'total_size':
        str(total_size / s) + unit,
        'location':
        'IKWEN_DB_BACKUPS',
        'period':
        "From  %s  to  %s" %
        (start.strftime('%Y/%m/%d %H:%M'), now.strftime('%Y/%m/%d %H:%M'))
    }
    activate('en')
    try:
        html_content = get_mail_content(
            subject,
            template_name='dbbackup/mails/succeeded_backup_notification.html',
            extra_context=extra_context)
    except:
        logger.error("Could not generate HTML content from template",
                     exc_info=True)
        return
    msg = EmailMessage(subject, html_content, sender, recipient_list)
    msg.content_subtype = "html"
    msg.bcc = staff_list
    msg.send()
Esempio n. 25
0
    def send_code(self, request, new_code=False, next_url=None):
        member = request.user
        uid = urlsafe_base64_encode(force_bytes(member.pk))
        token = default_token_generator.make_token(member)

        do_send = False
        try:
            current = request.session[
                'uid']  # Test whether there's a pending code in session
            if new_code:
                request.session['uid'] = uid
                do_send = True
        except KeyError:
            request.session['uid'] = uid
            do_send = True

        if do_send:
            subject = _("Confirm your email and get started !")
            template_name = 'accesscontrol/mails/confirm_email.html'
            confirmation_url = reverse('ikwen:confirm_email',
                                       args=(uid, token))
            service = get_service_instance()
            if service.config.is_standalone:
                confirmation_url = service.url + confirmation_url
            else:
                confirmation_url = ikwenize(confirmation_url)
            ikwen_service = Service.objects.using(UMBRELLA).get(
                pk=IKWEN_SERVICE_ID)
            html_content = get_mail_content(subject,
                                            service=ikwen_service,
                                            template_name=template_name,
                                            extra_context={
                                                'confirmation_url':
                                                confirmation_url,
                                                'member_name':
                                                member.first_name,
                                                'next_url': next_url
                                            })
            sender = '%s <no-reply@%s.com>' % (ikwen_service.project_name,
                                               ikwen_service.domain)
            msg = EmailMessage(subject, html_content, sender, [member.email])
            msg.content_subtype = "html"
            Thread(target=lambda m: m.send(), args=(msg, )).start()
Esempio n. 26
0
def render_product_on_sale(target, product, revival, **kwargs):
    service = revival.service
    sender = '%s <no-reply@%s>' % (service.project_name, service.domain)
    if target.member.date_joined > product.created_on or target.revival_count >= 1:
        # Do not revive customers who joined after product creation
        return None, None
    subject = _("Wow ! Seize this opportunity on %s" % product.name)
    template_name = 'kako/mails/product_on_sale.html'
    media_url = ikwen_settings.CLUSTER_MEDIA_URL + service.project_name_slug
    extra_context = {
        'member_name': target.member.first_name,
        'product': product.project_name,
        'media_url': media_url
    }
    html_content = get_mail_content(subject,
                                    template_name=template_name,
                                    service=service,
                                    extra_context=extra_context)
    return sender, subject, html_content
Esempio n. 27
0
def set_dara_stats(partner_original, service_partner, invoice, dara_earnings):
    set_counters(partner_original)
    increment_history_field(partner_original, 'turnover_history',
                            dara_earnings)
    increment_history_field(partner_original, 'earnings_history',
                            dara_earnings)
    increment_history_field(partner_original, 'transaction_count_history')

    set_counters(service_partner)
    increment_history_field(service_partner, 'earnings_history', dara_earnings)
    increment_history_field(service_partner, 'transaction_count_history')

    ikwen_service = get_service_instance()
    try:
        config = ikwen_service.config
        activate(partner_original.member.language)
        subject = _("New transaction on %s" % config.company_name)
        dashboard_url = 'https://daraja.ikwen.com' + reverse(
            'daraja:dashboard')
        html_content = get_mail_content(
            subject,
            template_name='daraja/mails/new_transaction.html',
            extra_context={
                'currency_symbol': config.currency_symbol,
                'amount': invoice.amount,
                'dara_earnings': dara_earnings,
                'tx_date': invoice.updated_on.strftime('%Y-%m-%d'),
                'tx_time': invoice.updated_on.strftime('%H:%M:%S'),
                'account_balance': partner_original.balance,
                'dashboard_url': dashboard_url
            })
        sender = 'ikwen Daraja <*****@*****.**>'
        msg = XEmailMessage(subject, html_content, sender,
                            [partner_original.member.email])
        msg.content_subtype = "html"
        if getattr(settings, 'UNIT_TESTING', False):
            msg.send()
        else:
            Thread(target=lambda m: m.send(), args=(msg, )).start()
    except:
        logger.error("Failed to notify %s Dara after follower purchase." %
                     partner_original,
                     exc_info=True)
Esempio n. 28
0
def _get_email_msg(member, subject, message, invoice, vendor, config):
    """
    Returns a ready to send HTML EmailMessage object from data in parameters
    """
    activate(member.language)
    invoice_url = 'http://ikwen.com' + reverse('billing:invoice_detail', args=(invoice.id,))
    html_content = get_mail_content(subject, message, template_name='billing/mails/notice.html',
                                    extra_context={'member_name': member.first_name, 'invoice': invoice,
                                                   'invoice_url': invoice_url, 'cta': _("Pay now"),
                                                   'currency': config.currency_symbol, 'service': vendor,
                                                   'config': config, 'logo': config.logo,
                                                   'project_name': vendor.project_name,
                                                   'company_name': config.company_name})
    # Sender is simulated as being no-reply@company_name_slug.com to avoid the mail
    # to be delivered to Spams because of origin check.
    sender = '%s <no-reply@%s>' % (config.company_name, vendor.domain)
    msg = EmailMessage(subject, html_content, sender, [member.email])
    msg.content_subtype = "html"
    return msg
Esempio n. 29
0
    def send_mail_to_visitor(self, request):
        service = get_service_instance()
        config = service.config
        visitor_email = request.GET.get('visitor_email')
        if not visitor_email:
            response = {'error': 'No Email found'}
            return HttpResponse(json.dumps(response),
                                'content-type: text/json')
        try:
            member = Member.objects.get(email=visitor_email)
        except MultipleObjectsReturned:
            member = Member.objects.filter(email=visitor_email)[0]
        except Member.DoesNotExist:
            username = visitor_email
            member = Member.objects.create_user(username,
                                                DEFAULT_GHOST_PWD,
                                                email=visitor_email,
                                                phone=visitor_email,
                                                is_ghost=True)
        tag_fk_list = []
        tag = TSUNAMI
        tsunami_tag = ProfileTag.objects.get(slug=tag)
        tag_fk_list.append(tsunami_tag.id)
        member_profile, update = MemberProfile.objects.get_or_create(
            member=member)
        member_profile.tag_fk_list.extend(tag_fk_list)
        member_profile.save()

        try:
            subject = _("Do more with Tsunami !")
            html_content = get_mail_content(
                subject,
                template_name='tsunami/mails/first_contact.html',
            )
            sender = '%s <no-reply@%s>' % (config.company_name, service.domain)
            msg = EmailMessage(subject, html_content, sender, visitor_email)
            msg.content_subtype = "html"
            Thread(target=lambda m: m.send(), args=(msg, )).start()
        except:
            pass
        next_url = reverse('tsunami:bundles')
        return HttpResponseRedirect(next_url)
Esempio n. 30
0
 def add_partner(self, request):
     partner_id = request.GET['partner_id']
     partner = Service.objects.using(UMBRELLA).get(pk=partner_id)
     partner_config = OperatorProfile.objects.using(UMBRELLA).get(
         service=partner)
     partner_member = partner.member
     service = get_service_instance()
     member = Member.objects.get(pk=service.member.id)
     config = OperatorProfile.objects.get(service=service)
     if getattr(settings, 'IS_BANK', False):
         partner_member.save(using='default')
         partner.save(using='default')
         partner_config.save(using='default')
         partner_db = partner.database
         add_database(partner_db)
         member.save(using=partner_db)
         service.save(using=partner_db)
         config.save(using=partner_db)
         PaymentMean.objects.using(partner_db).filter(
             slug='cashflex').update(is_active=True)
         PaymentMean.objects.using(partner_db).create(
             name=service.project_name,
             slug=service.project_name_slug,
             is_cashflex=True)
         subject = "Welcome"
     else:
         subject = "Request for integration"
     messages.success(
         request, _("%s successfully added." % partner_config.company_name))
     html_content = get_mail_content(
         subject,
         '',
         template_name='trade/mails/partnership_notice.html',
         extra_context={'settings': settings})
     sender = '%s <no-reply@%s>' % (service.project_name, service.domain)
     msg = EmailMessage(subject, html_content, sender,
                        [partner_config.contact_email])
     msg.bcc = ['*****@*****.**']
     msg.content_subtype = "html"
     Thread(target=lambda m: m.send(), args=(msg, )).start()
     next_url = reverse('trade:partner_list')
     return HttpResponseRedirect(next_url)