#coding=utf-8 import datetime import re import tablib from libs.utils import strfdate from libs import utils try: from openpyxl.utils.exceptions import InvalidFileException except: from tablib.packages.openpyxl.shared.exc import InvalidFileException from apps.exceptions import CustomError DATETIME_FORMAT = '%Y-%m-%d %H:%M' DATETIME_FORMAT1 = '%Y-%m-%d %H:%M:%S' DATE_FORMAT = '%Y-%m-%d' class Formater(): @staticmethod def formatStr(value): res = u'' if value != None: try: res = str(value) except: pass return res @staticmethod def formatStrTime(value): res = u'' if value != None: if isinstance(value, datetime.datetime): res = value.strftime('%Y-%m-%d %H:%M') elif isinstance(value, str): res = value return res @staticmethod def formatStrTimeS(value): res = u'' if value != None: if isinstance(value, datetime.datetime): res = value.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(value, str): res = value return res @staticmethod def formatStrDate(value): res = u'' if value != None: if isinstance(value, datetime.date): res = strfdate(value) elif isinstance(value, str): res = value return res class ExcelImporter(): def getExcelData(self,file): if not file: raise CustomError(u'请上传数据文件') try: data = tablib.import_set(file.read(), format='xlsx').dict if not len(data): raise CustomError(u'上传的文件内没有发现数据') return data except InvalidFileException: raise CustomError(u'请上传xlsx格式的数据文件,老版本的xls格式不被支持!') def validRow(self,row): data = {} for (k,v) in self.fields.items(): is_required = v[0] format_proc = v[1] try: value = row[k] except: raise CustomError(u'缺少[%s]列,请检查模板文件或重新下载' % k) if is_required and value == None: raise CustomError(u'%s:为必填项' % k) if format_proc and value != None: try: value = format_proc(value) except CustomError as e: raise CustomError(u'%s:错误的值[%s]' % (k,e.get_error_msg())) data[k] = value return data @staticmethod def formatUnicode(value): try: return str(value).strip(u' ') except: return '' @staticmethod def formatDateTime(value): try: res = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S') except: try: res = datetime.datetime.strptime(value, '%Y-%m-%d') except: raise CustomError(u'格式为:2018-01-01 或 2018-01-01 00:00:00') return res @staticmethod def formatInt(value): try: return int(float(str(value).strip(u' '))) except: raise CustomError(u'不能转换为整数') @staticmethod def formatFloat(value): try: return round(float(str(value).strip(u' ')) or 0,2) except: raise CustomError(u'不能转换为小数') @staticmethod def formatFloatGtZ(value): v = ExcelImporter.formatFloat(value) if v <= 0: raise CustomError(u'必须大于0') return v @staticmethod def formatFloatGeZ(value): v = ExcelImporter.formatFloat(value) if v < 0: raise CustomError(u'必须大于等于0') return v @staticmethod def formatTel(value): try: value = str(value).strip(u' ') except: value = '' if value == '': return value 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) is_tel = re.match(r'^([0-9]{3,4}-)?[0-9]{7,8}$', value) if not (is_mobile or is_tel): raise CustomError(u'不合法的手机号或者固话号') return value class Filter(): @staticmethod def limit(rows, start, end): if start and end: rows = rows[start:end] else: if start: rows = rows[start:] elif end: rows = rows[:end] return rows class Shower(): def __init__(self, fields_map, show_data): if isinstance(show_data, dict): self.show_type = 'dict' self.fields,self.kips = Shower.getFkips(fields_map, show_data) elif isinstance(show_data, (list, tuple)): self.show_type = 'arr' self.fields, self.ips = Shower.getFips(fields_map, show_data) def getNeedFields(self): return self.fields def format(self, rows,start,end): rows = Filter.limit(rows,start,end) if self.show_type == 'dict': return self.formatDict(rows) elif self.show_type == 'arr': return self.formatArr(rows) return [] def formatArr(self,rows): data = [] for row in rows: item = [] for ip in self.ips: if ip[1]: value = ip[1](row[ip[0]]) else: value = row[ip[0]] item.append(value) data.append(item) return data def formatDict(self,rows): data = [] for row in rows: item = {} for kip in self.kips: if kip[2]: value = kip[2](row[kip[1]]) else: value = row[kip[1]] item[kip[0]] = value data.append(item) return data @staticmethod def getFips(fields_map, show_arr): fields = [] ips = [] index = 0 for item in show_arr: field = Shower.getFieldByKey(fields_map,item) if field: fields.append(field[0]) ip = (index, field[1]) ips.append(ip) index += 1 return fields, ips @staticmethod def getFkips(fields_map, show_map): fields = [] kips = [] index = 0 for (k,v) in show_map.items(): field = Shower.getFieldByKey(fields_map,v) if field: fields.append(field[0]) kip = (k, index, field[1]) kips.append(kip) index += 1 return fields, kips @staticmethod def getFieldByKey(fields_map,key): try: return fields_map[key] except: return None class CustomShower(Shower): def __init__(self, fields_map, show_data, user): Shower.__init__(self,fields_map,show_data) self.user = user def format(self, rows,start,end): rows = Filter.limit(rows,start,end) if self.show_type == 'dict': return self.formatDict(rows) elif self.show_type == 'arr': return self.formatArr(rows) return [] def getNeedFields(self): return self.fields def formatArr(self,rows): data = [] for row in rows: item = [] for ip in self.ips: if ip[1]: value = ip[1](row[ip[0]],self.user) else: value = row[ip[0]] item.append(value) data.append(item) return data def formatDict(self,rows): data = [] for row in rows: item = {} for kip in self.kips: if kip[2]: value = kip[2](row[kip[1]],self.user) else: value = row[kip[1]] item[kip[0]] = value data.append(item) return data def formatAmountShow(self,value): #from apps.foundation.models import Config #num = Config.objects.get_proprty(self.user.company.id, Config.KEY_PART_ENTRY_PRICE_ROUND) #if not num: # num = 4 #return round(float(value or 0) / 1000000, int(num)) return Formater.formatAmountShow(value) def clean_datetime_range(data, fieldname, source=None): if data is not None and fieldname in data and data[fieldname] != '': if data is not None and source in data and data[source] == 'touch': t = data[fieldname].split('T')[0] data = data.copy() data[fieldname + '_0'] = t data[fieldname + '_1'] = t + ' 23:59:59' else: t = data[fieldname].split(' - ') data = data.copy() data[fieldname+'_0'] = t[0] data[fieldname+'_1'] = t[1] + ' 23:59:59' data.pop(fieldname) return data def clean_date_range(data, fieldname): if data is not None and fieldname in data and data[fieldname] != '': t = data[fieldname].split(' - ') data = data.copy() data[fieldname+'_0'] = t[0] data[fieldname+'_1'] = t[1] data.pop(fieldname) return data