123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- #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 = unicode(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, unicode):
- 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, unicode):
- res = value
- return res
- @staticmethod
- def formatStrDate(value):
- res = u''
- if value != None:
- if isinstance(value, datetime.date):
- res = strfdate(value)
- elif isinstance(value, unicode):
- res = value
- return res
- @staticmethod
- def formatCount(value):
- return long(round(float(value or 0) * 100,0))
- @staticmethod
- def formatPrice(value):
- return long(round(float(value or 0) * 100,0))
- @staticmethod
- def formatCountShow(value):
- return '%.2f' % round(float(value or 0)/100.0,2)
- @staticmethod
- def formatPriceShow(value):
- return '%.2f' % round(float(value or 0)/100.0,2)
- @staticmethod
- def formatEmptyPriceShow(value):
- if value == None or value == '':
- return ''
- return '%.2f' % round(float(value or 0) / 100.0, 2)
- @staticmethod
- def formatAmount(value):
- return long(round(float(value or 0) * 10000,0))
- @staticmethod
- def formatAmountShow(value):
- return '%.4f' % round(float(value or 0) / 10000.0 + 0.0000001, 2)
- @staticmethod
- def formatAmountShowWithTwoDecimalPlaces(value):
- return '%.2f' % round(float(value or 0) / 10000.0 + 0.0000001, 2)
- @staticmethod
- def formatEmptyAmountShow(value):
- if value == None or value == '':
- return ''
- return '%.4f' % round(float(value or 0) / 10000.0 + 0.0000001, 2)
- @staticmethod
- def formatAmountCNY(value):
- return utils.number2CNY(Formater.formatAmountShow(value))
- class CustomFormaterByUser():
- @staticmethod
- def formatEmptyStr(value,user):
- return Formater.formatEmptyStr(value)
- @staticmethod
- def formatEmptyFloat(value, user):
- #return round(value or 0, 2)
- return Formater.formatEmptyFloat(value)
- @staticmethod
- def formatTime(value,user):
- return Formater.formatTime(value)
- @staticmethod
- def formatDate(value, user):
- return Formater.formatDate(value)
- @staticmethod
- def formatCountShow(value,user):
- return Formater.formatCountShow(value)
- @staticmethod
- def formatPartAmountShow(value, user):
- #from apps.foundation.models import Config
- #num = Config.objects.get_proprty(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)
- 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'请上传<strong>xlsx</strong>格式的数据文件,老版本的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,e:
- raise CustomError(u'%s:错误的值[%s]' % (k,e.get_error_msg()))
- data[k] = value
- return data
- @staticmethod
- def formatUnicode(value):
- try:
- return unicode(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(unicode(value).strip(u' ')))
- except:
- raise CustomError(u'不能转换为整数')
- @staticmethod
- def formatFloat(value):
- try:
- return round(float(unicode(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 = unicode(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
|