Files
Java_Examples/pickMaint/AS400Interface.java
T

1062 lines
44 KiB
Java

package pickMaint;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
/**
* AS400Interface
*
* @TODO Implement production/test data selection from log-in prompt
*
* This class is designed to abstract the database transactions required by the GUI components in Editor.java.
*
* A connection is established with the AS400 upon instantiating this class.
* There is only one constructor which takes two strings (User and Password).
*
* All multiple use SQL statements are pre-compiled into java.sql.PreparedStatement objects during initialization.
*
* The following are cached locally (into HashMaps) from the server during init:
* Down time reason codes/descriptions
* Weaver numbers/names
* Loom speeds (in 1000s of picks/hour)
* These items are used frequently for calculation/display purposes and don't often change so it is more than enough to
* cache them temporarily during application startup.
*
* @author Wesley Ray
*/
public class AS400Interface {
private String LIB = "STMDATA";
private static final Logger LOGGER = Logger.getLogger(AS400Interface.class.getName());
private static final HashMap<String, String> downTimeCodeLookup = new HashMap<String, String>();
private static final HashMap<Integer, String> weaverNameLookup = new HashMap<Integer, String>();
private static final HashMap<Integer, Float> loomPPHLookup = new HashMap<Integer, Float>();
private Connection conn; //java.sql.Connection object
private PreparedStatement queryLoomds;
private PreparedStatement queryLoomds2;
private PreparedStatement adjPicksLoomds;
private PreparedStatement adjPicksLoomds2;
private PreparedStatement chgWeaverLoomds;
private PreparedStatement chgWeaverLoomds2;
private PreparedStatement chgDtCodeLoomds;
private PreparedStatement chgDtCodeLoomds2;
private PreparedStatement adjHoursLoomds;
private PreparedStatement adjHoursLoomds2;
private PreparedStatement adjHrsPksLoomds;
private PreparedStatement adjHrsPksLoomds2;
private PreparedStatement newLoomDSRecord;
private PreparedStatement newLoomDS2Record;
private PreparedStatement delLoomDSRecord;
private PreparedStatement delLoomDS2Record;
private PreparedStatement getProdLoomHours;
private PreparedStatement getProdPicks;
private PreparedStatement getNobLoomHours;
private PreparedStatement getNobPicks;
private PreparedStatement getSampLoomHours;
private PreparedStatement getSampPicks;
private PreparedStatement getShiftLength;
private PreparedStatement getEfficiencies;
public AS400Interface(String usr, String psw, boolean production) throws SQLException{
this.LIB = production ? "STMDATA" : "WES"; //Sets name of library to be compiled into SQL statements
//Register AS400 DB2 driver and open a connection with the AS400
LOGGER.info("Connecting to AS400 as user: " + usr);
DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());
this.conn = DriverManager.getConnection("jdbc:as400://0.0.0.0", usr, psw);
setUpDTcodeHashMap(); //Grabs down time codes from server
setUpWeaverHashMap(); //Grabs weaver names from server
setUpLoomPPHHashMap(); //Grabs loom speeds from server
preCompileStatements(); //Pre-compile SQL statements
}
/**
* Called by the constructor to pre-compile all of the SQl statements used by the program.
* @throws SQLException - Shouldn't happen, usually only thrown when there are syntax errors in the queries.
*/
private final void preCompileStatements() throws SQLException{
LOGGER.info("Pre-compiling multiple use SQL statements.");
queryLoomds = this.conn.prepareStatement("SELECT lddate, "
+ " ldloom, "
+ " ldshif, "
+ " ldweav, "
+ " wvrnam, "
+ " ldsty1, "
+ " ldhrs, "
+ " ldpick, "
+ " lmppm, "
+ " lmppms, "
+ " ( ( 100.0 * lmppm ) / 82.0 ) AS picksHR, "
+ " ( ( 100.0 * lmppms ) / 82.0 ) AS picksHRsam, "
+ " ldreas, "
+ " ldcut1, "
+ " ldcut2, "
+ " bmtycd, "
+ " lddlcd "
+ "FROM " + LIB + ".loomds, "
+ " stmdata.iewvms, "
+ " stmdata.loomms "
+ "WHERE ldweav = wvr# "
+ " AND ldloom = lmlomn "
+ " AND LDDATE = ? "
+ " AND LDSHIF = ? "
+ "ORDER BY ldloom");
queryLoomds2 = this.conn.prepareStatement("SELECT ldpick, "
+ " ldhrs "
+ "FROM " + LIB + ".loomds2 "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ "ORDER BY ldloom");
adjPicksLoomds = this.conn.prepareStatement("UPDATE " + LIB + ".loomds "
+ "SET ldpick = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
adjPicksLoomds2 = this.conn.prepareStatement("UPDATE " + LIB + ".loomds2 "
+ "SET ldpick = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
chgWeaverLoomds = this.conn.prepareStatement("UPDATE " + LIB + ".loomds "
+ "SET ldweav = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
chgWeaverLoomds2 = this.conn.prepareStatement("UPDATE " + LIB + ".loomds2 "
+ "SET ldweav = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
chgDtCodeLoomds = this.conn.prepareStatement("UPDATE " + LIB + ".loomds "
+ "SET ldreas = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
chgDtCodeLoomds2 = this.conn.prepareStatement("UPDATE " + LIB + ".loomds2 "
+ "SET ldreas = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
adjHoursLoomds = this.conn.prepareStatement("UPDATE " + LIB + ".loomds "
+ "SET ldhrs = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
adjHoursLoomds2 = this.conn.prepareStatement("UPDATE " + LIB + ".loomds2 "
+ "SET ldhrs = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
adjHrsPksLoomds = this.conn.prepareStatement("UPDATE " + LIB + ".loomds "
+ "SET ldhrs = ?, "
+ " ldpick = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
adjHrsPksLoomds2 = this.conn.prepareStatement("UPDATE " + LIB + ".loomds2 "
+ "SET ldhrs = ?, "
+ " ldpick = ? "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = ? ");
newLoomDSRecord = this.conn.prepareStatement("insert into " + LIB + ".LOOMDS values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
newLoomDS2Record = this.conn.prepareStatement("insert into " + LIB + ".LOOMDS2 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
delLoomDSRecord = this.conn.prepareStatement("DELETE FROM " + LIB + ".loomds "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = 0 ");
delLoomDS2Record = this.conn.prepareStatement("DELETE FROM " + LIB + ".loomds2 "
+ "WHERE lddate = ? "
+ " AND ldloom = ? "
+ " AND ldshif = ? "
+ " AND ldweav = ? "
+ " AND ldsty1 = ? "
+ " AND ldsty2 = 0 ");
getProdLoomHours = this.conn.prepareStatement("SELECT Sum(ldhrs) AS loom_hours "
+ "FROM " + LIB + ".loomds "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ "GROUP BY lddate, "
+ " ldshif "
+ "ORDER BY lddate ");
getProdPicks = this.conn.prepareStatement("SELECT Sum(ldpick) AS total_picks "
+ "FROM " + LIB + ".loomds "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ "GROUP BY lddate, "
+ " ldshif "
+ "ORDER BY lddate ");
getNobLoomHours = this.conn.prepareStatement("SELECT Sum(ldhrs) AS loom_hours "
+ "FROM " + LIB + ".loomds2 "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ "GROUP BY lddate, "
+ " ldshif "
+ "ORDER BY lddate ");
getNobPicks = this.conn.prepareStatement("SELECT Sum(ldpick) AS total_picks "
+ "FROM " + LIB + ".loomds2 "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ "GROUP BY lddate, "
+ " ldshif "
+ "ORDER BY lddate ");
getSampLoomHours = this.conn.prepareStatement("SELECT Sum(ldhrs) AS total_hours "
+ "FROM " + LIB + ".loomds "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ " AND ldsty1 = ' SAM' "
+ "GROUP BY lddate, "
+ " ldshif "
+ "ORDER BY lddate ");
getSampPicks = this.conn.prepareStatement("SELECT Sum(ldpick) AS total_picks "
+ "FROM " + LIB + ".loomds "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ " AND ldsty1 = ' SAM' "
+ "GROUP BY lddate, "
+ " ldshif "
+ "ORDER BY lddate ");
getShiftLength = this.conn.prepareStatement("SELECT Max(ldhrs) AS shift_length "
+ "FROM " + LIB + ".loomds "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ "GROUP BY lddate, "
+ " ldshif "
+ "ORDER BY lddate ");
getEfficiencies = this.conn.prepareStatement("SELECT ( ( 100.0 / 82.0 ) * lmppm ) AS target_pph, "
+ " ( ldpick / ldhrs ) AS acutal_pph "
+ "FROM " + LIB + ".loomds "
+ " INNER JOIN stmdata.loomms "
+ " ON ldloom = lmlomn "
+ "WHERE lddate = ? "
+ " AND ldshif = ? "
+ " AND ldhrs > 0 ");
}
/**
* Quietly close and null ALL PreparedStatement objects and the java.sql.Connection object.
*
* If an exception is raised while closing one of the PreparedStatement objects the Connection object
* will be closed in the finally block.
*/
public void close(){
try {
queryLoomds.close();
queryLoomds2.close();
adjPicksLoomds.close();
adjPicksLoomds2.close();
chgWeaverLoomds.close();
chgWeaverLoomds2.close();
chgDtCodeLoomds.close();
chgDtCodeLoomds2.close();
adjHoursLoomds.close();
adjHoursLoomds2.close();
adjHrsPksLoomds.close();
adjHrsPksLoomds2.close();
newLoomDSRecord.close();
newLoomDS2Record.close();
delLoomDSRecord.close();
delLoomDS2Record.close();
getProdLoomHours.close();
getProdPicks.close();
getNobLoomHours.close();
getNobPicks.close();
getSampLoomHours.close();
getSampPicks.close();
getShiftLength.close();
getEfficiencies.close();
conn.close();
queryLoomds = null;
queryLoomds2 = null;
adjPicksLoomds = null;
adjPicksLoomds2 = null;
chgWeaverLoomds = null;
chgWeaverLoomds2 = null;
chgDtCodeLoomds = null;
chgDtCodeLoomds2 = null;
adjHoursLoomds = null;
adjHoursLoomds2 = null;
adjHrsPksLoomds = null;
adjHrsPksLoomds2 = null;
newLoomDSRecord = null;
newLoomDS2Record = null;
delLoomDSRecord = null;
delLoomDS2Record = null;
getProdLoomHours = null;
getProdPicks = null;
getNobLoomHours = null;
getNobPicks = null;
getSampLoomHours = null;
getSampPicks = null;
getShiftLength = null;
getEfficiencies = null;
conn = null;
LOGGER.info("Open connection resources closed successfully!");
} catch(SQLException e){
} finally {
if(conn != null)
try {
conn.close();
conn = null;
} catch (SQLException e) {
}
}
}
/**
* Queries the AS400 for picks records for the given date/shift combination. Returns results as a LoomDSRecord[]
* @param date - Date to use in query
* @param shift - Shift to use in query
* @return Pick records for date/shift as LoomDSRecord[]
* @throws SQLException
*/
public LoomDSRecord[] getShiftDetail(int date, int shift) throws SQLException{
LOGGER.info("Fetching picks for " + ((shift == 1) ? "1st" : (shift == 2) ? "2nd" : (shift == 3) ? "3rd" : "") + " shift on " + new SimpleDateFormat("MM/dd/yyyy").format(intToDate(date)) + " from server.");
ArrayList<LoomDSRecord> list = new ArrayList<LoomDSRecord>();
queryLoomds.setInt(1, date);
queryLoomds.setInt(2, shift);
ResultSet rs = queryLoomds.executeQuery();
while(rs.next()){
list.add(new LoomDSRecord(this, rs));
}
rs.close();
if(list.size() < 1)
throw new SQLException("Empty result set for " + ((shift == 1) ? "1st" : (shift == 2) ? "2nd" : (shift == 3) ? "3rd" : "" + shift) + " Shift on " + intToDate(date));
return list.toArray(new LoomDSRecord[list.size()]); //Return a fixed length array rather than an ArrayList, we are done adding elements
}
/**
* The actual hours and picks for no bonus looms reside in LOOMDS2. If the LoomDSRecord constructor detects that a record is no bonus
* it will call this method to query LOOMDS2 for the hours and picks for that record.
* @param date - date to use in query
* @param loom - loom # to use in query
* @param shift - Shift to use in query
* @param weaver - weaver # to use in query
* @return - float[] return[0] contains the hours, float[1] contains the picks
* @throws SQLException
*/
public float[] getLoomDS2HoursPicks(int date, int loom, int shift, int weaver) throws SQLException{
queryLoomds2.setInt(1, date);
queryLoomds2.setInt(2, loom);
queryLoomds2.setInt(3, shift);
queryLoomds2.setInt(4, weaver);
ResultSet rs = queryLoomds2.executeQuery();
if(rs.next()) {
return new float[]{rs.getFloat(2) , (float) rs.getInt(1)};
} else {
LOGGER.severe("No record found in LOOMDS2 for " + weaverLookup(weaver) + " (" + weaver + ") on loom " + loom + " for " + ((shift == 1) ? "1st" : (shift == 2) ? "2nd" : (shift == 3) ? "3rd" : "") + " shift on " + new SimpleDateFormat("MM/dd/yyyy").format(intToDate(date)));
return new float[]{-1, -1};
}
}
/**
* Returns the length of the given shift on the given date.
* This works by returning the largest value found for the HOURS column within the records selected based on the
* date and shift supplied.
*
* SELECT Max(ldhrs) AS shift_length
* FROM stmdata.loomds "
* WHERE lddate = ?
* AND ldshif = ?
* GROUP BY lddate,
* ldshif
* ORDER BY lddate
*
* @param date - The date of the shift you want the length of
* @param shift - The shift you want the length of
* @return The length of the shift in hours
* @throws SQLException
*/
public float getShiftLength(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getShiftLength.setInt(1, d);
getShiftLength.setInt(2, shift);
ResultSet rs = getShiftLength.executeQuery();
if(rs.next())
return rs.getFloat(1);
else
throw new SQLException("Got an empty result set for shift length query. Your guess is as good as mine...");
}
/**
* Returns the shift's efficiency as a function of (TOTAL_PICKS / PICKS_POSSIBLE)
*
* This query is run:
*
* SELECT ( ( 100.0 / 82.0 ) * lmppm ) AS target_pph,
* ( ldpick / ldhrs ) AS acutal_pph
* FROM stmdata.loomds
* INNER JOIN stmdata.loomms
* ON ldloom = lmlomn
* WHERE lddate = ?
* AND ldshif = ?
* AND ldhrs > 0
*
* The result set is looped over; summing up target and actual picks per hour for the entire shift.
*
* @param date - The date of the shift you want
* @param shift - The shift you want
* @return (TOTAL_PICKS / PICKS_POSSIBLE) for the entire shift.
* @throws SQLException
*/
public float getShiftEfficiency(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getEfficiencies.setInt(1, d);
getEfficiencies.setInt(2, shift);
ResultSet rs = getEfficiencies.executeQuery();
double target = 0;
double actual = 0;
while(rs.next()){
target += rs.getDouble(1);
actual += rs.getDouble(2);
}
return (float) (actual / target);
}
/**
* Totals and returns loom-hours for bonus looms only. For the given date and shift.
*
* SELECT Sum(ldhrs) AS loom_hours
* FROM stmdata.loomds
* WHERE lddate = ?
* AND ldshif = ?
* GROUP BY lddate,
* ldshif
* ORDER BY lddate
*
* @param date - The date of the shift you want
* @param shift - The shift you want
* @return Total production loom hours for the supplied shift
* @throws SQLException
*/
public float getProductionLoomHours(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getProdLoomHours.setInt(1, d);
getProdLoomHours.setInt(2, shift);
ResultSet rs = getProdLoomHours.executeQuery();
if(rs.next())
return rs.getFloat(1);
else
throw new SQLException("Got an empty result set for aggregate production hours query. Your guess is as good as mine...");
}
/**
* Totals and returns all bonus picks for the given shift.
*
* SELECT Sum(ldpick) AS total_picks
* FROM stmdata.loomds
* WHERE lddate = ?
* AND ldshif = ?
* GROUP BY lddate,
* ldshif
* ORDER BY lddate
*
* @param date - The date of the shift you want
* @param shift - The shift you want
* @return Total production picks for the supplied shift
* @throws SQLException
*/
public int getProductionPicks(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getProdPicks.setInt(1, d);
getProdPicks.setInt(2, shift);
ResultSet rs = getProdPicks.executeQuery();
if(rs.next())
return rs.getInt(1);
else
throw new SQLException("Got an empty result set for aggregate production picks query. Your guess is as good as mine...");
}
/**
* Totals and returns no-bonus loom-hours for the supplied shift.
*
* SELECT Sum(ldhrs) AS loom_hours
* FROM stmdata.loomds2
* WHERE lddate = ?
* AND ldshif = ?
* GROUP BY lddate,
* ldshif
* ORDER BY lddate
*
* @param date - The date of the shift you want
* @param shift - The shift you want
* @return Total no-bonus loom-hours for the supplied shift
* @throws SQLException
*/
public float getNoBonusLoomHours(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getNobLoomHours.setInt(1, d);
getNobLoomHours.setInt(2, shift);
ResultSet rs = getNobLoomHours.executeQuery();
if(rs.next())
return rs.getFloat(1);
else
throw new SQLException("Got an empty result set for aggregate no bonus hours query. Your guess is as good as mine...");
}
/**
* Totals and returns all no-bonus picks for the supplied shift.
*
* SELECT Sum(ldpick) AS total_picks
* FROM stmdata.loomds2
* WHERE lddate = ?
* AND ldshif = ?
* GROUP BY lddate,
* ldshif
* ORDER BY lddate
*
* @param date - The date of the shift you want
* @param shift - The shift you want
* @return Total no-bonus picks for the supplied shift
* @throws SQLException
*/
public int getNoBonusPicks(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getNobPicks.setInt(1, d);
getNobPicks.setInt(2, shift);
ResultSet rs = getNobPicks.executeQuery();
if(rs.next())
return rs.getInt(1);
else
throw new SQLException("Got an empty result set for aggregate no bonus picks query. Your guess is as good as mine...");
}
/**
* Totals and returns all loom-hours that can be attributed to sample cuts for the supplied shift.
*
* SELECT Sum(ldhrs) AS total_hours
* FROM stmdata.loomds
* WHERE lddate = ?
* AND ldshif = ?
* AND ldsty1 = ' SAM'
* GROUP BY lddate,
* ldshif
* ORDER BY lddate
*
*
* @param date - The date of the shift you want
* @param shift - The shift you want
* @return total loom-hours that ran samples for the shift
* @throws SQLException
*/
public float getSampleLoomHours(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getSampLoomHours.setInt(1, d);
getSampLoomHours.setInt(2, shift);
ResultSet rs = getSampLoomHours.executeQuery();
if(rs.next())
return rs.getFloat(1);
else
throw new SQLException("Got an empty result set for aggregate no bonus hours query. Your guess is as good as mine...");
}
/**
* Totals and returns the amount of sample picks woven for the supplied shift
*
* SELECT Sum(ldpick) AS total_picks
* FROM stmdata.loomds
* WHERE lddate = ?
* AND ldshif = ?
* AND ldsty1 = ' SAM'
* GROUP BY lddate,
* ldshif
* ORDER BY lddate
*
* @param date - The date of the shift you want
* @param shift - The shift you want
* @return total sample picks woven during the supplied shift
* @throws SQLException
*/
public int getSamplePicks(Date date, int shift) throws SQLException{
int d = AS400Interface.dateToInt(date);
getSampPicks.setInt(1, d);
getSampPicks.setInt(2, shift);
ResultSet rs = getSampPicks.executeQuery();
if(rs.next())
return rs.getInt(1);
else
throw new SQLException("Got an empty result set for aggregate no bonus picks query. Your guess is as good as mine...");
}
/**
* Deletes the record from the database represented by the information contained in the supplied LoomDSRecord object.
* Specifically, it uses the date, loom #, shift, weaver #, and style from the LoomDSRecord object for the where criteria
* in the delete statement.
* @param record - The record to be removed from the database
* @throws SQLException
*/
public void delRecord(LoomDSRecord record) throws SQLException{
delLoomDSRecord.setInt(1, dateToInt(record.getDate()));
delLoomDSRecord.setInt(2, record.getLoomNumber());
delLoomDSRecord.setInt(3, record.getShift());
delLoomDSRecord.setInt(4, record.getWeaverNumber());
delLoomDSRecord.setString(5, " " + record.getLdStyle().trim());
LOGGER.info(delLoomDSRecord.executeUpdate() + " row deleted in LOOMDS");
if(!record.isBonus()){
delLoomDS2Record.setInt(1, dateToInt(record.getDate()));
delLoomDS2Record.setInt(2, record.getLoomNumber());
delLoomDS2Record.setInt(3, record.getShift());
delLoomDS2Record.setInt(4, record.getWeaverNumber());
delLoomDS2Record.setString(5, " " + record.getLdStyle().trim());
LOGGER.info(delLoomDS2Record.executeUpdate() + " row deleted in LOOMDS2");
}
}
/**
* Creates a new entry in the database. If the entry is to be "no bonus" a record must also be written into LOOMDS2.
* The actual hours and picks for no bonus entries are stored in LOOMDS2 and LOOMDS gets zeros instead. For normal entries
* a single record is written into LOOMDS.
*
* @param date - Date. <Required>
* @param loom - Loom Number. <Required>
* @param shift - Shift. <Required>
* @param weaver - Weaver # that worked. <Required>
* @param style1 - BLN, TRL, or SAM. Only required if noBonus.
* @param hours - How many hours worked. <Required>
* @param picks - How many picks woven. <Required>
* @param dtCode - Down time reason code, if there is one.
* @param cut - The cut number. For sample cuts only.
* @param cutSuffix - The character portion of the cut number, if there is one. For sample cuts only.
* @param typeCode - [B]lanket, [I]nitial, or [T]rial. Only required if noBonus. I is never used.
* @param noBonus - Did this loom run production for bonus or not? <Required>
* @throws SQLException
*/
public void addRecord(Date date, int loom, int shift, int weaver, String style1, Double hours,
int picks, String dtCode, int cut, String cutSuffix, String typeCode,
boolean noBonus) throws SQLException {
newLoomDSRecord.setObject(1, dateToInt(date)); //Date YYMMDD
newLoomDSRecord.setObject(2, loom); //Loom #
newLoomDSRecord.setObject(3, shift); //Shift
newLoomDSRecord.setObject(4, weaver); //Weaver #
newLoomDSRecord.setObject(5, style1); //Style 1 ϵ [BLN, TRL, SAM]
newLoomDSRecord.setObject(6, 0); //Style 2 - I've never seen this anything other than zero
newLoomDSRecord.setObject(7, (noBonus ? 0 : hours)); //Hours
newLoomDSRecord.setObject(8, (noBonus ? 0 : picks)); //Picks
newLoomDSRecord.setObject(9, dtCode); //Down time Reason Code
newLoomDSRecord.setObject(10, "D"); //Loom Type - Always "D" for Dornier
newLoomDSRecord.setObject(11, 0); //Loom Fixer - Never seems to be filled in
newLoomDSRecord.setInt(12, cut); //Cut 1 - For when samples are cut in on production looms
newLoomDSRecord.setObject(13, cutSuffix); //Cut 2 - For when samples are cut in on production looms
newLoomDSRecord.setObject(14, typeCode); //Type code ϵ [B, I, T]
newLoomDSRecord.setObject(15, " "); //Filler
newLoomDSRecord.setObject(16, (noBonus ? "N" : " ")); //Delete Code - In LOOMDS if it is no bonus picks write an "N"
LOGGER.info(newLoomDSRecord.executeUpdate() + " row added to LOOMDS");
if(noBonus){
newLoomDS2Record.setObject(1, dateToInt(date)); //Date YYMMDD
newLoomDS2Record.setObject(2, loom); //Loom #
newLoomDS2Record.setObject(3, shift); //Shift
newLoomDS2Record.setObject(4, weaver); //Weaver #
newLoomDS2Record.setObject(5, style1); //Style 1 ϵ [BLN, TRL, SAM]
newLoomDS2Record.setObject(6, 0); //Style 2 - I've never seen this anything other than zero
newLoomDS2Record.setObject(7, hours); //Hours
newLoomDS2Record.setObject(8, picks); //Picks
newLoomDS2Record.setObject(9, dtCode); //Down time Reason Code
newLoomDS2Record.setObject(10, "D"); //Loom Type - Always "D" for Dornier
newLoomDS2Record.setObject(11, 0); //Loom Fixer - Never seems to be filled in
newLoomDS2Record.setInt(12, cut); //Cut 1 - For when samples are cut in on production looms
newLoomDS2Record.setObject(13, cutSuffix); //Cut 2 - For when samples are cut in on production looms
newLoomDS2Record.setObject(14, typeCode); //Type code ϵ [B, I, T]
newLoomDS2Record.setObject(15, " "); //Filler
newLoomDS2Record.setObject(16, " "); //Delete Code
LOGGER.info(newLoomDS2Record.executeUpdate() + " row added to LOOMDS2");
}
}
/**
* "Sample Cuts" are records with particular values for a few of the fields to indicate that they
* are indeed samples that were cut into the production schedule for that loom.
*
* Parameter 5 will always be: " SAM"
* Parameter 9 will always be: " "
* Parameter 14 will always be: "T"
*
* Additionally a cut number is required for sample cuts
*
* @param source
* @param cut
* @param cutSuffix
* @param hours
* @param picks
* @throws SQLException
*/
public void addSampleCut(LoomDSRecord source, int cut, String cutSuffix, Double hours, int picks) throws SQLException{
newLoomDSRecord.setObject(1, dateToInt(source.getDate())); //Date YYMMDD
newLoomDSRecord.setObject(2, source.getLoomNumber()); //Loom #
newLoomDSRecord.setObject(3, source.getShift()); //Shift
newLoomDSRecord.setObject(4, source.getWeaverNumber()); //Weaver #
newLoomDSRecord.setObject(5, " SAM"); //Style 1 ϵ [BLN, TRL, SAM]
newLoomDSRecord.setObject(6, 0); //Style 2 - I've never seen this anything other than zero
newLoomDSRecord.setObject(7, hours); //Hours
newLoomDSRecord.setObject(8, picks); //Picks
newLoomDSRecord.setObject(9, " "); //Down time Reason Code
newLoomDSRecord.setObject(10, "D"); //Loom Type - Always "D" for Dornier
newLoomDSRecord.setObject(11, 0); //Loom Fixer - Never seems to be filled in
newLoomDSRecord.setInt(12, cut); //Cut 1 - For when samples are cut in on production looms
newLoomDSRecord.setObject(13, cutSuffix); //Cut 2 - For when samples are cut in on production looms
newLoomDSRecord.setObject(14, "T"); //Type code ϵ [B, I, T]
newLoomDSRecord.setObject(15, " "); //Filler
newLoomDSRecord.setObject(16, " "); //Delete Code - In LOOMDS if it is no bonus picks write an "N"
LOGGER.info(newLoomDSRecord.executeUpdate() + " row added to LOOMDS");
}
/**
* Adjusts hours and picks in a single transaction.
* See adjustHours() and adjustPicks() for detailed information.
*
* @param record - A LoomDSRecord representative of the record you wish to change on the server
* @throws SQLException
*/
public void adjustHoursPicks(LoomDSRecord record) throws SQLException{
if(record.isBonus()){
adjHrsPksLoomds.setObject(1, record.getHours());
adjHrsPksLoomds.setObject(2, record.getPicks());
adjHrsPksLoomds.setInt(3, dateToInt(record.getDate()));
adjHrsPksLoomds.setInt(4, record.getLoomNumber());
adjHrsPksLoomds.setInt(5, record.getShift());
adjHrsPksLoomds.setInt(6, record.getWeaverNumber());
adjHrsPksLoomds.setObject(7, " " + record.getLdStyle());
adjHrsPksLoomds.setInt(8, 0);
LOGGER.info(adjHrsPksLoomds.executeUpdate() + " row updated in LOOMDS");
} else {
adjHrsPksLoomds2.setObject(1, record.getHours());
adjHrsPksLoomds2.setObject(2, record.getPicks());
adjHrsPksLoomds2.setInt(3, dateToInt(record.getDate()));
adjHrsPksLoomds2.setInt(4, record.getLoomNumber());
adjHrsPksLoomds2.setInt(5, record.getShift());
adjHrsPksLoomds2.setInt(6, record.getWeaverNumber());
adjHrsPksLoomds2.setObject(7, " " + record.getLdStyle());
adjHrsPksLoomds2.setInt(8, 0);
LOGGER.info(adjHrsPksLoomds2.executeUpdate() + " row updated in LOOMDS2");
}
}
/**
* Change the hours (on the AS400) for the supplied record object.
* The SQL statement needs a date, loom #, shift, weaver #, and style for the key to
* lookup the record to be changed; these are obtained from the LoomDSRecord parameter.
*
* The hours will be changed to whatever record.getHours() returns.
*
* So basically, change the object and then call this method to save those changes to the server: *
* LoomDSRecord derp;
* derp.setHours(4.5);
* as400.adjustHours(derp);
*
* @param record - A LoomDSRecord representative of the record you wish to change on the server
* @throws SQLException
*/
public void adjustHours(LoomDSRecord record) throws SQLException{
if(record.isBonus()){
adjHoursLoomds.setObject(1, record.getHours());
adjHoursLoomds.setInt(2, dateToInt(record.getDate()));
adjHoursLoomds.setInt(3, record.getLoomNumber());
adjHoursLoomds.setInt(4, record.getShift());
adjHoursLoomds.setInt(5, record.getWeaverNumber());
adjHoursLoomds.setObject(6, " " + record.getLdStyle());
adjHoursLoomds.setInt(7, 0);
LOGGER.info(adjHoursLoomds.executeUpdate() + " row updated in LOOMDS");
} else {
adjHoursLoomds2.setObject(1, record.getHours());
adjHoursLoomds2.setInt(2, dateToInt(record.getDate()));
adjHoursLoomds2.setInt(3, record.getLoomNumber());
adjHoursLoomds2.setInt(4, record.getShift());
adjHoursLoomds2.setInt(5, record.getWeaverNumber());
adjHoursLoomds2.setObject(6, " " + record.getLdStyle());
adjHoursLoomds2.setInt(7, 0);
LOGGER.info(adjHoursLoomds2.executeUpdate() + " row updated in LOOMDS2");
}
}
/**
* Change the picks (on the AS400) for the supplied record object.
* The SQL statement needs a date, loom #, shift, weaver #, and style for the key to
* lookup the record to be changed; these are obtained from the LoomDSRecord parameter.
*
* The picks will be changed to whatever record.getPicks() returns.
*
* So basically, change the object and then call this method to save those changes to the server: *
* LoomDSRecord derp;
* derp.setPicks(154);
* as400.adjustPicks(derp);
*
* @param record - A LoomDSRecord representative of the record you wish to change on the server
* @throws SQLException
*/
public void adjustPicks(LoomDSRecord record) throws SQLException{
if(record.isBonus()){
adjPicksLoomds.setInt(1, record.getPicks());
adjPicksLoomds.setInt(2, dateToInt(record.getDate()));
adjPicksLoomds.setInt(3, record.getLoomNumber());
adjPicksLoomds.setInt(4, record.getShift());
adjPicksLoomds.setInt(5, record.getWeaverNumber());
adjPicksLoomds.setObject(6, " " + record.getLdStyle());
adjPicksLoomds.setInt(7, 0);
LOGGER.info(adjPicksLoomds.executeUpdate() + " row updated in LOOMDS");
} else {
adjPicksLoomds2.setInt(1, record.getPicks());
adjPicksLoomds2.setInt(2, dateToInt(record.getDate()));
adjPicksLoomds2.setInt(3, record.getLoomNumber());
adjPicksLoomds2.setInt(4, record.getShift());
adjPicksLoomds2.setInt(5, record.getWeaverNumber());
adjPicksLoomds2.setObject(6, " " + record.getLdStyle());
adjPicksLoomds2.setInt(7, 0);
LOGGER.info(adjPicksLoomds2.executeUpdate() + " row updated in LOOMDS2");
}
}
/**
* Changes the weaver number (on the AS400) for the supplied record object.
* The SQL statement needs a date, loom #, shift, weaver #, and style for the key to
* lookup the record to be changed; these are obtained from the LoomDSRecord parameter.
*
* Since the weaver number is part of the key we need to lookup the appropriate record on
* the server we need an extra parameter (currentWeaver) to supply the currentWeaver number
* for building the record key.
*
* The new weaver number is obtained from the LoomDsRecord object.
*
* Example:
* LoomDsRecord derp;
* int oldWeaver = derp.getWeaver();
* derp.setWeaver(888);
* as400.changeWeaver(derp, oldWeaver);
*
* @param record - A LoomDSRecord representative of the record you wish to change on the server
* @param currentWeaver - The weaver number currently on the server for the record you wish to change
* @throws SQLException
*/
public void changeWeaver(LoomDSRecord record, int currentWeaver) throws SQLException{
chgWeaverLoomds.setInt(1, record.getWeaverNumber());
chgWeaverLoomds.setInt(2, dateToInt(record.getDate()));
chgWeaverLoomds.setInt(3, record.getLoomNumber());
chgWeaverLoomds.setInt(4, record.getShift());
chgWeaverLoomds.setInt(5, currentWeaver);
chgWeaverLoomds.setObject(6, " " + record.getLdStyle());
chgWeaverLoomds.setInt(7, 0);
LOGGER.info(chgWeaverLoomds.executeUpdate() + " row updated in LOOMDS");
chgWeaverLoomds2.setInt(1, record.getWeaverNumber());
chgWeaverLoomds2.setInt(2, dateToInt(record.getDate()));
chgWeaverLoomds2.setInt(3, record.getLoomNumber());
chgWeaverLoomds2.setInt(4, record.getShift());
chgWeaverLoomds2.setInt(5, currentWeaver);
chgWeaverLoomds2.setObject(6, " " + record.getLdStyle());
chgWeaverLoomds2.setInt(7, 0);
LOGGER.info(chgWeaverLoomds2.executeUpdate() + " row updated in LOOMDS2");
}
/**
* Change the down time code (on the AS400) for the supplied record object.
* The SQL statement needs a date, loom #, shift, weaver #, and style for the key to
* lookup the record to be changed; these are obtained from the LoomDSRecord parameter.
*
* The down time code will be change to whatever record.getDownTimeCode() returns.
*
* So basically, change the object and then call this method to save those changes to the server: *
* LoomDSRecord derp;
* derp.setDownTimeCode("IC");
* as400.changeDTCode(derp);
*
* @param record - A LoomDSRecord representative of the record you wish to change on the server
* @throws SQLException
*/
public void changeDtCode(LoomDSRecord record) throws SQLException{
chgDtCodeLoomds.setObject(1, record.getDownTimeCode());
chgDtCodeLoomds.setInt(2, dateToInt(record.getDate()));
chgDtCodeLoomds.setInt(3, record.getLoomNumber());
chgDtCodeLoomds.setInt(4, record.getShift());
chgDtCodeLoomds.setInt(5, record.getWeaverNumber());
chgDtCodeLoomds.setObject(6, " " + record.getLdStyle());
chgDtCodeLoomds.setInt(7, 0); //This field is never used on the AS400; always zero
LOGGER.info(chgDtCodeLoomds.executeUpdate() + " row updated in LOOMDS");
chgDtCodeLoomds2.setObject(1, record.getDownTimeCode());
chgDtCodeLoomds2.setInt(2, dateToInt(record.getDate()));
chgDtCodeLoomds2.setInt(3, record.getLoomNumber());
chgDtCodeLoomds2.setInt(4, record.getShift());
chgDtCodeLoomds2.setInt(5, record.getWeaverNumber());
chgDtCodeLoomds2.setObject(6, " " + record.getLdStyle());
chgDtCodeLoomds2.setInt(7, 0); //This field is never used on the AS400; always zero
LOGGER.info(chgDtCodeLoomds2.executeUpdate() + " row updated in LOOMDS2");
}
/**
* Down time codes will probably never change; despite that I decided against hard-coding them in and went with this approach instead.
* We are opening a connection with the database anyway so we might as well grab the DT codes quick on application start up.
*
* Grabs down time codes and their descriptions from the server and stores them in the downTimeCodeLookup class var for speedy lookups later.
* Since downTimeCodeLookup is a static class variable, after this class is instantiated at least once you will be able to get the description
* for any DT code by calling:
*
* String description = AS400Interface.downTimeCodeLookup.get("EW"); //Don't do this
* String description = AS400Interface.dtCodeLookup("EW"); //Same result; Encapsulation FTW
*
* This will work from any context since it's a class variable/method.
* @throws SQLException
*/
private final void setUpDTcodeHashMap() throws SQLException{
LOGGER.info("Caching down time codes/decriptions locally from server.");
ResultSet rs = this.conn.createStatement().executeQuery("select IEDTCD, IEDTDS from stmdata.iedtfl order by IEDTCD");
while(rs.next()) {
AS400Interface.downTimeCodeLookup.put(rs.getString(1).trim(), rs.getString(2).trim());
}
rs.close();
}
/**
* Lookup a down time code description from the hash table created during init.
* @param code - The code you want the description for (1 or 2 characters only)
* @return A string (30 chars max) containing the description of the supplied down time code
*/
public static final String dtCodeLookup(String code){
return AS400Interface.downTimeCodeLookup.get(code);
}
/**
* Cache weaver names locally for speedy lookups later.
* See documentation for setUpDTcodeHashMap() for a more detailed explanation.
* @throws SQLException
*/
private final void setUpWeaverHashMap() throws SQLException{
LOGGER.info("Caching weaver table locally from server.");
ResultSet rs = this.conn.createStatement().executeQuery("select WVR#, WVRNAM from stmdata.iewvms where shift > 0 order by WVR#");
while(rs.next()) {
AS400Interface.weaverNameLookup.put(rs.getInt(1), rs.getString(2).trim());
}
rs.close();
}
/**
* Lookup a weaver name from the hash table created during init
* @param weaver - The weaver number whos name you want
* @return A string (15 chars max) containing the name associated with the supplied weaver number
*/
public static final String weaverLookup(int weaver){
return AS400Interface.weaverNameLookup.get(weaver);
}
/**
* Cache all loom speeds locally in a hash table for speedy lookups later
* See documentation for setUpDTcodeHashMap() for a more detailed explanation.
* @throws SQLException
*/
private final void setUpLoomPPHHashMap() throws SQLException{
LOGGER.info("Caching loom speeds locally from server.");
ResultSet rs = this.conn.createStatement().executeQuery("select lmlomn, (lmppm * (100.0 / 82.0)) as max_picks_per_hour from stmdata.loomms where lmlomn > 200");
while(rs.next()) {
AS400Interface.loomPPHLookup.put(rs.getInt(1), rs.getFloat(2));
}
rs.close();
}
/**
* Get a loom speed in 1000s Picks/hour from the hash table we created at init.
* @param loom - The loom number whos speed you want
* @return The speed in 1000s of Picks/hour
*/
public static final float loomSpeedLookup(int loom){
return AS400Interface.loomPPHLookup.get(loom);
}
/**
* Returns all down time codes and their descriptions in a string array.
* This is used for creating a JComboBox in the GUI.
* @return
*/
public static final String[] getDtCodeChoices(){
String[] ret = new String[downTimeCodeLookup.size() + 1]; //+1 since we want to include "None" as a choice
ret[0] = "";
int i = 1;
for (Map.Entry<String, String> entry : downTimeCodeLookup.entrySet()) {
ret[i] = entry.getKey() + " - " + entry.getValue();
i++;
}
Arrays.sort(ret); //Sort the array; ret[0] is blank at this point and will be placed at the beginning of the array
ret[0] = "None"; //Now stick "None" into ret[0] so it will be at the top of the JComboBox
return ret;
}
/**
* Converts a java.util.Date into a integer date in yyMMdd format.
*
* Example: June 30th, 2013 --> 130630
*
* In many files on the AS400 dates are stored in this format, so this is desirable when writing information
* back to the database.
*
* @param d a java.util.Date to convert
* @return
*/
public static final int dateToInt(Date d){
return Integer.parseInt(new SimpleDateFormat("yyMMdd").format(d));
}
/**
* Many dates are stored in yyMMdd format as a single integer on the AS400; this method can parse that
* into a java.util.Date object which is handy when working with dates read from the server.
*
* Example: 140120 --> January 20th, 2014
* 990315 --> March 15th, 2099
*
* @param d an integer date (yyMMdd) to convert to a java.util.Date
* @return
*/
public static final Date intToDate(int d){
Calendar ret = Calendar.getInstance();
ret.set(((d / 10000) + 2000), (((d - ((d / 10000) * 10000)) / 100) - 1), (d % 100), 0, 0); //Hows this for a one-liner haha...
return ret.getTime();
}
}