Example #1
0
    def ban(self, edited_by: User, reason: typing.Optional[str] = None, note: typing.Optional[str] = None) -> bool:
        'Mark lead account as banned, send cutomer.io event.'
        if self.status == LeadAccount.STATUS_BANNED:
            return False
        now = timezone.localtime(timezone.now())
        self.ban_reason = reason
        self.banned_date = now
        self.ban_note = note

        self.save()

        result = self.set_status(LeadAccount.STATUS_BANNED, edited_by)
        active_accounts = LeadAccount.get_active_lead_accounts(self.lead)

        if self.status == LeadAccount.STATUS_AVAILABLE:
            CustomerIOClient().send_lead_event(self.lead, CustomerIOClient.EVENT_AVAILABLE_BANNED, account_type=self.account_type)
        elif active_accounts:
            active_accounts_str = '{} account{}'.format(
                ' and '.join([i.account_type for i in active_accounts]),
                's' if len(active_accounts) > 1 else '',
            )
            CustomerIOClient().send_lead_event(self.lead, CustomerIOClient.EVENT_BANNED_HAS_ACCOUNTS, account_type=self.account_type, active_accounts=active_accounts_str)
        else:
            pass
            # CustomerIOClient().send_lead_event(self.lead, CustomerIOClient.EVENT_BANNED, account_type=self.account_type)

        # if not active_accounts:
        #     self.lead.ban(edited_by)
        return result
    def get(self, request: HttpRequest) -> JsonResponse:
        if not request.META.get('HTTP_SECRET', '') == settings.CRON_SECRET:
            return JsonResponse({'error': 'no secret'})

        time_deltas = [
            datetime.timedelta(days=1),
            datetime.timedelta(days=3),
            datetime.timedelta(days=7),
        ]
        max_timedelta = datetime.timedelta(days=8)
        now = timezone.localtime(timezone.now())
        lead_accounts = LeadAccount.objects.filter(
            status=LeadAccount.STATUS_AVAILABLE,
            created__gt=now - max_timedelta).prefetch_related('lead')
        sent = []
        for lead_account in lead_accounts:
            delta_not_qualified = now - lead_account.created
            last_not_qualified_reported = lead_account.last_not_qualified_reported or now - max_timedelta
            for time_delta in time_deltas:
                if delta_not_qualified > time_delta and lead_account.created + time_delta > last_not_qualified_reported:
                    lead_account.last_not_qualified_reported = now
                    lead_account.save()
                    CustomerIOClient().send_lead_event(
                        lead_account.lead,
                        CustomerIOClient.EVENT_NOT_QUALIFIED,
                        days=delta_not_qualified.days)
                    sent.append({
                        'email': lead_account.lead.email,
                        'days_not_qualified': delta_not_qualified.days
                    })
                    break
        return JsonResponse({'result': True, 'count': len(sent), 'sent': sent})
Example #3
0
    def set_status(self, value: str, edited_by: User) -> bool:
        'Change status, create LeadChangeinstance.'
        if value not in dict(self.STATUS_CHOICES).keys():
            raise ValueError('Unknown status: {}'.format(value))
        if value == self.status:
            return False

        old_value = self.status

        if value == self.STATUS_QUALIFIED and old_value == self.STATUS_IN_PROGRESS:
            return False

        if self.status != Lead.STATUS_BANNED:
            self.old_status = self.status

        self.status = value
        self.add_comment(f'Status changed from {old_value} to {self.status}',
                         edited_by)
        # self.insert_note(f'Status changed from {old_value} to {self.status} by {edited_by.email if edited_by else edited_by}')
        # self.save()
        LeadChange(lead=self,
                   field=LeadChange.FIELD_STATUS,
                   value=value,
                   old_value=old_value,
                   edited_by=edited_by).save()
        try:
            CustomerIOClient().send_lead(self)
        except:  # pylint: disable=bare-except
            pass
        return True
Example #4
0
    def update_from_shipstation(self,
                                data: typing.Optional[typing.Dict] = None
                                ) -> None:
        'Set tracking number if item was sent, set ship_date if empty.'
        if data is None:
            data = requests.get(
                'https://ssapi.shipstation.com/shipments',
                # params={'shipDateStart': '2017-12-30'},
                params={
                    'orderNumber': self.shipstation_order_number
                },
                auth=requests.auth.HTTPBasicAuth(
                    settings.SHIPSTATION_API_KEY,
                    settings.SHIPSTATION_API_SECRET),
            ).json().get('shipments')
            data = data[0] if data else {}

        if not data:
            return

        new_ship_date = data.get('shipDate')
        new_tracking_number = data.get('trackingNumber')

        if not self.ship_date and isinstance(new_ship_date, str):
            self.ship_date = parser.parse(new_ship_date).date()
            self.save()

        if data and isinstance(
                new_tracking_number,
                str) and self.usps_tracking_code != new_tracking_number:
            self.usps_tracking_code = new_tracking_number
            self.tracking_info = None
            self.pi_delivered = False
            CustomerIOClient().send_lead_event(
                self,
                CustomerIOClient.EVENT_SHIPPED,
                tracking_code=self.usps_tracking_code)
            # self.pi_delivered = True
            self.save()
