Ejemplo n.º 1
0
class Lead(BaseModel):
    user = models.ForeignKey('users.user', on_delete=models.CASCADE)
    contact = models.ForeignKey(
        'crm.Contact', null=True, blank=True, on_delete=models.CASCADE)
    campaign = models.ForeignKey(
        'users.Campaign', null=True, blank=True, on_delete=models.CASCADE)
    pincode = models.CharField(max_length=6, null=True)
    bookmark = models.BooleanField(default=False)
    is_client = models.BooleanField(default=False)
    ignore = models.BooleanField(default=False)

    class Meta:
        ordering = ('-bookmark',)

    def create_opportunity(self, validated_data):
        instance = Opportunity.objects.create(
            lead_id=self.id, category_id=validated_data['category_id'])
        instance.update_category_opportunity(validated_data)
        return instance

    def get_quotes(self):
        from sales.models import Quote
        return Quote.objects.filter(
            opportunity__lead_id=self.id,
            ignore=False).exclude(status='rejected')

    def __str__(self):
        return "%s - Contact: %s" % (
            self.user.get_full_name(),
            self.contact.first_name if self.contact else 'Pending')
Ejemplo n.º 2
0
class Note(BaseModel):
    lead = models.ForeignKey('crm.Lead', on_delete=models.PROTECT)
    title = models.CharField(max_length=128)
    text = models.TextField()
    read = models.BooleanField(default=False)
    ignore = models.BooleanField(default=False)

    def __str__(self):
        return self.title
Ejemplo n.º 3
0
class ProductVariant(BaseModel):
    company_category = models.ForeignKey('product.CompanyCategory',
                                         null=True,
                                         blank=True,
                                         on_delete=models.CASCADE)
    parent = models.ForeignKey('self',
                               null=True,
                               blank=True,
                               on_delete=models.CASCADE)
    name = models.CharField(max_length=256,
                            default="",
                            verbose_name="Product Name")
    parent_product = models.CharField(max_length=128,
                                      null=True,
                                      blank=True,
                                      default='GoPlannr')
    feature_variant = models.CharField(max_length=256, default='base')
    short_description = models.CharField(max_length=128, null=True, blank=True)
    long_description = models.TextField(null=True, blank=True)
    online_process = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    chronic = models.BooleanField(default=True)

    def get_product_details(self):
        return {
            'name': self.product_short_name,
            'company': self.company_category.company.name,
            'logo': self.logo,
            'variant_name': self.product_short_name
        }

    @cached_property
    def logo(self):
        from goplannr.settings import DEBUG
        return (Constants.DEBUG_HOST
                if DEBUG else '') + self.company_category.company.logo.url

    @cached_property
    def product_short_name(self):
        return self.name

    def get_basic_details(self):
        return dict(toll_free_number=', '.join(
            self.company_category.company.toll_free_number),
                    brochure=self.get_help_file('sales_brochure'),
                    claim_form=self.get_help_file('claim_form'))

    def get_help_file(self, file_type):
        from content.models import HelpFile
        helpfile = HelpFile.objects.filter(product_variant_id=self.id,
                                           file_type=file_type).first()
        return helpfile.file.url if helpfile else '-'

    def __str__(self):
        return self.product_short_name
Ejemplo n.º 4
0
class IPAddress(BaseModel):
    account = models.ForeignKey(
        'users.Account', on_delete=models.PROTECT, null=True, blank=True)
    ip_address = models.CharField(max_length=16)
    company_name = models.CharField(max_length=128)
    authentication_required = models.BooleanField(default=True)
    blocked = models.BooleanField(default=False)

    @classmethod
    def _get_whitelisted_networks(cls):
        return cls.objects.filter(
            blocked=False).values_list('ip_address', flat=True)
Ejemplo n.º 5
0
class Member(BaseModel):
    application = models.ForeignKey('sales.Application',
                                    on_delete=models.CASCADE)
    relation = models.CharField(max_length=128,
                                choices=get_choices(
                                    Constants.RELATION_CHOICES),
                                db_index=True)
    first_name = models.CharField(max_length=128, blank=True)
    last_name = models.CharField(max_length=128, blank=True)
    dob = models.DateField(null=True)
    gender = models.CharField(choices=get_choices(Constants.GENDER),
                              max_length=16,
                              null=True)
    occupation = models.CharField(choices=get_choices(
        Constants.OCCUPATION_CHOICES),
                                  max_length=32,
                                  null=True,
                                  blank=True)
    height = models.FloatField(default=0.0)
    weight = models.FloatField(default=0.0)
    ignore = models.BooleanField(default=None, db_index=True, null=True)

    def save(self, *ar, **kw):
        try:
            self.__class__.objects.get(pk=self.id)
        except self.__class__.DoesNotExist:
            if self.relation not in [
                    'son', 'daughter'
            ] and self.__class__.objects.filter(
                    relation=self.relation,
                    application_id=self.application_id).exists():
                raise IntegrityError('%s relation already exists.' %
                                     self.relation)
        super(Member, self).save(*ar, **kw)

    def update_fields(self, **kw):
        for field in kw.keys():
            setattr(self, field, kw[field])
        self.save()

    def get_full_name(self):
        name = '%s %s' % (self.first_name, self.last_name)
        return name.strip()

    @property
    def age(self):
        if self.dob:
            return int((now().today().date() - self.dob).days / 365.2425)

    @property
    def height_foot(self):
        return int(self.height / 30.48)

    @property
    def height_inches(self):
        return round((self.height - self.height_foot * 30.48) / 2.54, 2)

    def __str__(self):
        return '%s | %s' % (self.relation.title(), self.application.__str__())
