예제 #1
0
class User(AbstractUser):
    BASE, VIP, PREMIUM = range(1, 4)
    SUB_TYPES = ((BASE, 'Base subscription'), (VIP, 'VIP subscription'),
                 (PREMIUM, 'Premium subscription'))

    SEX_CHOICES = (('M', 'Male'), ('F', 'Female'))

    sex = models.CharField(max_length=1, choices=SEX_CHOICES, null=True)
    age = models.PositiveSmallIntegerField(
        null=True, validators=[MinValueValidator(18),
                               MaxValueValidator(150)])
    preferred_sex = models.CharField(max_length=1,
                                     choices=SEX_CHOICES,
                                     null=True)
    preferred_age_min = models.PositiveSmallIntegerField(default=18)
    preferred_age_max = models.PositiveSmallIntegerField(default=150)
    description = models.CharField(max_length=2000, null=True, blank=True)
    profile_pic = models.ImageField(upload_to='avatars', null=True)
    relations = models.ManyToManyField('self',
                                       through='Relationship',
                                       symmetrical=False)
    location = models.OneToOneField('Location',
                                    null=True,
                                    on_delete=models.CASCADE)
    subscription = models.PositiveSmallIntegerField(choices=SUB_TYPES,
                                                    default=BASE)
    swipes_per_day = models.PositiveIntegerField(null=True)
    search_radius = models.PositiveIntegerField(null=True)

    @property
    def h**o(self) -> bool:
        return self.preferred_sex == self.sex

    @property
    def opposite_sex(self) -> str:
        return 'M' if self.sex == 'F' else 'F'

    def add_relation(self, to_user, status: int):
        relation, created = Relationship.objects.get_or_create(
            from_user=self, to_user=to_user, defaults={'status': status})
        return relation, created

    def _get_user_relations(self, status: int):
        return self.relations.filter(to_users__from_user=self,
                                     to_users__status=status)

    def _get_related(self, status: int):
        return self.relations.filter(from_users__to_user=self,
                                     from_users__status=status)

    def get_user_likes(self):
        return self._get_user_relations(Relationship.LIKED)

    def get_user_dislikes(self):
        return self._get_user_relations(Relationship.DISLIKED)

    def get_related_likes(self):
        return self._get_related(Relationship.LIKED)

    def get_related_dislikes(self):
        return self._get_related(Relationship.DISLIKED)

    def get_matched_list(self):
        return self.relations.filter(
            to_users__from_user=self,
            to_users__status=Relationship.LIKED,
            from_users__to_user=self,
            from_users__status=Relationship.LIKED,
        )

    def is_matched(self, other) -> bool:
        return Relationship.objects.filter(
            from_user=self,
            to_user=other,
            status=Relationship.LIKED
        ).exists() and \
        Relationship.objects.filter(
            from_user=other,
            to_user=self,
            status=Relationship.LIKED
        ).exists()

    def get_chat_id(self, other):
        return Chat.objects.filter(participants=self.id).intersection(
            Chat.objects.filter(participants=other.id)).first()

    @classmethod
    def get_subscription_swipes(cls, subscription: int):
        swipes = {cls.BASE: 20, cls.VIP: 100, cls.PREMIUM: 2147483647}
        return swipes[subscription]

    @classmethod
    def get_subscription_radius(cls, subscription: int):
        radius = {cls.BASE: 10, cls.VIP: 25, cls.PREMIUM: 2147483647}
        return radius[subscription]
