/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.util.databasechange;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.openmrs.Order;
import liquibase.change.custom.CustomTaskChange;
import liquibase.database.Database;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.CustomChangeException;
import liquibase.exception.DatabaseException;
import liquibase.exception.SetupException;
import liquibase.exception.ValidationErrors;
import liquibase.resource.ResourceAccessor;
public class CreateDiscontinueOrders implements CustomTaskChange {
@Override
public void execute(Database database) throws CustomChangeException {
JdbcConnection connection = (JdbcConnection) database.getConnection();
try {
List<DiscontinuedOrder> discontinuedOrders = getDiscontinuedOrders(connection);
createDiscontinueOrders(connection, discontinuedOrders);
}
catch (SQLException e) {
throw new CustomChangeException(e);
}
catch (DatabaseException e) {
throw new CustomChangeException(e);
}
}
private void createDiscontinueOrders(JdbcConnection connection, List<DiscontinuedOrder> discontinuedOrders)
throws CustomChangeException, SQLException, DatabaseException {
final int batchSize = 1000;
int index = 0;
PreparedStatement insertStatement = null;
Boolean autoCommit = null;
try {
autoCommit = connection.getAutoCommit();
connection.setAutoCommit(false);
insertStatement = connection
.prepareStatement("Insert into orders(previous_order_id, concept_id, patient_id, encounter_id, "
+ "creator, date_created, discontinued_reason, discontinued_reason_non_coded, "
+ "uuid, order_action, orderer, order_number, order_type_id, start_date, auto_expire_date) "
+ "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
for (DiscontinuedOrder discontinuedOrder : discontinuedOrders) {
insertStatement.setInt(1, discontinuedOrder.previousOrderId);
insertStatement.setInt(2, discontinuedOrder.conceptId);
insertStatement.setInt(3, discontinuedOrder.patientId);
setIntOrNull(insertStatement, 4, discontinuedOrder.encounterId);
insertStatement.setInt(5, discontinuedOrder.discontinuedById);
insertStatement.setDate(6, new Date(System.currentTimeMillis()));
setIntOrNull(insertStatement, 7, discontinuedOrder.discontinuedReasonId);
insertStatement.setString(8, discontinuedOrder.discontinuedReasonNonCoded);
insertStatement.setString(9, UUID.randomUUID().toString());
insertStatement.setString(10, Order.Action.DISCONTINUE.name());
setIntOrNull(insertStatement, 11, discontinuedOrder.discontinuedById);
insertStatement.setString(12, discontinuedOrder.orderNumber);
insertStatement.setInt(13, discontinuedOrder.orderTypeId);
insertStatement.setDate(14, discontinuedOrder.dateActivated);
insertStatement.setDate(15, discontinuedOrder.dateActivated);
insertStatement.addBatch();
if (index % batchSize == 0) {
insertStatement.executeBatch();
}
index++;
}
insertStatement.executeBatch();
connection.commit();
}
catch (DatabaseException e) {
handleError(connection, e);
}
catch (SQLException e) {
handleError(connection, e);
}
finally {
if (autoCommit != null) {
connection.setAutoCommit(autoCommit);
}
if (insertStatement != null) {
insertStatement.close();
}
}
}
private void setIntOrNull(PreparedStatement statement, int index, Integer value) throws SQLException {
if (value == null || value == 0) {
statement.setNull(index, Types.INTEGER);
} else {
statement.setInt(index, value);
}
}
private void handleError(JdbcConnection connection, Exception e) throws DatabaseException, CustomChangeException {
connection.rollback();
throw new CustomChangeException(e);
}
private List<DiscontinuedOrder> getDiscontinuedOrders(JdbcConnection connection) throws CustomChangeException,
SQLException {
List<DiscontinuedOrder> dcOrders = new ArrayList<DiscontinuedOrder>();
PreparedStatement statement = null;
try {
statement = connection.prepareStatement("select order_id, concept_id, patient_id, encounter_id, date_stopped, "
+ "discontinued_by, discontinued_reason, discontinued_reason_non_coded, order_type_id "
+ "from orders where discontinued = ?");
statement.setBoolean(1, true);
ResultSet rs = statement.executeQuery();
while (rs.next()) {
dcOrders.add(new DiscontinuedOrder(rs.getInt("order_id"), rs.getInt("concept_id"), rs.getInt("patient_id"),
rs.getInt("encounter_id"), rs.getInt("discontinued_by"), rs.getInt("discontinued_reason"), rs
.getString("discontinued_reason_non_coded"), rs.getDate("date_stopped"), rs
.getInt("order_type_id")));
}
}
catch (SQLException e) {
throw new CustomChangeException(e);
}
catch (DatabaseException e) {
throw new CustomChangeException(e);
}
finally {
if (statement != null) {
statement.close();
}
}
return dcOrders;
}
@Override
public String getConfirmationMessage() {
return "Finished creating discontinue orders for discontinued orders";
}
@Override
public void setUp() throws SetupException {
}
@Override
public void setFileOpener(ResourceAccessor resourceAccessor) {
}
@Override
public ValidationErrors validate(Database database) {
return null;
}
private static class DiscontinuedOrder {
public int orderId;
public int conceptId;
public int patientId;
public int encounterId;
public int discontinuedReasonId;
public String discontinuedReasonNonCoded;
public Date dateActivated;
public int discontinuedById;
public Date dateCreated;
public int previousOrderId;
public String orderNumber;
public int orderTypeId;
public Date date;
private DiscontinuedOrder(int orderId, int conceptId, int patientId, int encounterId, int discontinuedById,
int discontinuedReasonId, String discontinuedReasonNonCoded, Date dateStopped, int orderTypeId) {
this.orderId = orderId;
this.previousOrderId = orderId;
this.conceptId = conceptId;
this.patientId = patientId;
this.encounterId = encounterId;
this.discontinuedReasonId = discontinuedReasonId;
this.discontinuedReasonNonCoded = discontinuedReasonNonCoded;
this.dateActivated = dateStopped;
this.discontinuedById = discontinuedById;
this.dateCreated = dateStopped;
this.orderNumber = String.valueOf(orderId).concat("-DC");
this.orderTypeId = orderTypeId;
}
}
}