Ejemplo n.º 6
0
class BankAccount(BaseModel):
    user = models.ForeignKey('users.User', on_delete=models.CASCADE)
    branch = models.OneToOneField(
        'content.BankBranch', on_delete=models.CASCADE)
    account_no = models.CharField(max_length=32)
    default = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    def save(self, *args, **kwargs):
        try:
            if self.default and BankAccount.objects.filter(
                    default=True).exists():
                self.default = False
        except self.__class__.DoesNotExist:
            self.__class__.objects.all().update(default=False)
            self.default = True
        super(BankAccount, self).save(*args, **kwargs)
Ejemplo n.º 7
0
class HealthPremium(BaseModel):
    product_variant = models.ForeignKey('product.ProductVariant',
                                        null=True,
                                        blank=True,
                                        on_delete=models.CASCADE)
    deductible = models.ForeignKey('product.DeductibleMaster',
                                   null=True,
                                   blank=True,
                                   on_delete=models.CASCADE)
    sum_insured = models.IntegerField(default=0.0)
    suminsured_range = IntegerRangeField(db_index=True)
    age_range = IntegerRangeField(db_index=True)
    adults = models.IntegerField(null=True, blank=True, db_index=True)
    childrens = models.IntegerField(null=True, blank=True, db_index=True)
    citytier = models.CharField(max_length=256, null=True, blank=True)
    base_premium = models.FloatField(default=Constants.DEFAULT_BASE_PREMIUM)
    gst = models.FloatField(default=Constants.DEFAULT_GST)
    commission = models.FloatField(default=0.0)
    premium = GenericRelation('sales.quote',
                              related_query_name='healthinsurance',
                              object_id_field='premium_id')
    online_process = models.BooleanField(default=True)
    is_active = models.BooleanField(default=True)
    ignore = models.BooleanField(default=False)

    def get_details(self):
        return dict(sum_insured=self.sum_insured,
                    amount=self.amount,
                    commision=self.commission_amount)

    @cached_property
    def commission_amount(self):
        company = self.product_variant.company_category.company
        category = self.product_variant.company_category.category
        return self.amount * (self.commission + company.commission +
                              category.commission)

    @cached_property
    def amount(self):
        return round((self.gst * self.base_premium) + self.base_premium, 2)

    def __str__(self):
        return '%s | %s | %s' % (self.sum_insured, self.product_variant.name,
                                 self.age_range)
Ejemplo n.º 8
0
class CompanyCategory(BaseModel):
    category = models.ForeignKey('product.Category', on_delete=models.CASCADE)
    company = models.ForeignKey('product.Company', on_delete=models.CASCADE)
    claim_settlement = models.CharField(max_length=128, null=True, blank=True)
    offer_flag = models.BooleanField(default=False)

    class Meta:
        unique_together = ('category', 'company')

    def __str__(self):
        return '%s - %s' % (self.company.short_name, self.category.name)
Ejemplo n.º 9
0
class Category(BaseModel):
    name = models.CharField(max_length=128, db_index=True)
    description = models.TextField(null=True, blank=True)
    logo = models.ImageField(upload_to=Constants.CATEGORY_UPLOAD_PATH,
                             default=Constants.DEFAULT_LOGO)
    hexa_code = models.CharField(max_length=8,
                                 default=Constants.DEFAULT_HEXA_CODE)
    is_active = models.BooleanField(default=False)
    commission = models.FloatField(default=Constants.DEFAULT_COMMISSION)

    def __str__(self):
        return self.name
Ejemplo n.º 10
0
class Answer(BaseModel):
    question = models.ForeignKey('questionnaire.Question',
                                 on_delete=models.CASCADE)
    answer = models.CharField(max_length=128)
    order = models.IntegerField(default=0)
    ignore = models.BooleanField(default=False)
    score = models.IntegerField(default=0)

    class Meta:
        ordering = ('order', )

    def __str__(self):
        return self.answer
Ejemplo n.º 11
0
class Question(BaseModel):
    category = models.ForeignKey('product.Category', on_delete=models.CASCADE)
    title = models.CharField(max_length=32)
    question_type = models.CharField(max_length=10,
                                     choices=get_choices(
                                         constants.QUESTION_COICES),
                                     default="single")
    question = models.TextField()
    order = models.IntegerField(default=0)
    ignore = models.BooleanField(default=False)

    class Meta:
        ordering = ('order', )

    def __str__(self):
        return self.title
Ejemplo n.º 12
0
class KYCDocument(BaseModel):
    account = models.ForeignKey('users.Account', on_delete=models.CASCADE)
    document_type = models.CharField(
        choices=get_choices(Constants.KYC_DOC_TYPES), max_length=16)
    document_number = models.CharField(max_length=64, null=True, blank=True)
    file = models.FileField(upload_to=get_kyc_upload_path)
    ignore = models.BooleanField(default=False)

    def save(self, *args, **kwargs):
        previous = self.__class__.objects.filter(
            document_type=self.document_type, account_id=self.id)
        if previous.exists():
            previous.update(ignore=True)
        super(self.__class__, self).save(*args, **kwargs)

    def __str__(self):
        return self.document_type
Ejemplo n.º 13
0
class ProposerDocument(BaseModel):
    contact = models.ForeignKey('crm.Contact', on_delete=models.CASCADE)
    document_number = models.CharField(max_length=64, null=True, blank=True)
    document_type = models.CharField(choices=get_choices(
        Constants.KYC_DOC_TYPES),
                                     max_length=16)
    file = models.FileField(upload_to=get_proposer_upload_path,
                            null=True,
                            blank=True)
    ignore = models.BooleanField(default=False)

    def save(self, *args, **kwargs):
        previous = self.__class__.objects.filter(
            document_type=self.document_type, contact_id=self.contact_id)
        if previous.exists():
            previous.update(ignore=True)
        super(self.__class__, self).save(*args, **kwargs)
