Beispiel #1
0
class User(AbstractUser):
    is_teacher = models.BooleanField(default=False)
    is_student = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    school = models.ForeignKey(School, on_delete=models.CASCADE, null=True)
    date_of_birth = models.DateField(null=True)
    student_class = models.ForeignKey(Class,
                                      on_delete=models.CASCADE,
                                      related_name='studentprofile',
                                      null=True)
    academic_year = models.ForeignKey(AcademicYear,
                                      on_delete=models.CASCADE,
                                      related_name='student_profile',
                                      null=True)

    CHR = 'Christian'
    MUS = 'Muslim'
    OTH = "Other"

    rel = (
        (CHR, 'Christian'),
        (MUS, 'Muslim'),
        (OTH, 'Other'),
    )

    religion = models.CharField(max_length=100, choices=rel, null=True)

    # Teacher Specific
    date_employed = models.DateField(null=True)
    subject = models.ManyToManyField(Subject)
    salary = MoneyField(max_digits=10,
                        decimal_places=2,
                        default_currency='NGN',
                        null=True,
                        blank=True)
    phone_no = models.CharField(max_length=50, null=True)
    classes = models.ManyToManyField(Class)
    admission_date = models.DateField(null=True, blank=True)

    # Student Specific
    mother_name = models.CharField(max_length=50, null=True)
    mother_number = models.CharField(max_length=50, null=True)
    father_name = models.CharField(max_length=50, null=True)
    father_number = models.CharField(max_length=50, null=True)

    address = models.CharField(max_length=100, null=True)

    MALE = 'Male'
    FEMALE = 'Female'

    sex = (
        (MALE, 'Male'),
        (FEMALE, 'Female'),
    )

    gender = models.CharField(max_length=100, choices=sex, null=True)

    image = models.ImageField(default='default-profile-picture.jpg',
                              upload_to=user_upload,
                              null=True)

    def __str__(self):
        return self.username

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
Beispiel #2
0
class ModelWithVanillaMoneyField(models.Model):
    money = MoneyField(max_digits=10, decimal_places=2)
Beispiel #3
0
class ModelWithDefaultAsStringWithCurrency(models.Model):
    money = MoneyField(default='123 USD', max_digits=10, decimal_places=2)
Beispiel #4
0
class Order(AbstractPeriod, CommonInfo, ValidationMixin):
    """The order class."""

    filler: Type = OrderAutoFiller
    copy_contacts: Callable[["Order"], None] = copy_contacts_from_order_to_user
    notifier: Callable[["Order", bool], None] = notify_order_update

    validators: List[Callable[["Order"], None]] = [
        orders_validators.validate_order_dates,
        orders_validators.validate_order_status,
        orders_validators.validate_order_client,
        orders_validators.validate_order_client_location,
        orders_validators.validate_order_service_location,
        orders_validators.validate_order_availability,
    ]

    objects: OrdersManager = OrdersManager()

    STATUS_NOT_CONFIRMED: str = "not_confirmed"
    STATUS_CONFIRMED: str = "confirmed"
    STATUS_PAID: str = "paid"
    STATUS_COMPLETED: str = "completed"
    STATUS_CANCELED: str = "canceled"
    STATUS_CHOICES = [
        (STATUS_NOT_CONFIRMED, _("not confirmed")),
        (STATUS_CONFIRMED, _("confirmed")),
        (STATUS_PAID, _("paid")),
        (STATUS_COMPLETED, _("completed")),
        (STATUS_CANCELED, _("canceled")),
    ]

    service: "Service" = models.ForeignKey(
        "services.Service",
        on_delete=models.PROTECT,
        related_name="orders",
        verbose_name=_("service"),
    )
    service_location: "ServiceLocation" = models.ForeignKey(
        "services.ServiceLocation",
        on_delete=models.PROTECT,
        related_name="orders",
        verbose_name=_("service location"),
        null=True,
        blank=True,
    )
    client_location: "UserLocation" = models.ForeignKey(
        "users.UserLocation",
        on_delete=models.SET_NULL,
        related_name="orders",
        verbose_name=_("client location"),
        null=True,
        blank=True,
    )
    client: "User" = models.ForeignKey(
        "users.User",
        on_delete=models.PROTECT,
        related_name="orders",
        verbose_name=_("user"),
    )
    status = models.CharField(
        _("status"),
        max_length=20,
        choices=STATUS_CHOICES,
        default=STATUS_NOT_CONFIRMED,
    )
    note = models.CharField(
        _("note"),
        null=True,
        blank=True,
        max_length=255,
    )
    price = MoneyField(
        max_digits=settings.D8B_MONEY_MAX_DIGITS,
        decimal_places=settings.D8B_MONEY_DECIMAL_PLACES,
        verbose_name=_("price"),
        null=True,
        blank=True,
        validators=[MinMoneyValidator(0)],
        db_index=True,
    )
    is_another_person = models.BooleanField(
        default=False,
        verbose_name=_("Order for another person?"),
        db_index=True,
    )
    first_name = models.CharField(
        _("first name"),
        max_length=30,
        null=False,
        blank=True,
    )
    last_name = models.CharField(
        _("last name"),
        max_length=150,
        null=False,
        blank=True,
    )
    phone = PhoneNumberField(
        _("phone"),
        blank=True,
        null=True,
        db_index=True,
    )

    def full_clean(self, exclude=None, validate_unique=True):
        """Validate the object."""
        self.filler(self).fill()
        return super().full_clean(exclude, validate_unique)

    def clean(self):
        """Validate the object."""
        self.filler(self).fill()
        return super().clean()

    def save(self, **kwargs):
        """Save the object."""
        is_created = not bool(self.pk)
        self.filler(self).fill()
        super().save(**kwargs)
        self.copy_contacts()
        self.notifier(is_created)

    @property
    def duration(self) -> float:
        """Return the order duration."""
        delta = self.end_datetime - self.start_datetime
        return delta.total_seconds() / 60

    def __str__(self) -> str:
        """Return the string representation."""
        return f"#{self.pk}: {super().__str__()}"

    class Meta(CommonInfo.Meta):
        """The metainformation."""

        abstract = False
