models.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. # coding=utf-8
  2. from django.utils import timezone
  3. from django.conf import settings
  4. from django.db import models
  5. from apps.log.models import BizLog
  6. from apps.tenant import tenant_log
  7. from apps.tenant.models import Tenant
  8. from apps.upload.models import Upload
  9. from apps.tenant.building.models import Building
  10. from utils.exceptions import CustomError
  11. from apps.tenant.option.models import Option
  12. from utils.format import strftime, strfsecond
  13. from apps.account.models import User
  14. class RepairOrder(models.Model):
  15. REPAIR_ORDER = 1
  16. INSPECTION_ORDER = 2
  17. ORDER_TYPE = (
  18. (REPAIR_ORDER, '报修工单'),
  19. (INSPECTION_ORDER, '巡检转报修工单')
  20. )
  21. no = models.CharField(max_length=50, verbose_name='单号', blank=True)
  22. tenant = models.ForeignKey(Tenant, verbose_name=u'租户', on_delete=models.PROTECT, blank=True)
  23. building = models.ForeignKey(Building, verbose_name='楼宇', on_delete=models.PROTECT, blank=True, null=True)
  24. fault_des = models.CharField(max_length=200, verbose_name='故障描述')
  25. repair_type = models.ForeignKey(Option, verbose_name='报修类型', on_delete=models.PROTECT)
  26. user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"报修人员", on_delete=models.PROTECT,
  27. editable=False)
  28. name = models.CharField(max_length=11, verbose_name='报修人员')
  29. tel = models.CharField(max_length=11, verbose_name='报修电话')
  30. repair_users = models.ManyToManyField(settings.AUTH_USER_MODEL, verbose_name='维修人员', related_name='repair_users')
  31. status = models.PositiveSmallIntegerField(choices=settings.REPAIR_STATUS_CHOICES, verbose_name=u'状态',
  32. default=settings.NOT_CHECKED)
  33. order_type = models.PositiveSmallIntegerField(choices=ORDER_TYPE, verbose_name=u'工单类型',
  34. default=REPAIR_ORDER)
  35. images = models.ManyToManyField(Upload, verbose_name='图片', blank=True)
  36. create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
  37. delete = models.BooleanField(verbose_name='删除', default=False)
  38. class Meta:
  39. db_table = 'repair_order'
  40. verbose_name = '报修工单'
  41. ordering = ['-create_time']
  42. index_together = (
  43. 'status',
  44. 'create_time',
  45. )
  46. default_permissions = ()
  47. permissions = [
  48. ('browse_repair_order', u'查看'),
  49. ('add_repair_order', u'添加'),
  50. ('delete_repair_order', u'删除'),
  51. ('check_repair_order', u'审核'),
  52. ('invalid_repair_order', u'作废'),
  53. ('dispatch_repair_order', u'派工'),
  54. ('rob_repair_order', u'抢单'),
  55. ('finish_repair_order', u'完工'),
  56. ]
  57. def get_no(self):
  58. now = timezone.now()
  59. no = '%s%d-%s' % ('BX', self.tenant.id, now.strftime('%Y%m%d%H%M%S'))
  60. return no
  61. def get_full_building(self):
  62. builiding = u'{0}-{1}-{2}'.format(self.building.building,self.building.floor,self.building.location,)
  63. return builiding
  64. @staticmethod
  65. def get_instance_by_id(id, tenant):
  66. try:
  67. id = int(id)
  68. except:
  69. raise CustomError('无效的报修单ID')
  70. instance = RepairOrder.objects.filter(pk=id, tenant=tenant, delete=False).first()
  71. if not instance:
  72. raise CustomError('未找到对应的报修工单')
  73. return instance
  74. def hange_up_repair_order(self, user, reason):
  75. # 挂起
  76. if not self.status == settings.DISPATCH:
  77. raise CustomError('当前报修工单不允许挂起!')
  78. self.status = settings.HANG_UP
  79. self.save()
  80. RepairOrderRecord.objects.create(repair_order=self, status=settings.HANG_UP, user=user, notes=reason)
  81. tenant_log(user.employee, BizLog.INSERT, u'挂起报修工单[%s],id=%d' % (self.no, self.id))
  82. def cancel_hange_up_repair_order(self, user):
  83. # 取消挂起
  84. if not self.status == settings.HANG_UP:
  85. raise CustomError('当前报修工单非挂起状态!')
  86. self.status = settings.DISPATCH
  87. self.save()
  88. RepairOrderRecord.objects.create(repair_order=self, status=settings.CANCEL_HANG_UP, user=user)
  89. tenant_log(user.employee, BizLog.INSERT, u'取消挂起报修工单[%s],id=%d' % (self.no, self.id))
  90. def check_repair_order(self, user):
  91. # 审核
  92. if self.status > settings.NOT_CHECKED:
  93. raise CustomError('当前报修工单状态已审核!')
  94. self.status = settings.CHECKED
  95. self.save()
  96. RepairOrderRecord.objects.create(repair_order=self, status=settings.CHECKED, user=user)
  97. tenant_log(user.employee, BizLog.INSERT, u'审核报修工单[%s],id=%d' % (self.no, self.id))
  98. def dispatch_repair_order(self, user, dispacth_users):
  99. self.status = settings.DISPATCH
  100. self.repair_users.add(dispacth_users)
  101. self.save()
  102. # 记录操作
  103. RepairOrderRecord.objects.create(repair_order=self, status=settings.DISPATCH, user=user,
  104. repair_users=dispacth_users)
  105. def invalid(self, user):
  106. # 作废
  107. if self.status == settings.NOT_CHECKED:
  108. raise CustomError('当前报修工单状态未审核,不能进行作废!')
  109. if self.status > settings.APPRAISE:
  110. raise CustomError('该报修单已作废!')
  111. self.status = settings.INVALID
  112. self.save()
  113. # 记录操作
  114. RepairOrderRecord.objects.create(repair_order=self, status=settings.INVALID, user=user)
  115. tenant_log(user.employee, BizLog.UPDATE, u'作废报修工单[%s],id=%d' % (self.no, self.id))
  116. def finish_order(self, user, notes, images):
  117. # 完工
  118. self.status = settings.FINISH
  119. self.save()
  120. # 记录操作
  121. repair_order_record = RepairOrderRecord.objects.create(repair_order=self, status=settings.FINISH, user=user,
  122. notes=notes)
  123. for image in images:
  124. repair_order_record.images.add(image)
  125. repair_order_record.save()
  126. class RepairOrderRecord(models.Model):
  127. repair_order = models.ForeignKey(RepairOrder, verbose_name='报修工单', on_delete=models.PROTECT,
  128. related_name='repair_order_record')
  129. status = models.PositiveSmallIntegerField(choices=settings.REPAIR_STATUS_CHOICES, verbose_name=u'状态',
  130. default=settings.NOT_CHECKED)
  131. user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"操作人", on_delete=models.PROTECT,
  132. editable=False)
  133. notes = models.CharField(max_length=500, verbose_name='备注', null=True)
  134. repair_users = models.CharField(max_length=500, verbose_name='维修人员', null=True)
  135. operation_time = models.DateTimeField(verbose_name='操作时间', auto_now_add=True)
  136. class Meta:
  137. db_table = 'repair_order_record'
  138. verbose_name = '维修工单记录'
  139. ordering = ['operation_time']
  140. default_permissions = ()
  141. def get_records(self, order_id):
  142. dict = {
  143. 'status': self.status,
  144. 'status_text': settings.REPAIR_STATUS_CHOICES[self.status - 1][1],
  145. 'operation_time': strftime(self.operation_time),
  146. }
  147. user_name = self.user.employee.name
  148. if self.status == settings.NOT_CHECKED:
  149. dict['no'] = self.repair_order.no
  150. dict['desc'] = u'下单人:{}-{}'.format(self.repair_order.name, self.repair_order.tel)
  151. dict['tel'] = self.repair_order.tel
  152. elif self.status == settings.CHECKED:
  153. dict['desc'] = u'审核人:{}'.format(user_name)
  154. elif self.status == settings.DISPATCH:
  155. user_ids = self.repair_users.split(',') or []
  156. repair_users = User.objects.filter(id__in=user_ids).values('employee__name', 'employee__tel', )
  157. e_name = [u'{0}-{1}'.format(e['employee__name'], e['employee__tel']) for e in repair_users]
  158. if str(self.user.id) in user_ids:
  159. desc = u'维修工【{0}】接单'.format(','.join(e_name))
  160. if self.repair_order.order_type == RepairOrder.INSPECTION_ORDER:
  161. desc = u'维修工【{0}】巡检转维修接单'.format(','.join(e_name))
  162. else:
  163. desc = u'【{0}】派单给维修工【{1}】'.format(user_name, ','.join(e_name))
  164. dict['desc'] = desc
  165. dict['employees'] = [{'name': e['employee__name'], 'tel': e['employee__tel']} for e in repair_users]
  166. elif self.status == settings.HANG_UP:
  167. dict['desc'] = u'挂起原因:{}'.format(self.notes)
  168. elif self.status == settings.FINISH:
  169. dispatch_time = RepairOrderRecord.objects.filter(repair_order_id=order_id,
  170. status=settings.DISPATCH).order_by(
  171. 'operation_time').first()
  172. diff_time = self.operation_time - dispatch_time.operation_time
  173. hang_up = RepairOrderRecord.objects.filter(repair_order_id=order_id, status=settings.HANG_UP).first()
  174. if hang_up:
  175. cancel_hang_up = RepairOrderRecord.objects.filter(repair_order_id=order_id,
  176. status=settings.CANCEL_HANG_UP).first()
  177. # 挂起时间
  178. hang_up_time = cancel_hang_up.operation_time - hang_up.operation_time
  179. diff_time = diff_time - hang_up_time
  180. desc = u'维修工【{0}】完工,共用时:{1}天{2}'.format(user_name, diff_time.days, strfsecond(diff_time.seconds))
  181. dict['desc'] = desc
  182. order_finish = RepairOrderFinish.objects.filter(repair_order=order_id).first()
  183. dict['fault_cause'] = order_finish.fault_cause.name
  184. dict['content'] = order_finish.content
  185. dict['images'] = []
  186. images = order_finish.images.all()
  187. for img in images:
  188. dict['images'].append(
  189. {
  190. 'url': img.picture
  191. }
  192. )
  193. elif self.status == settings.TURN_EMPLOYEE:
  194. user_ids = self.repair_users.split(',') or []
  195. e_name = User.objects.filter(id__in=user_ids).values('employee__name', 'employee__tel', )
  196. e_name = [e['employee__name'] + '-' + e['employee__tel'] for e in e_name]
  197. desc = u'【{0}】转单给维修工【{1}】'.format(user_name, ','.join(e_name))
  198. dict['desc'] = desc
  199. elif self.status == settings.APPRAISE:
  200. comment = RepairOrderComment.objects.filter(repair_order_id=order_id).first()
  201. if comment:
  202. dict['desc'] = u'评价内容:{0}'.format(comment.content)
  203. dict['start'] = comment.start
  204. else:
  205. dict['desc'] = ''
  206. return dict
  207. class RepairOrderComment(models.Model):
  208. repair_order = models.ForeignKey(RepairOrder, verbose_name='报修工单', on_delete=models.PROTECT,
  209. related_name='repair_order_comment')
  210. content = models.CharField(max_length=200, verbose_name='评价内容')
  211. user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"评价人", on_delete=models.PROTECT,
  212. editable=False)
  213. start = models.PositiveSmallIntegerField(verbose_name='评分', default=5)
  214. create_time = models.DateTimeField(verbose_name='评价时间', auto_now_add=True)
  215. class Meta:
  216. db_table = 'repair_order_comment'
  217. verbose_name = '维修工单评价'
  218. default_permissions = ()
  219. class RepairOrderFinish(models.Model):
  220. repair_order = models.ForeignKey(RepairOrder, verbose_name='报修工单', on_delete=models.PROTECT)
  221. fault_cause = models.ForeignKey(Option, verbose_name=u'故障原因', on_delete=models.PROTECT)
  222. quality_date = models.DateField(verbose_name=u'质保到期', null=True)
  223. content = models.CharField(verbose_name=u'完工内容', max_length=500, null=True)
  224. images = models.ManyToManyField(Upload, verbose_name='图片', blank=True)
  225. class Meta:
  226. db_table = 'repair_order_finish'
  227. verbose_name = '维修完工'
  228. ordering = ['-id']
  229. default_permissions = ()