Ejemplo n.º 14
0
class Nominee(BaseModel):
    application = models.ForeignKey('sales.Application',
                                    on_delete=models.CASCADE)
    relation = models.CharField(max_length=128,
                                choices=get_choices(
                                    Constants.RELATION_CHOICES),
                                db_index=True)
    first_name = models.CharField(max_length=128)
    last_name = models.CharField(max_length=128)
    phone_no = models.CharField(max_length=10)
    ignore = models.BooleanField(default=False)

    def save(self, *ar, **kw):
        if not self.__class__.objects.filter(pk=self.id):
            existing_nominee = self.__class__.objects.filter(
                application_id=self.application.id)
            if existing_nominee.exists():
                existing_nominee.update(ignore=True)
        super(Nominee, self).save(*ar, **kw)

    def get_full_name(self):
        name = '%s %s' % (self.first_name, self.last_name)
        return name.strip()
Ejemplo n.º 15
0
class Company(BaseModel):
    name = models.CharField(max_length=128,
                            db_index=True,
                            verbose_name="Company Name")
    short_name = models.CharField(max_length=128)
    categories = models.ManyToManyField('product.Category')
    logo = models.ImageField(upload_to=Constants.COMPANY_UPLOAD_PATH,
                             default=Constants.DEFAULT_LOGO)
    hexa_code = models.CharField(max_length=8,
                                 default=Constants.DEFAULT_HEXA_CODE)
    website = models.URLField(null=True, blank=True)
    spoc = models.TextField(null=True, blank=True)
    toll_free_number = ArrayField(models.CharField(max_length=32),
                                  default=list,
                                  blank=True,
                                  null=True)
    long_description = models.TextField(null=True, blank=True)
    small_description = models.TextField(null=True, blank=True)
    commission = models.FloatField(default=0.0)
    is_active = models.BooleanField(default=False)

    def __str__(self):
        return self.name
Ejemplo n.º 16
0
class HealthInsurance(Insurance):
    gastrointestinal_disease = JSONField(
        default=list, help_text=Constants.GASTROINTESTINAL_DISEASE)
    neuronal_diseases = JSONField(default=list,
                                  help_text=Constants.NEURONAL_DISEASES)
    oncology_disease = JSONField(default=list,
                                 help_text=Constants.ONCOLOGY_DISEASE)
    respiratory_diseases = JSONField(default=list,
                                     help_text=Constants.RESPIRATORY_DISEASES)
    cardiovascular_disease = JSONField(
        default=list, help_text=Constants.CARDIOVASCULAR_DISEASE)
    ent_diseases = JSONField(default=list, help_text=Constants.ENT_DISEASE)
    blood_diseases = JSONField(default=list, help_text=Constants.BLOOD_DISODER)
    alcohol_consumption = models.IntegerField(
        default=0.0,
        help_text=Constants.ALCOHOL_CONSUMPTION,
        null=True,
        blank=True)
    tobacco_consumption = models.IntegerField(
        default=0.0,
        help_text=Constants.TABBACO_CONSUMPTION,
        null=True,
        blank=True)
    cigarette_consumption = models.IntegerField(
        default=0.0,
        help_text=Constants.CIGARETTE_CONSUMPTION,
        null=True,
        blank=True)
    previous_claim = models.BooleanField(default=False,
                                         help_text=Constants.PREVIOUS_CLAIM,
                                         null=True,
                                         blank=True)
    proposal_terms = models.BooleanField(default=False,
                                         help_text=Constants.PROPOSAL_TERMS,
                                         null=True,
                                         blank=True)

    def __init__(self, *args, **kwargs):
        super(self.__class__, self).__init__(*args, **kwargs)

    def update_default_fields(self, kw):
        for field in Constants.HEALTHINSURANCE_FIELDS:
            setattr(self, field, kw)
        self.save()

    def switch_premium(self, adults, childrens):
        opportunity = self.application.quote.opportunity
        data = dict(
            effective_age=(now().year -
                           self.application.active_members.aggregate(
                               s=models.Min('dob'))['s'].year),
            adults=adults,
            product_variant_id=self.application.quote.premium.
            product_variant_id,  # noqa
            childrens=childrens)
        for member in Constants.RELATION_CHOICES:
            members = self.application.active_members.filter(relation=member)
            if members.exists() and member not in ['son', 'daughter']:
                data['%s_age' % (member)] = members.get().age
        data[
            'customer_segment_id'] = opportunity.category_opportunity.get_customer_segment(
                **data).id  # noqa
        opportunity.refresh_quote_data(**data)
        quote = opportunity.get_quotes().first()
        if not quote:
            raise RecommendationException('No quote found for this creteria')
        previous_quote = self.application.quote
        if quote.id != previous_quote.id:
            previous_quote.status = 'rejected'
            previous_quote.save()
        quote.status = 'accepted'
        quote.save()
        self.application.quote_id = quote.id
        self.application.premium = quote.premium.amount
        self.application.suminsured = quote.premium.sum_insured
        self.application.save()

    def get_summary(self):
        response = dict()
        for field in self._meta.fields:
            if field.name in Constants.INSURANCE_EXCLUDE_FIELDS:
                continue
            field_value = getattr(self, field.name)
            if isinstance(field_value, list):
                values = list()
                for row in field_value:
                    if row['value']:
                        values.append(
                            Member.objects.get(id=row['id']).relation)
                field_value = None
                if values:
                    field_value = ", ".join(values)
            if not field_value:
                continue
            response[field.name] = field_value
        return response

    def get_insurance_fields(self):
        field_data = list()
        from sales.serializers import (MemberSerializer,
                                       GetInsuranceFieldsSerializer)
        members = self.application.active_members or Member.objects.filter(
            application_id=self.application_id)
        for field in self._meta.fields:
            if field.name in Constants.INSURANCE_EXCLUDE_FIELDS:
                continue
            if field.__class__.__name__ not in [
                    'BooleanField', 'IntegerField'
            ]:
                members_data = list()
                for member in getattr(self, field.name):
                    row = MemberSerializer(members.get(id=member['id'])).data
                    row['value'] = member['value']
                    members_data.append(row)
            if field.__class__.__name__ == 'BooleanField':
                data = dict(text=field.help_text,
                            field_name=field.name,
                            field_requirements=[{
                                'relation':
                                'None',
                                'value':
                                getattr(self, field.name)
                            }])
            elif field.__class__.__name__ == 'IntegerField':
                data = dict(text=field.help_text,
                            field_name=field.name,
                            field_requirements=[{
                                'relation':
                                'None',
                                'consumption':
                                getattr(self, field.name)
                            }])
            else:
                data = dict(text=field.help_text,
                            field_name=field.name,
                            field_requirements=members_data)
            serializer = GetInsuranceFieldsSerializer(data=data)
            serializer.is_valid(raise_exception=True)
            field_data.append(serializer.data)
        return field_data