Beispiel #5
0
class Produce(models.Model):
    name = models.CharField(max_length=255)
    about = models.TextField(blank=True)

    category = models.ForeignKey(Category,
                                 null=True,
                                 blank=True,
                                 on_delete=models.PROTECT)

    is_fresh = models.BooleanField(
        default=False,
        verbose_name='Fresh',
        help_text=_('This is a fresh product (i.e. unprocessed).'))
    is_glutenfree = models.BooleanField(
        default=False,
        verbose_name='Gluten-free',
        help_text=_('Check if this product is free of gluten.'))
    is_dairyfree = models.BooleanField(
        default=False,
        verbose_name='Dairy-free',
        help_text=_('Milk is not part of this produce.'))
    is_nutsfree = models.BooleanField(
        default=False,
        verbose_name='Nut-free',
        help_text=_('Nuts are not part of this produce.'))
    is_vegan = models.BooleanField(
        default=False,
        verbose_name='Vegan',
        help_text=_('This is not an animal product.'))

    QUANTITYCHOICE = (
        ('kg', 'Kilogram'),
        ('g', 'Gram'),
        ('l', 'Litre'),
        ('b', 'Bushel'),
    )
    price_quantity = models.CharField(max_length=2,
                                      choices=QUANTITYCHOICE,
                                      null=True,
                                      blank=True)
    price_chf = MoneyField(max_digits=10,
                           decimal_places=2,
                           default_currency='CHF',
                           null=True,
                           blank=True)

    image = models.ForeignKey('wagtailimages.Image',
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL,
                              related_name='+')
    labels = models.ManyToManyField(
        Label,
        blank=True,
        help_text=_('What special modes of production were used.'))
    farms = models.ManyToManyField(
        Farm,
        blank=True,
        related_name='produce',
        help_text=_('Where is this produce available.'))

    panels = [
        FieldPanel('name'),
        FieldPanel('farms'),
        MultiFieldPanel(
            [
                FieldPanel('category'),
                FieldPanel('about'),
                ImageChooserPanel('image'),
                FieldPanel('price_chf'),
                FieldPanel('price_quantity'),
            ],
            heading="Details",
            classname="col5",
        ),
        MultiFieldPanel(
            [
                FieldPanel('is_fresh'),
                FieldPanel('is_glutenfree'),
                FieldPanel('is_dairyfree'),
                FieldPanel('is_nutsfree'),
                FieldPanel('is_vegan'),
                FieldPanel('labels'),
            ],
            heading="Features",
            classname="col7",
        ),
    ]

    api_fields = [
        APIField('name'),
        APIField('about'),
        APIField('category'),
        APIField('image_thumb',
                 serializer=ImageRenditionField('width-160', source='image')),
        APIField('image_full',
                 serializer=ImageRenditionField('width-800', source='image')),
        APIField('labels'),
        APIField('farms'),
    ]
    api_meta_fields = [
        'is_fresh',
        'is_glutenfree',
        'is_dairyfree',
        'is_nutsfree',
        'is_vegan',
    ]

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'Produce'
Beispiel #6
0
class ModelWithNonMoneyField(models.Model):
    money = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')
    desc = models.CharField(max_length=10)
