base.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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 = unicode(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, unicode):
  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, unicode):
  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, unicode):
  50. res = value
  51. return res
  52. @staticmethod
  53. def formatCount(value):
  54. return long(round(float(value or 0) * 100,0))
  55. @staticmethod
  56. def formatPrice(value):
  57. return long(round(float(value or 0) * 100,0))
  58. @staticmethod
  59. def formatCountShow(value):
  60. return '%.2f' % round(float(value or 0)/100.0,2)
  61. @staticmethod
  62. def formatPriceShow(value):
  63. return '%.2f' % round(float(value or 0)/100.0,2)
  64. @staticmethod
  65. def formatEmptyPriceShow(value):
  66. if value == None or value == '':
  67. return ''
  68. return '%.2f' % round(float(value or 0) / 100.0, 2)
  69. @staticmethod
  70. def formatAmount(value):
  71. return long(round(float(value or 0) * 10000,0))
  72. @staticmethod
  73. def formatAmountShow(value):
  74. return '%.4f' % round(float(value or 0) / 10000.0 + 0.0000001, 2)
  75. @staticmethod
  76. def formatAmountShowWithTwoDecimalPlaces(value):
  77. return '%.2f' % round(float(value or 0) / 10000.0 + 0.0000001, 2)
  78. @staticmethod
  79. def formatEmptyAmountShow(value):
  80. if value == None or value == '':
  81. return ''
  82. return '%.4f' % round(float(value or 0) / 10000.0 + 0.0000001, 2)
  83. @staticmethod
  84. def formatAmountCNY(value):
  85. return utils.number2CNY(Formater.formatAmountShow(value))
  86. class CustomFormaterByUser():
  87. @staticmethod
  88. def formatEmptyStr(value,user):
  89. return Formater.formatEmptyStr(value)
  90. @staticmethod
  91. def formatEmptyFloat(value, user):
  92. #return round(value or 0, 2)
  93. return Formater.formatEmptyFloat(value)
  94. @staticmethod
  95. def formatTime(value,user):
  96. return Formater.formatTime(value)
  97. @staticmethod
  98. def formatDate(value, user):
  99. return Formater.formatDate(value)
  100. @staticmethod
  101. def formatCountShow(value,user):
  102. return Formater.formatCountShow(value)
  103. @staticmethod
  104. def formatPartAmountShow(value, user):
  105. #from apps.foundation.models import Config
  106. #num = Config.objects.get_proprty(user.company.id, Config.KEY_PART_ENTRY_PRICE_ROUND)
  107. #if not num:
  108. # num = 4
  109. #return round(float(value or 0) / 1000000, int(num))
  110. return Formater.formatAmountShow(value)
  111. class ExcelImporter():
  112. def getExcelData(self,file):
  113. if not file:
  114. raise CustomError(u'请上传数据文件')
  115. try:
  116. data = tablib.import_set(file.read(), format='xlsx').dict
  117. if not len(data):
  118. raise CustomError(u'上传的文件内没有发现数据')
  119. return data
  120. except InvalidFileException:
  121. raise CustomError(u'请上传<strong>xlsx</strong>格式的数据文件,老版本的xls格式不被支持!')
  122. def validRow(self,row):
  123. data = {}
  124. for (k,v) in self.fields.items():
  125. is_required = v[0]
  126. format_proc = v[1]
  127. try:
  128. value = row[k]
  129. except:
  130. raise CustomError(u'缺少[%s]列,请检查模板文件或重新下载' % k)
  131. if is_required and value == None:
  132. raise CustomError(u'%s:为必填项' % k)
  133. if format_proc and value != None:
  134. try:
  135. value = format_proc(value)
  136. except CustomError,e:
  137. raise CustomError(u'%s:错误的值[%s]' % (k,e.get_error_msg()))
  138. data[k] = value
  139. return data
  140. @staticmethod
  141. def formatUnicode(value):
  142. try:
  143. return unicode(value).strip(u' ')
  144. except:
  145. return ''
  146. @staticmethod
  147. def formatDateTime(value):
  148. try:
  149. res = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
  150. except:
  151. try:
  152. res = datetime.datetime.strptime(value, '%Y-%m-%d')
  153. except:
  154. raise CustomError(u'格式为:2018-01-01 或 2018-01-01 00:00:00')
  155. return res
  156. @staticmethod
  157. def formatInt(value):
  158. try:
  159. return int(float(unicode(value).strip(u' ')))
  160. except:
  161. raise CustomError(u'不能转换为整数')
  162. @staticmethod
  163. def formatFloat(value):
  164. try:
  165. return round(float(unicode(value).strip(u' ')) or 0,2)
  166. except:
  167. raise CustomError(u'不能转换为小数')
  168. @staticmethod
  169. def formatFloatGtZ(value):
  170. v = ExcelImporter.formatFloat(value)
  171. if v <= 0:
  172. raise CustomError(u'必须大于0')
  173. return v
  174. @staticmethod
  175. def formatFloatGeZ(value):
  176. v = ExcelImporter.formatFloat(value)
  177. if v < 0:
  178. raise CustomError(u'必须大于等于0')
  179. return v
  180. @staticmethod
  181. def formatTel(value):
  182. try:
  183. value = unicode(value).strip(u' ')
  184. except:
  185. value = ''
  186. if value == '':
  187. return value
  188. 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)
  189. is_tel = re.match(r'^([0-9]{3,4}-)?[0-9]{7,8}$', value)
  190. if not (is_mobile or is_tel):
  191. raise CustomError(u'不合法的手机号或者固话号')
  192. return value
  193. class Filter():
  194. @staticmethod
  195. def limit(rows, start, end):
  196. if start and end:
  197. rows = rows[start:end]
  198. else:
  199. if start:
  200. rows = rows[start:]
  201. elif end:
  202. rows = rows[:end]
  203. return rows
  204. class Shower():
  205. def __init__(self, fields_map, show_data):
  206. if isinstance(show_data, dict):
  207. self.show_type = 'dict'
  208. self.fields,self.kips = Shower.getFkips(fields_map, show_data)
  209. elif isinstance(show_data, (list, tuple)):
  210. self.show_type = 'arr'
  211. self.fields, self.ips = Shower.getFips(fields_map, show_data)
  212. def getNeedFields(self):
  213. return self.fields
  214. def format(self, rows,start,end):
  215. rows = Filter.limit(rows,start,end)
  216. if self.show_type == 'dict':
  217. return self.formatDict(rows)
  218. elif self.show_type == 'arr':
  219. return self.formatArr(rows)
  220. return []
  221. def formatArr(self,rows):
  222. data = []
  223. for row in rows:
  224. item = []
  225. for ip in self.ips:
  226. if ip[1]:
  227. value = ip[1](row[ip[0]])
  228. else:
  229. value = row[ip[0]]
  230. item.append(value)
  231. data.append(item)
  232. return data
  233. def formatDict(self,rows):
  234. data = []
  235. for row in rows:
  236. item = {}
  237. for kip in self.kips:
  238. if kip[2]:
  239. value = kip[2](row[kip[1]])
  240. else:
  241. value = row[kip[1]]
  242. item[kip[0]] = value
  243. data.append(item)
  244. return data
  245. @staticmethod
  246. def getFips(fields_map, show_arr):
  247. fields = []
  248. ips = []
  249. index = 0
  250. for item in show_arr:
  251. field = Shower.getFieldByKey(fields_map,item)
  252. if field:
  253. fields.append(field[0])
  254. ip = (index, field[1])
  255. ips.append(ip)
  256. index += 1
  257. return fields, ips
  258. @staticmethod
  259. def getFkips(fields_map, show_map):
  260. fields = []
  261. kips = []
  262. index = 0
  263. for (k,v) in show_map.items():
  264. field = Shower.getFieldByKey(fields_map,v)
  265. if field:
  266. fields.append(field[0])
  267. kip = (k, index, field[1])
  268. kips.append(kip)
  269. index += 1
  270. return fields, kips
  271. @staticmethod
  272. def getFieldByKey(fields_map,key):
  273. try:
  274. return fields_map[key]
  275. except:
  276. return None
  277. class CustomShower(Shower):
  278. def __init__(self, fields_map, show_data, user):
  279. Shower.__init__(self,fields_map,show_data)
  280. self.user = user
  281. def format(self, rows,start,end):
  282. rows = Filter.limit(rows,start,end)
  283. if self.show_type == 'dict':
  284. return self.formatDict(rows)
  285. elif self.show_type == 'arr':
  286. return self.formatArr(rows)
  287. return []
  288. def getNeedFields(self):
  289. return self.fields
  290. def formatArr(self,rows):
  291. data = []
  292. for row in rows:
  293. item = []
  294. for ip in self.ips:
  295. if ip[1]:
  296. value = ip[1](row[ip[0]],self.user)
  297. else:
  298. value = row[ip[0]]
  299. item.append(value)
  300. data.append(item)
  301. return data
  302. def formatDict(self,rows):
  303. data = []
  304. for row in rows:
  305. item = {}
  306. for kip in self.kips:
  307. if kip[2]:
  308. value = kip[2](row[kip[1]],self.user)
  309. else:
  310. value = row[kip[1]]
  311. item[kip[0]] = value
  312. data.append(item)
  313. return data
  314. def formatAmountShow(self,value):
  315. #from apps.foundation.models import Config
  316. #num = Config.objects.get_proprty(self.user.company.id, Config.KEY_PART_ENTRY_PRICE_ROUND)
  317. #if not num:
  318. # num = 4
  319. #return round(float(value or 0) / 1000000, int(num))
  320. return Formater.formatAmountShow(value)
  321. def clean_datetime_range(data, fieldname, source=None):
  322. if data is not None and fieldname in data and data[fieldname] != '':
  323. if data is not None and source in data and data[source] == 'touch':
  324. t = data[fieldname].split('T')[0]
  325. data = data.copy()
  326. data[fieldname + '_0'] = t
  327. data[fieldname + '_1'] = t + ' 23:59:59'
  328. else:
  329. t = data[fieldname].split(' - ')
  330. data = data.copy()
  331. data[fieldname+'_0'] = t[0]
  332. data[fieldname+'_1'] = t[1] + ' 23:59:59'
  333. data.pop(fieldname)
  334. return data
  335. def clean_date_range(data, fieldname):
  336. if data is not None and fieldname in data and data[fieldname] != '':
  337. t = data[fieldname].split(' - ')
  338. data = data.copy()
  339. data[fieldname+'_0'] = t[0]
  340. data[fieldname+'_1'] = t[1]
  341. data.pop(fieldname)
  342. return data