base.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #coding=utf-8
  2. import datetime
  3. import re
  4. import tablib
  5. from libs.utils import strfdate
  6. from libs import utils
  7. try:
  8. from openpyxl.utils.exceptions import InvalidFileException
  9. except:
  10. from tablib.packages.openpyxl.shared.exc import InvalidFileException
  11. from apps.exceptions import CustomError
  12. DATETIME_FORMAT = '%Y-%m-%d %H:%M'
  13. DATETIME_FORMAT1 = '%Y-%m-%d %H:%M:%S'
  14. DATE_FORMAT = '%Y-%m-%d'
  15. class Formater():
  16. @staticmethod
  17. def formatStr(value):
  18. res = u''
  19. if value != None:
  20. try:
  21. res = str(value)
  22. except:
  23. pass
  24. return res
  25. @staticmethod
  26. def formatStrTime(value):
  27. res = u''
  28. if value != None:
  29. if isinstance(value, datetime.datetime):
  30. res = value.strftime('%Y-%m-%d %H:%M')
  31. elif isinstance(value, str):
  32. res = value
  33. return res
  34. @staticmethod
  35. def formatStrTimeS(value):
  36. res = u''
  37. if value != None:
  38. if isinstance(value, datetime.datetime):
  39. res = value.strftime('%Y-%m-%d %H:%M:%S')
  40. elif isinstance(value, str):
  41. res = value
  42. return res
  43. @staticmethod
  44. def formatStrDate(value):
  45. res = u''
  46. if value != None:
  47. if isinstance(value, datetime.date):
  48. res = strfdate(value)
  49. elif isinstance(value, str):
  50. res = value
  51. return res
  52. class ExcelImporter():
  53. def getExcelData(self,file):
  54. if not file:
  55. raise CustomError(u'请上传数据文件')
  56. try:
  57. data = tablib.import_set(file.read(), format='xlsx').dict
  58. if not len(data):
  59. raise CustomError(u'上传的文件内没有发现数据')
  60. return data
  61. except InvalidFileException:
  62. raise CustomError(u'请上传<strong>xlsx</strong>格式的数据文件,老版本的xls格式不被支持!')
  63. def validRow(self,row):
  64. data = {}
  65. for (k,v) in self.fields.items():
  66. is_required = v[0]
  67. format_proc = v[1]
  68. try:
  69. value = row[k]
  70. except:
  71. raise CustomError(u'缺少[%s]列,请检查模板文件或重新下载' % k)
  72. if is_required and value == None:
  73. raise CustomError(u'%s:为必填项' % k)
  74. if format_proc and value != None:
  75. try:
  76. value = format_proc(value)
  77. except CustomError as e:
  78. raise CustomError(u'%s:错误的值[%s]' % (k,e.get_error_msg()))
  79. data[k] = value
  80. return data
  81. @staticmethod
  82. def formatUnicode(value):
  83. try:
  84. return str(value).strip(u' ')
  85. except:
  86. return ''
  87. @staticmethod
  88. def formatDateTime(value):
  89. try:
  90. res = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
  91. except:
  92. try:
  93. res = datetime.datetime.strptime(value, '%Y-%m-%d')
  94. except:
  95. raise CustomError(u'格式为:2018-01-01 或 2018-01-01 00:00:00')
  96. return res
  97. @staticmethod
  98. def formatInt(value):
  99. try:
  100. return int(float(str(value).strip(u' ')))
  101. except:
  102. raise CustomError(u'不能转换为整数')
  103. @staticmethod
  104. def formatFloat(value):
  105. try:
  106. return round(float(str(value).strip(u' ')) or 0,2)
  107. except:
  108. raise CustomError(u'不能转换为小数')
  109. @staticmethod
  110. def formatFloatGtZ(value):
  111. v = ExcelImporter.formatFloat(value)
  112. if v <= 0:
  113. raise CustomError(u'必须大于0')
  114. return v
  115. @staticmethod
  116. def formatFloatGeZ(value):
  117. v = ExcelImporter.formatFloat(value)
  118. if v < 0:
  119. raise CustomError(u'必须大于等于0')
  120. return v
  121. @staticmethod
  122. def formatTel(value):
  123. try:
  124. value = str(value).strip(u' ')
  125. except:
  126. value = ''
  127. if value == '':
  128. return value
  129. is_mobile = re.match(r'^0?(13[0-9]|14[0-9]|15[0-9]|17[0-9]|18[0-9]|19[0-9]|166)[0-9]{8}$', value)
  130. is_tel = re.match(r'^([0-9]{3,4}-)?[0-9]{7,8}$', value)
  131. if not (is_mobile or is_tel):
  132. raise CustomError(u'不合法的手机号或者固话号')
  133. return value
  134. class Filter():
  135. @staticmethod
  136. def limit(rows, start, end):
  137. if start and end:
  138. rows = rows[start:end]
  139. else:
  140. if start:
  141. rows = rows[start:]
  142. elif end:
  143. rows = rows[:end]
  144. return rows
  145. class Shower():
  146. def __init__(self, fields_map, show_data):
  147. if isinstance(show_data, dict):
  148. self.show_type = 'dict'
  149. self.fields,self.kips = Shower.getFkips(fields_map, show_data)
  150. elif isinstance(show_data, (list, tuple)):
  151. self.show_type = 'arr'
  152. self.fields, self.ips = Shower.getFips(fields_map, show_data)
  153. def getNeedFields(self):
  154. return self.fields
  155. def format(self, rows,start,end):
  156. rows = Filter.limit(rows,start,end)
  157. if self.show_type == 'dict':
  158. return self.formatDict(rows)
  159. elif self.show_type == 'arr':
  160. return self.formatArr(rows)
  161. return []
  162. def formatArr(self,rows):
  163. data = []
  164. for row in rows:
  165. item = []
  166. for ip in self.ips:
  167. if ip[1]:
  168. value = ip[1](row[ip[0]])
  169. else:
  170. value = row[ip[0]]
  171. item.append(value)
  172. data.append(item)
  173. return data
  174. def formatDict(self,rows):
  175. data = []
  176. for row in rows:
  177. item = {}
  178. for kip in self.kips:
  179. if kip[2]:
  180. value = kip[2](row[kip[1]])
  181. else:
  182. value = row[kip[1]]
  183. item[kip[0]] = value
  184. data.append(item)
  185. return data
  186. @staticmethod
  187. def getFips(fields_map, show_arr):
  188. fields = []
  189. ips = []
  190. index = 0
  191. for item in show_arr:
  192. field = Shower.getFieldByKey(fields_map,item)
  193. if field:
  194. fields.append(field[0])
  195. ip = (index, field[1])
  196. ips.append(ip)
  197. index += 1
  198. return fields, ips
  199. @staticmethod
  200. def getFkips(fields_map, show_map):
  201. fields = []
  202. kips = []
  203. index = 0
  204. for (k,v) in show_map.items():
  205. field = Shower.getFieldByKey(fields_map,v)
  206. if field:
  207. fields.append(field[0])
  208. kip = (k, index, field[1])
  209. kips.append(kip)
  210. index += 1
  211. return fields, kips
  212. @staticmethod
  213. def getFieldByKey(fields_map,key):
  214. try:
  215. return fields_map[key]
  216. except:
  217. return None
  218. class CustomShower(Shower):
  219. def __init__(self, fields_map, show_data, user):
  220. Shower.__init__(self,fields_map,show_data)
  221. self.user = user
  222. def format(self, rows,start,end):
  223. rows = Filter.limit(rows,start,end)
  224. if self.show_type == 'dict':
  225. return self.formatDict(rows)
  226. elif self.show_type == 'arr':
  227. return self.formatArr(rows)
  228. return []
  229. def getNeedFields(self):
  230. return self.fields
  231. def formatArr(self,rows):
  232. data = []
  233. for row in rows:
  234. item = []
  235. for ip in self.ips:
  236. if ip[1]:
  237. value = ip[1](row[ip[0]],self.user)
  238. else:
  239. value = row[ip[0]]
  240. item.append(value)
  241. data.append(item)
  242. return data
  243. def formatDict(self,rows):
  244. data = []
  245. for row in rows:
  246. item = {}
  247. for kip in self.kips:
  248. if kip[2]:
  249. value = kip[2](row[kip[1]],self.user)
  250. else:
  251. value = row[kip[1]]
  252. item[kip[0]] = value
  253. data.append(item)
  254. return data
  255. def formatAmountShow(self,value):
  256. #from apps.foundation.models import Config
  257. #num = Config.objects.get_proprty(self.user.company.id, Config.KEY_PART_ENTRY_PRICE_ROUND)
  258. #if not num:
  259. # num = 4
  260. #return round(float(value or 0) / 1000000, int(num))
  261. return Formater.formatAmountShow(value)
  262. def clean_datetime_range(data, fieldname, source=None):
  263. if data is not None and fieldname in data and data[fieldname] != '':
  264. if data is not None and source in data and data[source] == 'touch':
  265. t = data[fieldname].split('T')[0]
  266. data = data.copy()
  267. data[fieldname + '_0'] = t
  268. data[fieldname + '_1'] = t + ' 23:59:59'
  269. else:
  270. t = data[fieldname].split(' - ')
  271. data = data.copy()
  272. data[fieldname+'_0'] = t[0]
  273. data[fieldname+'_1'] = t[1] + ' 23:59:59'
  274. data.pop(fieldname)
  275. return data
  276. def clean_date_range(data, fieldname):
  277. if data is not None and fieldname in data and data[fieldname] != '':
  278. t = data[fieldname].split(' - ')
  279. data = data.copy()
  280. data[fieldname+'_0'] = t[0]
  281. data[fieldname+'_1'] = t[1]
  282. data.pop(fieldname)
  283. return data