/******************************************************************************* * Copyright (c) 2014 MEDEVIT. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * T. Huster - initial API and implementation ******************************************************************************/ package ch.elexis.labortarif2009.data; import java.io.InputStream; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.elexis.core.constants.Preferences; import ch.elexis.core.data.activator.CoreHub; import ch.elexis.core.data.events.ElexisEventDispatcher; import ch.elexis.core.importer.div.importers.ExcelWrapper; import ch.elexis.core.interfaces.AbstractReferenceDataImporter; import ch.elexis.core.jdt.NonNull; import ch.elexis.core.jdt.Nullable; import ch.elexis.data.Query; import ch.elexis.labortarif2009.data.Importer.Fachspec; import ch.rgw.tools.JdbcLink; import ch.rgw.tools.StringTool; import ch.rgw.tools.TimeTool; public class EALReferenceDataImporter extends AbstractReferenceDataImporter { private static final Logger logger = LoggerFactory.getLogger(EALReferenceDataImporter.class); int langdef = 0; TimeTool validFrom; Fachspec[] specs; int row; // use local HashMap instead of creating new one for every tarif position private HashMap<String, String> importedValues = new HashMap<String, String>(); @Override public @NonNull Class<?> getReferenceDataTypeResponsibleFor(){ return Labor2009Tarif.class; } @Override public IStatus performImport(@Nullable IProgressMonitor monitor, @NonNull InputStream input, @Nullable Integer newVersion){ if (monitor == null) { monitor = new NullProgressMonitor(); } validFrom = getValidFromVersion(newVersion); String lang = JdbcLink.wrap(CoreHub.localCfg.get( // d,f,i Preferences.ABL_LANGUAGE, "d").toUpperCase()); //$NON-NLS-1$ if (lang.startsWith("F")) { //$NON-NLS-1$ langdef = 1; } else if (lang.startsWith("I")) { //$NON-NLS-1$ langdef = 2; } specs = Importer.loadFachspecs(langdef); if (specs != null) { ExcelWrapper exw = new ExcelWrapper(); exw.setFieldTypes(new Class[] { String.class /* chapter */, String.class /* rev */, String.class /* code */, String.class /* tp */, String.class /* name */, String.class /* lim */, String.class /* fach (2011) comment (2012) */, String.class /* fach (2012) */ }); if (exw.load(input, langdef)) { int first = exw.getFirstRow(); int last = exw.getLastRow(); int count = last - first; if (monitor != null) monitor.beginTask(Messages.Importer_importEAL, count); String[] line = exw.getRow(1).toArray(new String[0]); // determine format of file according to year of tarif int formatYear = getFormatYear(line); if (formatYear != 2011 && formatYear != 2012) return new Status(Status.ERROR, "ch.elexis.labotarif.ch2009", //$NON-NLS-1$ "unknown file format"); //$NON-NLS-1$ for (int i = first + 1; i <= last; i++) { row = i; line = exw.getRow(i).toArray(new String[0]); if (formatYear == 2011) fillImportedValues2011(line); else if (formatYear == 2012) fillImportedValues2012(line); if (importedValues.size() > 0) { updateOrCreateFromImportedValues(); } if (monitor != null) { monitor.worked(1); if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } } } closeAllOlder(); if (monitor != null) monitor.done(); ElexisEventDispatcher.reload(Labor2009Tarif.class); if(newVersion != null) { Labor2009Tarif.setCurrentCodeVersion(newVersion); } EALBlocksCodeUpdater blocksUpdater = new EALBlocksCodeUpdater(); String message = blocksUpdater.updateBlockCodes(); logger.info("Updated Blocks: \n" + message); //$NON-NLS-1$ return Status.OK_STATUS; } } return new Status(Status.ERROR, "ch.elexis.labotarif.ch2009", //$NON-NLS-1$ "could not load file"); //$NON-NLS-1$ } /** * Convert version Integer in yymmdd format to date. * * @param newVersion * @return */ private TimeTool getValidFromVersion(Integer newVersion){ String intString = Integer.toString(newVersion); if (intString.length() != 6) { throw new IllegalStateException("Version " + newVersion + " can not be parsed to valid date."); } String year = intString.substring(0, 2); String month = intString.substring(2, 4); String day = intString.substring(4, 6); TimeTool ret = new TimeTool(); ret.set(TimeTool.YEAR, Integer.parseInt(year) + 2000); ret.set(TimeTool.MONTH, Integer.parseInt(month) - 1); ret.set(TimeTool.DAY_OF_MONTH, Integer.parseInt(day)); return ret; } public int getVersionFromValid(TimeTool validFrom){ int year = validFrom.get(TimeTool.YEAR); int month = validFrom.get(TimeTool.MONTH) + 1; int day = validFrom.get(TimeTool.DAY_OF_MONTH); return day + (month * 100) + ((year - 2000) * 10000); } private void updateOrCreateFromImportedValues(){ // get all entries with matching code Query<Labor2009Tarif> qEntries = new Query<Labor2009Tarif>(Labor2009Tarif.class); qEntries.add(Labor2009Tarif.FLD_CODE, "=", importedValues.get(Labor2009Tarif.FLD_CODE)); List<Labor2009Tarif> entries = qEntries.execute(); List<Labor2009Tarif> openEntries = new ArrayList<Labor2009Tarif>(); // get open entries -> field FLD_GUELTIG_BIS not set for (Labor2009Tarif labor2009Tarif : entries) { String gBis = labor2009Tarif.get(Labor2009Tarif.FLD_GUELTIG_BIS); if (gBis == null || gBis.trim().length() == 0) openEntries.add(labor2009Tarif); } if (openEntries.isEmpty()) { // just create if there are no open entries Labor2009Tarif tarif = new Labor2009Tarif(importedValues.get(Labor2009Tarif.FLD_CHAPTER), importedValues.get(Labor2009Tarif.FLD_CODE), importedValues.get(Labor2009Tarif.FLD_TP), importedValues.get(Labor2009Tarif.FLD_NAME), importedValues.get(Labor2009Tarif.FLD_LIMITATIO), importedValues.get(Labor2009Tarif.FLD_FACHBEREICH), Fachspec.getFachspec(specs, row)); tarif.set(Labor2009Tarif.FLD_GUELTIG_VON, validFrom.toString(TimeTool.DATE_COMPACT)); } else { // do actual import if entries with updating open entries for (Labor2009Tarif labor2009Tarif : openEntries) { if (labor2009Tarif.get(Labor2009Tarif.FLD_GUELTIG_VON).equals( validFrom.toString(TimeTool.DATE_COMPACT))) { // test if the gVon is the same -> update the values of the entry labor2009Tarif.set(new String[] { Labor2009Tarif.FLD_CHAPTER, Labor2009Tarif.FLD_CODE, Labor2009Tarif.FLD_TP, Labor2009Tarif.FLD_NAME, Labor2009Tarif.FLD_LIMITATIO, Labor2009Tarif.FLD_FACHBEREICH, Labor2009Tarif.FLD_FACHSPEC }, concatChapter(labor2009Tarif, importedValues.get(Labor2009Tarif.FLD_CHAPTER)), importedValues.get(Labor2009Tarif.FLD_CODE), importedValues.get(Labor2009Tarif.FLD_TP), importedValues.get(Labor2009Tarif.FLD_NAME), importedValues.get(Labor2009Tarif.FLD_LIMITATIO), importedValues.get(Labor2009Tarif.FLD_FACHBEREICH), Integer.toString(Fachspec.getFachspec(specs, row))); } else { // close entry and create new entry labor2009Tarif.set(Labor2009Tarif.FLD_GUELTIG_BIS, validFrom.toString(TimeTool.DATE_COMPACT)); Labor2009Tarif tarif = new Labor2009Tarif(importedValues.get(Labor2009Tarif.FLD_CHAPTER), importedValues.get(Labor2009Tarif.FLD_CODE), importedValues.get(Labor2009Tarif.FLD_TP), importedValues.get(Labor2009Tarif.FLD_NAME), importedValues.get(Labor2009Tarif.FLD_LIMITATIO), importedValues.get(Labor2009Tarif.FLD_FACHBEREICH), Fachspec.getFachspec(specs, row)); tarif.set(Labor2009Tarif.FLD_GUELTIG_VON, validFrom.toString(TimeTool.DATE_COMPACT)); } } } } private String concatChapter(Labor2009Tarif existing, String chapter){ String existingChapter = existing.get(Labor2009Tarif.FLD_CHAPTER); if (existingChapter != null && !existingChapter.isEmpty()) { return existingChapter + ", " + chapter; } else { return chapter; } } private void fillImportedValues2012(String[] line){ importedValues.clear(); importedValues.put(Labor2009Tarif.FLD_CHAPTER, StringTool.getSafe(line, 0)); // convert code to nnnn.mm String code = convertCodeString(StringTool.getSafe(line, 2)); importedValues.put(Labor2009Tarif.FLD_CODE, code); importedValues.put(Labor2009Tarif.FLD_TP, convertLocalizedNumericString(StringTool.getSafe(line, 3)).toString()); importedValues.put(Labor2009Tarif.FLD_NAME, StringTool.limitLength(StringTool.getSafe(line, 4), 254)); importedValues.put(Labor2009Tarif.FLD_LIMITATIO, StringTool.getSafe(line, 5)); importedValues.put(Labor2009Tarif.FLD_FACHBEREICH, StringTool.getSafe(line, 7)); } private void fillImportedValues2011(String[] line){ importedValues.clear(); importedValues.put(Labor2009Tarif.FLD_CHAPTER, StringTool.getSafe(line, 0)); // convert code to nnnn.mm String code = convertCodeString(StringTool.getSafe(line, 2)); importedValues.put(Labor2009Tarif.FLD_CODE, code); importedValues.put(Labor2009Tarif.FLD_TP, convertLocalizedNumericString(StringTool.getSafe(line, 3)).toString()); importedValues.put(Labor2009Tarif.FLD_NAME, StringTool.limitLength(StringTool.getSafe(line, 4), 254)); importedValues.put(Labor2009Tarif.FLD_LIMITATIO, StringTool.getSafe(line, 5)); importedValues.put(Labor2009Tarif.FLD_FACHBEREICH, StringTool.getSafe(line, 6)); } private void closeAllOlder(){ // get all entries TimeTool defaultValidFrom = new TimeTool(); defaultValidFrom.set(1970, 0, 1); Query<Labor2009Tarif> qEntries = new Query<Labor2009Tarif>(Labor2009Tarif.class); List<Labor2009Tarif> entries = qEntries.execute(); for (Labor2009Tarif labor2009Tarif : entries) { String validFromString = labor2009Tarif.get(Labor2009Tarif.FLD_GUELTIG_VON); String validUntilString = labor2009Tarif.get(Labor2009Tarif.FLD_GUELTIG_BIS); if ((validFromString == null || validFromString.trim().length() == 0)) { // old entry with no valid from labor2009Tarif.set(Labor2009Tarif.FLD_GUELTIG_VON, defaultValidFrom.toString(TimeTool.DATE_COMPACT)); labor2009Tarif.set(Labor2009Tarif.FLD_GUELTIG_BIS, validFrom.toString(TimeTool.DATE_COMPACT)); } else if ((validUntilString == null || validUntilString.trim().length() == 0) && !validFrom.toString(TimeTool.DATE_COMPACT).equals(validFromString)) { // old entry not closed yet labor2009Tarif.set(Labor2009Tarif.FLD_GUELTIG_BIS, validFrom.toString(TimeTool.DATE_COMPACT)); } } } private String convertCodeString(String code){ // split by all possible delimiters after reading for xls String[] parts = code.split("[\\.,']"); StringBuilder sb = new StringBuilder(); for (String part : parts) { sb.append(part); // at one point we should reach nnnn -> then add the '.' delimiter if (sb.length() == 4) sb.append("."); } // if there was no "sub number" add "00" if (sb.length() == 5) sb.append("00"); else if (sb.length() == 6) sb.append("0"); return sb.toString(); } private String convertLocalizedNumericString(String localized){ DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(); Number number = new Integer(0); try { number = df.parse(localized); } catch (ParseException pe) { /* ignore and return default 0 */} // cut off decimals if there are none if ((number.doubleValue() % 1.0) > 0) { return Double.toString(number.doubleValue()); } else { return Integer.toString(number.intValue()); } } private int getFormatYear(String[] line){ String fach2011 = StringTool.getSafe(line, 6); String fach2012 = StringTool.getSafe(line, 7); if (fach2012.equals("") && !fach2011.equals("")) return 2011; else if (fach2011.equals("") && !fach2012.equals("")) return 2012; else return -1; } @Override public int getCurrentVersion(){ return Labor2009Tarif.getCurrentCodeVersion(); } }