/*******************************************************************************
* Copyright (c) 2007-2009, G. Weirich and Elexis
* 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:
* G. Weirich - initial implementation
*
*******************************************************************************/
package ch.berchtold.emanuel.privatrechnung.data;
import java.util.List;
import ch.elexis.data.Fall;
import ch.elexis.data.PersistentObject;
import ch.elexis.data.VerrechenbarAdapter;
import ch.elexis.data.Xid;
import ch.rgw.tools.Money;
import ch.rgw.tools.TimeTool;
import ch.rgw.tools.VersionInfo;
/**
* A billing plugin that is able to manage several arbitrary tax systems
*
* @author gerry
*
*/
public class Leistung extends VerrechenbarAdapter {
/**
* Definition of the name of the table where Objects of this class should be stored the
* tablename should alwas be prefixed with tghe plugin's id to avoid name clashes if a plugins
* needs only one table, the name might as well be just the ID by itself. note: replace dots in
* the id with underscores
*/
static final String TABLENAME = "CH_BERCHTOLD_PRIVATRECHNUNG";
public static final String CODESYSTEM_NAME = "Privattarif";
public static final String CODESYSTEM_CODE = "999";
public static final String FIELD_NAME = "name";
static final String VERSION = "0.3.3";
public static final String XIDDOMAIN = "www.xid.ch/id/customservices/" + CODESYSTEM_NAME;
/**
* If the table does not exist when this plugin is loaded, it must create it on the fly. it
* should use this as explained here. The create script must make sure that it can run
* successful on any sql compliant database
*/
private static final String createDB = "CREATE TABLE "
+ TABLENAME
+ "("
+ "ID VARCHAR(25) primary key,"// This field must always be present
+ "deleted CHAR(1) default '0',"
+ "lastupdate BIGINT,"// This field must always be present
+ "parent VARCHAR(80),"
+ "name VARCHAR(499),"
+ "short VARCHAR(80),"
+ "cost CHAR(8),"// use always fixed char fields for amounts
+ "price CHAR(8),"// amounts are always in cents/rp
+ "time CHAR(4),"
+ "subsystem VARCHAR(25),"
+ "valid_from CHAR(8),"// use always char(8) for dates
+ "valid_until CHAR(8),"
+ "ExtInfo BLOB);"
+ // An ExtInfo field can be used to store arbitrary data
"INSERT INTO " + TABLENAME + " (ID,name) VALUES ('VERSION','" + VERSION + "');"
+ "CREATE INDEX chelpr_idx1 on " + TABLENAME + "(parent,name);"
+ "CREATE INDEX chelpr_idx2 on " + TABLENAME + "(valid_from);";
private static final String UPDATE_033 = "ALTER TABLE " + TABLENAME + " ADD lastupdate BIGINT;";
/**
* Here we define the mapping between internal fieldnames and database fieldnames. (@see
* PersistentObject) then we try to load a version element. If this does not exist, we create
* the table. If it exists, we check the version
*/
static {
addMapping(TABLENAME, "parent", "Name=name", "Kuerzel=short", "Kosten=cost", "Preis=price",
"subsystem", "Zeit=time", "DatumVon=S:D:valid_from", "DatumBis=S:D:valid_until",
"ExtInfo");
Leistung check = load("VERSION");
if (check.state() < PersistentObject.DELETED) { // Object never existed, so we have to
// create the database
createOrModifyTable(createDB);
} else { // found existing table, check version
VersionInfo v = new VersionInfo(check.get("Name"));
if (v.isOlder(VERSION)) {
createOrModifyTable(UPDATE_033);
check.set("Name", VERSION);
}
}
Xid.localRegisterXIDDomainIfNotExists(XIDDOMAIN, "Privatrechnung B", Xid.ASSIGNMENT_LOCAL);
}
public static void createTable(){
createOrModifyTable(createDB);
}
public String getXidDomain(){
return XIDDOMAIN;
}
public Leistung(String subsystem, String parent, final String name, final String kuerzel,
final String kostenInRp, final String preisInRp, final String ZeitInMin, String DatumVon,
String DatumBis){
create(null);
if (subsystem == null) {
subsystem = "";
}
if (DatumVon == null) {
DatumVon = TimeTool.BEGINNING_OF_UNIX_EPOCH;
}
if (DatumBis == null) {
DatumBis = TimeTool.END_OF_UNIX_EPOCH;
}
if (parent == null) {
parent = "NIL";
}
set(new String[] {
"parent", "Name", "Kuerzel", "Kosten", "Preis", "Zeit", "subsystem", "DatumVon",
"DatumBis"
}, new String[] {
parent, name, kuerzel, kostenInRp, preisInRp, ZeitInMin, subsystem, DatumVon, DatumBis
});
}
/**
* A code to describe this code system uniquely (can be written on bills etc.)
*/
@Override
public String getCodeSystemCode(){
return CODESYSTEM_CODE;
}
/**
* The name of this code system to be displayed in the CodeSelector for the user
*/
@Override
public String getCodeSystemName(){
return CODESYSTEM_NAME;
}
/**
* A Label for this code
*/
@Override
public String getLabel(){
return get("Name");
}
@Override
public String getText(){
return get("Name");
}
@Override
public String getCode(){
return get("Kuerzel");
}
@Override
public Money getKosten(final TimeTool dat){
return new Money(checkZero(get("Kosten")));
}
@Override
public int getMinutes(){
return checkZero(get("Zeit"));
}
/**
* Mandatory method: return the table where elements of this class are stored
*/
@Override
protected String getTableName(){
return TABLENAME;
}
/**
* fields to display in code selector
*/
public String[] getDisplayedFields(){
return new String[] {
"Name", "Preis"
};
}
/**
* factor to calculate the final price from the base price as stored in the table and the factor
* that is in effect at the given date and that migh depend from the "Fall-Type" and the billing
* type.
*/
public double getFactor(final TimeTool date, final Fall fall){
return getVKMultiplikator(date, fall);
}
/**
* base price at a given date for this service
*/
public int getTP(final TimeTool date, final Fall fall){
return checkZero(get("Preis"));
}
/**
* -required- This is the standard method to construct a PersistentObject from its
* representation in the database. For semantic reasons we intenionally do not use the "new"
* constructor for that purpose. "New" should only be used to create really "new" Objects and
* not to load existing objects from the database. Internally, however, load simply calls
* new(String). The static method load(String) must exist in every sublclass of
* PersistentObject, but it can always be written just exacly as here. The method needs not to
* guarantee that the returned object exists. It can, if desired, return a null value to
* indicate a inexistent object. Here we return just whatever the superclass gives us.
*
*/
public static Leistung load(final String id){
return new Leistung(id);
}
/**
* The empty constructor is only needed by the factory and should never be public.
*/
protected Leistung(){}
/**
* The constructor with a single String is used to load objects from the database and should
* never be called directly. For that purpose is the static method load() to be used instead.
* This constructor should always be defined exactly the same way as shown below. It loads the
* object "lazily", what means that an access to the database will not occur until a member of
* the object is needed. This means, that the constructor will always succeed, even if the
* accessed object does not exist or is not valid. The caller could check this with exists() or
* isValid(), but this would mean an (in most cases unneccessary) database access.
*/
protected Leistung(final String id){
super(id);
}
@Override
public boolean isDragOK(){
return true;
}
public List<Object> getActions(Object context){
// TODO Auto-generated method stub
return null;
}
}