Beispiel #7
0
class InheritorModel(AbstractModel):
    second_field = MoneyField(max_digits=10,
                              decimal_places=2,
                              default_currency='USD')
Beispiel #8
0
class RevisionedModel(models.Model):
    amount = MoneyField(max_digits=10,
                        decimal_places=2,
                        default_currency='USD')
Beispiel #9
0
class InheritedModel(BaseModel):
    second_field = MoneyField(max_digits=10,
                              decimal_places=2,
                              default_currency='USD')
Beispiel #10
0
class MoneyFieldClass(models.Model):
    """Create a MoneyField datatype to be able to allow serialization"""
    amount = MoneyField(max_digits=8, decimal_places=2)
Beispiel #11
0
class EducationalNeed(models.Model):

    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    date_uuid = models.CharField(max_length=100, blank=True, null=True)
    user = models.ForeignKey('auth.User')
    pub_date = models.DateField(default=timezone.now)
    title = models.CharField(max_length=200)
    permanent_address = models.TextField()
    hide_permanent_address = models.BooleanField(default=True)
    additional_mobile_number = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        validators=[
            RegexValidator(regex='^[0-9]*$',
                           message='Please use only numeric characters.')
        ])
    hide_mobile_number = models.BooleanField(default=True)
    additional_phone_number = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        validators=[
            RegexValidator(regex='^[0-9]*$',
                           message='Please use only numeric characters.')
        ])
    hide_phone_number = models.BooleanField(default=True)
    current_address = models.TextField()
    hide_current_address = models.BooleanField(default=True)
    college_school_address = models.TextField()
    college_school_contact_details = models.CharField(max_length=200)
    view_count = models.IntegerField(default=0)
    amount_required = MoneyField(max_digits=10,
                                 decimal_places=2,
                                 default_currency='INR',
                                 blank=True,
                                 null=True)
    requirement_description = RichTextField()
    youtube_url = models.URLField(blank=True, null=True)
    closed = models.BooleanField(default=False)

    # Define choices for communication_mode field
    PHONE = 'PH'
    MOBILE = 'MO'
    EMAIL = 'EM'
    COMMUNICATION_MODE_CHOICES = (
        (PHONE, 'Phone'),
        (MOBILE, 'Mobile'),
        (EMAIL, 'E-mail'),
    )

    communication_mode = models.CharField(
        max_length=2,
        choices=COMMUNICATION_MODE_CHOICES,
        default=PHONE,
    )

    verified = models.BooleanField(default=False)

    def __str__(self):
        return 'Educational Need {}'.format(str(self.pk))

    def save(self, *args, **kwargs):
        if not self.date_uuid:
            self.date_uuid = self.pub_date.strftime('%Y/%m/%d/') + str(
                self.uuid)
        super().save(*args, **kwargs)

    def create_youtube_embed_link(self):
        return str(self.youtube_url).replace('watch?v=', 'embed/')
Beispiel #12
0
class AdvertisingCampaign(models.Model):
    name = models.CharField(max_length=128)
    account = models.ForeignKey('accounts.Account')
    venue_account = models.ForeignKey('accounts.VenueAccount',
                                      blank=True,
                                      null=True,
                                      on_delete=models.SET_NULL)
    all_of_canada = models.BooleanField()
    regions = models.ManyToManyField(Region)

    budget = MoneyField(max_digits=10,
                        decimal_places=2,
                        default_currency='CAD')
    ammount_spent = MoneyField(max_digits=18,
                               decimal_places=10,
                               default_currency='CAD')

    enough_money = models.BooleanField(default=False)

    started = models.DateTimeField(auto_now=True, auto_now_add=True)
    ended = models.DateTimeField(auto_now=False,
                                 auto_now_add=False,
                                 null=True,
                                 blank=True)

    active_from = models.DateTimeField('active to',
                                       null=True,
                                       blank=True,
                                       auto_now=False,
                                       auto_now_add=False)
    active_to = models.DateTimeField('active to',
                                     null=True,
                                     blank=True,
                                     auto_now=False,
                                     auto_now_add=False)

    website = models.URLField()

    free = models.BooleanField(default=False)

    objects = money_manager(models.Manager())
    admin = AdminAdvertisingCampaignManager()
    with_unused_money = AdvertisingCampaignWithUnsusedMoney()

    active = ActiveAdvertisingCampaign()
    expired = ExpiredAdvertisingCampaign()

    def save(self, *args, **kwargs):
        if self.enough_money and self.ammount_spent >= self.budget and self.budget > Money(
                0, CAD):
            inform_user_that_money_was_spent(self)

        if self.ammount_spent >= self.budget:
            self.enough_money = False
        else:
            self.enough_money = True

        super(AdvertisingCampaign, self).save(*args, **kwargs)
        return self

    def __unicode__(self):
        return self.name

    def ammount_remaining(self):
        return self.budget - self.ammount_spent

    def regions_representation(self):
        return ", ".join(self.regions.all().values_list("name", flat=True))

    def is_active(self):
        now = datetime.datetime.now()
        return (self.enough_money or self.free) and (
            not self.active_from
            or self.active_from < now) and (not self.active_to
                                            or self.active_to > now)

    def is_finished(self):
        return self.active_to and self.active_to < datetime.datetime.now()

    def is_future(self):
        return self.active_from and self.active_from > datetime.datetime.now()
