Esempio n. 1
0
class Party(ResourceModelMixin, RandomIDModel):
    """
    Party model.

    A single party: has a name, a type, a type-dependent set of
    attributes and relationships with other parties and spatial units
    (i.e. tenure relationships).

    """

    # Possible party types: TYPE_CHOICES is the well-known name used
    # by the JSONAttributesField field type to manage the range of
    # allowed attribute fields.
    INDIVIDUAL = 'IN'
    CORPORATION = 'CO'
    GROUP = 'GR'
    TYPE_CHOICES = ((INDIVIDUAL, _('Individual')),
                    (CORPORATION, _('Corporation')), (GROUP, _('Group')))

    # All parties are associated with a single project.
    project = models.ForeignKey(Project,
                                on_delete=models.CASCADE,
                                related_name='parties')

    # All parties have a name: for individuals, this is the full name,
    # while for groups and corporate entities, it's whatever name is
    # conventionally used to identify the organisation.
    name = models.CharField(max_length=200)

    # Party type: used to manage range of allowed attributes.
    type = models.CharField(max_length=2,
                            choices=TYPE_CHOICES,
                            default=INDIVIDUAL)

    contacts = JSONField(validators=[validate_contact], default={})

    # JSON attributes field with management of allowed members.
    attributes = JSONAttributeField(default={})

    # Party-party relationships: includes things like family
    # relationships and group memberships.
    relationships = models.ManyToManyField('self',
                                           through='PartyRelationship',
                                           through_fields=('party1', 'party2'),
                                           symmetrical=False,
                                           related_name='relationships_set')

    # Tenure relationships.
    tenure_relationships = models.ManyToManyField(
        SpatialUnit,
        through='TenureRelationship',
        related_name='tenure_relationships')

    history = HistoricalRecords()

    class Meta:
        ordering = ('name', )

    class TutelaryMeta:
        perm_type = 'party'
        path_fields = ('project', 'id')
        actions = (('party.list', {
            'description': _("List existing parties of a project"),
            'error_message': messages.PARTY_LIST,
            'permissions_object': 'project'
        }), ('party.create', {
            'description': _("Add a party to a project"),
            'error_message': messages.PARTY_CREATE,
            'permissions_object': 'project'
        }), ('party.view', {
            'description': _("View an existing party"),
            'error_message': messages.PARTY_VIEW
        }), ('party.update', {
            'description': _("Update an existing party"),
            'error_message': messages.PARTY_UPDATE
        }), ('party.delete', {
            'description': _("Delete an existing party"),
            'error_message': messages.PARTY_DELETE
        }), ('party.resources.add', {
            'description': _("Add resources to the party"),
            'error_message': messages.PARTY_RESOURCES_ADD
        }))

    def __str__(self):
        return "<Party: {}>".format(self.name)

    def __repr__(self):
        return str(self)

    @property
    def ui_class_name(self):
        return _("Party")

    @property
    def ui_detail_url(self):
        return reverse(
            'parties:detail',
            kwargs={
                'organization': self.project.organization.slug,
                'project': self.project.slug,
                'party': self.id,
            },
        )
Esempio n. 2
0
class MovimientoDetalle(models.Model):
    cantidad = models.DecimalField(
        max_digits=20, decimal_places=4, default=0.0)
    articulo = models.ForeignKey(Articulo)
    cabecera = models.ForeignKey(MovimientoCabecera)
    history = HistoricalRecords()
Esempio n. 3
0
class Tienda(models.Model):
    estilos = models.ForeignKey(Estilo,
                                on_delete=models.CASCADE,
                                blank=True,
                                null=True)
    # associations
    cliente = models.ForeignKey(Cliente,
                                related_name='client_store',
                                null=True,
                                blank=True)
    marca = models.ForeignKey(Marca,
                              related_name='brand_store',
                              default='Ciente',
                              null=True,
                              blank=True)
    categoria = models.ForeignKey(Categoria,
                                  related_name='category_store',
                                  null=True,
                                  blank=True)
    comuna = models.ForeignKey(Comuna,
                               null=True,
                               blank=True,
                               related_name='comuna_store')

    tipo_panorama = models.CharField(_('tipo de evento'),
                                     choices=TIPO_PANORAMA_CHOICES,
                                     blank=True,
                                     null=True,
                                     max_length=2)

    # metas
    autor = models.ForeignKey('auth.User', null=True, blank=True)
    fecha_creacion = models.DateTimeField(auto_created=True,
                                          editable=False,
                                          null=True,
                                          blank=True)
    fecha_modificacion = models.DateTimeField(auto_now_add=True,
                                              editable=False,
                                              null=True,
                                              blank=True)

    # self
    expiracion = models.DateField(null=True,
                                  blank=True,
                                  default=datetime.datetime.today())
    fecha_inicio = models.DateField(null=True,
                                    blank=True,
                                    default=datetime.datetime.today())
    activo = models.BooleanField(default=False)
    panorama_destacado = models.BooleanField('Panoramas', default=False)
    tipster_recomienda = models.BooleanField(default=False)

    # info
    nombre = models.CharField(max_length=64)
    panorama_para = models.CharField(
        'Recomendado para',
        max_length=64,
        null=True,
        blank=True,
        help_text='Aparecerá arriba de "abierto ahora"')
    logo = models.FileField(
        upload_to='logos',
        null=True,
        blank=True,
        help_text=
        'Será procesada como archivo, no se redimensionará ni recortará, solo se modificará su tamaño de ancho y largo'
    )
    frase = models.CharField('Slogan', max_length=64, null=True, blank=True)
    quienes_somos = models.TextField(null=True, blank=True)
    telefono = models.CharField(max_length=16, null=True, blank=True)
    email = models.EmailField(null=True, blank=True)
    sitio_web = models.URLField(null=True, blank=True)
    direccion = models.CharField(max_length=64, null=True, blank=True)
    precio = models.BigIntegerField('Precio desde', null=True, blank=True)

    # medias
    google_map = GeopositionField(default='-39.8173788,-73.24253329999999',
                                  blank=True)

    # others
    habilitacion_comentarios = models.BooleanField(default=False)
    slug = models.SlugField(unique=True)
    history = HistoricalRecords()
    objects = TiendaQuerySet.as_manager()

    # sociales:
    facebook_url = models.URLField(null=True, blank=True)
    twitter_url = models.URLField(null=True, blank=True)
    pinterest_url = models.URLField(null=True, blank=True)
    linkedin_url = models.URLField(null=True, blank=True)
    instagram_url = models.URLField(null=True, blank=True)
    vimeo_url = models.URLField(null=True, blank=True)
    youtube_url = models.URLField(null=True, blank=True)

    # horarios:
    horario_semana_inicio = models.TimeField(_('Apertura durante la semana'),
                                             null=True,
                                             blank=True)
    horario_semana_fin = models.TimeField(_('Cierre durante la semana'),
                                          null=True,
                                          blank=True)

    #horario_fin_semana_inicio = models.TimeField(_('Apertura durante fin de semana'), null=True, blank=True)
    #horario_fin_semana_fin = models.TimeField(_('Cierre durante fin de semana'), null=True, blank=True)

    # TODO: options to website (locations, colors, etc)
    def promedio_evaluacion(self):
        acumulador = 0
        contador = 0
        if self.tienda_comentario.select_related() > 2:
            for c in self.tienda_comentario.select_related():
                acumulador = acumulador + float(c.evaluacion)
                contador = contador + 1
                # print acumulador

        if contador == 0:
            acumulador = 4
            contador = 1

        promedio = acumulador / contador
        # print promedio
        return str(round(float(promedio), 1))

    def get_foto_cabecera(self):
        c = self.tienda_foto.filter(cabecera=True).last()
        return c

    def get_foto_tarjeta(self):
        c = self.tienda_foto.filter(tarjeta=True).last()
        return c

    def __unicode__(self):
        if self.nombre:
            return u'%s' % self.nombre
        elif self.marca:
            return u'%s' % self.marca.nombre

    # todo: def publish():
    class Meta:
        verbose_name = _('tienda')
        verbose_name_plural = _('tiendas')

    def ultimo_comentario(self):
        a = self.tienda_comentario.select_related().filter(visible=True).last()
        return a
class Initiative(Timestamped, Authored):
    type = models.CharField(_('Initiative type'),
                            max_length=2,
                            choices=InitiativeType.choices,
                            default=InitiativeType.BOTHERS_ME)
    reviewer = models.CharField(
        _('Reviewer role'),
        max_length=2,
        choices=Reviwers.choices,
        default=Reviwers.AREA_ADMIN,
    )
    reviewer_user = models.ForeignKey('initiatives.AllAdminUser',
                                      verbose_name=_('Reviewer'),
                                      related_name='reviewed',
                                      on_delete=models.SET_NULL,
                                      null=True,
                                      blank=True)
    reviewer_user_history = models.ManyToManyField(
        'initiatives.AllAdminUser',
        verbose_name=_('Reviewer history'),
        through='initiatives.ReviewerHistory',
        null=True,
        blank=True)
    title = models.CharField(_('Title'), max_length=50, null=True, blank=True)
    statuses = models.ManyToManyField('initiatives.Status',
                                      verbose_name=_('Status of initiative'),
                                      through='initiatives.StatusInitiative')
    area = models.ForeignKey('initiatives.Area',
                             verbose_name=_('Area'),
                             on_delete=models.CASCADE,
                             related_name='initiatives',
                             null=True,
                             blank=True)
    location = geo_models.PointField(null=True,
                                     verbose_name=_('Lokacija'),
                                     blank=True)
    address = models.CharField(_("Address of initiative"),
                               max_length=100,
                               null=True,
                               blank=True)
    zone = models.ForeignKey('initiatives.Zone',
                             verbose_name=_('GEO Zone of initiative'),
                             on_delete=models.SET_NULL,
                             related_name='initiatives',
                             null=True,
                             blank=True)
    publisher = models.ForeignKey(settings.AUTH_USER_MODEL,
                                  on_delete=models.CASCADE,
                                  verbose_name=_('publisher'),
                                  related_name='published_initiatives',
                                  null=True,
                                  blank=True)
    cover_image = models.ForeignKey('initiatives.Image',
                                    verbose_name=_('Cover image before'),
                                    on_delete=models.SET_NULL,
                                    related_name='initiative_before',
                                    null=True,
                                    blank=True)
    cover_image_after = models.ForeignKey('initiatives.Image',
                                          verbose_name=_('Cover image after'),
                                          on_delete=models.SET_NULL,
                                          related_name='initiative_after',
                                          null=True,
                                          blank=True)
    archived = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Arhivirano',
    )
    is_draft = models.BooleanField(_('In review'), default=False)
    is_social_inovative_idea = models.BooleanField(
        _('Is social inovative idea'), default=False)

    history = HistoricalRecords()

    class Meta:
        verbose_name = _("Pobuda")
        verbose_name_plural = _('Pobude')

    def __str__(self):
        return f'#{self.id} {self.title}' if self.title else f'#{self.id} unnamed'

    def comment_count(self):
        return self.initiative_comments.filter(
            status=CommentStatus.PUBLISHED).count()

    def tilte(self):
        return f'#{self.id} {self.title}' if self.title else f'#{self.id} unnamed'

    def status(self):
        try:
            return self.initiative_statuses.filter(
                publication_status=Published.PUBLISHED).latest(
                    'created').status.name
        except:
            return None

    def telephone(self):
        self.author.phone_number

    def email(self):
        self.author.email

    def status_history(self):
        statuses = self.initiative_statuses.all()
        if statuses:
            table_lines = "".join([
                status.to_table_row()
                for status in statuses.order_by('created')
            ])
        else:
            table_lines = f'''<tr>
                <td colspan="4">{_("Pobuda je brez statusa")}</td>
                </tr>'''

        return mark_safe(f'''<table>
            <tr>
                <th>{_("Status")}</th>
                <th>{_("Opis")}</th>
                <th>{_("Status objace")}</th>
                <th>{_("Status spremenjen dne")}</th>
                <th>{_("Avtor")}</th>
            </tr>
                {table_lines}
            </table>
            ''')

    def description(self):
        output = ''
        descriptions = self.descriptions.all()
        for description in descriptions:
            output += f'<h3>{description.title}</h3><br>{description.content}'

        return mark_safe(output)

    @property
    def description_property(self):
        self.description()

    def images_preview(self):
        images = ""
        if self.cover_image:
            images += f'''<img src="{self.cover_image}" style="width:50%;">'''
        if self.cover_image_after:
            images += f'''<img src="{self.cover_image_after}" style="width:50%;">'''
        return mark_safe(f'''
            <div style="width:100%;">
                {images}
            </div>
            ''')

    def _is_published(self):
        return bool(
            self.initiative_statuses.filter(
                publication_status=Published.PUBLISHED))

    def _needs_publish(self):
        return bool(
            self.initiative_statuses.filter(
                publication_status=Published.DRAFT))

    def vote_count(self):
        return self.votes.count()

    def is_archived(self):
        return self.archived is not None

    def archive(self, *args, **kwargs):
        if not self.pk:
            raise ObjectDoesNotExist(
                _('Object must be created before it can be archived'))
        self.archived = timezone.now()
        return super(StoreDeleted, self).save(*args, **kwargs)

    def get_admin_url(self, role):
        role_str = self.get_role_url_key(role)
        type_str = self.get_type_url_key(self.type)
        logger.debug(f'admin:{type_str}initiative{role_str}_change')
        return reverse(
            f'admin:initiatives_{type_str}initiative{role_str}_change',
            args=[self.id])

    @property
    def get_super_admin_url(self):
        return self.get_admin_url('SA')

    def get_role_url_key(self, key):
        return {
            'SA': 'super',
            'AA': 'area',
            'AP': 'appraiser',
            'CA': 'contractor'
        }[key]

    def get_type_url_key(self, key):
        return {
            InitiativeType.BOTHERS_ME: 'bothers',
            InitiativeType.HAVE_IDEA: 'idea',
            InitiativeType.INTERESTED_IN: 'interested'
        }[key]

    _needs_publish.boolean = True
    _is_published.boolean = True
    is_published = property(_is_published)
    needs_published = property(_needs_publish)

    _is_published.short_description = _("Objavljeno")
    _needs_publish.short_description = _("Potrebuje pregled")
    comment_count.short_description = _("Št. komentarjev")
    status_history.short_description = _("Zgodovina statusov")
    images_preview.short_description = _("Predogled slik")
    description.short_description = _("Opis")
