models.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. from mongoengine import StringField, DateTimeField, IntField, ObjectIdField, Q, DoesNotExist, BooleanField, ListField
  5. from apps.web.constant import INSURANCE_CATEGORY
  6. from apps.web.core.db import Searchable, MonetaryField
  7. from apps.web.dealer.models import Dealer
  8. from apps.web.device.models import Group
  9. from apps.web.user.models import MyUser, RechargeRecord
  10. class InsuranceOrder(Searchable):
  11. """
  12. 用户的上保订单
  13. """
  14. # 保险种类的ID
  15. insuranceId = StringField(verbose_name = u"母单")
  16. name = StringField(verbose_name=u"保险名称")
  17. # 用户的投保单号
  18. orderNo = StringField(verbose_name = u"投保单号")
  19. # 用户的信息
  20. openId = StringField(verbose_name = u"用户")
  21. ownerId = StringField(verbose_name = u"经销商")
  22. devNo = StringField(verbose_name = u"设备IMEI")
  23. logicalCode = StringField(verbose_name = u"设备编号")
  24. groupId = StringField(verbose_name = "投保地址")
  25. # 实际支付的保单的价格
  26. money = MonetaryField(verbose_name = u"支付")
  27. # 可以报险的时间段 36小时
  28. startTime = DateTimeField(verbose_name = u"起始时间")
  29. endTime = DateTimeField(verbose_name = u"结束时间")
  30. # 有效情况 退款后保单失效
  31. effective = IntField(verbose_name = u"有效", choices = (0, 1), default = 1)
  32. # 关联的支付订单
  33. rechargeRcdId = ObjectIdField(verbose_name = u"支付订单")
  34. # 报险
  35. applyTime = DateTimeField(verbose_name = u"报险时间")
  36. phoneNumber = StringField(verbose_name = u"联系电话")
  37. # 保单的创建时间
  38. dateTimeAdded = DateTimeField(verbose_name = u"创建时间", default = datetime.datetime.now)
  39. # meta = {
  40. # 'collection': 'InsuranceOrder'
  41. # }
  42. @staticmethod
  43. def get_insurance_order_no(insurance):
  44. """
  45. 用户的投保单号 目前使用大保单号进行显示
  46. :param insurance:
  47. :return:
  48. """
  49. return insurance.insuranceNo
  50. @classmethod
  51. def create_by_recharge(cls, rechargeOrder, insurance): # type:(RechargeRecord, Insurance) -> InsuranceOrder
  52. """
  53. 创建用户的保单
  54. :param rechargeOrder:
  55. :param insurance:
  56. :return:
  57. """
  58. order = cls(
  59. insuranceId = str(insurance.id),
  60. name = insurance.name,
  61. openId = rechargeOrder.openId,
  62. ownerId = rechargeOrder.ownerId,
  63. devNo = rechargeOrder.devNo,
  64. logicalCode = rechargeOrder.logicalCode,
  65. groupId = rechargeOrder.groupId,
  66. money = rechargeOrder.money,
  67. startTime = rechargeOrder.dateTimeAdded,
  68. endTime = rechargeOrder.dateTimeAdded + datetime.timedelta(hours = insurance.validTime),
  69. rechargeRcdId = rechargeOrder.id
  70. )
  71. order.orderNo = cls.get_insurance_order_no(insurance)
  72. return order.save()
  73. @classmethod
  74. def get_user_effective_orders(cls, openId): # type:(str) -> QuerySet
  75. """
  76. 获取用户 未进行退款的 保险订单
  77. :param openId:
  78. :return:
  79. """
  80. return cls.objects.filter(openId = openId, effective = 1)
  81. @classmethod
  82. def get_user_not_effective_orders(cls, openId):
  83. """
  84. 获取用户已经完全失效的保险订单(退款的)
  85. """
  86. return cls.objects.filter(openId = openId, effective = 0)
  87. @classmethod
  88. def get_user_legal_order(cls, openId):
  89. """
  90. 获取用户可以报险的保险单
  91. """
  92. nowTime = datetime.datetime.now()
  93. return cls.get_user_effective_orders(openId).filter(
  94. endTime__gte=nowTime,
  95. startTime__lte=nowTime
  96. )
  97. @classmethod
  98. def get_user_expired_order(cls, openId):
  99. """
  100. 获取用户 已经失去报险资格的保险单
  101. """
  102. nowTime = datetime.datetime.now()
  103. return cls.get_user_effective_orders(openId).filter(
  104. Q(endTime__lt=nowTime) | Q(startTime__gt=nowTime)
  105. )
  106. @classmethod
  107. def get_user_effective_by_recharge_order(cls, rechargeOrder):
  108. """
  109. 通过充值订单 查询相应的保险单 有效的
  110. """
  111. return cls.get_user_legal_order(rechargeOrder.openId).filter(rechargeRcdId = rechargeOrder.id).first()
  112. @classmethod
  113. def apply(cls, orderId, phoneNumber, openId):
  114. """
  115. 报险
  116. :param orderId:
  117. :param phoneNumber:
  118. :param openId:
  119. :return:
  120. """
  121. result = cls.objects.filter(
  122. id = orderId,
  123. openId = openId
  124. ).filter(
  125. effective = 1,
  126. applyTime = None,
  127. phoneNumber = None
  128. ).update(
  129. applyTime = datetime.datetime.now(),
  130. phoneNumber = phoneNumber
  131. )
  132. return result
  133. @property
  134. def dealer(self):
  135. return Dealer.get_dealer(self.ownerId)
  136. @property
  137. def group(self):
  138. return Group.get_group(self.groupId)
  139. @property
  140. def user(self):
  141. return MyUser.objects.get(groupId = self.groupId, openId = self.openId)
  142. @property
  143. def rechargeOrder(self):
  144. return RechargeRecord.objects.get(id = self.rechargeRcdId)
  145. @property
  146. def insurance(self):
  147. try:
  148. insurance = Insurance.objects.get(id = self.insuranceId)
  149. except DoesNotExist:
  150. return None
  151. return insurance
  152. def cancel(self):
  153. """
  154. 一般是退款后调用 将订单置为失效状态
  155. :return:
  156. """
  157. self.effective = 0
  158. self.save()
  159. def to_dict(self):
  160. return {
  161. "id": str(self.id),
  162. "name": self.name,
  163. "openId": self.openId,
  164. "ownerId": self.ownerId,
  165. "devNo": self.devNo,
  166. "logicalCode": self.logicalCode,
  167. "groupId": self.groupId,
  168. "money": self.money,
  169. "startTime": self.startTime.strftime("%Y-%m-%d %H:%M:%S"),
  170. "endTime": self.endTime.strftime("%Y-%m-%d %H:%M:%S"),
  171. "dateTimeAdded": self.dateTimeAdded.strftime("%Y-%m-%d %H:%M:%S"),
  172. "applyTime": self.applyTime.strftime("%Y-%m-%d %H:%M:%S") if self.applyTime else "",
  173. "phoneNumber": self.phoneNumber or ""
  174. }
  175. from mongoengine.signals import post_save
  176. # 检测订单是否变为失效或者变为生效
  177. def save_success_message(sender, document, created): # type:(InsuranceOrder.__class__, InsuranceOrder, bool) -> None
  178. from taskmanager.mediator import task_caller
  179. # 保单刚刚生效 发送通知给用户 保单生效
  180. if created:
  181. task_caller("notify_insurance_order_subscribe", orderId = str(document.id))
  182. return
  183. # 保单被取消的时候 发送 保单失效给用户
  184. if not created and not document.effective:
  185. task_caller("notify_insurance_order_cancel", orderId = str(document.id))
  186. return
  187. # 信号注册
  188. post_save.connect(receiver = save_success_message, sender = InsuranceOrder)
  189. class Insurance(Searchable):
  190. """
  191. 用户充电险
  192. 目前
  193. """
  194. # 大保单的保单号
  195. insuranceNo = StringField(verbose_name = u"保单号", required = True)
  196. # 对外显示的名称
  197. name = StringField(verbose_name = u"保险的名称")
  198. # 单次购买定价
  199. price = MonetaryField(verbose_name = u"价格", required = True)
  200. # 报险的过期时间
  201. validTime = IntField(verbose_name = u"有效期", default = 12)
  202. # 是否在售
  203. onSale = BooleanField(verbose_name = u"销售状态", default = False)
  204. # 保险的种类 (目前只有充电险、后续可能会有骑行险或者是偷盗险一类的)
  205. category = StringField(verbose_name = u"种类", choices = INSURANCE_CATEGORY.choices())
  206. # 支持的主设备类型 某些不支持的直接排除
  207. supportMajorDeviceType = ListField(verbose_name = u"支持的主设备类型", default = [u"充电桩"])
  208. @classmethod
  209. def get_on_sale_by_id(cls, _id):
  210. try:
  211. obj = cls.objects.get(id = _id, onSale = True)
  212. except DoesNotExist:
  213. return None
  214. return obj
  215. @classmethod
  216. def get_on_sale_by_category(cls, category):
  217. return cls.objects.filter(onSale=True, category=category).first()
  218. @property
  219. def categoryName(self):
  220. if self.category == INSURANCE_CATEGORY.CHARGE:
  221. return u"充电险"
  222. if self.category == INSURANCE_CATEGORY.STOLEN:
  223. return u"偷盗险"
  224. if self.category == INSURANCE_CATEGORY.CYCLE:
  225. return u"骑行险"
  226. return
  227. def to_dict(self):
  228. return {
  229. "id": str(self.id),
  230. "price": self.price,
  231. "validTime": self.validTime
  232. }