def get_request_id():
    if 'registration_no' in request.args:
        reg_no = request.args['registration_no']
    else:
        return Response(json.dumps({'error': 'no registration_no'}),
                        status=400)

    if 'registration_date' in request.args:
        reg_date = request.args['registration_date']
    else:
        return Response(json.dumps({'error': 'no registration_date'}),
                        status=400)

    if 'reprint_type' in request.args:
        reprint_type = request.args['reprint_type']
    else:
        return Response("no reprint_type specified", status=400)

    logging.audit(
        format_message("Retrieve request details for registration %s of %s"),
        reg_no, reg_date)
    request_id = 0
    if reprint_type == 'registration':
        request_id = get_k22_request_id(reg_no, reg_date)
    elif reprint_type == 'search':
        request_id = 0  # write method to get k17/18 request ids

    return Response(json.dumps(request_id),
                    status=200,
                    mimetype='application/json')
def reprints(reprint_type):
    request_id = ''
    if reprint_type == 'registration':
        registration_no = request.args['registration_no']
        registration_date = request.args['registration_date']
        url = app.config['LAND_CHARGES_URI'] + '/request_details?reprint_type=' + reprint_type
        url += '&registration_no=' + registration_no + '&registration_date=' + registration_date
        response = requests.get(url, headers=get_headers())
        data = json.loads(response.content.decode('utf-8'))
        if "request_id" not in data:
            return "invalid request_id for " + registration_no + ' ' + registration_date
        request_id = data['request_id']
    elif reprint_type == 'search':
        request_id = request.args['request_id']
    if not request_id:
        datetime.strptime(registration_date, '%Y-%m-%d')
        formatted_registration_date = datetime.strptime(registration_date, '%Y-%m-%d').strftime('%d/%m/%Y')
        err = "Could not find request for {} of {}.".format(registration_no, formatted_registration_date)
        logging.error(format_message(err))
        return Response(err, status=400)
    logging.audit(format_message("Request reprint for %s"), request_id)
    # for the time being call reprint on result-generate. this probably needs moving into casework-api
    url = app.config['RESULT_GENERATE_URI'] + '/reprints?request=' + str(request_id)
    response = requests.get(url, headers=get_headers())
    if response.headers['content-type'] == 'application/pdf':
        return send_file(BytesIO(response.content), as_attachment=False, attachment_filename='reprint.pdf',
                         mimetype='application/pdf')
    else:
        err = "An error occured {}.".format(response.text)
        logging.error(format_message(err))
        return Response(err, status=405)
def get_searches():
    logging.audit(format_message("Search reprints"))
    search_data = request.data
    response = requests.post(app.config['LAND_CHARGES_URI'] + '/request_search_details', data=search_data,
                             headers=get_headers({'Content-Type': 'application/json'}))
    data = json.loads(response.content.decode('utf-8'))
    return Response(json.dumps(data), status=200, mimetype='application/json')
def registration(date, reg_no):
    if "class_of_charge" in request.args:
        class_of_charge = request.args["class_of_charge"]
    else:
        class_of_charge = None
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        logging.audit(format_message("Retrieve entry details for %s, %s"),
                      reg_no, date)

        details = get_registration_details(cursor, reg_no, date,
                                           class_of_charge)
        if details is not None:
            addl_info = get_additional_info(cursor, details)

            if addl_info is not None:
                details['additional_information'] = addl_info
    finally:
        complete(cursor)
    if details is None:
        logging.warning(
            format_message("Returning 404 for /registrations/{}/{}".format(
                date, reg_no)))
        return Response(status=404)
    else:
        return Response(json.dumps(details),
                        status=200,
                        mimetype='application/json')
def unlock_application(appn_id):
    logging.info(format_message("Unlock application"))
    logging.audit(format_message("Unlock application"))
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        clear_lock_ind(cursor, appn_id)
    finally:
        complete(cursor)
    return Response(status=200)
