accounts.models

  1from django.db import models
  2from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
  3from django.utils import timezone
  4import hashlib
  5from django.core.exceptions import PermissionDenied
  6from django.core.validators import RegexValidator
  7
  8class Role(models.Model):
  9    """
 10    Represents a user role within a hospital.
 11
 12    Fields:
 13        - hospital: ForeignKey to Hospital.
 14        - name: Name of the role.
 15        - description: Optional description of the role.
 16        - is_protected: If True, role cannot be deleted.
 17        - is_approver: If True, role can approve memos.
 18        - is_responder: If True, role can respond to memos.
 19        - is_creator: If True, role can create memos.
 20
 21    Meta:
 22        - unique_together: Role name must be unique within a hospital.
 23        - db_table: Table name in DB.
 24
 25    Methods:
 26        - delete(): Prevents deletion if role is protected.
 27        - __str__(): String representation of the role.
 28    """
 29    hospital = models.ForeignKey('Hospital', on_delete=models.CASCADE, related_name='roles', verbose_name='Hospital')
 30    name = models.CharField(max_length=100,verbose_name='Role Name')
 31    description = models.TextField(blank=True, null=True, verbose_name='Description')
 32    is_protected = models.BooleanField(default=False)
 33    is_approver = models.BooleanField(default=False, verbose_name='Is Approver', help_text='If this role can approve memos')
 34    is_responder = models.BooleanField(default=False, verbose_name='Is Responder', help_text='If this role can respond to memos')
 35    is_creator = models.BooleanField(default=False, verbose_name='Is Creator', help_text='If this role can create memos')
 36    
 37    def delete(self, *args, **kwargs):
 38        if self.is_protected:
 39            raise PermissionDenied("This hospital cannot be deleted.")
 40        super().delete(*args, **kwargs)
 41    class Meta:
 42        verbose_name = 'Role'
 43        verbose_name_plural = 'Roles'
 44        db_table = 'roles'
 45        unique_together = ('name', 'hospital')
 46    
 47    def __str__(self):
 48        return self.name
 49
 50class Hospital(models.Model):
 51    """
 52    Represents a hospital.
 53
 54    Fields:
 55        - name: Hospital name.
 56        - address: Hospital address.
 57        - geolocation_point: Geolocation as (latitude, longitude).
 58        - radius: Coverage radius in meters.
 59        - created_at: Timestamp when hospital was created.
 60        - updated_at: Timestamp when hospital was last updated.
 61        - geolocation_changes: List of geolocation change history.
 62
 63    Meta:
 64        - db_table: Table name in DB.
 65
 66    Methods:
 67        - save(): Tracks geolocation changes.
 68        - __str__(): String representation of the hospital.
 69    """
 70    name = models.CharField(max_length=255, verbose_name='Hospital Name')
 71    address = models.TextField(blank=True, null=True, verbose_name='Address')
 72    geolocation_point = models.CharField(max_length=255,blank=True, null=True, verbose_name='Geolocation Point', help_text='Geolocation Point as (latitude, longitude)')
 73    radius = models.IntegerField(blank=True, null=True, verbose_name='Radius', help_text='Radius in meters')
 74    created_at = models.DateTimeField(auto_now_add=True)
 75    updated_at = models.DateTimeField(auto_now=True)
 76    geolocation_changes = models.JSONField(default=list, blank=True, null=True, verbose_name='Geolocation Changes')
 77    
 78    class Meta:
 79        verbose_name = 'Hospital'
 80        verbose_name_plural = 'Hospitals'
 81    
 82    def save(self, *args, **kwargs):
 83        if self.pk:
 84            old_instance = Hospital.objects.get(pk=self.pk)
 85            if old_instance.geolocation_point != self.geolocation_point:
 86                self.geolocation_changes.append({
 87                    'old_point': old_instance.geolocation_point,
 88                    'new_point': self.geolocation_point,
 89                    'old_radius': old_instance.radius,
 90                    'new_radius': self.radius,
 91                    'updated_at': timezone.now()
 92                })
 93        super().save(*args, **kwargs)
 94    
 95    def __str__(self):
 96        return self.name
 97
 98class UserManager(BaseUserManager):
 99    """
100    Custom manager for User model.
101
102    Methods:
103        - create_user(): Creates a regular user.
104        - create_superuser(): Creates a superuser.
105    """
106    use_in_migrations = True
107    
108    def create_user(self, institution_id, role, phone_number, hospital, password=None):
109        """
110        Creates and saves a User with the given institution_id, role, phone_number, and hospital.
111        Password is optional as it might be set later.
112        """
113        if not institution_id:
114            raise ValueError('Users must have a institution ID')
115        if not role:
116            raise ValueError('Users must have a role')
117        if not phone_number:
118            raise ValueError('Users must have a phone number')
119
120        # Generate a globally unique institution_id by combining hospital_id and display_id
121        if not hospital:
122            raise ValueError('Regular users must have a hospital')
123            
124        user = self.model(
125            institution_id=institution_id,
126            role=role,
127            phone_number=phone_number,
128            hospital=hospital,
129        )
130        
131        if password:
132            user.set_password(password)
133            user.password_set = True
134        else:
135            user.set_unusable_password()
136            user.password_set = False
137        
138        # Set is_staff=True for hospital admins
139        if role.name == 'ADMIN':
140            user.is_staff = True
141            
142        user.save(using=self._db)
143        return user
144        
145    def create_superuser(self, institution_id, role, phone_number, hospital, password=None):
146        """
147        Creates and saves a User with the given institution_id, role, phone_number, and hospital.
148        Password is optional as it might be set later.
149        """
150        if not institution_id:
151            raise ValueError('Users must have a institution ID')
152        if not phone_number:
153            raise ValueError('Users must have a phone number')
154            
155        user = self.model(
156            institution_id=institution_id,
157            role=role,
158            phone_number=phone_number,
159            hospital=hospital,
160            is_staff=True,
161            is_superuser=True
162        )
163        
164        if password:
165            user.set_password(password)
166            user.password_set = True
167        else:
168            user.set_unusable_password()
169            user.password_set = False
170        
171        user.save(using=self._db)
172        return user
173
174class User(AbstractBaseUser, PermissionsMixin):
175    """
176    Represents a hospital user.
177
178    Fields:
179        - institution_id: Display ID (unique within a hospital).
180        - hospital: ForeignKey to Hospital.
181        - role: ForeignKey to Role.
182        - phone_number: Unique phone number.
183        - current_block: ForeignKey to Blocks (current block).
184        - current_ward: ForeignKey to Ward (current ward).
185        - fcm_token: FCM token for push notifications.
186        - fcm_token_updated_at: Timestamp of last FCM token update.
187        - current_device: Device info.
188        - is_active: Is user active.
189        - is_logged_in: Is user currently logged in.
190        - is_staff: Is user staff.
191        - is_superuser: Is user superuser.
192        - date_joined: Timestamp when user joined.
193        - password_set: Has user set their password.
194
195    Meta:
196        - db_table: Table name in DB.
197
198    Methods:
199        - __str__(): String representation of the user.
200        - has_perm(): Always returns True.
201        - has_module_perms(): Always returns True.
202    """
203    institution_id = models.CharField(max_length=100, verbose_name='Display ID')
204    hospital = models.ForeignKey(Hospital, null=True,blank=True,on_delete=models.CASCADE,related_name='users')
205    role = models.ForeignKey('Role',null=True,blank=True, on_delete=models.SET_NULL,verbose_name='Role')
206    phone_number = models.CharField(max_length=15,unique=True,validators=[RegexValidator(regex=r'^(\+91|91|0)?[-.\s]?(\d{10})$')], blank=True, null=True, verbose_name='Phone Number')
207    current_block = models.ForeignKey('management.Blocks', on_delete=models.SET_NULL, null=True, blank=True)
208    current_ward = models.ForeignKey('management.Ward', on_delete=models.SET_NULL, null=True, blank=True)
209    fcm_token = models.CharField(max_length=512, blank=True, null=True, verbose_name='FCM Token')
210    fcm_token_updated_at = models.DateTimeField(blank=True, null=True)
211    current_device = models.CharField(max_length=100, blank=True, null=True, verbose_name='Current Device')
212    
213    class Meta:
214        db_table = 'users'
215    is_active = models.BooleanField(default=True)
216    is_logged_in = models.BooleanField(default=False, verbose_name='Logged In', help_text='Indicates if the user is currently logged in')
217    is_staff = models.BooleanField(default=False)
218    is_superuser = models.BooleanField(default=False)
219    date_joined = models.DateTimeField(default=timezone.now)
220    password_set = models.BooleanField(default=False, help_text='Indicates if the user has set their password')
221    
222    objects = UserManager()
223    
224    USERNAME_FIELD = 'phone_number'
225    REQUIRED_FIELDS = ['role']
226    
227    def __str__(self):
228        return self.institution_id
229    
230    def has_perm(self, perm, obj=None):
231        "Does the user have a specific permission?"
232        return True
233
234    def has_module_perms(self, app_label):
235        "Does the user have permissions to view the app `app_label`?"
236        return True
237
238class SiteUser(models.Model):
239    """
240    Represents an admin user for the institution (not hospital).
241
242    Fields:
243        - name: Admin username.
244        - password: Hashed password.
245
246    Meta:
247        - db_table: Table name in DB.
248
249    Methods:
250        - save(): Hashes password before saving.
251        - check_password(): Checks password against hash.
252        - __str__(): String representation of the admin user.
253    """
254    name = models.CharField(max_length=100)
255    password = models.CharField(max_length=300)
256    
257    class Meta:
258        db_table = 'site_users'
259    
260    def save(self, *args, **kwargs):
261        """Encrypt password using SHA256 hash."""
262        self.password = hashlib.sha256(self.password.encode()).hexdigest()
263        super().save(*args, **kwargs)
264        
265    def check_password(self, raw_password):
266        """Check password using SHA256 hash."""
267        return hashlib.sha256(raw_password.encode()).hexdigest() == self.password
268    
269    def __str__(self):
270        return self.name
class Role(django.db.models.base.Model):
 9class Role(models.Model):