Example #5
0
    def post(self, request):
        form = self.form_class(request.POST, request.FILES)
        if not form.is_valid():
            # raise ValueError(form.errors)
            form_errors = []
            for error_list in form.errors.values():
                for error in error_list:
                    form_errors.append(error)
            return render(
                request, 'signup.html',
                dict(
                    user=request.user,
                    isp='',
                    form_errors=form_errors,
                    remote_addr=request.META.get('REMOTE_ADDR'),
                    form=form,
                ))

        data = form.cleaned_data

        lead = Lead.objects.filter(email=data['email']).first()
        if lead:
            return redirect('thankyou_email', leadid=lead.leadid)

        lead_id = str(uuid.uuid4()).replace('-', '')

        lead = Lead(
            leadid=lead_id,
            account_name='',
            first_name=data['first_name'],
            last_name=data['last_name'],
            status=Lead.STATUS_AVAILABLE,
            email=data['email'],
            phone=data['phone'],
            utm_source=data['utm_source'],
            bundler=Bundler.get_by_utm_source(data['utm_source']),
            # facebook_account=True,
            # facebook_account_status=Lead.STATUS_AVAILABLE,
            # fb_email=data['fb_email'],
            # fb_secret=data['fb_secret'],
            # fb_friends=data['fb_friends'],
            # fb_profile_url=data['facebook_profile_url'],
            apartment=data.get('apartment'),
            street=data['street'],
            company=Lead.COMPANY_FBM,
            city=data['city'],
            state=data['state'],
            postal_code=data['postal_code'],
            country='United States',
            photo_id=data['photo_id'],
            extra_photo_id=data['extra_photo_id'],
        )
        try:
            lead.save()
        except django.db.Error:
            form_errors = ['This account is already registered']
            return render(
                request, 'signup.html',
                dict(
                    user=request.user,
                    isp='',
                    form_errors=form_errors,
                    remote_addr=request.META.get('REMOTE_ADDR'),
                    form=form,
                ))

        account_type = LeadAccount.ACCOUNT_TYPE_FACEBOOK
        if data['apply_type'] == SignupForm.APPLY_TYPE_SCREENSHOT:
            account_type = LeadAccount.ACCOUNT_TYPE_FACEBOOK_SCREENSHOT

        lead_account = LeadAccount(
            lead=lead,
            username=data['fb_email'],
            password=data['fb_secret'],
            friends=data['fb_friends'],
            account_url=data['facebook_profile_url'],
            status=LeadAccount.STATUS_AVAILABLE,
            primary=True,
            account_type=account_type,
        )
        lead_account.save()
        # lead.send_web_to_lead()

        customerio_client = CustomerIOClient()
        customerio_client.send_lead(lead)
        customerio_client.send_lead_event(lead,
                                          CustomerIOClient.EVENT_APPROVED,
                                          account_type='facebook')
        if account_type == LeadAccount.ACCOUNT_TYPE_FACEBOOK_SCREENSHOT:
            return redirect('thankyou_screenshot')
        return redirect('thankyou_email', leadid=lead.leadid)
Example #6
0
    def get(self, request):
        'Get endpoint'
        leads = []
        delivered = []
        not_delivered = []
        errors = []
        changed = []
        process_all = request.GET.get('all') == 'true'
        test = request.GET.get('test') == 'true'
        threads = int(request.GET.get('threads', 10))
        days_ago = int(request.GET.get('days_ago', 31))
        if process_all:
            leads = Lead.objects.filter(
                status__in=Lead.STATUSES_ACTIVE,
                usps_tracking_code__isnull=False,
                ship_date__gte=timezone.now() -
                datetime.timedelta(days=days_ago),
            ).prefetch_related('raspberry_pi')
        else:
            leads = Lead.objects.filter(
                status__in=Lead.STATUSES_ACTIVE,
                usps_tracking_code__isnull=False,
                pi_delivered=False,
                ship_date__gte=timezone.now() -
                datetime.timedelta(days=days_ago),
            ).prefetch_related('raspberry_pi')
        pool = ThreadPool(processes=threads)
        results = pool.map(self.get_tracking_info, leads)
        results_map = dict(results)
        for lead in leads:
            label = lead.raspberry_pi.rpid if lead.raspberry_pi else lead.email
            tracking_info_xml = results_map.get(lead.email)
            pi_delivered = lead.get_pi_delivered_from_xml(tracking_info_xml)
            if pi_delivered is None:
                errors.append(label)
                continue
            lead.tracking_info = tracking_info_xml
            if pi_delivered is not None and pi_delivered != lead.pi_delivered:
                changed.append(label)
                if not test and pi_delivered:
                    CustomerIOClient().send_lead_event(
                        lead,
                        CustomerIOClient.EVENT_DELIVERED,
                        tracking_code=lead.usps_tracking_code)
            lead.update_pi_delivered(pi_delivered, tracking_info_xml)

            if pi_delivered:
                delivered.append(label)
            else:
                not_delivered.append(label)

        if not test:
            bulk_update(leads,
                        update_fields=[
                            'tracking_info', 'pi_delivered', 'delivery_date'
                        ])
        else:
            bulk_update(leads, update_fields=[
                'tracking_info',
            ])

        return JsonResponse({
            'all': process_all,
            'result': True,
            'changed': changed,
            'delivered': delivered,
            'not_delivered': not_delivered,
            'errors': errors,
        })