Ejemplo n.º 17
0
class Bank(models.Model):
    name = models.CharField(max_length=256, db_index=True)
    is_active = models.BooleanField(default=False)

    def __str__(self):
        return self.name
Ejemplo n.º 18
0
class Quote(BaseModel):
    opportunity = models.ForeignKey('crm.Opportunity',
                                    on_delete=models.CASCADE,
                                    null=True,
                                    blank=True)
    status = models.CharField(max_length=16,
                              choices=Constants.STATUS_CHOICES,
                              default='pending')
    limit = models.Q(app_label='product', model='healthpremium')
    content_type = models.ForeignKey(ContentType,
                                     on_delete=models.CASCADE,
                                     limit_choices_to=limit)
    premium_id = models.PositiveIntegerField()
    premium = GenericForeignKey('content_type', 'premium_id')
    recommendation_score = models.FloatField(default=0.0)
    ignore = models.BooleanField(default=False)

    def save(self, *args, **kwargs):
        self.__class__.objects.filter(
            opportunity_id=self.opportunity_id,
            premium_id=self.premium_id,
            ignore=False).exclude(status='accepted').update(ignore=True)
        super(Quote, self).save(*args, **kwargs)

    def __str__(self):
        return '%s - %s' % (self.premium.amount, self.premium.product_variant.
                            company_category.company.name)

    class Meta:
        ordering = [
            '-recommendation_score',
        ]

    def get_feature_details(self):
        variant = self.premium.product_variant
        features = variant.feature_set.all()
        if variant.parent:
            features = features | variant.parent.feature_set.exclude(
                feature_master__name__in=features.values_list(
                    'feature_master__name', flat=True))
        return features.order_by('feature_master__order').values(
            'feature_master__name', 'short_description',
            'feature_master__long_description')

    def get_faq(self):
        company_category = self.premium.product_variant.company_category
        return [
            dict(question='Claim settlement ratio',
                 answer=company_category.claim_settlement),
            dict(question='Company details',
                 answer='Name: %s\nWebsite: %s' %
                 (company_category.company.name,
                  company_category.company.website or '-'))
        ]

    @cached_property
    def health_checkup(self):
        return 1500 * self.opportunity.category_opportunity.adults

    @cached_property
    def wellness_reward(self):
        return round(self.opportunity.category_opportunity.wellness_reward *
                     self.premium.amount, 2)  # noqa

    @cached_property
    def tax_saving(self):
        return round(self.opportunity.category_opportunity.tax_saving *
                     self.premium.amount, 2)  # noqa

    @cached_property
    def effective_premium(self):
        return round(self.premium.amount -
                     (self.health_checkup + self.wellness_reward +
                      self.tax_saving))
Ejemplo n.º 19
0
class NewsletterSubscriber(BaseModel):
    email = models.EmailField()
    unsubscribe = models.BooleanField(default=False)