def update_request_fee(request_id, transaction_fee):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    cursor.execute(
        'UPDATE request SET transaction_fee = %(fee)s '
        'WHERE id = %(request_id)s', {
            'request_id': request_id,
            'fee': transaction_fee
        })
    logging.audit(format_message("Set transaction fee to %s for request %s"),
                  transaction_fee, request_id)
    complete(cursor)
    return Response(status=200)
def get_office_copy():
    logging.audit("Retrieve office copy")
    class_of_charge = request.args['class']
    reg_no = request.args['reg_no']
    date = request.args['date']
    uri = app.config['LAND_CHARGES_URI'] + '/office_copy' + '?class=' + class_of_charge + '&reg_no=' + reg_no + \
        '&date=' + date
    response = requests.get(uri, headers=get_headers({'Content-Type': 'application/json'}))
    logging.info('GET {} -- {}'.format(uri, response.text))
    data = json.loads(response.text)
    contents, file_name = create_document_only(data, app.config)
    response = send_file(BytesIO(contents), as_attachment=True, attachment_filename=file_name)
    return response
def lock_application(appn_id):
    logging.info(format_message("Lock application"))
    logging.audit(format_message("Lock application"))
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        locked = set_lock_ind(cursor, appn_id)
        if locked is None:
            # Selected application already locked or no longer on work list
            return Response(status=404)
        else:
            return Response(status=200)
    finally:
        complete(cursor)
def remove_application(appn_id):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        if 'reject' in request.args:
            logging.audit(format_message("Reject application"))
        else:
            logging.audit(format_message("Remove application"))
        rows = delete_application(cursor, appn_id)
    finally:
        complete(cursor)

    if rows == 0:
        return Response(status=404)
    return Response(status=204, mimetype='application/json')
def all_registrations():
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        logging.audit(format_message("Retrieve all registrations"))
        details = get_all_registrations(cursor)
    finally:
        complete(cursor)
    if details is None:
        logging.warning(format_message("Returning 404 for /registrations"))
        return Response(status=404)
    else:
        return Response(json.dumps(details),
                        status=200,
                        mimetype='application/json')
def get_registration(reg_date, reg_name):
    if "class_of_charge" in request.args:
        class_of_charge = request.args["class_of_charge"]
    else:
        class_of_charge = None

    logging.audit(format_message("Retrieve registration details for %s / %s"), reg_date, reg_name)
    response = get_registration_details(reg_date, reg_name, class_of_charge)
    logging.debug(response['data'])

    if response['status'] != 200:
        return Response(json.dumps(response['data']), status=response['status'], mimetype='application/json')
    else:
        return Response(json.dumps(response['data']), status=200, mimetype='application/json')
def reclassify_form():
    data = request.get_json(force=True)
    appn_id = data['appn_id']
    form_type = data['form_type']
    logging.info("T:%s Reclassify as a %s Application ", str(appn_id), str(form_type))
    logging.audit(format_message("Reclassify %s as %s"), str(appn_id), str(form_type))
    work_type = get_work_type(form_type)
    logging.info("move to %s", work_type["list_title"])
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        unlock_application(appn_id)
        reclassify_appn(cursor, appn_id, form_type, work_type["work_type"])
    finally:
        complete(cursor)
    return Response(json.dumps(work_type), status=200, mimetype='application/json')
def registrations_by_date(date):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        logging.audit(format_message("Retrieve registrations dated %s"), date)
        details = get_registrations_by_date(cursor, date)
    finally:
        complete(cursor)
    if details is None:
        logging.warning(
            format_message("Returning 404 for date {}".format(date)))
        return Response(status=404)
    else:
        return Response(json.dumps(details),
                        status=200,
                        mimetype='application/json')
def registration_history(date, reg_no):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        logging.audit(format_message("Retrieve entry history for %s, %s"),
                      reg_no, date)
        details = get_registration_history(cursor, reg_no, date)
    finally:
        complete(cursor)
    if details is None:
        logging.warning("Returning 404")
        return Response(status=404)
    else:
        return Response(json.dumps(details),
                        status=200,
                        mimetype='application/json')