Esempio n. 5
0
class CreditRequest(TimeStampedModel):
    """
    A request for credit from a particular credit provider.

    When a user initiates a request for credit, a CreditRequest record will be created.
    Each CreditRequest is assigned a unique identifier so we can find it when the request
    is approved by the provider.  The CreditRequest record stores the parameters to be sent
    at the time the request is made.  If the user re-issues the request
    (perhaps because the user did not finish filling in forms on the credit provider's site),
    the request record will be updated, but the UUID will remain the same.
    """

    uuid = models.CharField(max_length=32, unique=True, db_index=True)
    username = models.CharField(max_length=255, db_index=True)
    course = models.ForeignKey(CreditCourse, related_name="credit_requests")
    provider = models.ForeignKey(CreditProvider,
                                 related_name="credit_requests")
    parameters = JSONField()

    REQUEST_STATUS_PENDING = "pending"
    REQUEST_STATUS_APPROVED = "approved"
    REQUEST_STATUS_REJECTED = "rejected"

    REQUEST_STATUS_CHOICES = (
        (REQUEST_STATUS_PENDING, "Pending"),
        (REQUEST_STATUS_APPROVED, "Approved"),
        (REQUEST_STATUS_REJECTED, "Rejected"),
    )
    status = models.CharField(max_length=255,
                              choices=REQUEST_STATUS_CHOICES,
                              default=REQUEST_STATUS_PENDING)

    history = HistoricalRecords()

    class Meta(object):  # pylint: disable=missing-docstring
        # Enforce the constraint that each user can have exactly one outstanding
        # request to a given provider.  Multiple requests use the same UUID.
        unique_together = ('username', 'course', 'provider')
        get_latest_by = 'created'

    @classmethod
    def credit_requests_for_user(cls, username):
        """
        Retrieve all credit requests for a user.

        Arguments:
            username (unicode): The username of the user.

        Returns: list

        Example Usage:
        >>> CreditRequest.credit_requests_for_user("bob")
        [
            {
                "uuid": "557168d0f7664fe59097106c67c3f847",
                "timestamp": 1434631630,
                "course_key": "course-v1:HogwartsX+Potions101+1T2015",
                "provider": {
                    "id": "HogwartsX",
                    "display_name": "Hogwarts School of Witchcraft and Wizardry",
                },
                "status": "pending"  # or "approved" or "rejected"
            }
        ]

        """

        return [{
            "uuid": request.uuid,
            "timestamp": request.parameters.get("timestamp"),
            "course_key": request.course.course_key,
            "provider": {
                "id": request.provider.provider_id,
                "display_name": request.provider.display_name
            },
            "status": request.status
        }
                for request in cls.objects.select_related(
                    'course', 'provider').filter(username=username)]

    @classmethod
    def get_user_request_status(cls, username, course_key):
        """
        Returns the latest credit request of user against the given course.

        Args:
            username(str): The username of requesting user
            course_key(CourseKey): The course identifier

        Returns:
            CreditRequest if any otherwise None

        """
        try:
            return cls.objects.filter(
                username=username,
                course__course_key=course_key).select_related(
                    'course', 'provider').latest()
        except cls.DoesNotExist:
            return None

    def __unicode__(self):
        """Unicode representation of a credit request."""
        return u"{course}, {provider}, {status}".format(
            course=self.course.course_key,
            provider=self.provider.provider_id,  # pylint: disable=no-member
            status=self.status,
        )
Esempio n. 6
0
class UlcerRecord(models.Model):

    SITE_CHOICES = (('back_of_head', "Back of Head"), ('forehead', 'Forehead'),
                    ('right_shoulder', 'Right Shoulder'), ('left_shoulder',
                                                           'Left Shoulder'),
                    ('right_heel', 'Right Heel'), ('left_heel', "Left Heel"),
                    ('left_elbow', "Left Elbow"), ('right_elbow',
                                                   "Right Elbow"),
                    ('right_buttock', "Right Buttock"), ('left_buttock',
                                                         "Left Buttock"),
                    ('right_knee', 'Right Knee'), ("left_knee", "Left Knee"),
                    ('left_hip', "Left Hip"), ('right_hip', 'Right Hip'),
                    ('fingers', 'Fingers'), ('toes', 'Toes'), ('other',
                                                               'Other'))

    STAGE_CHOICES = (('I', "Stage I"), ("II", "Stage II"),
                     ("III", "Stage III"), ("IV", "Stage IV"),
                     ("DTI", "Deep Tissue Injury"), ("UN", "Unstaged"))

    MARGIN_CHOICES = (('reg', 'Regular'), ('irreg', 'Irregular'))

    EDGE_CHOICES = (('sloping', 'Sloping'), ('punched_out', "Punched out"),
                    ('rollout', "Rollout"), ('everted', "Everted"))

    FLOOR_CHOICES = (('healthy', 'Healthy'), ('granulation',
                                              'Granualation Tissue'),
                     ('slough', 'Slough'), ('necrotic', 'Necrotic'),
                     ('eschar', 'Eschar'), ('epithelial', 'Epithelial'))

    DISCHARGE_CHOICES = (('serous', 'Serous'), ('purulent', 'Purulent'),
                         ('serosanguineous', 'Serosanguineous'), ('other',
                                                                  'Other'))

    DISCHARGE_AMOUNT_CHOICES = (('s', "Small"), ('m', "Medium"), ('h',
                                                                  "Heavy"))

    SKIN_CHOICES = (('warm', "Warm"), ('thickend', "Thickend"),
                    ('hyperpigmented', "Hyperpigmented"), ('hypopignmented',
                                                           "Hypopignmented"),
                    ('gangrenous', "Gangreous"), ('itching', 'Itching'),
                    ('swelling', 'Swelling'))

    SENSATION_CHOICE = (('g', "Good"), ('b', "Impaired"))

    PROGRESS_CHOICES = (("improved", "Improved"), ("no_change", "No Change"),
                        ("stable", "Stable"), ("declined", "Declined"))

    patient = models.ForeignKey(User, on_delete=models.CASCADE)
    reported_by = models.ForeignKey(User,
                                    on_delete=models.SET_NULL,
                                    null=True,
                                    blank=True,
                                    related_name='reported_ulcers')
    last_update = models.DateTimeField(auto_now=True, auto_now_add=False)

    site = models.CharField(max_length=50, choices=SITE_CHOICES)

    stage = models.CharField(max_length=20, choices=STAGE_CHOICES)

    duration = models.DurationField(null=True, blank=True)

    length = models.FloatField()
    width = models.FloatField()
    depth = models.FloatField()

    margin = models.CharField(max_length=8, choices=MARGIN_CHOICES)

    edge = models.CharField(max_length=20, choices=EDGE_CHOICES)
    edge_color = models.CharField(max_length=50)
    underminings = models.BooleanField(default=False)
    sinus_tracts = models.BooleanField(default=False)

    floor = ChoiceArrayField(models.CharField(max_length=50,
                                              blank=True,
                                              choices=FLOOR_CHOICES),
                             size=6)

    discharge = models.CharField(max_length=50,
                                 choices=DISCHARGE_CHOICES,
                                 null=True,
                                 blank=True)
    discharge_amount = models.CharField(max_length=50,
                                        choices=DISCHARGE_AMOUNT_CHOICES,
                                        null=True,
                                        blank=True)

    surrounding_skin = ChoiceArrayField(models.CharField(max_length=50,
                                                         blank=True,
                                                         choices=SKIN_CHOICES),
                                        size=5)
    skin_sensation = models.CharField(max_length=50, choices=SENSATION_CHOICE)

    regional_lymph_nodes_enlarged = models.BooleanField(default=False)

    smell = models.BooleanField(default=False)

    pain = models.BooleanField(default=False)

    progress = models.CharField(max_length=50, choices=PROGRESS_CHOICES)

    image = models.ImageField(upload_to='images/ulcers/',
                              blank=True,
                              null=True)

    history = HistoricalRecords()
Esempio n. 7
0
class CertificateInvalidation(TimeStampedModel):
    """
    Model for storing Certificate Invalidation.

    .. no_pii:
    """
    generated_certificate = models.ForeignKey(GeneratedCertificate,
                                              on_delete=models.CASCADE)
    invalidated_by = models.ForeignKey(User, on_delete=models.CASCADE)
    notes = models.TextField(default=None, null=True)
    active = models.BooleanField(default=True)

    # This is necessary because CMS does not install the certificates app, but
    # this code is run when other models in this file are imported there (or in
    # common code). Simple History will attempt to connect to the installed
    # model in the certificates app, which will fail.
    if 'certificates' in apps.app_configs:
        history = HistoricalRecords()

    class Meta:
        app_label = "certificates"

    def __str__(self):
        return "Certificate %s, invalidated by %s on %s." % \
               (self.generated_certificate, self.invalidated_by, self.created)

    def deactivate(self):
        """
        Deactivate certificate invalidation by setting active to False.
        """
        self.active = False
        self.save()

    @classmethod
    def get_certificate_invalidations(cls, course_key, student=None):
        """
        Return certificate invalidations filtered based on the provided course and student (if provided),

        Returned value is JSON serializable list of dicts, dict element would have the following key-value pairs.
         1. id: certificate invalidation id (primary key)
         2. user: username of the student to whom certificate belongs
         3. invalidated_by: user id of the instructor/support user who invalidated the certificate
         4. created: string containing date of invalidation in the following format "December 29, 2015"
         5. notes: string containing notes regarding certificate invalidation.
        """
        certificate_invalidations = cls.objects.filter(
            generated_certificate__course_id=course_key,
            active=True,
        )
        if student:
            certificate_invalidations = certificate_invalidations.filter(
                generated_certificate__user=student)
        data = []
        for certificate_invalidation in certificate_invalidations:
            data.append({
                'id':
                certificate_invalidation.id,
                'user':
                certificate_invalidation.generated_certificate.user.username,
                'invalidated_by':
                certificate_invalidation.invalidated_by.username,
                'created':
                certificate_invalidation.created.strftime("%B %d, %Y"),
                'notes':
                certificate_invalidation.notes,
            })
        return data

    @classmethod
    def has_certificate_invalidation(cls, student, course_key):
        """Check that whether the student in the course has been invalidated
        for receiving certificates.

        Arguments:
            student (user): logged-in user
            course_key (CourseKey): The course associated with the certificate.

        Returns:
             Boolean denoting whether the student in the course is invalidated
             to receive certificates
        """
        return cls.objects.filter(
            generated_certificate__course_id=course_key,
            active=True,
            generated_certificate__user=student).exists()
