'This callback will be called when importing location records it will look
to see if the record being imported is a duplicate.
@param item: An S3ImportItem object which includes all the details
of the record being imported
If the record is a duplicate then it will set the item method to update
Rules for finding a duplicate:
- If there is no level, then deduplicate based on the address
- Look for a record with the same name, ignoring case
- If no match, also check name_l10n
- If parent exists in the import, the same parent
- If start_date exists in the import, the same start_date
- If end_date exists in the import, the same end_date
@ToDo: Check soundex? (only good in English)
http://eden.sahanafoundation.org/ticket/481
- make a deployment_setting for relevant function?'

@staticmethod
def gis_location_duplicate(item):

    data = item.data
    name = data.get('name')
    if (not name):
        return
    level = data.get('level')
    if (not level):
        address = data.get('addr_street')
        if (not address):
            return
        table = item.table
        query = ((table.addr_street == address) & (table.deleted != True))
        postcode = data.get('addr_postcode')
        if postcode:
            query &= (table.addr_postcode == postcode)
        parent = data.get('parent')
        if parent:
            query &= (table.parent == parent)
        duplicate = current.db(query).select(table.id, limitby=(0, 1)).first()
        if duplicate:
            item.id = duplicate.id
            item.method = item.METHOD.UPDATE
        return
    MAP_ADMIN = current.auth.s3_has_role(current.session.s3.system_roles.MAP_ADMIN)
    if (level == 'L0'):
        item.method = None
        if (not MAP_ADMIN):
            item.skip = True
        return
    def skip(level, location_id):
        if (not MAP_ADMIN):
            return (not gis_hierarchy_editable(level, location_id))
        return False
    table = item.table
    settings = current.deployment_settings
    if (settings.get_database_type() == 'postgres'):
        orderby = (~ table.end_date)
    else:
        orderby = table.end_date
    code = settings.get_gis_lookup_code()
    if code:
        kv_table = current.s3db.gis_location_tag
        query = (((kv_table.tag == code) & (kv_table.value == name)) & (kv_table.location_id == table.id))
        duplicate = current.db(query).select(table.id, table.name, table.level, orderby=orderby, limitby=(0, 1)).first()
        if duplicate:
            data.name = duplicate.name
            item.id = duplicate.id
            item.method = item.METHOD.UPDATE
            item.skip = skip(duplicate.level, duplicate.id)
            return
    parent = data.get('parent')
    start_date = data.get('start_date')
    end_date = data.get('end_date')
    if (current.deployment_settings.get_database_type() == 'postgres'):
        query = ((table.name.lower() == s3_unicode(name).lower().encode('utf8')) & (table.level == level))
    else:
        query = ((table.name.lower() == name.lower()) & (table.level == level))
    if parent:
        query &= (table.parent == parent)
    if end_date:
        query &= (table.end_date == end_date)
    if start_date:
        query &= ((table.start_date == start_date) | (table.end_date == None))
    duplicate = current.db(query).select(table.id, table.level, orderby=orderby, limitby=(0, 1)).first()
    if duplicate:
        item.id = duplicate.id
        item.method = item.METHOD.UPDATE
        item.skip = skip(duplicate.level, duplicate.id)
        return
    elif current.deployment_settings.get_L10n_translate_gis_location():
        ltable = current.s3db.gis_location_name
        query = (((ltable.name_l10n == name) & (ltable.location_id == table.id)) & (table.level == level))
        if parent:
            query &= (table.parent == parent)
        if end_date:
            query &= (table.end_date == end_date)
        if start_date:
            query &= (table.start_date == start_date)
        duplicate = current.db(query).select(table.id, table.name, table.level, orderby=orderby, limitby=(0, 1)).first()
        if duplicate:
            data.name = duplicate.name
            item.id = duplicate.id
            item.method = item.METHOD.UPDATE
            item.skip = skip(duplicate.level, duplicate.id)
        else:
            pass
