models.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. # coding=utf-8
  2. from django.db import models
  3. from django.db.models import Q
  4. from django.conf import settings
  5. from django.utils import timezone
  6. from apps.customer.models import Customer
  7. from apps.order.models import Order
  8. from apps.customer.models import SuperiorDistributor
  9. from utils.exceptions import CustomError
  10. '''
  11. 现金返利及现金变动记录
  12. '''
  13. class CashLog(models.Model):
  14. CASH_REBATE = 1
  15. CASH_TRANSFER = 2
  16. TYPE_CHOICES = (
  17. (CASH_REBATE, u'现金返利'),
  18. (CASH_TRANSFER, u'返利提现'),
  19. )
  20. customer = models.ForeignKey(Customer, verbose_name=u'客户', on_delete=models.PROTECT)
  21. type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=u"类型")
  22. happen_time = models.DateTimeField(verbose_name=u"发生时间", default=timezone.now)
  23. amount = models.BigIntegerField(verbose_name=u"变动额")
  24. balance = models.BigIntegerField(verbose_name=u"余额")
  25. class Meta:
  26. db_table = "cash_log"
  27. verbose_name = u'现金日志'
  28. ordering = ['-happen_time',]
  29. index_together = (
  30. 'happen_time',
  31. )
  32. default_permissions = ()
  33. permissions = []
  34. @staticmethod
  35. def addnew(customer, type, amount):
  36. customer.balance += amount
  37. # if customer.balance < 0:
  38. # raise CustomError(u'用户余额不足!')
  39. customer.save()
  40. instance = CashLog.objects.create(
  41. customer=customer,
  42. type=type,
  43. happen_time=timezone.now(),
  44. amount=amount,
  45. balance=customer.balance
  46. )
  47. return instance
  48. class CashRebate(models.Model):
  49. order = models.ForeignKey(Order, verbose_name=u'订单', related_name='cash_rebate_order', editable=False, on_delete=models.PROTECT)
  50. ratio = models.FloatField(verbose_name=u'返利比例', default=0)
  51. amount = models.BigIntegerField(verbose_name=u'返利金额', default=0)
  52. customer = models.ForeignKey(Customer, verbose_name=u'客户', editable=False, on_delete=models.PROTECT)
  53. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now, editable=False)
  54. class Meta:
  55. db_table = "cash_rebate"
  56. verbose_name = u'现金返利'
  57. ordering = []
  58. index_together = ()
  59. default_permissions = ()
  60. permissions = []
  61. class CashRebateLog(models.Model):
  62. rebate = models.OneToOneField(CashRebate, verbose_name=u'现金返利', related_name='rebate', editable=False, on_delete=models.PROTECT)
  63. log = models.OneToOneField(CashLog, verbose_name=u'日志', related_name='rebate_log', editable=False, on_delete=models.PROTECT)
  64. class Meta:
  65. db_table = "cash_rebate_log"
  66. verbose_name = u'现金返利日志'
  67. ordering = []
  68. index_together = ()
  69. default_permissions = ()
  70. permissions = []
  71. @staticmethod
  72. def addnew(rebate):
  73. customer = Customer.objects.select_for_update().filter(id=rebate.customer.id).first()
  74. log = CashLog.addnew(customer, CashLog.CASH_REBATE, rebate.amount)
  75. instance = CashRebateLog.objects.create(rebate=rebate, log=log)
  76. return instance
  77. class TransferCashRebate(models.Model):
  78. DEFAULT = 0 # 未处理 没有申请转账
  79. ACCEPTED = 1 # 已受理。
  80. PROCESSING = 2 # 转账中。已开始处理批次内的转账明细单
  81. WAIT_PAY = 3 # 待付款 商户员工确认付款阶段
  82. FINISHED = 4 # 已完成。批次内的所有转账明细单都处理完成
  83. CLOSED = 5 # 已关闭。可查询具体的批次关闭原因
  84. STATUS = (
  85. (DEFAULT, u'未处理'),
  86. (ACCEPTED, u'已受理'),
  87. (PROCESSING, u'转账中'),
  88. (WAIT_PAY, u'待付款'),
  89. (FINISHED, u'已完成'),
  90. (CLOSED, u'已关闭'),
  91. )
  92. order = models.ForeignKey(Order, verbose_name=u'订单', related_name='transfer_order', editable=False, on_delete=models.PROTECT)
  93. no = models.CharField(max_length=50, verbose_name=u'批次号', editable=False, null=True, blank=True)
  94. transfer_status = models.PositiveSmallIntegerField(choices=STATUS, verbose_name=u"返利转账状态", default=DEFAULT)
  95. batch_id = models.CharField(verbose_name=u"微信批次单号", max_length=100, null=True, blank=True)
  96. transfer_time = models.DateTimeField(verbose_name=u"批次创建时间", null=True, blank=True)
  97. transfer_amount = models.BigIntegerField(verbose_name=u'转账总金额', default=0, editable=False)
  98. transfer_num = models.IntegerField(verbose_name=u'转账总笔数', default=0, editable=False)
  99. success_amount = models.BigIntegerField(verbose_name=u'转账成功金额', default=0, editable=False)
  100. success_num = models.IntegerField(verbose_name=u"转账成功笔数", default=0, editable=False)
  101. fail_amount = models.BigIntegerField(verbose_name=u"转账失败金额", default=0, editable=False)
  102. fail_num = models.IntegerField(verbose_name=u"转账失败笔数", default=0, editable=False)
  103. update_time = models.DateTimeField(verbose_name=u"批次更新时间", null=True, blank=True)
  104. close_reason = models.CharField(verbose_name=u"批次关闭原因", max_length=100, null=True, blank=True)
  105. class Meta:
  106. db_table = "transfer"
  107. verbose_name = u'返利转账'
  108. ordering = ['id']
  109. index_together = ()
  110. unique_together = (
  111. 'no',
  112. )
  113. default_permissions = ()
  114. permissions = []
  115. class TransferCashRebateDetail(models.Model):
  116. DEFAULT = 0
  117. PENDING = 1
  118. SUCCESS = 2
  119. FAIL = 3
  120. STATUS_CHOICES = (
  121. (DEFAULT, u'未处理'),
  122. (PENDING, u'转账中'), # 正在处理中,转账结果尚未明确
  123. (SUCCESS, u'转账成功'),
  124. (FAIL, u'转账失败'), # 需要确认失败原因后,在决定是否重新发起对该笔明细单的转账(并非真个转账批次单) 重新发起转账 需要新的批次号重新发起转账
  125. )
  126. no = models.CharField(max_length=50, verbose_name=u'单号', editable=False, null=True, blank=True)
  127. main = models.ForeignKey(TransferCashRebate, verbose_name=u'转账', related_name='transfer_detail_main', editable=False, on_delete=models.PROTECT)
  128. rebate = models.ForeignKey(CashRebate, verbose_name=u'返利', related_name='transfer_detail_Rebate', editable=False, on_delete=models.PROTECT)
  129. amount = models.BigIntegerField(verbose_name=u'返利金额', default=0)
  130. customer = models.ForeignKey(Customer, verbose_name=u'客户', editable=False, on_delete=models.PROTECT)
  131. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now, editable=False)
  132. detail_no = models.CharField(verbose_name=u"微信明细单号", max_length=100, null=True, blank=True)
  133. status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"转账状态", default=DEFAULT)
  134. fail_reason = models.CharField(max_length=1000, verbose_name=u"转账失败原因", null=True, blank=True)
  135. initiate_time = models.DateTimeField(verbose_name=u'转账发起时间', null=True, blank=True)
  136. update_time = models.DateTimeField(verbose_name=u'明细更新时间', null=True, blank=True)
  137. class Meta:
  138. db_table = "transfer_detail"
  139. verbose_name = u'返利转账明细'
  140. ordering = ['id', ]
  141. index_together = ()
  142. unique_together = (
  143. 'no',
  144. )
  145. default_permissions = ()
  146. permissions = []
  147. class CashTransferLog(models.Model):
  148. transfer = models.OneToOneField(TransferCashRebateDetail, verbose_name=u'返利转账', related_name='transfer', editable=False, on_delete=models.PROTECT)
  149. log = models.OneToOneField(CashLog, verbose_name=u'日志', related_name='transfer_log', editable=False, on_delete=models.PROTECT)
  150. class Meta:
  151. db_table = "cash_transfer_log"
  152. verbose_name = u'现金返利提现日志'
  153. ordering = []
  154. index_together = ()
  155. default_permissions = ()
  156. permissions = []
  157. @staticmethod
  158. def addnew(transfer):
  159. customer = Customer.objects.select_for_update().filter(id=transfer.customer.id).first()
  160. log = CashLog.addnew(customer, CashLog.CASH_TRANSFER, -transfer.amount)
  161. instance = CashTransferLog.objects.create(transfer=transfer, log=log)
  162. return instance
  163. '''
  164. 积分返利及积分变动记录
  165. '''
  166. class PointLog(models.Model):
  167. POINT_REBATE = 1
  168. POINT_ORDER = 2
  169. POINT_GIVE = 3
  170. POINT_CANCEL = 4
  171. TYPE_CHOICES = (
  172. (POINT_REBATE, u'积分返利'),
  173. (POINT_ORDER, u'积分兑换商品'),
  174. (POINT_GIVE, u'购买商品赠送积分'), # 购买商品赠送的积分
  175. (POINT_CANCEL, u'取消订单返还积分'), # 取消订单的时候将已扣除的积分返还
  176. )
  177. customer = models.ForeignKey(Customer, verbose_name=u'客户', on_delete=models.PROTECT)
  178. type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=u"类型")
  179. happen_time = models.DateTimeField(verbose_name=u"发生时间", default=timezone.now)
  180. amount = models.IntegerField(verbose_name=u"变动额")
  181. balance = models.IntegerField(verbose_name=u"余额")
  182. class Meta:
  183. db_table = "point_log"
  184. verbose_name = u'积分日志'
  185. ordering = ['-happen_time',]
  186. index_together = (
  187. 'happen_time',
  188. )
  189. default_permissions = ()
  190. permissions = []
  191. @staticmethod
  192. def addnew(customer, type, point):
  193. customer.points += point
  194. if customer.points < 0:
  195. raise CustomError(u'用户积分不足!')
  196. customer.save()
  197. instance = PointLog.objects.create(
  198. customer=customer,
  199. type=type,
  200. happen_time=timezone.now(),
  201. amount=point,
  202. balance=customer.points
  203. )
  204. return instance
  205. class PointRebate(models.Model):
  206. order = models.ForeignKey(Order, verbose_name=u'订单', related_name='point_rebate_order', editable=False, on_delete=models.PROTECT)
  207. ratio = models.FloatField(verbose_name=u'返利比例', default=0)
  208. amount = models.IntegerField(verbose_name=u'返利积分', default=0)
  209. customer = models.ForeignKey(Customer, verbose_name=u'客户', editable=False, on_delete=models.PROTECT)
  210. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now, editable=False)
  211. class Meta:
  212. db_table = "point_rebate"
  213. verbose_name = u'积分返利'
  214. ordering = []
  215. index_together = ()
  216. default_permissions = ()
  217. permissions = []
  218. class PointGive(models.Model):
  219. order = models.ForeignKey(Order, verbose_name=u'订单', related_name='point_give_order', editable=False, on_delete=models.PROTECT)
  220. ratio = models.FloatField(verbose_name=u'赠送比例', default=0)
  221. amount = models.IntegerField(verbose_name=u'赠送积分', default=0)
  222. customer = models.ForeignKey(Customer, verbose_name=u'客户', editable=False, on_delete=models.PROTECT)
  223. create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now, editable=False)
  224. class Meta:
  225. db_table = "point_give"
  226. verbose_name = u'积分返利'
  227. ordering = []
  228. index_together = ()
  229. default_permissions = ()
  230. permissions = []
  231. class PointLogOrder(models.Model):
  232. order = models.ForeignKey(Order, verbose_name=u'订单', related_name='order', editable=False, on_delete=models.PROTECT)
  233. log = models.OneToOneField(PointLog, verbose_name=u'日志', related_name='order_log', editable=False, on_delete=models.PROTECT)
  234. class Meta:
  235. db_table = "point_log_order"
  236. verbose_name = u'积分兑换日志'
  237. ordering = []
  238. index_together = ()
  239. default_permissions = ()
  240. permissions = []
  241. @staticmethod
  242. def addnew(order, cancel_order=False):
  243. customer = Customer.objects.select_for_update().filter(id=order.customer.id).first()
  244. total_point = -order.total_point
  245. type = PointLog.POINT_ORDER
  246. if cancel_order:
  247. # 如果是作废订单就将订单积分加上去
  248. total_point = order.total_point
  249. type = PointLog.POINT_CANCEL
  250. log = PointLog.addnew(customer, type, total_point)
  251. instance = PointLogOrder.objects.create(order=order, log=log)
  252. return instance
  253. class PointRebateLog(models.Model):
  254. rebate = models.OneToOneField(PointRebate, verbose_name=u'积分返利', related_name='rebate', editable=False, on_delete=models.PROTECT)
  255. log = models.OneToOneField(PointLog, verbose_name=u'日志', related_name='rebate_log', editable=False, on_delete=models.PROTECT)
  256. class Meta:
  257. db_table = "point_log_rebate"
  258. verbose_name = u'积分返利日志'
  259. ordering = []
  260. index_together = ()
  261. default_permissions = ()
  262. permissions = []
  263. @staticmethod
  264. def addnew(rebate):
  265. customer = Customer.objects.select_for_update().filter(id=rebate.customer.id).first()
  266. log = PointLog.addnew(customer, PointLog.POINT_REBATE, rebate.amount)
  267. instance = PointRebateLog.objects.create(rebate=rebate, log=log)
  268. return instance
  269. class PointGiveLog(models.Model):
  270. give = models.OneToOneField(PointGive, verbose_name=u'赠送积分', related_name='give', editable=False, on_delete=models.PROTECT)
  271. log = models.OneToOneField(PointLog, verbose_name=u'日志', related_name='give_log', editable=False, on_delete=models.PROTECT)
  272. class Meta:
  273. db_table = "point_log_give"
  274. verbose_name = u'赠送积分日志'
  275. ordering = []
  276. index_together = ()
  277. default_permissions = ()
  278. permissions = []
  279. @staticmethod
  280. def addnew(give):
  281. customer = Customer.objects.select_for_update().filter(id=give.customer.id).first()
  282. log = PointLog.addnew(customer, PointLog.POINT_GIVE, give.amount)
  283. instance = PointGiveLog.objects.create(give=give, log=log)
  284. return instance