Beispiel #13
0
        class Model(models.Model):
            field = MoneyField(**field_kwargs)

            class Meta:
                app_label = 'test'
Beispiel #14
0
class OrderItem(Timestampable, Annotatable, models.Model):

    order = models.ForeignKey('shop.Order',
                              null=False,
                              on_delete=models.CASCADE,
                              related_name='order_items')
    item = models.ForeignKey('shop.Item',
                             null=True,
                             on_delete=models.PROTECT,
                             related_name='order_items')

    option_items = models.ManyToManyField('shop.Item',
                                          related_name='order_items_as_option')
    # note: duplicates in options and addons are ok, represents quantity
    addon_items = models.ManyToManyField('shop.Item',
                                         related_name='order_items_as_addon')

    quantity = models.DecimalField(default=1, decimal_places=2, max_digits=8)

    is_ad_hoc_item = models.BooleanField(default=False)
    ad_hoc_name = models.CharField(max_length=100, default="", blank=True)
    ad_hoc_price = MoneyField(max_digits=8,
                              decimal_places=2,
                              null=True,
                              blank=True,
                              default_currency='THB')

    # MODEL PROPERTIES

    @property
    def price(self):
        logging.debug("calculating price .. again")
        if self.ad_hoc_price:
            return self.ad_hoc_price.amount * self.quantity

        total_amount = self.item.price.amount

        # add options
        for option_item in self.option_items.all():
            total_amount += (option_item.option_price.amount
                             or option_item.price.amount)

        # add price.amount for each addon, excluding free addons
        free_counters = {}
        for addon_item in self.addon_items.all():
            item_addon_group_membership = addon_item.item_addon_group_memberships.filter(
                addon_group__item_id=self.item_id).order_by(
                    'custom_addon_price')
            # order by custom price so free_addon_count is applied to non-custom items first

            # if never free, find price by hierarchy
            if item_addon_group_membership.is_never_free:
                total_amount += (
                    item_addon_group_membership.custom_addon_price.amount
                    or item_addon_group_membership.addon_group.per_addon_price.
                    amount or item_addon_group_membership.item.price.amount)
                continue

            # check against possible addon_free_count and add price if/when necessary
            addon_group = item_addon_group_membership.addon_group
            if addon_group.id in free_counters:
                free_counters[addon_group.id] -= 1
            else:
                free_counters[
                    addon_group.id] = addon_group.addon_free_count or 0
                free_counters[addon_group.id] -= 1
            if free_counters[addon_group.id] < 0:
                total_amount += (
                    item_addon_group_membership.custom_addon_price.amount
                    or item_addon_group_membership.addon_group.per_addon_price.
                    amount or item_addon_group_membership.item.price.amount)

        return Money(
            round(total_amount * self.quantity,
                  2),  # finally round off to nearest 2 decimal places
            self.item.price.currency)

    # MODEL FUNCTIONS
    def get_cart_index_string(self):
        index_string = f"i{self.item.id}"
        for option_item in self.option_items.order_by('id'):
            index_string += f"+o{option_item.id}"
        for addon_item in self.addon_items.order_by('id'):
            index_string += f"+a{addon_item.id}"
        return index_string

    def get_quantity_display(self):
        return f'{self.quantity:.0f}' if (self.quantity %
                                          1 == 0) else f'{self.quantity:.2f}'

    def get_price_amount_display(self):
        price_amount = self.price.amount
        return f'{price_amount:.0f}' if (price_amount %
                                         1 == 0) else f'{price_amount:.2f}'
Beispiel #15
0
class ModelWithDefaultAsMoney(models.Model):
    money = MoneyField(default=moneyed.Money('0.01', 'RUB'),
                       max_digits=10,
                       decimal_places=2)
Beispiel #16
0
class SimpleModel(models.Model):
    money = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')
Beispiel #17
0
class ModelWithTwoMoneyFields(models.Model):
    amount1 = MoneyField(max_digits=10, decimal_places=2)
    amount2 = MoneyField(max_digits=10, decimal_places=3)
