No Description

models.py 39KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. # -*- coding: utf-8 -*-
  2. from django.conf import settings
  3. from django.db import models
  4. from django.utils.translation import ugettext_lazy as _
  5. from django_models_ext import (BaseModelMixin, ProvinceShortModelMixin, SexModelMixin, upload_file_path,
  6. upload_file_url, upload_path)
  7. from jsonfield import JSONField
  8. from shortuuidfield import ShortUUIDField
  9. from TimeConvert import TimeConvert as tc
  10. from coupon.models import CouponInfo
  11. class AdministratorInfo(BaseModelMixin):
  12. ADMINISTRATOR = 0
  13. MAINTENANCE = 1
  14. OPERATOR = 2
  15. SALESMAN = 3
  16. USER_TYPE_TUPLE = (
  17. (ADMINISTRATOR, u'管理员'),
  18. (SALESMAN, u'销售员'),
  19. (MAINTENANCE, u'维修员'),
  20. (OPERATOR, u'运营人员'),
  21. )
  22. ACTIVATED = 1
  23. DISABLED = 2
  24. DELETED = 3
  25. USER_STATUS_TUPLE = (
  26. (ACTIVATED, u'已激活'),
  27. (DISABLED, u'已禁用'),
  28. (DELETED, u'已删除'),
  29. )
  30. admin_id = ShortUUIDField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'管理员唯一标识', db_index=True, unique=True)
  31. admin_type = models.IntegerField(_(u'admin_type'), choices=USER_TYPE_TUPLE, default=ADMINISTRATOR, help_text=u'管理员类型', db_index=True)
  32. phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'管理员电话', db_index=True)
  33. password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'管理员密码')
  34. encryption = models.CharField(_(u'encryption'), max_length=255, blank=True, null=True, help_text=u'管理员密码')
  35. name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'管理员姓名')
  36. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  37. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  38. user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS_TUPLE, default=ACTIVATED, help_text=u'管理员状态', db_index=True)
  39. class Meta:
  40. verbose_name = _(u'管理员信息')
  41. verbose_name_plural = _(u'管理员信息')
  42. def __unicode__(self):
  43. return u'{}-{}'.format(self.name, self.phone)
  44. class OperatorInfo(BaseModelMixin):
  45. ACTIVATED = 1
  46. DISABLED = 2
  47. DELETED = 3
  48. USER_STATUS_TUPLE = (
  49. (ACTIVATED, u'已激活'),
  50. (DISABLED, u'已禁用'),
  51. (DELETED, u'已删除'),
  52. )
  53. operator_id = ShortUUIDField(_(u'operator_id'), max_length=32, blank=True, null=True, help_text=u'操作员唯一标识', db_index=True, unique=True)
  54. phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'操作员电话', db_index=True)
  55. password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'操作员密码')
  56. encryption = models.CharField(_(u'encryption'), max_length=255, blank=True, null=True, help_text=u'操作员密码')
  57. name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'操作员姓名')
  58. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  59. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  60. brand_domain = models.CharField(_(u'brand_domain'), max_length=255, blank=True, null=True, help_text=u'品牌域名')
  61. user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS_TUPLE, default=ACTIVATED, help_text=u'操作员状态', db_index=True)
  62. class Meta:
  63. verbose_name = _(u'操作员信息')
  64. verbose_name_plural = _(u'操作员信息')
  65. def __unicode__(self):
  66. return u'{}-{}'.format(self.name, self.phone)
  67. @property
  68. def data(self):
  69. return {
  70. 'operator_id': self.operator_id,
  71. 'phone': self.phone,
  72. 'name': self.name,
  73. }
  74. @property
  75. def kododata(self):
  76. return {
  77. 'optor_id': self.operator_id,
  78. 'brand_domain': self.brand_domain or settings.KODO_DEFAULT_BRAND_DOMAIN,
  79. }
  80. class BrandInfo(BaseModelMixin):
  81. brand_id = ShortUUIDField(_(u'brand_id'), max_length=32, help_text=u'品牌唯一标识', db_index=True, unique=True)
  82. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  83. brand_descr = models.TextField(_(u'brand_descr'), max_length=255, blank=True, null=True, help_text=u'品牌描述')
  84. brand_logo = models.ImageField(_(u'brand_logo'), upload_to=upload_path, blank=True, null=True, help_text=u'品牌商标')
  85. brand_domain = models.CharField(_(u'brand_domain'), max_length=255, blank=True, null=True, help_text=u'品牌域名')
  86. position = models.IntegerField(_(u'position'), default=1, help_text=u'排序')
  87. class Meta:
  88. verbose_name = _(u'品牌信息')
  89. verbose_name_plural = _(u'品牌信息')
  90. def __unicode__(self):
  91. return '%d' % self.pk
  92. @property
  93. def brand_logo_url(self):
  94. return upload_file_url(self.brand_logo)
  95. @property
  96. def data(self):
  97. return {
  98. 'brand_id': str(self.pk),
  99. 'brand_name': self.brand_name,
  100. 'brand_descr': self.brand_descr,
  101. }
  102. class ModelInfo(BaseModelMixin):
  103. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  104. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  105. jancode = models.CharField(_(u'jancode'), max_length=16, blank=True, null=True, help_text=u'JAN_CODE', db_index=True)
  106. model_id = ShortUUIDField(_(u'model_id'), max_length=32, help_text=u'型号唯一标识', db_index=True, unique=True)
  107. model_name = models.CharField(_(u'model_name'), max_length=32, blank=True, null=True, help_text=u'型号名称')
  108. model_uni_name = models.CharField(_(u'model_uni_name'), max_length=32, blank=True, null=True, help_text=u'型号统一名称')
  109. model_full_name = models.CharField(_(u'model_full_name'), max_length=255, blank=True, null=True, help_text=u'型号全名称')
  110. model_descr = models.TextField(_(u'model_descr'), max_length=255, blank=True, null=True, help_text=u'型号描述')
  111. category = models.CharField(_(u'category'), max_length=32, blank=True, null=True, help_text=u'型号类别', db_index=True)
  112. warehouse = models.CharField(_(u'warehouse'), max_length=32, blank=True, null=True, help_text=u'所属仓库', db_index=True)
  113. image = models.ImageField(_(u'image'), upload_to=upload_path, blank=True, null=True, help_text=u'图片')
  114. url = models.CharField(_(u'url'), max_length=255, blank=True, null=True, help_text=u'链接')
  115. image2 = models.ImageField(_(u'image2'), upload_to=upload_path, blank=True, null=True, help_text=u'图片2')
  116. factory_yuan = models.FloatField(_(u'factory_yuan'), default=1000, help_text=u'出厂价(元)')
  117. factory_fee = models.IntegerField(_(u'factory_fee'), default=100000, help_text=u'出厂价(分)')
  118. integral = models.IntegerField(_(u'integral'), default=100, help_text=u'【销售员】卡路里')
  119. position = models.IntegerField(_(u'position'), default=1, help_text=u'排序')
  120. display = models.BooleanField(_(u'display'), default=True, help_text=_(u'Display'))
  121. is_important = models.BooleanField(_(u'is_important'), default=False, help_text=_(u'是否重要型号'))
  122. shot_type_id = models.CharField(_(u'shot_type_id'), max_length=32, blank=True, null=True, help_text=u'镜头类型唯一标识', db_index=True)
  123. shot_member_integral = models.IntegerField(_(u'shot_member_integral'), default=0, help_text=u'【消费者】镜头会员积分')
  124. shot_member_image = models.ImageField(_(u'shot_member_image'), upload_to=upload_path, blank=True, null=True, help_text=u'镜头会员图片')
  125. shot_member_name = models.CharField(_(u'shot_member_name'), max_length=255, blank=True, null=True, help_text=u'型号全名称')
  126. is_show_shot = models.BooleanField(_(u'is_show_shot'), default=False, help_text=_(u'是否在镜头类型里显示'))
  127. class Meta:
  128. verbose_name = _(u'型号信息')
  129. verbose_name_plural = _(u'型号信息')
  130. def __unicode__(self):
  131. return '%d' % self.pk
  132. @property
  133. def image_path(self):
  134. return upload_file_path(self.image)
  135. @property
  136. def image_url(self):
  137. return upload_file_url(self.image)
  138. @property
  139. def image2_path(self):
  140. return upload_file_path(self.image2)
  141. @property
  142. def image2_url(self):
  143. return upload_file_url(self.image2)
  144. @property
  145. def shot_member_image_path(self):
  146. return upload_file_path(self.shot_member_image)
  147. @property
  148. def shot_member_image_url(self):
  149. return upload_file_url(self.shot_member_image)
  150. @property
  151. def data(self):
  152. return {
  153. 'jancode': self.jancode,
  154. 'model_id': str(self.pk),
  155. 'model_name': self.model_name,
  156. 'model_descr': self.model_descr,
  157. }
  158. @property
  159. def imgdata(self):
  160. return {
  161. 'image_url': self.image_url,
  162. 'url': self.url,
  163. }
  164. @property
  165. def imgdata1(self):
  166. return self.shot_member_image_url
  167. @property
  168. def images(self):
  169. return [self.imgdata] if self.image else []
  170. # imgs = ModelImageInfo.objects.filter(model_id=self.model_id, status=True)
  171. # return [img.data for img in imgs]
  172. @property
  173. def admindata(self):
  174. return {
  175. 'jancode': self.jancode,
  176. 'model_id': self.model_id,
  177. 'model_name': self.model_name,
  178. 'model_uni_name': self.model_uni_name,
  179. 'model_full_name': self.model_full_name,
  180. 'model_descr': self.model_descr,
  181. 'category': self.category,
  182. 'warehouse': self.warehouse,
  183. 'image_path': self.image_path,
  184. 'image_url': self.image_url,
  185. 'image2_path': self.image2_path,
  186. 'image2_url': self.image2_url,
  187. 'factory_yuan': self.factory_yuan,
  188. 'integral': self.integral,
  189. 'is_important': self.is_important,
  190. }
  191. fulldata = admindata
  192. @property
  193. def member_shot_data(self):
  194. return {
  195. 'shot_id': self.model_id,
  196. 'shot_name': self.shot_member_name,
  197. 'shot_image': self.shot_member_image_url,
  198. 'integral': self.shot_member_integral,
  199. }
  200. @property
  201. def consumer_shot_data(self):
  202. from member.models import ShotTypeInfo
  203. shot_type = ShotTypeInfo.objects.get(shot_type_id=self.shot_type_id)
  204. return {
  205. 'model_id': self.model_id,
  206. 'model_name': self.model_name,
  207. 'model_uni_name': self.model_uni_name,
  208. 'model_full_name': self.model_full_name,
  209. 'model_desc': self.model_descr,
  210. 'shot_type': self.shot_type_id,
  211. 'shot_name': self.shot_member_name,
  212. 'shot_type_name': shot_type.shot_type_name
  213. }
  214. class ModelImageInfo(BaseModelMixin):
  215. model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)
  216. model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称')
  217. image = models.ImageField(_(u'image'), upload_to=upload_path, blank=True, null=True, help_text=u'图片')
  218. url = models.CharField(_(u'url'), max_length=255, blank=True, null=True, help_text=u'链接')
  219. position = models.IntegerField(_(u'position'), default=1, help_text=u'排序')
  220. class Meta:
  221. verbose_name = _(u'型号图片信息')
  222. verbose_name_plural = _(u'型号图片信息')
  223. def __unicode__(self):
  224. return '%d' % self.pk
  225. @property
  226. def image_url(self):
  227. return upload_file_url(self.image)
  228. @property
  229. def data(self):
  230. return {
  231. 'image_url': self.image_url,
  232. 'url': self.url,
  233. }
  234. class CameraModelInfo(BaseModelMixin):
  235. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  236. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  237. camera_brand_name = models.CharField(_(u'camera_brand_name'), max_length=255, blank=True, null=True, help_text=u'机身品牌')
  238. camera_name = models.CharField(_(u'camera_name'), max_length=255, blank=True, null=True, help_text=u'机身名称')
  239. camera_image = models.ImageField(_(u'camera_image'), upload_to=upload_path, blank=True, null=True, help_text=u'机身图片')
  240. camera_market_time = models.DateField(_(u'camera_market_time'), blank=True, null=True, help_text=u'机身上市日期')
  241. class Meta:
  242. verbose_name = _(u'机身信息')
  243. verbose_name_plural = _(u'机身信息')
  244. def __unicode__(self):
  245. return '%d' % self.pk
  246. class ModelCameraBodyInfo(BaseModelMixin):
  247. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  248. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  249. model_name = models.CharField(_(u'model_name'), max_length=32, blank=True, null=True, help_text=u'型号名称')
  250. model_full_name = models.CharField(_(u'model_full_name'), max_length=255, blank=True, null=True, help_text=u'型号全名称')
  251. model_image = models.ImageField(_(u'model_image'), upload_to=upload_path, blank=True, null=True, help_text=u'镜头图片')
  252. is_important = models.BooleanField(_(u'is_important'), default=False, help_text=_(u'是否重要型号'))
  253. camera_brand_name = models.CharField(_(u'camera_brand_name'), max_length=255, blank=True, null=True, help_text=u'机身品牌')
  254. camera_name = models.CharField(_(u'camera_name'), max_length=255, blank=True, null=True, help_text=u'机身名称')
  255. camera_image = models.ImageField(_(u'camera_image'), upload_to=upload_path, blank=True, null=True, help_text=u'机身图片')
  256. camera_market_time = models.DateField(_(u'camera_market_time'), blank=True, null=True, help_text=u'机身上市日期')
  257. is_ILDC = models.BooleanField(_(u'is_ILDC'), default=False, help_text=_(u'是否需要原厂转接环'))
  258. remark = models.CharField(_(u'remark'), max_length=255, blank=True, null=True, help_text=u'备注')
  259. class Meta:
  260. verbose_name = _(u'型号机身适配信息')
  261. verbose_name_plural = _(u'型号机身适配信息')
  262. def __unicode__(self):
  263. return '%d' % self.pk
  264. @property
  265. def model_url(self):
  266. return upload_file_url(self.model_image)
  267. @property
  268. def camera_url(self):
  269. return upload_file_url(self.camera_image)
  270. @property
  271. def final_camera_market_time(self):
  272. if not self.camera_market_time:
  273. return ''
  274. return tc.local_string(utc_dt=self.camera_market_time, format='%Y-%m-%d')
  275. @property
  276. def data(self):
  277. return {
  278. 'model_name': self.model_name,
  279. 'model_full_name': self.model_full_name,
  280. 'model_url': self.model_url,
  281. 'camera_brand_name': self.camera_brand_name,
  282. 'camera_name': self.camera_name,
  283. 'camera_url': self.camera_url,
  284. 'is_ILDC': self.is_ILDC,
  285. 'remark': self.remark,
  286. }
  287. class DistributorInfo(BaseModelMixin):
  288. DISTRIBOR_OFFICE_UNKNOWN = -1
  289. DISTRIBOR_OFFICE_BEIJING = 0
  290. DISTRIBOR_OFFICE_CHENGDOU = 1
  291. DISTRIBOR_OFFICE_GUANGZHOU = 2
  292. DISTRIBOR_OFFICE_SHANGHAI = 3
  293. DISTRIBOR_OFFICE_WUHAN = 4
  294. DISTRIBOR_OFFICE_XIAN = 5
  295. DISTRIBOR_OFFICE_SPACE = (
  296. (DISTRIBOR_OFFICE_UNKNOWN, u'未知'),
  297. (DISTRIBOR_OFFICE_BEIJING, u'北京所'),
  298. (DISTRIBOR_OFFICE_CHENGDOU, u'成都所'),
  299. (DISTRIBOR_OFFICE_GUANGZHOU, u'广州所'),
  300. (DISTRIBOR_OFFICE_SHANGHAI, u'上海所'),
  301. (DISTRIBOR_OFFICE_WUHAN, u'武汉所'),
  302. (DISTRIBOR_OFFICE_XIAN, u'西安所'),
  303. )
  304. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  305. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  306. distributor_id = ShortUUIDField(_(u'distributor_id'), max_length=32, help_text=u'经销商唯一标识', db_index=True, unique=True)
  307. distributor_name = models.CharField(_(u'distributor_name'), max_length=255, blank=True, null=True, help_text=u'经销商名称')
  308. distributor_short_name = models.CharField(_(u'distributor_short_name'), max_length=8, blank=True, null=True, help_text=u'经销商简称')
  309. distributor_descr = models.TextField(_(u'distributor_descr'), max_length=255, blank=True, null=True, help_text=u'经销商描述')
  310. distributor_province_code = models.CharField(_(u'distributor_province_code'), max_length=6, blank=True, null=True, help_text=u'经销商所在省份编码')
  311. distributor_province_name = models.CharField(_(u'distributor_province_name'), max_length=3, choices=ProvinceShortModelMixin.PROVINCE_NAME_TUPLE, default=ProvinceShortModelMixin.PROVINCE_DEFAULT_NAME, blank=True, null=True, help_text=u'经销商所在省份名称')
  312. department_id = models.IntegerField(_(u'department_id'), default=-1, help_text=u'企业微信部门ID')
  313. department_name = models.CharField(_(u'department_name'), max_length=32, blank=True, help_text=u'企业微信部门名称', db_index=True)
  314. sr_id = models.CharField(_(u'sr_id'), max_length=32, blank=True, null=True, help_text=u'销售担当唯一标识', db_index=True)
  315. office = models.IntegerField(_(u'office'), choices=DISTRIBOR_OFFICE_SPACE, default=DISTRIBOR_OFFICE_UNKNOWN, help_text=u'事务所', db_index=True)
  316. position = models.IntegerField(_(u'position'), default=1, help_text=u'排序')
  317. class Meta:
  318. verbose_name = _(u'经销商信息')
  319. verbose_name_plural = _(u'经销商信息')
  320. def __unicode__(self):
  321. return '%d' % self.pk
  322. @property
  323. def data(self):
  324. return {
  325. 'distributor_id': str(self.pk),
  326. 'distributor_name': self.distributor_name,
  327. 'distributor_short_name': self.distributor_short_name,
  328. 'distributor_descr': self.distributor_descr,
  329. }
  330. @property
  331. def admindata(self):
  332. return {
  333. 'distributor_id': self.distributor_id,
  334. 'distributor_name': self.distributor_name,
  335. 'distributor_short_name': self.distributor_short_name,
  336. 'distributor_descr': self.distributor_descr,
  337. 'province_code': self.distributor_province_code,
  338. 'province_name': self.distributor_province_name,
  339. 'sr_id': self.sr_id,
  340. 'office': self.office,
  341. }
  342. class SaleclerkInfo(BaseModelMixin, SexModelMixin):
  343. REFUSED = -1
  344. UNVERIFIED = 0
  345. ACTIVATED = 1
  346. DISABLED = 2
  347. DELETED = 3
  348. ASSIGN = 10
  349. USER_STATUS = (
  350. (REFUSED, u'已拒绝'),
  351. (UNVERIFIED, u'未验证'),
  352. (ACTIVATED, u'已激活'),
  353. (DISABLED, u'已禁用'),
  354. (DELETED, u'已删除'),
  355. (ASSIGN, u'已分配'),
  356. )
  357. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  358. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  359. distributor_id = models.CharField(_(u'distributor_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)
  360. distributor_name = models.CharField(_(u'distributor_name'), max_length=32, blank=True, null=True, help_text=u'经销商名称')
  361. clerk_id = ShortUUIDField(_(u'clerk_id'), max_length=32, help_text=u'店员唯一标识', db_index=True, unique=True)
  362. clerk_name = models.CharField(_(u'clerk_name'), max_length=32, blank=True, null=True, help_text=u'店员名称')
  363. clerk_sex = models.IntegerField(_(u'clerk_sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.MALE, help_text=u'店员性别', db_index=True)
  364. clerk_phone = models.CharField(_(u'clerk_phone'), max_length=11, blank=True, null=True, help_text=u'店员联系电话', unique=True)
  365. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  366. unionid = models.CharField(_(u'unionid'), max_length=32, blank=True, null=True, help_text=u'微信 UnionID', db_index=True)
  367. openid = models.CharField(_(u'openid'), max_length=32, blank=True, null=True, help_text=u'微信 OpenID', db_index=True)
  368. wx_userid = models.CharField(_(u'wx_userid'), max_length=32, blank=True, null=True, help_text=u'企业微信 user_id', db_index=True)
  369. num = models.IntegerField(_(u'num'), default=0, help_text=u'支数')
  370. integral = models.IntegerField(_(u'integral'), default=0, help_text=u'积分')
  371. total_integral = models.IntegerField(_(u'total_integral'), default=0, help_text=u'全部积分')
  372. user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED, help_text=u'用户状态', db_index=True)
  373. refused_reason = models.TextField(_(u'refused_reason'), blank=True, null=True, help_text=u'审核拒绝原因')
  374. is_auth = models.BooleanField(_(u'is_auth'), default=False, help_text=_(u'是否已授权'))
  375. test_user = models.BooleanField(_(u'test_user'), default=False, help_text=_(u'是否为测试用户'))
  376. is_online_sales = models.BooleanField(_(u'is_online_sales'), default=False, help_text=_(u'是否为网销'))
  377. class Meta:
  378. verbose_name = _(u'经销商销售员信息')
  379. verbose_name_plural = _(u'经销商销售员信息')
  380. unique_together = (
  381. ('clerk_phone', 'brand_id'),
  382. )
  383. def __unicode__(self):
  384. return '%d' % self.pk
  385. @property
  386. def admindata(self):
  387. return {
  388. 'distributor_id': self.distributor_id,
  389. 'distributor_name': self.distributor_name,
  390. 'clerk_id': self.clerk_id,
  391. 'clerk_name': self.clerk_name,
  392. 'clerk_sex': self.clerk_sex,
  393. 'clerk_phone': self.clerk_phone,
  394. 'num': self.num,
  395. 'integral': self.integral,
  396. 'total_integral': self.total_integral,
  397. 'status': self.user_status,
  398. 'refused_reason': self.refused_reason,
  399. 'is_auth': self.is_auth,
  400. 'is_online_sales': self.is_online_sales,
  401. }
  402. data = admindata
  403. class MaintenancemanInfo(BaseModelMixin, SexModelMixin):
  404. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  405. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  406. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True, unique=True)
  407. wx_userid = models.CharField(_(u'wx_userid'), max_length=32, blank=True, null=True, help_text=u'企业微信 user_id', db_index=True)
  408. maintenance_id = ShortUUIDField(_(u'maintenance_id'), max_length=32, help_text=u'维修员唯一标识', db_index=True, unique=True)
  409. maintenance_name = models.CharField(_(u'maintenance_name'), max_length=32, blank=True, null=True, help_text=u'维修员名称')
  410. maintenance_sex = models.IntegerField(_(u'maintenance_sex'), choices=SexModelMixin.SEX_TUPLE, default=SexModelMixin.MALE, help_text=u'维修员性别', db_index=True)
  411. maintenance_phone = models.CharField(_(u'maintenance_phone'), max_length=11, blank=True, null=True, help_text=u'维修员联系电话', unique=True)
  412. class Meta:
  413. verbose_name = _(u'维修员信息')
  414. verbose_name_plural = _(u'维修员信息')
  415. unique_together = (
  416. ('maintenance_phone', 'brand_id'),
  417. )
  418. def __unicode__(self):
  419. return '%d' % self.pk
  420. @property
  421. def data(self):
  422. return {
  423. 'maintenance_id': self.maintenance_id,
  424. 'maintenance_name': self.maintenance_name,
  425. 'maintenance_phone': self.maintenance_phone,
  426. }
  427. class BrandModelDistributorPriceInfo(BaseModelMixin):
  428. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  429. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  430. model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)
  431. model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称')
  432. distributor_id = models.CharField(_(u'distributor_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)
  433. distributor_name = models.CharField(_(u'distributor_name'), max_length=255, blank=True, null=True, help_text=u'经销商名称')
  434. factory_yuan = models.FloatField(_(u'factory_yuan'), default=1000, help_text=u'出厂价(元)')
  435. factory_fee = models.IntegerField(_(u'factory_fee'), default=100000, help_text=u'出厂价(分)')
  436. integral = models.IntegerField(_(u'integral'), default=100, help_text=u'积分')
  437. class Meta:
  438. verbose_name = _(u'品牌/型号/代理商价格信息')
  439. verbose_name_plural = _(u'品牌/型号/代理商价格信息')
  440. unique_together = (
  441. ('brand_id', 'model_id', 'distributor_id'),
  442. )
  443. def __unicode__(self):
  444. return '%d' % self.pk
  445. class LatestAppInfo(BaseModelMixin):
  446. latest_adr_version_code = models.IntegerField(_(u'latest_adr_version_code'), default=0, help_text=u'最新安卓版本号')
  447. latest_adr_version_name = models.CharField(_(u'latest_adr_version_name'), max_length=16, blank=True, null=True, help_text=u'最新安卓版本名')
  448. latest_adr_app = models.FileField(_(u'latest_adr_app'), upload_to=upload_path, blank=True, null=True, help_text=u'最新版安卓 APP')
  449. latest_adr_url = models.URLField(_(u'latest_adr_url'), max_length=255, blank=True, null=True, help_text=u'最新版 APP 链接')
  450. latest_ios_version_code = models.IntegerField(_(u'latest_ios_version_code'), default=0, help_text=u'最新 iOS 版本号')
  451. latest_ios_version_name = models.CharField(_(u'latest_ios_version_name'), max_length=16, blank=True, null=True, help_text=u'最新 iOS 版本名')
  452. latest_ios_url = models.URLField(_(u'latest_ios_url'), max_length=255, blank=True, null=True, help_text=u'最新版 iOS 链接')
  453. class Meta:
  454. verbose_name = _(u'升级配置信息')
  455. verbose_name_plural = _(u'升级配置信息')
  456. def __unicode__(self):
  457. return u'{0.pk}'.format(self)
  458. @property
  459. def final_latest_adr_url(self):
  460. return self.latest_adr_url or upload_file_url(self.latest_adr_app)
  461. @property
  462. def data(self):
  463. return {
  464. 'latest_adr_version_code': self.latest_adr_version_code,
  465. 'latest_adr_version_name': self.latest_adr_version_name,
  466. 'latest_adr_url': self.final_latest_adr_url,
  467. 'latest_ios_version_code': self.latest_ios_version_code,
  468. 'latest_ios_version_name': self.latest_ios_version_name,
  469. 'latest_ios_url': self.latest_ios_url,
  470. }
  471. @property
  472. def adr(self):
  473. return {
  474. 'latest_adr_version_code': self.latest_adr_version_code,
  475. 'latest_adr_version_name': self.latest_adr_version_name,
  476. 'latest_adr_url': self.final_latest_adr_url,
  477. }
  478. class LatestAppScreenInfo(BaseModelMixin):
  479. latest_adr_version_code = models.IntegerField(_(u'latest_adr_version_code'), default=0, help_text=u'最新安卓版本号')
  480. latest_adr_version_name = models.CharField(_(u'latest_adr_version_name'), max_length=16, blank=True, null=True, help_text=u'最新安卓版本名')
  481. latest_adr_app = models.FileField(_(u'latest_adr_app'), upload_to=upload_path, blank=True, null=True, help_text=u'最新版安卓 APP')
  482. latest_adr_url = models.URLField(_(u'latest_adr_url'), max_length=255, blank=True, null=True, help_text=u'最新版 APP 链接')
  483. latest_ios_version_code = models.IntegerField(_(u'latest_ios_version_code'), default=0, help_text=u'最新 iOS 版本号')
  484. latest_ios_version_name = models.CharField(_(u'latest_ios_version_name'), max_length=16, blank=True, null=True, help_text=u'最新 iOS 版本名')
  485. latest_ios_url = models.URLField(_(u'latest_ios_url'), max_length=255, blank=True, null=True, help_text=u'最新版 iOS 链接')
  486. class Meta:
  487. verbose_name = _(u'升级配置信息(数据大屏)')
  488. verbose_name_plural = _(u'升级配置信息(数据大屏)')
  489. def __unicode__(self):
  490. return u'{0.pk}'.format(self)
  491. @property
  492. def final_latest_adr_url(self):
  493. return self.latest_adr_url or upload_file_url(self.latest_adr_app)
  494. @property
  495. def data(self):
  496. return {
  497. 'latest_adr_version_code': self.latest_adr_version_code,
  498. 'latest_adr_version_name': self.latest_adr_version_name,
  499. 'latest_adr_url': self.final_latest_adr_url,
  500. 'latest_ios_version_code': self.latest_ios_version_code,
  501. 'latest_ios_version_name': self.latest_ios_version_name,
  502. 'latest_ios_url': self.latest_ios_url,
  503. }
  504. @property
  505. def adr(self):
  506. return {
  507. 'latest_adr_version_code': self.latest_adr_version_code,
  508. 'latest_adr_version_name': self.latest_adr_version_name,
  509. 'latest_adr_url': self.final_latest_adr_url,
  510. }
  511. class ConsumeInfoSubmitLogInfo(BaseModelMixin):
  512. user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)
  513. phone = models.CharField(_(u'phone'), max_length=11, blank=True, null=True, help_text=u'用户手机', db_index=True)
  514. iv = models.CharField(_(u'iv'), max_length=255, blank=True, null=True, help_text=u'iv')
  515. encryptedData = models.CharField(_(u'encryptedData'), max_length=255, blank=True, null=True, help_text=u'encryptedData')
  516. lat = models.FloatField(_(u'lat'), default=1.0, help_text=u'纬度')
  517. lon = models.FloatField(_(u'lon'), default=1.0, help_text=u'经度')
  518. brand_id = models.CharField(_(u'brand_id'), max_length=32, blank=True, null=True, help_text=u'品牌唯一标识', db_index=True)
  519. brand_name = models.CharField(_(u'brand_name'), max_length=255, blank=True, null=True, help_text=u'品牌名称')
  520. model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)
  521. model_name = models.CharField(_(u'model_name'), max_length=255, blank=True, null=True, help_text=u'型号名称')
  522. model_uni_name = models.CharField(_(u'model_uni_name'), max_length=255, blank=True, null=True, help_text=u'型号统称')
  523. distributor_id = models.CharField(_(u'distributor_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True)
  524. distributor_name = models.CharField(_(u'distributor_name'), max_length=255, blank=True, null=True, help_text=u'经销商名称')
  525. serialNo = models.CharField(_(u'serialNo'), max_length=16, blank=True, null=True, help_text=u'序列号', db_index=True)
  526. verifyResult = models.IntegerField(_(u'verifyResult'), default=0, help_text=u'验证结果', db_index=True)
  527. dupload = models.BooleanField(_(u'dupload'), default=False, help_text=_(u'是否为重复提交'))
  528. submit_during_activity = models.BooleanField(_(u'submit_during_activity'), default=False, help_text=_(u'是否为活动期间上传'))
  529. activity_id = models.IntegerField(_(u'activity_id'), default=0, help_text=_(u'活动唯一标识'))
  530. coupon_expire_at = models.DateTimeField(_(u'coupon_expire_at'), blank=True, null=True, help_text=_(u'维修券过期时间'))
  531. coupon_value = models.IntegerField(_(u'coupon_value'), default=0, help_text=_(u'维修券金额(单位:分)'))
  532. has_used = models.BooleanField(_(u'has_used'), default=False, help_text=_(u'是否已核销'))
  533. admin_id = models.CharField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'核销员唯一标识', db_index=True)
  534. used_at = models.DateTimeField(_(u'used_at'), blank=True, null=True, help_text=_(u'维修券核销时间'))
  535. code_version = models.IntegerField(_(u'code_version'), default=1, help_text=u'统览码版本', db_index=True)
  536. ym = models.IntegerField(_(u'ym'), default=0, help_text=u'年月', db_index=True) # 例:201712, tc.local_string(format='%Y%m')
  537. ymd = models.IntegerField(_(u'ymd'), default=0, help_text=u'年月日', db_index=True) # 例:20171208, tc.local_string(format='%Y%m%d')
  538. integral = models.IntegerField(_(u'integral'), default=0, help_text=u'积分')
  539. province = models.CharField(_(u'province'), max_length=32, blank=True, null=True, help_text=u'省份', db_index=True)
  540. test_user = models.BooleanField(_(u'test_user'), default=False, help_text=_(u'是否为测试用户'))
  541. class Meta:
  542. verbose_name = _(u'消费者信息提交记录')
  543. verbose_name_plural = _(u'消费者信息提交记录')
  544. def __unicode__(self):
  545. return '%d' % self.pk
  546. @property
  547. def model_info(self):
  548. try:
  549. info = ModelInfo.objects.get(model_id=self.model_id).fulldata
  550. except ModelInfo.DoesNotExist:
  551. info = {}
  552. return info
  553. @property
  554. def coupon_info(self):
  555. return {
  556. 'coupon_expire_at': '',
  557. 'coupon_value': 0,
  558. 'coupon_has_expired': True,
  559. }
  560. @property
  561. def coupon_info2(self):
  562. return self.coupon_info,
  563. @property
  564. def data(self):
  565. if self.submit_during_activity:
  566. try:
  567. act = ActivityInfo.objects.get(pk=self.activity_id)
  568. except ActivityInfo.DoesNotExist:
  569. act = None
  570. else:
  571. act = None
  572. return {
  573. 'id': self.pk,
  574. 'lat': self.lat,
  575. 'lon': self.lon,
  576. 'brand_id': self.brand_id,
  577. 'brand_name': self.brand_name,
  578. 'model_id': self.model_id,
  579. 'model_name': self.model_name,
  580. 'model_info': self.model_info,
  581. 'serialNo': self.serialNo,
  582. 'dupload': self.dupload,
  583. 'verifyResult': self.verifyResult,
  584. 'submit_during_activity': self.submit_during_activity,
  585. 'coupon_info': act.coupon_info2(created_at=self.created_at) if act else self.coupon_info2,
  586. 'final_coupon_info': act.coupon_info(created_at=self.created_at) if act else self.coupon_info,
  587. 'has_used': self.has_used,
  588. 'used_at': self.used_at,
  589. }
  590. @property
  591. def adminuserdata(self):
  592. try:
  593. model_info = ModelInfo.objects.get(model_id=self.model_id)
  594. except ModelInfo.DoesNotExist:
  595. model_info = {}
  596. return {
  597. 'id': self.pk,
  598. 'model_id': self.model_id,
  599. 'model_name': self.model_name,
  600. 'serialNo': self.serialNo,
  601. 'integral': model_info.shot_member_integral,
  602. 'dupload': self.dupload,
  603. 'code_version': self.code_version,
  604. 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d'),
  605. }
  606. @property
  607. def admindata(self):
  608. return {
  609. 'pk': self.pk,
  610. 'user_id': self.user_id,
  611. 'model_name': self.model_name,
  612. 'model_uni_name': self.model_uni_name,
  613. 'serialNo': self.serialNo,
  614. 'phone': self.phone,
  615. 'code_version': self.code_version,
  616. 'dupload': self.dupload,
  617. 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d %H:%M:%S'),
  618. }
  619. class ActivityInfo(BaseModelMixin):
  620. FIXED_EXPIRED_TIME = 0
  621. CHANGED_EXPIRED_TIME = 1
  622. COUPON_EXPIRED_TIME_TUPLE = (
  623. (FIXED_EXPIRED_TIME, u'固定结束时间'),
  624. (CHANGED_EXPIRED_TIME, u'可变结束时间'),
  625. )
  626. activity_id = ShortUUIDField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True, unique=True)
  627. activity_name = models.CharField(_(u'activity_name'), max_length=255, blank=True, null=True, help_text=u'活动名称')
  628. model_uni_names = JSONField(_(u'model_uni_names'), default=[], blank=True, null=True, help_text=u'型号统一名称列表')
  629. start_at = models.DateTimeField(_(u'start_at'), help_text=_(u'start_at'))
  630. end_at = models.DateTimeField(_(u'end_at'), help_text=_(u'end_at'))
  631. coupon_id = models.CharField(_(u'coupon_id'), max_length=32, blank=True, null=True, help_text=u'券唯一标识', db_index=True)
  632. coupon_expire_type = models.IntegerField(_(u'coupon_expire_type'), choices=COUPON_EXPIRED_TIME_TUPLE, default=FIXED_EXPIRED_TIME, help_text=_(u'维修券类型'))
  633. coupon_valid_period = models.IntegerField(_(u'coupon_valid_period'), default=0, help_text=_(u'维修券有效时间(单位:天)'))
  634. coupon_expire_at = models.DateTimeField(_(u'coupon_expire_at'), blank=True, null=True, help_text=_(u'维修券过期时间'))
  635. coupon_value = models.IntegerField(_(u'coupon_value'), default=0, help_text=_(u'维修券金额(单位:分)'))
  636. class Meta:
  637. verbose_name = _(u'活动信息')
  638. verbose_name_plural = _(u'活动信息')
  639. def __unicode__(self):
  640. return '%d' % self.pk
  641. def final_expire_at(self, created_at=None):
  642. if self.coupon_expire_type == ActivityInfo.FIXED_EXPIRED_TIME:
  643. return self.coupon_expire_at
  644. return tc.utc_datetime(dt=created_at, days=self.coupon_valid_period)
  645. def final_coupon_expire_at(self, created_at=None):
  646. final_expire_at = self.final_expire_at(created_at=created_at)
  647. if not final_expire_at:
  648. return ''
  649. return tc.local_string(utc_dt=final_expire_at, format=u'%Y年%m月%d日', isuc=True)
  650. def has_unexpired_activity(self, model_name):
  651. return ((self.model_uni_names and model_name in self.model_uni_names) or not self.model_uni_names) and (self.start_at <= tc.utc_datetime() < self.end_at)
  652. def coupon_info(self, created_at=None):
  653. return {
  654. 'coupon_expire_at': self.final_coupon_expire_at(created_at=created_at),
  655. 'coupon_value': self.coupon_value,
  656. 'coupon_has_expired': tc.utc_datetime() >= self.final_expire_at(created_at=created_at),
  657. }
  658. def coupon_info2(self, created_at=None):
  659. return self.coupon_info(created_at=created_at),
  660. @property
  661. def coupon_info3(self):
  662. try:
  663. coupon = CouponInfo.objects.get(coupon_id=self.coupon_id)
  664. except CouponInfo.DoesNotExist:
  665. coupon = None
  666. return {
  667. 'coupon_image': coupon.coupon_image_url,
  668. 'coupon_expire_at': coupon.coupon_expire_at,
  669. 'coupon_value': coupon.coupon_value,
  670. 'coupon_title': coupon.coupon_title,
  671. 'coupon_valid_period': coupon.coupon_valid_period,
  672. 'coupon_id': coupon.coupon_id,
  673. 'activity_id': self.activity_id,
  674. 'activity_name': self.activity_name,
  675. } if coupon else {}