10    """
11    Represents a user role within a hospital.
12
13    Fields:
14        - hospital: ForeignKey to Hospital.
15        - name: Name of the role.
16        - description: Optional description of the role.
17        - is_protected: If True, role cannot be deleted.
18        - is_approver: If True, role can approve memos.
19        - is_responder: If True, role can respond to memos.
20        - is_creator: If True, role can create memos.
21
22    Meta:
23        - unique_together: Role name must be unique within a hospital.
24        - db_table: Table name in DB.
25
26    Methods:
27        - delete(): Prevents deletion if role is protected.
28        - __str__(): String representation of the role.
29    """
30    hospital = models.ForeignKey('Hospital', on_delete=models.CASCADE, related_name='roles', verbose_name='Hospital')
31    name = models.CharField(max_length=100,verbose_name='Role Name')
32    description = models.TextField(blank=True, null=True, verbose_name='Description')
33    is_protected = models.BooleanField(default=False)
34    is_approver = models.BooleanField(default=False, verbose_name='Is Approver', help_text='If this role can approve memos')
35    is_responder = models.BooleanField(default=False, verbose_name='Is Responder', help_text='If this role can respond to memos')
36    is_creator = models.BooleanField(default=False, verbose_name='Is Creator', help_text='If this role can create memos')
37    
38    def delete(self, *args, **kwargs):
39        if self.is_protected:
40            raise PermissionDenied("This hospital cannot be deleted.")
41        super().delete(*args, **kwargs)
42    class Meta:
43        verbose_name = 'Role'
44        verbose_name_plural = 'Roles'
45        db_table = 'roles'
46        unique_together = ('name', 'hospital')
47    
48    def __str__(self):
49        return self.name