Esempio n. 8
0
class File(Base):
    STATUS = (
        (u"سررسید گذشته", u"سر رسید گذشته"),
        (u"معوق", u"معوق"),
        (u"مشکوک الوصول", u"مشکوک الوصول")
    )

    TYPE = (
        (' جعاله', 'جعاله'),
        ('اعتباری خرید کالا', 'اعتباری خرید کالا'),
        ('خرید خودرو', 'خرید خودرو'),
    )

    ASSURANCE_TYPE = (
        ('خرد', 'خرد'),
        ('متوسط', 'متوسط'),
        ('کلان', 'کلان'),
    )

    STATE_TYPE = (
        ('در حال پیگیری', 'در حال پیگیری'),
        ('عودت', 'عودت'),
        ('تسویه حساب', 'تسویه حساب'),
    )
    FILE_CODE_ERROR_MESSAGE = {
        'unique': 'شماره پرونده وارد شده تکراری می باشد لطفا شماره دیگری وارد نمایید.',
        'duplicate': 'شماره پرونده وارد شده تکراری می باشد لطفا شماره دیگری وارد نمایید.'
    }
    file_code = models.CharField(_(u'کد پرونده'), max_length=200, unique=True, error_messages=FILE_CODE_ERROR_MESSAGE)
    contract_code = models.CharField(_(u'شماره قرارداد'), max_length=200, null=True)
    main_deposit = models.BigIntegerField(_(u'اصل مبلغ بدهی'), default=100)
    nc_deposit = models.BigIntegerField(_(u'وجه التزام'), default=100)
    so_deposit = models.BigIntegerField(_(u'سود'), default=100)
    cost_proceeding = models.BigIntegerField(_(u'هزینه دادرسی'), default=100)
    branch = models.ForeignKey(Branch, verbose_name=_(u'شعبه'), related_name='files')
    persian_date_refrence = models.CharField(_(u'تاریخ ارجاع'), max_length=10, default=None, blank=True, null=True)
    persian_normal_date_refrence = models.CharField(_(u'تاریخ ارجاع'), max_length=10, default=None, null=True)
    status = models.CharField(_(u'وضعیت'), max_length=20, choices=STATUS, default='مشکوک')
    # file_type = models.CharField(_('نوع قرارداد'), max_length=50, choices=TYPE, default='جعاله')
    file_type = models.ForeignKey(FileType, verbose_name=_('نوع پرونده'), null=True)
    states = models.CharField(_('وضعیت'), max_length=50, choices=STATE_TYPE, default='در حال پیگیری')

    objects = models.Manager()
    ordered = OrderManager()
    history = HistoricalRecords()

    class Meta:
        ordering = ['file_code']
        verbose_name = _('پرونده')
        verbose_name_plural = _('پرونده ها')
        db_table = 'files'

    def __unicode__(self):
        return "{}".format(self.file_code)

    @property
    def assurance(self):
        if self.main_deposit < 10000000:
            return 'خرد'

        if 10000000 < self.main_deposit < 1000000000:
            return 'متوسط'

        if self.main_deposit > 1000000000:
            return 'کلان'

    @property
    def person_list(self):
        person_str = ''
        for person in self.file_persons.filter(relation_type='مدیون'):
            person_str += '{}'.format(person.person.full_name)

        return person_str

    @property
    def offices(self):
        office_str = ''
        for office in self.related_office.filter(relation_type='مدیون'):
            office_str += '{}'.format(office.office.name)

        return office_str
Esempio n. 9
0
class ProgramEnrollment(TimeStampedModel):
    """
    This is a model for Program Enrollments from the registrar service

    .. pii: PII is found in the external key for a program enrollment
    .. pii_types: other
    .. pii_retirement: local_api
    """
    STATUS_CHOICES = ProgramEnrollmentStatuses.__MODEL_CHOICES__

    class Meta(object):
        app_label = "program_enrollments"

        # A student enrolled in a given (program, curriculum) should always
        # have a non-null ``user`` or ``external_user_key`` field (or both).
        unique_together = (
            ('user', 'program_uuid', 'curriculum_uuid'),
            ('external_user_key', 'program_uuid', 'curriculum_uuid'),
        )

    user = models.ForeignKey(
        User,
        null=True,
        blank=True, on_delete=models.CASCADE
    )
    external_user_key = models.CharField(
        db_index=True,
        max_length=255,
        null=True
    )
    program_uuid = models.UUIDField(db_index=True, null=False)
    curriculum_uuid = models.UUIDField(db_index=True, null=False)
    status = models.CharField(max_length=9, choices=STATUS_CHOICES)
    historical_records = HistoricalRecords()

    def clean(self):
        if not (self.user or self.external_user_key):
            raise ValidationError(_('One of user or external_user_key must not be null.'))

    @classmethod
    def retire_user(cls, user_id):
        """
        With the parameter user_id, retire the external_user_key field

        Return True if there is data that was retired
        Return False if there is no matching data
        """

        enrollments = cls.objects.filter(user=user_id)
        if not enrollments:
            return False

        for enrollment in enrollments:
            retired_external_key = user_util.get_retired_external_key(
                enrollment.external_user_key,
                settings.RETIRED_USER_SALTS,
            )
            enrollment.historical_records.update(external_user_key=retired_external_key)
            enrollment.external_user_key = retired_external_key
            enrollment.save()

        return True

    def __str__(self):
        return '[ProgramEnrollment id={}]'.format(self.id)

    def __repr__(self):
        return (
            "<ProgramEnrollment"    # pylint: disable=missing-format-attribute
            " id={self.id}"
            " user={self.user!r}"
            " external_user_key={self.external_user_key!r}"
            " program_uuid={self.program_uuid!r}"
            " curriculum_uuid={self.curriculum_uuid!r}"
            " status={self.status!r}"
            ">"
        ).format(self=self)
Esempio n. 10
0
class ApiAccessRequest(TimeStampedModel):
    """Model to track API access for a user."""

    PENDING = 'pending'
    DENIED = 'denied'
    APPROVED = 'approved'
    STATUS_CHOICES = (
        (PENDING, _('Pending')),
        (DENIED, _('Denied')),
        (APPROVED, _('Approved')),
    )
    user = models.OneToOneField(User)
    status = models.CharField(
        max_length=255,
        choices=STATUS_CHOICES,
        default=PENDING,
        db_index=True,
        help_text=_('Status of this API access request'),
    )
    website = models.URLField(
        help_text=_('The URL of the website associated with this API user.'))
    reason = models.TextField(
        help_text=_('The reason this user wants to access the API.'))
    company_name = models.CharField(max_length=255, default='')
    company_address = models.CharField(max_length=255, default='')
    site = models.ForeignKey(Site)
    contacted = models.BooleanField(default=False)

    history = HistoricalRecords()

    @classmethod
    def has_api_access(cls, user):
        """Returns whether or not this user has been granted API access.

        Arguments:
            user (User): The user to check access for.

        Returns:
            bool
        """
        return cls.api_access_status(user) == cls.APPROVED

    @classmethod
    def api_access_status(cls, user):
        """
        Returns the user's API access status, or None if they have not
        requested access.

        Arguments:
            user (User): The user to check access for.

        Returns:
            str or None
        """
        try:
            return cls.objects.get(user=user).status
        except cls.DoesNotExist:
            return None

    def approve(self):
        """Approve this request."""
        log.info('Approving API request from user [%s].', self.user.id)
        self.status = self.APPROVED
        self.save()

    def deny(self):
        """Deny this request."""
        log.info('Denying API request from user [%s].', self.user.id)
        self.status = self.DENIED
        self.save()

    def __unicode__(self):
        return u'ApiAccessRequest {website} [{status}]'.format(
            website=self.website, status=self.status)
Esempio n. 11
0
class Resource(RandomIDModel):
    name = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)
    file = S3FileField(upload_to='resources', accepted_types=ACCEPTED_TYPES)
    original_file = models.CharField(max_length=200)
    file_versions = JSONField(null=True, blank=True)
    mime_type = models.CharField(max_length=100,
                                 validators=[validate_file_type])
    archived = models.BooleanField(default=False)
    last_updated = models.DateTimeField(auto_now=True)
    contributor = models.ForeignKey('accounts.User')
    project = models.ForeignKey('organization.Project')

    objects = ResourceManager()

    # Audit history
    created_date = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)

    history = HistoricalRecords()

    class Meta:
        ordering = ('name', )

    class TutelaryMeta:
        perm_type = 'resource'
        path_fields = ('project', 'pk')
        actions = (
            ('resource.list', {
                'description': _("List resources"),
                'permissions_object': 'project',
                'error_message': messages.RESOURCE_LIST
            }),
            ('resource.add', {
                'description': _("Add resources"),
                'permissions_object': 'project',
                'error_message': messages.RESOURCE_ADD
            }),
            ('resource.view', {
                'description': _("View resource"),
                'error_message': messages.RESOURCE_VIEW
            }),
            ('resource.edit', {
                'description': _("Edit resource"),
                'error_message': messages.RESOURCE_EDIT
            }),
            ('resource.archive', {
                'description': _("Archive resource"),
                'error_message': messages.RESOURCE_ARCHIVE
            }),
            ('resource.unarchive', {
                'description': _("Unarchive resource"),
                'error_message': messages.RESOURCE_UNARCHIVE
            }),
        )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._original_url = self.file.url

    def __repr__(self):
        repr_string = ('<Resource id={obj.id} name={obj.name}'
                       ' file={obj.file.url} project={obj.project.slug}>')
        return repr_string.format(obj=self)

    @property
    def file_name(self):
        if not hasattr(self, '_file_name'):
            self._file_name = self.file.url.split('/')[-1]

        return self._file_name

    @property
    def file_type(self):
        return self.file_name.split('.')[-1]

    @property
    def thumbnail(self):
        if not hasattr(self, '_thumbnail'):
            icon = settings.ICON_LOOKUPS.get(self.mime_type, None)
            if ('image' in self.mime_type and all(img not in self.mime_type
                                                  for img in ['tif', 'svg'])):
                ext = self.file_name.split('.')[-1]
                base_url = self.file.url[:self.file.url.rfind('.')]
                self._thumbnail = base_url + '-128x128.' + ext
            elif icon:
                self._thumbnail = settings.ICON_URL.format(icon)
            else:
                self._thumbnail = ''

        return self._thumbnail

    @property
    def num_entities(self):
        if not hasattr(self, '_num_entities'):
            self._num_entities = ContentObject.objects.filter(
                resource=self).count()
        return self._num_entities

    def save(self, *args, **kwargs):
        create_thumbnails(self, (not self.id))
        super().save(*args, **kwargs)

    @property
    def ui_class_name(self):
        return _("Resource")

    def get_absolute_url(self):
        return iri_to_uri(
            reverse(
                'resources:project_detail',
                kwargs={
                    'organization': self.project.organization.slug,
                    'project': self.project.slug,
                    'resource': self.id,
                },
            ))