Ejemplo n.º 20
0
class Application(BaseModel):
    app_client = models.ForeignKey('crm.Lead',
                                   on_delete=models.PROTECT,
                                   null=True,
                                   blank=True)
    reference_no = models.CharField(max_length=10, unique=True, db_index=True)
    premium = models.FloatField(default=0.0)
    suminsured = models.FloatField(default=0.0)
    proposer = models.ForeignKey('crm.Contact',
                                 null=True,
                                 on_delete=models.PROTECT)
    application_type = models.CharField(max_length=32,
                                        choices=get_choices(
                                            Constants.APPLICATION_TYPES))
    quote = models.OneToOneField('sales.Quote', on_delete=models.CASCADE)
    status = models.CharField(max_length=32,
                              choices=Constants.APPLICATION_STATUS,
                              default='fresh')
    stage = models.CharField(max_length=32,
                             default='proposer_details',
                             choices=get_choices(Constants.APPLICATION_STAGES))
    previous_policy = models.BooleanField(default=False)
    name_of_insurer = models.CharField(blank=True, max_length=128)
    proposer_verified = models.BooleanField(default=False)
    payment_failed = models.BooleanField(null=True, blank=True)
    payment_mode = models.CharField(max_length=64, default='offline')
    aggregator_error = models.CharField(max_length=256, null=True, blank=True)
    terms_and_conditions = models.BooleanField(null=True)

    def save(self, *args, **kwargs):
        try:
            current = self.__class__.objects.get(pk=self.id)
            if self.status != current.status:
                self.handle_status_change(current)
            if (current.payment_failed != self.payment_failed and
                    self.payment_failed) or self.status == 'completed':  # noqa
                self.send_slack_notification()
            if self.status == 'payment_due' and self.aggregator_error != current.aggregator_error:
                self.send_slack_notification()
        except self.__class__.DoesNotExist:
            self.generate_reference_no()
            self.application_type = self.company_category.category.name.lower(
            ).replace(' ', '')
        super(Application, self).save(*args, **kwargs)

    def handle_status_change(self, current):
        if self.status == 'submitted' and self.stage == 'completed':
            self.create_client()
            self.create_policy()
            self.create_commission(current)
        if current.status == 'fresh' and self.status == 'submitted':
            self.send_slack_notification()

    def send_slack_notification(self):
        event = None
        if self.quote.opportunity.lead.user.user_type == 'subscriber':
            event = 'Application created and payment process done'
        elif self.payment_mode == 'offline':
            event = 'Application created and payment process done'
        elif self.payment_failed:
            event = Constants.PAYMENT_ERROR
        elif self.aggregator_error:
            event = Constants.BROKER_ERROR
        else:
            event = Constants.PAYMENT_SUCCESS
        if event:
            self.send_slack_request(event)

    def aggregator_operation(self):
        premium = self.quote.premium
        if not premium.product_variant.online_process or not premium.online_process:  # noqa
            return False
        self.status = 'payment_due'
        from aggregator.wallnut.models import Application as Aggregator
        if not hasattr(self, 'application'):
            Aggregator.objects.create(reference_app_id=self.id,
                                      insurance_type=self.application_type)
            self.payment_mode = 'Aggregated payment mode'
        self.save()
        return self.payment_mode != 'offline'

    def update_fields(self, **kw):
        updated = False
        for field in kw.keys():
            setattr(self, field, kw[field])
            if not updated:
                updated = True
        if updated:
            self.save()

    def generate_reference_no(self):
        self.reference_no = genrate_random_string(10)
        if self.__class__.objects.filter(
                reference_no=self.reference_no).exists():
            while self.__class__.objects.filter(
                    reference_no=self.reference_no).exists():
                self.reference_no = genrate_random_string(10)

    def add_default_members(self):
        category_opportunity = self.quote.opportunity.category_opportunity
        today = now()
        members = list()

        def get_member_instance(gender, relation, dob=None):
            instance = Member(application_id=self.id,
                              dob=dob,
                              relation=relation,
                              gender=gender)
            if relation == 'self':
                responses = Response.objects.filter(
                    question__category_id=self.company_category.category.id,
                    opportunity_id=category_opportunity.opportunity_id)
                occupation_res = responses.filter(question__title='Occupation')
                if occupation_res.exists():
                    instance.occupation = responses.latest(
                        'created').answer.answer.replace(' ',
                                                         '_').lower()  # noqa
            return instance

        for member, age in category_opportunity.family.items():
            member = member.split('_')[0]
            gender = category_opportunity.gender if member == 'self' else 'male'  # noqa
            if member == 'spouse':
                gender = 'male' if category_opportunity.gender == 'female' else 'female'  # noqa
            elif member == 'mother':
                gender = 'female'
            elif member in ['son', 'daughter']:
                while age > 0:
                    members.append(
                        get_member_instance(
                            ('male' if member == 'son' else 'female'), member))
                    age -= 1
                continue
            instance = get_member_instance(
                gender, member,
                '%s-%s-%s' % (today.year - int(age), today.month, today.day))
            members.append(instance)
        Member.objects.bulk_create(members)

    def verify_proposer(self, otp):
        from django.core.cache import cache
        response = otp == cache.get('APP-%s:' % self.reference_no)
        cache.delete('APP-%s:' % self.reference_no)
        return response

    def send_propser_otp(self):
        from users.models import Account
        Account.send_otp('APP-%s:' % self.reference_no, self.proposer.phone_no)

    def create_policy(self):
        return Policy.objects.get_or_create(application_id=self.id)

    def invalidate_cache(self):
        from django.core.cache import cache
        cache.delete('USER_CART:%s' % self.quote.opportunity.lead.user_id)
        cache.delete('USER_CONTACTS:%s' % self.quote.opportunity.lead.user_id)
        cache.delete('USER_EARNINGS:%s' % self.quote.opportunity.lead.user_id)

    def create_client(self, save=False):
        lead = self.quote.opportunity.lead
        if not lead.is_client:
            lead.is_client = True
            lead.save()
        self.app_client_id = lead.id

    def create_commission(self, current):
        from earnings.models import Commission
        cc = self.quote.premium.product_variant.company_category
        amount = self.quote.premium.commission + cc.company.commission + cc.category.commission + self.quote.opportunity.lead.user.enterprise.commission  # noqa
        if not hasattr(self, 'commission'):
            commission = Commission(application_id=self.id,
                                    amount=self.premium * amount)
            if current.payment_failed != self.payment_failed and self.payment_failed is False:  # noqa
                commission.status = 'application_submitted'
            commission.save()
            commission.updated = True
            commission.save()
            commission.earning.user.account.send_sms(
                commission.earning.get_earning_message(self))

    def send_slack_request(self, event, mode_type='success'):
        import requests
        client = self.quote.opportunity.lead
        endpoint = 'https://hooks.slack.com/services/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'  # noqa
        link = '%s://admin.%s/sales/application/%s/change/' % (
            'http' if ENV == 'localhost:8000' else 'https', ENV, self.id)
        text = event
        mode = self.payment_mode
        if self.aggregator_error:
            text += '\nError: %s' % (self.aggregator_error)
            mode = 'Broker Error'
            mode_type = 'error'
        data = dict(attachments=[
            dict(fallback='Required plain-text summary of the attachment.',
                 color={
                     'success': '#36a64f',
                     'warning': '#ff9966',
                     'error': '#cc3300'
                 }[mode_type],
                 pretext=event,
                 author_name=mode,
                 title='Open Application',
                 title_link=link,
                 text=text,
                 fields=[
                     dict(type='mrkdwn',
                          value="*Application id:*\n%s" % self.reference_no),
                     dict(type='mrkdwn',
                          value="*Advisor Name:*\n%s" %
                          client.user.get_full_name()),
                     dict(type='mrkdwn',
                          value="*Advisor phone:*\n%s" %
                          client.user.account.phone_no)
                 ],
                 thumb_url='https://onecover.in/favicon.png',
                 footer='Post application flow',
                 footer_icon='https://onecover.in/favicon.png',
                 ts=now().timestamp())
        ])
        return requests.post(endpoint, json=data)

    @property
    def adults(self):
        return self.active_members.filter(dob__year__lte=(now().year -
                                                          18)).count()

    @property
    def childrens(self):
        return self.active_members.count() - self.adults

    @cached_property
    def active_members(self):
        return self.member_set.filter(ignore=False)

    @cached_property
    def inactive_members(self):
        return self.member_set.exclude(ignore=False)

    @cached_property
    def company_category(self):
        return self.quote.premium.product_variant.company_category

    @cached_property
    def people_listed(self):
        return self.active_members.count()

    @cached_property
    def client(self):
        return self.app_client

    def __str__(self):
        return '%s - %s - %s' % (self.reference_no, self.application_type,
                                 self.company_category.company.name)

    class Meta:
        ordering = ('-created', )