def get_application(appn_id):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)

    # locked = lock_application(cursor, appn_id)
    # if locked is None:
    #     # Selected application already locked or no longer on work list
    #     complete(cursor)
    #     return Response(status=404)
    # else:
    try:
        logging.audit("Retrieve application")
        appn = get_application_by_id(cursor, appn_id)
    finally:
        complete(cursor)

    return Response(json.dumps(appn), status=200, mimetype='application/json')
def get_searches_by_date(date):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        data = get_search_ids_by_date(cursor, date)
    finally:
        logging.audit(format_message("Retrieve searches for date: %s"), date)
        complete(cursor)

    if data is None:
        logging.warning(
            format_message("Returning 404 for date {}".format(date)))
        return Response(status=404)
    else:
        return Response(json.dumps(data),
                        status=200,
                        mimetype='application/json')
def create_search():
    if request.headers['Content-Type'] != "application/json":
        logging.error(format_message('Content-Type is not JSON'))
        return Response(status=415)

    data = request.get_json(force=True)
    logging.debug('this is search data: %s', json.dumps(data))
    errors = validate(data, SEARCH_SCHEMA)
    if errors is not None:
        return Response(json.dumps(errors), status=400)
    logging.debug(data['parameters']['search_type'])

    if data['parameters']['search_type'] not in ['full', 'banks']:
        message = "Invalid search type supplied: {}".format(
            data['parameters']['search_type'])
        logging.error(format_message(message))
        return Response(message, status=400)

    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        # Store the search request
        if 'X-LC-Username' in request.headers:
            data['user_id'] = request.headers['X-LC-Username']
        search_request_id, search_details_id, search_data = store_search_request(
            cursor, data)

        # Run the queries
        results = perform_search(cursor, search_data['parameters'],
                                 search_data['search_date'])
        for item in results:
            store_search_result(cursor, search_request_id, search_details_id,
                                item['name_id'], item['name_result'])

        logging.audit(format_message("Submit search request: %d, ID: %d"),
                      search_request_id, search_details_id)
        complete(cursor)
        logging.info(format_message("Search request and result committed"))
    except:
        rollback(cursor)
        raise
    results = [search_request_id]
    if len(results) == 0:
        return Response(status=404)
    else:
        return Response(json.dumps(results, ensure_ascii=False),
                        status=200,
                        mimetype='application/json')
def retrieve_office_copy():
    class_of_charge = request.args['class']
    reg_no = request.args['reg_no']
    date = request.args['date']

    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        data = get_ins_office_copy(cursor, class_of_charge, reg_no, date)
    finally:
        logging.audit(format_message("Retrieve office copy for %s, %s (%s)"),
                      reg_no, date, class_of_charge)
        complete(cursor)

    if data is None:
        return Response(data, status=404, mimetype='application/json')
    else:
        return Response(data, status=200, mimetype='application/json')
def get_search_type(request_id):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    # get all rows for this request id, if none contain results then search type is 'search_nr'
    try:
        sql = "Select result from search_results where request_id = %(request_id)s"
        cursor.execute(sql, {"request_id": request_id})
        rows = cursor.fetchall()
    finally:
        logging.audit(
            format_message("Retrieve search results for request: %s"),
            request_id)
        complete(cursor)
    search_type = {'search_type': 'search nr'}
    for row in rows:
        if row['result']:
            search_type = {'search_type': 'search'}
    return Response(json.dumps(search_type),
                    status=200,
                    mimetype='application/json')
