Нема описа

models.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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. try:
  132. for h0 in Hospital.objects.all():
  133. p2 = (h0.geolocation.lat, h0.geolocation.lon)
  134. p1 = (self.geolocation.lat, self.geolocation.lon)
  135. d = round(hs.haversine(p1,p2), 2)
  136. if d < dlimit:
  137. #bd += f"<tr><td>{h0.title}</td><td>{d}km</td></tr>"
  138. temps.append({'title': h0.title, 'd': d, 'id': h0.id, 'beds': h0.free_beds()})
  139. #print(f"to {h0.title} => {hs.haversine(p1, p2)}km")
  140. temps.sort(key= lambda s: s['d'], reverse=False)
  141. for t in temps:
  142. 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>"
  143. rt = f'''
  144. <br>
  145. <table><thead><tr><th>Hospital</th><th>Distance</th><th>Free Beds</th></tr></thead>
  146. <tbody>
  147. {bd}
  148. </tbody>
  149. </table>
  150. '''
  151. return rt
  152. except:
  153. return "-"
  154. def nearby(self):
  155. #self.nearby_from_db()
  156. try:
  157. r = gmaps.places_nearby(location=(self.geolocation.lat, self.geolocation.lon), type="hospital", radius=10000)
  158. bd = ""
  159. for r0 in r['results']:
  160. openh = "-"
  161. if 'opening_hours' in r0:
  162. openh = r0['opening_hours']['open_now']
  163. else:
  164. openh = "-"
  165. bd += f"<tr><td>{r0['name']}</td><td>{openh}</td><td>{r0['vicinity']}</td></tr>"
  166. rt = f'''
  167. <br>
  168. <table><thead><tr><th>Name</th><th>Opening Hours</th><th>Vicinity</th></tr></thead>
  169. <tbody>
  170. {bd}
  171. </tbody>
  172. </table>
  173. '''
  174. return rt
  175. except:
  176. return "-"
  177. class ImportFile(models.Model):
  178. hospital_file = models.FileField(upload_to="uploads/%Y/%m/%d/", blank=True, verbose_name="Hospital (csv)")
  179. def save(self, *args, **kwargs):
  180. super(ImportFile, self).save(*args, **kwargs)
  181. with self.hospital_file.open('r') as csv_file:
  182. csv_reader = csv.reader(csv_file, delimiter=',')
  183. Hospital.objects.all().delete()
  184. line_count = 0
  185. for r in csv_reader:
  186. if line_count > 0:
  187. print(r)
  188. print(f"{r[7]},{r[6]}")
  189. try:
  190. gp = map_fields.GeoPt(lat=float(r[6]), lon=float(r[7]))
  191. location = fromstr(f'POINT({r[7]} {r[6]})', srid=4326)
  192. print(location)
  193. h = Hospital(title=r[3], address_text=r[5], geolocation=gp, address=r[3])
  194. h.save()
  195. except Exception as e:
  196. print(e)
  197. line_count += 1
  198. class Place(models.Model):
  199. #title = models.Char
  200. title = models.CharField(max_length=200, blank=True, null=True)
  201. address = map_fields.AddressField(max_length=200)
  202. geolocation = map_fields.GeoLocationField(max_length=100)
  203. created_at = models.DateTimeField(auto_now_add=True, null=True)
  204. updated_at = models.DateTimeField(auto_now=True)
  205. more_info = models.JSONField(null=True, blank=True)
  206. def __str__(self):
  207. return f"{self.address} ({self.geolocation})"
  208. class Hospital(models.Model):
  209. title = models.CharField(max_length=200)
  210. location = models.PointField(blank=True, null=True)
  211. address_text = models.TextField(blank=True, null=True)
  212. #address = models.CharField(max_length=100)
  213. address = map_fields.AddressField(max_length=200)
  214. geolocation = map_fields.GeoLocationField(max_length=100)
  215. tel = models.CharField(max_length=100, null=True, blank=True)
  216. line_id = models.CharField(max_length=100, null=True, blank=True)
  217. created_at = models.DateTimeField(auto_now_add=True, null=True)
  218. updated_at = models.DateTimeField(auto_now=True)
  219. def __str__(self):
  220. return f"{self.title} {self.address_text}"
  221. def free_beds(self):
  222. return self.bed_set.filter(~Q(occupy=True)).count()
  223. class Points(models.Model):
  224. #src = models.ForeignKey(Place, on_delete=models.SET_NULL, null=True, blank=False, related_name='src')
  225. #ticket = models.ForeignKey(AmbulanceTicket, on_delete=models.SET_NULL, null=True)
  226. dest = models.ForeignKey(Hospital, on_delete=models.SET_NULL, null=True, blank=False)
  227. address = map_fields.AddressField(max_length=200, null=True)
  228. geolocation = map_fields.GeoLocationField(max_length=100, null=True)
  229. distance = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=7, verbose_name="Distance (km)")
  230. duration = models.CharField(max_length=200, null=True, blank=True)
  231. directions = models.JSONField(null=True, blank=True)
  232. def save(self, *args, **kwargs):
  233. geocode_result = gmaps.geocode('1600 Amphitheatre Parkway, Mountain View, CA')
  234. print(geocode_result)
  235. print(self.geolocation)
  236. origin = [(self.geolocation.lat, self.geolocation.lon)]
  237. dest = [(self.dest.geolocation.lat, self.dest.geolocation.lon)]
  238. dst = gmaps.distance_matrix(origin, dest)
  239. dirs = gmaps.directions(origin[0], dest[0])
  240. self.directions = dirs
  241. print(dirs)
  242. self.distance = dst['rows'][0]['elements'][0]['distance']['value'] / 1000
  243. self.duration = dst['rows'][0]['elements'][0]['duration']['text']
  244. print(dst)
  245. super(Points, self).save(*args, **kwargs)
  246. class Bed(models.Model):
  247. code = models.CharField(max_length=30)
  248. occupy = models.BooleanField(default=False)
  249. patient = models.ForeignKey(Patient, on_delete=models.SET_NULL, null=True, blank=True)
  250. hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE)
  251. created_at = models.DateTimeField(auto_now_add=True, null=True)
  252. updated_at = models.DateTimeField(auto_now=True)
  253. def __str__(self):
  254. return self.code
  255. class PatientLog(models.Model):
  256. patient = models.ForeignKey(Patient, on_delete=models.SET_NULL, null=True)
  257. hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, null=True)
  258. bed = ChainedForeignKey(
  259. "Bed",
  260. chained_field="hospital",
  261. chained_model_field="hospital",
  262. show_all=False,
  263. auto_choose=True,
  264. null=True
  265. )
  266. notes = models.TextField(blank=True, null=True)
  267. condition_level = models.CharField(
  268. max_length=30,
  269. choices=(("green", "Green"), ("yellow", "Yellow"), ("red", "Red")),
  270. null=True,
  271. )
  272. status = models.CharField(
  273. max_length=30,
  274. choices=(("active", "Active"), ("inactive", "Inactive"), ("transfer", "Transfer")),
  275. null=True,
  276. )
  277. checkin_at = models.DateTimeField(null=True, blank=True)
  278. checkout_at = models.DateTimeField(null=True, blank=True)
  279. created_at = models.DateTimeField(auto_now_add=True, null=True)
  280. updated_at = models.DateTimeField(auto_now=True)