<commit_before># coding: utf-8

from django.db import models
from django.utils.translation import ugettext_lazy as _

from accounts.models import UserAccount
from scheduler.models import Shift


class Membership(models.Model):
    related_name = None

    class JoinMode:
        INVITATION_ONLY, APPROVAL_BY_ADMIN, ANYONE = 0, 1, 2
        CHOICES = (
            (INVITATION_ONLY, _(u'by invitation')),
            (APPROVAL_BY_ADMIN, _(u'anyone (approved by manager)')),
            (ANYONE, _(u'anyone')),
        )

    class Status:
        REJECTED, PENDING, APPROVED = 0, 1, 2
        CHOICES = (
            (REJECTED, _(u'rejected')),
            (PENDING, _(u'pending')),
            (APPROVED, _(u'approved')),
        )

    class Roles:
        ADMIN, MANAGER, MEMBER = 0, 1, 2
        CHOICES = (
            (ADMIN, _(u'admin')),
            (MANAGER, _(u'manager')),
            (MEMBER, _(u'member')),
        )

    role = models.PositiveSmallIntegerField(choices=Roles.CHOICES,
                                            default=Roles.MEMBER,
                                            verbose_name=_(u'role'))

    status = models.PositiveSmallIntegerField(choices=Status.CHOICES,
                                              default=Status.APPROVED,
                                              verbose_name=_(u'status'))

    user_account = models.ForeignKey(UserAccount,
                                     verbose_name=_(u'user account'),
                                     related_name=related_name)

    class Meta:
        abstract = True


class Organization(models.Model):
    # the name of the organization, ie. "<NAME>"
    name = models.CharField(max_length=256, verbose_name=_(u'name'))

    # a short description of the organization.
    # will be derived from description, if empty
    short_description = models.TextField(blank=True,
                                         verbose_name=_(u'short description'))

    # a description of the organization
    description = models.TextField(verbose_name=_(u'description'))

    # anything one needs to know on how to contact the facility
    contact_info = models.TextField(verbose_name=_(u'contact info'))

    # the orgs address
    address = models.TextField(verbose_name=_('address'))

    # users associated with this organization
    # ie. members, admins, admins
    members = models.ManyToManyField(
        UserAccount,
        through='organizations.OrganizationMembership'
    )

    slug = models.SlugField(verbose_name=_(u'slug'))

    join_mode = models.PositiveSmallIntegerField(
        choices=Membership.JoinMode.CHOICES,
        default=Membership.JoinMode.INVITATION_ONLY,
        verbose_name=_(u'join mode'),
        help_text=_(u'Who can join this organization?'))

    class Meta:
        verbose_name = _(u'organization')
        verbose_name_plural = _(u'organizations')
        ordering = ('name',)

    def __unicode__(self):
        return _(u"{name}").format(name=self.name)


class Facility(models.Model):
    # the organization running this facility
    organization = models.ForeignKey('organizations.Organization',
                                     verbose_name=_('organization'),
                                     related_name='facilities')

    # the name of the facility, ie. "Fehrbelliner Platz 4"
    name = models.CharField(max_length=256, verbose_name=_(u'name'))

    # a short description of the facility.
    # will be derived from description, if empty
    short_description = models.TextField(blank=True,
                                         verbose_name=_(u'short description'))

    # a description of the facility
    description = models.TextField(verbose_name=_(u'description'))

    # anything one needs to know on how to contact the facility
    contact_info = models.TextField(verbose_name=_(u'contact info'))

    # users associated with this facility
    # ie. members, admins, admins
    members = models.ManyToManyField(UserAccount,
                                     through='organizations.FacilityMembership')

    # the geographical location of the faciltiy
    place = models.ForeignKey("places.Place",
                              null=False,
                              related_name='facilities',
                              verbose_name=_('place'))

    # not all addresses need to have the western pattern of
    # street, postal code, city
    address = models.TextField(verbose_name=_('address'))

    # might be useful later, once we want to search by zip code
    zip_code = models.CharField(max_length=25,
                                blank=True,
                                verbose_name=_('postal code'))

    # coordinates for showing it on a map and a flag to switch it on
    show_on_map = models.BooleanField(default=True,
                                      verbose_name=_(
                                          'Show on map of all facilities'))
    latitude = models.CharField(max_length=30, blank=True,
                                verbose_name=_('latitude'))
    longitude = models.CharField(max_length=30, blank=True,
                                 verbose_name=_('longitude'))

    slug = models.SlugField(verbose_name=_(u'slug'))

    join_mode = models.PositiveSmallIntegerField(
        choices=Membership.JoinMode.CHOICES,
        default=Membership.JoinMode.INVITATION_ONLY,
        verbose_name=_(u'join mode'),
        help_text=_(u'Who can join this facility?'))

    class Meta:
        verbose_name = _(u'facility')
        verbose_name_plural = _(u'facilities')
        ordering = ('organization', 'place', 'name',)

    @property
    def address_line(self):
        return self.address.replace("\n", ", ").strip()

    # TODO: Could this be implemented in a more optimized way?
    @property
    def open_shifts(self):
        return Shift.open_shifts.filter(facility=self)

    def __unicode__(self):
        return _(u"{name}").format(name=self.name)