Beispiel #18
0
class NullMoneyFieldModel(models.Model):
    field = MoneyField(max_digits=10,
                       decimal_places=2,
                       null=True,
                       default_currency='USD',
                       blank=True)
Beispiel #19
0
class AbstractModel(models.Model):
    money = MoneyField(max_digits=10, decimal_places=2, default_currency='USD')
    m2m_field = models.ManyToManyField(ModelWithDefaultAsInt)

    class Meta:
        abstract = True
Beispiel #20
0
class ModelWithCustomManager(models.Model):
    field = MoneyField(max_digits=10, decimal_places=2)

    manager = money_manager(MoneyManager())
Beispiel #21
0
class BankPayment(models.Model):
    """Bank payment."""

    identifier = models.TextField(verbose_name=_('Payment ID'))
    uuid = models.UUIDField(unique=True, editable=False, default=uuid.uuid4)
    payment_type = models.TextField(choices=PAYMENT_TYPE_CHOICES, default=PaymentType.TRANSFER,
                                    verbose_name=_('Payment type'))
    account = models.ForeignKey(BankAccount, on_delete=models.CASCADE, verbose_name=_('Destination account'))
    create_time = models.DateTimeField(auto_now_add=True, db_index=True, verbose_name=_('Create time'))
    transaction_date = models.DateField(null=True, db_index=True, verbose_name=_('Transaction date'))

    counter_account_number = models.TextField(blank=True, verbose_name=_('Counter account number'))
    counter_account_name = models.TextField(blank=True, verbose_name=_('Counter account name'))

    amount = MoneyField(max_digits=64, decimal_places=CURRENCY_PRECISION, verbose_name=_('Amount'))
    description = models.TextField(blank=True, verbose_name=_('Description'))
    state = models.TextField(choices=PAYMENT_STATE_CHOICES, default=PaymentState.READY_TO_PROCESS, db_index=True,
                             verbose_name=_('Payment state'))
    card_payment_state = models.TextField(blank=True, verbose_name=_('Card payment state'))

    processing_error = models.TextField(choices=PROCESSING_ERROR_CHOICES, null=True, blank=True,
                                        verbose_name=_('Automatic processing error'))

    # Payment symbols (specific for Czech Republic and Slovak Republic).
    constant_symbol = models.CharField(max_length=10, blank=True, verbose_name=_('Constant symbol'))
    variable_symbol = models.CharField(max_length=10, blank=True, verbose_name=_('Variable symbol'))
    specific_symbol = models.CharField(max_length=10, blank=True, verbose_name=_('Specific symbol'))

    processor = models.TextField(verbose_name=_('Processor'), blank=True)
    card_handler = models.TextField(verbose_name=_('Card handler'), blank=True)

    class Meta:
        """Model Meta class."""

        unique_together = ('identifier', 'account')
        verbose_name = _('Bank payment')
        verbose_name_plural = _('Bank payments')

        constraints = [
            CheckConstraint(check=Q(payment_type=PaymentType.TRANSFER) & ~Q(counter_account_number__exact='')
                            | Q(payment_type=PaymentType.CARD_PAYMENT, counter_account_number__exact=''),
                            name='payment_counter_account_only_for_transfer')
        ]

    def __str__(self):
        """Return string representation of bank payment."""
        return self.identifier

    def clean(self):
        """Check whether payment currency is the same as currency of related bank account."""
        if self.account.currency != self.amount.currency.code:
            raise ValidationError('Bank payment {} is in different currency ({}) than bank account {} ({}).'.format(
                self.identifier, self.amount.currency.code, self.account, self.account.currency
            ))
        super().clean()

    @property
    def advance_invoice(self):
        """Return advance invoice if it exists."""
        invoices = self.invoices.filter(invoice_type=InvoiceType.ADVANCE)
        return invoices.first()

    @property
    def objective(self):
        """Return processed payment objective."""
        if self.processor:
            return get_processor_objective(self.processor)
        else:
            return ''
    objective.fget.short_description = _('Objective')  # type: ignore

    @classmethod
    def objective_choices(self):
        """Return payment processor default objectives choices."""
        choices = BLANK_CHOICE_DASH.copy()
        for proc_name in SETTINGS.processors:
            proc = get_processor_instance(proc_name)
            choices.append((proc_name, proc.default_objective))
        return choices

    @classmethod
    def from_payment_data_class(cls, payment: Payment):
        """Convert Payment data class from teller to Django model."""
        result = cls(identifier=payment.identifier,
                     transaction_date=payment.transaction_date,
                     counter_account_number=cls._value_or_blank(payment.counter_account),
                     counter_account_name=cls._value_or_blank(payment.name),
                     amount=payment.amount,
                     description=cls._value_or_blank(payment.description),
                     constant_symbol=cls._value_or_blank(payment.constant_symbol),
                     variable_symbol=cls._value_or_blank(payment.variable_symbol),
                     specific_symbol=cls._value_or_blank(payment.specific_symbol))
        return result

    @staticmethod
    def _value_or_blank(value: Optional[str]) -> str:
        return '' if value is None else value