Esempio n. 12
0
class KeyValue(models.Model):
    hostid = models.ForeignKey(Host, db_index=True)
    keyid = models.ForeignKey(AllowedKey, db_index=True)
    value = models.CharField(max_length=200, blank=True)
    origin = models.CharField(max_length=200, blank=True)
    createdate = models.DateField(auto_now_add=True)
    modifieddate = models.DateField(auto_now=True)
    history = HistoricalRecords()

    ############################################################################
    def save(self, user=None, readonlychange=False, **kwargs):
        if not user:
            user = getUser()
        self.value = self.value.lower().strip()
        # Check to see if we are restricted
        if self.keyid.restrictedFlag:
            rk = RestrictedValue.objects.filter(keyid=self.keyid, value=self.value)
            if not rk:
                raise RestrictedValueException(key=self.keyid, msg="%s is a restricted key" % self.keyid)

        if self.keyid.readonlyFlag and not readonlychange:
            raise ReadonlyValueException(key=self.keyid, msg="%s is a readonly key" % self.keyid)
        if self.keyid.get_validtype_display() == 'date':
            self.value = validateDate(self.value)
        if self.id:                        # Check for update
            oldobj = KeyValue.objects.get(id=self.id)
            undo = UndoLog(user=user, action='hostinfo_replacevalue %s=%s %s %s' % (self.keyid, self.value, oldobj.value, self.hostid))
            undo.save()
        else:                                # New object
            undo = UndoLog(user=user, action='hostinfo_deletevalue %s=%s %s' % (self.keyid, self.value, self.hostid))
            undo.save()

        # Actually do the saves
        if not self.keyid.auditFlag:
            self.skip_history_when_saving = True
        super(KeyValue, self).save(**kwargs)

    ############################################################################
    def delete(self, user=None, readonlychange=False):
        if not user:
            user = getUser()
        if self.keyid.readonlyFlag and not readonlychange:
            raise ReadonlyValueException(key=self.keyid, msg="%s is a read only key" % self.keyid)
        if self.keyid.get_validtype_display() == 'list':
            undoflag = '--append'
        else:
            undoflag = ''
        undo = UndoLog(
            user=user,
            action='hostinfo_addvalue %s %s=%s %s' % (undoflag, self.keyid, self.value, self.hostid)
            )
        undo.save()
        super(KeyValue, self).delete()

    ############################################################################
    def __str__(self):      # pragma: no cover
        return "%s=%s" % (self.keyid.key, self.value)

    ############################################################################
    class Meta:
        unique_together = (('hostid', 'keyid', 'value'), )
Esempio n. 13
0
class Refund(StatusMixin, TimeStampedModel):
    """Main refund model, used to represent the state of a refund."""
    order = models.ForeignKey('order.Order', related_name='refunds', verbose_name=_('Order'))
    user = models.ForeignKey('core.User', related_name='refunds', verbose_name=_('User'))
    total_credit_excl_tax = models.DecimalField(_('Total Credit (excl. tax)'), decimal_places=2, max_digits=12)
    currency = models.CharField(_("Currency"), max_length=12, default=get_default_currency)
    status = models.CharField(
        _('Status'),
        max_length=255,
        choices=[
            (REFUND.OPEN, REFUND.OPEN),
            (REFUND.DENIED, REFUND.DENIED),
            (REFUND.PAYMENT_REFUND_ERROR, REFUND.PAYMENT_REFUND_ERROR),
            (REFUND.PAYMENT_REFUNDED, REFUND.PAYMENT_REFUNDED),
            (REFUND.REVOCATION_ERROR, REFUND.REVOCATION_ERROR),
            (REFUND.COMPLETE, REFUND.COMPLETE),
        ]
    )

    history = HistoricalRecords()
    pipeline_setting = 'OSCAR_REFUND_STATUS_PIPELINE'

    @classmethod
    def all_statuses(cls):
        """Returns all possible statuses for a refund."""
        return list(getattr(settings, cls.pipeline_setting).keys())

    @classmethod
    def create_with_lines(cls, order, lines):
        """Given an order and order lines, creates a Refund with corresponding RefundLines.

        Only creates RefundLines for unrefunded order lines. Refunds corresponding to a total
        credit of $0 are approved upon creation.

        Arguments:
            order (order.Order): The order to which the newly-created refund corresponds.
            lines (list of order.Line): Order lines to be refunded.

        Returns:
            None: If no unrefunded order lines have been provided.
            Refund: With RefundLines corresponding to each given unrefunded order line.
        """
        unrefunded_lines = [line for line in lines if not line.refund_lines.exclude(status=REFUND_LINE.DENIED).exists()]

        if unrefunded_lines:
            status = getattr(settings, 'OSCAR_INITIAL_REFUND_STATUS', REFUND.OPEN)
            total_credit_excl_tax = sum([line.line_price_excl_tax for line in unrefunded_lines])
            refund = cls.objects.create(
                order=order,
                user=order.user,
                status=status,
                total_credit_excl_tax=total_credit_excl_tax
            )

            audit_log(
                'refund_created',
                amount=total_credit_excl_tax,
                currency=refund.currency,
                order_number=order.number,
                refund_id=refund.id,
                user_id=refund.user.id
            )

            status = getattr(settings, 'OSCAR_INITIAL_REFUND_LINE_STATUS', REFUND_LINE.OPEN)
            for line in unrefunded_lines:
                RefundLine.objects.create(
                    refund=refund,
                    order_line=line,
                    line_credit_excl_tax=line.line_price_excl_tax,
                    quantity=line.quantity,
                    status=status
                )

            if total_credit_excl_tax == 0:
                refund.approve(notify_purchaser=False)

            return refund

    @property
    def num_items(self):
        """Returns the number of items in this refund."""
        num_items = 0
        for line in self.lines.all():
            num_items += line.quantity
        return num_items

    @property
    def can_approve(self):
        """Returns a boolean indicating if this Refund can be approved."""
        return self.status not in (REFUND.COMPLETE, REFUND.DENIED)

    @property
    def can_deny(self):
        """Returns a boolean indicating if this Refund can be denied."""
        return self.status == settings.OSCAR_INITIAL_REFUND_STATUS

    def _issue_credit(self):
        """Issue a credit to the purchaser via the payment processor used for the original order."""
        try:
            # NOTE: Update this if we ever support multiple payment sources for a single order.
            source = self.order.sources.first()
            processor = get_processor_class_by_name(source.source_type.name)(self.order.site)
            amount = self.total_credit_excl_tax

            refund_reference_number = processor.issue_credit(self.order, source.reference, amount, self.currency)
            source.refund(amount, reference=refund_reference_number)
            event_type, __ = PaymentEventType.objects.get_or_create(name=PaymentEventTypeName.REFUNDED)
            PaymentEvent.objects.create(
                event_type=event_type,
                order=self.order,
                amount=amount,
                reference=refund_reference_number,
                processor_name=processor.NAME
            )

            audit_log(
                'credit_issued',
                amount=amount,
                currency=self.currency,
                processor_name=processor.NAME,
                refund_id=self.id,
                user_id=self.user.id
            )
        except AttributeError:
            # Order has no sources, resulting in an exception when trying to access `source_type`.
            # This occurs when attempting to refund free orders.
            logger.info("No payments to credit for Refund [%d]", self.id)

    def _notify_purchaser(self):
        """ Notify the purchaser that the refund has been processed. """
        site_configuration = self.order.site.siteconfiguration
        site_code = site_configuration.partner.short_code

        if not site_configuration.send_refund_notifications:
            logger.info(
                'Refund notifications are disabled for Partner [%s]. No notification will be sent for Refund [%d]',
                site_code, self.id
            )
            return

        # NOTE (CCB): The initial version of the refund email only supports refunding a single course.
        product = self.lines.first().order_line.product
        product_class = product.get_product_class().name

        if product_class != SEAT_PRODUCT_CLASS_NAME:
            logger.warning(
                ('No refund notification will be sent for Refund [%d]. The notification supports product lines '
                 'of type Course, not [%s].'),
                self.id, product_class
            )
            return

        course_name = self.lines.first().order_line.product.course.name
        order_number = self.order.number
        order_url = get_receipt_page_url(site_configuration, order_number)
        amount = format_currency(self.currency, self.total_credit_excl_tax)

        send_course_refund_email.delay(self.user.email, self.id, amount, course_name, order_number,
                                       order_url, site_code=site_code)
        logger.info('Course refund notification scheduled for Refund [%d].', self.id)

    def _revoke_lines(self):
        """Revoke fulfillment for the lines in this Refund."""
        if revoke_fulfillment_for_refund(self):
            self.set_status(REFUND.COMPLETE)
        else:
            logger.error('Unable to revoke fulfillment of all lines of Refund [%d].', self.id)
            self.set_status(REFUND.REVOCATION_ERROR)

    def approve(self, revoke_fulfillment=True, notify_purchaser=True):
        if self.status == REFUND.COMPLETE:
            logger.info('Refund [%d] has already been completed. No additional action is required to approve.', self.id)
            return True
        elif not self.can_approve:
            logger.warning('Refund [%d] has status set to [%s] and cannot be approved.', self.id, self.status)
            return False
        elif self.status in (REFUND.OPEN, REFUND.PAYMENT_REFUND_ERROR):
            try:
                self._issue_credit()
                self.set_status(REFUND.PAYMENT_REFUNDED)
                if notify_purchaser:
                    self._notify_purchaser()
            except PaymentError:
                logger.exception('Failed to issue credit for refund [%d].', self.id)
                self.set_status(REFUND.PAYMENT_REFUND_ERROR)
                return False

        if revoke_fulfillment and self.status in (REFUND.PAYMENT_REFUNDED, REFUND.REVOCATION_ERROR):
            self._revoke_lines()

        if not revoke_fulfillment and self.status == REFUND.PAYMENT_REFUNDED:
            logger.info('Skipping the revocation step for refund [%d].', self.id)
            # Mark the status complete as it does not involve the revocation.
            self.set_status(REFUND.COMPLETE)
            for refund_line in self.lines.all():
                refund_line.set_status(REFUND_LINE.COMPLETE)

        if self.status == REFUND.COMPLETE:
            post_refund.send_robust(sender=self.__class__, refund=self)
            return True

        return False

    def deny(self):
        if self.status == REFUND.DENIED:
            logger.info('Refund [%d] has already been denied. No additional action is required to deny.', self.id)
            return True

        if not self.can_deny:
            logger.warning('Refund [%d] cannot be denied. Its status is [%s].', self.id, self.status)
            return False

        self.set_status(REFUND.DENIED)

        result = True
        for line in self.lines.all():
            try:
                line.deny()
            except Exception:  # pylint: disable=broad-except
                logger.exception('Failed to deny RefundLine [%d].', line.id)
                result = False

        return result