def get_request_details(request_id):
    request_type = get_request_type(request_id)
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        if request_type.lower() == 'search':
            data = get_search_request_details(request_id)
        else:  # not a search - reg register details
            data = get_register_request_details(request_id)

            for index, row in enumerate(
                    data):  # Each AKA registration needs populating

                revealable = get_most_recent_revealable(
                    cursor, row["registration_no"], row["registration_date"])
                if revealable:
                    if index < len(revealable['registrations']):
                        details = get_registration_details(
                            cursor,
                            revealable['registrations'][index]['number'],
                            revealable['registrations'][index]['date'])
                else:  # if nothing came back from revealable
                    details = get_registration_details(
                        cursor, row["registration_no"],
                        row["registration_date"])
                if details is not None:
                    if 'particulars' in details:
                        if 'counties' in details['particulars']:
                            if len(details['particulars']['counties']) > 1:
                                county = get_county(cursor,
                                                    row['registration_no'],
                                                    row['registration_date'])
                                details['particulars']['counties'] = county
                    addl_info = get_additional_info(cursor, details)
                    if addl_info is not None:
                        details['additional_information'] = addl_info
                row['details'] = details
    finally:
        logging.audit(format_message("Retrieve request details for ID: %s"),
                      request_id)
        complete(cursor)
    return Response(json.dumps(data), status=200, mimetype='application/json')
def registration_by_id(reg_id):
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        logging.audit(format_message("Retrieve entry details for %s"), reg_id)

        details = get_registration_details_by_register_id(cursor, reg_id)
        if details is not None:
            addl_info = get_additional_info(cursor, details)

            if addl_info is not None:
                details['additional_information'] = addl_info
    finally:
        complete(cursor)
    if details is None:
        logging.warning(
            format_message(
                "Returning 404 for /registrations/{}".format(reg_id)))
        return Response(status=404)
    else:
        return Response(json.dumps(details),
                        status=200,
                        mimetype='application/json')
def court_ref_existence_check(ref):
    logging.debug("Court existence checking")
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        logging.audit(format_message("Retrieve details by court: %s"), ref)
        cursor.execute(
            "SELECT registration_no, date FROM register r, register_details rd "
            + "WHERE UPPER(rd.legal_body_ref)=%(body_ref)s " +
            "AND rd.id=r.details_id "
            "AND (r.expired_on is NULL OR r.expired_on > current_date) "
            "AND rd.cancelled_by is NULL " +
            "AND (UPPER(rd.amendment_type)!='CANCELLATION' or rd.amendment_type is NULL) ",
            {"body_ref": ref.upper()})
        rows = cursor.fetchall()
        results = []
        if len(rows) > 0:
            status_code = 200
            for row in rows:
                details = get_registration_details(cursor,
                                                   row['registration_no'],
                                                   row['date'])
                debtor_name = details['parties'][0]['names'][0]['private']
                name_string = " ".join(
                    debtor_name['forenames']) + " " + debtor_name['surname']
                results.append({
                    'reg_no': details['registration']['number'],
                    'date': details['registration']['date'],
                    'class_of_charge': details['class_of_charge'],
                    'name': name_string
                })
        else:
            status_code = 404
    finally:
        complete(cursor)

    return Response(json.dumps(results),
                    status=status_code,
                    mimetype='application/json')
def get_request_type(request_id):
    if not request_id:
        return None
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    # get all rows for this request id, if none contain results then search type is 'search_nr'
    try:
        cursor.execute(
            "Select application_type "
            "from request where id = %(request_id)s ",
            {"request_id": request_id})
        rows = cursor.fetchall()
    finally:
        logging.audit(format_message("Retrieve request type for request: %s"),
                      request_id)
        complete(cursor)
    data = ""
    if rows:
        for row in rows:
            data = row['application_type']
    else:
        logging.error("could not find request " + request_id)
        return None
    return data
def associate_image():
    data = request.get_json(force=True)
    logging.debug(json.dumps(data))
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    logging.audit(format_message("Link image to registration %s of %s"), data['reg_no'], data['date'])
    try:
        cursor.execute("UPDATE registered_documents SET doc_id = %(doc_id)s " +
                       "WHERE number=%(reg)s and date=%(date)s",
                       {
                           "doc_id": data['document_id'], "reg": int(data['reg_no']), "date": data['date']
                       })
        rows = cursor.rowcount
        if rows == 0:
            status_code = 404
        else:
            delete_application(cursor, data['appn_id'])
            status_code = 200
        complete(cursor)
    except:
        rollback(cursor)
        raise

    return Response(status=status_code, mimetype='application/json')