class OrganizationMembership(Membership):
    related_name = 'organizations'

    organization = models.ForeignKey(Organization,
                                     verbose_name=_(u'organization'),
                                     related_name='memberships',
                                     related_query_name='membership')

    class Meta:
        verbose_name = _(u'organization member')
        verbose_name_plural = _(u'organization members')
        ordering = ('organization', 'role', 'user_account')

    def __unicode__(self):
        return _(u"{username} at {organization_name} ({user_role})").format(
            username=self.user_account.user.username,
            organization_name=self.organization.name,
            user_role=self.role)


class FacilityMembership(Membership):
    related_name = 'facilities'
<commit_msg>Add get_absolute_url methods to Facility and Organization<commit_after># coding: utf-8
from django.core.urlresolvers import reverse

from django.db import models
from django.utils.translation import ugettext_lazy as _

from accounts.models import UserAccount
from scheduler.models import Shift


class Membership(models.Model):
    related_name = None

    class JoinMode:
        INVITATION_ONLY, APPROVAL_BY_ADMIN, ANYONE = 0, 1, 2
        CHOICES = (
            (INVITATION_ONLY, _(u'by invitation')),
            (APPROVAL_BY_ADMIN, _(u'anyone (approved by manager)')),
            (ANYONE, _(u'anyone')),
        )

    class Status:
        REJECTED, PENDING, APPROVED = 0, 1, 2
        CHOICES = (
            (REJECTED, _(u'rejected')),
            (PENDING, _(u'pending')),
            (APPROVED, _(u'approved')),
        )

    class Roles:
        ADMIN, MANAGER, MEMBER = 0, 1, 2
        CHOICES = (
            (ADMIN, _(u'admin')),
            (MANAGER, _(u'manager')),
            (MEMBER, _(u'member')),
        )

    role = models.PositiveSmallIntegerField(choices=Roles.CHOICES,
                                            default=Roles.MEMBER,
                                            verbose_name=_(u'role'))

    status = models.PositiveSmallIntegerField(choices=Status.CHOICES,
                                              default=Status.APPROVED,
                                              verbose_name=_(u'status'))

    user_account = models.ForeignKey(UserAccount,
                                     verbose_name=_(u'user account'),
                                     related_name=related_name)

    class Meta:
        abstract = True


class Organization(models.Model):
    # the name of the organization, ie. "<NAME>"
    name = models.CharField(max_length=256, verbose_name=_(u'name'))

    # a short description of the organization.
    # will be derived from description, if empty
    short_description = models.TextField(blank=True,
                                         verbose_name=_(u'short description'))

    # a description of the organization
    description = models.TextField(verbose_name=_(u'description'))

    # anything one needs to know on how to contact the facility
    contact_info = models.TextField(verbose_name=_(u'contact info'))

    # the orgs address
    address = models.TextField(verbose_name=_('address'))

    # users associated with this organization
    # ie. members, admins, admins
    members = models.ManyToManyField(
        UserAccount,
        through='organizations.OrganizationMembership'
    )

    slug = models.SlugField(verbose_name=_(u'slug'))

    join_mode = models.PositiveSmallIntegerField(
        choices=Membership.JoinMode.CHOICES,
        default=Membership.JoinMode.INVITATION_ONLY,
        verbose_name=_(u'join mode'),
        help_text=_(u'Who can join this organization?'))

    class Meta:
        verbose_name = _(u'organization')
        verbose_name_plural = _(u'organizations')
        ordering = ('name',)

    def __unicode__(self):
        return _(u"{name}").format(name=self.name)

    def get_absolute_url(self):
        return reverse('organization',
                       args=[self.slug])