Beispiel #22
0
class ModelWithVanillaMoneyField(models.Model):
    money = MoneyField(max_digits=10, decimal_places=2)
    second_money = MoneyField(max_digits=10,
                              decimal_places=2,
                              default_currency='EUR')
    integer = models.IntegerField(default=0)
Beispiel #23
0
class Offer(models.Model):
    application_id = models.DecimalField(verbose_name="application_id",
                                         max_digits=100,
                                         decimal_places=0,
                                         primary_key=True)

    nr = models.CharField(verbose_name="number",
                          max_length=100,
                          blank=True,
                          null=True)
    title = models.CharField(verbose_name="title",
                             max_length=255,
                             blank=True,
                             null=True)
    status = models.CharField(verbose_name='Status',
                              max_length=255,
                              choices=ENTSCHEIDUNG_STATUS,
                              default='Betätigt')

    contact_reference = models.ForeignKey(to=Contact,
                                          related_name='offers',
                                          on_delete=models.CASCADE)
    contact = models.CharField(verbose_name="contact",
                               max_length=255,
                               blank=True,
                               null=True)
    contact_number = models.CharField(verbose_name="contact_number",
                                      max_length=255,
                                      blank=True,
                                      null=True)

    project = models.CharField(verbose_name="project",
                               max_length=100,
                               blank=True,
                               null=True)
    contact_person_name = models.CharField(verbose_name="contact_person_name",
                                           max_length=100,
                                           blank=True,
                                           null=True)
    seller = models.CharField(verbose_name='seller',
                              max_length=100,
                              blank=True,
                              null=True)

    currency = models.CharField(verbose_name="currency",
                                max_length=100,
                                blank=True,
                                null=True)
    net_amount = MoneyField(verbose_name="net_amount",
                            max_digits=14,
                            decimal_places=2,
                            default_currency='CHF')
    gross_amount = MoneyField(verbose_name="gross_amount",
                              max_digits=14,
                              decimal_places=2,
                              default_currency='CHF')

    date = models.DateField(verbose_name="date", blank=True, null=True)
    due_date = models.DateField(verbose_name="due_date", blank=True, null=True)

    bank_account = models.CharField(verbose_name='bank_account',
                                    max_length=255,
                                    blank=True,
                                    null=True)

    created = models.DateTimeField(auto_now_add=True, null=True)
    updated = models.DateTimeField(auto_now=True, null=True)

    def __str__(self):
        return f"{self.application_id}: {self.title} - {self.status}" if self.title is not None else f"{self.application_id}: {self.status}"
Beispiel #24
0
class ModelWithDefaultAsStringWithCurrency(models.Model):
    money = MoneyField(default='123 USD', max_digits=10, decimal_places=2)

    class Meta:
        verbose_name = 'model_default_string_currency'