Ejemplo n.º 21
0
class Application(BaseModel):
    _host = 'https://wallnut.in/%s'
    reference_app = models.OneToOneField('sales.application',
                                         on_delete=models.PROTECT)
    section = models.CharField(max_length=16)
    company_name = models.CharField(max_length=64, null=True)
    suminsured = models.CharField(max_length=16)
    premium = models.FloatField(default=0.0)
    insurance_type = models.CharField(max_length=16)
    quote_id = models.CharField(max_length=128, null=True)
    customer_code = models.CharField(max_length=64, null=True, blank=True)
    product_code = models.CharField(max_length=64, null=True, blank=True)
    producer_code = models.CharField(max_length=64, null=True, blank=True)
    city_code = models.CharField(max_length=16, null=True)
    state_code = models.CharField(max_length=16, null=True)
    dealstage = models.CharField(max_length=32, null=True)
    user_id = models.CharField(max_length=16, null=True)
    proposal_id = models.CharField(max_length=32, null=True)
    proposal_id2 = models.CharField(max_length=32, null=True)
    customer_id = models.CharField(max_length=32, null=True)
    city = models.CharField(max_length=16, null=True)
    state = models.CharField(max_length=16, null=True)
    pincode = models.CharField(max_length=16, null=True)
    payment_ready = models.BooleanField(default=False)
    regenerate_payment_link = models.BooleanField(default=True)
    payment_captured = models.BooleanField(default=False)
    raw_quote = JSONField(default=dict)
    insurer_product = None

    def __init__(self, *args, **kwargs):
        super(self.__class__, self).__init__(*args, **kwargs)
        if self.company_name:
            self.insurer_product = evaluateClassName(self.company_name,
                                                     self.insurance_type)(self)

    def save(self, *args, **kwargs):
        try:
            self.__class__.objects.get(pk=self.id)
        except self.__class__.DoesNotExist:
            self.handle_creation()
        super(self.__class__, self).save(*args, **kwargs)

    def get_payment_link(self):
        return self.insurer_product.get_payment_link()

    def send_payment_link(self):
        from users.tasks import send_sms
        message = Constant.PAYMENT_MESSAGE % (
            self.proposer.get_full_name(), self.reference_app.reference_no,
            self.premium,
            self.reference_app.quote.premium.product_variant.__str__(),
            self.get_payment_link())
        send_sms.delay(self.reference_app.proposer.phone_no, message)

    def handle_creation(self):
        self.section = Constant.SECTION.get(
            self.reference_app.application_type)
        self.suminsured = int(self.reference_app.suminsured)
        self.premium = self.reference_app.premium
        self.pincode = self.reference_app.quote.opportunity.lead.pincode
        self.dealstage = 'productshortlisted'
        self.get_state_city()
        self.generate_quote_id()
        self.get_quote_data()

    def get_state_city(self):
        url = 'https://wallnut.in/health/proposal_aditya_birla/get_state_city?Pincode=%s' % (  # noqa
            self.reference_app.quote.opportunity.lead.pincode)
        request_log = ApplicationRequestLog.objects.create(
            application_id=self.reference_app.id, url=url, request_type='GET')
        response = requests.get(url).json()
        request_log.response = response
        request_log.save()
        self.city = response['city']
        self.state = response['state']

    def get_premium(self):
        url = self._host % 'mediclaim/get_premium'
        data = dict(
            health_pay_mode=self.pay_mode,
            health_pay_type=self.health_pay_type,
            health_pay_type_text=self.health_pay_type_text,
            health_sum_insured=self.suminsured,
            health_pay_mode_text=self.pay_mode_text,
            health_me=self.health_me,
            gender_age=self.gender_ages,
            pincode=self.pincode,
            health_insu_id=self.insurer_code,
            health_sum_insured_range=[self.suminsured, self.suminsured],
            health_city_id=self.city_code or '',
            health_state_id=self.state_code or '')
        request_log = ApplicationRequestLog.objects.create(
            application_id=self.reference_app.id,
            url=url,
            request_type='POST',
            payload=data)
        response = requests.post(url, data=data)
        request_log.response = response
        request_log.save()

    def generate_quote_id(self):
        url = self._host % 'save_quote_data'
        import json
        data = dict(section=self.section,
                    quote_data=json.dumps(
                        dict(health_pay_mode=self.pay_mode,
                             health_pay_mode_text=self.pay_mode_text,
                             health_me=self.health_me,
                             health_pay_type=self.health_pay_type,
                             health_pay_type_text=self.health_pay_type_text,
                             health_sum_insured=self.suminsured,
                             pincode=self.pincode,
                             gender_age=self.gender_ages,
                             health_sum_insured_range=[
                                 self.suminsured, self.suminsured
                             ],
                             spouse='',
                             child='',
                             child_data=list())),
                    quote='')
        request_log = ApplicationRequestLog.objects.create(
            application_id=self.reference_app.id,
            url=url,
            request_type='POST',
            payload=data)
        response = requests.post(url, data=data).json()
        request_log.response = response
        request_log.save()
        self.quote_id = response['quote']

    def get_products(self):
        url = (self._host % 'mediclaim/get_products/%s') % self.quote_id
        data = dict(quote=self.quote_id)
        ApplicationRequestLog.objects.create(
            application_id=self.reference_app.id,
            url=url,
            request_type='POST',
            payload=data)
        response = requests.post(url, data=data)
        return response

    def get_quote_data(self):
        self.get_products()
        import requests
        url = (self._host % 'get_quote_data/%s') % self.quote_id
        log = ApplicationRequestLog.objects.create(
            application_id=self.reference_app.id,
            url=url,
            request_type='GET',
        )
        response = requests.get(url).json()
        log.response = response
        log.save()
        self.city_code = response['data']['health_city_id']
        self.state_code = response['data']['health_state_id']
        self.fetch_quote_details()

    def fetch_quote_details(self):
        url = (self._host % 'mediclaim/fetch_quote/%s') % self.quote_id
        log = ApplicationRequestLog.objects.create(
            application_id=self.reference_app.id, url=url, request_type='GET')
        response = requests.get(url).json()
        log.response = response
        log.save()
        self.raw_quote = self.get_live_quote(response['quote_data'])
        self.company_name = re.sub('[ .]', '', self.raw_quote['company_name'])
        reference_app = self.reference_app
        reference_app.premium = self.raw_quote['total_premium']
        reference_app.save()

    def get_live_quote(self, quote_data):
        data = filter(
            lambda product: product['company_name'] == Constant.COMPANY_NAME.
            get(self.reference_app.quote.premium.product_variant.
                company_category.company.name  # noqa
                ),
            quote_data)
        quote = next(data)
        premium = int(self.reference_app.premium)
        product = self.reference_app.quote.premium.product_variant
        if product.parent and product.company_category.company.short_name == 'Aditya Birla':  # noqa
            return quote
        while int(quote['total_premium']) not in range(premium - 100,
                                                       premium + 100):
            quote = next(data)
        self.premium = quote['total_premium']
        return quote

    def get_user_id(self):
        if self.user_id:
            return self.user_id
        url = self._host % 'save_user_info'
        app = self.reference_app
        data = dict(
            first_name=app.proposer.first_name,
            dob=app.proposer.dob.strftime('%d-%M-%Y'),
            last_name=app.proposer.last_name,
            email=app.proposer.email,
            gender=Constant.GENDER.get(app.proposer.gender, 'M'),
            mobile_no=app.proposer.phone_no,
            alternate_mobile='',
            occupation=Constant.OCCUPATION_CODE[app.proposer.occupation],
            pincode=self.pincode,
            city=self.city,
            state=self.state,
            address=app.proposer.address.full_address,
            user_id='',
            dealstage=self.dealstage,
            insu_id=self.insurer_code,
            insurance_type=self.section.title() + ' Insurance',
            amount=self.premium)
        log = ApplicationRequestLog.objects.create(
            application_id=self.reference_app.id,
            url=url,
            request_type='POST',
            payload=data)
        response = requests.post(url, data=data).json()
        log.response = response
        log.save()
        return response['user_id']

    def insurer_operation(self):
        self.user_id = self.get_user_id()
        self.save()
        self.insurer_product.perform_creation()
        # self.send_payment_link()
        return True

    @cached_property
    def health_me(self):
        gender_ages = list()
        for member in self.reference_app.active_members.exclude(
                relation='self'):
            gender_ages.append([('M' if member.gender == 'male' else 'F'),
                                str(member.age)])
        return gender_ages

    @cached_property
    def proposer(self):
        self.self_insured = False
        proposers = self.reference_app.active_members
        if proposers.filter(relation='self').exists():
            self.self_insured = True
            proposer = proposers.get(relation='self')
        elif proposers.filter(relation='spouse').exists():
            proposer = proposers.get(relation='spouse')
        else:
            proposer = proposers.first()
        proposer.marital_status = Constant.get_marital_status(
            proposer.relation
        ) or self.reference_app.proposer.marital_status.title()  # noqa
        return proposer

    @cached_property
    def health_pay_type(self):
        if self.reference_app.active_members.count() == 1:
            return ''
        return '%sA%sC' % (self.reference_app.adults,
                           self.reference_app.childrens)

    @cached_property
    def health_pay_type_text(self):
        pay_type_text = ''
        if self.reference_app.active_members.count() == 1:
            return pay_type_text
        if self.reference_app.active_members.filter(relation='self').exists():
            pay_type_text += 'ME '
        if self.reference_app.active_members.filter(
                relation='spouse').exists():  # noqa
            pay_type_text += 'Spouse '
        if self.reference_app.active_members.filter(
                relation__in=['son', 'daughter']).exists():  # noqa
            pay_type_text += '%sChild' % self.reference_app.childrens
        return pay_type_text.strip()

    @cached_property
    def pay_mode(self):
        return 'I' if len(self.reference_app.active_members) == 1 else 'F'

    @cached_property
    def pay_mode_text(self):
        return 'Individual' if len(
            self.reference_app.active_members) == 1 else 'Family'

    @cached_property
    def gender_ages(self):
        return [[Constant.GENDER[self.proposer.gender], self.proposer.age]]

    @cached_property
    def all_premiums(self):
        return self.raw_quote['all_premium'].split(',')

    @cached_property
    def insurer_code(self):
        return self.raw_quote['insurance_code']

    def __str__(self):
        return '%s | %s' % (self.quote_id, self.reference_app.__str__())