Esempio n. 14
0
class Company(DataOceanModel):  # constraint for not null in both name & short_name fields
    UKRAINE_REGISTER = 'ukr'
    GREAT_BRITAIN_REGISTER = 'gb'
    ANTAC = 'antac'
    SOURCES = (
        (UKRAINE_REGISTER,
         _(
             'The United State Register of Legal Entities, Individual Entrepreneurs and Public Organizations of Ukraine')),
        (GREAT_BRITAIN_REGISTER, _('Company House (UK companies` register)')),
        (ANTAC, _('ANTAC')),
    )

    INVALID = 'invalid'  # constant for empty edrpou fild etc.
    name = models.CharField(_('name'), max_length=500, null=True, help_text='Company name in Ukrainian')
    short_name = models.CharField(_('short name'), max_length=500, null=True,
                                  help_text='Short name of the company in Ukrainian')
    company_type = models.ForeignKey(CompanyType, on_delete=models.CASCADE, null=True,
                                     verbose_name=_('company type'), help_text='Type of the company')
    edrpou = models.CharField(_('number'), max_length=260, null=True, db_index=True,
                              help_text='EDRPOU number as string')
    boss = models.CharField(_('CEO'), max_length=100, null=True, blank=True, default='',
                            help_text='CEO of the company')
    authorized_capital = models.FloatField(_('share capital'), null=True, help_text='Authorized capital as number')
    country = models.ForeignKey(Country, max_length=60, on_delete=models.CASCADE, null=True,
                                verbose_name=_('country'), help_text='Country of origin')
    address = models.CharField(_('address'), max_length=1000, null=True,
                               help_text='Registration address in Ukrainian')
    status = models.ForeignKey(
        Status,
        on_delete=models.CASCADE,
        null=True,
        verbose_name=_('status'),
        help_text='Company legal status. Can be: "зареєстровано", "в стані припинення", "припинено", "EMP", "порушено '
                  'справу про банкрутство", "порушено справу про банкрутство (санація)", "зареєстровано, свідоцтво про '
                  'державну реєстрацію недійсне", "скасовано", "active", "active - proposal to strike off", "liquidation",'
                  ' "administration order", "voluntary arrangement", "in administration/administrative receiver", '
                  '"in administration", "live but receiver manager on at least one charge", "in administration/receiver '
                  'manager", "receivership", "receiver manager / administrative receiver", "administrative receiver", '
                  'voluntary arrangement / administrative receiver", "voluntary arrangement / receiver manager".'
    )
    bylaw = models.ForeignKey(Bylaw, on_delete=models.CASCADE, null=True,
                              verbose_name=_('charter'), help_text='By law')
    registration_date = models.DateField(_('registration date'), null=True,
                                         help_text='Registration date as string in YYYY-MM-DD format')
    registration_info = models.CharField(_('registration info'), max_length=450, null=True,
                                         help_text='Registration info of the company')
    contact_info = models.CharField(_('contacts'), max_length=310, null=True, help_text='Info about contacts')
    authority = models.ForeignKey(Authority, on_delete=models.CASCADE, null=True,
                                  verbose_name=_('registration authority'),
                                  help_text='Authorized state agency which register the company')
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True,
                               verbose_name=_('parent company'),
                               help_text='Company that has a controlling interest in the company')
    antac_id = models.PositiveIntegerField(_("id from ANTACs DB"), unique=True,
                                           db_index=True, null=True, default=None, blank=True,
                                           help_text='ID from ANTACs DB')
    from_antac_only = models.BooleanField(null=True, help_text='If this field has "true" - '
                                                               'Data provided by the Anti-Corruption Action Center.')
    source = models.CharField(_('source'), max_length=5, choices=SOURCES, null=True,
                              blank=True, default=None, db_index=True, help_text='Source')
    code = models.CharField(_('our code'), max_length=510, db_index=True, help_text='Our code')
    history = HistoricalRecords()

    @property
    def founder_of(self):
        if not self.edrpou:
            return []
        founder_of = Founder.objects.filter(edrpou=self.edrpou)
        founded_companies = []
        for founder in founder_of:
            founded_companies.append(founder.company)
        return founded_companies

    @property
    def founder_of_count(self):
        if not self.edrpou:
            return 0
        return Founder.objects.filter(edrpou=self.edrpou).count()

    @property
    def is_closed(self):
        if not self.status:
            return None
        return self.status.name == 'припинено'

    @property
    def is_foreign(self):
        if not self.country:
            return None
        return self.country.name != 'ukraine'

    class Meta:
        verbose_name = _('company')
        verbose_name_plural = _('companies')
        index_together = [
            ('edrpou', 'source')
        ]
Esempio n. 15
0
class CityCouncilExpense(DatasetMixin):
    PHASE = (
        ("empenho", "Empenho"),
        ("liquidacao", "Liquidação"),
        ("pagamento", "Pagamento"),
    )
    published_at = models.DateField("Publicado em",
                                    null=True,
                                    blank=True,
                                    db_index=True)
    phase = models.CharField("Fase",
                             max_length=20,
                             choices=PHASE,
                             db_index=True)
    phase_code = models.CharField("Código da fase",
                                  max_length=20,
                                  null=True,
                                  blank=True,
                                  db_index=True)
    company_or_person = models.TextField("Empresa ou pessoa",
                                         null=True,
                                         blank=True,
                                         db_index=True)
    value = models.DecimalField("Valor", max_digits=10, decimal_places=2)
    number = models.CharField("Número",
                              max_length=50,
                              null=True,
                              blank=True,
                              db_index=True)
    document = models.CharField("CNPJ ou CPF",
                                max_length=50,
                                null=True,
                                blank=True,
                                db_index=True)
    date = models.DateField("Data", db_index=True)
    process_number = models.CharField("Número do processo",
                                      max_length=50,
                                      null=True,
                                      blank=True,
                                      db_index=True)
    summary = models.TextField("Descrição",
                               null=True,
                               blank=True,
                               db_index=True)
    legal_status = models.CharField("Natureza",
                                    max_length=200,
                                    null=True,
                                    blank=True,
                                    db_index=True)
    function = models.CharField("Função",
                                max_length=50,
                                null=True,
                                blank=True,
                                db_index=True)
    subfunction = models.CharField("Subfunção",
                                   max_length=50,
                                   null=True,
                                   blank=True,
                                   db_index=True)
    resource = models.CharField("Fonte",
                                max_length=200,
                                null=True,
                                blank=True,
                                db_index=True)
    subgroup = models.CharField("Subgrupos",
                                max_length=100,
                                null=True,
                                blank=True,
                                db_index=True)
    group = models.CharField("Grupo",
                             max_length=100,
                             null=True,
                             blank=True,
                             db_index=True)
    budget_unit = models.PositiveIntegerField("Unidade orçamentária",
                                              default=101)
    modality = models.CharField(
        "Modalidade",
        max_length=50,
        null=True,
        blank=True,
        choices=EXPENSE_MODALITIES,
        db_index=True,
    )
    excluded = models.BooleanField("Excluído?", default=False)
    external_file_code = models.CharField(
        "Código do arquivo (externo)",
        max_length=50,
        null=True,
        blank=True,
        db_index=True,
    )
    external_file_line = models.CharField(
        "Linha do arquivo (externo)",
        max_length=50,
        null=True,
        blank=True,
        db_index=True,
    )
    history = HistoricalRecords()

    class Meta:
        verbose_name = "Câmara de Vereadores - Despesa"
        verbose_name_plural = "Câmara de Vereadores - Despesas"
        get_latest_by = "date"
        ordering = ["-date"]

    def __repr__(self):
        return f"{self.date} {self.phase} {self.company_or_person} {self.value}"

    def __str__(self):
        return f"{self.date} {self.phase} {self.company_or_person} {self.value}"
Esempio n. 16
0
class Pep(DataOceanModel):
    DIED = 'died'
    RESIGNED = 'resigned'
    LINKED_PEP_DIED = 'linked pep died'
    LINKED_PEP_RESIGNED = 'linked pep resigned'
    LEGISLATION_CHANGED = 'legislation changed'
    COMPANY_STATUS_CHANGED = 'company status changed'
    REASONS = (
        (DIED, _('Is dead')),
        (RESIGNED, _('Resigned or term ended')),
        (LINKED_PEP_DIED, _("Associated PEP is dead")),
        (LINKED_PEP_RESIGNED, _("Associated person is no more PEP")),
        (LEGISLATION_CHANGED, _('Legislation was changed')),
        (COMPANY_STATUS_CHANGED, _('Company is no more state')),
    )
    NATIONAL_PEP = 'national PEP'
    FOREIGN_PEP = 'foreign PEP'
    PEP_FROM_INTERNATIONAL_ORGANISATION = 'PEP with political functions in international organization'
    PEP_ASSOCIATED_PERSON = 'associated person with PEP'
    PEP_FAMILY_MEMBER = "member of PEP`s family"
    TYPES = (
        (NATIONAL_PEP, _('National politically exposed person')),
        (FOREIGN_PEP, _('Foreign politically exposed person')),
        (PEP_FROM_INTERNATIONAL_ORGANISATION,
         _('Politically exposed person, having political functions in international organization'
           )),
        (PEP_ASSOCIATED_PERSON, _("Associated person")),
        (PEP_FAMILY_MEMBER, _("Family member")),
    )

    code = models.CharField(max_length=15, unique=True, db_index=True)
    first_name = models.CharField(_('first name'),
                                  max_length=20,
                                  db_index=True,
                                  help_text='First name of PEP in Ukrainian')
    middle_name = models.CharField(_('middle name'),
                                   max_length=25,
                                   db_index=True,
                                   help_text='Middle name of PEP in Ukrainian')
    last_name = models.CharField(_('surname'),
                                 max_length=30,
                                 db_index=True,
                                 help_text='Last name of PEP in Ukrainian')
    fullname = models.CharField(
        _("full name"),
        max_length=75,
        db_index=True,
        help_text='Full name "last name first name middle name" in Ukrainian.')
    fullname_transcriptions_eng = models.TextField(
        _('options for writing the full name'),
        db_index=True,
        help_text='Full name in English transcription.')
    last_job_title = models.CharField(
        _('last position'),
        max_length=340,
        null=True,
        db_index=True,
        help_text='Title of the last job in Ukrainian.')
    last_employer = models.CharField(_('last office'),
                                     max_length=512,
                                     null=True,
                                     db_index=True,
                                     help_text='Last employer in Ukrainian.')
    is_pep = models.BooleanField(
        _('is pep'),
        default=True,
        help_text=
        'Boolean type. Can be true or false. True - person is politically exposed '
        'person, false - person is not politically exposed person.')
    related_persons = models.ManyToManyField(
        'self',
        verbose_name=_("associated persons"),
        through='RelatedPersonsLink')
    pep_type = models.CharField(
        _('type'),
        choices=TYPES,
        max_length=60,
        null=True,
        blank=True,
        db_index=True,
        help_text=
        'Type of politically exposed person. Can be national politically exposed '
        'person, foreign politically exposed person,  politically exposed person,'
        ' having political functions in international organization, associated '
        'person or family member.')
    info = models.TextField(_('additional info'),
                            null=True,
                            help_text='Additional info about pep.')
    sanctions = models.TextField(
        _('known sanctions against the person'),
        null=True,
        help_text=
        'Known sanctions against the person. If its is null, the person has no sanctions against him.'
    )
    criminal_record = models.TextField(
        _('known sentences against the person'),
        null=True,
        help_text=
        'Existing criminal proceeding. If its is null, the person has no sentences against him.'
    )
    assets_info = models.TextField(_('assets info'),
                                   null=True,
                                   help_text='Info about person`s assets.')
    criminal_proceedings = models.TextField(
        _('known criminal proceedings against the person'),
        null=True,
        help_text=
        'Known criminal proceedings against the person. If its is null, the person has no criminal '
        'proceedings against him.')
    wanted = models.TextField(
        _('wanted'),
        null=True,
        help_text=
        'Information on being wanted. If its null, the person is not on the wanted list.'
    )
    date_of_birth = models.CharField(
        _('date of birth'),
        max_length=10,
        null=True,
        db_index=True,
        help_text='Person`s date of birth in YYYY-MM-DD format.')
    place_of_birth = models.CharField(
        _('place of birth'),
        max_length=100,
        null=True,
        help_text='The name of the settlement where the person was born.')
    is_dead = models.BooleanField(
        _('is_dead'),
        default=False,
        help_text=
        'Boolean type. Can be true or false. True - person is dead, false - person is alive.'
    )
    termination_date = models.DateField(
        _('PEP status termination date '),
        null=True,
        help_text='PEP status termination date in YYYY-MM-DD format.')
    reason_of_termination = models.CharField(
        _('reason of termination'),
        choices=REASONS,
        max_length=125,
        null=True,
        blank=True,
        help_text=
        'PEP status reason of termination. Can be "Is dead", "Resigned or term ended", "Associated PEP is'
        ' dead", "Legislation was changed", "Company is no more state" or null.'
    )
    source_id = models.PositiveIntegerField(_("id from ANTACs DB"),
                                            unique=True,
                                            null=True,
                                            blank=True)
    history = HistoricalRecords(excluded_fields=['url', 'code'])

    @property
    def check_companies(self):
        pep_name = ' '.join([
            x for x in [self.last_name, self.first_name, self.middle_name] if x
        ])
        founders_with_pep_name = Founder.objects.filter(
            name__contains=pep_name).select_related('company').distinct(
                'company__edrpou')
        if not len(founders_with_pep_name):
            return []
        possibly_founded_companies = []
        related_companies_id = self.related_companies.values_list('company_id',
                                                                  flat=True)
        for founder in founders_with_pep_name:
            if founder.company_id not in related_companies_id:
                possibly_founded_companies.append(founder.company)
        return possibly_founded_companies

    class Meta:
        indexes = [
            models.Index(fields=['updated_at']),
        ]
        verbose_name = _('politically exposed person')
        verbose_name_plural = _('politically exposed persons')
        ordering = ['id']

    def __str__(self):
        return self.fullname
Esempio n. 17
0
class Setting(SingletonModel):
    initial_data_runned = models.BooleanField(default=False, blank=True)
    history = HistoricalRecords()
