def test_prep_value(self): """ Tests correct db storage value against different setting of PHONENUMBER_DB_FORMAT Required output format is set as string constant to guarantee consistent database storage values """ number = PhoneNumberField() for frmt in ["E164", "RFC3966", "INTERNATIONAL"]: with override_settings(PHONENUMBER_DB_FORMAT=frmt): self.assertEqual( number.get_prep_value(to_python(self.storage_numbers[frmt][0])), self.storage_numbers[frmt][1], )
def test_prep_value(self): ''' Tests correct db storage value against different setting of PHONENUMBER_DB_FORMAT Required output format is set as string constant to guarantee consistent database storage values ''' number = PhoneNumberField() old_format = getattr(settings, 'PHONENUMBER_DB_FORMAT', 'E164') for frmt in ['E164', 'RFC3966', 'INTERNATIONAL']: setattr(settings, 'PHONENUMBER_DB_FORMAT', frmt) self.assertEqual( number.get_prep_value( to_python(self.storage_numbers[frmt][0]) ), self.storage_numbers[frmt][1]) setattr(settings, 'PHONENUMBER_DB_FORMAT', old_format)
class User(AbstractUser): department = models.ForeignKey(Department,on_delete=models.CASCADE, null=True, blank=True) contact_no = PhoneNumberField(null=True, blank=True) profile_pic = models.ImageField(upload_to ='media/user/',null=True, blank=True) role = models.ForeignKey(Role,on_delete=models.CASCADE, null=True, blank=True)
class User(AbstractBaseUser, PermissionsMixin): """ Partaj users are expected to authenticate themselves through Cerbère, an identity provider that uses CAS/SAML to interoperate with applications. """ # Generic fields to build up minimal data on any user id = models.UUIDField( verbose_name=_("id"), help_text=_("Primary key for the user as UUID"), primary_key=True, default=uuid.uuid4, editable=False, ) date_joined = models.DateTimeField(verbose_name=_("created at"), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_("updated at"), auto_now=True) is_active = models.BooleanField( verbose_name=_("active"), help_text=_( "Designates whether this user should be treated as active. " "Unselect this instead of deleting accounts." ), default=True, ) is_staff = models.BooleanField( verbose_name=_("staff status"), help_text=_("Designates whether the user can log into this admin site."), default=False, ) # Information we can pick up from our identity provider username = models.CharField( verbose_name=_("username"), help_text=_("unique human readable username"), # ==email for Cerbère users max_length=255, unique=True, ) first_name = models.CharField( verbose_name=_("first name"), max_length=255, blank=True ) last_name = models.CharField( verbose_name=_("last name"), max_length=255, blank=True ) email = models.EmailField(verbose_name=_("email"), max_length=255, unique=True) phone_number = PhoneNumberField( verbose_name=_("phone number"), help_text=_("Phone number for this user"), blank=True, ) unit_name = models.CharField( verbose_name=_("unit name"), max_length=255, blank=True ) title = models.CharField(verbose_name=_("title"), max_length=255, blank=True) objects = UserManager() USERNAME_FIELD = "username" REQUIRED_FIELDS = ["email"] def __str__(self): """ String representation of a user, for internal purposes. """ return f"{self._meta.verbose_name.title()} <{self.username}>" def get_full_name(self): """ Get a string showing a user's full name. Avoid doing random concatenation throughout the app and get a consistent name for our user. """ return f"{self.first_name} {self.last_name}" class Meta: db_table = "partaj_user" verbose_name = _("user")
class Customers(AbstractBaseUser): email = models.EmailField(verbose_name="email", max_length=70, unique=True) username = models.CharField(max_length=30) company_name = models.CharField("Business Legal Name", max_length=30) first_name = models.CharField("Company Owner's First Name", max_length=30) last_name = models.CharField("Company Owner's Last Name", max_length=30) stripe_customer = models.CharField(max_length=150) ein = models.CharField(verbose_name="Tax Payer Number", max_length=15, blank=True, null=True, unique=True) ein_verified = models.BooleanField(verbose_name="TPN Verified?", default=False) phone = PhoneNumberField(null=False, blank=False) date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True) last_login = models.DateTimeField(verbose_name='last login', auto_now=True) user_permissions = models.ManyToManyField(Permission, blank=True) groups = models.ManyToManyField(Group, blank=True) is_admin = models.BooleanField(default=False) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) is_superuser = models.BooleanField(default=False) USERNAME_FIELD = 'email' EMAIL_FIELD = 'email' REQUIRED_FIELDS = [] objects = CustomersManager() def __str__(self): return self.email def has_perm(self, perm, obj=None): return self.is_admin def has_module_perms(self, app_label): return True class Meta: verbose_name = "customer" verbose_name_plural = "customers" ordering = ("date_joined", ) def get_full_name(self): ''' Returns the first_name plus the last_name, with a space in between. ''' full_name = '%s %s' % (self.first_name, self.last_name) return full_name.strip() def get_short_name(self): ''' Returns the short name for the user. ''' return self.first_name def get_legal_name(self): ''' Returns the short name for the user. ''' return self.company_name def email_customer(self, subject, message, from_email=None, **kwargs): ''' Sends an email to this User. ''' from django.core.mail import send_mail send_mail(subject, message, from_email, [self.email], **kwargs)
class Group(models.Model): name = models.CharField(max_length=64, null=True, blank=False, verbose_name="Group Name") slug = models.SlugField(null=True, blank=False, unique=True, max_length=100) signup_date = models.DateTimeField(null=True, blank=True, auto_now_add=True) group_id = models.CharField(max_length=4, null=True, blank=False) rep_email = models.EmailField(null=True, blank=False, verbose_name="Contact Email", max_length=254) rep_first_name = models.CharField(max_length=35, null=True, blank=False, verbose_name="First Name") rep_last_name = models.CharField(max_length=35, null=True, blank=False, verbose_name="Last Name") rep_postal_code = models.CharField(max_length=12, null=True, blank=True, verbose_name="Postal Code") rep_phone = PhoneNumberField(null=True, blank=True, verbose_name="Phone Number") county = models.CharField(max_length=64, null=True, blank=True) city = models.CharField(max_length=64, null=True, blank=True) state = USStateField(max_length=2, null=True, blank=True) postal_code = models.CharField(max_length=12, null=True, blank=False, verbose_name="Postal Code") country = CountryField(null=True, blank=False, default="US") point = PointField(null=True, blank=True) size = models.CharField(max_length=21, null=True, blank=True, verbose_name="Group Size") last_meeting = models.DateTimeField(null=True, blank=True, verbose_name="Date of Last Meeting") recurring_meeting = RecurrenceField(null=True, blank=True, verbose_name="Recurring Meeting") meeting_address_line1 = models.CharField("Address Line 1", max_length=45, null=True, blank=True) meeting_address_line2 = models.CharField("Address Line 2", max_length=45, null=True, blank=True) meeting_postal_code = models.CharField("Postal Code", max_length=12, null=True, blank=True) meeting_city = models.CharField(max_length=64, null=True, blank=True, verbose_name="City") meeting_state_province = models.CharField("State/Province", max_length=40, null=True, blank=True) meeting_country = CountryField(null=True, blank=True, verbose_name="Country", default='US') TYPES_OF_ORGANIZING_CHOICES = ( ('direct-action', 'Direct Action'), ('electoral', 'Electoral Organizing'), ('legistlative', 'Advocating for Legislation or Ballot Measures'), ('community', 'Community Organizing'), ('other', 'Other')) types_of_organizing = MultiSelectField(null=True, blank=True, choices=TYPES_OF_ORGANIZING_CHOICES, verbose_name="Types of Organizing") other_types_of_organizing = models.TextField( null=True, blank=True, verbose_name="Other Types of Organizing", max_length=250) description = models.TextField( null=True, blank=False, max_length=250, verbose_name="Description (250 characters or less)") issues = models.ManyToManyField(Issue, blank=True) other_issues = models.TextField(null=True, blank=True, max_length=250, verbose_name="Other Issues") constituency = models.TextField(null=True, blank=True, max_length=250) facebook_url = models.URLField(null=True, blank=True, verbose_name="Facebook URL", max_length=255) twitter_url = models.URLField(null=True, blank=True, verbose_name="Twitter URL", max_length=255) website_url = models.URLField(null=True, blank=True, verbose_name="Website URL", max_length=255) instagram_url = models.URLField(null=True, blank=True, verbose_name="Instagram URL", max_length=255) other_social = models.TextField(null=True, blank=True, verbose_name="Other Social Media", max_length=250) STATUSES = ( ('submitted', 'Submitted'), ('signed-mou', 'Signed MOU'), ('approved', 'Approved'), ('removed', 'Removed') # can flesh out later ) status = models.CharField(max_length=16, choices=STATUSES, default='submitted') # source = models.CharField(max_length=17, null=True, blank=True) # subsource = models.FloatField(null=True, blank=True) # i_p__address = models.CharField(max_length=16, null=True, blank=True) # constituent__id = models.IntegerField(null=True, blank=True) # signup__id = models.IntegerField(null=True, blank=True) def __unicode__(self): return self.name
class OptionalPhoneNumber(models.Model): phone_number = PhoneNumberField(blank=True, default='')
class Contact(models.Model): name = models.CharField(max_length=100) email = models.EmailField() phoneNumber = PhoneNumberField() message = models.TextField() submitted = models.DateTimeField(auto_now_add=True)
class Customer(models.Model): """ This model stores customers i.e. people who sign up to user APR """ DAY = 1 WEEK = 2 MONTH = 3 YEAR = 4 TIME_UNIT_CHOICES = [ (DAY, _("Day")), (WEEK, _("Week")), (MONTH, _("Month")), (YEAR, _("Year")), ] WEEKDAYS = 7 MONTHDAYS = 30.44 YEARDAYS = 365.25 SHOW_CLIENT_NAME = '1' SHOW_CLIENT_PHONE = '2' SHOW_CLIENT_EMAIL = '3' SHOW_CLIENT_ID = '4' SHOW_CLIENT_NAME_AND_ID = '5' SHOW_CLIENT_NAME_PHONE_AND_ID = '6' SHOW_APPOINTMENT_TITLE = '7' CLIENT_DISPLAY_CHOICES = ( (SHOW_CLIENT_NAME, _('Client Name')), (SHOW_CLIENT_PHONE, _('Client Phone')), (SHOW_CLIENT_EMAIL, _('Client Email')), (SHOW_CLIENT_ID, _('Client ID')), (SHOW_CLIENT_NAME_AND_ID, _('Client Name & Client ID')), (SHOW_CLIENT_NAME_PHONE_AND_ID, _('Client Name, Client Phone & Client ID')), (SHOW_APPOINTMENT_TITLE, _('Appointment Title')), ) NUMBER_OF_DAYS_CHOICES = [(x, "{}".format(x)) for x in range(1, 8)] user = models.ForeignKey( User, verbose_name=_("User"), null=True, default=None, blank=True, on_delete=models.PROTECT, help_text=_("This user will be able to log in as this customer")) created_on = models.DateTimeField(_("Created on"), auto_now_add=True) updated_on = models.DateTimeField(_("Updated on"), auto_now=True) name = models.CharField(_('Customer name'), max_length=255, blank=False) email = models.EmailField(_('Email address'), blank=True) phone = PhoneNumberField(_('Phone Number'), max_length=255, blank=True) is_active = models.BooleanField( _('Active'), default=True, help_text=_('Designates whether this customer should be treated as ' 'active.')) shown_days = models.PositiveIntegerField( _("Number of days to show in main calendar"), choices=NUMBER_OF_DAYS_CHOICES, default=6) allow_overlap = models.BooleanField( _("Allow appointment overlap"), default=False, help_text=_( "Should we allow two or more appointments at the same time?")) send_sms = models.BooleanField( _("SMS reminder"), default=True, help_text=_("Should we send reminders by text message (SMS)?")) send_email = models.BooleanField( _("Email reminder"), default=True, help_text=_("Should we send reminders by email?")) # reminder stuff custom_reminder = models.BooleanField( _("Use custom script"), default=False, help_text= _("If you check this, we will use the custom script provided by you below. Leave it blank to use the system default." )) reminder_sender = models.EmailField( _("Reminder from address"), blank=False, default=settings.REMINDER_FROM_EMAIL_ONLY) reminder_subject = models.CharField( _("Reminder subject line"), max_length=100, blank=False, default= _("Reminder Appointment with $OUR_NAME at $APPOINTMENT_DATE from $APPOINTMENT_START_TIME" )) reminder_email = models.TextField( _("Reminder email message"), blank=False, default= _("We wanted to remind you that you have an appointment at $OUR_NAME on $APPOINTMENT_DATE from $APPOINTMENT_START_TIME. Please be on time." )) reminder_sms = models.CharField( _("Reminder SMS message"), max_length=255, blank=False, default= _("Reminder! Appointment with $OUR_NAME on $APPOINTMENT_DATE from $APPOINTMENT_START_TIME" )) show_confirm_link = models.BooleanField( _("Show a link to confirm appointment"), default=True, blank=False) show_cancel_link = models.BooleanField( _("Show a link to cancel appointment"), default=True, blank=False) # client display client_display = models.CharField( _("Client Display"), max_length=1, choices=CLIENT_DISPLAY_CHOICES, blank=False, default=SHOW_CLIENT_NAME, help_text=_("How should the client be represented in the calendar?")) # greetings birthday_greeting_active = models.BooleanField( _("Activate birthday greetings"), help_text=_( "Birthday greetings are sent to clients on their birth days"), default=False) birthday_greeting_sender = models.EmailField( _("Birthday greeting from address"), blank=False, default=settings.REMINDER_FROM_EMAIL_ONLY) birthday_greeting_subject = models.CharField( _("Birthday greeting subject line"), max_length=100, blank=False, default=_("Happy Birthday, $FIRST_NAME")) birthday_greeting_email = models.TextField( _("Birthday greeting email message"), blank=False, default= _("We are thinking of you on this important day and hope that it is filled with happiness. Wishing you many joyous years ahead!" )) birthday_greeting_sms = models.CharField( _("Birthday greeting SMS message"), max_length=255, blank=False, default= _("Happy Birthday! Wishing you all the best today and always! $OUR_NAME" )) birthday_greeting_send_email = models.BooleanField( _("Birthday greeting send email"), default=True) birthday_greeting_send_sms = models.BooleanField( _("Birthday greeting send SMS"), default=True) # Rebooking rebooking_active = models.BooleanField( _("Activate Rebooking"), help_text= _("These are booking reminders which are sent to clients a while after their last appointment to encourage them to book a new appointment" ), default=False) rebooking_period = models.PositiveIntegerField( _("Rebooking period length"), blank=True, default=6) rebooking_period_unit = models.PositiveIntegerField( _("Rebooking period units"), choices=TIME_UNIT_CHOICES, default=MONTH) rebooking_sender = models.EmailField( _("Rebooking from address"), blank=False, default=settings.REMINDER_FROM_EMAIL_ONLY) rebooking_subject = models.CharField(_("Rebooking subject line"), max_length=100, blank=False, default=_("$FIRST_NAME, we miss you")) rebooking_email = models.TextField( _("Rebooking email message"), blank=False, default= _("We wanted to remind you that your next appointment is due soon. Feel free to call us on $OUR_PHONE to book an appointment." )) rebooking_sms = models.CharField( _("Rebooking SMS message"), max_length=255, blank=False, default= _("Your next appointment with $OUR_NAME is due soon. Call $OUR_PHONE to book." )) rebooking_send_email = models.BooleanField(_("Rebooking send email"), default=True) rebooking_send_sms = models.BooleanField(_("Rebooking send SMS"), default=True) use_tags = models.BooleanField( _("Use Tags"), default=False, help_text=_("Tags are used to classify appointments")) use_four_day = models.BooleanField(_("Activate Three-day View"), default=False) use_no_background_print = models.BooleanField( _("No background color on print"), default=False) time_slot_height = models.IntegerField( _("Time Slot Height"), default=25, help_text= _('The height of each timeslot in pixels. Calendar event text is scaled relative to the timeslot height.' )) time_slots_per_hour = models.IntegerField( _("Time Slots Per Hour"), default=4, help_text=_( "The number of timeslots that will be available within an hour.")) class Meta: verbose_name = _("Customer") verbose_name_plural = _("Customers") ordering = ['name'] def __unicode__(self): return self.name def meta(self): return self._meta def global_opening_time(self): """ returns the customer's opening time object with earliest from_hour """ return self.openinghour_set.exclude(from_hour=None).exclude( to_hour=None).exclude( venue__main_calendar=False).order_by('from_hour').first() def global_closing_time(self): """ returns the customer's closing time object with latest to_hour """ return self.openinghour_set.exclude(from_hour=None).exclude( to_hour=None).exclude( venue__main_calendar=False).order_by('to_hour').last() def has_subscription(self): return customer_has_subscription(self) def number_of_venues(self): return self.venue_set.all().count() def is_new(self): return (timezone.now() - self.created_on) < timedelta(days=3)
class User(AbstractBaseUser, PermissionsMixin): username = models.CharField(unique=True, db_index=True, max_length=100, verbose_name='Username') email = models.EmailField(blank=True, null=True, unique=True, db_index=True, verbose_name='Email') first_name = models.CharField(null=True, blank=True, max_length=200, verbose_name='First name') last_name = models.CharField(null=True, blank=True, max_length=200, verbose_name='Last name') birth_date = models.DateField(blank=True, null=True, verbose_name='Birth Date') phone = PhoneNumberField(blank=True, null=True, verbose_name='Phone Number') country = CountryField(default=settings.DEFAULT_COUNTRY, verbose_name='Countries') is_staff = models.BooleanField(default=False, verbose_name='Is Staff ?') is_active = models.BooleanField(default=False, verbose_name='Is Activated ?') activation_key = models.UUIDField(unique=True, default=uuid4, editable=False, verbose_name='Activation Key') date_joined = models.DateTimeField(auto_now_add=True, editable=False, verbose_name='Date of inscription') date_update = models.DateTimeField(auto_now_add=True, verbose_name='Date Updated') user_condition_is_read = models.BooleanField( default=False, verbose_name='User conditions is read ?') profile_picture = models.ImageField(upload_to="photo_user/", null=True, blank=True, verbose_name='Profile Picture') USERNAME_FIELD = 'username' REQUIRED_FIELDS = [] objects = UserManager() class Meta: app_label = 'account' verbose_name = 'User' verbose_name_plural = 'Users' def __str__(self): return self.username def get_full_name(self): if self.first_name or self.last_name: full_name = "%s %s" % (self.first_name, self.last_name) return full_name.strip() if self.email: return self.email return self.username
class Account(models.Model): ACCOUNT_STATUS_CHOICE = (("open", "Open"), ("close", "Close")) name = models.CharField(pgettext_lazy( "Name of Account", "Name"), max_length=64) email = models.EmailField() phone = PhoneNumberField(null=True) industry = models.CharField( _("Industry Type"), max_length=255, choices=INDCHOICES, blank=True, null=True ) # billing_address = models.ForeignKey( # Address, related_name='account_billing_address', on_delete=models.CASCADE, blank=True, null=True) # shipping_address = models.ForeignKey( # Address, related_name='account_shipping_address', on_delete=models.CASCADE, blank=True, null=True) billing_address_line = models.CharField( _("Address"), max_length=255, blank=True, null=True ) billing_street = models.CharField( _("Street"), max_length=55, blank=True, null=True) billing_city = models.CharField( _("City"), max_length=255, blank=True, null=True) billing_state = models.CharField( _("State"), max_length=255, blank=True, null=True) billing_postcode = models.CharField( _("Post/Zip-code"), max_length=64, blank=True, null=True ) billing_country = models.CharField( max_length=3, choices=COUNTRIES, blank=True, null=True ) website = models.URLField(_("Website"), blank=True, null=True) description = models.TextField(blank=True, null=True) created_by = models.ForeignKey( Profile, related_name="account_created_by", on_delete=models.SET_NULL, null=True ) created_on = models.DateTimeField(_("Created on"), auto_now_add=True) is_active = models.BooleanField(default=False) tags = models.ManyToManyField(Tags, blank=True) status = models.CharField( choices=ACCOUNT_STATUS_CHOICE, max_length=64, default="open" ) lead = models.ForeignKey( "leads.Lead", related_name="account_leads", on_delete=models.SET_NULL, null=True ) contact_name = models.CharField( pgettext_lazy("Name of Contact", "Contact Name"), max_length=120 ) contacts = models.ManyToManyField( "contacts.Contact", related_name="account_contacts" ) assigned_to = models.ManyToManyField( Profile, related_name="account_assigned_users") teams = models.ManyToManyField(Teams, related_name="account_teams") org = models.ForeignKey( Org, on_delete=models.SET_NULL, null=True, blank=True, related_name="account_org" ) class Meta: ordering = ["-created_on"] def __str__(self): return self.name def get_complete_address(self): """Concatenates complete address.""" address = "" add_to_address = [ self.billing_street, self.billing_city, self.billing_state, self.billing_postcode, self.get_billing_country_display(), ] address = utils.append_str_to(address, *add_to_address) return address @property def created_on_arrow(self): return arrow.get(self.created_on).humanize() @property def contact_values(self): contacts = list(self.contacts.values_list("id", flat=True)) return ",".join(str(contact) for contact in contacts) @property def get_team_users(self): team_user_ids = list(self.teams.values_list("users__id", flat=True)) return Profile.objects.filter(id__in=team_user_ids) @property def get_team_and_assigned_users(self): team_user_ids = list(self.teams.values_list("users__id", flat=True)) assigned_user_ids = list(self.assigned_to.values_list("id", flat=True)) user_ids = team_user_ids + assigned_user_ids return Profile.objects.filter(id__in=user_ids) @property def get_assigned_users_not_in_teams(self): team_user_ids = list(self.teams.values_list("users__id", flat=True)) assigned_user_ids = list(self.assigned_to.values_list("id", flat=True)) user_ids = set(assigned_user_ids) - set(team_user_ids) return Profile.objects.filter(id__in=list(user_ids))
class User(AbstractUser): _ADMINISTRATOR = _('administrator') _FACILITATOR = _('facilitator') _RESPONDENT = _('respondent') uuid = models.UUIDField( _('UUID'), default=uuid.uuid4, editable=False, unique=True ) avatar = models.ImageField( _('profile picture'), blank=True, null=True, upload_to='users/avatars' ) avatar_thumbnail = ImageSpecField( source='avatar', processors=[ResizeToFit(100, 100)], format='PNG', options={'quality': 100} ) avatar_sm = ImageSpecField( source='avatar', processors=[ResizeToFit(50, 50)], format='PNG', options={'quality': 100} ) phone_number = PhoneNumberField(_('phone number'), blank=True) gender = models.ForeignKey( 'users.Gender', blank=True, null=True, limit_choices_to={'is_primary': True}, related_name='users', related_query_name='user', on_delete=models.SET_NULL, verbose_name=_('gender') ) country = CountryField(_('country'), blank=True) address = models.TextField(_('address'), blank=True) is_facilitator = models.BooleanField(_('is facilitator'), default=False) is_respondent = models.BooleanField(_('is respondent'), default=False) def save(self, *args, **kwargs): if not self.is_superuser and not self.is_staff and not self.is_facilitator: self.is_respondent = True super().save(*args, **kwargs) @property def user_type(self): titles = [] # NOTE: Calling str() on translatable/proxy string so that they can be joined as normal strings. if self.is_staff: titles.append(str(self._ADMINISTRATOR)) if self.is_facilitator: titles.append(str(self._FACILITATOR)) if self.is_respondent: titles.append(str(self._RESPONDENT)) return ', '.join(titles)
class User(AbstractBaseUser): """ Replacing the base user model - switch to using email as username """ username = models.CharField(verbose_name='user name', max_length=80, unique=True, db_index=True) email = models.EmailField(verbose_name='email address', max_length=255, unique=True, db_index=True) first_name = models.CharField(max_length=50, blank=True) last_name = models.CharField(max_length=50, blank=True) medicare_connected = models.BooleanField(default=False) medicare_verified = models.BooleanField(default=False) # Done: modify joined to date_joined in user model date_joined = models.DateTimeField(auto_now_add=True) is_active = models.BooleanField(default=False) is_admin = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) is_superuser = models.BooleanField(default=False) # DONE: Add Activity Notification notify_activity = models.CharField(max_length=1, default="N", choices=ACTIVITY_NOTIFY_CHOICES, verbose_name="Notify Account Activity") # DONE: Add mobile number and carrier mobile = PhoneNumberField(blank=True) carrier = models.CharField( max_length=100, blank=True, default="None", choices=CARRIER_SELECTION, ) # DONE: Add switch for Multi-factor Authentication via mobile mfa = models.BooleanField(default=False, verbose_name='Send Login PIN Code?') verified_mobile = models.BooleanField(default=False) objects = UserManager() #USERNAME_FIELD = 'email' USERNAME_FIELD = 'username' REQUIRED_FIELDS = [ 'email', 'first_name', 'last_name', ] def get_full_name(self): # The user is identified by their username return self.username def get_email(self): # return the email address return self.email def get_real_name(self): # Get first and last name return "%s %s" % (self.first_name, self.last_name) def get_short_name(self): # The user is identified by their username return self.username # def __str__(self): # __unicode__ on Python 2 # return self.email def has_perm(self, perm, obj=None): "Does the user have a specific permission?" # Simplest possible answer: Yes, always return True def has_module_perms(self, app_label): "Does the user have permissions to view the app `app_label`?" # Simplest possible answer: Yes, always return True # @property # def is_staff(self): # "Is the user a member of staff?" # # Simplest possible answer: All admins are staff # return self.is_admin def __str__(self): # __unicode__ on Python 2 # return "%s %s (%s)" % (self.first_name, # self.last_name, # self.email) return str(self.username) def Meta(self): verbose_name = _('User') verbose_name_plural = _('Users')
class UserInfo(models.Model): default_user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) role = models.CharField(default='user_info', max_length=16) phone_number = PhoneNumberField(blank=True, null=True) activated = models.BooleanField(default=False, blank=True, null=True) verified = models.BooleanField(default=False) credit = models.IntegerField(default=0) has_profile_picture = models.BooleanField(default=False) profile_picture = models.ImageField(upload_to='profile_images/main/', blank=True, null=True) profile_thumbnail = models.ImageField(upload_to='profile_images/thumbnail/', blank=True, null=True) def full_name(self): return " ".join([self.default_user.first_name, self.default_user.last_name]) def create_thumbnail(self): if not self.profile_picture or self.profile_picture is None: return True image = Image.open(self.profile_picture.file) w, h = image.size crop_size = min(w, h) image = image.crop(((w-crop_size)//2, (h - crop_size)//2, (w + crop_size) // 2, (h+ crop_size) // 2)) image.thumbnail(size=(256, 256)) image_file = BytesIO() image.save(image_file, 'JPEG') main_name = os.path.basename(self.profile_picture.name) main_name = os.path.splitext(main_name)[0] self.profile_thumbnail.save( main_name + "_thumbnail.jpg", InMemoryUploadedFile( image_file, None, '', 'image/jpeg', image.size, None, ), save=True ) return True def charge(self, amount): amount = int(amount) self.credit = self.credit + amount self.save() def get_profile(self): if self.has_profile_picture and self.profile_picture is not None: return self.profile_picture.url else: return static('img/UserProfileDefault.png') def get_notifications_l5(self): l = list(self.notification_key.all().order_by('-date_created')) return l[:5] def get_notifications(self): return self.notification_key.all().order_by('date_created') def get_unread_notifications(self): return self.notification_key.filter(read=False).order_by('date_created') def get_profile_thumbnail(self): if self.has_profile_picture and self.profile_thumbnail is not None: return self.profile_thumbnail.url else: return static('img/UserProfileDefault.png')
class Order(models.Model): PROCESSED = 'PR' UNPROCESSED = 'UP' STATUS = [ (PROCESSED, 'Обработанный'), (UNPROCESSED, 'Необработанный') ] CASH = 'CH' CART = 'CR' TRANSFER = 'TR' CRYPTOCURRENCY = 'CC' PAYMENT_METHOD = [ (CASH, 'Наличными'), (CART, 'Банковская карта'), (TRANSFER, 'Электронный перевод'), (CRYPTOCURRENCY, 'Криптовалютный перевод'), ] objects = CustomQuerySet.as_manager() firstname = models.CharField(max_length=50, verbose_name='имя') lastname = models.CharField(max_length=50, verbose_name='фамилия') address = models.CharField(max_length=100, verbose_name='адрес') phonenumber = PhoneNumberField(verbose_name='номер телефона') registered_at = models.DateTimeField(default=timezone.now, db_index=True, verbose_name='время рагистрации') updated_at = models.DateTimeField(verbose_name='время звонка', db_index=True, null=True) delivered_at = models.DateTimeField(verbose_name='время доставки', db_index=True, null=True) order_status = models.CharField(max_length=2, choices=STATUS, default=UNPROCESSED, db_index=True, verbose_name='статус заказа') payment_method = models.CharField(max_length=2, choices=PAYMENT_METHOD, db_index=True, blank=True, verbose_name='способ оплаты') restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE, null=True, blank=True, verbose_name='ресторан') comment = models.TextField(max_length=250, verbose_name='комментарии', blank=True) place = models.ForeignKey('Place', on_delete=models.CASCADE, related_name='orders', null=True, blank=True, verbose_name='место на карте') def full_name(self): return '{} {}'.format(self.firstname, self.lastname) class Meta: verbose_name = 'заказ' verbose_name_plural = 'заказы' def get_order_cost(self): return self.details.aggregate(order_cost=Sum('product_price'))['order_cost'] def get_rest_rang(self): rest_range = [] restaurants = Restaurant.objects.all() for rest in restaurants: if self.place: order_coords = self.place.get_coords() rest_coords = rest.get_coords() rest_distance = distance.distance(order_coords, rest_coords).km rest_range.append((rest.name, str(round(rest_distance, 3)) + ' km')) rest_range.sort(key=lambda x: x[1]) else: rest_range.append(['No Geo API data']) rang_of_restrs = map(' - '.join, rest_range) return rang_of_restrs
class Member(models.Model): id = models.UUIDField(primary_key=True, unique=True, editable=False, default=uuid.uuid4) codename = models.CharField(max_length=64, editable=False, null=True) name = models.CharField(default='', max_length=50) notes = models.TextField(default='', blank=True) registered_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) registered_at = models.DateTimeField(auto_now_add=True) language = models.CharField(max_length=5, choices=LANGUAGES, default='en_gb') registered = models.BooleanField(default=False) phone_number = PhoneNumberField(max_length=20, unique=True, null=True, blank=True, help_text="Enter a valid phone number (e.g. 0121 234 5678) or a number with an international call prefix.") signing_center = models.CharField(choices=SIGNING_CENTERS, default='dallas court', max_length=50) is_ok = models.BooleanField("Is safe", default=True) warning_message_sent_at = models.DateTimeField(null=True) overdue_message_sent_at = models.DateTimeField(null=True) sos_alert_received_at = models.DateTimeField(null=True) telegram_username = models.CharField(default='', null=True, unique=True, validators=[validate_telegram_username], blank=True, max_length=32, help_text="Without the initial '@'") telegram_chat_id = models.BigIntegerField(default=0) preferred_channel = models.CharField(choices=SUPPORTED_CHANNELS, default=settings.PREFERRED_CHANNEL, max_length=8, help_text="Which channel should the app contact the user via?") def __str__(self): return self.name def save(self, *args, **kwargs): if not self.codename: # Generate codename once, then check the db. If exists, keep trying. self.codename = generate_codename() while Member.objects.filter(codename=self.codename).exists(): self.codename = generate_codename() if not self.telegram_username: self.telegram_username = None super(Member, self).save() def ok_status(self): state = { True: "safe", False: "not safe" } return state[self.is_ok] def sign_in(self): in_time = timezone.localtime() out_time = in_time + settings.CHECKIN_TTL self.is_ok = True self.save() checkin, created = Checkin.objects.update_or_create(member=self, defaults={'time_stamp': in_time}) with translation.override(self.language, deactivate=True): if created: response = _("Your check in time at %(center)s is %(in time)s.\n\nI will raise the alarm if you don't check out by %(out time)s.\n\nI will update your check in time if you message IN again.") % { "center": self.signing_center, "in time": str(in_time.time().strftime('%X')), "out time": out_time.strftime('%X') } else: response = _("You were already checked in.\n\nI updated your check in time to %(time)s.") % { "time": in_time.time().strftime('%X') } return response def sign_out(self): self.is_ok = True self.save() try: checkin = Checkin.objects.get(member=self) except Checkin.DoesNotExist: with translation.override(self.language, deactivate=True): # Translators: the uppercase commands need to remain in English return _("You were not checked in.\n\nTo check in, message IN.\n\nTo raise the alarm, message SOS.") checkin.delete() with translation.override(self.language, deactivate=True): # Translators: feel free to change this to a similar sentiment in your culture return _("Your check out time from %(center)s is %(time)s.\n\nI hope you have a lovely day!") % { 'center': self.signing_center, 'time': str(timezone.localtime().time().strftime( '%H:%M:%S'))} def handle_sos(self): self.is_ok = False self.sos_alert_received_at = timezone.now() self.save() # send notifications time = timezone.localtime() subject = f"[IMOK] {self.name} sent an SOS" if self.notes == "": notes = "No notes saved for this member" else: notes = f"{self.notes}" body = f"⚠️ {self.name} ({self.phone_number}) sent an SOS at {self.signing_center}.\n\n⏰ They raised it at {time.strftime('%H:%M')} on {time.strftime('%d/%m/%Y')}.\n\n📝 {notes}." notify_admins(subject, body) with translation.override(self.language, deactivate=True): return _("Thank you for letting me know.\n\nI notified the admins at %(time)s.") % { "time": timezone.localtime().time().strftime('%X')} def send_message(self, message): if self.preferred_channel == 'TELEGRAM': if self.telegram_chat_id == 0: logger.error(f"Cannot message {self.telegram_username}, the member hasn't added the bot.") return telegram_send(self.telegram_chat_id, message) elif self.preferred_channel == 'TWILIO': twilio_send(self.phone_number.as_e164, message) else: raise ImproperlyConfigured("Member uses an unsupported channel")
class Applicant(models.Model): # Basic Information given_name = models.CharField('First Name', max_length=40, blank=False) family_name = models.CharField('Last Name', max_length=40, blank=False) email = models.EmailField('Email Address', blank=False) # Address address_street1 = models.CharField('Street Address', max_length=100, blank=True, null=True) address_street2 = models.CharField('Street Address 2', max_length=100, blank=True, null=True) address_city = models.CharField('City', max_length=100, blank=True, null=True) address_state = USStateField('State', blank=True, null=True) address_zip = USZipCodeField('Zip Code', blank=True, null=True) # Phone Number phone_number = PhoneNumberField(blank=True, null=True) phone_can_receive_sms = models.BooleanField(null=False, default=False) # Emergency Contact Info emergency_contact_name = models.CharField(max_length=100, blank=True, null=True) emergency_contact_phone = PhoneNumberField(blank=True, null=True) # Just in case keyfob_code = models.CharField(max_length=50, blank=True, null=True) # Links to related records civicrm_identifier = models.CharField('CiviCRM Contact ID', max_length=6) user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) # Holds invite code uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, null=False) # Applicant performs these steps basic_info_collected_at = models.DateTimeField(blank=True, null=True) contact_info_collected_at = models.DateTimeField(blank=True, null=True) liability_waiver_accepted_at = models.DateTimeField(blank=True, null=True) application_completed_at = models.DateTimeField(blank=True, null=True) # TCMaker Staff performs these steps keyfob_issued_at = models.DateTimeField(blank=True, null=True) account_invitation_created_at = models.DateTimeField(blank=True, null=True) # After orientation, applicant completes these steps account_invitation_accepted_at = models.DateTimeField(blank=True, null=True) account_created_at = models.DateTimeField(blank=True, null=True) membership_completed_at = models.DateTimeField(blank=True, null=True) # Managers objects = models.Manager() # default manager pending = PendingApprovalManager() class Meta: abstract = True def create_civicrm_contact(self): resp = civicrm.signup_create_contact({ 'first_name': self.given_name, 'last_name': self.family_name, }) self.civicrm_identifier = resp['id'] self.save() resp = civicrm.signup_add_email(self.civicrm_identifier, self.email) def add_civicrm_address(self): civicrm.signup_add_address( self.civicrm_identifier, { 'street_address': self.address_street1, 'city': self.address_city, 'state_province_id': self.address_state, 'postal_code': self.address_zip, }) def add_civicrm_phone(self): civicrm.signup_add_phone(self.civicrm_identifier, str(self.phone_number), self.phone_can_receive_sms) def add_civicrm_emergency_info(self): civicrm.signup_add_emergency_contact(self.civicrm_identifier, self.emergency_contact_name, str(self.emergency_contact_phone)) def add_civicrm_keyfob_code(self): civicrm.signup_add_keyfob_code(self.civicrm_identifier, self.keyfob_code) def civicrm_accept_liability_waiver(self): civicrm.signup_accept_liability_waiver(self.civicrm_identifier) def create_current_membership(self): civicrm.signup_add_current_membership(self.civicrm_identifier) def send_invitation_email(self): context = {'registration': self, 'hostname': settings.WEBAPP_URL_BASE} msg_html = render_to_string('signup/email/invitation.html', context) msg = EmailMessage( subject='Twin Cities Maker: Complete Your Registration', body=msg_html, to=[self.email]) msg.content_subtype = "html" # Main content is now text/html print("about to send message") print(msg.send()) print("just sent message")
class StaffProfile(TimeStampedModel, MPTTModel): """ StaffProfile model class. Extends auth.User and adds more fields """ # sex choices # according to https://en.wikipedia.org/wiki/ISO/IEC_5218 NOT_KNOWN = "0" MALE = "1" FEMALE = "2" NOT_APPLICABLE = "9" SEX_CHOICES = ( (NOT_KNOWN, _("Not Known")), (MALE, _("Male")), (FEMALE, _("Female")), (NOT_APPLICABLE, _("Not Applicable")), ) user = models.OneToOneField(USER, verbose_name=_("User"), on_delete=models.CASCADE) supervisor = TreeForeignKey( "self", verbose_name=_("Manager"), on_delete=models.PROTECT, null=True, blank=True, related_name="children", ) image = ImageField( upload_to="staff-images/", max_length=255, verbose_name=_("Profile Image"), help_text=_("A square image works best"), blank=True, ) sex = models.CharField( _("Gender"), choices=SEX_CHOICES, max_length=1, default=NOT_KNOWN, blank=True, db_index=True, ) role = models.ForeignKey( Role, verbose_name=_("Role"), blank=True, default=None, null=True, on_delete=models.SET_NULL, ) phone = PhoneNumberField(_("Phone"), blank=True, default="") address = models.TextField(_("Addresss"), blank=True, default="") birthday = models.DateField(_("Birthday"), blank=True, default=None, null=True) leave_days = models.PositiveIntegerField( _("Leave days"), default=21, blank=True, help_text=_("Number of leave days allowed in a year."), ) sick_days = models.PositiveIntegerField( _("Sick days"), default=10, blank=True, help_text=_("Number of sick days allowed in a year."), ) overtime_allowed = models.BooleanField(_("Overtime allowed"), blank=True, default=False) start_date = models.DateField( _("Start Date"), null=True, default=None, blank=True, help_text=_("The start date of employment"), ) end_date = models.DateField( _("End Date"), null=True, default=None, blank=True, help_text=_("The end date of employment"), ) data = JSONField(_("Data"), default=dict, blank=True) class Meta: # pylint: disable=too-few-public-methods """Meta options for StaffProfile.""" abstract = False verbose_name = _("Staff Profile") verbose_name_plural = _("Staff Profiles") ordering = [ "user__first_name", "user__last_name", "user__username", "created" ] class MPTTMeta: """Meta options for MPTT.""" parent_attr = "supervisor" def get_name(self): """Return the staff member's name.""" # pylint: disable=no-member return f"{self.user.first_name} {self.user.last_name}" @cached_property def _current_year(self): # pylint: disable=no-self-use """Get the current year.""" return datetime.today().year def get_approved_leave_days(self, year: Optional[int] = None): """Get approved leave days in the current year.""" # pylint: disable=no-member return get_taken_leave_days( staffprofile=self, status=Leave.APPROVED, leave_type=Leave.REGULAR, start_year=year or self._current_year, end_year=year or self._current_year, ) def get_approved_sick_days(self, year: Optional[int] = None): """Get approved leave days in the current year.""" return get_taken_leave_days( staffprofile=self, status=Leave.APPROVED, leave_type=Leave.SICK, start_year=year or self._current_year, end_year=year or self._current_year, ) def get_available_leave_days(self, year: Optional[int] = None): """Get available leave days.""" try: # pylint: disable=no-member leave_record = AnnualLeave.objects.get(leave_type=Leave.REGULAR, staff=self, year=year or self._current_year) except AnnualLeave.DoesNotExist: return Decimal(0) else: return leave_record.get_available_leave_days() def get_available_sick_days(self, year: Optional[int] = None): """Get available sick days.""" try: # pylint: disable=no-member leave_record = AnnualLeave.objects.get(leave_type=Leave.SICK, staff=self, year=year or self._current_year) except AnnualLeave.DoesNotExist: return Decimal(0) else: return leave_record.get_available_leave_days() def __str__(self): """Unicode representation of class object.""" return self.get_name() # pylint: disable=no-member
class DivorceComplaint(models.Model): dc_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, verbose_name='Complaint ID') #pk # own info of customer user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True) o_name = models.CharField( max_length=128, verbose_name='Complainant Name') #complainant name o_email = models.EmailField( max_length=64, verbose_name='Complainant Email') #complainant email o_no = PhoneNumberField(verbose_name='Complainant No') #complainant no o_state = models.CharField( max_length=32, verbose_name='Complainant Name') #complainant state o_city = models.CharField( max_length=32, verbose_name='Complainant City') #complainant city gender = models.CharField(max_length=8, choices=GENDER_CHOICES, default='MALE', verbose_name='Gender') #complainant gender age = models.CharField(max_length=8, choices=AGE_CHOICES, default='20-25', verbose_name='Complainant Age') #complainant age year = models.IntegerField( choices=YEAR_CHOICES, default=datetime.datetime.now().year, verbose_name='Year of Marriage') #year of marriage get_div = models.CharField( max_length=16, choices=GET_DIV, default='YOU', verbose_name='Who wants Divorce') #who wants divorce sure_div = models.CharField(max_length=64, choices=SURE_DIV, default='I AM NOT SURE', verbose_name='How sure you are to get divorce' ) #how sure to get divorce court_div = models.CharField( max_length=3, choices=ICC_CHOICES, default='YES', verbose_name='Divorce filed at court') #divorce filed in court children = models.CharField( max_length=2, choices=CHILDREN_CHOICES, default='1', verbose_name='No. of children') #no of children c_reln = models.CharField( max_length=16, choices=RELATION_CHOICES, default='LOW CONFLICT', verbose_name='Current relation status') #current relation o_emp = models.CharField( max_length=4, choices=ICC_CHOICES, default='YES', verbose_name='Complainant employed') #own employability p_emp = models.CharField( max_length=4, choices=ICC_CHOICES, default='YES', verbose_name='Partner employed') #partner employability c_description = models.TextField(max_length=4056, verbose_name='Complainant Description', validators=[MinLengthValidator(30) ]) #complaint discription c_document = models.FileField(upload_to='divorce/', null=True, blank=True, verbose_name='Complaint related documents') c_filed = models.DateField(auto_now_add=True, verbose_name='Complaint filed date') c_amt = models.DecimalField(decimal_places=2, max_digits=1000000000, verbose_name='Complaint Amount', null=True, blank=True) p_date = models.DateTimeField(null=True, verbose_name='Payment Date', blank=True) p_status = models.BooleanField(verbose_name='Payment Status', default=0) new_cid = models.CharField(max_length=128, null=True, blank=True, verbose_name='Order ID') txn_id = models.CharField(max_length=128, null=True, blank=True, verbose_name='Transaction ID') update_flag = models.BooleanField(verbose_name='Information Updated', default=0) admin_reply = models.TextField(max_length=4056, verbose_name='Update Complaint Status', null=True, blank=True) admin_document = models.FileField(upload_to='admin/divorce/', null=True, blank=True, verbose_name='Attach documents') def __str__(self): return self.o_name
class Phone(models.Model): number = PhoneNumberField(unique=True) type = models.CharField(max_length=32) person = models.ForeignKey(Person, on_delete=models.CASCADE)
class UserAddress(AbstractUserAddress): """ """ email = models.EmailField(_("Email ID"), blank=True, help_text=_("Email Address")) alt_phone_number = PhoneNumberField( _("Alternate Phone number"), blank=True, help_text=_("Alternate Contact Number")) address_type = models.CharField(max_length=1, choices=CHOICES, default=HOME) # Fields, used for `summary` property definition and hash generation. base_fields = hash_fields = [ 'salutation', 'address_type', 'line1', 'line2', 'line3', 'line4', 'state', 'postcode', 'country' ] def get_field_values(self, fields): field_values = [] for field in fields: # Title is special case if field == 'title': value = self.get_title_display() elif field == 'address_type': value = self.get_address_type_display() elif field == 'country': try: value = self.country.printable_name except exceptions.ObjectDoesNotExist: value = '' elif field == 'salutation': value = self.salutation else: value = getattr(self, field) field_values.append(value) return field_values def clean(self): # Strip all whitespace for field in [ 'first_name', 'line1', 'line2', 'line3', 'line4', 'state', 'postcode' ]: if self.__dict__[field]: self.__dict__[field] = self.__dict__[field].strip() # Ensure postcodes are valid for country self.ensure_postcode_is_valid_for_country() def _update_search_text(self): search_fields = filter(bool, [ self.first_name, self.address_type, self.line1, self.line2, self.line3, self.line4, self.state, self.postcode, self.country.name ]) self.search_text = ' '.join(search_fields) # PROPERTIES @property def address(self): return self.line1 @property def locality(self): return self.line2 @property def landmark(self): return self.line3 # city already defined in parent class as line4 @property def pincode(self): return self.postcode @property def salutation(self): return self.join_fields(('title', 'first_name'), separator=u" ") # as first_name is of 255 char so using it. @property def name(self): return self.first_name
class PhoneNumber(models.Model): provider = models.ForeignKey(to='providers.Provider') phone_number = PhoneNumberField()
class Business(ExportModelOperationsMixin('business'), EventModel): objects = BusinessEventManager() events = BusinessHistoryEvent name = models.CharField( max_length=255, ) location = models.ForeignKey( 'geodata.NPA', on_delete=models.SET_NULL, null=True, related_name='located' ) address = models.CharField( max_length=255, default='' ) description = models.TextField( blank=True ) main_category = models.ForeignKey( 'Category', on_delete=models.SET_NULL, null=True, related_name='as_main_category', blank=False ) other_categories = models.ManyToManyField( 'Category', related_name='as_other_category', blank=True ) delivers_to = models.ManyToManyField( 'geodata.NPA', related_name='delivers', blank=True ) delivers_to_canton = models.ManyToManyField( 'geodata.Canton', related_name='delivers', blank=True ) delivers_to_district = models.ManyToManyField( 'geodata.District', related_name='delivers', blank=True ) delivers_to_municipality = models.ManyToManyField( 'geodata.Municipality', related_name='delivers', blank=True ) delivers_to_ch = models.BooleanField( default=False, verbose_name='Delivers to whole Switzerland' ) website = models.URLField( blank=True ) phone = PhoneNumberField( blank=True ) email = models.EmailField( blank=True ) parent_request = models.ForeignKey( Request, related_name='child_businesses', null=True, blank=True, on_delete=models.SET_NULL ) class Meta: verbose_name_plural = 'businesses' def __str__(self): return '%s (%s)' % (self.name, self.location) def clear_npa_cache(self): cache_key = str(self.location.pk) + '_businesses' cache.delete(cache_key)
class StaffProfile(TimeStampedModel, models.Model): """ StaffProfile model class Extends auth.User and adds more fields """ # sex choices # according to https://en.wikipedia.org/wiki/ISO/IEC_5218 NOT_KNOWN = '0' MALE = '1' FEMALE = '2' NOT_APPLICABLE = '9' SEX_CHOICES = ((NOT_KNOWN, _('Not Known')), (MALE, _('Male')), (FEMALE, _('Female')), (NOT_APPLICABLE, _('Not Applicable'))) user = models.OneToOneField(USER, verbose_name=_('User'), on_delete=models.CASCADE) image = ImageField(upload_to="staff-images/", max_length=255, verbose_name=_("Profile Image"), help_text=_("A square image works best"), blank=True) sex = models.CharField(_('Gender'), choices=SEX_CHOICES, max_length=1, default=NOT_KNOWN, blank=True, db_index=True) role = models.ForeignKey(Role, verbose_name=_('Role'), blank=True, default=None, null=True, on_delete=models.SET_NULL) phone = PhoneNumberField(_('Phone'), blank=True, default='') address = models.TextField(_('Addresss'), blank=True, default="") birthday = models.DateField(_('Birthday'), blank=True, default=None, null=True) leave_days = models.PositiveIntegerField( _('Leave days'), default=21, blank=True, help_text=_('Number of leave days allowed in a year.')) sick_days = models.PositiveIntegerField( _('Sick days'), default=10, blank=True, help_text=_('Number of sick days allowed in a year.')) overtime_allowed = models.BooleanField(_('Overtime allowed'), blank=True, default=False) start_date = models.DateField(_('Start Date'), null=True, default=None, blank=True, help_text=_('The start date of employment')) end_date = models.DateField(_('End Date'), null=True, default=None, blank=True, help_text=_('The end date of employment')) data = JSONField(_('Data'), default=dict, blank=True) class Meta: # pylint: disable=too-few-public-methods """ Meta options for StaffProfile """ abstract = False verbose_name = _('Staff Profile') verbose_name_plural = _('Staff Profiles') ordering = [ 'user__first_name', 'user__last_name', 'user__username', 'created' ] def get_name(self): """ Returns the staff member's name """ # pylint: disable=no-member return f'{self.user.first_name} {self.user.last_name}' def get_approved_leave_days(self, year: int = datetime.today().year): """ Get approved leave days in the current year """ # pylint: disable=no-member return get_taken_leave_days(staffprofile=self, status=Leave.APPROVED, leave_type=Leave.REGULAR, start_year=year, end_year=year) def get_approved_sick_days(self, year: int = datetime.today().year): """ Get approved leave days in the current year """ return get_taken_leave_days(staffprofile=self, status=Leave.APPROVED, leave_type=Leave.SICK, start_year=year, end_year=year) def get_available_leave_days(self, year: int = datetime.today().year): """ Get available leave days """ try: # pylint: disable=no-member leave_record = AnnualLeave.objects.get(leave_type=Leave.REGULAR, staff=self, year=year) except AnnualLeave.DoesNotExist: return Decimal(0) else: return leave_record.get_available_leave_days() def get_available_sick_days(self, year: int = datetime.today().year): """ Get available sick days """ try: # pylint: disable=no-member leave_record = AnnualLeave.objects.get(leave_type=Leave.SICK, staff=self, year=year) except AnnualLeave.DoesNotExist: return Decimal(0) else: return leave_record.get_available_leave_days() def __str__(self): return self.get_name() # pylint: disable=no-member
class Organization(AttachmentMixin, CommentMixin, ComplaintMixin, RatingMixin, ViewMixin, TimeStampedModel): """Organization Model.""" # ------------------------------------------------------------------------- # --- Basics author = models.ForeignKey(User, db_index=True, related_name="created_organizations", verbose_name=_("Author"), help_text=_("Organization Author")) avatar = models.ImageField(upload_to=organization_directory_path) name = models.CharField(db_index=True, max_length=80, verbose_name=_("Name"), help_text=_("Organization Name")) description = models.TextField(null=True, blank=True, verbose_name=_("Description"), help_text=_("Organization Description")) slug = AutoSlugField(populate_from="name", unique=True, always_update=False) # ------------------------------------------------------------------------- # --- Tags tags = TaggableManager(through=None, blank=True, verbose_name=_("Tags"), help_text=_("A comma-separated List of Tags.")) hashtag = models.CharField(db_index=True, max_length=80, null=True, blank=True, verbose_name=_("Hashtag"), help_text=_("Hashtag")) # ------------------------------------------------------------------------- # --- Address & Phone Number addressless = models.BooleanField( default=False, verbose_name=_("I will provide the Location later, if any."), help_text=_("I will provide the Location later, if any.")) address = models.ForeignKey(Address, db_index=True, null=True, blank=True, verbose_name=_("Address"), help_text=_("Organization Address")) phone_number = models.ForeignKey(Phone, db_index=True, null=True, blank=True, verbose_name=_("Phone Numbers"), help_text=_("Organization Phone Numbers")) # ------------------------------------------------------------------------- # --- URLs website = models.URLField(db_index=True, null=True, blank=True, verbose_name=_("Website"), help_text=_("Organization Website")) video = models.URLField(db_index=True, null=True, blank=True, verbose_name=_("Video"), help_text=_("Organization Informational Video")) email = models.EmailField(db_index=True, null=True, blank=True, verbose_name=_("Email"), help_text=_("Organization Email")) # ------------------------------------------------------------------------- # --- Social Links # ------------------------------------------------------------------------- # --- Subscribers subscribers = models.ManyToManyField( User, db_index=True, blank=True, related_name="organization_subscribers", verbose_name=_("Subscribers"), help_text=_("Organization Subscribers")) # ------------------------------------------------------------------------- # --- Contact Person. Author by default. is_alt_person = models.BooleanField(default=False) alt_person_fullname = models.CharField( max_length=80, null=True, blank=True, verbose_name=_("Full Name"), help_text=_("Organization contact Person full Name")) alt_person_email = models.EmailField( max_length=80, null=True, blank=True, verbose_name=_("Email"), help_text=_("Organization contact Person Email")) alt_person_phone = PhoneNumberField( blank=True, verbose_name=_("Phone Number"), help_text=_( "Please, use the International Format, e.g. +1-202-555-0114.")) # ------------------------------------------------------------------------- # --- Flags is_newly_created = models.BooleanField(default=True) is_hidden = models.BooleanField(default=False) is_deleted = models.BooleanField(default=False) objects = OrganizationManager() class Meta: verbose_name = _("organization") verbose_name_plural = _("organizations") ordering = [ "-created", ] def __repr__(self): """Docstring.""" return u"<%s (%s: '%s')>" % (self.__class__.__name__, self.id, self.name) def __unicode__(self): """Docstring.""" return u"%s" % self.name def __str__(self): """Docstring.""" return self.__unicode__() # ------------------------------------------------------------------------- # --- Organization direct URL def public_url(self, request=None): """Docstring.""" if request: DOMAIN_NAME = request.get_host() else: DOMAIN_NAME = settings.DOMAIN_NAME url = reverse("organization-details", kwargs={ "slug": self.slug, }) organization_link = u"http://{domain}{url}".format( domain=DOMAIN_NAME, url=url, ) return organization_link def get_absolute_url(self): """Method to be called by Django Sitemap Framework.""" url = reverse("organization-details", kwargs={ "slug": self.slug, }) return url def get_hours_received(self): """Docstring.""" from challenges.choices import CHALLENGE_STATUS from challenges.models import Challenge hours_worked = Challenge.objects.filter( status=CHALLENGE_STATUS.COMPLETE, organization=self, ).aggregate(Sum("duration")) return hours_worked["duration__sum"] def get_upcoming_challenges(self): """Docstring.""" from challenges.choices import CHALLENGE_STATUS from challenges.models import Challenge upcoming_challenges = Challenge.objects.filter( organization=self, status=CHALLENGE_STATUS.UPCOMING, start_date__gte=datetime.date.today(), ) return upcoming_challenges # ------------------------------------------------------------------------- # --- Methods def image_tag(self): """Render Avatar Thumbnail.""" if self.avatar: return u"<img src='{url}' width='{width}' height='{height}' />".format( url=self.avatar.url, width=100, height=60, ) else: return "(Sin Imagen)" image_tag.short_description = "Avatar" image_tag.allow_tags = True def email_notify_admin_org_created(self, request=None): """Send Notification to the Organization Admin.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") # --------------------------------------------------------------------- # --- Render HTML Email Content greetings = _("Dear, %(user)s.") % { "user": self.author.first_name, } htmlbody = _( "<p>The Organization \"<a href=\"%(url)s\">%(name)s</a>\" was successfully created.</p>" ) % { "url": self.public_url(request), "name": self.name, } # --------------------------------------------------------------------- # --- Send Email send_templated_email( template_subj={ "name": "organizations/emails/organization_created_subject.txt", "context": {}, }, template_text={ "name": "organizations/emails/organization_created.txt", "context": { "user": self.author, "organization": self, "organization_link": self.public_url(request), }, }, template_html={ "name": "emails/base.html", "context": { "greetings": greetings, "htmlbody": htmlbody, }, }, from_email=settings.EMAIL_SENDER, to=[ self.author.email, ], headers=None, ) def email_notify_alt_person_org_created(self, request=None): """Send Notification to the Organization alternative Contact Person.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") if not self.is_alt_person: return # --------------------------------------------------------------------- # --- Render HTML Email Content greetings = _("Dear, %(user)s.") % { "user": self.alt_person_fullname, } htmlbody = _( "<p>The Organization \"<a href=\"%(url)s\">%(name)s</a>\" was successfully created, and you were added as a Contact Person to it.</p>" ) % { "url": self.public_url(request), "name": self.name, } # --------------------------------------------------------------------- # --- Send Email send_templated_email( template_subj={ "name": "organizations/emails/organization_created_subject.txt", "context": {}, }, template_text={ "name": "organizations/emails/organization_created_alt.txt", "context": { "user": self.alt_person_fullname, "organization": self, "organization_link": self.public_url(request), }, }, template_html={ "name": "emails/base.html", "context": { "greetings": greetings, "htmlbody": htmlbody, }, }, from_email=settings.EMAIL_SENDER, to=[ self.alt_person_email, ], headers=None, ) def email_notify_admin_org_modified(self, request=None): """Send Notification to the Organization Admin.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") # --------------------------------------------------------------------- # --- Render HTML Email Content greetings = _("Dear, %(user)s.") % { "user": self.author.first_name, } htmlbody = _( "<p>Your Organization \"<a href=\"%(url)s\">%(name)s</a>\" was modified.</p>" ) % { "url": self.public_url(request), "name": self.name, } # --------------------------------------------------------------------- # --- Send Email send_templated_email( template_subj={ "name": "organizations/emails/organization_modified_subject.txt", "context": {}, }, template_text={ "name": "organizations/emails/organization_modified.txt", "context": { "admin": self.author, "organization": self, "organization_link": self.public_url(request), }, }, template_html={ "name": "emails/base.html", "context": { "greetings": greetings, "htmlbody": htmlbody, }, }, from_email=settings.EMAIL_SENDER, to=[ self.author.email, ], headers=None, ) def email_notify_alt_person_org_modified(self, request=None): """Send Notification to the Organization alternative Contact Person.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") if not self.is_alt_person: return # --------------------------------------------------------------------- # --- Render HTML Email Content greetings = _("Dear, %(user)s.") % { "user": self.alt_person_fullname, } htmlbody = _( "<p>The Organization \"<a href=\"%(url)s\">%(name)s</a>\", were you added as a Contact Person, was modified!.</p>" ) % { "url": self.public_url(request), "name": self.name, } # --------------------------------------------------------------------- # --- Send Email send_templated_email( template_subj={ "name": "organizations/emails/organization_modified_subject.txt", "context": {}, }, template_text={ "name": "organizations/emails/organization_modified_alt.txt", "context": { "user": self.alt_person_fullname, "organization": self, "organization_link": self.public_url(request), }, }, template_html={ "name": "emails/base.html", "context": { "greetings": greetings, "htmlbody": htmlbody, }, }, from_email=settings.EMAIL_SENDER, to=[ self.alt_person_email, ], headers=None, ) def email_notify_admin_org_newsletter_created(self, request=None, newsletter=None): """Send Notification to the Organization Admin.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") if not newsletter: return # --------------------------------------------------------------------- # --- Render HTML Email Content greetings = _("Dear, %(user)s.") % { "user": self.author.first_name, } htmlbody = _( "<p>The Organization\'s \"<a href=\"%(url)s\">%(name)s</a>\" Newsletter with the Title \"%(title)s\", was successfully created and populated.</p>" ) % { "url": self.public_url(request), "name": self.name, "title": newsletter.title, } # --------------------------------------------------------------------- # --- Send Email send_templated_email( template_subj={ "name": "organizations/emails/organization_newsletter_admin_subject.txt", "context": {}, }, template_text={ "name": "organizations/emails/organization_newsletter_admin.txt", "context": { "admin": self.author, "organization": self, "organization_link": self.public_url(request), "newsletter": newsletter, }, }, template_html={ "name": "emails/base.html", "context": { "greetings": greetings, "htmlbody": htmlbody, }, }, from_email=settings.EMAIL_SENDER, to=[ self.author.email, ], headers=None, ) def email_notify_newsletter_populate(self, request=None, newsletter=None): """Populate Newsletter among Organization's Subscribers.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") for subscriber in self.subscribers.all(): newsletter.recipients.add(subscriber) # ----------------------------------------------------------------- # --- Render HTML Email Content greetings = _( "The \"<a href=\"%(url)s\">%(name)s</a>\" Newsletter:<br/>\"%(title)s\"" ) % { "name": self.name, "url": self.public_url(request), "title": newsletter.title, } htmlbody = _( "<p>%(content)s<br/>You have received this Email, because you're subscribed to the Organization's Newsletters and Activity Notifications.</p>" ) % { "content": newsletter.content, } # ----------------------------------------------------------------- # --- Send Email send_templated_email( template_subj={ "name": "organizations/emails/organization_newsletter_subject.txt", "context": {}, }, template_text={ "name": "organizations/emails/organization_newsletter.txt", "context": { "user": subscriber, "organization": self, "organization_link": self.public_url(request), "newsletter": newsletter, }, }, template_html={ "name": "emails/base.html", "context": { "greetings": greetings, "htmlbody": htmlbody, }, }, from_email=settings.EMAIL_SENDER, to=[ subscriber.email, ], headers=None, ) # ------------------------------------------------------------------------- # --- Signals def pre_save(self, **kwargs): """Docstring.""" pass def post_save(self, created, **kwargs): """Docstring.""" # --------------------------------------------------------------------- # --- Ping Google try: ping_google() except Exception as e: print colored("###" * 27, "white", "on_red") print colored( "### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") # --------------------------------------------------------------------- # --- Update/insert SEO Model Instance Metadata update_seo_model_instance_metadata( title=self.name, description=self.description, keywords=", ".join(self.tags.names()), heading=self.name, path=self.get_absolute_url(), object_id=self.id, content_type_id=ContentType.objects.get_for_model(self).id, ) # --------------------------------------------------------------------- # --- The Path for uploading Avatar Images is: # # MEDIA_ROOT/organizations/<id>/avatars/<filename> # # --- As long as the uploading Path is being generated before # the Organization Instance gets assigned with the unique ID, # the uploading Path for the brand new Organization looks like: # # MEDIA_ROOT/organizations/None/avatars/<filename> # # --- To fix this: # 1. Open the Avatar File in the Path; # 2. Assign the Avatar File Content to the Organization Avatar Object; # 3. Save the Organization Instance. Now the Avatar Image in the # correct Path; # 4. Delete previous Avatar File; # if created: avatar = File(storage.open(self.avatar.file.name, "rb")) self.avatar = avatar self.save() storage.delete(avatar.file.name) def pre_delete(self, **kwargs): """Docstring.""" # --------------------------------------------------------------------- # --- Remove related Invites, if any. print colored( "[--- LOG ---] Going to remove Invites, related with the Instance", "green") try: content_type = ContentType.objects.get_for_model(self) related_invites = Invite.objects.filter( content_type=content_type, object_id=self.id, ) print colored( "[--- DUMP ---] RELATED INVITES : %s" % related_invites, "yellow") related_invites.delete() except Exception as e: print colored("###" * 27, "white", "on_red") print colored( "### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") def post_delete(self, **kwargs): """Docstring.""" pass
class User(AbstractBaseUser, PermissionsMixin): email = models.EmailField( verbose_name=_('Email address'), max_length=255, unique=True, ) first_name = models.CharField(_('first name'), max_length=30) last_name = models.CharField(_('last name'), max_length=150) ik = models.BigIntegerField(_('isikukood'), null=True, blank=True, validators=[ MinValueValidator(30000000000), MaxValueValidator(69999999999), ik_validator ]) phone = PhoneNumberField(_('Phone'), help_text=_('Contact phone number')) car_model = models.CharField(_('car model'), max_length=50) car_type = models.IntegerField(_('car type'), choices=conf.CAR_TYPE, default=conf.CAR_TYPE[-1][0]) car_carrying = models.IntegerField( _('car carrying (kg)'), validators=[MinValueValidator(100), MaxValueValidator(10000)]) car_number = models.CharField(_('car number'), max_length=7, validators=[ MinLengthValidator(5), MaxLengthValidator(7), car_number_validator ]) payment = models.IntegerField(_('payment method'), choices=conf.PAYMENT_METHOD, default=conf.PAYMENT_METHOD[0][0]) movers_num = models.IntegerField(_('number of available movers'), choices=[(0, '0'), (1, '1'), (2, '2'), (3, '3'), (4, '4')], default=0) preferred_language = models.IntegerField( _('Preferred language'), choices=conf.PREFERRED_LANGUAGE, default=conf.PREFERRED_LANGUAGE[0][0], help_text=_('Preferred language to use delivery24')) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(null=True, blank=True) is_active = models.BooleanField(default=True) email_confirmed = models.BooleanField(default=False) is_admin = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'email' # required fields will be used when using command createsuperuser REQUIRED_FIELDS = [ 'first_name', 'last_name', 'ik', 'phone', 'car_model', 'car_carrying', 'car_number', 'payment', 'movers_num', 'preferred_language' ] class Meta: verbose_name = _('user', ) verbose_name_plural = _('users', ) def __str__(self): return self.email def has_perm(self, perm, obj=None): "Does the user have a specific permission?" # Simplest possible answer: Yes, always return True def has_module_perms(self, app_label): "Does the user have permissions to view the app `app_label`?" # Simplest possible answer: Yes, always return True @property def is_staff(self): "Is the user a member of staff?" # Simplest possible answer: All admins are staff return self.is_admin def email_user(self, subject, message, from_email=None, **kwargs): """Send an email to this user.""" send_mail(subject, message, from_email, [self.email], **kwargs)
class MandatoryPhoneNumber(models.Model): phone_number = PhoneNumberField()
class Lead(models.Model): title = models.CharField(pgettext_lazy( "Treatment Pronouns for the customer", "Title"), max_length=64) first_name = models.CharField(("First name"), null=True, max_length=255) last_name = models.CharField(("Last name"), null=True, max_length=255) email = models.EmailField(null=True, blank=True) phone = PhoneNumberField(null=True, blank=True) status = models.CharField(_("Status of Lead"), max_length=255, blank=True, null=True, choices=LEAD_STATUS) source = models.CharField(_("Source of Lead"), max_length=255, blank=True, null=True, choices=LEAD_SOURCE) address_line = models.CharField(_("Address"), max_length=255, blank=True, null=True) street = models.CharField(_("Street"), max_length=55, blank=True, null=True) city = models.CharField(_("City"), max_length=255, blank=True, null=True) state = models.CharField(_("State"), max_length=255, blank=True, null=True) postcode = models.CharField(_("Post/Zip-code"), max_length=64, blank=True, null=True) country = models.CharField(max_length=3, choices=COUNTRIES, blank=True, null=True) website = models.CharField(_("Website"), max_length=255, blank=True, null=True) description = models.TextField(blank=True, null=True) assigned_to = models.ManyToManyField(User, related_name='lead_assigned_users') account_name = models.CharField(max_length=255, null=True, blank=True) opportunity_amount = models.DecimalField(_("Opportunity Amount"), decimal_places=2, max_digits=12, blank=True, null=True) created_by = models.ForeignKey(User, related_name='lead_created_by', on_delete=models.SET_NULL, null=True) created_on = models.DateTimeField(_("Created on"), auto_now_add=True) is_active = models.BooleanField(default=False) enquery_type = models.CharField(max_length=255, blank=True, null=True) tags = models.ManyToManyField(Tags, blank=True) contacts = models.ManyToManyField(Contact, related_name="lead_contacts") created_from_site = models.BooleanField(default=False) class Meta: ordering = ['-created_on'] def __str__(self): if self.first_name and self.last_name: return self.first_name + self.last_name else: return self.title def get_complete_address(self): return return_complete_address(self) @property def created_on_arrow(self): return arrow.get(self.created_on).humanize()
class NullablePhoneNumber(models.Model): phone_number = PhoneNumberField(null=True)
class mentor(models.Model): name = models.CharField(max_length=50) phone = PhoneNumberField() content = models.TextField(blank=True) email = models.EmailField(blank=True, null=True)
class CustomUser(AbstractUser): phone = PhoneNumberField()
class Coder(BaseModel): user = models.OneToOneField(User, on_delete=models.CASCADE) username = models.CharField(max_length=255, unique=True, blank=True) first_name_native = models.CharField(max_length=255, blank=True) last_name_native = models.CharField(max_length=255, blank=True) middle_name_native = models.CharField(max_length=255, blank=True) date_of_birth = models.DateField(null=True, blank=True) organization = models.ForeignKey('Organization', null=True, blank=True, on_delete=models.SET_NULL) timezone = models.CharField(max_length=32, default="UTC") settings = models.JSONField(default=dict, blank=True) country = CountryField(null=True, blank=True) phone_number = PhoneNumberField(blank=True) addition_fields = models.JSONField(default=dict, blank=True) n_accounts = models.IntegerField(default=0, db_index=True) class Meta: indexes = [ GistIndexTrgrmOps(fields=['username']), ] def __str__(self): return "%s" % (self.username) @property def chat(self): if not hasattr(self, 'cchat'): self.cchat = list(self.chat_set.filter(is_group=False)) return self.cchat[0] if self.cchat else None def get_contest_filter(self, categories, ignores=None): if not isinstance(categories, (list, tuple, set)): categories = (categories, ) filter_categories = Q() filter_categories_with_coder = Q() for c in categories: if '@' in c: c, coder = c.split('@', 1) filter_categories_with_coder |= Q(coder__username=coder, categories__contains=[c]) else: filter_categories |= Q(categories__contains=[c]) if ignores: filter_categories &= ~Q(id__in=ignores) if filter_categories_with_coder: filters = Filter.objects.filter(filter_categories_with_coder) elif self is not None: filters = self.filter_set.filter(filter_categories) else: filters = [] hide = Q() show = Q() for filter_ in filters: query = Q() if filter_.resources: query &= Q(resource__id__in=filter_.resources) if filter_.duration_from: seconds = timedelta( minutes=filter_.duration_from).total_seconds() query &= Q(duration_in_secs__gte=seconds) if filter_.duration_to: seconds = timedelta( minutes=filter_.duration_to).total_seconds() query &= Q(duration_in_secs__lte=seconds) if filter_.regex: field = 'title' regex = filter_.regex match = re.search( r'^(?P<field>[a-z]+):(?P<sep>.)(?P<regex>.+)(?P=sep)$', filter_.regex) if match: f = match.group('field') if f in ('url', ): field = f regex = match.group('regex') query_regex = Q(**{f'{field}__regex': regex}) if filter_.inverse_regex: query_regex = ~query_regex query &= query_regex if filter_.contest_id: query &= Q(pk=filter_.contest_id) if filter_.to_show: show |= query else: hide |= query result = ~hide & show return result def get_categories(self): categories = [{'id': c, 'text': c} for c in Filter.CATEGORIES] for chat in self.chat_set.filter(is_group=True).order_by('pk'): categories.append({ 'id': chat.chat_id, 'text': chat.get_group_name(), }) return categories def get_notifications(self): ret = list(django_settings.NOTIFICATION_CONF.METHODS_CHOICES) for chat in self.chat_set.filter(is_group=True): name = chat.get_group_name() ret.append(('telegram:{}'.format(chat.chat_id), name)) return ret def get_tshirt_size(self): p = self.participant_set.order_by('-modified').first() return p.tshirt_size_value if p is not None else None def account_set_order_by_pk(self): return self.account_set.select_related('resource').order_by('pk') @property def ordered_filter_set(self): return self.filter_set.order_by('created') def get_account(self, host): return self.account_set.filter(resource__host=host).first()