예제 #2
0
class Member(models.Model):
    """
    Class model represents the Neighbourhood Watch registered member for the
    particular tenant.
    """

    '''
    METADATA
    '''

    class Meta:
        app_label = 'tenant_foundation'
        db_table = 'nwapp_members'
        verbose_name = _('Member')
        verbose_name_plural = _('Members')
        default_permissions = ()
        permissions = ()

    '''
    CONSTANTS
    '''

    class MEMBER_STATE:
        ACTIVE = 'active'
        INACTIVE = 'inactive'

    class MEMBER_TYPE_OF:
        RESIDENTIAL = 1
        BUSINESS = 2
        COMMUNITY_CARES = 3

    class MEMBER_DEACTIVATION_REASON:
        NOT_SPECIFIED = 0
        OTHER = 1
        BLACKLISTED = 2
        MOVED = 3
        DECEASED = 4
        DO_NOT_CONTACT = 5

    '''
    CHOICES
    '''

    MEMBER_STATE_CHOICES = (
        (MEMBER_STATE.ACTIVE, _('Active')),
        (MEMBER_STATE.INACTIVE, _('Inactive')),
    )

    MEMBER_TYPE_OF_CHOICES = (
        (MEMBER_TYPE_OF.BUSINESS, _('Business')),
        (MEMBER_TYPE_OF.RESIDENTIAL, _('Residential')),
        (MEMBER_TYPE_OF.COMMUNITY_CARES, _('Community Cares')),
    )

    MEMBER_DEACTIVATION_REASON_CHOICES = (
        (MEMBER_DEACTIVATION_REASON.BLACKLISTED, _('Blacklisted')),
        (MEMBER_DEACTIVATION_REASON.MOVED, _('Moved')),
        (MEMBER_DEACTIVATION_REASON.DECEASED, _('Deceased')),
        (MEMBER_DEACTIVATION_REASON.DO_NOT_CONTACT, _('Do not contact')),
        (MEMBER_DEACTIVATION_REASON.NOT_SPECIFIED, _('Not specified')),
        (MEMBER_DEACTIVATION_REASON.OTHER, _('Other')),
    )

    '''
    OBJECT MANAGERS
    '''

    objects = MemberManager()

    '''
    MODEL FIELDS
    '''

    # SYSTEM FIELDS

    user = models.OneToOneField(
        SharedUser,
        help_text=_('The user whom is a member.'),
        related_name="member",
        on_delete=models.CASCADE,
        primary_key=True,
    )
    type_of = models.PositiveSmallIntegerField(
        _("Type of"),
        help_text=_('The type of member this is.'),
        choices=MEMBER_TYPE_OF_CHOICES,
        db_index=True,
    )

    # STATE FIELDS

    state = models.CharField(
        _('State'),
        help_text=_('The state of this member.'),
        max_length=15,
        choices=MEMBER_STATE_CHOICES,
        default=MEMBER_STATE.ACTIVE,
        blank=True,
        db_index=True,
    )
    deactivation_reason = models.PositiveSmallIntegerField(
        _("Deactivation reason"),
        help_text=_('The reason why this member was deactivated.'),
        blank=True,
        choices=MEMBER_DEACTIVATION_REASON_CHOICES,
        default=MEMBER_DEACTIVATION_REASON.NOT_SPECIFIED
    )
    deactivation_reason_other = models.CharField(
        _("Deactivation reason (other)"),
        max_length=2055,
        help_text=_('The reason why this member was deactivated which was not in the list.'),
        blank=True,
        null=True,
        default=""
    )

    # MISC FIELDS

    avatar_image = models.ForeignKey(
        "PrivateImageUpload",
        help_text=_('The avatar image of this member.'),
        related_name="members",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    watch = models.ForeignKey(
        "Watch",
        help_text=_('The watch this member belongs to.'),
        related_name="members",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )

    # AUDITING FIELDS

    uuid = models.CharField(
        _("UUID"),
        help_text=_('The unique identifier we want to release to the public to identify this unique record.'),
        default=uuid.uuid4,
        editable=False,
        max_length=63, # Do not change
        unique=True,
        db_index=True,
    )
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    created_by = models.ForeignKey(
        SharedUser,
        help_text=_('The user whom created this object.'),
        related_name="created_members",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    created_from = models.GenericIPAddressField(
        _("Created from"),
        help_text=_('The IP address of the creator.'),
        blank=True,
        null=True
    )
    created_from_is_public = models.BooleanField(
        _("Is the IP "),
        help_text=_('Is creator a public IP and is routable.'),
        default=False,
        blank=True
    )
    created_from_position = models.PointField(
        _("Created from position"),
        help_text=_('The latitude and longitude coordinates for the creator.'),
        srid=4326,
        geography=True,
        null=True,
        blank=True,
    )
    last_modified_at = models.DateTimeField(auto_now=True)
    last_modified_by = models.ForeignKey(
        SharedUser,
        help_text=_('The user whom modified this object last.'),
        related_name="last_modified_members",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    last_modified_from = models.GenericIPAddressField(
        _("Last modified from"),
        help_text=_('The IP address of the modifier.'),
        blank=True,
        null=True
    )
    last_modified_from_is_public = models.BooleanField(
        _("Is the IP "),
        help_text=_('Is modifier a public IP and is routable.'),
        default=False,
        blank=True
    )
    last_modified_from_position = models.PointField(
        _("Last modified from position"),
        help_text=_('The latitude and longitude coordinates for the last modified user.'),
        srid=4326,
        geography=True,
        null=True,
        blank=True,
    )

    # SEARCHABLE FIELDS

    indexed_text = models.CharField(
        _("Indexed Text"),
        max_length=1023,
        help_text=_('The searchable content text used by the keyword searcher function.'),
        blank=True,
        null=True,
        db_index=True,
        unique=True
    )

    """
    MODEL FUNCTIONS
    """

    def __str__(self):
        '''
        Override the `casting` function so we output the following string when
        an object gets casted to a string.
        '''
        return self.user.get_full_name()

    def get_role_label(self):
        return self.user.role_label

    @transaction.atomic
    def save(self, *args, **kwargs):
        '''
        Override the `save` function to support extra functionality of our model.
        '''
        if self.created_from:
            self.created_from_position = get_point_from_ip(self.created_from)
        if self.last_modified_from:
            self.last_modified_from_position = get_point_from_ip(self.last_modified_from)

        '''
        Finally call the parent function which handles saving so we can carry
        out the saving operation by Django in our ORM.
        '''
        super(Member, self).save(*args, **kwargs)

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

    def get_pretty_state(self):
        return str(dict(Member.MEMBER_STATE_CHOICES).get(self.state))

    def get_pretty_type_of(self):
        return str(dict(Member.MEMBER_TYPE_OF_CHOICES).get(self.type_of))

    def get_pretty_deactivation_reason(self):
        return str(dict(Member.MEMBER_DEACTIVATION_REASON_CHOICES).get(self.deactivation_reason))

    def invalidate(self, method_name): #TODO: IMPLEMENT
        """
        Function used to clear the cache for the cached property functions.
        """
        try:
            pass
            # if method_name == 'fullname':
            #     del self.fullname
            # else:
            #     raise Exception("Method name not found.")
        except AttributeError:
            pass

    def invalidate_all(self):
        self.invalidate("fullname")

    @staticmethod
    def get_searchable_content(member):
        """
        Utility function which refreshes the searchable content used when
        searching for `keywords`.
        """
        text = member.user.slug + " "
        if member.contact:
            text += member.contact.get_searchable_content()
        if member.address:
            text += " " + member.address.get_searchable_content()
        if member.metric:
            text += " " + member.metric.get_searchable_content()
        if member.watch:
            text += " " + member.watch.get_searchable_content()
        return text

    @staticmethod
    def seed(tenant, length=25):
        from faker import Faker
        from shared_foundation.models import SharedUser, SharedGroup
        from tenant_foundation.models import Member
        from tenant_foundation.models import MemberAddress
        from tenant_foundation.models import MemberContact
        from tenant_foundation.models import MemberMetric
        from tenant_foundation.models import MemberComment
        from tenant_foundation.models import Watch
        from tenant_foundation.models import StreetAddressRange
        from tenant_foundation.models import HowHearAboutUsItem
        from tenant_foundation.models import ExpectationItem
        from tenant_foundation.models import MeaningItem
        results = []
        faker = Faker('en_CA')
        for i in range(0,length):
            try:
                first_name = faker.first_name()
                last_name = faker.last_name()
                street_address = StreetAddressRange.objects.random()
                organization_name = faker.company()
                organization_type_of = faker.pyint(min_value=2, max_value=4, step=1)
                user = SharedUser.objects.create(
                    tenant=tenant,
                    email = faker.safe_email(),
                    first_name = first_name,
                    middle_name = None,
                    last_name = last_name,
                )
                user.groups.add(SharedGroup.GROUP_MEMBERSHIP.MEMBER)
                member = Member.objects.create(
                    user=user,
                    type_of=street_address.watch.type_of,
                    watch=street_address.watch,
                )
                member_contact = MemberContact.objects.create(
                    member=member,
                    is_ok_to_email=True,
                    is_ok_to_text=True,
                    organization_name=organization_name,
                    organization_type_of=organization_type_of,
                    first_name=user.first_name,
                    last_name=user.last_name,
                    email=user.email,
                    primary_phone=faker.phone_number(),
                    secondary_phone=faker.phone_number(),
                )
                member_address = MemberAddress.objects.create(
                    member=member,
                    country="Canada",
                    province="Ontario",
                    city=faker.city(),
                    street_number=faker.pyint(
                        min_value=street_address.street_number_start,
                        max_value=street_address.street_number_end,
                        step=1
                    ),
                    street_name=street_address.street_name,
                    apartment_unit=faker.pyint(
                        min_value=1,
                        max_value=1000,
                        step=1
                    ),
                    street_type=street_address.street_type,
                    street_type_other=street_address.street_type_other,
                    street_direction=street_address.street_direction,
                    postal_code=faker.postalcode(),
                )
                member_metric = MemberMetric.objects.create(
                    member = member,
                    how_did_you_hear = HowHearAboutUsItem.objects.random(),
                    how_did_you_hear_other = faker.company(),
                    expectation = ExpectationItem.objects.random(),
                    expectation_other = faker.company(),
                    meaning = MeaningItem.objects.random(),
                    meaning_other = faker.company(),
                    # gender=
                    # willing_to_volunteer=
                    another_household_member_registered=False,
                    year_of_birth=faker.pyint(min_value=1920, max_value=1990, step=1),
                    total_household_count=faker.pyint(min_value=2, max_value=6, step=1),
                    over_18_years_household_count = faker.pyint(min_value=0, max_value=1, step=1),
                    organization_employee_count = faker.pyint(min_value=0, max_value=10, step=1),
                    organization_founding_year=faker.pyint(min_value=1920, max_value=1990, step=1),
                )
                results.append(member)
            except Exception as e:
                print(e)
                pass
        return results


    def promote_to_area_coordinator(self, defaults):
        """
        - defaults
            - has_signed_area_coordinator_agreement
            - has_signed_conflict_of_interest_agreement
            - has_signed_code_of_conduct_agreement
            - has_signed_confidentiality_agreement
            - police_check_date
            - created_by
            - created_from
            - created_from_is_public
            - last_modified_by
            - last_modified_from
            - last_modified_from_is_public
        """
        from django.template.loader import render_to_string  # HTML / TXT
        from django.utils import timezone
        from shared_foundation.models import SharedGroup
        from tenant_foundation.models import AreaCoordinator

        has_signed_area_coordinator_agreement = defaults.get('has_signed_area_coordinator_agreement', None)
        has_signed_conflict_of_interest_agreement = defaults.get('has_signed_conflict_of_interest_agreement', None)
        has_signed_code_of_conduct_agreement = defaults.get('has_signed_code_of_conduct_agreement', None)
        has_signed_confidentiality_agreement = defaults.get('has_signed_confidentiality_agreement', None)
        police_check_date = defaults.get('police_check_date', None)
        created_by = defaults.get('created_by', None)
        created_from = defaults.get('created_from', None)
        created_from_is_public = defaults.get('created_from_is_public', None)
        last_modified_by = defaults.get('last_modified_by', None)
        last_modified_from = defaults.get('last_modified_from', None)
        last_modified_from_is_public = defaults.get('last_modified_from_is_public', None)

        # Defensive code.
        assert self.user != None
        assert isinstance(has_signed_area_coordinator_agreement, bool)
        assert isinstance(has_signed_conflict_of_interest_agreement, bool)
        assert isinstance(has_signed_code_of_conduct_agreement, bool)
        assert isinstance(has_signed_confidentiality_agreement, bool)
        assert police_check_date != None

        # Get the text agreement which will be signed.
        area_coordinator_agreement = render_to_string('account/area_coordinator_agreement/2019_05_01.txt', {}) if has_signed_area_coordinator_agreement else None
        conflict_of_interest_agreement = render_to_string('account/conflict_of_interest_agreement/2019_05_01.txt', {}) if has_signed_conflict_of_interest_agreement else None
        code_of_conduct_agreement = render_to_string('account/code_of_conduct_agreement/2019_05_01.txt', {}) if has_signed_code_of_conduct_agreement else None
        confidentiality_agreement = render_to_string('account/confidentiality_agreement/2019_05_01.txt', {}) if has_signed_confidentiality_agreement else None

        # Create or update our model.
        area_coordinator, created = AreaCoordinator.objects.update_or_create(
            user=self.user,
            defaults={
                'user': self.user,
                'watch': self.watch,
                'type_of': self.type_of,
                'has_signed_area_coordinator_agreement': has_signed_area_coordinator_agreement,
                'area_coordinator_agreement': area_coordinator_agreement,
                'area_coordinator_agreement_signed_on': timezone.now(),
                'has_signed_conflict_of_interest_agreement': has_signed_conflict_of_interest_agreement,
                'conflict_of_interest_agreement': conflict_of_interest_agreement,
                'conflict_of_interest_agreement_signed_on': timezone.now(),
                'has_signed_code_of_conduct_agreement': has_signed_code_of_conduct_agreement,
                'code_of_conduct_agreement': code_of_conduct_agreement,
                'code_of_conduct_agreement_signed_on': timezone.now(),
                'has_signed_confidentiality_agreement': has_signed_confidentiality_agreement,
                'confidentiality_agreement': confidentiality_agreement,
                'confidentiality_agreement_signed_on': timezone.now(),
                'police_check_date': police_check_date,
                'created_by': created_by,
                'created_from': created_from,
                'created_from_is_public': created_from_is_public,
                'created_from_position': get_point_from_ip(created_from),
                'last_modified_by': last_modified_by,
                'last_modified_from': last_modified_from,
                'last_modified_from_is_public': last_modified_from_is_public,
                'last_modified_from_position': get_point_from_ip(last_modified_from),
            }
        )

        # Set the user's role to be a area coordinator after clearing the
        # previous group memberships.
        area_coordinator.user.groups.clear()
        area_coordinator.user.groups.add(SharedGroup.GROUP_MEMBERSHIP.AREA_COORDINATOR)

        return area_coordinator

    def promote_to_associate(self, defaults):
        """
        - defaults
            - has_signed_associate_agreement
            - has_signed_conflict_of_interest_agreement
            - has_signed_code_of_conduct_agreement
            - has_signed_confidentiality_agreement
            - police_check_date
            - created_by
            - created_from
            - created_from_is_public
            - last_modified_by
            - last_modified_from
            - last_modified_from_is_public
        """
        from django.template.loader import render_to_string  # HTML / TXT
        from django.utils import timezone
        from shared_foundation.models import SharedGroup
        from tenant_foundation.models import Associate

        has_signed_associate_agreement = defaults.get('has_signed_associate_agreement', None)
        has_signed_conflict_of_interest_agreement = defaults.get('has_signed_conflict_of_interest_agreement', None)
        has_signed_code_of_conduct_agreement = defaults.get('has_signed_code_of_conduct_agreement', None)
        has_signed_confidentiality_agreement = defaults.get('has_signed_confidentiality_agreement', None)
        police_check_date = defaults.get('police_check_date', None)
        created_by = defaults.get('created_by', None)
        created_from = defaults.get('created_from', None)
        created_from_is_public = defaults.get('created_from_is_public', None)
        last_modified_by = defaults.get('last_modified_by', None)
        last_modified_from = defaults.get('last_modified_from', None)
        last_modified_from_is_public = defaults.get('last_modified_from_is_public', None)

        # Defensive code.
        assert self.user != None
        assert isinstance(has_signed_associate_agreement, bool)
        assert isinstance(has_signed_conflict_of_interest_agreement, bool)
        assert isinstance(has_signed_code_of_conduct_agreement, bool)
        assert isinstance(has_signed_confidentiality_agreement, bool)
        assert police_check_date != None

        # Get the text agreement which will be signed.
        associate_agreement = render_to_string('account/associate_agreement/2019_05_01.txt', {}) if has_signed_associate_agreement else None
        conflict_of_interest_agreement = render_to_string('account/conflict_of_interest_agreement/2019_05_01.txt', {}) if has_signed_conflict_of_interest_agreement else None
        code_of_conduct_agreement = render_to_string('account/code_of_conduct_agreement/2019_05_01.txt', {}) if has_signed_code_of_conduct_agreement else None
        confidentiality_agreement = render_to_string('account/confidentiality_agreement/2019_05_01.txt', {}) if has_signed_confidentiality_agreement else None

        # Create or update our model.
        associate, created = Associate.objects.update_or_create(
            user=self.user,
            defaults={
                'user': self.user,
                'watch': self.watch,
                'type_of': self.type_of,
                'has_signed_associate_agreement': has_signed_associate_agreement,
                'associate_agreement': associate_agreement,
                'associate_agreement_signed_on': timezone.now(),
                'has_signed_conflict_of_interest_agreement': has_signed_conflict_of_interest_agreement,
                'conflict_of_interest_agreement': conflict_of_interest_agreement,
                'conflict_of_interest_agreement_signed_on': timezone.now(),
                'has_signed_code_of_conduct_agreement': has_signed_code_of_conduct_agreement,
                'code_of_conduct_agreement': code_of_conduct_agreement,
                'code_of_conduct_agreement_signed_on': timezone.now(),
                'has_signed_confidentiality_agreement': has_signed_confidentiality_agreement,
                'confidentiality_agreement': confidentiality_agreement,
                'confidentiality_agreement_signed_on': timezone.now(),
                'police_check_date': police_check_date,
                'created_by': created_by,
                'created_from': created_from,
                'created_from_is_public': created_from_is_public,
                'created_from_position': get_point_from_ip(created_from),
                'last_modified_by': last_modified_by,
                'last_modified_from': last_modified_from,
                'last_modified_from_is_public': last_modified_from_is_public,
                'last_modified_from_position': get_point_from_ip(last_modified_from),
            }
        )

        # Set the user's role to be a area coordinator after clearing the
        # previous group memberships.
        associate.user.groups.clear()
        associate.user.groups.add(SharedGroup.GROUP_MEMBERSHIP.ASSOCIATE)

        return associate

    def promote_to_staff(self, defaults):
        """
        - defaults
            - role_id
            - has_signed_staff_agreement
            - has_signed_conflict_of_interest_agreement
            - has_signed_code_of_conduct_agreement
            - has_signed_confidentiality_agreement
            - police_check_date
            - created_by
            - created_from
            - created_from_is_public
            - last_modified_by
            - last_modified_from
            - last_modified_from_is_public
        """
        from django.template.loader import render_to_string  # HTML / TXT
        from django.utils import timezone
        from shared_foundation.models import SharedGroup
        from tenant_foundation.models import Staff

        role_id = defaults.get('role_id', None)
        has_signed_staff_agreement = defaults.get('has_signed_staff_agreement', None)
        has_signed_conflict_of_interest_agreement = defaults.get('has_signed_conflict_of_interest_agreement', None)
        has_signed_code_of_conduct_agreement = defaults.get('has_signed_code_of_conduct_agreement', None)
        has_signed_confidentiality_agreement = defaults.get('has_signed_confidentiality_agreement', None)
        police_check_date = defaults.get('police_check_date', None)
        created_by = defaults.get('created_by', None)
        created_from = defaults.get('created_from', None)
        created_from_is_public = defaults.get('created_from_is_public', None)
        last_modified_by = defaults.get('last_modified_by', None)
        last_modified_from = defaults.get('last_modified_from', None)
        last_modified_from_is_public = defaults.get('last_modified_from_is_public', None)

        # Defensive code.
        assert self.user != None
        assert isinstance(role_id, int)
        assert isinstance(has_signed_staff_agreement, bool)
        assert isinstance(has_signed_conflict_of_interest_agreement, bool)
        assert isinstance(has_signed_code_of_conduct_agreement, bool)
        assert isinstance(has_signed_confidentiality_agreement, bool)
        assert police_check_date != None

        # Get the text agreement which will be signed.
        staff_agreement = render_to_string('account/staff_agreement/2019_05_01.txt', {}) if has_signed_staff_agreement else None
        conflict_of_interest_agreement = render_to_string('account/conflict_of_interest_agreement/2019_05_01.txt', {}) if has_signed_conflict_of_interest_agreement else None
        code_of_conduct_agreement = render_to_string('account/code_of_conduct_agreement/2019_05_01.txt', {}) if has_signed_code_of_conduct_agreement else None
        confidentiality_agreement = render_to_string('account/confidentiality_agreement/2019_05_01.txt', {}) if has_signed_confidentiality_agreement else None

        # Create or update our model.
        staff, created = Staff.objects.update_or_create(
            user=self.user,
            defaults={
                'user': self.user,
                'has_signed_staff_agreement': has_signed_staff_agreement,
                'staff_agreement': staff_agreement,
                'staff_agreement_signed_on': timezone.now(),
                'has_signed_conflict_of_interest_agreement': has_signed_conflict_of_interest_agreement,
                'conflict_of_interest_agreement': conflict_of_interest_agreement,
                'conflict_of_interest_agreement_signed_on': timezone.now(),
                'has_signed_code_of_conduct_agreement': has_signed_code_of_conduct_agreement,
                'code_of_conduct_agreement': code_of_conduct_agreement,
                'code_of_conduct_agreement_signed_on': timezone.now(),
                'has_signed_confidentiality_agreement': has_signed_confidentiality_agreement,
                'confidentiality_agreement': confidentiality_agreement,
                'confidentiality_agreement_signed_on': timezone.now(),
                'police_check_date': police_check_date,
                'created_by': created_by,
                'created_from': created_from,
                'created_from_is_public': created_from_is_public,
                'created_from_position': get_point_from_ip(created_from),
                'last_modified_by': last_modified_by,
                'last_modified_from': last_modified_from,
                'last_modified_from_is_public': last_modified_from_is_public,
                'last_modified_from_position': get_point_from_ip(last_modified_from),
            }
        )

        # Set the user's role to be after clearing the previous group memberships.
        staff.user.groups.clear()
        staff.user.groups.add(role_id)

        return staff
예제 #3
0
class Ambulance(PublishMixin, UpdatedByModel):

    # TODO: Should we consider denormalizing Ambulance to avoid duplication with AmbulanceUpdate?

    equipmentholder = models.OneToOneField(EquipmentHolder,
                                           on_delete=models.CASCADE,
                                           verbose_name=_('equipmentholder'))

    # ambulance properties
    identifier = models.CharField(_('identifier'), max_length=50, unique=True)

    # TODO: Should we add an active flag?

    capability = models.CharField(_('capability'),
                                  max_length=1,
                                  choices=make_choices(AmbulanceCapability))

    # status
    status = models.CharField(_('status'),
                              max_length=2,
                              choices=make_choices(AmbulanceStatus),
                              default=AmbulanceStatus.UK.name)

    # location
    orientation = models.FloatField(_('orientation'), default=0.0)
    location = models.PointField(_('location'),
                                 srid=4326,
                                 default=defaults['location'])

    # timestamp
    timestamp = models.DateTimeField(_('timestamp'), default=timezone.now)

    # active
    active = models.BooleanField(_('active'), default=True)

    # default value for _loaded_values
    _loaded_values = None

    @classmethod
    def from_db(cls, db, field_names, values):

        # call super
        instance = super(Ambulance, cls).from_db(db, field_names, values)

        # store the original field values on the instance
        instance._loaded_values = dict(zip(field_names, values))

        # return instance
        return instance

    def save(self, *args, **kwargs):

        # creation?
        created = self.pk is None

        # loaded_values?
        loaded_values = self._loaded_values is not None

        # create equipment holder?
        try:
            if created or self.equipmentholder is None:
                self.equipmentholder = EquipmentHolder.objects.create()
        except EquipmentHolder.DoesNotExist:
            self.equipmentholder = EquipmentHolder.objects.create()

        # has location changed?
        has_moved = False
        if (not loaded_values) or \
                calculate_distance(self._loaded_values['location'], self.location) > stationary_radius:
            has_moved = True

        # calculate orientation only if location has changed and orientation has not changed
        if has_moved and loaded_values and self._loaded_values[
                'orientation'] == self.orientation:
            # TODO: should we allow for a small radius before updating direction?
            self.orientation = calculate_orientation(
                self._loaded_values['location'], self.location)
            # logger.debug('< {} - {} = {}'.format(self._loaded_values['location'],
            #                                      self.location,
            #                                      self.orientation))

        # logger.debug('loaded_values: {}'.format(loaded_values))
        # logger.debug('_loaded_values: {}'.format(self._loaded_values))

        # if comment, capability, status or location changed
        # model_changed = False
        if has_moved or \
                self._loaded_values['status'] != self.status or \
                self._loaded_values['capability'] != self.capability or \
                self._loaded_values['comment'] != self.comment:

            # save to Ambulance
            super().save(*args, **kwargs)

            # logger.debug('SAVED')

            # save to AmbulanceUpdate
            data = {
                k: getattr(self, k)
                for k in ('capability', 'status', 'orientation', 'location',
                          'timestamp', 'comment', 'updated_by', 'updated_on')
            }
            data['ambulance'] = self
            obj = AmbulanceUpdate(**data)
            obj.save()

            # logger.debug('UPDATE SAVED')

            # # model changed
            # model_changed = True

        # if identifier changed
        # NOTE: self._loaded_values is NEVER None because has_moved is True
        elif self._loaded_values['identifier'] != self.identifier:

            # save only to Ambulance
            super().save(*args, **kwargs)

            # logger.debug('SAVED')

            # # model changed
            # model_changed = True

        # # Did the model change?
        # if model_changed:
        #
        #     # publish to mqtt
        #
        #     from mqtt.publish import SingletonPublishClient
        #     SingletonPublishClient().publish_ambulance(self)
        #
        #     # logger.debug('PUBLISHED ON MQTT')

        # just created?
        if created:
            # invalidate permissions cache
            from mqtt.cache_clear import mqtt_cache_clear
            mqtt_cache_clear()

    def publish(self, **kwargs):

        # publish to mqtt
        from mqtt.publish import SingletonPublishClient
        SingletonPublishClient().publish_ambulance(self, **kwargs)

    def delete(self, *args, **kwargs):

        # invalidate permissions cache
        from mqtt.cache_clear import mqtt_cache_clear
        mqtt_cache_clear()

        # delete from Ambulance
        super().delete(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('ambulance:detail', kwargs={'pk': self.id})

    def __str__(self):
        return ('Ambulance {}(id={}) ({}) [{}]:\n' + '    Status: {}\n' +
                '  Location: {} @ {}\n' + '   Updated: {} by {}').format(
                    self.identifier, self.id,
                    AmbulanceCapability[self.capability].value, self.comment,
                    AmbulanceStatus[self.status].value, self.location,
                    self.timestamp, self.updated_by, self.updated_on)
예제 #4
0
class AggregateNeighborhood(AggregateSummaryModel):
    location = models.OneToOneField(Neighborhood, related_name='aggregates')
예제 #5
0
class GeoUser(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    home_location = models.PointField()
    current_location = models.PointField()
예제 #6
0
class Artist(models.Model):
    artist_id = models.OneToOneField(CustomUser,
                                     on_delete=models.DO_NOTHING,
                                     primary_key=True)
    genre = models.CharField(max_length=15)
    band_name = models.CharField(max_length=100)
예제 #7
0
class FacilityCoordinates(CoordinatesValidatorMixin, GISAbstractBase):

    """
    Location derived by the use of GPS satellites and GPS device or receivers.

    It is three dimensional.
    The three-dimensional readings from a GPS device are latitude, longitude,
    and attitude. The date/time the reading is done is also important, as
    is the source and method of the reading.
    """
    facility = gis_models.OneToOneField(
        Facility, related_name='facility_coordinates_through', unique=True)
    coordinates = gis_models.PointField()
    source = gis_models.ForeignKey(
        GeoCodeSource, null=True, blank=True,
        help_text="where the geo code came from", on_delete=gis_models.PROTECT)
    method = gis_models.ForeignKey(
        GeoCodeMethod, null=True, blank=True,
        help_text="Method used to obtain the geo codes. e.g"
        " taken with GPS device")
    collection_date = gis_models.DateTimeField(default=timezone.now)

    @property
    def simplify_coordinates(self):
        return {
            "coordinates": [
                float('%.2f' % round(self.coordinates[0], 2)),
                float('%.2f' % round(self.coordinates[1], 2))
            ]
        }
    def validate_coordinates_decimal_places_at_least_six(self):
        if (len(str(self.coordinates[0])) < 7 or
                len(str(self.coordinates[1])) < 7):
            raise ValidationError({
                "coordinates":
                    ["Please provide at-least 6 decimal places number. "]
                })

    @property
    def json_features(self):
        return {
            "geometry": self.simplify_coordinates,
        }

    def clean(self):
        self.validate_coordinates_decimal_places_at_least_six()
        self.validate_long_and_lat_within_kenya()
        self.validate_long_and_lat_within_county(
            self.facility.ward.constituency.county)
        self.validate_long_and_lat_within_constituency(
            self.facility.ward.constituency)
        self.validate_long_and_lat_within_ward(
            self.facility.ward)
        super(FacilityCoordinates, self).clean()

    def __str__(self):
        return "{}:{}:{}".format(self.facility, self.source, self.method)

    class Meta(GISAbstractBase.Meta):
        verbose_name_plural = 'facility coordinates'
        verbose_name = 'facility coordinates'
예제 #8
0
class Office(models.Model):
    telephone = models.CharField(max_length=48)
    account_number = models.CharField(max_length=10, unique=True)
    organisation = models.ForeignKey("Organisation", on_delete=models.CASCADE)
    location = models.OneToOneField("Location", null=True, on_delete=models.CASCADE)
    categories = models.ManyToManyField(Category)
예제 #9
0
class ProductViewCount(models.Model):
    product = models.OneToOneField(Product)
    count = models.PositiveIntegerField(default=0)
예제 #10
0
class Signal(CreatedUpdatedModel):
    SOURCE_DEFAULT_ANONYMOUS_USER = '******'

    # we need an unique id for external systems.
    # TODO SIG-563 rename `signal_id` to `signal_uuid` to be more specific.
    signal_id = models.UUIDField(default=uuid.uuid4, db_index=True)
    source = models.CharField(max_length=128,
                              default=SOURCE_DEFAULT_ANONYMOUS_USER)

    text = models.CharField(max_length=3000)
    text_extra = models.CharField(max_length=10000, default='', blank=True)

    location = models.OneToOneField('signals.Location',
                                    related_name='signal',
                                    null=True,
                                    on_delete=models.SET_NULL)
    status = models.OneToOneField('signals.Status',
                                  related_name='signal',
                                  null=True,
                                  on_delete=models.SET_NULL)
    category_assignment = models.OneToOneField('signals.CategoryAssignment',
                                               related_name='signal',
                                               null=True,
                                               on_delete=models.SET_NULL)
    categories = models.ManyToManyField('signals.Category',
                                        through='signals.CategoryAssignment')
    reporter = models.OneToOneField('signals.Reporter',
                                    related_name='signal',
                                    null=True,
                                    on_delete=models.SET_NULL)
    priority = models.OneToOneField('signals.Priority',
                                    related_name='signal',
                                    null=True,
                                    on_delete=models.SET_NULL)
    directing_departments_assignment = models.OneToOneField(
        'signals.SignalDepartments',
        related_name='directing_department_signal',
        null=True,
        on_delete=models.SET_NULL)
    routing_assignment = models.OneToOneField('signals.SignalDepartments',
                                              related_name='routing_signal',
                                              null=True,
                                              on_delete=models.SET_NULL)
    user_assignment = models.OneToOneField(
        'users.SignalUser',
        related_name='user_assignment_signal',
        null=True,
        on_delete=models.SET_NULL)

    # Date of the incident.
    incident_date_start = models.DateTimeField(null=False)
    incident_date_end = models.DateTimeField(null=True)

    # Date action is expected
    operational_date = models.DateTimeField(null=True)

    # Date we should have reported back to reporter.
    expire_date = models.DateTimeField(null=True)

    # file will be saved to MEDIA_ROOT/uploads/2015/01/30
    upload = ArrayField(models.FileField(upload_to='uploads/%Y/%m/%d/'),
                        null=True)  # TODO: remove

    extra_properties = JSONField(null=True)

    # SIG-884
    parent = models.ForeignKey(to='self',
                               related_name='children',
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL)

    objects = SignalQuerySet.as_manager()
    actions = SignalManager()

    @property
    def image(self):
        """ Field for backwards compatibility. The attachment table replaces the old 'image'
        property """
        attachment = self.attachments.filter(is_image=True).first()
        return attachment.file if attachment else ""

    @property
    def image_crop(self):
        attachment = self.attachments.filter(is_image=True).first()
        return attachment.image_crop if self.image else ''

    class Meta:
        permissions = (
            ('sia_read', 'Leesrechten algemeen'),  # SIG-2192
            ('sia_write', 'Schrijfrechten algemeen'),  # SIG-2194
            ('sia_split', 'Splitsen van een melding'),  # SIG-2192
            ('sia_signal_create_initial', 'Melding aanmaken'),  # SIG-2192
            ('sia_signal_create_note',
             'Notitie toevoegen bij een melding'),  # SIG-2192
            ('sia_signal_change_status',
             'Wijzigen van status van een melding'),  # SIG-2192
            ('sia_signal_change_category',
             'Wijzigen van categorie van een melding'),  # SIG-2192
            ('sia_signal_export', 'Meldingen exporteren'),  # SIG-2192
            ('sia_signal_report', 'Rapportage beheren'),  # SIG-2192
        )
        ordering = ('created_at', )
        indexes = [
            models.Index(fields=['created_at']),
            models.Index(fields=['id', 'parent']),
        ]

    def __init__(self, *args, **kwargs):
        super(Signal, self).__init__(*args, **kwargs)
        if not self.signal_id:
            self.signal_id = uuid.uuid4()

    def __str__(self):
        """Identifying string.
        DO NOT expose sensitive stuff here.
        """

        # Fix for bug SIG-2486 Timezones were not consistently shown
        created_at = self.created_at
        field_timezone = timezone.get_current_timezone(
        ) if settings.USE_TZ else None
        if timezone.is_aware(created_at) and field_timezone:
            created_at = created_at.astimezone(field_timezone)
        elif timezone.is_aware(created_at):
            created_at = timezone.make_naive(created_at, utc)

        return f'{self.id} - ' \
               f'{self.status.state if self.status else ""} - ' \
               f'{self.location.buurt_code if self.location else ""} - ' \
               f'{created_at.isoformat()}'

    @property
    def sia_id(self):
        """SIA identifier used for external communication.

        :returns: str
        """
        return 'SIA-{id}'.format(id=self.id)

    def get_fqdn_image_crop_url(self):
        """Get FQDN image crop url.

        :returns: url (str) or None
        """
        if not self.image_crop:
            return None

        is_swift = isinstance(self.image_crop.storage, SwiftStorage)
        if is_swift:
            return self.image_crop.url  # Generated temp url from Swift Object Store.
        else:
            # Generating a fully qualified url ourself.
            current_site = Site.objects.get_current()
            is_local = 'localhost' in current_site.domain or settings.DEBUG
            fqdn_url = '{scheme}://{domain}{path}'.format(
                scheme='http' if is_local else 'https',
                domain=current_site.domain,
                path=self.image_crop.url)
            return fqdn_url

    def is_parent(self):
        # If we have children we are a parent
        return self.children.exists()

    def is_child(self):
        # If we have a parent we are a child
        return self.parent is not None

    @property
    def siblings(self):
        if self.is_child():
            # If we are a child return all siblings
            siblings_qs = self.parent.children.all()
            if self.pk:
                # Exclude myself if possible
                return siblings_qs.exclude(pk=self.pk)
            return siblings_qs

        # Return a non queryset
        return self.__class__.objects.none()

    def _validate(self):
        if self.is_parent() and self.is_child():
            # We cannot be a parent and a child at once
            raise ValidationError('Cannot be a parent and a child at the once')

        if self.parent and self.parent.is_child():
            # The parent of this Signal cannot be a child of another Signal
            raise ValidationError('A child of a child is not allowed')

        if (self.pk is None and self.is_child() and self.siblings.count() >=
                settings.SIGNAL_MAX_NUMBER_OF_CHILDREN):
            # we are a new child and our parent already has the max number of children
            raise ValidationError(
                'Maximum number of children reached for the parent Signal')

    def save(self, *args, **kwargs):
        self._validate()
        super(Signal, self).save(*args, **kwargs)

    @property
    def type_assignment(self):
        return self.types.first() if self.types.exists() else None
예제 #11
0
class ShipmentCarrierAssignment(models.Model):
    assignment = models.OneToOneField('ShipmentAssignment',
                                      null=True,
                                      blank=True)
예제 #12
0
class Project(ModelWithSlugMixin, CloneableModelMixin, TimeStampedModel):
    STATUS_CHOICES = (
        ('not-started', _('Not Started')),
        ('active', _('Active')),
        ('complete', _('Complete')),
    )

    LINK_TYPE_CHOICES = (
        ('event', _('Event')),
        ('section', _('Section')),
        ('external', _('External URL')),
    )

    LAYOUT_CHOICES = (
        ('generic', _('Default (classic)')),
        ('shareabouts', _('Shareabouts Map')),
    )

    title = models.TextField(blank=True)
    slug = models.CharField(max_length=128, blank=True)
    public = models.BooleanField(default=False, blank=True)
    status = models.CharField(
        help_text=_("A string representing the project's status"),
        choices=STATUS_CHOICES,
        default='not-started',
        max_length=32,
        blank=True)
    location = models.TextField(help_text=_(
        "The general location of the project, e.g. \"Philadelphia, PA\", \"Clifton Heights, Louisville, KY\", \"4th St. Corridor, Brooklyn, NY\", etc."
    ),
                                default='',
                                blank=True)
    contact = models.TextField(
        help_text=_("The contact information for the project"),
        default='',
        blank=True)
    owner = models.ForeignKey('Profile', related_name='projects')

    details = JSONField(blank=True, default=dict)
    theme = models.ForeignKey('Theme',
                              related_name='projects',
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL)
    layout = models.CharField(max_length=20,
                              choices=LAYOUT_CHOICES,
                              default='generic')
    cover_img_url = models.URLField(_('Cover Image URL'),
                                    blank=True,
                                    max_length=2048)
    logo_img_url = models.URLField(_('Logo Image URL'),
                                   blank=True,
                                   max_length=2048)
    template = models.ForeignKey(
        'Project',
        help_text=_("The project, if any, that this one is based off of"),
        null=True,
        blank=True,
        on_delete=models.SET_NULL)

    geometry = models.GeometryField(null=True, blank=True)

    expires_at = models.DateTimeField(null=True, blank=True)
    payment_type = models.CharField(max_length=20, blank=True)
    customer = models.OneToOneField('moonclerk.Customer',
                                    blank=True,
                                    null=True,
                                    related_name='project')
    payments = GenericRelation('moonclerk.Payment',
                               content_type_field='item_type',
                               object_id_field='item_id')

    # NOTE: These may belong in a separate model, but are on the project for
    #       now. I think the model would be called a Highlight.
    happening_now_description = models.TextField(blank=True)
    happening_now_link_type = models.CharField(max_length=16,
                                               choices=LINK_TYPE_CHOICES,
                                               blank=True)
    happening_now_link_url = models.CharField(max_length=2048, blank=True)

    get_involved_description = models.TextField(blank=True)
    get_involved_link_type = models.CharField(max_length=16,
                                              choices=LINK_TYPE_CHOICES,
                                              blank=True)
    get_involved_link_url = models.CharField(max_length=2048, blank=True)

    # Project activity
    last_opened_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                       null=True,
                                       blank=True,
                                       related_name='+')
    last_opened_at = models.DateTimeField(null=True, blank=True)
    last_saved_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                      null=True,
                                      blank=True,
                                      related_name='+')
    last_saved_at = models.DateTimeField(null=True, blank=True)

    objects = ProjectManager()

    class Meta:
        unique_together = [('owner', 'slug')]

    def __str__(self):
        return self.title

    def get_summary(self):
        for section in self.sections.all():
            if section.type == 'text':
                return section.details.get('content', '')

    def mark_opened_by(self, user, opened_at=None):
        # TODO: This could just be done in the cache.
        self.last_opened_at = opened_at or now()
        self.last_opened_by = user if (user
                                       and user.is_authenticated()) else None
        self.save()

    def mark_closed(self):
        self.mark_opened_by(None)

    def is_opened_by(self, user):
        two_minutes = timedelta(minutes=2)
        return self.last_opened_by == user and (
            now() - self.last_opened_at) < two_minutes

    def get_opened_by(self):
        two_minutes = timedelta(minutes=2)
        if self.last_opened_at and (now() - self.last_opened_at) < two_minutes:
            return self.last_opened_by
        else:
            return None

    def natural_key(self):
        return self.owner.natural_key() + (self.slug, )

    def get_slug_basis(self):
        """
        Get the string off that will be slugified to construct the slug.
        """
        return self.title

    def get_all_slugs(self):
        """
        Generate the set of all mututally unique slugs with respect to this
        model.
        """
        return [p.slug for p in self.owner.projects.all()]

    def slug_exists(self, slug):
        return self.owner.projects.filter(slug__iexact=slug).exists()

    def clone(self, *args, **kwargs):
        new_inst = super(Project, self).clone(*args, **kwargs)
        for e in self.events.all():
            e.clone(project=new_inst)
        for s in self.sections.all():
            s.clone(project=new_inst)
        return new_inst

    def owned_by(self, obj):
        UserAuth = auth.get_user_model()
        if isinstance(obj, UserAuth):
            try:
                obj = obj.profile
            except Profile.DoesNotExist:
                return False
        return (self.owner == obj)

    def editable_by(self, obj):
        UserAuth = auth.get_user_model()
        if hasattr(obj, 'is_authenticated') and not obj.is_authenticated():
            return False

        if isinstance(obj, UserAuth):
            try:
                obj = obj.profile
            except Profile.DoesNotExist:
                return False

        if obj.auth.is_superuser:
            return True

        return self.owned_by(obj) or (obj in self.owner.members.all())

    def reset_trial_period(self):
        if hasattr(settings, 'TRIAL_DURATION'):
            duration = settings.TRIAL_DURATION
            if not isinstance(duration, timedelta):
                duration = timedelta(seconds=duration)
            self.expires_at = now() + duration

    def save(self, *args, **kwargs):
        if self.pk is None:  # Creating...
            if self.expires_at is None:
                self.reset_trial_period()
        return super(Project, self).save(*args, **kwargs)
예제 #13
0
class Profile(ModelWithSlugMixin, TimeStampedModel):
    name = models.CharField(max_length=128,
                            blank=True,
                            help_text=_('The full name of the person or team'))
    slug = models.CharField(
        max_length=128,
        unique=True,
        blank=True,
        help_text=
        _('A short name that will be used in URLs for projects owned by this profile'
          ))
    email = models.EmailField(
        blank=True, help_text=_('Contact email address of the profile holder'))
    description = models.TextField(blank=True, default='')
    avatar_url = models.URLField(blank=True, null=True)
    # projects (reverse, Project)

    # User-profile specific
    auth = models.OneToOneField(settings.AUTH_USER_MODEL,
                                related_name='profile',
                                null=True,
                                blank=True,
                                on_delete=models.CASCADE)
    affiliation = models.CharField(max_length=256, blank=True, default='')
    teams = models.ManyToManyField('Profile',
                                   related_name='members',
                                   blank=True,
                                   limit_choices_to={'auth__isnull': True})

    # Team-profile specific
    # members (reverse, Profile)

    # Feature flags/versions
    class Versions:
        AMETHYST = 1
        BISTRE = 2

    PROJECT_EDITOR_VERSION_CHOICES = (
        (Versions.AMETHYST, "Amethyst"),
        (Versions.BISTRE, "Bistre"),
    )

    project_editor_version = models.PositiveIntegerField(
        choices=PROJECT_EDITOR_VERSION_CHOICES, default=Versions.BISTRE)

    objects = ProfileManager()

    def __str__(self):
        return self.slug if self.auth is None else self.auth.username

    def natural_key(self):
        return (self.slug, )

    def get_slug_basis(self):
        return self.name

    def get_all_slugs(self):
        return set([p['slug'] for p in Profile.objects.all().values('slug')])

    def slug_exists(self, slug):
        return Profile.objects.filter(slug__iexact=slug).exists()

    def is_user_profile(self):
        return self.auth is not None

    def is_owned_by(self, user):
        return (user.id == self.auth_id)

    def has_member(self, user):
        members = list(self.members.all())
        if user.id in [profile.auth_id for profile in members]:
            return True
        else:
            return any(profile.has_member(user) for profile in members)

    def is_synced_with_auth(self, auth=None):
        auth = auth or self.auth
        if self.email != auth.email:
            return False
        return True

    def save(self, **kwargs):
        super(Profile, self).save(**kwargs)
        if self.auth and not self.is_synced_with_auth():
            self.auth.username = self.slug
            self.auth.email = self.email
            self.auth.save()

    def authorizes(self, user):
        """
        Test whether a given authenticated user is allowed to perform
        actions on behalf of this profile.
        """
        if user.is_superuser:
            return True

        if self.is_owned_by(user):
            return True

        if self.has_member(user):
            return True

        return False
예제 #14
0
class UserProfile(models.Model):
    # https://docs.djangoproject.com/en/dev/topics/auth/#creating-users
    # This field is required.
    user = models.OneToOneField(User, related_name="profile")
    email_announcements = models.BooleanField(default=True)
    default_location = models.PointField(null=True,
                                         blank=True,
                                         help_text='Default center point')
    # default to private
    default_view_authority = models.ForeignKey(
        'ObjectAuthority',
        default=1,
        verbose_name='Share Preference',
        help_text='Your default sharing settings for your maps and media')
    contacts = models.ManyToManyField(
        'auth.User',
        related_name='%(app_label)s_%(class)s_related',
        blank=True,
        verbose_name="Users You're Following")
    date_created = models.DateTimeField(default=datetime.now)
    time_stamp = models.DateTimeField(default=datetime.now,
                                      db_column='last_updated')
    objects = models.GeoManager()

    class Meta:
        app_label = 'site'

    @classmethod
    def update_location(self, profile, point):
        profile.default_location = point
        profile.save()
        return True

    @classmethod
    def create(cls, user):
        # create a new profile:
        profile = UserProfile()
        profile.email_announcements = True
        profile.default_view_authority = ObjectAuthority.objects.get(id=1)
        profile.user = user
        profile.save()

        # create a default project:
        default_project = Project()
        default_project.slug = 'default-' + user.username
        default_project.name = 'My First Project'
        default_project.description = 'Default Local Ground project'
        default_project.last_updated_by = user
        default_project.access_authority = ObjectAuthority.objects.get(id=1)
        default_project.owner = user
        default_project.save()

        # create map:
        StyledMap.create(center=GEOSGeometry(
            '{"type": "Point", "coordinates": [-122, 38]}'),
                         zoom=6,
                         last_updated_by=default_project.owner,
                         owner=default_project.owner,
                         project=default_project,
                         slug=uuid.uuid4().hex,
                         name='Untitled Map')
        return profile

    def can_view(self, user=None, access_key=None):
        if user.is_authenticated():
            return True

    def can_edit(self, user):
        if user.is_authenticated():
            return True

    def can_manage(self, user):
        if user.is_authenticated():
            return True
예제 #15
0
class StationBasin(Garea, GGRS87Mixin, BasinMixin):
    """A subbasin defined by a measuring station."""

    river_basin = models.ForeignKey(RiverBasin, on_delete=models.CASCADE)
    station = models.OneToOneField(Station, on_delete=models.CASCADE)
예제 #16
0
class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone = models.CharField(max_length=20, blank=True, null=True)

    def __str__(self):
        return f"{self.user}'s profile"
예제 #17
0
class CustomUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    role_num = models.ForeignKey(Role, on_delete=models.DO_NOTHING)
예제 #18
0
class SignupToken(models.Model):
    uuid = models.UUIDField(primary_key=True,
                            default=uuid.uuid4,
                            editable=False)
    referrer = models.CharField(max_length=255, blank=True, null=True)
    user = models.OneToOneField(User, on_delete=models.PROTECT, null=True)
예제 #19
0
class Profile(models.Model):
    user = models.OneToOneField(User, unique=True)
    country = CountryField(verbose_name=_("Country"), null=True, blank=True)
    affiliation = models.CharField(verbose_name=_("Affiliation"),
                                   max_length=250,
                                   null=True,
                                   blank=True)
    telephone = models.CharField(verbose_name=_("Telephone"),
                                 max_length=20,
                                 null=True,
                                 blank=True)
    address1 = models.CharField(verbose_name=_("Address1"),
                                max_length=50,
                                null=True,
                                blank=True)
    address2 = models.CharField(verbose_name=_("Address2"),
                                max_length=50,
                                null=True,
                                blank=True)
    city = models.CharField(verbose_name=_("City"),
                            max_length=50,
                            null=True,
                            blank=True)
    state = models.CharField(verbose_name=_("State"),
                             max_length=80,
                             null=True,
                             blank=True)
    postal = models.CharField(verbose_name=_("Postal code"),
                              max_length=10,
                              null=True,
                              blank=True)
    url = models.CharField(verbose_name=_("URL"),
                           max_length=100,
                           null=True,
                           blank=True)
    gisday = models.NullBooleanField(verbose_name=_("Attending GIS Day"),
                                     blank=True,
                                     null=True)

    def get_all_fields(self):
        """Returns a list of all field names on the instance."""
        fields = []
        for f in self._meta.fields:

            fname = f.name
            # resolve picklists/choices, with get_xyz_display() function
            get_choice = 'get_' + fname + '_display'
            if hasattr(self, get_choice):
                value = getattr(self, get_choice)()
            else:
                try:
                    value = getattr(self, fname)
                except User.DoesNotExist:
                    value = None

            # only display fields with values and skip some fields entirely
            if f.editable and value and f.name not in ('id', 'status',
                                                       'workshop', 'user',
                                                       'complete'):

                fields.append({
                    'label': f.verbose_name,
                    'name': f.name,
                    'value': value,
                })
        return fields

    def __unicode__(self):
        return self.user.username
예제 #20
0
class Avaliacao(models.Model):

    OPCOES = (
        ('favoravel', 'Favorável'),
        ('aceitavel', 'Aceitável'),
        ('critica', 'Crítica'),
    )

    ponto = models.OneToOneField('Ponto')
    acesso = models.CharField("Condição de Acesso",
                              choices=OPCOES,
                              max_length=10)
    acesso_desc = models.TextField("Justificativa Acesso")

    abrigo = models.CharField("Condição do Abrigo",
                              choices=OPCOES,
                              max_length=10)
    abrigo_desc = models.TextField("Justificativa Abrigo")

    piso = models.CharField("Condição do Piso", choices=OPCOES, max_length=10)
    piso_desc = models.TextField("Justificativa Piso")

    rampa = models.CharField("Condição das Rampas",
                             choices=OPCOES,
                             max_length=10)
    rampa_desc = models.TextField("Justificativa Rampas")

    calcada = models.CharField("Condição das Calçadas",
                               choices=OPCOES,
                               max_length=10)
    calcada_desc = models.TextField("Justificativa Calçada")

    plataforma = models.CharField("Condição das Plataformas",
                                  choices=OPCOES,
                                  max_length=10)
    plataforma_desc = models.TextField("Justificativa Plataformas")

    transito = models.CharField("Condição do Trânsito de Usuários",
                                choices=OPCOES,
                                max_length=10)
    transito_desc = models.TextField("Justificativa Trânsito")

    equipamento = models.CharField("Condição dos Equipamentos",
                                   choices=OPCOES,
                                   max_length=10)
    equipamento_desc = models.TextField("Justificativa Equipamentos")

    identificacao = models.CharField("Condição de Identificação",
                                     choices=OPCOES,
                                     max_length=10)
    identificacao_desc = models.TextField("Justificativa Identificação")

    piso_tatil = models.CharField("Condição do Piso Tátil",
                                  choices=OPCOES,
                                  max_length=10)
    piso_tatil_desc = models.TextField("Justificativa Piso Tátil")

    linhas = models.CharField("Condição de Identificação das Linhas de Ônibus",
                              choices=OPCOES,
                              max_length=10)
    linhas_desc = models.TextField("Justificativa Identificação das Linhas")

    logradouro = models.CharField("Condição de Identificação do Logradouro",
                                  choices=OPCOES,
                                  max_length=10)
    logradouro_desc = models.TextField("Justificativa Logradouro")
    objects = models.GeoManager()

    def final(self):
        resultado = [
            self.acesso, self.abrigo, self.piso, self.rampa, self.calcada,
            self.plataforma, self.transito, self.equipamento,
            self.identificacao, self.piso_tatil, self.linhas, self.logradouro
        ]
        pontuacao = resultado.count('favoravel') * 2 \
            + resultado.count('aceitavel') * 1

        if pontuacao >= 14:
            return 'favoravel'
        elif pontuacao >= 7:
            return 'aceitavel'
        else:
            return 'critica'

    def __str__(self):
        return 'Avaliação do Ponto %s' % self.ponto

    class Meta:
        verbose_name = "Avaliação"
        verbose_name_plural = "Avaliações"
예제 #21
0
class TreeResource(ResourceSummaryModel):
    """
    resource results for a specific tree.  should get updated whenever a tree does.
    """
    tree = models.OneToOneField(Tree, primary_key=True)
    def __unicode__(self): return '%s' % (self.tree)
예제 #22
0
class Trek(StructureRelated, PicturesMixin, PublishableMixin, MapEntityMixin,
           Topology):
    topo_object = models.OneToOneField(Topology,
                                       parent_link=True,
                                       db_column='evenement')
    departure = models.CharField(verbose_name=_(u"Departure"),
                                 max_length=128,
                                 blank=True,
                                 help_text=_(u"Departure description"),
                                 db_column='depart')
    arrival = models.CharField(verbose_name=_(u"Arrival"),
                               max_length=128,
                               blank=True,
                               help_text=_(u"Arrival description"),
                               db_column='arrivee')

    description_teaser = models.TextField(
        verbose_name=_(u"Description teaser"),
        blank=True,
        help_text=_(u"A brief summary (map pop-ups)"),
        db_column='chapeau')
    description = models.TextField(verbose_name=_(u"Description"),
                                   blank=True,
                                   db_column='description',
                                   help_text=_(u"Complete description"))
    ambiance = models.TextField(verbose_name=_(u"Ambiance"),
                                blank=True,
                                db_column='ambiance',
                                help_text=_(u"Main attraction and interest"))
    access = models.TextField(verbose_name=_(u"Access"),
                              blank=True,
                              db_column='acces',
                              help_text=_(u"Best way to go"))
    disabled_infrastructure = models.TextField(
        verbose_name=_(u"Disabled infrastructure"),
        db_column='handicap',
        blank=True,
        help_text=_(u"Any specific infrastructure"))
    duration = models.FloatField(
        verbose_name=_(u"Duration"),
        default=0,
        blank=True,
        db_column='duree',
        help_text=_(u"In decimal hours (ex. 1.5 for 1 h 30)"),
        validators=[MinValueValidator(0)])
    is_park_centered = models.BooleanField(
        verbose_name=_(u"Is in the midst of the park"),
        db_column='coeur',
        help_text=_(u"Crosses center of park"))
    advised_parking = models.CharField(verbose_name=_(u"Advised parking"),
                                       max_length=128,
                                       blank=True,
                                       db_column='parking',
                                       help_text=_(u"Where to park"))
    parking_location = models.PointField(verbose_name=_(u"Parking location"),
                                         db_column='geom_parking',
                                         srid=settings.SRID,
                                         spatial_index=False,
                                         blank=True,
                                         null=True)
    public_transport = models.TextField(
        verbose_name=_(u"Public transport"),
        blank=True,
        db_column='transport',
        help_text=_(u"Train, bus (see web links)"))
    advice = models.TextField(verbose_name=_(u"Advice"),
                              blank=True,
                              db_column='recommandation',
                              help_text=_(u"Risks, danger, best period, ..."))
    themes = models.ManyToManyField(Theme,
                                    related_name="treks",
                                    db_table="o_r_itineraire_theme",
                                    blank=True,
                                    null=True,
                                    verbose_name=_(u"Themes"),
                                    help_text=_(u"Main theme(s)"))
    networks = models.ManyToManyField('TrekNetwork',
                                      related_name="treks",
                                      db_table="o_r_itineraire_reseau",
                                      blank=True,
                                      null=True,
                                      verbose_name=_(u"Networks"),
                                      help_text=_(u"Hiking networks"))
    practice = models.ForeignKey('Practice',
                                 related_name="treks",
                                 blank=True,
                                 null=True,
                                 verbose_name=_(u"Practice"),
                                 db_column='pratique')
    accessibilities = models.ManyToManyField(
        'Accessibility',
        related_name="treks",
        db_table="o_r_itineraire_accessibilite",
        blank=True,
        null=True,
        verbose_name=_(u"Accessibilities"))
    route = models.ForeignKey('Route',
                              related_name='treks',
                              blank=True,
                              null=True,
                              verbose_name=_(u"Route"),
                              db_column='parcours')
    difficulty = models.ForeignKey('DifficultyLevel',
                                   related_name='treks',
                                   blank=True,
                                   null=True,
                                   verbose_name=_(u"Difficulty"),
                                   db_column='difficulte')
    web_links = models.ManyToManyField('WebLink',
                                       related_name="treks",
                                       db_table="o_r_itineraire_web",
                                       blank=True,
                                       null=True,
                                       verbose_name=_(u"Web links"),
                                       help_text=_(u"External resources"))
    related_treks = models.ManyToManyField(
        'self',
        through='TrekRelationship',
        verbose_name=_(u"Related treks"),
        symmetrical=False,
        help_text=_(u"Connections between treks"),
        related_name='related_treks+')  # Hide reverse attribute
    parent = models.ForeignKey('self',
                               verbose_name=_(u"Parent"),
                               db_column='parent',
                               blank=True,
                               null=True,
                               related_name='children')
    information_desks = models.ManyToManyField(
        tourism_models.InformationDesk,
        related_name='treks',
        db_table="o_r_itineraire_renseignement",
        blank=True,
        null=True,
        verbose_name=_(u"Information desks"),
        help_text=_(u"Where to obtain information"))
    points_reference = models.MultiPointField(
        verbose_name=_(u"Points of reference"),
        db_column='geom_points_reference',
        srid=settings.SRID,
        spatial_index=False,
        blank=True,
        null=True)
    source = models.ManyToManyField('common.RecordSource',
                                    null=True,
                                    blank=True,
                                    related_name='treks',
                                    verbose_name=_("Source"),
                                    db_table='o_r_itineraire_source')
    eid = models.CharField(verbose_name=_(u"External id"),
                           max_length=128,
                           blank=True,
                           db_column='id_externe')
    eid2 = models.CharField(verbose_name=_(u"Second external id"),
                            max_length=128,
                            blank=True,
                            db_column='id_externe2')

    objects = Topology.get_manager_cls(models.GeoManager)()

    category_id_prefix = 'T'

    class Meta:
        db_table = 'o_t_itineraire'
        verbose_name = _(u"Trek")
        verbose_name_plural = _(u"Treks")
        ordering = ['name']

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_document_public_url(self):
        """ Override ``geotrek.common.mixins.PublishableMixin``
        """
        return ('trekking:trek_document_public', [], {
            'lang': get_language(),
            'pk': self.pk,
            'slug': self.slug
        })

    @property
    def related(self):
        return self.related_treks.exclude(deleted=True).exclude(
            pk=self.pk).distinct()

    @classproperty
    def related_verbose_name(cls):
        return _("Related treks")

    @property
    def relationships(self):
        # Does not matter if a or b
        return TrekRelationship.objects.filter(trek_a=self)

    @property
    def published_relationships(self):
        return self.relationships.filter(trek_b__published=True)

    @property
    def poi_types(self):
        if settings.TREKKING_TOPOLOGY_ENABLED:
            # Can't use values_list and must add 'ordering' because of bug:
            # https://code.djangoproject.com/ticket/14930
            values = self.pois.values('ordering', 'type')
        else:
            values = self.pois.values('type')
        pks = [value['type'] for value in values]
        return POIType.objects.filter(pk__in=set(pks))

    @property
    def length_kilometer(self):
        return "%.1f" % (self.length / 1000.0)

    @property
    def networks_display(self):
        return ', '.join([unicode(n) for n in self.networks.all()])

    @property
    def districts_display(self):
        return ', '.join([unicode(d) for d in self.districts])

    @property
    def themes_display(self):
        return ', '.join([unicode(n) for n in self.themes.all()])

    @property
    def city_departure(self):
        cities = self.cities
        return unicode(cities[0]) if len(cities) > 0 else ''

    def kml(self):
        """ Exports trek into KML format, add geometry as linestring and POI
        as place marks """
        kml = simplekml.Kml()
        # Main itinerary
        geom3d = self.geom_3d.transform(4326, clone=True)  # KML uses WGS84
        line = kml.newlinestring(name=self.name,
                                 description=plain_text(self.description),
                                 coords=geom3d.coords)
        line.style.linestyle.color = simplekml.Color.red  # Red
        line.style.linestyle.width = 4  # pixels
        # Place marks
        for poi in self.pois:
            place = poi.geom_3d.transform(settings.API_SRID, clone=True)
            kml.newpoint(name=poi.name,
                         description=plain_text(poi.description),
                         coords=[place.coords])
        return kml._genkml()

    def has_geom_valid(self):
        """A trek should be a LineString, even if it's a loop.
        """
        return super(Trek, self).has_geom_valid(
        ) and self.geom.geom_type.lower() == 'linestring'

    @property
    def duration_pretty(self):
        return trekking_tags.duration(self.duration)

    @classproperty
    def duration_pretty_verbose_name(cls):
        return _("Formated duration")

    @classmethod
    def path_treks(cls, path):
        treks = cls.objects.existing().filter(aggregations__path=path)
        # The following part prevents conflict with default trek ordering
        # ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
        return treks.order_by('topo_object').distinct('topo_object')

    @classmethod
    def topology_treks(cls, topology):
        if settings.TREKKING_TOPOLOGY_ENABLED:
            qs = cls.overlapping(topology)
        else:
            area = topology.geom.buffer(settings.TREK_POI_INTERSECTION_MARGIN)
            qs = cls.objects.existing().filter(geom__intersects=area)
        return qs

    @classmethod
    def published_topology_treks(cls, topology):
        return cls.topology_treks(topology).filter(published=True)

    # Rando v1 compat
    @property
    def usages(self):
        return [self.practice] if self.practice else []

    @classmethod
    def get_create_label(cls):
        return _(u"Add a new trek")

    @property
    def children_id(self):
        return list(
            self.children.order_by('name').values_list('id', flat=True))

    @property
    def previous_id(self):
        if self.parent is None:
            return None
        children = self.parent.children_id
        try:
            return children[children.index(self.id) - 1]
        except IndexError:
            return None

    @property
    def next_id(self):
        if self.parent is None:
            return None
        children = self.parent.children_id
        try:
            return children[children.index(self.id) + 1]
        except IndexError:
            return None

    def clean(self):
        if self.parent and self.parent == self:
            raise ValidationError(_(u"Cannot use itself as parent trek."))
        if self.parent and self.parent.parent:
            raise ValidationError(
                _(u"Cannot use a a child trek as parent trek."))

    @property
    def prefixed_category_id(self):
        if settings.SPLIT_TREKS_CATEGORIES_BY_PRACTICE and self.practice:
            return '{prefix}{id}'.format(prefix=self.category_id_prefix,
                                         id=self.practice.id)
        else:
            return self.category_id_prefix

    def distance(self, to_cls):
        if self.practice and self.practice.distance is not None:
            return self.practice.distance
        else:
            return settings.TOURISM_INTERSECTION_MARGIN

    def is_public(self):
        return self.any_published or (self.parent
                                      and self.parent.any_published)

    def save(self, *args, **kwargs):
        if self.pk is not None and kwargs.get('update_fields', None) is None:
            field_names = set()
            for field in self._meta.concrete_fields:
                if not field.primary_key and not hasattr(field, 'through'):
                    field_names.add(field.attname)
            old_trek = Trek.objects.get(pk=self.pk)
            if self.geom is not None and old_trek.geom.equals_exact(
                    self.geom, tolerance=0.00001):
                field_names.remove('geom')
            if self.geom_3d is not None and old_trek.geom_3d.equals_exact(
                    self.geom_3d, tolerance=0.00001):
                field_names.remove('geom_3d')
            return super(Trek, self).save(update_fields=field_names,
                                          *args,
                                          **kwargs)
        super(Trek, self).save(*args, **kwargs)
예제 #23
0
class AggregateZipCode(AggregateSummaryModel):
    location = models.OneToOneField(ZipCode, related_name='aggregates')
예제 #24
0
class POI(StructureRelated, PicturesMixin, PublishableMixin, MapEntityMixin,
          Topology):

    topo_object = models.OneToOneField(Topology,
                                       parent_link=True,
                                       db_column='evenement')
    description = models.TextField(verbose_name=_(u"Description"),
                                   db_column='description',
                                   help_text=_(u"History, details,  ..."))
    type = models.ForeignKey('POIType',
                             related_name='pois',
                             verbose_name=_(u"Type"),
                             db_column='type')
    eid = models.CharField(verbose_name=_(u"External id"),
                           max_length=128,
                           blank=True,
                           db_column='id_externe')

    class Meta:
        db_table = 'o_t_poi'
        verbose_name = _(u"POI")
        verbose_name_plural = _(u"POI")

    # Override default manager
    objects = Topology.get_manager_cls(POIManager)()

    def __unicode__(self):
        return u"%s (%s)" % (self.name, self.type)

    @models.permalink
    def get_document_public_url(self):
        """ Override ``geotrek.common.mixins.PublishableMixin``
        """
        return ('trekking:poi_document_public', [], {
            'lang': get_language(),
            'pk': self.pk,
            'slug': self.slug
        })

    def save(self, *args, **kwargs):
        super(POI, self).save(*args, **kwargs)
        # Invalidate treks map
        for trek in self.treks.all():
            try:
                os.remove(trek.get_map_image_path())
            except OSError:
                pass

    @property
    def type_display(self):
        return unicode(self.type)

    @property
    def serializable_type(self):
        return {
            'label': self.type.label,
            'pictogram': self.type.get_pictogram_url()
        }

    @classmethod
    def path_pois(cls, path):
        return cls.objects.existing().filter(
            aggregations__path=path).distinct('pk')

    @classmethod
    def topology_pois(cls, topology):
        if settings.TREKKING_TOPOLOGY_ENABLED:
            qs = cls.overlapping(topology)
        else:
            area = topology.geom.buffer(settings.TREK_POI_INTERSECTION_MARGIN)
            qs = cls.objects.existing().filter(geom__intersects=area)
        return qs

    @classmethod
    def published_topology_pois(cls, topology):
        return cls.topology_pois(topology).filter(published=True)

    def distance(self, to_cls):
        return settings.TOURISM_INTERSECTION_MARGIN
예제 #25
0
class LonelyPerson(models.Model):
    only_friend = models.OneToOneField(Person, on_delete=models.CASCADE)
예제 #26
0
class Service(StructureRelated, MapEntityMixin, Topology):

    topo_object = models.OneToOneField(Topology,
                                       parent_link=True,
                                       db_column='evenement')
    type = models.ForeignKey('ServiceType',
                             related_name='services',
                             verbose_name=_(u"Type"),
                             db_column='type')
    eid = models.CharField(verbose_name=_(u"External id"),
                           max_length=128,
                           blank=True,
                           db_column='id_externe')

    class Meta:
        db_table = 'o_t_service'
        verbose_name = _(u"Service")
        verbose_name_plural = _(u"Services")

    # Override default manager
    objects = Topology.get_manager_cls(ServiceManager)()

    def __unicode__(self):
        return unicode(self.type)

    @property
    def name(self):
        return self.type.name

    @property
    def name_display(self):
        s = u'<a data-pk="%s" href="%s" title="%s">%s</a>' % (
            self.pk, self.get_detail_url(), self.name, self.name)
        if self.type.published:
            s = u'<span class="badge badge-success" title="%s">&#x2606;</span> ' % _(
                "Published") + s
        elif self.type.review:
            s = u'<span class="badge badge-warning" title="%s">&#x2606;</span> ' % _(
                "Waiting for publication") + s
        return s

    @classproperty
    def name_verbose_name(cls):
        return _("Type")

    @property
    def type_display(self):
        return unicode(self.type)

    @property
    def serializable_type(self):
        return {
            'label': self.type.label,
            'pictogram': self.type.get_pictogram_url()
        }

    @classmethod
    def path_services(cls, path):
        return cls.objects.existing().filter(
            aggregations__path=path).distinct('pk')

    @classmethod
    def topology_services(cls, topology):
        if settings.TREKKING_TOPOLOGY_ENABLED:
            qs = cls.overlapping(topology)
        else:
            area = topology.geom.buffer(settings.TREK_POI_INTERSECTION_MARGIN)
            qs = cls.objects.existing().filter(geom__intersects=area)
        if isinstance(topology, Trek):
            qs = qs.filter(type__practices=topology.practice)
        return qs

    @classmethod
    def published_topology_services(cls, topology):
        return cls.topology_services(topology).filter(type__published=True)

    def distance(self, to_cls):
        return settings.TOURISM_INTERSECTION_MARGIN
예제 #27
0
class Coordinates(models.Model):
    hotel = models.OneToOneField(Hotels, on_delete=models.CASCADE)
    lat = models.DecimalField(max_digits=10, decimal_places=7)
    lon = models.DecimalField(max_digits=10, decimal_places=7)
예제 #28
0
파일: gw_well.py 프로젝트: meomancer/gwml2
class GWWell(models.Model):
    """
    7.6.38 GW_Well
    A shaft or hole sunk, dug or drilled into the Earth to observe, extract or inject water (after
    IGH1397)."""

    gw_well_name = models.TextField(null=False,
                                    blank=False,
                                    verbose_name="gwWellName",
                                    help_text="Name or ID of the well.")
    gw_well_location = models.PointField(
        null=False,
        blank=False,
        verbose_name="gwWellLocation",
        help_text="Surface location of the well.")
    gw_well_contribution_zone = models.GeometryField(
        null=True,
        blank=True,
        verbose_name="gwWellContributionZone",
        help_text="The area or volume surrounding a pumping well"
        "or other discharge site that encompasses all areas"
        "and features that supply groundwater to the well"
        "or discharge site.")
    gw_well_construction = models.ForeignKey(
        Borehole,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name="gwWellConstruction",
        help_text="Construction details for a well.")
    gw_well_total_length = models.FloatField(
        null=True,
        blank=True,
        verbose_name="gwWellTotalLength",
        help_text="Total length of the well from reference elevation.")
    gw_well_status = models.ForeignKey(
        WellStatusTypeTerm,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name="gwWellStatus",
        help_text="Status of the well, Can be new, unfinished, "
        "reconditioned, deepened, not in use, standby,"
        "unknown, abandoned dry, abandoned"
        "insufficient, abandoned quality. (gwml1)")
    gw_well_static_water_depth = models.OneToOneField(
        Quantity,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name="gwWellStaticWaterDepth",
        help_text="Depth of the fluid body (e.g. piezometric level).",
        related_name='gw_well_static_water_depth')
    gw_well_licence = models.OneToOneField(
        GWLicence,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name='gwWellLicence',
        help_text=
        'Licence relating to the drilling of the well or to the extraction of groundwater.'
    )
    gw_well_constructed_depth = models.OneToOneField(
        Quantity,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name="gwWellConstructedDepth",
        help_text="Constructed depth of the well.",
        related_name='gw_well_constructed_depth')
예제 #29
0
class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True, on_delete=models.CASCADE)
    age = models.IntegerField()
예제 #30
0
class LandUseAgreementCompensations(NameModel):
    """
    In Finnish: Maankäyttökorvaus
    """

    # In Finnish: Maankäyttösopimus
    land_use_agreement = models.OneToOneField(
        LandUseAgreement,
        related_name="compensations",
        verbose_name=_("Land use agreement"),
        null=True,
        on_delete=models.CASCADE,
    )

    # In Finnish: Rahakorvaus
    cash_compensation = models.DecimalField(
        verbose_name=_("Cash compensation"),
        decimal_places=2,
        max_digits=12,
        blank=True,
        null=True,
    )

    # In Finnish: Maakorvaus
    land_compensation = models.DecimalField(
        verbose_name=_("Land compensation"),
        decimal_places=2,
        max_digits=12,
        blank=True,
        null=True,
    )

    # In Finnish: Muu korvaus
    other_compensation = models.DecimalField(
        verbose_name=_("Other compensation"),
        decimal_places=2,
        max_digits=12,
        blank=True,
        null=True,
    )

    # In Finnish: Ensimmäisen maksuerän korotus
    first_installment_increase = models.DecimalField(
        verbose_name=_("First installment increase"),
        decimal_places=2,
        max_digits=12,
        blank=True,
        null=True,
    )

    # In Finnish: Katualueen hankinta-arvo
    street_acquisition_value = models.DecimalField(
        verbose_name=_("Street acquisition value"),
        decimal_places=2,
        max_digits=12,
        blank=True,
        null=True,
    )

    # In Finnish: Katualueen pinta-ala
    street_area = models.DecimalField(
        decimal_places=2, max_digits=12, blank=True, null=True
    )

    # In Finnish: Puistoalueen hankinta-arvo
    park_acquisition_value = models.DecimalField(
        verbose_name=_("Park acquisition value"),
        decimal_places=2,
        max_digits=12,
        blank=True,
        null=True,
    )

    # In Finnish: Puistoalueen pinta-ala
    park_area = models.DecimalField(
        decimal_places=2, max_digits=12, blank=True, null=True
    )

    # In Finnish: Muun alueen hankinta-arvo
    other_acquisition_value = models.DecimalField(
        verbose_name=_("Other acquisition value"),
        decimal_places=2,
        max_digits=12,
        blank=True,
        null=True,
    )

    # In Finnish: Muun alueen pinta-ala
    other_area = models.DecimalField(
        decimal_places=2, max_digits=12, blank=True, null=True
    )