models.py 12 KB

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