Beispiel #25
0
class Listing(models.Model):
    title = models.CharField(max_length=100, verbose_name=_('Title'))
    slug = models.SlugField(max_length=100,
                            unique=True,
                            blank=False,
                            verbose_name=_('Slug'))
    description = models.TextField(verbose_name=_('Description'),
                                   null=True,
                                   blank=True)
    price = MoneyField(default=Money(0, USD),
                       max_digits=12,
                       decimal_places=2,
                       verbose_name=_('Price'))
    location = models.ForeignKey(Location, null=True, blank=True)
    type = models.CharField(_('Listing Type'), max_length=30, choices=TYPES)
    offer = models.CharField(max_length=10,
                             choices=OFFERS,
                             verbose_name=_('Offer'))
    active = models.BooleanField(_('Active'), default=False)
    featured = models.BooleanField(default=False, verbose_name=_('Featured'))
    baths = models.PositiveIntegerField(_('Bathrooms'),
                                        default=0,
                                        null=True,
                                        blank=True)
    beds = models.PositiveIntegerField(_('Bedrooms'),
                                       default=0,
                                       null=True,
                                       blank=True)
    size = models.PositiveIntegerField(_('Size(m2)'),
                                       default=0,
                                       null=True,
                                       blank=True)
    coords = models.CharField(max_length=255,
                              default='19.000000,-70.400000',
                              verbose_name=_('Coords'),
                              null=True,
                              blank=True)
    agent = models.ForeignKey(Agent,
                              null=True,
                              blank=True,
                              verbose_name=_('Agent'))
    contact = models.ForeignKey(Contact, null=True, blank=True)
    notes = models.TextField(max_length=500,
                             verbose_name=_('Private Notes'),
                             null=True,
                             blank=True)
    created_at = models.DateTimeField(auto_now_add=True,
                                      verbose_name=_('Created'))
    last_modified = models.DateTimeField(auto_now=True,
                                         verbose_name=_('Last Modified'))

    objects = ListingManager()

    @property
    def main_image(self):
        im = self.images.all()
        if im.count():
            return im[0]
        return None

    @property
    def image_list(self):
        return [{
            'title': image.name,
            'url': image.absolute_url,
            'order': image.order
        } for image in self.images.all()]

    @property
    def address(self):
        return self.get_address()

    def get_address(self):
        if self.location is None:
            return _('No location provided')
        return self.location

    def __unicode__(self):
        return self.title

    class Meta:
        verbose_name = _('Listing')
        verbose_name_plural = _('Listings')
        ordering = [
            '-pk',
        ]

    def save(self, **kwargs):
        self._generate_valid_slug()
        super(Listing, self).save(**kwargs)

    def _generate_valid_slug(self):
        if not self.is_valid_slug():
            slug = slugify(self.title)
            while Listing.objects.filter(slug=slug).exclude(
                    id=self.id).exists():
                slug_parts = slug.split('-')
                if slug_parts[-1].isdigit():
                    slug_parts[-1] = '%s' % (int(slug_parts[-1]) + 1)
                else:
                    slug_parts.append('2')
                slug = '-'.join(slug_parts)
            self.slug = slug

    def is_valid_slug(self):
        if self.slug is None or len(self.slug) < 10:
            return False
        match = re.match('[^\w\s-]', self.slug)
        if not match:
            return False
        return self.slug == slugify(self.slug)

    @property
    def absolute_url(self):
        return self.get_absolute_url()

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

    def get_features(self):
        attributes = []
        for attribute in self.attributelisting_set.all():
            attribute_name = _(attribute.attribute.name)
            if attribute.attribute.validation == 'realestate.listing.utils.validation_simple':
                attributes.append('{0}: {1}'.format(attribute_name,
                                                    attribute.value))
            elif attribute.attribute.validation == 'realestate.listing.utils.validation_yesno':
                attributes.append(attribute_name)
            else:
                if attribute.attribute.validation == 'realestate.listing.utils.validation_integer':
                    attributes.append('{0} {1}'.format(attribute.value,
                                                       attribute_name))
                else:
                    attributes.append('{0:.2f} {1}'.format(
                        Decimal(attribute.value), attribute_name))

        return attributes

    @property
    def nearby(self):
        return Listing.objects.active(location=self.location).exclude(
            id=self.id).order_by('?')

    @property
    def has_baths_or_beds(self):
        return self.should_have_beds or self.should_have_baths

    @property
    def suggested(self):
        qs = Listing.objects.active(type=self.type)

        price = self.price
        lh = price * .90
        rh = price * 1.10

        if self.has_baths_or_beds:
            if self.should_have_baths:
                qs = qs.filter(baths=self.baths)
            if self.should_have_beds:
                qs = qs.filter(beds=self.beds)

            if qs.count() == 0:
                qs = Listing.objects.active(type=self.type,
                                            price__range=(lh, rh))
        else:
            qs = qs.filter(price__range=(lh, rh))

        return qs.exclude(id=self.id).order_by('?')

    @property
    def should_have_beds(self):
        return self.type in (
            'house',
            'penthouse',
            'apartment',
            'villa',
        )

    @property
    def should_have_baths(self):
        return 'land' not in self.type

    @property
    def on_sale(self):
        return Deal.objects.on_sale(listing__in=(self, )).exists()

    @property
    def code(self):
        if self.agent is not None:
            agent = self.agent
            prefix = '{0}{1}'.format(agent.first_name[0], agent.last_name[0])
            return '{0}{1:04}'.format(prefix, self.id).upper()

        rent_or_sale = 'v' if self.offer in ('buy-rent', 'buy') else 'r'
        return '{0}{1:04x}'.format(rent_or_sale, self.id).upper()
Beispiel #26
0
class ModelWithDefaultAsFloat(models.Model):
    money = MoneyField(default=12.05,
                       max_digits=10,
                       decimal_places=2,
                       default_currency='PLN')
Beispiel #27
0
class ModelWithDefaultAsInt(models.Model):
    money = MoneyField(default=123, max_digits=10, decimal_places=2, default_currency='GHS')