def get_searches():
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)

    try:
        if 'name' in request.args:
            name = request.args['name']
            result = read_searches(cursor, name)

        elif 'id' in request.args:
            result = get_search_by_request_id(cursor, request.args['id'])

        else:
            result = []

        data = []
        for results in result:
            for ids in results['result']:
                reg_data = get_registration(cursor, ids, None)
                data.append({
                    'reg_id': ids,
                    'reg_no': reg_data['registration_no'],
                    'reg_date': reg_data['registration_date'],
                    'class': reg_data['class_of_charge']
                })

    finally:
        if 'name' in request.args:
            logging.audit(
                format_message("Retrieve search results by name: %s"),
                request.args['name'])

        elif 'id' in request.args:
            logging.audit(format_message("Retrieve search results by ID: %s"),
                          request.args['id'])

        else:
            logging.audit(format_message("Retrieve search results"))

        complete(cursor)

    return Response(json.dumps(data), status=200, mimetype='application/json')
示例#26
0
def get_multi_reg_check(reg_date, reg_no):
    logging.audit(format_message("Check multiple registration for %s %s"), reg_no, reg_date)
    url = app.config['LAND_CHARGES_URI'] + '/multi_reg_check/' + reg_date + "/" + reg_no
    data = requests.get(url, headers=get_headers())
    return Response(data, status=200, mimetype='application/json')
示例#27
0
def update_application(appn_id):
    # TODO: validate
    action = 'store'
    if 'action' in request.args:
        action = request.args['action']

    logging.debug(request.headers)

    data = request.get_json(force=True)
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    # store fee info for later use. Quick fix because of data structure in rectifications
    if 'fee_details' in data:
        fee_ind = True
        fee_details = data['fee_details']
    else:
        fee_ind = False
        fee_details = {}

    try:
        if action == 'store':
            logging.info(format_message("Store application"))
            logging.audit(format_message("Store application"))
            # logging.debug(data)
            # update_application_details(cursor, appn_id, data)
            store_application(cursor, appn_id, data)
            appn = get_application_by_id(cursor, appn_id)
        elif action == 'complete':
            logging.info(format_message("Complete registration"))
            logging.audit(format_message("Complete application"))
            appn = complete_application(cursor, appn_id, data)
        elif action == 'amend' or action == 'rectify':
            logging.info(format_message("Complete update"))
            logging.audit(format_message("Complete update application"))
            appn = amend_application(cursor, appn_id, data)
        elif action == 'cancel':
            logging.info(format_message("Complete cancellation"))
            logging.audit(format_message("Complete cancellation application"))
            appn = cancel_application(cursor, appn_id, data)
        elif action == 'renewal':
            logging.info(format_message("Complete renewal"))
            logging.audit(format_message("Complete renewal application"))
            appn = renew_application(cursor, appn_id, data)
        elif action == 'correction':
            logging.info(format_message("Complete correction"))
            logging.audit(format_message("Complete correction"))
            appn = correct_application(cursor, data)
        else:
            return Response("Invalid action", status=400)
        # sort out the fee
        # everything but searches
        if fee_ind is True:
            logging.debug("fee selected" + json.dumps(fee_details))
            if fee_details['type'] == 'wf' or  fee_details['type'] == 'nf':
                save_request_fee(str(appn['request_id']), str(0))
            else:
                # build the fee details to pass to legacy_adapter
                build_fee_data(data, appn, fee_details, action)
        complete(cursor)
        status = 200
    except ValidationError as e:
        rollback(cursor)
        error_str = str(e)
        error_dict = json.loads(error_str[1:-1])  # Exception seems to add quotes, annoyingly
        appn = {"ValidationError": error_dict}
        status = 400
    except:
        rollback(cursor)
        raise
    return Response(json.dumps(appn), status=status)