class Facility(models.Model):
    # the organization running this facility
    organization = models.ForeignKey('organizations.Organization',
                                     verbose_name=_('organization'),
                                     related_name='facilities')

    # the name of the facility, ie. "Fehrbelliner Platz 4"
    name = models.CharField(max_length=256, verbose_name=_(u'name'))

    # a short description of the facility.
    # will be derived from description, if empty
    short_description = models.TextField(blank=True,
                                         verbose_name=_(u'short description'))

    # a description of the facility
    description = models.TextField(verbose_name=_(u'description'))

    # anything one needs to know on how to contact the facility
    contact_info = models.TextField(verbose_name=_(u'contact info'))

    # users associated with this facility
    # ie. members, admins, admins
    members = models.ManyToManyField(UserAccount,
                                     through='organizations.FacilityMembership')

    # the geographical location of the faciltiy
    place = models.ForeignKey("places.Place",
                              null=False,
                              related_name='facilities',
                              verbose_name=_('place'))

    # not all addresses need to have the western pattern of
    # street, postal code, city
    address = models.TextField(verbose_name=_('address'))

    # might be useful later, once we want to search by zip code
    zip_code = models.CharField(max_length=25,
                                blank=True,
                                verbose_name=_('postal code'))

    # coordinates for showing it on a map and a flag to switch it on
    show_on_map = models.BooleanField(default=True,
                                      verbose_name=_(
                                          'Show on map of all facilities'))
    latitude = models.CharField(max_length=30, blank=True,
                                verbose_name=_('latitude'))
    longitude = models.CharField(max_length=30, blank=True,
                                 verbose_name=_('longitude'))

    slug = models.SlugField(verbose_name=_(u'slug'))

    join_mode = models.PositiveSmallIntegerField(
        choices=Membership.JoinMode.CHOICES,
        default=Membership.JoinMode.INVITATION_ONLY,
        verbose_name=_(u'join mode'),
        help_text=_(u'Who can join this facility?'))

    class Meta:
        verbose_name = _(u'facility')
        verbose_name_plural = _(u'facilities')
        ordering = ('organization', 'place', 'name',)

    @property
    def address_line(self):
        return self.address.replace("\n", ", ").strip()

    # TODO: Could this be implemented in a more optimized way?
    @property
    def open_shifts(self):
        return Shift.open_shifts.filter(facility=self)

    def __unicode__(self):
        return _(u"{name}").format(name=self.name)

    def get_absolute_url(self):
        return reverse('facility',
                       args=[self.organization.slug, self.slug])


class OrganizationMembership(Membership):
    related_name = 'organizations'

    organization = models.ForeignKey(Organization,
                                     verbose_name=_(u'organization'),
                                     related_name='memberships',
                                     related_query_name='membership')

    class Meta:
        verbose_name = _(u'organization member')
        verbose_name_plural = _(u'organization members')
        ordering = ('organization', 'role', 'user_account')

    def __unicode__(self):
        return _(u"{username} at {organization_name} ({user_role})").format(
            username=self.user_account.user.username,
            organization_name=self.organization.name,
            user_role=self.role)


class FacilityMembership(Membership):
    related_name = 'facilities'

{'fraction_non_alphanumeric': 0.09648809098061654, 'fraction_numerical': 0.003290179529361276, 'mean_word_length': 2.1820664542558035, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6779353', 'n_tokens_mistral': 3847, 'n_tokens_neox': 3632, 'n_words': 849}