Beispiel #28
0
class ModelWithDefaultAsDecimal(models.Model):
    money = MoneyField(default=Decimal('0.01'),
                       max_digits=10,
                       decimal_places=2,
                       default_currency='CHF')
Beispiel #29
0
class ModelWithDefaultAsString(models.Model):
    money = MoneyField(default='123', max_digits=10, decimal_places=2, default_currency='PLN')
Beispiel #30
0
class Membership(models.Model):
    """
    Organization memberships.

    Pending:
      In discussion that we really confident will lead to membership
    Out of signatures:
      Agreement has been sent out for signatures (membership eminent)
    Active:
      Agreement has been signed and term of agreement has started
    Dormant:
      Agreement has been signed but term of agreement has not started
    Expired:
      Term of agreement has ended
    Lead:
      Interest in membership has been expressed, but an agreement may or
    may not be likely
    Stale:
      At one point was pending or lead, but a membership does now not
    seem likely
    """
    PENDING = 'PD'
    OUT4SIGNATURES = 'OS'
    ACTIVE = 'AC'
    DORMANT = 'DT'
    EXPIRED = 'EX'
    LEAD = 'LD'
    STALE = 'ST'

    STATUS_CHOICES = (
        (PENDING, 'Pending'),
        (OUT4SIGNATURES, 'Out for Signatures'),
        (ACTIVE, 'Active'),
        (DORMANT, 'Dormant'),
        (EXPIRED, 'Expired'),
        (LEAD, 'Lead'),
        (STALE, 'Stale'),
    )

    NEW = 'N'
    RENEWAL = 'R'
    OTHER = 'O'

    NEW_RENEW_CHOICES = ((NEW, 'New'), (RENEWAL, 'Renewal'), (OTHER, 'Other'))

    PAID = 'PD'
    SENT = 'ST'
    REQUESTED = 'RQ'
    NOT_READY = 'NR'
    NUMFOCUS = 'NF'

    INVOICE_REQUEST = (
        (PAID, 'Paid'),
        (SENT, 'Sent'),
        (REQUESTED, 'Requested'),
        (NOT_READY, 'Not ready to request'),
        (NUMFOCUS, 'Request from NumFOCUS'),
    )

    COMPLETE = 'CP'
    SCHEDULED = 'SD'
    # PENDING = 'PD' Already defined
    SCHINPROGRESS = 'SP'

    EVENT_STATUS = ((COMPLETE, 'Complete'), (SCHEDULED, 'Scheduled'),
                    (PENDING, 'Pending'), (SCHINPROGRESS,
                                           'Scheduling in Progress'))

    organization = models.ForeignKey(Organization,
                                     on_delete=models.CASCADE,
                                     help_text='Long form name of member')
    member_type = models.ForeignKey(Term,
                                    on_delete=models.CASCADE,
                                    help_text='Type of membership')
    status = models.CharField('Status',
                              max_length=2,
                              choices=STATUS_CHOICES,
                              default=LEAD,
                              help_text='Current status of membership')
    new_renew = models.CharField(
        'New or renew?',
        max_length=1,
        choices=NEW_RENEW_CHOICES,
        default=NEW,
        help_text='Is it a new membership or is it a renewal?')
    hubspot = models.URLField('Hubspot link',
                              help_text='Hubspot link to member',
                              blank=True,
                              null=True)
    annual_fee = MoneyField('Annual fee',
                            max_digits=10,
                            decimal_places=2,
                            default_currency='USD',
                            help_text='Annual Fee paid in USD')
    paid_in_full = models.BooleanField(
        'Paid in full?',
        help_text='Did they pay all their membership up-front?')
    # term calculated field: expires - start_date in years
    start_date = models.DateField(
        'Starting date', help_text='The starting date for the membership')
    expires = models.DateField(
        'Expiring date',
        help_text='Calculated as start date plus membership term duration')
    agreement = models.URLField(
        'Agreement Github link',
        help_text='GitHub repo link for agreement text',
        blank=True,
        null=True)
    invoice_request = models.CharField('Invoice request',
                                       max_length=2,
                                       choices=INVOICE_REQUEST,
                                       help_text='Status of invoice',
                                       blank=True,
                                       null=True)
    event_status = models.CharField(
        'Event status',
        max_length=2,
        choices=EVENT_STATUS,
        default=PENDING,
        help_text='Have we held instructor training for them yet?',
        blank=True,
        null=True)
    event = models.URLField('Event',
                            help_text='URLs in AMY for Training event',
                            blank=True,
                            null=True)
    notes = GenericRelation(Note)

    def __str__(self):
        return "{} {} {}".format(self.organization, self.member_type,
                                 self.status)