def get_search_request_ids():
    post_data = json.loads(request.data.decode('utf-8'))
    data = post_data
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    sql = " select a.id as request_id, b.search_timestamp, c.name_type, c.forenames, c.surname, c.complex_name, " \
          " c.complex_number, c.local_authority_name, c.local_authority_area, c.other_name, c.company_name," \
          " c.year_from, c.year_to " \
          " from request a, search_details b, search_name c " \
          " where a.id = b.request_id and b.search_timestamp >= %(date_from)s and b.search_timestamp <= %(date_to)s " \
          " and b.id = c.details_id "
    date_from = datetime.datetime.strptime(data['date_from'], '%Y-%m-%d')
    date_from = date_from + datetime.timedelta(days=-1)
    date_to = datetime.datetime.strptime(data['date_to'], '%Y-%m-%d')
    date_to = date_to + datetime.timedelta(days=1)

    logging.audit(format_message("Retrieve search results in range %s - %s"),
                  date_from.strftime('%Y-%m-%d'), date_to.strftime('%Y-%m-%d'))

    params = {"date_from": date_from, "date_to": date_to}
    if data['key_number'] != '' and data['key_number'] != ' ':
        sql += " and a.key_number = %(key_number)s "
    params['key_number'] = data['key_number']
    if data['estate_owner_ind'].lower() == "privateindividual":
        forenames = ""
        for forename in data['estate_owner']['private']['forenames']:
            forenames += forename.upper() + " "
        if not forenames.strip() == "":
            sql += " and UPPER(c.forenames) = %(forenames)s "
            params['forenames'] = forenames.strip()
        if not data['estate_owner']['private']['surname'].strip() == "":
            sql += " and UPPER(c.surname) = %(surname)s "
            params['surname'] = data['estate_owner']['private'][
                'surname'].upper()
    if data['estate_owner_ind'].lower() == "countycouncil":
        if not data['estate_owner']['local']['name'] == "":
            sql += " and UPPER(c.local_authority_name) = %(local_authority_name)s "
            params['local_authority_name'] = data['estate_owner']['local'][
                'name'].upper()
        if not data['estate_owner']['local']['area'] == "":
            sql += " and UPPER(c.local_authority_area) = %(local_authority_area)s "
            params['local_authority_area'] = data['estate_owner']['local'][
                'area'].upper()
    if data['estate_owner_ind'].lower() == "localauthority":
        if not data['estate_owner']['local']['name'] == "":
            sql += " and UPPER(c.local_authority_name) = %(local_authority_name)s "
            params['local_authority_name'] = data['estate_owner']['local'][
                'name'].upper()
        if not data['estate_owner']['local']['area'] == "":
            sql += " and UPPER(c.local_authority_area) = %(local_authority_area)s "
            params['local_authority_area'] = data['estate_owner']['local'][
                'area'].upper()
    if data['estate_owner_ind'].lower() == "other":
        if not data['estate_owner']['other'] == "":
            sql += " and UPPER(c.other_name) = %(other_name)s "
            params['other_name'] = data['estate_owner']['other'].upper()
    if data['estate_owner_ind'].lower() == 'limitedcompany':
        if not data['estate_owner']['company'] == "":
            sql += " and UPPER(c.company_name) = %(company_name)s "
            params['company_name'] = data['estate_owner']['company'].upper()
    if data['estate_owner_ind'].lower() == 'complexname':
        if not data['estate_owner']['complex']['name'] == "":
            sql += " and UPPER(c.complex_name) = %(complex_name)s "
            params['complex_name'] = data['estate_owner']['complex'][
                'name'].upper()
    cursor.execute(sql, params)
    rows = cursor.fetchall()
    results = {'results': []}
    request_ids = []
    for row in rows:
        # if not row['request_id'] in request_ids:
        res = {
            'request_id': row['request_id'],
            'name_type': row['name_type'],
            'search_timestamp': str(row['search_timestamp']),
            'estate_owner': {
                'private': {
                    "forenames": row['forenames'],
                    "surname": row['surname']
                },
                'local': {
                    'name': row['local_authority_name'],
                    "area": row['local_authority_area']
                },
                'complex': {
                    "name": row['complex_name'],
                    "number": row['complex_number']
                },
                "other": row['other_name'],
                "company": row['company_name']
            }
        }
        results['results'].append(res)
        request_ids.append(row['request_id'])
    return Response(json.dumps(results),
                    status=200,
                    mimetype='application/json')