Ejemplo n.º 22
0
class User(BaseModel):
    account = models.ForeignKey('users.Account', on_delete=models.CASCADE)
    user_type = models.CharField(
        choices=get_choices(Constants.USER_TYPE), max_length=16,
        default=Constants.DEFAULT_USER_TYPE)
    campaign = models.ForeignKey(
        'users.Campaign', null=True, blank=True, on_delete=models.CASCADE)
    rating = models.IntegerField(default=5)
    enterprise = models.ForeignKey(
        'users.Enterprise', on_delete=models.PROTECT)
    flag = JSONField(default=Constants.USER_FLAG)
    is_active = models.BooleanField(default=False)
    manager_id = models.CharField(max_length=48, null=True, blank=True)

    def save(self, *args, **kwargs):
        cache.delete('USER_DETAIL:%s' % self.id)
        super(self.__class__, self).save(*args, **kwargs)

    class Meta:
        unique_together = ('user_type', 'account')

    def __str__(self):
        return self.account.get_full_name()

    def get_authorization_key(self):
        return jwt.encode(
            {'user_id': str(self.id)},
            JWT_SECRET, algorithm='HS256')

    def get_full_name(self):
        return self.account.get_full_name()

    @classmethod
    def get_authenticated_user(cls, token):
        try:
            payload = jwt.decode(token, JWT_SECRET)
            return cls.objects.get(id=payload.get('user_id'))
        except Exception:
            pass
        return None

    def get_accounts(self):
        return self.bankaccount_set.filter(is_active=True)

    def generate_referral(self, referral_reference=None):
        import random
        code = ('%s%s' % (
            self.account.first_name.lower()[:3], self.account.phone_no[-5:])
        ).upper()
        if Referral.objects.filter(code=code).exists():
            while Referral.objects.filter(code=code).exists():
                code = ('%s%s' % (
                    self.account.first_name.lower()[:3],
                    random.randint(11111, 99999))).upper()
        return Referral.objects.create(
            code=code, reference_code=referral_reference,
            user_id=self.id)

    def get_categories(self):
        categories = list()
        from product.models import Category
        for category in Category.objects.only(
                'name', 'id', 'hexa_code', 'logo', 'is_active'):
            is_active = False
            categorys = self.enterprise.categories.filter(id=category.id)
            if categorys.exists():
                is_active = categorys.get().is_active
            categories.append(dict(
                id=category.id, hexa_code=category.hexa_code,
                name=category.name.split(' ')[0], is_active=is_active,
                logo=(
                    Constants.DEBUG_HOST if DEBUG else '') + category.logo.url
            ))
        categories = sorted(
            categories, key=lambda category: Constants.CATEGORY_ORDER.get(
                category['name'], 1))
        return categories

    def get_companies(self):
        return self.enterprise.companies.filter(is_active=True)

    def get_applications(self, status=None):
        from sales.models import Application
        query = dict(quote__opportunity__lead__user_id=self.id)
        if status and isinstance(status, list):
            query['status__in'] = status
        elif status:
            query['status'] = status
        return Application.objects.filter(**query)

    def get_policies(self):
        from sales.models import Policy
        return Policy.objects.filter(
            application__quote__opportunity__lead__user_id=self.id)

    def get_earnings(self, earning_type=None):
        from earnings.models import Earning
        return Earning.get_user_earnings(self.id, earning_type)

    def get_rules(self):
        rules = dict.fromkeys(Constants.PROMO_RULES_KEYS, False)
        rules['button_text'] = dict(
            recommendation='View plan details', product_detail='Save Plan')
        promo_code = self.enterprise.promocode.code.split('-')[1:]
        for rule_code in promo_code:
            if not rule_code.isdigit():
                rule_code = 1
            rules.update(Constants.PROMO_RULES[int(rule_code)])
        if self.enterprise.enterprise_type != 'subscriber':
            rules['kyc_allowed'] = True
            rules['button_text']['recommendation'] = 'Buy Now'
            rules['button_text']['product_detail'] = 'Buy Now'
        return rules

    def get_collaterals(self):
        from content.models import Collateral
        return Collateral.objects.filter(
            promocode_id=self.enterprise.promocode_id)

    @staticmethod
    def validate_referral_code(code):
        return Referral.objects.filter(code=code).exists()

    @staticmethod
    def validate_promo_code(code):
        return PromoCode.objects.filter(code=code).exists()

    @staticmethod
    def get_referral_details(code):
        # To Dos: Remove this
        referrals = Referral.objects.filter(code=code)
        if not referrals.exists():
            return {
                'user_type': Constants.DEFAULT_USER_TYPE,
                'enterprise_id': SubcriberEnterprise.objects.get(
                    name=Constants.DEFAULT_ENTERPRISE).id
            }
        referral = referrals.get()
        from earnings.models import Earning
        Earning.objects.create(
            user_id=referral.user.id, earning_type='referral', amount=100)
        return dict(
            enterprise_id=(
                referral.enterprise or SubcriberEnterprise.objects.get(
                    name=Constants.DEFAULT_ENTERPRISE)).id)

    @staticmethod
    def get_promo_code_details(code, name):
        promo_code = PromoCode.objects.get(code=code)
        enterprises = Enterprise.objects.filter(
            promocode=promo_code, enterprise_type='enterprise')
        if enterprises.exists():
            return dict(
                user_type='enterprise', enterprise_id=enterprises.get().id)
        enterprise = Enterprise.objects.create(name=name, promocode=promo_code)
        from product.models import Category, Company
        for category_id in Category.objects.values_list('id', flat=True):
            enterprise.categories.add(category_id)
        for company_id in Company.objects.values_list('id', flat=True):
            enterprise.companies.add(company_id)
        enterprise.save()
        return dict(
            user_type=enterprise.enterprise_type,
            enterprise_id=enterprise.id)

    @property
    def account_no(self):
        return self.bankaccount_set.get(default=True).account_no

    @property
    def ifsc(self):
        return self.bankaccount_set.get(default=True).branch.ifsc

    @property
    def bank_name(self):
        return self.bankaccount_set.get(default=True).branch.bank.name