def ifns_reserve(ifns=None, service=None, batch_id=None, **kwargs): dt = kwargs['datetime'] service = int(service) result = None batch_db = DocumentBatchDbObject.query.filter_by(id=batch_id, _owner=current_user, deleted=False).scalar() if not batch_db: raise errors.InvalidParameterValue('batch_id') from services.llc_reg.llc_reg_manager import LlcRegBatchManager founder_applicant = LlcRegBatchManager.get_founder_applicant(batch_db, logger=current_app.logger) if not founder_applicant: raise errors.InvalidParameterValue("batch_id") reg_responsible_object = LlcRegBatchManager.get_reg_responsible_object(batch_db, logger=current_app.logger) if not batch_db.data: raise errors.InvalidParameterValue('batch_id') batch_data_data = batch_db.data if 'full_name' not in batch_data_data or not batch_data_data['full_name']: raise errors.InvalidParameterValue('batch_id') company_full_name = batch_data_data['full_name'] ifns_data = ifns_manager.get_ifns_data(ifns) if not ifns_data or not ifns_data.rou: raise errors.InvalidParameterValue("ifns") rou = ifns_data.rou if 'code' not in rou: raise errors.InvalidParameterValue("ifns") code = rou['code'] if service == IfnsServiceEnum.IS_REG_COMPANY: if code not in LLC_REG_INTERNAL_SERVICE_ID_MAP: raise errors.InvalidParameterValue("ifns") IFNS_LOGGER.debug( u"Trying to reserve ifns. ifns:%d, service:%s, dt:%s" % (int(ifns), unicode(service), unicode(dt))) company_data, person_data = get_company_person_data_for_ifns(founder_applicant, reg_responsible_object, current_user.email) obj_type = "person" if person_data is not None else "company" internal_ifns_service, internal_ifns_number = LLC_REG_INTERNAL_SERVICE_ID_MAP[code][obj_type] try: result = current_app.external_tools.book_ifns(person_data, company_data, internal_ifns_number, internal_ifns_service, dt, IFNS_LOGGER) except Exception: IFNS_LOGGER.exception(u"Failed to reserve ifns.") raise elif service == IfnsServiceEnum.IS_RECEIVE_REG_DOCS: try: if code not in RECEIVE_REG_DOCS_INTERNAL_SERVICE_ID_MAP: raise errors.InvalidParameterValue("ifns") general_manager = batch_data_data.get('general_manager') if not general_manager or '_id' not in general_manager: raise errors.InvalidParameterValue("batch_id") general_manager_id = general_manager['_id'] general_manager_obj = PrivatePersonDbObject.query.filter_by(id=general_manager_id).scalar() if not general_manager_obj: raise errors.InvalidParameterValue("batch_id") internal_ifns_service, internal_ifns_number = RECEIVE_REG_DOCS_INTERNAL_SERVICE_ID_MAP[code] company_data = { 'inn': '0000000000', "name": company_full_name, "phone": general_manager_obj.phone, "email": current_user.email, } result = current_app.external_tools.book_ifns(None, company_data, internal_ifns_number, internal_ifns_service, dt, IFNS_LOGGER) except Exception: IFNS_LOGGER.exception(u"Failed to reserve ifns.") raise if result: from fw.async_tasks import send_email try: booking = IfnsBookingObject( batch_id=batch_id, code=result['code'], date=result['date'], service=result['service'], phone=result['phone'], window=result['window'], address=result['address'], service_id=service, ifns=result['ifns'], how_to_get=result['how_to_get'] ) sqldb.session.add(booking) sqldb.session.commit() IFNS_LOGGER.debug(u"Reserverd ifns. booking id: %s" % booking.id) social_link = SocialServiceBackends.get_user_social_network_profile_url(current_user.id) rec_list = current_app.config['YURIST_EMAIL_LIST'] llc_full_name = batch_db.data.get('full_name', "") docs = BatchManager.get_shared_links_to_rendered_docs(batch_db, current_app.config, IFNS_LOGGER) for recipient in rec_list: send_email.send_email.delay( recipient, 'ifns_reservation_notification', email=current_user.email, mobile=current_user.mobile, social_link=social_link, full_name=llc_full_name, ifns=result['ifns'], booking_time=result['date'], docs=docs ) booking_field = IfnsBooking.db_obj_to_field(booking) return {'result': booking_field.get_api_structure()} except Exception, ex: IFNS_LOGGER.exception(u"Failed to save booking!") raise errors.ServerError()
def book_ifns(person_data, company_data, internal_ifns_number, internal_ifns_service, dt, logger): s = requests.Session() result = s.get(u'http://order.nalog.ru/details/') if result.status_code != 200: logger.error(u"Невозможно начать сессию с сервером order.nalog.ru") raise errors.ServerUnavailable() test_str = u"Укажите параметры для записи на посещение ИФНС России" ok = False if company_data: for x in range(4): result = s.post(u'http://order.nalog.ru/details/', data={ "ctl00$LastName": company_data['name'], "ctl00$inn": company_data['inn'], "ctl00$phone": company_data['phone'], "ctl00$email": company_data['email'], "__VIEWSTATE": u"", "ctl00$face": u"0", "ctl00$btNext": "" }, timeout=20) if result.status_code != 200: logger.error(u"order.nalog.ru вернул неожиданный код: %s" % unicode(result.status_code)) raise errors.ServerUnavailable() content = result.content.decode('utf-8') if test_str in content: ok = True break if not ok: logger.error(u"Не удалось начать работу с order.nalog.ru") raise errors.ServerUnavailable() elif person_data: for x in range(4): result = s.post(u'http://order.nalog.ru/details/', data={ "ctl00$LastName": person_data['surname'], "ctl00$FirstName": person_data['name'], "ctl00$SecondName": person_data['patronymic'] or u"", "ctl00$inn": person_data['inn'], "ctl00$phone": person_data['phone'], "ctl00$email": person_data['email'], "__VIEWSTATE": u"", "ctl00$face": u"1", "ctl00$btNext": "" }, timeout=20) if result.status_code != 200: logger.error(u"order.nalog.ru вернул неожиданный код: %s" % unicode(result.status_code)) raise errors.ServerUnavailable() content = result.content.decode('utf-8') if test_str in content: ok = True break if not ok: logger.error(u"Не удалось начать работу с order.nalog.ru") raise errors.ServerUnavailable() fns, sub_service = internal_ifns_number, internal_ifns_service # get_ifns_internal_id_by_ifns_name(s, region_name, reg_ifns_name, not company_data, logger) service = None is_multi_sub_service = 0 cb_param = 'c0:%d;%d;%d;%d' % (sub_service, is_multi_sub_service, (service if is_multi_sub_service else sub_service), fns) result = s.post(u'http://order.nalog.ru/fns_service/', data={ "__CALLBACKID": u"ctl00$cpday", "__CALLBACKPARAM": cb_param, "__EVENTTARGET": u"", "__EVENTARGUMENT": "", "__VIEWSTATE": u"", }, timeout=20) if result.status_code != 200: logger.error(u"order.nalog.ru вернул неожиданный код: %s" % unicode(result.status_code)) raise errors.ServerUnavailable() str_data = result.text[26:-3].encode( 'utf-8').decode('string_escape').replace('!-\\-', '!--').replace( '/-\\-', '/--').replace('\\/script', '/script') content = u"<!DOCTYPE html><html><head><title></title></head><body>%s</body></html>" % str_data.decode( 'utf-8') root = html5lib.parse(content, treebuilder='lxml', namespaceHTMLElements=False) year = None month = None # noinspection PyCallingNonCallable for item in CSSSelector('#ctl00_cpday_day_T')(root): item_text_parts = item.text.split(' ') if len(item_text_parts) < 2: logger.error(u"Ожидалась дата, получили %s" % item.text) raise errors.ServerUnavailable( u"Invalid nalog.ru service return content") try: month = MONTHS[item_text_parts[0].strip()] year = int(item_text_parts[1].strip()) break except Exception: logger.error(u"Не удалось распарсить дату: %s" % item.text) raise errors.ServerUnavailable( u"Invalid nalog.ru service return content") if not month or not year: logger.error(u"Дату так и не получили") raise Exception(u"Invalid nalog.ru service return content") day_prev = -1 days = [] first = True #noinspection PyCallingNonCallable for item in CSSSelector('#ctl00_cpday_day_mt td.dxeCalendarDay')(root): classes = filter(lambda x: not not x, [i.strip() for i in item.attrib['class'].split(' ')]) day = int(item.text) if first and (23 <= day <= 31): month -= 1 first = False if day_prev > day: month += 1 if month > 12: year += 1 month = 1 day_prev = day if 'dxeCalendarOutOfRange' in classes or 'dxeCalendarToday' in classes: continue d = datetime(year, month, day) if d not in (datetime(2015, 5, 1), datetime(2015, 5, 2), datetime(2015, 5, 3), datetime(2015, 5, 4), datetime(2015, 5, 9), datetime(2015, 5, 10), datetime(2015, 5, 11)): days.append(d) # ban check d = days[0] result = s.post('http://order.nalog.ru/fns_service/', data={ "__CALLBACKID": u"ctl00$clBanCheck", "__CALLBACKPARAM": u"c0:%s.%s.%s;%s;%s;0" % (unicode(d.year), unicode(d.month), unicode( d.day), unicode(180), unicode(fns)), "__EVENTARGUMENT": u"", "__EVENTTARGET": u"", "__VIEWSTATE": u"", }, timeout=20) if result.status_code != 200 or not result.content: logger.error(u"order.nalog.ru вернул неожиданный ответ") raise errors.ServerUnavailable() if u"'data':'0'" in result.text: raise errors.MaximumRegistrationsExceeded() # get time slots part = u"%d.%d.%d;%d;%d;%d;%d" % (dt.year, dt.month, dt.day, service if is_multi_sub_service else sub_service, fns, is_multi_sub_service, sub_service) part2 = u"14|CUSTOMCALLBACK%d|" % len(part) + part cb_param = u"c0:KV|2;[];GB|%d;" % len(part2) + part2 + ";" result = s.post('http://order.nalog.ru/fns_service/', data={ "__CALLBACKID": u"ctl00$gvTime", "__CALLBACKPARAM": cb_param, "__EVENTARGUMENT": u"", "__EVENTTARGET": u"", "__VIEWSTATE": u"", }, timeout=20) if result.status_code != 200 or not result.content: logger.error(u"order.nalog.ru вернул неожиданный ответ") raise errors.ServerUnavailable() if u"К сожалению, на указанную Вами услугу и дату полная запись. Предлагаем выбрать другую удобную для Вас дату." in result.text: raise errors.DayBusyOrHolliday(dt) text_parts = result.text.split('cpFS_ID\':') if len(text_parts) < 2: logger.error(u"order.nalog.ru вернул неожиданный ответ: %s" % result.text) raise errors.ServerUnavailable() sub_service_fs_id = filter(lambda x: x.isdigit(), text_parts[1]) cb_param = u"c0:" + unicode(dt.year) + u"." + unicode(dt.month) + u"." + unicode(dt.day) + u" " + dt.strftime( "%H:%M:00") + \ ";" + unicode(sub_service_fs_id) + u";" + unicode(fns) + u";" + unicode(sub_service) + ";" + unicode( is_multi_sub_service) result = s.post('http://order.nalog.ru/fns_service/', data={ "__CALLBACKID": u"ctl00$clRegister", "__CALLBACKPARAM": cb_param, "__EVENTARGUMENT": u"", "__EVENTTARGET": u"", "__VIEWSTATE": u"", }, timeout=20) if result.status_code != 200 or not result.content: logger.error(u"order.nalog.ru вернул неожиданный ответ") raise errors.ServerUnavailable() if "'DoubleTime'" in result: raise errors.DuplicateBookingAtTheSameTime() logger.error(result.text) result = result.content.decode('utf-8') parts = result.split("'data':'") if len(parts) < 2: logger.error(u"order.nalog.ru вернул неожиданный ответ: %s" % result) parts = parts[1].split("'") if len(parts) < 2: logger.error(u"order.nalog.ru вернул неожиданный ответ: %s" % result) code = parts[0].strip() logger.debug(u'booking url: http://order.nalog.ru/appointment/R%s/' % code) result = requests.get(u'http://order.nalog.ru/appointment/R%s/' % code, timeout=20) if result.status_code != 200 or not result.content: logger.error(u"order.nalog.ru вернул неожиданный ответ") raise errors.ServerUnavailable() root = html5lib.parse(result.text, treebuilder='lxml', namespaceHTMLElements=False) #noinspection PyCallingNonCallable if not len(CSSSelector("#ctl00_pnlDetails")(root)): logger.error(result.text) raise errors.DuplicateBookingAtTheSameTime() if len(CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")(root)) < 18: logger.error(u"order.nalog.ru вернул неожиданный ответ: %s" % result.text) raise errors.ServerUnavailable() #noinspection PyCallingNonCallable ifns = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")(root)[3].text #noinspection PyCallingNonCallable address = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")(root)[5].text #noinspection PyCallingNonCallable map = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")(root)[7].text #noinspection PyCallingNonCallable phone = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")(root)[9].text #noinspection PyCallingNonCallable service = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")(root)[11].text #noinspection PyCallingNonCallable data_str = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")( root)[13].text #noinspection PyCallingNonCallable time_str = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")( root)[15].text #noinspection PyCallingNonCallable window = CSSSelector("#ctl00_pnlDetails>table>tbody>tr>td")(root)[17].text try: dt = datetime.strptime(data_str + 'T' + time_str, "%d.%m.%YT%H:%M") except Exception: raise errors.ServerError(u"Invalid datetime format") return { "ifns": ifns, "service": service, "date": dt.strftime("%Y-%m-%dT%H:%M:%S"), "window": window, "address": address, "phone": phone, "how_to_get": map, "code": code }
'result': { "ifns": result['ifns'], "id": booking.id, "service": result['service'], "service_id": service, "date": result['date'], "window": result['window'], "address": result['address'], "phone": result['phone'], "how_to_get": result['how_to_get'], "code": result['code'] } } except Exception: logger.exception(u"Failed to save booking!") raise errors.ServerError() if result_value: raise gen.Return(result_value) logger.error(u"Failed to reserve ifns due to unknown reason.") raise errors.ServerError() class IfnsBookingView(JsonRequestHandler): @gen.coroutine @authorized @validate_arguments_tornado(batch_id=ObjectIdValidator(required=True)) def get_content_on_get(self, arguments=None, *args, **kwargs): result_values = [] logger = self.application.logger # todo: ifns logger! batch_id = arguments['batch_id']
def get_nalog_ru_time_slots(person_data, company_data, internal_ifns_number, internal_ifns_service, logger): s = requests.Session() result = s.get(u'http://order.nalog.ru/details/', timeout=20) if result.status_code != 200: logger.error(u"Невозможно начать сессию с сервером order.nalog.ru") raise errors.ServerUnavailable() if company_data: data = { "ctl00$LastName": company_data['name'], "ctl00$inn": company_data['inn'], "ctl00$phone": company_data['phone'], "ctl00$email": company_data['email'], "__VIEWSTATE": u"", "ctl00$face": u"0", "ctl00$btNext": "" } # start session result = s.post(u'http://order.nalog.ru/details/', data=data, timeout=20) if result.status_code != 200 or not result.text: logger.error(u"order.nalog.ru вернул неожиданный код: %s" % unicode(result.status_code)) raise errors.ServerUnavailable() elif person_data: data = { "ctl00$LastName": person_data['surname'], "ctl00$FirstName": person_data['name'], "ctl00$SecondName": person_data['patronymic'] or u"", "ctl00$inn": person_data['inn'], "ctl00$phone": person_data['phone'] or u"", "ctl00$email": person_data['email'], "__VIEWSTATE": u"", "ctl00$face": u"1", "ctl00$btNext": "" } result = s.post(u'http://order.nalog.ru/details/', data=data, timeout=20) if result.status_code != 200 or not result.text: logger.error(u"order.nalog.ru вернул неожиданный код: %s" % unicode(result.status_code)) raise errors.ServerUnavailable() else: logger.error(u"Invalid parameters") raise errors.ServerError() fns, sub_service = internal_ifns_number, internal_ifns_service # get_ifns_internal_id_by_ifns_name(s, region_name, reg_ifns_name, not company_data, logger, service) service = 0 is_multi_sub_service = 0 cb_param = 'c0:%d;%d;%d;%d' % (sub_service, is_multi_sub_service, (service if is_multi_sub_service else sub_service), fns) data = { "__CALLBACKID": u"ctl00$cpday", "__CALLBACKPARAM": cb_param, "__EVENTTARGET": u"", "__EVENTARGUMENT": "", "__VIEWSTATE": u"", } result = s.post(u'http://order.nalog.ru/fns_service/', data=data, timeout=20) if result.status_code != 200 or not result.content: logger.error(u"order.nalog.ru вернул неожиданный ответ") raise errors.ServerUnavailable() str_data = result.text[26:-3].encode( 'utf-8').decode('string_escape').replace('!-\\-', '!--').replace( '/-\\-', '/--').replace('\\/script', '/script') content = u"<!DOCTYPE html><html><head><title></title></head><body>%s</body></html>" % str_data.decode( 'utf-8') root = html5lib.parse(content, treebuilder='lxml', namespaceHTMLElements=False) year = None month = None # noinspection PyCallingNonCallable for item in CSSSelector('#ctl00_cpday_day_T')(root): item_text_parts = item.text.split(' ') if len(item_text_parts) < 2: logger.error(u"Ожидалась дата, получили %s" % item.text) raise errors.ServerUnavailable( u"Invalid nalog.ru service return content") try: month = MONTHS[item_text_parts[0].strip()] year = int(item_text_parts[1].strip()) break except Exception: logger.error(u"Не удалось распарсить дату: %s" % item.text) raise errors.ServerUnavailable( u"Invalid nalog.ru service return content") if not month or not year: logger.error(u"Дату так и не получили") raise Exception(u"Invalid nalog.ru service return content") day_prev = -1 days = [] first = True #noinspection PyCallingNonCallable for item in CSSSelector('#ctl00_cpday_day_mt td.dxeCalendarDay')(root): #logger.info('month: %s, item:%s' % (str(month), stringify_children(item))) classes = filter(lambda x: not not x, [i.strip() for i in item.attrib['class'].split(' ')]) #logger.info('classes:%s' % unicode(classes)) try: day = int(item.text) if first and (23 <= day <= 31): month -= 1 # (facepalm) first = False except Exception: logger.error(u"Invalid nalog.ru service response: %s" % unicode(item.text)) raise errors.ServerUnavailable( u"Invalid nalog.ru service response: %s" % unicode(item.text)) if day_prev > day: month += 1 #logger.info('increase month:%s'%str(month)) if month > 12: year += 1 month = 1 day_prev = day if 'dxeCalendarOutOfRange' in classes or 'dxeCalendarToday' in classes: #logger.info('skip') continue d = datetime(year, month, day) if d not in (datetime(2015, 5, 1), datetime(2015, 5, 2), datetime(2015, 5, 3), datetime(2015, 5, 4), datetime(2015, 5, 9), datetime(2015, 5, 10), datetime(2015, 5, 11)): days.append(d) if not days: logger.error(u"Invalid nalog.ru service response: no days returned") raise errors.ServerUnavailable( u"Invalid nalog.ru service response: no days returned") # ban check d = days[0] result = s.post('http://order.nalog.ru/fns_service/', data={ "__CALLBACKID": u"ctl00$clBanCheck", "__CALLBACKPARAM": u"c0:%s.%s.%s;%s;%s;0" % (unicode(d.year), unicode(d.month), unicode( d.day), unicode(180), unicode(fns)), "__EVENTARGUMENT": u"", "__EVENTTARGET": u"", "__VIEWSTATE": u"", }, timeout=20) if result.status_code != 200 or not result.content: logger.error(u"order.nalog.ru вернул неожиданный ответ") raise errors.ServerUnavailable() if "'data':'0'" in result.text: raise errors.MaximumRegistrationsExceeded() day_info = [] # get time slots for d in days: part = u"%d.%d.%d;%d;%d;%d;%d" % ( d.year, d.month, d.day, service if is_multi_sub_service else sub_service, fns, is_multi_sub_service, sub_service) part2 = u"14|CUSTOMCALLBACK%d|" % len(part) + part cb_param = u"c0:KV|2;[];GB|%d;" % len(part2) + part2 + ";" data = { "__CALLBACKID": u"ctl00$gvTime", "__CALLBACKPARAM": cb_param, "__EVENTARGUMENT": u"", "__EVENTTARGET": u"", "__VIEWSTATE": u"", } result = s.post('http://order.nalog.ru/fns_service/', data=data, timeout=20) if result.status_code != 200 or not result.content: logger.error(u"order.nalog.ru вернул неожиданный ответ") raise errors.ServerUnavailable() data_str = result.text[19:].encode( 'utf-8').decode('string_escape').replace('!-\\-', '!--').replace( '/-\\-', '/--').replace('\\/script', '/script') content = u"<!DOCTYPE html><html><head><title></title></head><body>%s</body></html>" % data_str.decode( 'utf-8') root = html5lib.parse(content, treebuilder='lxml', namespaceHTMLElements=False) time_slots = [] #noinspection PyCallingNonCallable for item in CSSSelector('#ctl00_gvTime_DXMainTable tr')(root): #noinspection PyCallingNonCallable tds = CSSSelector('td')(item) if len(tds) > 1: time_str = tds[0].text #noinspection PyCallingNonCallable spans = CSSSelector('span')(tds[1]) if len(spans): span_style = spans[0].attrib['style'] available = 'block' not in span_style #print(time_str, available) if available: hour, minutes = time_str.strip().replace( '00', '0').split(':') dt = datetime(2014, 1, 1, int(hour), int(minutes)) time_slots.append({ "slot_start": dt.strftime("%H:%M"), "slot_end": (dt + timedelta(seconds=1800)).strftime("%H:%M"), }) if time_slots: day_info.append({ 'date': d.strftime("%Y-%m-%d"), 'time_slots': time_slots }) return day_info
def request_bank_partner(bank_id=None, batch_id=None, bank_contact_phone_general_manager=False, bank_contact_phone="", send_private_data=None): if not bank_contact_phone_general_manager and not bank_contact_phone: raise errors.MissingRequiredParameter('bank_contact_phone') batch = DocumentBatchDbObject.query.filter_by( id=batch_id, _owner=current_user, deleted=False, batch_type=DocumentBatchTypeEnum.DBT_NEW_LLC).scalar() if not batch or not batch.data: raise errors.BatchNotFound() current_batch = DocumentBatch.db_obj_to_field(batch) partner = BankPartnersObject.query.filter_by(id=bank_id).first() if not partner: raise errors.InvalidParameterValue('partner_id') svc_data = BankPartnersServiceObject.query.filter_by( bank_partner_id=partner.id).first() if not svc_data: raise errors.ServerError() current_bank_request = BankPartnerRequestObject.query.filter_by( bank_partner_id=partner.id, batch_id=batch_id).first() if current_bank_request and current_bank_request.status in ('sending', 'success'): struct = current_batch.get_api_structure() return {'result': struct} if current_bank_request and abs( (datetime.utcnow() - current_bank_request.sent_date).total_seconds()) > 60: BankPartnerRequestObject.query.filter_by( id=current_bank_request.id).delete() sqldb.session.commit() current_bank_request = None svc_type = svc_data.type fields = svc_data.fields extra_context = { 'bank_contact_phone_general_manager': bank_contact_phone_general_manager, 'bank_contact_phone': bank_contact_phone, 'send_private_data': send_private_data, 'bank_title': partner.title } field_list = BatchManager.make_fields_from_data( batch_id, fields, current_app.config, extra_context=extra_context) context = {} errors_list = [] for name in field_list: field = field_list[name] try: if not field.initialized: if field.required: raise MissingRequiredFieldException(name) else: field.validate() except (InvalidFieldValueException, MissingRequiredFieldException), ex: if hasattr(field, "suppress_validation_errors"): suppress_validation_errors = field.suppress_validation_errors if isinstance(suppress_validation_errors, dict): suppress_validation_condition = Condition( suppress_validation_errors) context = copy.copy(batch.data) context.update(extra_context) suppress_validation_errors = suppress_validation_condition.check( context) if suppress_validation_errors: continue if getattr(ex, 'ext_data', None): err_list = error_tree_to_list(ex.ext_data) error_field_paths = [{ 'field': name + '.' + i['field'], 'error_code': i['error_code'] } for i in err_list] errors_list.extend(error_field_paths) else: errors_list.append({ 'field': name, 'error_code': ex.ERROR_CODE }) current_app.logger.exception(u"Field %s validation error" % name) continue if field_list[name].initialized: context[name] = field_list[name]