def get_keyholder(key_number):
    logging.audit(format_message("Get keyholder details"))
    uri = app.config['LEGACY_ADAPTER_URI'] + '/keyholders/' + key_number
    response = requests.get(uri, headers=get_headers())
    return Response(response.text, status=response.status_code, mimetype='application/json')
def post_search():
    data = request.get_json(force=True)

    logging.debug(json.dumps(data))
    logging.audit("Submit search")

    today = datetime.now().strftime('%Y-%m-%d')
    date_uri = app.config['LEGACY_ADAPTER_URI'] + '/dates/' + today
    date_response = requests.get(date_uri, headers=get_headers())

    if date_response.status_code != 200:
        raise CaseworkAPIError(json.dumps({
            "message": "Unexpected response from legacy_adapter/dates: " + str(date_response.status_code),
            "response": date_response.text
        }))

    # call legacy_adapter to retrieve the next search number
    url = app.config['LEGACY_ADAPTER_URI'] + '/search_number'
    response = requests.get(url, headers=get_headers())
    if response.status_code == 200:
        cert_no = response.text
    else:
        err = 'Failed to call search_number. Error code: {}'.format(str(response.status_code))
        logging.error(format_message(err))
        raise CaseworkAPIError(json.dumps({
            "message": err,
            "response": response.text
        }))

    date_info = date_response.json()
    data['expiry_date'] = date_info['search_expires']
    data['search_date'] = date_info['prev_working']
    data['cert_no'] = cert_no

    uri = app.config['LAND_CHARGES_URI'] + '/searches'
    response = requests.post(uri, data=json.dumps(data), headers=get_headers({'Content-Type': 'application/json'}))
    if response.status_code != 200:
        raise CaseworkAPIError(json.dumps(response.text))

    logging.info('POST {} -- {}'.format(uri, response.text))

    # store result
    response_data = response.json()
    logging.debug(json.dumps(response_data))
    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    try:
        # process fee info
        if data['fee_details']['type'] == 'wf' or data['fee_details']['type'] == 'nf':
            save_request_fee(str(response_data[0]), str(0))
        else:
            # build the fee details to pass to legacy_adapter
            build_fee_data(data, response_data, data['fee_details'], 'search')
        store_image_for_later(cursor, data['document_id'], None, None, response_data[0])
        complete(cursor)
    except:
        rollback(cursor)
        raise

    cursor = connect()
    for req_id in response_data:
        uri = app.config['LAND_CHARGES_URI'] + '/search_type/' + str(req_id)
        response = requests.get(uri, headers=get_headers())
        resp_data = response.json()
        res_type = resp_data['search_type']
        insert_result_row(cursor, req_id, res_type)
    complete(cursor)
    return Response(response.text, status=response.status_code, mimetype='application/json')