Esempio n. 18
0
class SurgeComparison(TimeSeriesComparison, AbstractSurge):
    history = HistoricalRecords(inherit=True)
Esempio n. 19
0
class GeneratedCertificate(models.Model):
    """
    Base model for generated certificates

    .. pii: PII can exist in the generated certificate linked to in this model. Certificate data is currently retained.
    .. pii_types: name, username
    .. pii_retirement: retained
    """
    # Import here instead of top of file since this module gets imported before
    # the course_modes app is loaded, resulting in a Django deprecation warning.
    from common.djangoapps.course_modes.models import CourseMode  # pylint: disable=reimported

    # Only returns eligible certificates. This should be used in
    # preference to the default `objects` manager in most cases.
    eligible_certificates = EligibleCertificateManager()

    # Only returns eligible certificates for courses that have an
    # associated CourseOverview
    eligible_available_certificates = EligibleAvailableCertificateManager()

    # Normal object manager, which should only be used when ineligible
    # certificates (i.e. new audit certs) should be included in the
    # results. Django requires us to explicitly declare this.
    objects = models.Manager()

    MODES = Choices('verified', 'honor', 'audit', 'professional',
                    'no-id-professional', 'masters', 'executive-education')

    VERIFIED_CERTS_MODES = [CourseMode.VERIFIED, CourseMode.CREDIT_MODE, CourseMode.MASTERS, CourseMode.EXECUTIVE_EDUCATION]  # pylint: disable=line-too-long

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    course_id = CourseKeyField(max_length=255, blank=True, default=None)
    verify_uuid = models.CharField(max_length=32,
                                   blank=True,
                                   default='',
                                   db_index=True)
    download_uuid = models.CharField(max_length=32, blank=True, default='')
    download_url = models.CharField(max_length=128, blank=True, default='')
    grade = models.CharField(max_length=5, blank=True, default='')
    key = models.CharField(max_length=32, blank=True, default='')
    distinction = models.BooleanField(default=False)
    status = models.CharField(max_length=32, default='unavailable')
    mode = models.CharField(max_length=32, choices=MODES, default=MODES.honor)
    name = models.CharField(blank=True, max_length=255)
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)
    error_reason = models.CharField(max_length=512, blank=True, default='')

    # This is necessary because CMS does not install the certificates app, but it
    # imports this model's code. Simple History will attempt to connect to the installed
    # model in the certificates app, which will fail.
    if 'certificates' in apps.app_configs:
        history = HistoricalRecords()

    class Meta:
        unique_together = (('user', 'course_id'), )
        app_label = "certificates"

    @classmethod
    def certificate_for_student(cls, student, course_id):
        """
        This returns the certificate for a student for a particular course
        or None if no such certificate exits.
        """
        try:
            return cls.objects.get(user=student, course_id=course_id)
        except cls.DoesNotExist:
            pass

        return None

    @classmethod
    def course_ids_with_certs_for_user(cls, user):
        """
        Return a set of CourseKeys for which the user has certificates.

        Sometimes we just want to check if a user has already been issued a
        certificate for a given course (e.g. to test refund eligibility).
        Instead of checking if `certificate_for_student` returns `None` on each
        course_id individually, we instead just return a set of all CourseKeys
        for which this student has certificates all at once.
        """
        return {
            cert.course_id
            for cert in cls.objects.filter(user=user).only('course_id')
        }

    @classmethod
    def get_unique_statuses(cls, course_key=None, flat=False):
        """
        1 - Return unique statuses as a list of dictionaries containing the following key value pairs
            [
            {'status': 'status value from db', 'count': 'occurrence count of the status'},
            {...},
            ..., ]

        2 - if flat is 'True' then return unique statuses as a list
        3 - if course_key is given then return unique statuses associated with the given course

        :param course_key: Course Key identifier
        :param flat: boolean showing whether to return statuses as a list of values or a list of dictionaries.
        """
        query = cls.objects

        if course_key:
            query = query.filter(course_id=course_key)

        if flat:
            return query.values_list('status', flat=True).distinct()
        else:
            return query.values('status').annotate(count=Count('status'))

    def __repr__(self):
        return "<GeneratedCertificate: {course_id}, user={user}>".format(
            course_id=self.course_id, user=self.user)

    def invalidate(self):
        """
        Invalidate Generated Certificate by  marking it 'unavailable'.

        Following is the list of fields with their defaults
            1 - verify_uuid = '',
            2 - download_uuid = '',
            3 - download_url = '',
            4 - grade = ''
            5 - status = 'unavailable'
        """
        log.info(
            'Marking certificate as unavailable for {user} : {course}'.format(
                user=self.user.id, course=self.course_id))

        self.verify_uuid = ''
        self.download_uuid = ''
        self.download_url = ''
        self.grade = ''
        self.status = CertificateStatuses.unavailable
        self.save()
        COURSE_CERT_REVOKED.send_robust(
            sender=self.__class__,
            user=self.user,
            course_key=self.course_id,
            mode=self.mode,
            status=self.status,
        )

    def mark_notpassing(self, grade):
        """
        Invalidates a Generated Certificate by marking it as not passing
        """
        log.info(
            'Marking certificate as notpassing for {user} : {course}'.format(
                user=self.user.id, course=self.course_id))

        self.verify_uuid = ''
        self.download_uuid = ''
        self.download_url = ''
        self.grade = grade
        self.status = CertificateStatuses.notpassing
        self.save()
        COURSE_CERT_REVOKED.send_robust(
            sender=self.__class__,
            user=self.user,
            course_key=self.course_id,
            mode=self.mode,
            status=self.status,
        )

    def is_valid(self):
        """
        Return True if certificate is valid else return False.
        """
        return self.status == CertificateStatuses.downloadable

    def save(self, *args, **kwargs):  # pylint: disable=signature-differs
        """
        After the base save() method finishes, fire the COURSE_CERT_AWARDED
        signal iff we are saving a record of a learner passing the course.
        As well as the COURSE_CERT_CHANGED for any save event.
        """
        super().save(*args, **kwargs)
        COURSE_CERT_CHANGED.send_robust(
            sender=self.__class__,
            user=self.user,
            course_key=self.course_id,
            mode=self.mode,
            status=self.status,
        )
        if CertificateStatuses.is_passing_status(self.status):
            COURSE_CERT_AWARDED.send_robust(
                sender=self.__class__,
                user=self.user,
                course_key=self.course_id,
                mode=self.mode,
                status=self.status,
            )
Esempio n. 20
0
class SurgeObservation(TimeSeriesPoint, AbstractSurge):
    history = HistoricalRecords(inherit=True)
Esempio n. 21
0
class Copy(models.Model):
    "djangocopy content"

    FORMAT_PLAIN = 'p'
    FORMAT_MARKDOWN = 'm'
    FORMAT_JSON = 'j'
    FORMAT_SAFE_HTML = 'h'
    FORMAT_SPECIAL_HTML = 's'

    FORMAT_CHOICES = (
        (FORMAT_PLAIN, 'Plain text'),
        (FORMAT_MARKDOWN, 'Markdown'),
        (FORMAT_JSON, 'JSON'),
        (FORMAT_SAFE_HTML, 'HTML'),
        (FORMAT_SPECIAL_HTML, 'Special HTML'),
    )

    STATUS_DRAFT = 'd'
    STATUS_PUBLISHED = 'p'

    STATUS_CHOICES = (
        (STATUS_DRAFT, 'Draft'),
        (STATUS_PUBLISHED, 'Published'),
    )

    fieldid = models.SlugField(
        max_length=100,
        help_text="The field identifier that will be used in templates")

    url = models.CharField(
        max_length=255,
        blank=True,
        help_text="URL name (leave empty to load for all templates)")
    locale = models.CharField(max_length=5,
                              blank=True,
                              help_text="Browser settings (e.g. 'en_GB')")
    geo = models.CharField(
        max_length=2,
        blank=True,
        help_text="Country code derived from the IP (e.g. 'GB')")

    text = models.TextField(max_length=10000)
    format = models.CharField(max_length=1,
                              choices=FORMAT_CHOICES,
                              default=FORMAT_PLAIN)
    status = models.CharField(max_length=1,
                              choices=STATUS_CHOICES,
                              default=STATUS_DRAFT)

    history = HistoricalRecords()

    class Meta:
        verbose_name_plural = 'copy'
        unique_together = (("fieldid", "url", "locale", "geo", "status"), )

    @property
    def status_as_string(self):
        return dict(self.STATUS_CHOICES).get(self.status, '--')

    def render(self):
        return __MAPPING__[self.format](self.text)

    def short_text(self, truncate=80):
        return self.text[:truncate] + '...' if len(
            self.text) > truncate else self.text

    def __str__(self):
        str = "{}/{} - {}".format(self.url or '*', self.fieldid,
                                  self.text[:40])
        if self.locale or self.geo:
            str += " ({},{})".format(self.locale or '*', self.geo or '*')
        str += ' ' + self.status_as_string.upper()
        return str

    @staticmethod
    def get_for_url(url, locale, geo, draft=False):
        """Retrieve set of copies for a given URL (or URL name), locale and geographical location"""
        if draft:
            qs = Copy.objects.filter(
                Q(url=url) | Q(url=resolve(url).url_name) | Q(url=''),
                Q(locale=locale) | Q(locale=locale[:2]) | Q(locale=''),
                Q(geo=geo) | Q(geo=''),
            ).order_by(
                'locale', 'geo', '-status'
            )  # Ordering puts defaults first so they get overwritten when converting to dict

        else:
            qs = Copy.objects.filter(
                Q(url=url) | Q(url=resolve(url).url_name) | Q(url=''),
                Q(locale=locale) | Q(locale=locale[:2]) | Q(locale=''),
                Q(geo='') | Q(geo=geo),
                status=Copy.STATUS_PUBLISHED,
            ).order_by(
                'locale', 'geo'
            )  # Ordering puts defaults first so they get overwritten when converting to dict

        values = qs.values_list('fieldid', 'text', 'format')
        out = [(fld, __MAPPING__[fmt](txt)) for fld, txt, fmt in values]
        return dict(out)
Esempio n. 22
0
class SurgeObservationCache(AbstractDatetimeCache, AbstractSurge):
    source = SurgeObservation
    serializer_class = 'SurgeObservationSerializer'

    history = HistoricalRecords()
Esempio n. 23
0
class CreditRequirementStatus(TimeStampedModel):
    """
    This model represents the status of each requirement.

    For a particular credit requirement, a user can either:
    1) Have satisfied the requirement (example: approved in-course reverification)
    2) Have failed the requirement (example: denied in-course reverification)
    3) Neither satisfied nor failed (example: the user hasn't yet attempted in-course reverification).

    Cases (1) and (2) are represented by having a CreditRequirementStatus with
    the status set to "satisfied" or "failed", respectively.

    In case (3), no CreditRequirementStatus record will exist for the requirement and user.

    """

    REQUIREMENT_STATUS_CHOICES = (
        ("satisfied", "satisfied"),
        ("failed", "failed"),
    )

    username = models.CharField(max_length=255, db_index=True)
    requirement = models.ForeignKey(CreditRequirement, related_name="statuses")
    status = models.CharField(max_length=32,
                              choices=REQUIREMENT_STATUS_CHOICES)

    # Include additional information about why the user satisfied or failed
    # the requirement.  This is specific to the type of requirement.
    # For example, the minimum grade requirement might record the user's
    # final grade when the user completes the course.  This allows us to display
    # the grade to users later and to send the information to credit providers.
    reason = JSONField(default={})

    # Maintain a history of requirement status updates for auditing purposes
    history = HistoricalRecords()

    class Meta(object):  # pylint: disable=missing-docstring
        unique_together = ('username', 'requirement')

    @classmethod
    def get_statuses(cls, requirements, username):
        """
        Get credit requirement statuses of given requirement and username

        Args:
            requirement(CreditRequirement): The identifier for a requirement
            username(str): username of the user

        Returns:
            Queryset 'CreditRequirementStatus' objects
        """
        return cls.objects.filter(requirement__in=requirements,
                                  username=username)

    @classmethod
    @transaction.commit_on_success
    def add_or_update_requirement_status(cls,
                                         username,
                                         requirement,
                                         status="satisfied",
                                         reason=None):
        """
        Add credit requirement status for given username.

        Args:
            username(str): Username of the user
            requirement(CreditRequirement): 'CreditRequirement' object
            status(str): Status of the requirement
            reason(dict): Reason of the status

        """
        requirement_status, created = cls.objects.get_or_create(
            username=username,
            requirement=requirement,
            defaults={
                "reason": reason,
                "status": status
            })
        if not created:
            requirement_status.status = status
            requirement_status.reason = reason if reason else {}
            requirement_status.save()

    @classmethod
    @transaction.commit_on_success
    def remove_requirement_status(cls, username, requirement):
        """
        Remove credit requirement status for given username.

        Args:
            username(str): Username of the user
            requirement(CreditRequirement): 'CreditRequirement' object
        """

        try:
            requirement_status = cls.objects.get(username=username,
                                                 requirement=requirement)
            requirement_status.delete()
        except cls.DoesNotExist:
            log_msg = (
                u'The requirement status {requirement} does not exist for username {username}.'
                .format(requirement=requirement, username=username))
            log.error(log_msg)
            return
