Nav apraksta

models.py 41KB

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