def register():
    # logging.log(25, format_message('Registration submitted'))

    logging.info(format_message("Received registration data: %s"),
                 request.data.decode('utf-8'))
    suppress = False
    if 'suppress_queue' in request.args:
        logging.info(format_message('Queue suppressed'))
        suppress = True

    if request.headers['Content-Type'] != "application/json":
        raise_error({
            "type": "E",
            "message": "Received invalid input data (non-JSON)",
            "stack": ""
        })
        logging.error(format_message('Content-Type is not JSON'))
        return Response(status=415)

    json_data = request.get_json(force=True)
    logging.debug(json.dumps(json_data))
    errors = validate_registration(json_data)
    if 'dev_date' in request.args and app.config['ALLOW_DEV_ROUTES']:
        logging.warning(format_message('Overriding date'))
        logging.debug(json_data)
        json_data['dev_registration'] = {'date': request.args['dev_date']}

    if len(errors) > 0:
        raise_error({
            "type": "E",
            "message": "Input data failed validation",
            "stack": ""
        })
        logging.error(format_message("Input data failed validation"))
        return Response(json.dumps(errors),
                        status=400,
                        mimetype='application/json')

    if 'postdate' in request.args:
        date = request.args['postdate']
        logging.error(
            format_message(
                'Registration submitted after closing date. Date set to {}'.
                format(date)))
        logging.debug(json_data)
        json_data['dev_registration'] = {'date': date}

    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)
    # pylint: disable=unused-variable
    try:
        # logging.audit(format_message("Submit new entries"))

        new_regns, details_id, request_id = insert_new_registration(
            cursor, get_username(), json_data)
        complete(cursor)
        logging.debug(new_regns)
        logging.info(format_message("Registration committed"))

        reg_message = ''
        for r in new_regns:
            reg_message += str(r['number']) + ' ' + r['date'] + ', '
        logging.audit(format_message("Committed new entries: %s"),
                      json.dumps(new_regns))
    except:
        if not cursor.closed:
            rollback(cursor)
        raise

    if not suppress:
        publish_new_bankruptcy(producer, new_regns)

    reg_type = 'new_registrations'
    if 'priority_notice' in json_data and json_data['priority_notice']:
        reg_type = 'priority_notices'

    return Response(json.dumps({
        reg_type: new_regns,
        'request_id': request_id
    }),
                    status=200,
                    mimetype='application/json')
def amend_registration(date, reg_no):
    # Amendment... we're being given the replacement data
    if request.headers['Content-Type'] != "application/json":
        logging.error(format_message('Content-Type is not JSON'))
        return Response(status=415)

    suppress = False
    if 'suppress_queue' in request.args:
        logging.info(format_message('Queue suppressed'))
        suppress = True

    json_data = request.get_json(force=True)

    logging.debug(json.dumps(json_data))

    if 'pab_amendment' in json_data:
        json_data['update_registration']['pab'] = "{}({})".format(
            json_data['pab_amendment']['reg_no'],
            json_data['pab_amendment']['date'])

        # #     date =
        #
        # pab_amendment = json_data['pab_amendment']
        del json_data['pab_amendment']
    # else:
    #     pab_amendment = None

    errors = validate_update(json_data)
    if 'dev_date' in request.args and app.config['ALLOW_DEV_ROUTES']:
        logging.warning(format_message('Overriding date'))
        json_data['dev_registration'] = {'date': request.args['dev_date']}

    if len(errors) > 0:
        raise_error({
            "type": "E",
            "message": "Input data failed validation",
            "stack": ""
        })
        logging.error(format_message("Input data failed validation"))
        return Response(json.dumps(errors),
                        status=400,
                        mimetype='application/json')

    cursor = connect(cursor_factory=psycopg2.extras.DictCursor)

    # TODO: may need to revisit if business rules for rectification differs to amendment
    # if appn_type == 'amend':
    # originals, reg_nos, rows = insert_amendment(cursor, reg_no, date, json_data)
    # else:
    try:
        originals, reg_nos, request_id = insert_rectification(
            cursor, get_username(), reg_no, date, json_data, None)
        data = {
            "new_registrations": reg_nos,
            "amended_registrations": originals,
            "request_id": request_id
        }

        logging.audit(format_message("Updated entries: was %s, now %s"),
                      json.dumps(originals), json.dumps(reg_nos))
        complete(cursor)
    except:
        rollback(cursor)
        raise

    return Response(json.dumps(data), status=200)