Esempio n. 24
0
class TidePredictionCache(AbstractDatetimeCache, AbstractTidePrediction):
    source = TidePrediction
    serializer_class = 'TidePredictionSerializer'

    history = HistoricalRecords()
Esempio n. 25
0
class Workup(AttestableNote):
    '''Datamodel of a workup. Has fields specific to each part of an exam,
    along with SNHC-specific info about where the patient has been referred for
    continuity care.'''

    attending = models.ForeignKey(Provider,
                                  null=True,
                                  blank=True,
                                  related_name="attending_physician",
                                  on_delete=models.PROTECT,
                                  validators=[validate_attending],
                                  help_text="Which attending saw the patient?")

    other_volunteer = models.ManyToManyField(
        Provider,
        blank=True,
        related_name="other_volunteer",
        help_text="Which other volunteer(s) did you work with (if any)?")

    clinic_day = models.ForeignKey(ClinicDate,
                                   on_delete=models.PROTECT,
                                   help_text="When was the patient seen?")

    chief_complaint = models.CharField(max_length=1000, verbose_name="CC")
    diagnosis = models.CharField(max_length=1000, verbose_name="Dx")
    diagnosis_categories = models.ManyToManyField(DiagnosisType)

    HPI = models.TextField(verbose_name="HPI")
    PMH_PSH = models.TextField(verbose_name="PMH/PSH")
    meds = models.TextField(verbose_name="Medications")
    allergies = models.TextField()
    fam_hx = models.TextField(verbose_name="Family History")
    soc_hx = models.TextField(verbose_name="Social History")
    ros = models.TextField(verbose_name="ROS")

    # represented internally in per min
    hr = models.PositiveSmallIntegerField(blank=True,
                                          null=True,
                                          verbose_name="Heart Rate")

    # represented internally as mmHg
    bp_sys = models.PositiveSmallIntegerField(
        blank=True,
        null=True,
        verbose_name="Systolic",
        validators=[workup_validators.validate_bp_systolic])
    bp_dia = models.PositiveSmallIntegerField(
        blank=True,
        null=True,
        verbose_name="Diastolic",
        validators=[workup_validators.validate_bp_diastolic])

    # represented internally in per min
    rr = models.PositiveSmallIntegerField(blank=True,
                                          null=True,
                                          verbose_name="Respiratory Rate")

    # represented internally in Fahrenheit
    t = models.DecimalField(max_digits=4,
                            decimal_places=1,
                            blank=True,
                            null=True,
                            verbose_name="Temperature")

    # represented internally as inches
    height = models.PositiveSmallIntegerField(blank=True, null=True)
    # represented internally as kg
    weight = models.DecimalField(max_digits=5,
                                 decimal_places=1,
                                 blank=True,
                                 null=True)

    pe = models.TextField(verbose_name="Physical Examination")

    labs_ordered_quest = models.TextField(
        blank=True, null=True, verbose_name="Labs Ordered from Quest")
    labs_ordered_internal = models.TextField(
        blank=True, null=True, verbose_name="Labs Ordered Internally")

    rx = models.TextField(blank=True,
                          null=True,
                          verbose_name="Prescription Orders")

    got_voucher = models.BooleanField(default=False)
    voucher_amount = models.DecimalField(max_digits=6,
                                         decimal_places=2,
                                         blank=True,
                                         null=True,
                                         validators=[MinValueValidator(0)])
    patient_pays = models.DecimalField(max_digits=6,
                                       decimal_places=2,
                                       blank=True,
                                       null=True,
                                       validators=[MinValueValidator(0)])

    got_imaging_voucher = models.BooleanField(default=False)
    imaging_voucher_amount = models.DecimalField(
        max_digits=6,
        decimal_places=2,
        blank=True,
        null=True,
        validators=[MinValueValidator(0)])
    patient_pays_imaging = models.DecimalField(
        max_digits=6,
        decimal_places=2,
        blank=True,
        null=True,
        validators=[MinValueValidator(0)])

    # Please note that these are no longer shown on the form and will not
    # be filled out because the referral app handles this functionality
    referral_type = models.ManyToManyField(ReferralType, blank=True)
    referral_location = models.ManyToManyField(ReferralLocation, blank=True)

    will_return = models.BooleanField(default=False,
                                      help_text="Will the pt. return to SNHC?")

    A_and_P = models.TextField()

    signer = models.ForeignKey(Provider,
                               blank=True,
                               null=True,
                               on_delete=models.PROTECT,
                               related_name="signed_workups",
                               validators=[validate_attending])
    signed_date = models.DateTimeField(blank=True, null=True)

    history = HistoricalRecords()

    def short_text(self):
        '''
        Return the 'short text' representation of this Note. In this case, it's
        simply the CC
        '''
        return self.chief_complaint

    # TODO: this is not consistent with the written datetime that we see for
    # the rest of the Note subclasses.
    def written_date(self):
        '''
        Returns the date (not datetime) this workup was written on.
        '''
        return self.clinic_day.clinic_date

    def url(self):
        return reverse('workup', args=(self.pk, ))

    def __str__(self):
        return self.patient.name() + " on " + str(self.clinic_day.clinic_date)
Esempio n. 26
0
class Appointment(models.Model):
    owner = models.ForeignKey(to=dj_settings.AUTH_USER_MODEL,
                              on_delete=models.CASCADE,
                              to_field='uuid')

    timeslot = models.ForeignKey(to=TimeSlot, on_delete=models.CASCADE)
    start_time = models.DateTimeField(
        validators=[validators.validate_start_time])
    duration = models.DurationField(validators=[validators.validate_duration])

    subject = models.ForeignKey(to='account.Subject',
                                on_delete=models.SET_NULL,
                                null=True,
                                blank=True)

    topic = models.CharField(max_length=255, blank=True)

    meeting = models.ForeignKey(to='roulette.Meeting',
                                on_delete=models.SET_NULL,
                                null=True,
                                blank=True)

    confirmation_request_time = models.DateTimeField(auto_now_add=True)
    invitee_rejects = models.ManyToManyField(
        to=dj_settings.AUTH_USER_MODEL,
        related_name='rejected_appointments',
        blank=True)

    reminded = models.BooleanField(default=False)

    all_objects = models.Manager()
    objects = ActiveAppointmentManager()

    class Status(models.TextChoices):
        REQUESTED = 'REQUESTED'
        CONFIRMED = 'CONFIRMED'

        # rejection states
        OWNER_REJECTED = 'OWNER_REJECTED'
        INVITEE_REJECTED = 'INVITEE_REJECTED'

        # meeting states
        OWNER_STARTED = 'OWNER_STARTED'
        INVITEE_STARTED = 'INVITEE_STARTED'
        BOTH_STARTED = 'BOTH_STARTED'

    status = models.TextField(choices=Status.choices, default=Status.REQUESTED)

    history = HistoricalRecords(user_db_constraint=False)

    @classmethod
    def book_available(cls, slot: 'AvailableSlot', duration, **kwargs):
        return cls.objects.create(timeslot=slot.parent,
                                  start_time=slot.start_time,
                                  duration=duration,
                                  **kwargs)

    def save(self, *args, **kwargs):
        # to check: is constraint satisfied?
        super(Appointment, self).save(*args, **kwargs)

    @property
    def end_time(self):
        return self.start_time + self.duration

    @property
    def invitee(self):
        return self.timeslot.owner

    @property
    def rejected(self) -> bool:
        return self.status == Appointment.Status.INVITEE_REJECTED or self.status == Appointment.Status.OWNER_REJECTED

    def check_in_range(self) -> bool:
        now = timezone.now()
        # only check if our start time actually is in the future!
        if self.start_time >= now:
            return util.check_slot_in_range(self.start_time, self.duration,
                                            self.timeslot)
        else:
            return True

    def check_collisions(self) -> list['Appointment']:
        collisions = []
        my_start = self.start_time
        my_end = self.end_time
        for appointment in self.objects.exclude(pk=self.pk):
            if my_start == appointment.start_time or my_end >= appointment.end_time:
                collisions.append(appointment)

        return collisions

    def send_confirmed(self):
        logger.debug(f'sending confirmation to owner: {self.owner.email}')
        mail.send(
            [self.owner.email],
            '*****@*****.**',
            'appointment_confirmed',
            context={
                'appointment': self,
                'confirming_party': self.invitee,
                'other_party': self.owner
            })
        self.confirmation_request_time = timezone.now()
        self.save()

    def send_confirmation_request(self):
        logger.debug(
            f'sending confirmation request to invitee {self.invitee.email}')
        mail.send([self.invitee.email],
                  '*****@*****.**',
                  'appointment_request',
                  context={'appointment': self})

    def send_reminder(self):
        with transaction.atomic():
            appointment = self.__class__.objects.select_for_update().get(
                pk=self.pk)
            if not appointment.reminded:
                mail.send(
                    [self.invitee.email],
                    '*****@*****.**',
                    'appointment_reminder',
                    context={
                        'appointment': appointment,
                        'reminded_party': self.invitee,
                        'other_party': self.owner
                    })
                mail.send(
                    [self.owner.email],
                    '*****@*****.**',
                    'appointment_reminder',
                    context={
                        'appointment': appointment,
                        'reminded_party': self.owner,
                        'other_party': self.invitee
                    })
            appointment.reminded = True
            appointment.save()
        self.refresh_from_db()

    def handle_rejection(self, rejecting_party):
        """Handle rejection of appointment from either party
        If the ::rejecting_party is the owner, don't search for another possible timeslot
        Otherwise try to match a new party!
        """
        if rejecting_party == self.owner:
            logger.debug(
                "Sending rejection notification to timeslot owner and updating appointment"
            )
            mail.send(
                [self.invitee.email],
                '*****@*****.**',
                template='appointment_rejected',
                context={
                    'appointment': self,
                    'rejecting_party': self.owner,
                    'other_party': self.invitee,
                    'new_try': False
                })
            self.status = Appointment.Status.OWNER_REJECTED
        elif rejecting_party == self.invitee:
            self.invitee_rejects.add(self.invitee)
            old_status = self.status
            new_slot = util.find_matching_timeslot(
                self.start_time, self.duration, self.subject, self.owner,
                TimeSlot.objects.exclude(owner__in=self.invitee_rejects.all()))
            if new_slot:
                self.timeslot = new_slot
                self.status = Appointment.Status.REQUESTED
                self.save()
                self.send_confirmation_request()
            else:
                logger.debug(
                    "Send rejection notification to owner and updating appointment"
                )
                self.status = Appointment.Status.INVITEE_REJECTED
                if old_status == Appointment.Status.CONFIRMED:
                    mail.send(
                        [self.owner.email],
                        '*****@*****.**',
                        template='appointment_rejected',
                        context={
                            'appointment': self,
                            'rejecting_party': self.invitee,
                            'other_party': self.owner,
                            'new_try':
                            self.status == Appointment.Status.REQUESTED
                        })
                else:
                    mail.send([self.owner.email],
                              '*****@*****.**',
                              template='appointment_failed',
                              context={
                                  'appointment': self,
                                  'other_party': self.owner,
                              })
        self.save()

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['timeslot', 'start_time'],
                name='unique_appointment_timeslot_start_time',
                condition=~Q(
                    Q(status='OWNER_REJECTED')
                    | Q(status='INVITEE_REJECTED'))),
        ]