Represents a user role within a hospital.

Fields: - hospital: ForeignKey to Hospital. - name: Name of the role. - description: Optional description of the role. - is_protected: If True, role cannot be deleted. - is_approver: If True, role can approve memos. - is_responder: If True, role can respond to memos. - is_creator: If True, role can create memos.

Meta: - unique_together: Role name must be unique within a hospital. - db_table: Table name in DB.

Methods: - delete(): Prevents deletion if role is protected. - __str__(): String representation of the role.

hospital

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def description(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_protected(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_approver(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_responder(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_creator(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def delete(self, *args, **kwargs):
38    def delete(self, *args, **kwargs):
39        if self.is_protected:
40            raise PermissionDenied("This hospital cannot be deleted.")
41        super().delete(*args, **kwargs)
hospital_id
def id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):
user_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

approverlevel_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

class Role.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class Role.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

class Hospital(django.db.models.base.Model):
51class Hospital(models.Model):
52    """
53    Represents a hospital.
54
55    Fields:
56        - name: Hospital name.
57        - address: Hospital address.
58        - geolocation_point: Geolocation as (latitude, longitude).
59        - radius: Coverage radius in meters.
60        - created_at: Timestamp when hospital was created.
61        - updated_at: Timestamp when hospital was last updated.
62        - geolocation_changes: List of geolocation change history.
63
64    Meta:
65        - db_table: Table name in DB.
66
67    Methods:
68        - save(): Tracks geolocation changes.
69        - __str__(): String representation of the hospital.
70    """
71    name = models.CharField(max_length=255, verbose_name='Hospital Name')
72    address = models.TextField(blank=True, null=True, verbose_name='Address')
73    geolocation_point = models.CharField(max_length=255,blank=True, null=True, verbose_name='Geolocation Point', help_text='Geolocation Point as (latitude, longitude)')
74    radius = models.IntegerField(blank=True, null=True, verbose_name='Radius', help_text='Radius in meters')
75    created_at = models.DateTimeField(auto_now_add=True)
76    updated_at = models.DateTimeField(auto_now=True)
77    geolocation_changes = models.JSONField(default=list, blank=True, null=True, verbose_name='Geolocation Changes')
78    
79    class Meta:
80        verbose_name = 'Hospital'
81        verbose_name_plural = 'Hospitals'
82    
83    def save(self, *args, **kwargs):
84        if self.pk:
85            old_instance = Hospital.objects.get(pk=self.pk)
86            if old_instance.geolocation_point != self.geolocation_point:
87                self.geolocation_changes.append({
88                    'old_point': old_instance.geolocation_point,
89                    'new_point': self.geolocation_point,
90                    'old_radius': old_instance.radius,
91                    'new_radius': self.radius,
92                    'updated_at': timezone.now()
93                })
94        super().save(*args, **kwargs)
95    
96    def __str__(self):
97        return self.name

Represents a hospital.

Fields: - name: Hospital name. - address: Hospital address. - geolocation_point: Geolocation as (latitude, longitude). - radius: Coverage radius in meters. - created_at: Timestamp when hospital was created. - updated_at: Timestamp when hospital was last updated. - geolocation_changes: List of geolocation change history.

Meta: - db_table: Table name in DB.

Methods: - save(): Tracks geolocation changes. - __str__(): String representation of the hospital.

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def address(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def geolocation_point(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def radius(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def created_at(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def updated_at(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def geolocation_changes(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def save(self, *args, **kwargs):
83    def save(self, *args, **kwargs):
84        if self.pk:
85            old_instance = Hospital.objects.get(pk=self.pk)
86            if old_instance.geolocation_point != self.geolocation_point:
87                self.geolocation_changes.append({
88                    'old_point': old_instance.geolocation_point,
89                    'new_point': self.geolocation_point,
90                    'old_radius': old_instance.radius,
91                    'new_radius': self.radius,
92                    'updated_at': timezone.now()
93                })
94        super().save(*args, **kwargs)

Save the current instance. Override this in a subclass if you want to control the saving process.

The 'force_insert' and 'force_update' parameters can be used to insist that the "save" must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.

def get_next_by_created_at(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

def get_previous_by_created_at(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

def get_next_by_updated_at(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

def get_previous_by_updated_at(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

def id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):
roles

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

users

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

blocks_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

shift_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

memos

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

class Hospital.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class Hospital.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

class UserManager(django.contrib.auth.base_user.BaseUserManager):
 99class UserManager(BaseUserManager):
100    """
101    Custom manager for User model.
102
103    Methods:
104        - create_user(): Creates a regular user.
105        - create_superuser(): Creates a superuser.
106    """
107    use_in_migrations = True
108    
109    def create_user(self, institution_id, role, phone_number, hospital, password=None):
110        """
111        Creates and saves a User with the given institution_id, role, phone_number, and hospital.
112        Password is optional as it might be set later.
113        """
114        if not institution_id:
115            raise ValueError('Users must have a institution ID')
116        if not role:
117            raise ValueError('Users must have a role')
118        if not phone_number:
119            raise ValueError('Users must have a phone number')
120
121        # Generate a globally unique institution_id by combining hospital_id and display_id
122        if not hospital:
123            raise ValueError('Regular users must have a hospital')
124            
125        user = self.model(
126            institution_id=institution_id,
127            role=role,
128            phone_number=phone_number,
129            hospital=hospital,
130        )
131        
132        if password:
133            user.set_password(password)
134            user.password_set = True
135        else:
136            user.set_unusable_password()
137            user.password_set = False
138        
139        # Set is_staff=True for hospital admins
140        if role.name == 'ADMIN':
141            user.is_staff = True
142            
143        user.save(using=self._db)
144        return user
145        
146    def create_superuser(self, institution_id, role, phone_number, hospital, password=None):
147        """
148        Creates and saves a User with the given institution_id, role, phone_number, and hospital.
149        Password is optional as it might be set later.
150        """
151        if not institution_id:
152            raise ValueError('Users must have a institution ID')
153        if not phone_number:
154            raise ValueError('Users must have a phone number')
155            
156        user = self.model(
157            institution_id=institution_id,
158            role=role,
159            phone_number=phone_number,
160            hospital=hospital,
161            is_staff=True,
162            is_superuser=True
163        )
164        
165        if password:
166            user.set_password(password)
167            user.password_set = True
168        else:
169            user.set_unusable_password()
170            user.password_set = False
171        
172        user.save(using=self._db)
173        return user

Custom manager for User model.

Methods: - create_user(): Creates a regular user. - create_superuser(): Creates a superuser.

use_in_migrations = True
def create_user(self, institution_id, role, phone_number, hospital, password=None):
109    def create_user(self, institution_id, role, phone_number, hospital, password=None):
110        """
111        Creates and saves a User with the given institution_id, role, phone_number, and hospital.
112        Password is optional as it might be set later.
113        """
114        if not institution_id:
115            raise ValueError('Users must have a institution ID')
116        if not role:
117            raise ValueError('Users must have a role')
118        if not phone_number:
119            raise ValueError('Users must have a phone number')
120
121        # Generate a globally unique institution_id by combining hospital_id and display_id
122        if not hospital:
123            raise ValueError('Regular users must have a hospital')
124            
125        user = self.model(
126            institution_id=institution_id,
127            role=role,
128            phone_number=phone_number,
129            hospital=hospital,
130        )
131        
132        if password:
133            user.set_password(password)
134            user.password_set = True
135        else:
136            user.set_unusable_password()
137            user.password_set = False
138        
139        # Set is_staff=True for hospital admins
140        if role.name == 'ADMIN':
141            user.is_staff = True
142            
143        user.save(using=self._db)
144        return user

Creates and saves a User with the given institution_id, role, phone_number, and hospital. Password is optional as it might be set later.

def create_superuser(self, institution_id, role, phone_number, hospital, password=None):
146    def create_superuser(self, institution_id, role, phone_number, hospital, password=None):
147        """
148        Creates and saves a User with the given institution_id, role, phone_number, and hospital.
149        Password is optional as it might be set later.
150        """
151        if not institution_id:
152            raise ValueError('Users must have a institution ID')
153        if not phone_number:
154            raise ValueError('Users must have a phone number')
155            
156        user = self.model(
157            institution_id=institution_id,
158            role=role,
159            phone_number=phone_number,
160            hospital=hospital,
161            is_staff=True,
162            is_superuser=True
163        )
164        
165        if password:
166            user.set_password(password)
167            user.password_set = True
168        else:
169            user.set_unusable_password()
170            user.password_set = False
171        
172        user.save(using=self._db)
173        return user

Creates and saves a User with the given institution_id, role, phone_number, and hospital. Password is optional as it might be set later.

class User(django.contrib.auth.base_user.AbstractBaseUser, django.contrib.auth.models.PermissionsMixin):
175class User(AbstractBaseUser, PermissionsMixin):
176    """
177    Represents a hospital user.
178
179    Fields:
180        - institution_id: Display ID (unique within a hospital).
181        - hospital: ForeignKey to Hospital.
182        - role: ForeignKey to Role.
183        - phone_number: Unique phone number.
184        - current_block: ForeignKey to Blocks (current block).
185        - current_ward: ForeignKey to Ward (current ward).
186        - fcm_token: FCM token for push notifications.
187        - fcm_token_updated_at: Timestamp of last FCM token update.
188        - current_device: Device info.
189        - is_active: Is user active.
190        - is_logged_in: Is user currently logged in.
191        - is_staff: Is user staff.
192        - is_superuser: Is user superuser.
193        - date_joined: Timestamp when user joined.
194        - password_set: Has user set their password.
195
196    Meta:
197        - db_table: Table name in DB.
198
199    Methods:
200        - __str__(): String representation of the user.
201        - has_perm(): Always returns True.
202        - has_module_perms(): Always returns True.
203    """
204    institution_id = models.CharField(max_length=100, verbose_name='Display ID')
205    hospital = models.ForeignKey(Hospital, null=True,blank=True,on_delete=models.CASCADE,related_name='users')
206    role = models.ForeignKey('Role',null=True,blank=True, on_delete=models.SET_NULL,verbose_name='Role')
207    phone_number = models.CharField(max_length=15,unique=True,validators=[RegexValidator(regex=r'^(\+91|91|0)?[-.\s]?(\d{10})$')], blank=True, null=True, verbose_name='Phone Number')
208    current_block = models.ForeignKey('management.Blocks', on_delete=models.SET_NULL, null=True, blank=True)
209    current_ward = models.ForeignKey('management.Ward', on_delete=models.SET_NULL, null=True, blank=True)
210    fcm_token = models.CharField(max_length=512, blank=True, null=True, verbose_name='FCM Token')
211    fcm_token_updated_at = models.DateTimeField(blank=True, null=True)
212    current_device = models.CharField(max_length=100, blank=True, null=True, verbose_name='Current Device')
213    
214    class Meta:
215        db_table = 'users'
216    is_active = models.BooleanField(default=True)
217    is_logged_in = models.BooleanField(default=False, verbose_name='Logged In', help_text='Indicates if the user is currently logged in')
218    is_staff = models.BooleanField(default=False)
219    is_superuser = models.BooleanField(default=False)
220    date_joined = models.DateTimeField(default=timezone.now)
221    password_set = models.BooleanField(default=False, help_text='Indicates if the user has set their password')
222    
223    objects = UserManager()
224    
225    USERNAME_FIELD = 'phone_number'
226    REQUIRED_FIELDS = ['role']
227    
228    def __str__(self):
229        return self.institution_id
230    
231    def has_perm(self, perm, obj=None):
232        "Does the user have a specific permission?"
233        return True
234
235    def has_module_perms(self, app_label):
236        "Does the user have permissions to view the app `app_label`?"
237        return True

Represents a hospital user.

Fields: - institution_id: Display ID (unique within a hospital). - hospital: ForeignKey to Hospital. - role: ForeignKey to Role. - phone_number: Unique phone number. - current_block: ForeignKey to Blocks (current block). - current_ward: ForeignKey to Ward (current ward). - fcm_token: FCM token for push notifications. - fcm_token_updated_at: Timestamp of last FCM token update. - current_device: Device info. - is_active: Is user active. - is_logged_in: Is user currently logged in. - is_staff: Is user staff. - is_superuser: Is user superuser. - date_joined: Timestamp when user joined. - password_set: Has user set their password.

Meta: - db_table: Table name in DB.

Methods: - __str__(): String representation of the user. - has_perm(): Always returns True. - has_module_perms(): Always returns True.

def institution_id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

hospital

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

role

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

def phone_number(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

current_block

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

current_ward

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

def fcm_token(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def fcm_token_updated_at(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def current_device(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_active(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_logged_in(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_staff(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def is_superuser(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def date_joined(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def password_set(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = ['role']
def has_perm(self, perm, obj=None):
231    def has_perm(self, perm, obj=None):
232        "Does the user have a specific permission?"
233        return True

Does the user have a specific permission?

def has_module_perms(self, app_label):
235    def has_module_perms(self, app_label):
236        "Does the user have permissions to view the app `app_label`?"
237        return True

Does the user have permissions to view the app app_label?

def password(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def last_login(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

groups

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example::

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

user_permissions

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example::

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

hospital_id
role_id
current_block_id
current_ward_id
def get_next_by_date_joined(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

def get_previous_by_date_joined(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

def id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

logentry_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

auth_token

Accessor to the related object on the reverse side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

blocks_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

user

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

shift_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

blockchange_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

wardchange_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

events

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

attendee_eta

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

class User.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class User.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

class SiteUser(django.db.models.base.Model):
239class SiteUser(models.Model):
240    """
241    Represents an admin user for the institution (not hospital).
242
243    Fields:
244        - name: Admin username.
245        - password: Hashed password.
246
247    Meta:
248        - db_table: Table name in DB.
249
250    Methods:
251        - save(): Hashes password before saving.
252        - check_password(): Checks password against hash.
253        - __str__(): String representation of the admin user.
254    """
255    name = models.CharField(max_length=100)
256    password = models.CharField(max_length=300)
257    
258    class Meta:
259        db_table = 'site_users'
260    
261    def save(self, *args, **kwargs):
262        """Encrypt password using SHA256 hash."""
263        self.password = hashlib.sha256(self.password.encode()).hexdigest()
264        super().save(*args, **kwargs)
265        
266    def check_password(self, raw_password):
267        """Check password using SHA256 hash."""
268        return hashlib.sha256(raw_password.encode()).hexdigest() == self.password
269    
270    def __str__(self):
271        return self.name

Represents an admin user for the institution (not hospital).

Fields: - name: Admin username. - password: Hashed password.

Meta: - db_table: Table name in DB.

Methods: - save(): Hashes password before saving. - check_password(): Checks password against hash. - __str__(): String representation of the admin user.

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def password(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def save(self, *args, **kwargs):
261    def save(self, *args, **kwargs):
262        """Encrypt password using SHA256 hash."""
263        self.password = hashlib.sha256(self.password.encode()).hexdigest()
264        super().save(*args, **kwargs)

Encrypt password using SHA256 hash.

def check_password(self, raw_password):
266    def check_password(self, raw_password):
267        """Check password using SHA256 hash."""
268        return hashlib.sha256(raw_password.encode()).hexdigest() == self.password

Check password using SHA256 hash.

def id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):
class SiteUser.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class SiteUser.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.