Example #1
0
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()
Example #2
0
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
    }
Example #3
0
                    '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']
Example #4
0
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
Example #5
0
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]