Esempio n. 27
0
class Estilo(models.Model):
    nombre = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )

    somos_background = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    somos_titulo_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    somos_titulo_descripcion = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )

    horarios_background = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    horarios_titulo_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    horarios_horario_relojhoras_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    horarios_horario_dias_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )

    galeria_background = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    galeria_titulo_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )

    resennas_tituloycontenidonombre_background = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    resennas_tituloycontenidonombre_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    resennas_fecha_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )

    mapa_background = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    mapa_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    mapa_info_back = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    mapa_info_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )

    sociales_info_background = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )
    sociales_titulo_color = models.CharField(
        max_length=100,
        null=True,
        blank=True,
    )

    history = HistoricalRecords()

    class Meta:
        verbose_name = _('Estilo')
        verbose_name_plural = _('Estilos')

    def __unicode__(self):
        return self.nombre
Esempio n. 28
0
class Proposal(TimeAuditModel):
    """ The proposals master """
    conference = models.ForeignKey(Conference)
    proposal_section = models.ForeignKey(ProposalSection,
                                         verbose_name="Proposal Section")
    proposal_type = models.ForeignKey(ProposalType,
                                      verbose_name="Proposal Type")
    author = models.ForeignKey(User, verbose_name="Primary Speaker")
    title = models.CharField(max_length=255)
    slug = AutoSlugField(max_length=255, populate_from=('title', ))
    description = models.TextField(default="")
    target_audience = models.PositiveSmallIntegerField(
        choices=ProposalTargetAudience.CHOICES,
        default=ProposalTargetAudience.BEGINNER,
        verbose_name="Target Audience")
    prerequisites = models.TextField(blank=True, default="")
    content_urls = models.TextField(blank=True, default="")
    speaker_info = models.TextField(blank=True, default="")
    speaker_links = models.TextField(blank=True, default="")
    status = models.PositiveSmallIntegerField(choices=ProposalStatus.CHOICES,
                                              default=ProposalStatus.DRAFT)
    review_status = models.PositiveSmallIntegerField(
        choices=ProposalReviewStatus.CHOICES,
        default=ProposalReviewStatus.YET_TO_BE_REVIEWED,
        verbose_name="Review Status")
    deleted = models.BooleanField(default=False, verbose_name="Is Deleted?")
    history = HistoricalRecords()

    def __str__(self):
        return "{}, {}".format(self.title, self.proposal_type)

    def is_public(self):
        # TODO: Fix with proper enum
        return self.status == 2

    def get_slug(self):
        return slugify(self.title)

    def get_hashid(self):
        hashids = Hashids(min_length=5)
        return hashids.encode(self.id)

    def get_absolute_url(self):
        return reverse(
            'proposal-detail',
            args=[self.conference.slug,
                  self.get_slug(),
                  self.get_hashid()])

    def get_update_url(self):
        return reverse('proposal-update',
                       args=[self.conference.slug, self.slug])

    def get_review_url(self):
        return reverse('proposal-review',
                       args=[self.conference.slug, self.slug])

    def get_vote_url(self):
        return reverse('proposal-reviewer-vote',
                       args=[self.conference.slug, self.slug])

    def get_secondary_vote_url(self):
        return reverse('proposal-reviewer-secondary-vote',
                       args=[self.conference.slug, self.slug])

    def get_delete_url(self):
        return reverse('proposal-delete',
                       args=[self.conference.slug, self.slug])

    def get_up_vote_url(self):
        return reverse('proposal-vote-up',
                       args=[self.conference.slug, self.slug])

    def get_down_vote_url(self):
        return reverse('proposal-vote-down',
                       args=[self.conference.slug, self.slug])

    def get_remove_vote_url(self):
        return reverse('proposal-vote-remove',
                       args=[self.conference.slug, self.slug])

    def get_comments_count(self):
        """ Show only public comments count """
        return ProposalComment.objects.filter(proposal=self,
                                              deleted=False,
                                              private=False,
                                              vote=False,
                                              reviewer=False).count()

    def get_reviews_comments_count(self):
        """ Show only private comments count """
        return ProposalComment.objects.filter(proposal=self,
                                              deleted=False,
                                              private=True,
                                              vote=False).count()

    def get_reviewer_comments_count(self, reviewer):
        """ Number of private comments by a reviewer """
        return ProposalComment.objects.filter(proposal=self,
                                              deleted=False,
                                              private=True,
                                              commenter=reviewer,
                                              vote=False).count()

    def get_votes_count(self):
        """ Show only the public comment count """
        votes = ProposalVote.objects.filter(
            proposal=self).values('up_vote').annotate(
                counts=models.Count('up_vote'))
        votes = {item['up_vote']: item['counts'] for item in votes}
        up_vote_count = votes.get(True, 0)
        down_vote_count = votes.get(False, 0)
        return up_vote_count - down_vote_count

    def get_reviewer_votes_count(self):
        """ Show sum of reviewer vote value. """
        return ProposalSectionReviewerVote.objects.filter(
            proposal=self).count()

    def get_reviewer_votes_count_by_value(self, vote_value):
        """ Show sum of reviewer votes for given vote value. """
        return ProposalSectionReviewerVote.objects.filter(
            proposal=self, vote_value__vote_value=vote_value).count()

    def get_reviewer_votes_sum(self):
        votes = ProposalSectionReviewerVote.objects.filter(proposal=self, )
        sum_of_votes = sum((v.vote_value.vote_value for v in votes))
        return sum_of_votes

    def get_reviewer_vote_value(self, reviewer):
        try:
            vote = ProposalSectionReviewerVote.objects.get(
                proposal=self,
                voter__conference_reviewer__reviewer=reviewer,
            )
            return vote.vote_value.vote_value
        except ProposalSectionReviewerVote.DoesNotExist:
            return 0

    def get_reviewers_count(self):
        """ Count of reviewers for given proposal section """
        return ProposalSectionReviewer.objects.filter(
            proposal_section=self.proposal_section).count()

    def has_negative_votes(self):
        """ Show sum of reviewer votes for given vote value. """
        return ProposalSectionReviewerVote.objects.filter(
            proposal=self,
            vote_value__vote_value=ProposalReviewVote.NOT_ALLOWED,
        ).count() > 0

    class Meta:
        unique_together = ("conference", "slug")
Esempio n. 29
0
class Evento(models.Model):
    # associations
    tienda = models.ForeignKey(Tienda,
                               blank=True,
                               null=True,
                               related_name='tienda_evento')
    marca = models.ForeignKey(Marca,
                              blank=True,
                              null=True,
                              related_name='brand_event')

    tipo_evento = models.CharField(_('tipo de evento'),
                                   choices=TIPO_EVENTOS_CHOICES,
                                   blank=True,
                                   null=True,
                                   max_length=2)
    comuna = models.ForeignKey(Comuna,
                               null=True,
                               blank=True,
                               related_name='comuna_event')

    # info
    titulo = models.CharField(max_length=64)
    subtitulo = models.CharField(max_length=300, blank=True, null=True)
    direccion = models.CharField(max_length=64, blank=True, null=True)
    descripcion = models.TextField(blank=True, null=True)

    url = models.URLField(blank=True, null=True)
    google_map_iframe = models.CharField(
        blank=True,
        null=True,
        max_length=999,
    )

    # options
    en_tienda = models.BooleanField(default=True)
    google_map = GeopositionField(default='-39.8173788,-73.24253329999999',
                                  blank=True)

    history = HistoricalRecords()
    slug = models.SlugField(unique=True, null=True, blank=True)  # self

    fecha_expiracion = models.DateTimeField(default=django.utils.timezone.now,
                                            null=True,
                                            blank=True)
    fecha_inicio = models.DateTimeField(default=django.utils.timezone.now,
                                        null=True,
                                        blank=True)

    activo = models.BooleanField(
        _('Activado'),
        default=False,
        help_text='Si se encuentra activo será visible')
    redireccion = models.BooleanField(
        _('Redireccionar'),
        default=False,
        help_text='Al pedir más informaciónredireccionará')

    def __unicode__(self):
        return u'%s' % self.titulo

    def get_map(self):
        return 'inicialize%s' % self.slug.replace("-", "")
Esempio n. 30
0
class TenureRelationship(ResourceModelMixin, RandomIDModel):
    """TenureRelationship model.

    Governs relationships between Party and SpatialUnit.
    """

    CONTRACTUAL_SHARE_CROP = 'CS'
    CUSTOMARY_ARRANGEMENT = 'CA'
    GIFT = 'GF'
    HOMESTEAD = 'HS'
    INFORMAL_OCCUPANT = 'IO'
    INHERITANCE = 'IN'
    LEASEHOLD = 'LH'
    PURCHASED_FREEHOLD = 'PF'
    RENTAL = 'RN'
    OTHER = 'OT'

    ACQUIRED_CHOICES = ((CONTRACTUAL_SHARE_CROP, _('Contractual/Share Crop')),
                        (CUSTOMARY_ARRANGEMENT,
                         _('Customary Arrangement')), (GIFT, _('Gift')),
                        (HOMESTEAD, _('Homestead')), (INFORMAL_OCCUPANT,
                                                      _('Informal Occupant')),
                        (INHERITANCE, _('Inheritance')),
                        (LEASEHOLD, _('Leasehold')), (PURCHASED_FREEHOLD,
                                                      _('Purchased Freehold')),
                        (RENTAL, _('Rental')), (OTHER, _('Other')))

    # All tenure relationships are associated with a single project
    project = models.ForeignKey(Project,
                                on_delete=models.CASCADE,
                                related_name='tenure_relationships')

    # Party to the relationship
    party = models.ForeignKey(Party, on_delete=models.CASCADE)

    # Spatial unit in the relationship
    spatial_unit = models.ForeignKey(SpatialUnit, on_delete=models.CASCADE)

    # Tenure relationships type: used to manage range of allowed attributes
    tenure_type = models.ForeignKey('TenureRelationshipType',
                                    related_name='tenure_type',
                                    null=False,
                                    blank=False)

    # JSON attributes field with management of allowed members.
    attributes = JSONAttributeField(default={})
    objects = managers.TenureRelationshipManager()

    history = HistoricalRecords()

    class TutelaryMeta:
        perm_type = 'tenure_rel'
        path_fields = ('project', 'id')
        actions = (
            ('tenure_rel.list', {
                'description':
                _("List existing tenure relationships"
                  " of a project"),
                'error_message':
                messages.TENURE_REL_LIST,
                'permissions_object':
                'project'
            }),
            ('tenure_rel.create', {
                'description': _("Add a tenure relationship to a project"),
                'error_message': messages.TENURE_REL_CREATE,
                'permissions_object': 'project'
            }),
            ('tenure_rel.view', {
                'description': _("View an existing tenure relationship"),
                'error_message': messages.TENURE_REL_VIEW
            }),
            ('tenure_rel.update', {
                'description': _("Update an existing tenure relationship"),
                'error_message': messages.TENURE_REL_UPDATE
            }),
            ('tenure_rel.delete', {
                'description': _("Delete an existing tenure relationship"),
                'error_message': messages.TENURE_REL_DELETE
            }),
            ('tenure_rel.resources.add', {
                'description': _("Add a resource to a tenure relationship"),
                'error_message': messages.TENURE_REL_RESOURCES_ADD
            }),
        )

    def __str__(self):
        return "<TenureRelationship: {}>".format(self.name)

    def __repr__(self):
        return str(self)

    @property
    def name(self):
        return "<{party}> {type} <{su}>".format(
            party=self.party.name,
            su=self.spatial_unit.name,
            type=self.tenure_type.label,
        )

    @property
    def ui_class_name(self):
        return _("Relationship")

    @property
    def ui_detail_url(self):
        return reverse(
            'parties:relationship_detail',
            kwargs={
                'organization': self.project.organization.slug,
                'project': self.project.slug,
                'relationship': self.id,
            },
        )