Нема описа

models.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #from django.db import models
  2. from django.contrib.gis.db import models
  3. from django_google_maps import fields as map_fields
  4. from colorfield.fields import ColorField
  5. #from smart_selects.db_fields import GroupedForeignKey
  6. from smart_selects.db_fields import (
  7. ChainedForeignKey,
  8. ChainedManyToManyField,
  9. GroupedForeignKey,
  10. )
  11. from django.db.models import Q
  12. import googlemaps
  13. from django.contrib.gis.geos import fromstr
  14. from django.conf import settings
  15. import csv
  16. import haversine as hs
  17. gmaps = googlemaps.Client(key=settings.GOOGLE_MAPS_API_KEY)
  18. # Create your models here.
  19. GENDER_CHOICES = (
  20. ('นางสาว','นางสาว'),
  21. ('นาย','นาย'),
  22. ('นาง', 'นาง'),
  23. ("ด.ช.","เด็กชาย"),
  24. ("ด.ญ.","เด็กหญิง"),
  25. )
  26. class Ambulance(models.Model):
  27. code = models.CharField(max_length=100)
  28. license_plate = models.CharField(max_length=100)
  29. brand = models.CharField(max_length=100)
  30. model_name = models.CharField(max_length=100)
  31. comment = models.TextField(blank=True, null=True)
  32. color = ColorField(default='#FF0000')
  33. status = models.CharField(
  34. max_length=30,
  35. choices=(("working", "Working"), ("free", "Free"), ("ma", "MA")),
  36. null=True,
  37. )
  38. created_at = models.DateTimeField(auto_now_add=True, null=True)
  39. updated_at = models.DateTimeField(auto_now=True)
  40. def __str__(self):
  41. return f"{self.license_plate} ({self.get_status_display()}) {self.code} {self.brand} / {self.model_name}"
  42. class Driver(models.Model):
  43. first_name = models.CharField(max_length=100)
  44. last_name = models.CharField(max_length=100)
  45. age = models.IntegerField()
  46. idcard = models.CharField(max_length=20, null=True, blank=False)
  47. prefix = models.CharField(
  48. max_length=30,
  49. choices=GENDER_CHOICES,
  50. null=True,
  51. )
  52. sex = models.CharField(
  53. max_length=30,
  54. choices=(("male", "Male"), ("female", "Female"),),
  55. null=True,
  56. )
  57. photo = models.FileField(upload_to="uploads/%Y/%m/%d/", blank=True, verbose_name="Photo")
  58. address = models.TextField(blank=True, null=True)
  59. #test
  60. status = models.CharField(
  61. max_length=30,
  62. choices=(("working", "Working"), ("free", "Free"), ("block", "Block")),
  63. null=True,
  64. )
  65. created_at = models.DateTimeField(auto_now_add=True, null=True)
  66. updated_at = models.DateTimeField(auto_now=True)
  67. def __str__(self):
  68. return f"{self.first_name} {self.last_name} ({self.get_status_display()})"
  69. class AmbulanceTicket(models.Model):
  70. driver = models.ForeignKey(Driver, on_delete=models.SET_NULL, null=True)
  71. ambulance = models.ForeignKey(Ambulance, on_delete=models.SET_NULL, null=True)
  72. status = models.CharField(
  73. max_length=30,
  74. choices=(("working", "Working"), ("free", "Free"), ("ma", "MA")),
  75. null=True,
  76. )
  77. checkin_at = models.DateTimeField(null=True, blank=True)
  78. checkout_at = models.DateTimeField(null=True, blank=True)
  79. created_at = models.DateTimeField(auto_now_add=True, null=True)
  80. updated_at = models.DateTimeField(auto_now=True)
  81. def save(self, *args, **kwargs):
  82. super(AmbulanceTicket, self).save(*args, **kwargs)
  83. self.ambulance.status = self.status
  84. self.ambulance.save()
  85. self.driver.status = "working"
  86. self.driver.save()
  87. def __str__(self):
  88. return f"{self.driver}@{self.ambulance}"
  89. class Patient(models.Model):
  90. first_name = models.CharField(max_length=100)
  91. last_name = models.CharField(max_length=100)
  92. birth_date = models.DateField(null=True)
  93. age = models.IntegerField(null=True, blank=True)
  94. idcard = models.CharField(max_length=20, null=True, blank=False)
  95. tel = models.CharField(max_length=100, null=True, blank=True)
  96. line_id = models.CharField(max_length=100, null=True, blank=True)
  97. prefix = models.CharField(
  98. max_length=30,
  99. choices=GENDER_CHOICES,
  100. null=True,
  101. )
  102. sex = models.CharField(
  103. max_length=30,
  104. choices=(("male", "Male"), ("female", "Female"),),
  105. null=True,
  106. )
  107. photo = models.FileField(upload_to="uploads/%Y/%m/%d/", blank=True, verbose_name="Photo")
  108. address = map_fields.AddressField(max_length=200, null=True)
  109. geolocation = map_fields.GeoLocationField(max_length=100, null=True)
  110. condition_level = models.CharField(
  111. max_length=30,
  112. choices=(("green", "Green"), ("yellow", "Yellow"), ("red", "Red")),
  113. null=True,
  114. )
  115. comment = models.TextField(blank=True, null=True)
  116. address_text = models.TextField(blank=True, null=True)
  117. #test
  118. patient_status = models.CharField(
  119. max_length=30,
  120. choices=(("request", "Request"), ("process", "Process"), ("complete", "Complete")),
  121. null=True,
  122. )
  123. created_at = models.DateTimeField(auto_now_add=True, null=True)
  124. updated_at = models.DateTimeField(auto_now=True)
  125. def __str__(self):
  126. #self.nearby()
  127. return f"{self.first_name} {self.last_name}"
  128. def nearby_from_db(self, dlimit):
  129. bd = ""
  130. temps = []
  131. for h0 in Hospital.objects.all():
  132. p2 = (h0.geolocation.lat, h0.geolocation.lon)
  133. p1 = (self.geolocation.lat, self.geolocation.lon)
  134. d = round(hs.haversine(p1,p2), 2)
  135. if d < dlimit:
  136. #bd += f"<tr><td>{h0.title}</td><td>{d}km</td></tr>"
  137. temps.append({'title': h0.title, 'd': d, 'id': h0.id, 'beds': h0.free_beds()})
  138. #print(f"to {h0.title} => {hs.haversine(p1, p2)}km")
  139. temps.sort(key= lambda s: s['d'], reverse=False)
  140. for t in temps:
  141. bd += f"<tr><td><a href='/admin/backend/hospital/{t['id']}/change/' target='_blank'>{t['title']}</a></td><td>{t['d']} km</td><td>{t['beds']}</td></tr>"
  142. rt = f'''
  143. <br>
  144. <table><thead><tr><th>Hospital</th><th>Distance</th><th>Free Beds</th></tr></thead>
  145. <tbody>
  146. {bd}
  147. </tbody>
  148. </table>
  149. '''
  150. return rt
  151. def nearby(self):
  152. #self.nearby_from_db()
  153. r = gmaps.places_nearby(location=(self.geolocation.lat, self.geolocation.lon), type="hospital", radius=10000)
  154. bd = ""
  155. for r0 in r['results']:
  156. openh = "-"
  157. if 'opening_hours' in r0:
  158. openh = r0['opening_hours']['open_now']
  159. else:
  160. openh = "-"
  161. bd += f"<tr><td>{r0['name']}</td><td>{openh}</td><td>{r0['vicinity']}</td></tr>"
  162. rt = f'''
  163. <br>
  164. <table><thead><tr><th>Name</th><th>Opening Hours</th><th>Vicinity</th></tr></thead>
  165. <tbody>
  166. {bd}
  167. </tbody>
  168. </table>
  169. '''
  170. return rt
  171. class ImportFile(models.Model):
  172. hospital_file = models.FileField(upload_to="uploads/%Y/%m/%d/", blank=True, verbose_name="Hospital (csv)")
  173. def save(self, *args, **kwargs):
  174. super(ImportFile, self).save(*args, **kwargs)
  175. with self.hospital_file.open('r') as csv_file:
  176. csv_reader = csv.reader(csv_file, delimiter=',')
  177. Hospital.objects.all().delete()
  178. line_count = 0
  179. for r in csv_reader:
  180. if line_count > 0:
  181. print(r)
  182. print(f"{r[7]},{r[6]}")
  183. try:
  184. gp = map_fields.GeoPt(lat=float(r[6]), lon=float(r[7]))
  185. location = fromstr(f'POINT({r[7]} {r[6]})', srid=4326)
  186. print(location)
  187. h = Hospital(title=r[3], address_text=r[5], geolocation=gp, address=r[3])
  188. h.save()
  189. except Exception as e:
  190. print(e)
  191. line_count += 1
  192. class Place(models.Model):
  193. #title = models.Char
  194. title = models.CharField(max_length=200, blank=True, null=True)
  195. address = map_fields.AddressField(max_length=200)
  196. geolocation = map_fields.GeoLocationField(max_length=100)
  197. created_at = models.DateTimeField(auto_now_add=True, null=True)
  198. updated_at = models.DateTimeField(auto_now=True)
  199. more_info = models.JSONField(null=True, blank=True)
  200. def __str__(self):
  201. return f"{self.address} ({self.geolocation})"
  202. class Hospital(models.Model):
  203. title = models.CharField(max_length=200)
  204. location = models.PointField(blank=True, null=True)
  205. address_text = models.TextField(blank=True, null=True)
  206. #address = models.CharField(max_length=100)
  207. address = map_fields.AddressField(max_length=200)
  208. geolocation = map_fields.GeoLocationField(max_length=100)
  209. tel = models.CharField(max_length=100, null=True, blank=True)
  210. line_id = models.CharField(max_length=100, null=True, blank=True)
  211. created_at = models.DateTimeField(auto_now_add=True, null=True)
  212. updated_at = models.DateTimeField(auto_now=True)
  213. def __str__(self):
  214. return f"{self.title} {self.address_text}"
  215. def free_beds(self):
  216. return self.bed_set.filter(~Q(occupy=True)).count()
  217. class Points(models.Model):
  218. #src = models.ForeignKey(Place, on_delete=models.SET_NULL, null=True, blank=False, related_name='src')
  219. #ticket = models.ForeignKey(AmbulanceTicket, on_delete=models.SET_NULL, null=True)
  220. dest = models.ForeignKey(Hospital, on_delete=models.SET_NULL, null=True, blank=False)
  221. address = map_fields.AddressField(max_length=200, null=True)
  222. geolocation = map_fields.GeoLocationField(max_length=100, null=True)
  223. distance = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=7, verbose_name="Distance (km)")
  224. duration = models.CharField(max_length=200, null=True, blank=True)
  225. directions = models.JSONField(null=True, blank=True)
  226. def save(self, *args, **kwargs):
  227. geocode_result = gmaps.geocode('1600 Amphitheatre Parkway, Mountain View, CA')
  228. print(geocode_result)
  229. print(self.geolocation)
  230. origin = [(self.geolocation.lat, self.geolocation.lon)]
  231. dest = [(self.dest.geolocation.lat, self.dest.geolocation.lon)]
  232. dst = gmaps.distance_matrix(origin, dest)
  233. dirs = gmaps.directions(origin[0], dest[0])
  234. self.directions = dirs
  235. print(dirs)
  236. self.distance = dst['rows'][0]['elements'][0]['distance']['value'] / 1000
  237. self.duration = dst['rows'][0]['elements'][0]['duration']['text']
  238. print(dst)
  239. super(Points, self).save(*args, **kwargs)
  240. class Bed(models.Model):
  241. code = models.CharField(max_length=30)
  242. occupy = models.BooleanField(default=False)
  243. patient = models.ForeignKey(Patient, on_delete=models.SET_NULL, null=True, blank=True)
  244. hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE)
  245. created_at = models.DateTimeField(auto_now_add=True, null=True)
  246. updated_at = models.DateTimeField(auto_now=True)
  247. def __str__(self):
  248. return self.code
  249. class PatientLog(models.Model):
  250. patient = models.ForeignKey(Patient, on_delete=models.SET_NULL, null=True)
  251. hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, null=True)
  252. bed = ChainedForeignKey(
  253. "Bed",
  254. chained_field="hospital",
  255. chained_model_field="hospital",
  256. show_all=False,
  257. auto_choose=True,
  258. null=True
  259. )
  260. notes = models.TextField(blank=True, null=True)
  261. condition_level = models.CharField(
  262. max_length=30,
  263. choices=(("green", "Green"), ("yellow", "Yellow"), ("red", "Red")),
  264. null=True,
  265. )
  266. status = models.CharField(
  267. max_length=30,
  268. choices=(("active", "Active"), ("inactive", "Inactive"), ("transfer", "Transfer")),
  269. null=True,
  270. )
  271. checkin_at = models.DateTimeField(null=True, blank=True)
  272. checkout_at = models.DateTimeField(null=True, blank=True)
  273. created_at = models.DateTimeField(auto_now_add=True, null=True)
  274. updated_at = models.DateTimeField(auto_now=True)