#from django.db import models from django.contrib.gis.db import models from django_google_maps import fields as map_fields from colorfield.fields import ColorField #from smart_selects.db_fields import GroupedForeignKey from smart_selects.db_fields import ( ChainedForeignKey, ChainedManyToManyField, GroupedForeignKey, ) from django.db.models import Q import googlemaps from django.contrib.gis.geos import fromstr from django.conf import settings import csv import haversine as hs gmaps = googlemaps.Client(key=settings.GOOGLE_MAPS_API_KEY) # Create your models here. GENDER_CHOICES = ( ('นางสาว','นางสาว'), ('นาย','นาย'), ('นาง', 'นาง'), ("ด.ช.","เด็กชาย"), ("ด.ญ.","เด็กหญิง"), ) class Ambulance(models.Model): code = models.CharField(max_length=100) license_plate = models.CharField(max_length=100) brand = models.CharField(max_length=100) model_name = models.CharField(max_length=100) comment = models.TextField(blank=True, null=True) color = ColorField(default='#FF0000') status = models.CharField( max_length=30, choices=(("working", "Working"), ("free", "Free"), ("ma", "MA")), null=True, ) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.license_plate} ({self.get_status_display()}) {self.code} {self.brand} / {self.model_name}" class Driver(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) age = models.IntegerField() idcard = models.CharField(max_length=20, null=True, blank=False) prefix = models.CharField( max_length=30, choices=GENDER_CHOICES, null=True, ) sex = models.CharField( max_length=30, choices=(("male", "Male"), ("female", "Female"),), null=True, ) photo = models.FileField(upload_to="uploads/%Y/%m/%d/", blank=True, verbose_name="Photo") address = models.TextField(blank=True, null=True) #test status = models.CharField( max_length=30, choices=(("working", "Working"), ("free", "Free"), ("block", "Block")), null=True, ) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.first_name} {self.last_name} ({self.get_status_display()})" class AmbulanceTicket(models.Model): driver = models.ForeignKey(Driver, on_delete=models.SET_NULL, null=True) ambulance = models.ForeignKey(Ambulance, on_delete=models.SET_NULL, null=True) status = models.CharField( max_length=30, choices=(("working", "Working"), ("free", "Free"), ("ma", "MA")), null=True, ) checkin_at = models.DateTimeField(null=True, blank=True) checkout_at = models.DateTimeField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True) def save(self, *args, **kwargs): super(AmbulanceTicket, self).save(*args, **kwargs) self.ambulance.status = self.status self.ambulance.save() self.driver.status = "working" self.driver.save() def __str__(self): return f"{self.driver}@{self.ambulance}" class Patient(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) birth_date = models.DateField(null=True) age = models.IntegerField(null=True, blank=True) idcard = models.CharField(max_length=20, null=True, blank=False) tel = models.CharField(max_length=100, null=True, blank=True) line_id = models.CharField(max_length=100, null=True, blank=True) prefix = models.CharField( max_length=30, choices=GENDER_CHOICES, null=True, ) sex = models.CharField( max_length=30, choices=(("male", "Male"), ("female", "Female"),), null=True, ) photo = models.FileField(upload_to="uploads/%Y/%m/%d/", blank=True, verbose_name="Photo") address = map_fields.AddressField(max_length=200, null=True) geolocation = map_fields.GeoLocationField(max_length=100, null=True) condition_level = models.CharField( max_length=30, choices=(("green", "Green"), ("yellow", "Yellow"), ("red", "Red")), null=True, ) comment = models.TextField(blank=True, null=True) address_text = models.TextField(blank=True, null=True) #test patient_status = models.CharField( max_length=30, choices=(("request", "Request"), ("process", "Process"), ("complete", "Complete")), null=True, ) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): #self.nearby() return f"{self.first_name} {self.last_name}" def nearby_from_db(self, dlimit): bd = "" temps = [] try: for h0 in Hospital.objects.all(): p2 = (h0.geolocation.lat, h0.geolocation.lon) p1 = (self.geolocation.lat, self.geolocation.lon) d = round(hs.haversine(p1,p2), 2) if d < dlimit: #bd += f"{h0.title}{d}km" temps.append({'title': h0.title, 'd': d, 'id': h0.id, 'beds': h0.free_beds()}) #print(f"to {h0.title} => {hs.haversine(p1, p2)}km") temps.sort(key= lambda s: s['d'], reverse=False) for t in temps: bd += f"{t['title']}{t['d']} km{t['beds']}" rt = f'''
{bd}
HospitalDistanceFree Beds
''' return rt except: return "-" def nearby(self): #self.nearby_from_db() try: r = gmaps.places_nearby(location=(self.geolocation.lat, self.geolocation.lon), type="hospital", radius=10000) bd = "" for r0 in r['results']: openh = "-" if 'opening_hours' in r0: openh = r0['opening_hours']['open_now'] else: openh = "-" bd += f"{r0['name']}{openh}{r0['vicinity']}" rt = f'''
{bd}
NameOpening HoursVicinity
''' return rt except: return "-" class ImportFile(models.Model): hospital_file = models.FileField(upload_to="uploads/%Y/%m/%d/", blank=True, verbose_name="Hospital (csv)") def save(self, *args, **kwargs): super(ImportFile, self).save(*args, **kwargs) with self.hospital_file.open('r') as csv_file: csv_reader = csv.reader(csv_file, delimiter=',') Hospital.objects.all().delete() line_count = 0 for r in csv_reader: if line_count > 0: print(r) print(f"{r[7]},{r[6]}") try: gp = map_fields.GeoPt(lat=float(r[6]), lon=float(r[7])) location = fromstr(f'POINT({r[7]} {r[6]})', srid=4326) print(location) h = Hospital(title=r[3], address_text=r[5], geolocation=gp, address=r[3]) h.save() except Exception as e: print(e) line_count += 1 class Place(models.Model): #title = models.Char title = models.CharField(max_length=200, blank=True, null=True) address = map_fields.AddressField(max_length=200) geolocation = map_fields.GeoLocationField(max_length=100) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True) more_info = models.JSONField(null=True, blank=True) def __str__(self): return f"{self.address} ({self.geolocation})" class Hospital(models.Model): title = models.CharField(max_length=200) location = models.PointField(blank=True, null=True) address_text = models.TextField(blank=True, null=True) #address = models.CharField(max_length=100) address = map_fields.AddressField(max_length=200) geolocation = map_fields.GeoLocationField(max_length=100) tel = models.CharField(max_length=100, null=True, blank=True) line_id = models.CharField(max_length=100, null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.title} {self.address_text}" def free_beds(self): return self.bed_set.filter(~Q(occupy=True)).count() class Points(models.Model): #src = models.ForeignKey(Place, on_delete=models.SET_NULL, null=True, blank=False, related_name='src') #ticket = models.ForeignKey(AmbulanceTicket, on_delete=models.SET_NULL, null=True) dest = models.ForeignKey(Hospital, on_delete=models.SET_NULL, null=True, blank=False) address = map_fields.AddressField(max_length=200, null=True) geolocation = map_fields.GeoLocationField(max_length=100, null=True) distance = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=7, verbose_name="Distance (km)") duration = models.CharField(max_length=200, null=True, blank=True) directions = models.JSONField(null=True, blank=True) def save(self, *args, **kwargs): geocode_result = gmaps.geocode('1600 Amphitheatre Parkway, Mountain View, CA') print(geocode_result) print(self.geolocation) origin = [(self.geolocation.lat, self.geolocation.lon)] dest = [(self.dest.geolocation.lat, self.dest.geolocation.lon)] dst = gmaps.distance_matrix(origin, dest) dirs = gmaps.directions(origin[0], dest[0]) self.directions = dirs print(dirs) self.distance = dst['rows'][0]['elements'][0]['distance']['value'] / 1000 self.duration = dst['rows'][0]['elements'][0]['duration']['text'] print(dst) super(Points, self).save(*args, **kwargs) class Bed(models.Model): code = models.CharField(max_length=30) occupy = models.BooleanField(default=False) patient = models.ForeignKey(Patient, on_delete=models.SET_NULL, null=True, blank=True) hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.code class PatientLog(models.Model): patient = models.ForeignKey(Patient, on_delete=models.SET_NULL, null=True) hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, null=True) bed = ChainedForeignKey( "Bed", chained_field="hospital", chained_model_field="hospital", show_all=False, auto_choose=True, null=True ) notes = models.TextField(blank=True, null=True) condition_level = models.CharField( max_length=30, choices=(("green", "Green"), ("yellow", "Yellow"), ("red", "Red")), null=True, ) status = models.CharField( max_length=30, choices=(("active", "Active"), ("inactive", "Inactive"), ("transfer", "Transfer")), null=True, ) checkin_at = models.DateTimeField(null=True, blank=True) checkout_at = models.DateTimeField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True, null=True) updated_at = models.DateTimeField(auto_now=True)