package com.example.services; import com.example.services.store.*; import com.example.services.xadmin.log.XadminLog; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Path("/stores") public class StoreService { private static final Logger logger = LoggerFactory.getLogger(StoreService.class); private static List cachedStoreList; private static final Lock cacheLock = new ReentrantLock(); /** * Retrieves a store by its ID. * * @param storeId the ID of the store to retrieve * @return a response containing the store information in JSON format */ @GET @Path("/{storeId}") @Produces(MediaType.APPLICATION_JSON) public Response getStoreById(@PathParam("storeId") String storeId) { if (storeId == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"storeId parameter is required\"}").build(); } DriverManager.setLoginTimeout(5); // Set timeout to 5 seconds try (DatabaseConnectDOTSOFT databaseConnection = new DatabaseConnectDOTSOFT("com02")) { String query = "SELECT st.id_structure," + " TRIM(st.nom) as nom," + " st.tel1 as telephone," + " st.enseigne," + " 'https://mp4.ikksgroup.com/photos/' || CASE WHEN metabp.id_photo_principale IS NOT NULL THEN mpprinc.url || TO_CHAR (metabp.id_photo_principale) " + "ELSE '0/0' END || '-small.JPG' as photoLink," + " TRIM(pp.nom) AS pays, " + " (" + " SELECT" + " NVL(STRAGG(hsc2.id_caisse || '|' || hsc2.ip),'0|0.0.0.0')" + " FROM" + " com02.HOTLINE_STRUCTURE_CAISSE hsc2" + " WHERE" + " hsc2.id_structure = st.id_structure" + " AND hsc2.id_caisse BETWEEN 20 AND 39) AS caisses," + " REPLACE(REPLACE(TRIM(st.adresse1), chr(10), ''), chr(13), '') AS adresse," + " axs.date_stock as date_migration" + " FROM COM02.structure st" + " JOIN com02.PARAM_PAYS pp ON pp.id_pays = st.id_pays" + " LEFT OUTER JOIN mobretail.mp_etab_param metabp ON metabp.id_etab = st.id_structure" + " LEFT OUTER JOIN mobretail.mr_photo mpprinc ON mpprinc.id_photo = metabp.id_photo_principale" + " LEFT OUTER JOIN omni.ASPD_XSTO_STRUCTURE axs ON st.ID_STRUCTURE = axs.ID_STRUCTURE " + " WHERE st.id_structure = ?"; logger.info(query); try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query)) { statement.setString(1, storeId); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { Store store = mapResultSetTostore(resultSet); ObjectMapper objectMapper = new ObjectMapper(); String jsonResponse = objectMapper.writeValueAsString(store); return Response.ok(jsonResponse).build(); } else { return Response.status(Response.Status.NOT_FOUND).entity("{\"error\":\"No store found\"}").build(); } } } } catch (SQLException e) { e.printStackTrace(); String errorResponse = "{\"error\":\"" + e.getMessage() + "\"}"; return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponse).build(); } catch (JsonProcessingException e) { e.printStackTrace(); // Handle exceptions correctly in a production environment return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"Error processing JSON\"}").build(); } } /** * Sets cachedStoreList to null, forcing a reload of stores from the database on the next call to /stores. * * @return A response indicating success */ @GET @Path("/reload") public Response reloadStores() { cacheLock.lock(); try { cachedStoreList = null; } finally { cacheLock.unlock(); } return Response.ok("{\"status\":\"Cache cleared\"}").build(); } /** * Retrieves all stores from the database and returns them as a JSON response. * * @return A JSON response containing the list of stores */ @GET @Produces(MediaType.APPLICATION_JSON) public Response getAllStores() { if (cachedStoreList == null) { // Use of a lock to prevent multiple requests from triggering simultaneous retrieval cacheLock.lock(); try { // Check again after acquiring the lock if (cachedStoreList == null) { // Retrieve from database only if list is not cached cachedStoreList = retrieveStoresFromDatabase(); } } finally { cacheLock.unlock(); } } ObjectMapper objectMapper = new ObjectMapper(); String jsonResponse; try { jsonResponse = objectMapper.writeValueAsString(cachedStoreList); return Response.ok(jsonResponse).build(); } catch (JsonProcessingException e) { e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"Error processing JSON\"}").build(); } } /** * Retrieves stores from the database. * * @return a list of stores retrieved from the database */ private List retrieveStoresFromDatabase() { DriverManager.setLoginTimeout(5); // Set timeout to 5 seconds try (DatabaseConnectDOTSOFT databaseConnection = new DatabaseConnectDOTSOFT("com02")) { String query = "SELECT st.id_structure," + " TRIM(st.nom) as nom," + " st.tel1 as telephone," + " st.enseigne," + " 'https://mp4.ikksgroup.com/photos/' || CASE WHEN metabp.id_photo_principale IS NOT NULL THEN mpprinc.url || TO_CHAR (metabp.id_photo_principale) " + "ELSE '0/0' END || '-small.JPG' as photoLink," + " TRIM(pp.nom) AS pays, " + " (" + " SELECT" + " NVL(STRAGG(hsc2.id_caisse || '|' || hsc2.ip),'0|0.0.0.0')" + " FROM" + " com02.HOTLINE_STRUCTURE_CAISSE hsc2" + " WHERE" + " hsc2.id_structure = st.id_structure" + " AND hsc2.id_caisse BETWEEN 20 AND 39) AS caisses," + " REPLACE(REPLACE(TRIM(st.adresse1), chr(10), ''), chr(13), '') AS adresse," + " axs.date_stock as date_migration" + " FROM COM02.structure st" + " JOIN com02.PARAM_PAYS pp ON pp.id_pays = st.id_pays" + " LEFT OUTER JOIN mobretail.mp_etab_param metabp ON metabp.id_etab = st.id_structure" + " LEFT OUTER JOIN mobretail.mr_photo mpprinc ON mpprinc.id_photo = metabp.id_photo_principale" + " LEFT OUTER JOIN omni.ASPD_XSTO_STRUCTURE axs ON st.ID_STRUCTURE = axs.ID_STRUCTURE" + " WHERE axs.date_stock is not null AND st.ID_NIVEAU=4 AND st.STATUT=2 AND st.id_canal_distribution = 1 and st.magasin_demo = 0" + " ORDER BY st.id_structure"; logger.info(query); try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query); ResultSet resultSet = statement.executeQuery()) { List storeList = new ArrayList<>(); while (resultSet.next()) { Store store = mapResultSetTostore(resultSet); storeList.add(store); } return storeList; } } catch (SQLException e) { e.printStackTrace(); return Collections.emptyList(); } } @GET @Path("/{storeId}/sequence") @Produces(MediaType.APPLICATION_JSON) public Response getSequence( @PathParam("storeId") Integer storeId, @QueryParam("dbHost") String dbHost) { if(storeId == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"storeId parameter is required\"}").build(); } if (dbHost == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"dbHost parameter is required\"}").build(); } DriverManager.setLoginTimeout(5); // Set timeout to 5 seconds try (DatabaseConnectXSTORE databaseConnection = new DatabaseConnectXSTORE(dbHost,"dtv")) { String query = "SELECT ORGANIZATION_ID, RTL_LOC_ID, WKSTN_ID, SEQUENCE_ID, SEQUENCE_MODE, SEQUENCE_NBR, CREATE_DATE, CREATE_USER_ID, UPDATE_DATE, UPDATE_USER_ID, RECORD_STATE "+ "FROM DTV.COM_SEQUENCE " + "WHERE organization_id = 1 " + "ORDER BY WKSTN_ID, SEQUENCE_ID"; logger.info(query); try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query)) { ResultSet resultSet = statement.executeQuery(); List sequenceList = new ArrayList<>(); while (resultSet.next()) { StoreSequence sequence = mapResultSetToStoreSequence(resultSet); sequenceList.add(sequence); } ObjectMapper objectMapper = new ObjectMapper(); String jsonResponse; try { jsonResponse = objectMapper.writeValueAsString(sequenceList); return Response.ok(jsonResponse).build(); } catch (JsonProcessingException e) { e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"Error processing JSON\"}").build(); } } } catch (SQLException e) { e.printStackTrace(); String errorResponse = "{\"error\":\"" + e.getMessage() + "\"}"; return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponse).build(); } } @GET @Path("/{storeId}/signature") @Produces(MediaType.APPLICATION_JSON) public Response getSignature( @PathParam("storeId") Integer storeId, @QueryParam("dbHost") String dbHost) { if(storeId == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"storeId parameter is required\"}").build(); } if (dbHost == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"dbHost parameter is required\"}").build(); } DriverManager.setLoginTimeout(5); // Set timeout to 5 seconds try (DatabaseConnectXSTORE databaseConnection = new DatabaseConnectXSTORE(dbHost,"dtv")) { String query = "SELECT ORGANIZATION_ID, RTL_LOC_ID, WKSTN_ID, SIGNATURE_ID, SIGNATURE_MODE, SIGNATURE_STRING, SIGNATURE_SOURCE, CREATE_DATE, CREATE_USER_ID, UPDATE_DATE, UPDATE_USER_ID, RECORD_STATE " + "FROM DTV.COM_SIGNATURE " + "WHERE organization_id = 1 " + "ORDER BY WKSTN_ID"; logger.info(query); try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query)) { ResultSet resultSet = statement.executeQuery(); List signatureList = new ArrayList<>(); while (resultSet.next()) { StoreSignature signature = mapResultSetToStoreSignature(resultSet); signatureList.add(signature); } ObjectMapper objectMapper = new ObjectMapper(); String jsonResponse; try { jsonResponse = objectMapper.writeValueAsString(signatureList); return Response.ok(jsonResponse).build(); } catch (JsonProcessingException e) { e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"Error processing JSON\"}").build(); } } } catch (SQLException e) { e.printStackTrace(); String errorResponse = "{\"error\":\"" + e.getMessage() + "\"}"; return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponse).build(); } } @GET @Path("/{storeId}/version") @Produces(MediaType.APPLICATION_JSON) public Response getVersion( @PathParam("storeId") Integer storeId, @QueryParam("dbHost") String dbHost) { if(storeId == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"storeId parameter is required\"}").build(); } if (dbHost == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"dbHost parameter is required\"}").build(); } DriverManager.setLoginTimeout(5); // Set timeout to 5 seconds try (DatabaseConnectXSTORE databaseConnection = new DatabaseConnectXSTORE(dbHost,"dtv")) { String query = "SELECT ORGANIZATION_ID,SEQ,BASE_SCHEMA_VERSION,CUSTOMER_SCHEMA_VERSION,CUSTOMER,BASE_SCHEMA_DATE,CUSTOMER_SCHEMA_DATE, " + "CREATE_DATE,CREATE_USER_ID,UPDATE_DATE,UPDATE_USER_ID " + "FROM dtv.CTL_VERSION_HISTORY " + "WHERE organization_id = 1 AND customer IS NOT NULL " + "ORDER BY seq DESC"; logger.info(query); try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query)) { ResultSet resultSet = statement.executeQuery(); List versionList = new ArrayList<>(); while (resultSet.next()) { StoreVersion version = mapResultSetToStoreVersion(resultSet); versionList.add(version); } ObjectMapper objectMapper = new ObjectMapper(); String jsonResponse; try { jsonResponse = objectMapper.writeValueAsString(versionList); return Response.ok(jsonResponse).build(); } catch (JsonProcessingException e) { e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"Error processing JSON\"}").build(); } } } catch (SQLException e) { e.printStackTrace(); String errorResponse = "{\"error\":\"" + e.getMessage() + "\"}"; return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponse).build(); } } @GET @Path("/{storeId}/log") @Produces(MediaType.APPLICATION_JSON) public Response getLog( @PathParam("storeId") Integer storeId, @QueryParam("dbHost") String dbHost, @QueryParam("logDate") String logDate) { if(storeId == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"storeId parameter is required\"}").build(); } if (logDate == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"logDate parameter is required\"}").build(); } if (dbHost == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"dbHost parameter is required\"}").build(); } DriverManager.setLoginTimeout(5); // Set timeout to 5 seconds try (DatabaseConnectXSTORE databaseConnection = new DatabaseConnectXSTORE(dbHost,"dtv")) { String query = "SELECT" + " FROM_TZ(cel.CREATE_DATE, 'UTC') " + " AT TIME ZONE " + " CASE loc.COUNTRY " + " WHEN 'CH' THEN 'Europe/Zurich' " + " WHEN 'NL' THEN 'Europe/Amsterdam' " + " WHEN 'MC' THEN 'Europe/Monaco' " + " WHEN 'LU' THEN 'Europe/Luxembourg' " + " WHEN 'ES' THEN 'Europe/Madrid' " + " WHEN 'FR' THEN 'Europe/Paris' " + " WHEN 'US' THEN 'America/New_York' " + " WHEN 'GB' THEN 'Europe/London' " + " WHEN 'BE' THEN 'Europe/Brussels' " + " ELSE 'UTC' " + " END " + "AS CREATE_DATE, " + "cel.CREATE_USER_ID, " + "cel.BUSINESS_DATE, " + "cel.RTL_LOC_ID, "+ "cel.RTL_LOC_ID || ' - ' || loc.STORE_NAME AS STORE_NAME, " + "cel.WKSTN_ID, " + "cel.LOG_LEVEL, " + "cel.THREAD_NAME, " + "cel.LOG_MESSAGE, " + "CASE WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.app.preflight' THEN 'Pre-flight error' " + " WHEN cel.LOGGER_CATEGORY LIKE 'dtv.xstore.dataloader%' THEN 'DataLoader' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.sysadmin.data.failover' THEN 'Data-failover' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.order.download.offline' THEN 'Order error' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.state.app.startup' THEN 'Xstore startup' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.state.app.shutdown' THEN 'Xstore shutdown' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.helpdesk.memory' THEN 'Application core' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.helpdesk' THEN 'Application core' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.sysadmin.data.repqueue.errors' THEN 'Replication errors' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.sysadmin.data.repqueue.nofails' THEN 'Replication errors' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.hardware.init' THEN 'Hardware init' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.sensitive-data.logging' THEN 'Sensitive data logging' " + " WHEN cel.LOGGER_CATEGORY = 'dtv.xstore.uncaught' THEN 'Uncaught exception' " + "ELSE cel.LOGGER_CATEGORY END as LOGGER_CATEGORY " + "FROM dtv.CTL_EVENT_LOG cel " + "JOIN dtv.LOC_RTL_LOC loc ON loc.RTL_LOC_ID = cel.RTL_LOC_ID " + "WHERE cel.CREATE_DATE BETWEEN " + "TO_TIMESTAMP(?, 'YYYYMMDD HH24:MI:SS') - INTERVAL '3' HOUR " + "AND " + "TO_TIMESTAMP(?, 'YYYYMMDD HH24:MI:SS') + INTERVAL '3' HOUR " + "AND TO_CHAR(FROM_TZ(cel.CREATE_DATE, 'UTC') AT TIME ZONE " + "CASE loc.COUNTRY " + " WHEN 'CH' THEN 'Europe/Zurich' " + " WHEN 'NL' THEN 'Europe/Amsterdam' " + " WHEN 'MC' THEN 'Europe/Monaco' " + " WHEN 'LU' THEN 'Europe/Luxembourg' " + " WHEN 'ES' THEN 'Europe/Madrid' " + " WHEN 'FR' THEN 'Europe/Paris' " + " WHEN 'US' THEN 'America/New_York' " + " WHEN 'GB' THEN 'Europe/London' " + " WHEN 'BE' THEN 'Europe/Brussels' " + " ELSE 'UTC' " + "END, 'YYYYMMDD HH24:MI:SS') BETWEEN ? AND ? " + "AND cel.ORGANIZATION_ID = 1 " + "AND cel.RTL_LOC_ID = ? " + "AND cel.THREAD_NAME IS NOT NULL " + "ORDER BY cel.CREATE_DATE DESC"; logger.info(query); try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query)) { statement.setString(1, logDate + " 00:00:00"); statement.setString(2, logDate + " 23:59:59"); statement.setString(3, logDate + " 00:00:00"); statement.setString(4, logDate + " 23:59:59"); statement.setInt(5, storeId); ResultSet resultSet = statement.executeQuery(); List storeLogList = new ArrayList<>(); while (resultSet.next()) { XadminLog storeLog = mapResultSetToStoreLog(resultSet); storeLogList.add(storeLog); } ObjectMapper objectMapper = new ObjectMapper(); String jsonResponse; try { jsonResponse = objectMapper.writeValueAsString(storeLogList); return Response.ok(jsonResponse).build(); } catch (JsonProcessingException e) { e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"Error processing JSON\"}").build(); } } } catch (SQLException e) { e.printStackTrace(); String errorResponse = "{\"error\":\"" + e.getMessage() + "\"}"; return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponse).build(); } } public XadminLog mapResultSetToStoreLog(ResultSet resultSet) throws SQLException { XadminLog xadminlog = new XadminLog(); xadminlog.setCreateDate(resultSet.getDate("CREATE_DATE")); xadminlog.setCreateUserId(resultSet.getString("CREATE_USER_ID")); xadminlog.setBusinessDate(resultSet.getDate("BUSINESS_DATE")); xadminlog.setRtlLocId(resultSet.getInt("RTL_LOC_ID")); xadminlog.setStoreName(resultSet.getString("STORE_NAME")); xadminlog.setWkstnId(resultSet.getInt("WKSTN_ID")); xadminlog.setLogLevel(resultSet.getString("LOG_LEVEL")); xadminlog.setThreadName(resultSet.getString("THREAD_NAME")); xadminlog.setLogMessage(resultSet.getString("LOG_MESSAGE")); xadminlog.setLoggerCategory(resultSet.getString("LOGGER_CATEGORY")); return xadminlog; } /** * Maps a ResultSet to a store object. * * @param resultSet the ResultSet containing the data to be mapped * @return the store object with mapped data * @throws SQLException if there is an error accessing the data from the ResultSet */ private Store mapResultSetTostore(ResultSet resultSet) throws SQLException { Store store = new Store(); store.setId_structure(resultSet.getInt("ID_STRUCTURE")); store.setNom(resultSet.getString("NOM")); store.setTelephone(resultSet.getString("TELEPHONE")); store.setEnseigne(resultSet.getString("ENSEIGNE")); store.setPhotoLink(resultSet.getString("PHOTOLINK")); store.setPays(resultSet.getString("PAYS")); store.setCaisses(resultSet.getString("CAISSES")); store.setAdresse(resultSet.getString("ADRESSE")); store.setDate_migration(resultSet.getDate("DATE_MIGRATION")); return store; } @GET @Path("/{storeId}/details") @Produces(MediaType.APPLICATION_JSON) public Response getStoreDetails( @PathParam("storeId") Integer storeId, @QueryParam("dbHost") String dbHost) { if (dbHost == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"dbHost parameter is required\"}").build(); } if (storeId == null) { return Response.status(Response.Status.BAD_REQUEST).entity("{\"error\":\"storeId parameter is required\"}").build(); } try { StoreDetails storeDetails = retrieveStoreDetails(dbHost,storeId); ObjectMapper objectMapper = new ObjectMapper(); try { String jsonResponse = objectMapper.writeValueAsString(storeDetails); return Response.ok(jsonResponse).build(); } catch (JsonProcessingException e) { e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("{\"error\":\"Error converting StoreDetails to JSON\"}") .build(); } } catch (RuntimeException e) { // Capture the RuntimeException to manage SQL errors e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"" + e.getMessage() + "\"}").build(); } } /** * Retrieves storeDetails from the database. * * @param dbHost the host of the database * @param storeId the ID of the store * @param workstationId the ID of the workstation * @return storeDetails */ private StoreDetails retrieveStoreDetails(String dbHost, Integer storeId) { DriverManager.setLoginTimeout(5); StoreDetails storeDetails = new StoreDetails(); // Declare object outside try blocks try (DatabaseConnectXSTORE databaseConnection = new DatabaseConnectXSTORE(dbHost,"dtv")) { // get Pos list String PosQuery = "SELECT cdr.RTL_LOC_ID, " + "cdr.WKSTN_ID, " + "cdr.IP_ADDRESS, " + "cdr.BUSINESS_DATE, " + "cdr.XSTORE_VERSION, " + "cdr.PRIMARY_REGISTER_FLAG " + "FROM dtv.ctl_device_registration cdr " + "WHERE cdr.ORGANIZATION_ID = 1 " + "ORDER BY cdr.PRIMARY_REGISTER_FLAG desc, cdr.WKSTN_ID"; logger.info(PosQuery); try (PreparedStatement posStatement = databaseConnection.getConnection().prepareStatement(PosQuery)) { try (ResultSet posResultSet = posStatement.executeQuery()) { Integer posRtlLocId = 0; Integer posWkstnId = 0; String posIp = ""; String posVersion = ""; Date posBusinessDate = null; Integer primaryRegisterFlag = 0; while (posResultSet.next()) { posRtlLocId = posResultSet.getInt("RTL_LOC_ID"); posWkstnId = posResultSet.getInt("WKSTN_ID"); posIp = posResultSet.getString("IP_ADDRESS"); posVersion = posResultSet.getString("XSTORE_VERSION"); posBusinessDate = posResultSet.getDate("BUSINESS_DATE"); primaryRegisterFlag = posResultSet.getInt("PRIMARY_REGISTER_FLAG"); StorePos pos = new StorePos(); // add new pos object storeDetails.getPos().add(pos); pos.setWorkstationId(posWkstnId); pos.setIp(posIp); pos.setVersion(posVersion); pos.setBusinessDate(posBusinessDate); pos.setPrimaryRegister(primaryRegisterFlag); pos.setFatalError(1); // retrieve all pos details only on database of the master pos retrieveStorePosDetails(databaseConnection, posRtlLocId, posWkstnId, posBusinessDate, pos); /* if (posResultSet.getString("IP_ADDRESS").equals(dbHost)) { retrieveStorePosDetails(databaseConnection, posRtlLocId, posWkstnId, posBusinessDate, pos); } else { try (DatabaseConnectXSTORE newDatabaseConnection = new DatabaseConnectXSTORE(posIp,"dtv")) { retrieveStorePosDetails(newDatabaseConnection, posRtlLocId, posWkstnId, posBusinessDate, pos); } catch (SQLException e) { e.printStackTrace(); // Handle exceptions correctly in a production environment } } */ } } } } catch (SQLException e) { e.printStackTrace(); // Handle exceptions correctly in a production environment } try (DatabaseConnectDOTSOFT databaseConnectionDS = new DatabaseConnectDOTSOFT("com02")) { // Store section String storeQuery = "SELECT st.id_structure," + " TRIM(st.nom) as nom," + " st.tel1 as telephone," + " st.enseigne," + " 'https://mp4.ikksgroup.com/photos/' || CASE WHEN metabp.id_photo_principale IS NOT NULL THEN mpprinc.url || TO_CHAR (metabp.id_photo_principale) " + "ELSE '0/0' END || '-small.JPG' as photoLink," + " TRIM(pp.nom) AS pays, " + " (" + " SELECT" + " NVL(STRAGG(hsc2.id_caisse || '|' || hsc2.ip),'0|0.0.0.0')" + " FROM" + " com02.HOTLINE_STRUCTURE_CAISSE hsc2" + " WHERE" + " hsc2.id_structure = st.id_structure" + " AND hsc2.id_caisse BETWEEN 20 AND 39) AS caisses," + " REPLACE(REPLACE(TRIM(st.adresse1), chr(10), ''), chr(13), '') AS adresse," + " axs.date_stock as date_migration" + " FROM COM02.structure st" + " JOIN com02.PARAM_PAYS pp ON pp.id_pays = st.id_pays" + " LEFT OUTER JOIN mobretail.mp_etab_param metabp ON metabp.id_etab = st.id_structure" + " LEFT OUTER JOIN mobretail.mr_photo mpprinc ON mpprinc.id_photo = metabp.id_photo_principale" + " LEFT OUTER JOIN omni.ASPD_XSTO_STRUCTURE axs ON st.ID_STRUCTURE = axs.ID_STRUCTURE " + " WHERE st.id_structure = ?"; logger.info(storeQuery); try (PreparedStatement storeStatement = databaseConnectionDS.getConnection().prepareStatement(storeQuery)) { storeStatement.setInt(1, storeId); // Set the value of the parameter try (ResultSet storeResultSet = storeStatement.executeQuery()) { if (storeResultSet.next()) { Store store = mapResultSetToStore(storeResultSet); storeDetails.setStore(store); } else { // Adjust to the desired behavior if no results are found } } } // Transaction section String boTransactionQuery = "SELECT COUNT(*) AS backOfficeTransactions, " + " MIN(cf.fdate_integration) AS minBackOfficeTransactionDate, " + " MAX(cf.fdate_integration) AS maxBackOfficeTransactionDate " + "FROM com02.client_facture cf " + "WHERE cf.id_structure = ? " + " AND cf.id_caisse = ? " + " AND TRUNC(cf.fdate) = ? " + " AND cf.version_info = 'XSTORE'"; for (StorePos pos : storeDetails.getPos()) { logger.info(boTransactionQuery); try (PreparedStatement boTransactionStatement = databaseConnectionDS.getConnection().prepareStatement(boTransactionQuery)) { boTransactionStatement.setInt(1, storeId); boTransactionStatement.setInt(2, pos.getWorkstationId()); boTransactionStatement.setDate(3, pos.getBusinessDate()); try (ResultSet boTransactionResultSet = boTransactionStatement.executeQuery()) { if (boTransactionResultSet.next()) { BackOfficeTransaction boTransaction = mapResultSetToBoTransaction(boTransactionResultSet); pos.setBoTransaction(boTransaction); } else { // Adjust to the desired behavior if no results are found } } } catch (SQLException e) { // Handle exception } } } catch (SQLException e) { e.printStackTrace(); // Handle exceptions correctly in a production environment } // Return the complete StoreDetails object return storeDetails; } private void retrieveStorePosDetails(DatabaseConnectXSTORE databaseConnection, Integer storeId, Integer workstationId, Date businessDate, StorePos pos) throws SQLException { // Replication section String replicationQuery = "SELECT COUNT(*) AS pendingReplications, " + "MIN(crq.CREATE_DATE) AS minPendingReplicationDate, " + "MAX(crq.CREATE_DATE) AS maxPendingReplicationDate " + "FROM repqueue.CTL_REPLICATION_QUEUE crq " + "WHERE crq.organization_id = 1 AND crq.RTL_LOC_ID = ? and crq.WKSTN_ID = ?"; logger.info(replicationQuery); try (PreparedStatement replicationStatement = databaseConnection.getConnection().prepareStatement(replicationQuery)) { replicationStatement.setInt(1, storeId); replicationStatement.setInt(2, workstationId); try (ResultSet replicationResultSet = replicationStatement.executeQuery()) { if (replicationResultSet.next()) { PosReplication posReplication = mapResultSetToPosReplication(replicationResultSet); pos.setReplication(posReplication); } else { // Adjust to the desired behavior if no results are found } } } // opening transation section String openingQuery = "SELECT MIN(lsj.TIME_STAMP) AS minOpeningDate " + "FROM loc_state_journal lsj " + "WHERE lsj.TIME_STAMP BETWEEN TRUNC(SYSDATE) AND TRUNC(SYSDATE + 1) " + "AND lsj.ORGANIZATION_ID = 1 " + "AND lsj.RTL_LOC_ID = ? " + "AND lsj.WKSTN_ID = ? " + "AND lsj.STATUS_TYPCODE = 'WKSTN_STATE' " + "AND lsj.STRING_VALUE = 'OPEN'"; logger.info(openingQuery); try (PreparedStatement openingStatement = databaseConnection.getConnection().prepareStatement(openingQuery)) { openingStatement.setInt(1, storeId); openingStatement.setInt(2, workstationId); try (ResultSet openingResultSet = openingStatement.executeQuery()) { if (openingResultSet.next()) { pos.setOpeningDate(openingResultSet.getTimestamp("minOpeningDate")); } else { // Adjust to the desired behavior if no results are found } } } // closing transation section String closingQuery = "SELECT MAX(lsj.TIME_STAMP) AS maxClosingDate " + "FROM loc_state_journal lsj " + "WHERE lsj.TIME_STAMP BETWEEN TRUNC(SYSDATE) AND TRUNC(SYSDATE + 1) " + "AND lsj.ORGANIZATION_ID = 1 " + "AND lsj.RTL_LOC_ID = ? " + "AND lsj.WKSTN_ID = ? " + "AND lsj.STATUS_TYPCODE = 'WKSTN_STATE' " + "AND lsj.STRING_VALUE = 'CLOSED'"; logger.info(closingQuery); try (PreparedStatement closingStatement = databaseConnection.getConnection().prepareStatement(closingQuery)) { closingStatement.setInt(1, storeId); closingStatement.setInt(2, workstationId); try (ResultSet closingResultSet = closingStatement.executeQuery()) { if (closingResultSet.next()) { pos.setClosingDate(closingResultSet.getTimestamp("maxClosingDate")); } else { // Adjust to the desired behavior if no results are found } } } // sale transation section String saleTransactionQuery = "SELECT COUNT(*) AS counter, " + "MIN(tt.END_DATETIME) AS minDate, " + "MAX(tt.END_DATETIME) AS maxDate " + "FROM dtv.trn_trans tt " + "WHERE tt.ORGANIZATION_ID = 1 "+ "AND tt.RTL_LOC_ID = ? " + "AND tt.BUSINESS_DATE = ? " + "AND tt.WKSTN_ID = ? " + "AND tt.trans_TYPCODE = 'RETAIL_SALE' " + "AND tt.TRANS_STATCODE = 'COMPLETE'"; logger.info(saleTransactionQuery); try (PreparedStatement saleTransactionStatement = databaseConnection.getConnection().prepareStatement(saleTransactionQuery)) { saleTransactionStatement.setInt(1, storeId); saleTransactionStatement.setDate(2, pos.getBusinessDate()); saleTransactionStatement.setInt(3, workstationId); try (ResultSet saleTransactionResultSet = saleTransactionStatement.executeQuery()) { if (saleTransactionResultSet.next()) { XstoreTransaction saleTransaction = mapResultSetToSaleTransaction(saleTransactionResultSet); pos.setSaleTransaction(saleTransaction); } else { // Adjust to the desired behavior if no results are found } } } // sale transation section String logQuery = "SELECT COUNT(*) as counter " + "FROM dtv.CTL_EVENT_LOG cel " + "WHERE cel.CREATE_DATE BETWEEN TRUNC(SYSDATE) AND TRUNC(SYSDATE + 1) " + "AND cel.ORGANIZATION_ID = 1 " + "AND cel.RTL_LOC_ID = ? " + "AND cel.WKSTN_ID = ? " + "AND cel.LOG_LEVEL = 'FATAL'"; logger.info(logQuery); try (PreparedStatement logStatement = databaseConnection.getConnection().prepareStatement(logQuery)) { logStatement.setInt(1, storeId); logStatement.setInt(2, workstationId); try (ResultSet logResultSet = logStatement.executeQuery()) { if (logResultSet.next()) { pos.setFatalError(logResultSet.getInt("counter")); } else { // Adjust to the desired behavior if no results are found } } } } private Store mapResultSetToStore(ResultSet resultSet) throws SQLException { Integer id_structure = resultSet.getInt("id_structure"); String nom = resultSet.getString("nom"); String telephone = resultSet.getString("telephone"); String photoLink = resultSet.getString("photoLink"); String enseigne = resultSet.getString("enseigne"); String pays = resultSet.getString("pays"); String caisses = resultSet.getString("caisses"); String adresse = resultSet.getString("adresse"); Date date_migration = resultSet.getDate("date_migration"); return new Store(id_structure, nom, telephone, photoLink, enseigne, pays, caisses, adresse, date_migration); } private PosReplication mapResultSetToPosReplication(ResultSet resultSet) throws SQLException { int pendingReplications = resultSet.getInt("pendingReplications"); Date minPendingReplicationDate = resultSet.getDate("minPendingReplicationDate"); Date maxPendingReplicationDate = resultSet.getDate("maxPendingReplicationDate"); return new PosReplication(pendingReplications, minPendingReplicationDate, maxPendingReplicationDate); } private XstoreTransaction mapResultSetToSaleTransaction(ResultSet resultSet) throws SQLException { int count = resultSet.getInt("counter"); Date minDate = resultSet.getDate("minDate"); Date maxDate = resultSet.getDate("maxDate"); return new XstoreTransaction(count, minDate, maxDate); } private BackOfficeTransaction mapResultSetToBoTransaction(ResultSet resultSet) throws SQLException { int backofficeTransactions = resultSet.getInt("backOfficeTransactions"); Date minBackofficeTransactionDate = resultSet.getDate("minBackOfficeTransactionDate"); Date maxBackofficeTransactionDate = resultSet.getDate("maxBackOfficeTransactionDate"); return new BackOfficeTransaction(backofficeTransactions, minBackofficeTransactionDate, maxBackofficeTransactionDate); } private StoreVersion mapResultSetToStoreVersion(ResultSet resultSet) throws SQLException { long organizationId = resultSet.getLong("ORGANIZATION_ID"); long seq = resultSet.getLong("SEQ"); String baseSchemaVersion = resultSet.getString("BASE_SCHEMA_VERSION"); String customerSchemaVersion = resultSet.getString("CUSTOMER_SCHEMA_VERSION"); String customer = resultSet.getString("CUSTOMER"); Date baseSchemaDate = resultSet.getDate("BASE_SCHEMA_DATE"); Date customerSchemaDate = resultSet.getDate("CUSTOMER_SCHEMA_DATE"); Date createDate= (resultSet.getDate("CREATE_DATE")); String createUserId = resultSet.getString("CREATE_USER_ID"); Date updateDate = (resultSet.getDate("UPDATE_DATE")); String updateUserId =(resultSet.getString("UPDATE_USER_ID")); return new StoreVersion( organizationId, seq, baseSchemaVersion, customerSchemaVersion, customer, baseSchemaDate, customerSchemaDate, createDate, createUserId, updateDate, updateUserId); } private StoreSequence mapResultSetToStoreSequence(ResultSet resultSet) throws SQLException { long organizationId = resultSet.getLong("ORGANIZATION_ID"); long rtl_loc_id = resultSet.getLong("RTL_LOC_ID"); long wkstnId = resultSet.getLong("WKSTN_ID"); String sequenceId = resultSet.getString("SEQUENCE_ID"); String sequenceMode = resultSet.getString("SEQUENCE_MODE"); Long sequenceNbr = resultSet.getLong("SEQUENCE_NBR"); Date createDate = resultSet.getDate("CREATE_DATE"); String createUserId = resultSet.getString("CREATE_USER_ID"); Date updateDate = resultSet.getDate("UPDATE_DATE"); String updateUserId = resultSet.getString("UPDATE_USER_ID"); String recordState = resultSet.getString("RECORD_STATE"); return new StoreSequence(organizationId, rtl_loc_id, wkstnId, sequenceId, sequenceMode, sequenceNbr, createDate, createUserId, updateDate, updateUserId, recordState); } private StoreSignature mapResultSetToStoreSignature(ResultSet resultSet) throws SQLException { Long organizationId = resultSet.getLong("ORGANIZATION_ID"); Long rtlLocId = resultSet.getLong("RTL_LOC_ID"); Long wkstnId = resultSet.getLong("WKSTN_ID"); String signatureId = resultSet.getString("SIGNATURE_ID"); String signatureMode = resultSet.getString("SIGNATURE_MODE"); String signatureString = resultSet.getString("SIGNATURE_STRING"); String signatureSource = resultSet.getString("SIGNATURE_SOURCE"); Date createDate = resultSet.getDate("CREATE_DATE"); String createUserId = resultSet.getString("CREATE_USER_ID"); Date updateDate = resultSet.getDate("UPDATE_DATE"); String updateUserId = resultSet.getString("UPDATE_USER_ID"); String recordState = resultSet.getString("RECORD_STATE"); return new StoreSignature(organizationId, rtlLocId, wkstnId, signatureId, signatureMode, signatureString, signatureSource, createDate, createUserId, updateDate, updateUserId, recordState); } }