Конвертирование адреса
Материал из BiTel WiKi
Версия от 08:20, 1 апреля 2014; Zavndw (Обсуждение | вклад)
По какой либо причине бывает адрес импортируется в формате текста, скрипт для конвертирования адреса из формата текст в формат адрес Разработка Bitel - dimOn
v. 5.2 и 6.0
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.kernel.container.managed.ServerContext; import ru.bitel.bgbilling.kernel.module.common.bean.User; import ru.bitel.bgbilling.server.util.Setup; import ru.bitel.common.Utils; import ru.bitel.common.sql.ConnectionSet; import ru.bitel.oss.kernel.directories.address.common.bean.House; import ru.bitel.oss.kernel.directories.address.common.bean.Street; import ru.bitel.oss.kernel.directories.address.common.service.AddressService; import bitel.billing.server.admin.bean.AddressStruct; import bitel.billing.server.admin.bean.AddressUtils; import bitel.billing.server.contract.bean.ContractAddressParamValue; import bitel.billing.server.contract.bean.ContractParameterManager; public class AddressConverter { int pidText = 35;//35 int pidAddress = 26;//26 int cityId = 1; AddressService addressService; ContractParameterManager parameterManager; Connection con; boolean test = false; public void execute( Setup setup, ConnectionSet connectionSet ) { try { con = connectionSet.getConnection(); this.run(); } catch( Exception e ) { e.printStackTrace(); } } private void run() throws SQLException, BGException { PreparedStatement ps = con.prepareStatement( "DROP TABLE IF EXISTS `_incorrectContractsAddressConvertor`" ); ps.execute(); ps.close(); ps = con.prepareStatement( "DROP TABLE IF EXISTS `_correctContractsAddressConvertorTEST`" ); ps.execute(); ps.close(); ps = con.prepareStatement( "CREATE TABLE IF NOT EXISTS `_incorrectContractsAddressConvertor` ( `cid` INT NOT NULL , `sourceParameter` VARCHAR(256) NULL , PRIMARY KEY (`cid`) )" ); ps.execute(); ps.close(); parameterManager = new ContractParameterManager( con ); addressService = ServerContext.get( ServerContext.class ).getService( AddressService.class, 0 ); if( test ) { ps = con.prepareStatement( "CREATE TABLE IF NOT EXISTS `_correctContractsAddressConvertorTEST` ( `cid` INT NOT NULL , `street` VARCHAR(128) NULL , `number` INT NULL , `korpus` VARCHAR(45) NULL , `kv` VARCHAR(45) NULL , `room` VARCHAR(45) NULL , `sourse` VARCHAR(256) NULL , PRIMARY KEY (`cid`) )" ); ps.execute(); ps.close(); ps = con.prepareStatement( "SELECT * FROM _contractaddressparamtest;" ); } else { ps = con.prepareStatement( "SELECT * FROM contract_parameter_type_1 WHERE pid=?" ); // добавить это " and cid=50110" к запросу если надо протестить на конкретном договоре. сид с лева от номера договора ps.setInt( 1, pidText ); } ResultSet rs = ps.executeQuery(); while( rs.next() ) { try { int cid = rs.getInt( "cid" ); String val = rs.getString( "val" ); if( !needToParse( cid, val ) ) continue; Entry entry = parse( val, cid ); if( entry.isError ) { if( test ) { PreparedStatement statement = con.prepareStatement( "INSERT INTO _correctContractsAddressConvertorTEST VALUES(?,?,?,?,?,?,?) " ); statement.setInt( 1, cid ); statement.setString( 2, entry.street ); statement.setInt( 3, entry.numberHome ); statement.setString( 4, entry.korpus ); statement.setString( 5, entry.apartment ); statement.setString( 6, entry.room ); statement.setString( 7, val ); statement.executeUpdate(); statement.close(); } else { ContractAddressParamValue param = new ContractAddressParamValue(); Street street = getStreet( entry ); int houseId = getHousId( entry, street ); String addressFull = AddressUtils.getAddress( Setup.getSetup(), getSruct( entry, houseId ), "default"); param.setAddress( addressFull ); param.setContractId( cid ); param.setHouseId( houseId ); param.setComment( "Конвертировано из текстового параметра" ); param.setFlat( entry.apartment ); param.setRoom( entry.room ); param.setFormatKey( "" ); parameterManager.updateAddressParam( cid, pidAddress, param, User.USER_SERVER ); } } else//заносим ошибочную запись в нашу таблицу. { PreparedStatement statement = con.prepareStatement( "INSERT INTO _incorrectContractsAddressConvertor VALUES(?,?) " ); statement.setInt( 1, cid ); statement.setString( 2, val ); statement.executeUpdate(); statement.close(); } } catch( Exception e ) { e.printStackTrace(); } } rs.close(); ps.close(); } /** Если нужно добавлять данную запись, вернет true. */ private boolean needToParse( int cid, String val ) { if( val.startsWith( "п. Сокол" ) ) return false; ContractAddressParamValue paramValue = parameterManager.getAddressParam( cid, pidAddress ); if( paramValue == null) return true; else return false; } private AddressStruct getSruct( Entry entry, int houseId ) throws BGException { AddressStruct struct = new AddressStruct(); struct.setCity( addressService.cityGet( cityId ).getTitle() ); struct.setStreet( entry.street ); String korp = Utils.parseInt( entry.korpus, -1 ) > 0 && entry.korpus != null ? "/" + entry.korpus : entry.korpus; if( korp == null ) korp = ""; struct.setFrac( korp ); struct.setHouse( Integer.toString( entry.numberHome) ); struct.setHouseId( houseId ); struct.setFlat( entry.apartment ); struct.setRoom( entry.room ); return struct; } private Entry parse( String str, int cid ) { Entry entry = new Entry(); String[] mas = getRealMas( str.replaceAll( " ", " " ).split( " " ) ); int index = 0; if( mas.length == 4 )//улица дом корпус квартира { entry.street = mas[index++].trim(); entry.numberHome = Utils.parseInt( mas[index++].trim() ); entry.korpus = mas[index++].trim(); entry.apartment = mas[index++].trim(); // раскидываем номер квартиры и номер комнаты entry = splitAppartmentAndRoom( entry, mas[mas.length - 1] ); if( entry.numberHome == 0 || !chekKv( entry.apartment ) ) { entry.isError = false; } } else if( mas.length == 3 )//улица дом квартира { entry.street = mas[index++].trim(); entry.numberHome = Utils.parseInt( mas[index++].trim() ); entry.apartment = mas[index++].trim(); // раскидываем номер квартиры и номер комнаты entry = splitAppartmentAndRoom( entry, mas[mas.length - 1] ); // Если квартира буква, то видимо это корпус, а квартиры нет. Их считаем неверными. Pattern pattern = Pattern.compile( "[А-Яа-яA-Za-z]?" ); Matcher matcher = pattern.matcher( entry.apartment ); if( matcher.lookingAt() ) { entry.isError = false; entry.korpus = entry.apartment; entry.apartment = null; } if( entry.numberHome == 0 || !chekKv( entry.apartment ) ) entry.isError = false; } else if( mas.length == 2 )//Номер квартиры пустой. { entry.street = mas[index++].trim(); entry.numberHome = Utils.parseInt( mas[index++].trim() ); if( entry.numberHome == 0 ) entry.isError = false; } else entry.isError = false; return entry; } private Entry splitAppartmentAndRoom( Entry entry, String value ) { String splitSymbol = null; if( value.indexOf( "/" ) > -1 ) splitSymbol = "/"; else if( value.indexOf( "-" ) > -1 ) splitSymbol = "-"; if( splitSymbol != null ) { String[] lMas = value.split( splitSymbol ); if( lMas.length == 2 ) { entry.apartment = lMas[0]; entry.room = lMas[1]; } } return entry; } /** Возвратит Street, если она существует, иначе создаст ее и вернет. */ private Street getStreet( Entry entry ) throws BGException { List<Street> streetList = addressService.streetList( cityId, entry.street ); if( streetList.size() > 0 ) { return streetList.get( 0 ); } else { Street street = new Street(); street.setCityId( cityId ); street.setCityTitle( addressService.cityGet( cityId ).getTitle() ); street.setTitle( entry.street ); street.setId( addressService.streetUpdate( street ) ); return street; } } /** * Возвращает ид дома, если он существует( проверка по названию города, дома и корпуса/дроби ) * Если дома нет, то дом будет добавлен, и возвратит его ид. * @throws BGException */ private int getHousId( Entry entry, Street street ) throws BGException { try { String korp = Utils.parseInt( entry.korpus, -1 ) > 0 && entry.korpus != null ? "/" + entry.korpus : entry.korpus; int houseId = get( street.getId(), entry.numberHome, entry.korpus == null ? "" : "/" + entry.korpus ); if( houseId > 0 ) return houseId; else { House house = new House(); house.setCityId( cityId ); house.setCityTitle( addressService.cityGet( cityId ).getTitle() ); if( entry.korpus != null ) house.setFrac( korp ); house.setStreetId( street.getId() ); house.setStreetTitle( street.getTitle() ); house.setHouse( entry.numberHome ); house.setComment( "Создан при конвертировании" ); return addressService.houseUpdate( house ); } } catch( BGException e ) { e.printStackTrace(); throw new BGException(); } catch( SQLException e ) { e.printStackTrace(); throw new BGException(); } } private String[] getRealMas( String[] mas ) { StringBuilder street = new StringBuilder(); ArrayList<String> list = new ArrayList<String>(); boolean flag = true; for( String str : mas ) { if( flag ) { if( Utils.parseInt( str, -5 ) > 0 ) { list.add( street.toString() ); list.add( str ); flag = false; } else street.append( str + " " ); } else list.add( str ); } return list.toArray( new String[1] ); } private boolean chekKv( String kv ) { if( kv == null ) return true; Pattern pattern = Pattern.compile( "\\d+[А-Яа-яA-Za-z]?" ); Matcher matcher = pattern.matcher( kv ); if( matcher.matches() ) return true; return false; } /** * Получение ид дома из таблицы домов по параметрам его. * @param streetid * @param house * @param frac * @return ид дома из таблицы address_house, или 0 если дом не найден * @throws SQLException */ private int get( int streetid, int house, String frac ) throws SQLException { int index = 1; int houseId = 0; StringBuffer query = new StringBuffer(); query.append( "SELECT id FROM address_house WHERE streetid=? AND house=?" ); //когда-то могли лобавлять просто дробь в отдельном редакторе, //а сейчас нельзя, но проверка все равно долдна быть на дробь //до сих пор не понимаю чем это удобнее (king).@костыль if( frac.startsWith( "/" ) ) { query.append( " AND ( frac=? OR frac=? )" ); } else { query.append( " AND frac=? " ); } PreparedStatement ps = con.prepareStatement( query.toString() ); ps.setInt( index++, streetid ); ps.setInt( index++, house ); ps.setString( index++, frac ); if( frac.startsWith( "/" ) ) { ps.setString( index++, frac.substring( 1 ) ); } ResultSet rs = ps.executeQuery(); if( rs.next() ) { houseId = rs.getInt( 1 ); } rs.close(); ps.close(); return houseId; } private class Entry { String street = null; int numberHome = 0; String korpus = null; String apartment = null; String room = new String(); boolean isError = true; } }