Конвертирование адреса

Материал из BiTel WiKi

Перейти к: навигация, поиск

По какой либо причине бывает адрес импортируется в формате текста, скрипт для конвертирования адреса из формата текст в формат адрес Разработка 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;
	}
 
}
Личные инструменты