OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 21 → Rev 25

/trunk/OpenConcerto/Configuration/Template/Default/VenteFacture.xml
95,8 → 95,8
<element location="B63" type="fill">
<field base="Societe" table="SAISIE_VENTE_FACTURE" name="ID_MODE_REGLEMENT">
 
<field base="Societe" table="MODE_REGLEMENT" name="NOM" prefix="Règlement souhaité" conditionField="COMPTANT" conditionExpValue="false" display="false"/>
<field base="Societe" table="MODE_REGLEMENT" name="NOM" prefix="Facture acquitée par" conditionField="COMPTANT" conditionExpValue="true" display="false"/>
<field base="Societe" table="MODE_REGLEMENT" name="NOM" prefix="Règlement souhaité" conditionField="COMPTANT" conditionExpValue="true" display="false"/>
<field base="Societe" table="MODE_REGLEMENT" name="NOM" prefix="Facture acquitée par" conditionField="COMPTANT" conditionExpValue="false" display="false"/>
 
<field base="Societe" table="MODE_REGLEMENT" name="ID_TYPE_REGLEMENT">
<field base="Societe" table="TYPE_REGLEMENT" name="NOM" valuesExpected="Indéfini"/>
112,6 → 112,10
 
<element location="B64" type="fill">
<field base="Societe" table="SAISIE_VENTE_FACTURE" name="DATE" type="DateEcheance" prefix="Règlement de cette facture au plus tard le " valuesExpected=" "/>
</element>
 
<element location="B64" type="fill">
<field base="Societe" table="SAISIE_VENTE_FACTURE" name="ID_MODE_REGLEMENT">
 
<field base="Societe" table="MODE_REGLEMENT" name="NOM" prefix="Règlement à date de réception de facture" conditionField="COMPTANT" conditionExpValue="false" display="false"/>
118,11 → 122,7
</field>
</element>
 
<element location="B64" type="fill">
<field base="Societe" table="SAISIE_VENTE_FACTURE" name="DATE" type="DateEcheance" prefix="Règlement de cette facture au plus tard le " valuesExpected=" "/>
</element>
 
<table endPageLine="65" firstLine="63" endLine="65" lastColumn="I" base="Societe" table="TVA">
<element location="I" name="NOM" prefix="Total ">
</element>
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/SQLSearchableTextCombo.java
18,18 → 18,9
import org.openconcerto.sql.sqlobject.SQLTextCombo.ITextComboCacheSQL;
import org.openconcerto.sql.sqlobject.itemview.RowItemViewComponent;
import org.openconcerto.ui.component.ComboLockedMode;
import org.openconcerto.ui.component.IComboCacheListModel;
import org.openconcerto.ui.component.combo.ISearchableTextCombo;
import org.openconcerto.utils.change.CollectionChangeEvent;
import org.openconcerto.utils.change.IListDataEvent;
import org.openconcerto.utils.model.DefaultIMutableListModel;
 
import java.util.Collection;
import java.util.List;
 
import javax.swing.SwingWorker;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
 
/**
* An ISearchableTextCombo with the cache from COMPLETION.
*
73,87 → 64,17
* @param cache the cache to set.
*/
public void initCacheLater(final ISQLListModel cache) {
cache.load(new Runnable() {
@Override
public void run() {
initCache(cache);
cache.initCacheLater(this);
}
});
}
 
public static class ISQLListModel extends DefaultIMutableListModel<String> {
public static class ISQLListModel extends IComboCacheListModel {
 
private final ITextComboCacheSQL cache;
private final ListDataListener l;
 
public ISQLListModel(final SQLField f) {
this(new ITextComboCacheSQL(f));
}
 
public ISQLListModel(final ITextComboCacheSQL c) {
this.cache = c;
this.l = new ListDataListener() {
 
@SuppressWarnings("unchecked")
public void contentsChanged(ListDataEvent e) {
// selection change, see DefaultIMutableListModel#setSelectedItem()
if (e.getIndex0() < 0)
return;
 
final CollectionChangeEvent evt = ((IListDataEvent) e).getCollectionChangeEvent();
this.remove(evt);
this.add(evt.getItemsAdded());
super(c);
}
 
public void intervalAdded(ListDataEvent e) {
this.add(getList().subList(e.getIndex0(), e.getIndex1() + 1));
}
 
public void intervalRemoved(ListDataEvent e) {
this.remove(((IListDataEvent) e).getCollectionChangeEvent());
}
 
private void add(Collection<String> toAdd) {
for (final String s : toAdd) {
ISQLListModel.this.cache.addToCache(s);
}
}
 
@SuppressWarnings("unchecked")
private void remove(CollectionChangeEvent evt) {
for (final String s : (Collection<String>) evt.getItemsRemoved())
ISQLListModel.this.cache.deleteFromCache(s);
}
};
}
 
private void load(final Runnable r) {
if (this.cache.isValid()) {
new SwingWorker<List<String>, Object>() {
 
@Override
protected List<String> doInBackground() throws Exception {
return ISQLListModel.this.cache.loadCache();
}
 
@Override
protected void done() {
// don't remove and add from the cache, items just came from it
removeListDataListener(ISQLListModel.this.l);
removeAllElements();
try {
addAll(get());
} catch (Exception e1) {
// tant pis, pas de cache
e1.printStackTrace();
}
addListDataListener(ISQLListModel.this.l);
if (r != null)
r.run();
}
 
}.execute();
}
}
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/SQLRequestComboBox.java
39,6 → 39,7
 
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.beans.PropertyChangeEvent;
47,6 → 48,7
import java.util.List;
 
import javax.accessibility.Accessible;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
120,6 → 122,13
 
this.combo = new ISearchableCombo<IComboSelectionItem>(ComboLockedMode.LOCKED, 1, this.stringStuff.length());
this.combo.setIncludeEmpty(addUndefined);
this.combo.getActions().add(new AbstractAction("Recharger") {
@Override
public void actionPerformed(ActionEvent e) {
// ignore cache since a user explicitly asked for an update
fillCombo(null, false);
}
});
 
this.emptySupp = new EmptyChangeSupport(this);
this.supp = new ValueChangeSupport<Integer>(this);
138,7 → 147,10
@Override
public void init(SQLRowItemView v) {
final SQLTable foreignTable = v.getField().getDBSystemRoot().getGraph().getForeignTable(v.getField());
if (!this.hasModel())
this.uiInit(Configuration.getInstance().getDirectory().getElement(foreignTable).getComboRequest());
else if (this.getRequest().getPrimaryTable() != foreignTable)
throw new IllegalArgumentException("Tables are different " + getRequest().getPrimaryTable().getSQLName() + " != " + foreignTable.getSQLName());
}
 
/**
297,9 → 309,13
}
 
public synchronized final void fillCombo(final Runnable r) {
this.req.fillCombo(r);
this.fillCombo(r, true);
}
 
public synchronized final void fillCombo(final Runnable r, final boolean readCache) {
this.req.fillCombo(r, readCache);
}
 
// combo
 
public final List<IComboSelectionItem> getItems() {
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/itemview/VWRowItemView.java
65,7 → 65,7
 
/**
* The predicate testing whether the value is empty or not. This implementation returns
* {@link EmptyObjFromVO#DEFAULT_PREDICATE}
* {@link EmptyObjFromVO#getDefaultPredicate()}
*
* @return the predicate testing whether the value is empty.
*/
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/ElementComboBox.java
18,6 → 18,7
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.request.SQLRowItemView;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel;
135,8 → 136,14
* @return this
*/
public final ElementComboBox init(SQLElement element) {
return this.init(element, element.getComboRequest());
}
 
public final ElementComboBox init(SQLElement element, final ComboSQLRequest req) {
if (element.getTable() != req.getPrimaryTable())
throw new IllegalArgumentException("Tables are different " + element.getTable().getSQLName() + " != " + req.getPrimaryTable().getSQLName());
this.element = element;
this.uiInit(this.element.getComboRequest());
this.uiInit(req);
return this;
}
 
146,7 → 153,10
if (foreignTable == null) {
throw new IllegalArgumentException("No foreign table for " + v.getField().getFullName());
}
if (this.getElement() == null)
this.init(Configuration.getInstance().getDirectory().getElement(foreignTable));
else if (this.getElement().getTable() != foreignTable)
throw new IllegalArgumentException("Tables are different " + getElement().getTable().getSQLName() + " != " + foreignTable.getSQLName());
}
 
public final SQLElement getElement() {
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/ITextWithCompletion.java
15,17 → 15,16
 
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.ui.component.text.TextComponent;
import org.openconcerto.utils.OrderedSet;
 
import org.openconcerto.utils.checks.MutableValueObject;
import org.openconcerto.utils.text.DocumentFilterList;
import org.openconcerto.utils.text.DocumentFilterList.FilterType;
import org.openconcerto.utils.text.LimitedSizeDocumentFilter;
import org.openconcerto.utils.text.DocumentFilterList.FilterType;
 
import java.awt.Component;
import java.awt.GridLayout;
118,19 → 117,12
 
this.isLoading = true;
loadCacheAsynchronous();
this.comboRequest.addTableListener(new SQLTableListener() {
 
public void rowAdded(SQLTable table, int id) {
// FIXME never removed
this.comboRequest.addTableListener(new SQLTableModifiedListener() {
@Override
public void tableModified(SQLTableEvent evt) {
loadCacheAsynchronous();
}
 
public void rowDeleted(SQLTable table, int id) {
loadCacheAsynchronous();
}
 
public void rowModified(SQLTable table, int id) {
loadCacheAsynchronous();
}
});
}
 
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/SQLTextCombo.java
15,6 → 15,7
 
import org.openconcerto.sql.Log;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.IResultSetHandler;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRowValues;
85,13 → 86,25
return this.t.getDBSystemRoot().getDataSource();
}
 
@SuppressWarnings("unchecked")
public List<String> loadCache() {
public List<String> loadCache(final boolean dsCache) {
final SQLSelect sel = new SQLSelect(this.t.getBase());
sel.addSelect(this.t.getField("LABEL"));
sel.setWhere(new Where(this.t.getField("CHAMP"), "=", this.field));
// ignore DS cache to allow the fetching of rows modified by another VM
@SuppressWarnings("unchecked")
final List<String> items = (List<String>) this.getDS().execute(sel.asString(), new IResultSetHandler(SQLDataSource.COLUMN_LIST_HANDLER) {
@Override
public boolean readCache() {
return dsCache;
}
 
@Override
public boolean writeCache() {
return true;
}
});
this.cache.clear();
this.cache.addAll(this.getDS().executeCol(sel.asString()));
this.cache.addAll(items);
 
return this.cache;
}
98,7 → 111,7
 
public List<String> getCache() {
if (!this.loadedOnce) {
this.loadCache();
this.loadCache(true);
this.loadedOnce = true;
}
return this.cache;
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/IComboModel.java
16,7 → 16,8
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.view.search.SearchSpec;
import org.openconcerto.sql.view.search.SearchSpecUtils;
27,7 → 28,6
import org.openconcerto.utils.checks.EmptyListener;
import org.openconcerto.utils.checks.EmptyObj;
import org.openconcerto.utils.checks.MutableValueObject;
import org.openconcerto.utils.model.DefaultIListModel;
import org.openconcerto.utils.model.DefaultIMutableListModel;
 
import java.beans.PropertyChangeEvent;
52,7 → 52,7
*
* @author Sylvain CUAZ
*/
public class IComboModel extends DefaultIMutableListModel<IComboSelectionItem> implements SQLTableListener, MutableValueObject<IComboSelectionItem>, EmptyObj {
public class IComboModel extends DefaultIMutableListModel<IComboSelectionItem> implements SQLTableModifiedListener, MutableValueObject<IComboSelectionItem>, EmptyObj {
 
private final ComboSQLRequest req;
 
72,8 → 72,6
// true from when the combo is filled with the sole "dots" item until it is loaded with actual
// items, no need to synchronize (EDT)
private boolean updating;
// true if the items being changed are for display only and do not reflect the db
private boolean uiItems;
// l'id à sélectionner à la fin du updateAll
private int idToSelect;
 
100,7 → 98,6
this.search = null;
this.runnables = new ArrayList<Runnable>();
this.setWillUpdate(null);
this.uiItems = false;
this.itemsByID = new HashMap<Integer, IComboSelectionItem>();
this.addMissingItem = true;
 
166,7 → 163,7
// selection change
comboValueChanged();
} else {
itemsChanged(((DefaultIListModel) e.getSource()).getList());
itemsChanged();
}
}
});
230,14 → 227,14
* Reload this combo. This method is thread-safe.
*/
public synchronized final void fillCombo() {
this.fillCombo(null);
this.fillCombo(null, true);
}
 
public synchronized final void fillCombo(final Runnable r) {
public synchronized final void fillCombo(final Runnable r, final boolean readCache) {
// wholly synch otherwise we might get onScreen after the if
// and thus completely ignore that fillCombo()
if (!this.isSleepAllowed() || this.isOnScreen() || r != null) {
this.doUpdateAll(r);
this.doUpdateAll(r, readCache);
} else {
this.isADirtyDrityGirl = true;
}
260,14 → 257,12
 
this.setUpdating(true);
 
this.uiItems = true;
this.removeAllItems();
addItem(new IComboSelectionItem(SQLRow.NONEXISTANT_ID, "...."));
this.uiItems = false;
// Like ITableModel, don't remove all items, so that if the request fails we still
// keep old items (we used to have uiItems=true while setting the list to "Loading...")
}
}
 
private void doUpdateAll(final Runnable r) {
private void doUpdateAll(final Runnable r, final boolean readCache) {
log("entering doUpdateAll");
synchronized (this) {
this.isADirtyDrityGirl = false;
290,13 → 285,12
protected List<IComboSelectionItem> doInBackground() throws InterruptedException {
// attends 1 peu pour voir si on va pas être annulé
Thread.sleep(50);
return SearchSpecUtils.filter(IComboModel.this.req.getComboItems(), search);
return SearchSpecUtils.filter(IComboModel.this.req.getComboItems(readCache), search);
}
 
// Runs on the event-dispatching thread.
@Override
public void done() {
try {
synchronized (IComboModel.this) {
// if cancel() is called after doInBackground() nothing happens
// but updating is set to a new instance
304,38 → 298,49
// une autre maj arrive
return;
 
final List<IComboSelectionItem> items = this.get();
final boolean firstFill = !IComboModel.this.filledOnce;
// store before removing since it can trigger a selection change
final int idToSelect = IComboModel.this.idToSelect;
List<IComboSelectionItem> items = null;
try {
items = this.get();
removeAllItems();
addAllItems(items);
final boolean firstFill = !IComboModel.this.filledOnce;
IComboModel.this.filledOnce = true;
} catch (InterruptedException e) {
// ne devrait pas arriver puisque done() appelée après doInBackground()
e.printStackTrace();
} catch (CancellationException e) {
// ne devrait pas arriver puisqu'on teste isCancelled()
e.printStackTrace();
} catch (ExecutionException e) {
if (!(e.getCause() instanceof RTInterruptedException))
// pas normal
e.printStackTrace();
} finally {
// always clear willUpdate otherwise the combo can't recover
assert IComboModel.this.willUpdate == this;
IComboModel.this.setWillUpdate(null);
 
}
// check if items could be retrieved
// TODO otherwise show the error to the user so he knows that items are
// stale and he could reload them
if (items != null) {
// restaurer l'état
// if there's only one item in the list and no previous ID to select
// and org.openconcerto.sql.sqlCombo.selectSoleItem=true,select the item
final boolean noSelection = IComboModel.this.idToSelect == SQLRow.NONEXISTANT_ID;
final boolean noSelection = idToSelect == SQLRow.NONEXISTANT_ID;
if (items.size() == 1 && noSelection && Boolean.getBoolean("org.openconcerto.sql.sqlCombo.selectSoleItem"))
IComboModel.this.setSelectedItem(items.get(0));
else if (noSelection && firstFill && getFirstFillSelection() != null)
IComboModel.this.setSelectedItem(getFirstFillSelection().transformChecked(items));
else
selectID(IComboModel.this.idToSelect);
selectID(idToSelect);
 
for (final Runnable r : IComboModel.this.runnables)
r.run();
IComboModel.this.runnables.clear();
}
} catch (InterruptedException e) {
// ne devrait pas arriver puisque done() appelée après doInBackground()
e.printStackTrace();
} catch (CancellationException e) {
// ne devrait pas arriver puisqu'on teste isCancelled()
e.printStackTrace();
} catch (ExecutionException e) {
if (!(e.getCause() instanceof RTInterruptedException))
// pas normal
e.printStackTrace();
}
}
};
401,10 → 406,9
}
}
 
private final void itemsChanged(final List newVal) {
private final void itemsChanged() {
final List<IComboSelectionItem> newVal = this.getList();
this.propSupp.firePropertyChange("items", null, newVal);
if (!this.uiItems)
this.propSupp.firePropertyChange("dataItems", null, newVal);
}
 
// *** value
484,17 → 488,10
log("entering selectID " + id);
assert SwingUtilities.isEventDispatchThread();
 
// selectID() caused by the removeAll() of updateAllBegun()
// so we don't want to forget the selection
if (this.uiItems) {
assert id == SQLRow.NONEXISTANT_ID;
return;
}
 
// no need to launch another updateAll() if one is already underway
if (this.neverBeenFilled() && !isUpdating())
// don't use fillCombo() which won't really update unless we're on screen
this.doUpdateAll(null);
this.doUpdateAll(null, true);
 
if (this.isUpdating()) {
this.idToSelect = id;
624,7 → 621,8
* ones (e.g. adding a '-- loading --' item).
*/
public final void addItemsListener(PropertyChangeListener l, final boolean all) {
this.addListener(all ? "items" : "dataItems", l);
// there's no uiItems anymore, so ignore the boolean
this.addListener("items", l);
}
 
public final void rmItemsListener(PropertyChangeListener l) {
633,41 → 631,15
 
// *** une table que nous affichons a changé
 
/*
* (non-Javadoc)
*
* @see org.openconcerto.sql.model.SQLTableListener2#rowModified(org.openconcerto.sql.model.SQLTable, int)
*/
public void rowModified(SQLTable table, int id) {
if (id >= SQLRow.MIN_VALID_ID && this.getForeignTable().equals(table)) {
@Override
public void tableModified(SQLTableEvent evt) {
final int id = evt.getId();
if (id >= SQLRow.MIN_VALID_ID && this.getForeignTable().equals(evt.getTable())) {
this.reloadComboItem(id);
} else
this.fillCombo();
}
 
/*
* (non-Javadoc)
*
* @see org.openconcerto.sql.model.SQLTableListener2#rowAdded(org.openconcerto.sql.model.SQLTable, int)
*/
public void rowAdded(SQLTable table, int id) {
this.fillCombo();
}
 
/*
* (non-Javadoc)
*
* @see org.openconcerto.sql.model.SQLTableListener2#rowDeleted(org.openconcerto.sql.model.SQLTable, int)
*/
public void rowDeleted(SQLTable table, int id) {
if (this.getForeignTable().equals(table)) {
// delete even if we're not on screen, since it takes next to no time
this.reloadComboItem(id);
} else {
this.fillCombo();
}
}
 
// *** search
 
public final void search(SearchSpec spec) {
/trunk/OpenConcerto/src/org/openconcerto/sql/Configuration.java
119,7 → 119,7
return newFile;
}
 
protected final File getConfDir(DBStructureItem<?> db) {
public final File getConfDir(DBStructureItem<?> db) {
return DBItemFileCache.getDescendant(new File(getConfDir(), "dataDepedent"), DBFileCache.getJDBCAncestorNames(db, true));
}
 
/trunk/OpenConcerto/src/org/openconcerto/sql/request/SQLCacheWatcher.java
16,7 → 16,7
import org.openconcerto.sql.model.SQLData;
import org.openconcerto.sql.model.SQLDataListener;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.utils.cache.CacheWatcher;
 
/**
27,7 → 27,7
*/
public class SQLCacheWatcher<K> extends CacheWatcher<K, SQLData> {
 
private final SQLTableListener listener;
private final SQLTableModifiedListener listener;
 
SQLCacheWatcher(final SQLCache<K, ?> c, final SQLData t) {
super(c, t);
36,7 → 36,7
clearCache();
}
});
this.getTable().addPremierTableListener(this.listener);
this.getTable().addPremierTableModifiedListener(this.listener);
}
 
private final SQLTable getTable() {
45,7 → 45,7
 
@Override
protected void dying() {
this.getTable().removeTableListener(this.listener);
this.getTable().removeTableModifiedListener(this.listener);
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/sql/request/BaseSQLRequest.java
16,7 → 16,7
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLFieldsSet;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableModifiedListener;
 
import java.util.Collection;
import java.util.Set;
38,15 → 38,15
*/
protected abstract Collection<SQLField> getAllFields();
 
public final void addTableListener(SQLTableListener l) {
public final void addTableListener(SQLTableModifiedListener l) {
for (final SQLTable t : this.getTables()) {
t.addTableListener(l);
t.addTableModifiedListener(l);
}
}
 
public final void removeTableListener(SQLTableListener l) {
public final void removeTableListener(SQLTableModifiedListener l) {
for (final SQLTable t : this.getTables()) {
t.removeTableListener(l);
t.removeTableModifiedListener(l);
}
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/request/SQLRowView.java
19,7 → 19,9
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableEvent.Mode;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.ui.SwingThreadUtils;
 
import java.awt.Component;
49,7 → 51,7
 
// la table cible de cette requete
private final SQLTable table;
private final SQLTableListener tableListener;
private final SQLTableModifiedListener tableListener;
// l'id affiché ou SQLRow.NONEXISTANT_ID si les valeurs affichées ne sont pas liées à une ligne
// dans la base
private int selectedID;
74,7 → 76,15
this.filling = false;
this.updating = false;
this.selectedID = SQLRow.NONEXISTANT_ID;
this.tableListener = new SQLTableListener() {
this.tableListener = new SQLTableModifiedListener() {
@Override
public void tableModified(SQLTableEvent evt) {
if (evt.getMode() == Mode.ROW_UPDATED)
this.rowModified(evt.getTable(), evt.getId());
else if (evt.getMode() == Mode.ROW_DELETED)
this.rowDeleted(evt.getTable(), evt.getId());
// else don't care
}
 
public void rowModified(SQLTable t, int id) {
if (!isUpdating() && existsInDB()) {
88,10 → 98,6
}
}
 
public void rowAdded(SQLTable t, int id) {
// don't care
}
 
public void rowDeleted(SQLTable t, int id) {
if (!isUpdating() && existsInDB()) {
if (!t.equals(getTable())) {
115,12 → 121,12
 
public final void activate(boolean b) {
if (b) {
this.table.addTableListener(this.tableListener);
this.table.addTableModifiedListener(this.tableListener);
if (this.existsInDB())
// to catch up to the changes which happened while we weren't listening
this.select(this.getSelectedID());
} else
this.table.removeTableListener(this.tableListener);
this.table.removeTableModifiedListener(this.tableListener);
}
 
/**
/trunk/OpenConcerto/src/org/openconcerto/sql/request/ComboSQLRequest.java
143,6 → 143,10
}
 
public final List<IComboSelectionItem> getComboItems() {
return this.getComboItems(true);
}
 
public final List<IComboSelectionItem> getComboItems(final boolean readCache) {
if (this.comboFields.isEmpty())
throw new IllegalStateException("La liste des items listitems est vide!! Ils faut utiliser addComboItem...");
 
151,14 → 155,17
final SQLRowValuesListFetcher comboSelect = this.getFetcher(null).freeze();
 
final CacheKey cacheKey = new CacheKey(comboSelect, this.fieldSeparator, this.undefLabel, this.customizeItem);
if (readCache) {
final CacheResult<List<IComboSelectionItem>> l = cache.check(cacheKey);
if (l.getState() == CacheResult.State.INTERRUPTED)
throw new RTInterruptedException("interrupted while waiting for the cache");
else if (l.getState() == CacheResult.State.VALID)
return l.getRes();
}
 
try {
final List<IComboSelectionItem> result = new ArrayList<IComboSelectionItem>();
// SQLRowValuesListFetcher don't cache
for (final SQLRowValues vals : comboSelect.fetch()) {
if (Thread.currentThread().isInterrupted())
throw new RTInterruptedException("interrupted in fill");
/trunk/OpenConcerto/src/org/openconcerto/sql/element/BaseSQLComponent.java
170,7 → 170,7
}
}
 
private Tuple2<JComponent, SQLType> getComp(String field) {
protected Tuple2<JComponent, SQLType> getComp(String field) {
if (getElement().getPrivateElement(field) != null)
// we create a MutableRowItemView and need SpecParser
throw new IllegalArgumentException("Private fields not supported");
192,6 → 192,7
// regular
comp = new SQLTextCombo();
}
comp.setOpaque(false);
return new Tuple2<JComponent, SQLType>(comp, type);
}
 
/trunk/OpenConcerto/src/org/openconcerto/sql/element/UISQLComponent.java
153,6 → 153,8
this.add(this.tabbedPane);
}
this.currentPanel = new JPanel();
// from Guillaume : tabs shouldn't be opaque in Windows L&F
this.currentPanel.setOpaque(false);
this.tabbedPane.addTab(tabTitle, this.currentPanel);
this.setLayouter(w, d);
}
/trunk/OpenConcerto/src/org/openconcerto/sql/element/LayoutHints.java
New file
0,0 → 1,93
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.sql.element;
 
public class LayoutHints {
 
private boolean maximizeWidth;
private boolean maximizeHeight;
private boolean showLabel;
private boolean separatedLabel;
private boolean fill;
public static final LayoutHints DEFAULT_FIELD_HINTS = new LayoutHints(false, false, true, false);
public static final LayoutHints DEFAULT_LARGE_FIELD_HINTS = new LayoutHints(true, false, true, false);
public static final LayoutHints DEFAULT_LIST_HINTS = new LayoutHints(true, true, false, false, true);
public static final LayoutHints DEFAULT_GROUP_HINTS = new LayoutHints(false, false, false, false);
public static final LayoutHints DEFAULT_LARGE_GROUP_HINTS = new LayoutHints(true, false, false, false);
 
public LayoutHints(boolean maximizeWidth, boolean maximizeHeight, boolean showLabel, boolean separatedLabel) {
this.maximizeWidth = maximizeWidth;
this.maximizeHeight = maximizeHeight;
this.showLabel = showLabel;
this.separatedLabel = separatedLabel;
this.fill = false;
}
 
public LayoutHints(boolean maximizeWidth, boolean maximizeHeight, boolean showLabel, boolean separatedLabel, boolean fill) {
this.maximizeWidth = maximizeWidth;
this.maximizeHeight = maximizeHeight;
this.showLabel = showLabel;
this.separatedLabel = separatedLabel;
this.fill = fill;
}
 
public boolean maximizeWidth() {
return maximizeWidth;
}
 
public boolean maximizeHeight() {
return maximizeHeight;
}
 
public boolean showLabel() {
return showLabel;
}
 
public boolean separatedLabel() {
return separatedLabel;
}
 
public boolean fill() {
return fill;
}
 
@Override
public String toString() {
String r = "";
if (maximizeHeight && maximizeWidth) {
r += "MaxW&H";
} else {
if (maximizeHeight) {
r += "MaxH";
}
if (maximizeWidth) {
r += "MaxW";
}
}
if (showLabel && separatedLabel) {
r += " SeparatedLabel";
} else {
if (showLabel) {
r += " StdLabel";
} else {
r += " NoLabel";
}
 
}
if (fill) {
r += " Fill";
}
return r;
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/element/Group.java
New file
0,0 → 1,156
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.sql.element;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
import org.openconcerto.utils.Tuple3;
 
public class Group {
 
private String id;
private int order = 0;
private List<Tuple3<Group, LayoutHints, Integer>> list = new ArrayList<Tuple3<Group, LayoutHints, Integer>>();
 
public Group(String id) {
this.id = id.trim();
 
}
 
public String getId() {
return id;
}
 
public void add(Group group) {
order += 100;
list.add(new Tuple3<Group, LayoutHints, Integer>(group, LayoutHints.DEFAULT_GROUP_HINTS, order));
}
 
public void add(Group group, LayoutHints hints) {
order += 100;
list.add(new Tuple3<Group, LayoutHints, Integer>(group, hints, order));
}
 
public void insert(Group group, LayoutHints hints, int order) {
list.add(new Tuple3<Group, LayoutHints, Integer>(group, hints, order));
}
 
public void add(String string) {
this.add(new Group(string), LayoutHints.DEFAULT_FIELD_HINTS);
 
}
 
public void add(String string, LayoutHints hints) {
this.add(new Group(string), hints);
 
}
 
public void dumpOneColumn() {
dumpOneColumn(LayoutHints.DEFAULT_GROUP_HINTS, 0, 1);
}
 
public void dumpOneColumn(LayoutHints localHint, int localOrder, int level) {
for (int i = 0; i < level - 1; i++) {
System.out.print(" ");
}
if (list.size() == 0)
System.out.print("+-- ");
else
System.out.print("+-+ ");
System.out.println(localOrder + " " + this.id + " [" + localHint + "]");
sortSubGroup();
for (Tuple3<Group, LayoutHints, Integer> tuple : list) {
 
((Group) tuple.get0()).dumpOneColumn(tuple.get1(), tuple.get2(), level + 1);
}
// System.out.println("== end" + this.id);
}
 
private void sortSubGroup() {
if (list.size() > 1) {
Collections.sort(list, new Comparator<Tuple3<Group, LayoutHints, Integer>>() {
 
@Override
public int compare(Tuple3<Group, LayoutHints, Integer> o1, Tuple3<Group, LayoutHints, Integer> o2) {
return o1.get2().compareTo(o2.get2());
}
});
}
}
 
public void dumpTwoColumn() {
dumpTwoColumn(0, LayoutHints.DEFAULT_GROUP_HINTS, 0, 1);
}
 
public int dumpTwoColumn(int x, LayoutHints localHint, int localOrder, int level) {
 
if (isEmpty()) {
System.out.print(" (" + x + ")");
 
System.out.print(localOrder + " " + this.id + "[" + localHint + "]");
 
if ((x % 2) == 1) {
System.out.println();
}
}
sortSubGroup();
for (Tuple3<Group, LayoutHints, Integer> tuple : list) {
final Group subGroup = tuple.get0();
final Integer subGroupOrder = (Integer) tuple.get2();
 
x = subGroup.dumpTwoColumn(x, tuple.get1(), subGroupOrder, level + 1);
 
}
if (isEmpty()) {
x++;
}
if (list.size() != 0 && localHint.maximizeWidth()) {
x = 0;
System.out.println();
}
return x;
}
 
public int getSize() {
return this.list.size();
}
 
public boolean isEmpty() {
return this.list.isEmpty();
}
 
public void sort() {
sortSubGroup();
for (Tuple3<Group, LayoutHints, Integer> tuple : list) {
final Group subGroup = tuple.get0();
subGroup.sort();
}
}
 
public Group getGroup(int i) {
return this.list.get(i).get0();
}
 
public LayoutHints getLayoutHints(int i) {
return this.list.get(i).get1();
}
 
public Integer getOrder(int i) {
return this.list.get(i).get2();
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/sql/element/SQLElementDirectory.java
104,7 → 104,15
for (final DirectoryListener dl : this.listeners) {
dl.elementAdded(elem);
}
String canonicalName = elem.getClass().getCanonicalName();
if (canonicalName.contains("erp.core") && canonicalName.contains(".element")) {
int i = canonicalName.indexOf("erp.core") + 9;
int j = canonicalName.indexOf(".element");
canonicalName = canonicalName.substring(i, j);
}
ElementMapper.getInstance().map(canonicalName + ".element", elem);
ElementMapper.getInstance().map(canonicalName + ".list.table", elem.getTable().getName());
}
 
public synchronized final boolean contains(SQLTable t) {
return this.elements.containsKey(t);
/trunk/OpenConcerto/src/org/openconcerto/sql/element/ElementMapper.java
New file
0,0 → 1,83
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.sql.element;
 
import org.openconcerto.utils.StringUtils;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class ElementMapper {
private final Map<String, Object> idToObject = new HashMap<String, Object>();
private final Map<Object, List<String>> objectsToIds = new HashMap<Object, List<String>>();
 
private static ElementMapper instance = new ElementMapper();
 
public ElementMapper() {
 
}
 
public static ElementMapper getInstance() {
return instance;
}
 
public void map(String id, Object obj) {
idToObject.put(id, obj);
List<String> l = objectsToIds.get(obj);
if (l == null) {
l = new ArrayList<String>(3);
l.add(id);
} else if (!l.contains(obj)) {
l.add(id);
}
}
 
public Object get(String id) {
return idToObject.get(id);
}
 
public String getString(String id) {
final Object object = idToObject.get(id);
if (object instanceof String) {
return (String) object;
}
return null;
}
 
public Group getGroup(String id) {
final Object object = idToObject.get(id);
if (object instanceof Group) {
return (Group) object;
}
return null;
}
 
public List<String> getIds(Object o) {
return objectsToIds.get(o);
}
 
public void dump() {
System.out.println(this.getClass().getName());
List<String> ids = new ArrayList<String>();
ids.addAll(this.idToObject.keySet());
Collections.sort(ids);
for (String id : ids) {
System.out.println(StringUtils.leftAlign(id, 40) + " : " + idToObject.get(id));
}
System.out.println(ids.size() + " identifiers found");
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/element/GroupSQLComponent.java
New file
0,0 → 1,188
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.sql.element;
 
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
 
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLType;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.Tuple3;
 
public class GroupSQLComponent extends BaseSQLComponent {
 
private Group group;
private int columns = 2;
private boolean forceViewOnly = true;
 
public GroupSQLComponent(SQLElement element, Group group) {
super(element);
this.group = group;
 
}
 
@Override
protected void addViews() {
group.dumpOneColumn();
this.setLayout(new GridBagLayout());
group.sort();
GridBagConstraints c = new DefaultGridBagConstraints();
layout(group, 0, LayoutHints.DEFAULT_GROUP_HINTS, 0, 0, c);
}
 
public int layout(Group currentGroup, Integer order, LayoutHints size, int x, int level, GridBagConstraints c) {
if (currentGroup.isEmpty()) {
System.out.print(" (" + x + ")");
String id = currentGroup.getId();
System.out.print(order + " " + id + "[" + size + "]");
c.gridwidth = 1;
if (size.showLabel()) {
c.weightx = 0;
// Label
if (size.separatedLabel()) {
c.gridx = 0;
c.gridwidth = 4;
c.fill = GridBagConstraints.NONE;
} else {
c.fill = GridBagConstraints.HORIZONTAL;
}
this.add(getLabel(id), c);
if (size.separatedLabel()) {
c.gridy++;
} else {
c.gridx++;
}
}
// Editor
c.weightx = 1;
if (size.maximizeWidth() && size.maximizeHeight()) {
c.fill = GridBagConstraints.BOTH;
} else if (size.maximizeWidth()) {
c.fill = GridBagConstraints.HORIZONTAL;
} else if (size.maximizeHeight()) {
c.fill = GridBagConstraints.VERTICAL;
} else {
c.fill = GridBagConstraints.NONE;
}
if (size.fill()) {
c.weighty = 1;
c.gridwidth = columns * 2;
}
 
this.add(getEditor(id), c);
c.weighty = 0;
c.gridx++;
if ((x % columns) != 0) {
c.gridx = 0;
c.gridy++;
}
}
 
final int stop = currentGroup.getSize();
for (int i = 0; i < stop; i++) {
final Group subGroup = currentGroup.getGroup(i);
final Integer subGroupOrder = currentGroup.getOrder(i);
final LayoutHints subGroupSize = currentGroup.getLayoutHints(i);
x = layout(subGroup, subGroupOrder, subGroupSize, x, level + 1, c);
 
}
 
if (currentGroup.isEmpty()) {
x++;
} else {
if (size.maximizeWidth()) {
c.gridx = 0;
c.gridy++;
}
}
 
return x;
}
 
JComponent getEditor(String id) {
if (id.startsWith("(") && id.endsWith(")*")) {
 
try {
String table = id.substring(1, id.length() - 2).trim();
String idEditor = ElementMapper.getInstance().getIds(table).get(0) + ".editor";
System.out.println("Editor: " + idEditor);
Class cl = (Class) ElementMapper.getInstance().get(idEditor);
return (JComponent) cl.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
 
}
 
SQLField field = this.getTable().getFieldRaw(id);
if (field == null) {
final JLabel jLabel = new JLabelBold("No field " + id);
jLabel.setForeground(Color.RED.darker());
String t = "<html>";
 
final Set<SQLField> fields = this.getTable().getFields();
 
for (SQLField sqlField : fields) {
t += sqlField.getFullName() + "<br>";
}
t += "</html>";
jLabel.setToolTipText(t);
return jLabel;
}
// if (/* this.getMode().equals(Mode.VIEW) || */forceViewOnly) {
// final JLabel jLabel = new JLabel();
// jLabel.setForeground(Color.gray);
// return jLabel;
// }
 
Tuple2<JComponent, SQLType> r = getComp(id);
final JComponent editorComp = r.get0();
if (editorComp != null) {
this.addView(editorComp, id);
return editorComp;
}
 
return new JButton(id);
}
 
JLabel getLabel(String id) {
final String fieldLabel = super.getLabelFor(id);
JLabel jLabel;
if (fieldLabel == null) {
jLabel = new JLabel(id);
jLabel.setForeground(Color.RED.darker());
 
} else {
jLabel = new JLabel(fieldLabel);
}
jLabel.setHorizontalAlignment(SwingConstants.RIGHT);
return jLabel;
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/element/RowBacked.java
21,7 → 21,6
import org.openconcerto.sql.model.SQLTable;
 
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
 
import org.apache.commons.collections.Transformer;
35,6 → 34,7
 
protected static abstract class PropExtractor implements Transformer {
 
@Override
public final Object transform(Object input) {
return this.extract((SQLRowAccessor) input);
}
51,9 → 51,7
this.propExtractors = new HashMap<String, PropExtractor>();
this.values = new HashMap<String, Object>();
 
final Iterator iter = PolymorphFK.findPolymorphFK(this.getTable()).iterator();
while (iter.hasNext()) {
final PolymorphFK f = (PolymorphFK) iter.next();
for (final PolymorphFK f : PolymorphFK.findPolymorphFK(this.getTable())) {
this.addPolymorphFK(f);
}
}
110,6 → 108,7
 
protected final void addPolymorphFK(final PolymorphFK fk) {
this.putExtractor(fk.getName(), new PropExtractor() {
@Override
public Object extract(SQLRowAccessor r) {
final String tableName = r.getString(fk.getTableField().getName());
final SQLTable foreignT = tableName == null ? null : r.getTable().getBase().getTable(tableName);
/trunk/OpenConcerto/src/org/openconcerto/sql/element/DefaultElementSQLObject.java
35,6 → 35,7
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
 
/**
* A default ElementSQLObject that displays a button to create, and when created a button to delete
61,6 → 62,7
super(parent, comp);
 
this.addValidListener(new ValidListener() {
@Override
public void validChange(ValidObject src, ValidState newValue) {
compChanged();
}
69,24 → 71,29
 
public void showSeparator(boolean visible) {
this.isSeparatorVisible = visible;
if (separator != null)
if (this.separator != null)
this.separator.setVisible(visible);
}
 
public void setDecorated(boolean decorated) {
this.isDecorated = decorated;
if (expandBtn != null)
if (this.expandBtn != null)
this.expandBtn.setVisible(decorated);
if (supprBtn != null)
if (this.supprBtn != null)
this.supprBtn.setVisible(decorated);
if (createBtn != null)
if (this.createBtn != null)
this.createBtn.setVisible(decorated);
}
 
@Override
protected void uiInit() {
final boolean isPlastic = UIManager.getLookAndFeel().getClass().getName().startsWith("com.jgoodies.plaf.plastic");
 
this.expandBtn = new JButton("+/-");
this.expandBtn.setEnabled(false);
this.expandBtn.setOpaque(false);
this.expandBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
toggleExpand();
}
95,8 → 102,10
this.supprBtn = new JButton(new ImageIcon(this.getClass().getResource("delete.png")));
this.supprBtn.setToolTipText("Supprimer");
this.supprBtn.setOpaque(false);
if (isPlastic)
this.supprBtn.setBorder(null);
this.supprBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0 || this.confirm())
setCreated(false);
107,7 → 116,10
}
});
this.createBtn = new JButton("Créer " + this.getSQLChild().getElement().getSingularName());
// false leaves only a line for the button under Plastic3DLookAndFeel
this.createBtn.setOpaque(isPlastic);
this.createBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setCreated(true);
}
116,6 → 128,7
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
}
 
@Override
protected final void setCreatePanel() {
if (this.editP != null)
this.editP.setVisible(false);
138,6 → 151,7
return this.createP;
}
 
@Override
protected final void setEditPanel() {
this.supprBtn.setVisible(!this.required && this.isDecorated);
if (this.createP != null)
195,6 → 209,7
return this.editP;
}
 
@Override
protected void compChanged() {
this.expandBtn.setEnabled(this.getCurrentID() != SQLRow.NONEXISTANT_ID && this.getValidState().isValid());
}
219,6 → 234,7
this.expand(!this.isExpanded());
}
 
@Override
public void setEditable(boolean enabled) {
super.setEditable(enabled);
this.createBtn.setEnabled(enabled);
/trunk/OpenConcerto/src/org/openconcerto/sql/element/SQLElement.java
118,6 → 118,7
private SQLCache<SQLRowAccessor, Object> modelCache;
 
private final Map<String, JComponent> additionalFields;
private final List<SQLTableModelColumn> additionalListCols;
 
public SQLElement(String singular, String plural, SQLTable primaryTable) {
super();
136,6 → 137,7
this.modelCache = null;
 
this.additionalFields = new HashMap<String, JComponent>();
this.additionalListCols = new ArrayList<SQLTableModelColumn>();
}
 
/**
331,6 → 333,15
}
 
/**
* Fields that cannot be empty.
*
* @return fields that cannot be empty.
*/
public Set<String> getRequiredFields() {
return Collections.emptySet();
}
 
/**
* Fields that can only be set on insertion.
*
* @return fields that cannot be modified.
759,7 → 770,8
// shared must be RESTRICT, parent at least CASCADE (to avoid child without a parent),
// normal is free
if (action.compareTo(ReferenceAction.RESTRICT) < 0 && !this.getNormalForeignFields().contains(ff))
throw new IllegalArgumentException(ff + " is not normal: " + this.getNormalForeignFields());
// getField() checks if the field exists
throw new IllegalArgumentException(getTable().getField(ff).getSQLName() + " is not a normal foreign field : " + this.getNormalForeignFields());
this.getActions().put(ff, action);
}
 
877,6 → 889,7
 
private final SQLTableModelSourceOnline createAndInitTableSource() {
final SQLTableModelSourceOnline res = this.createTableSource();
res.getColumns().addAll(this.additionalListCols);
return initTableSource(res);
}
 
915,6 → 928,15
 
abstract protected List<String> getListFields();
 
public final void addListFields(final List<String> fields) {
for (final String f : fields)
this.addListColumn(new SQLTableModelColumnPath(getTable().getField(f)));
}
 
public final void addListColumn(SQLTableModelColumn col) {
this.additionalListCols.add(col);
}
 
public final Collection<IListeAction> getRowActions() {
return this.rowActions;
}
1365,7 → 1387,8
 
public final int hashCode() {
// ne pas mettre getParent car des fois null
return this.getTable().hashCode() + this.getSharedForeignFields().hashCode() + this.getPrivateForeignFields().hashCode();
return this.getTable().hashCode(); // + this.getSharedForeignFields().hashCode() +
// this.getPrivateForeignFields().hashCode();
}
 
@Override
/trunk/OpenConcerto/src/org/openconcerto/sql/navigator/RowsSQLListModel.java
13,17 → 13,17
/*
* Créé le 21 mai 2005
*
*/
package org.openconcerto.sql.navigator;
 
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.IResultSetHandler;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.model.Where;
 
import java.util.List;
31,7 → 31,7
 
import org.apache.commons.dbutils.ResultSetHandler;
 
public class RowsSQLListModel extends SQLListModel<SQLRow> implements SQLTableListener {
public class RowsSQLListModel extends SQLListModel<SQLRow> implements SQLTableModifiedListener {
 
private final SQLElement element;
private final ResultSetHandler handler;
40,11 → 40,11
super();
this.element = element;
this.handler = new SQLRowListRSH(this.getElement().getTable(), true);
this.getElement().getTable().addTableListener(this);
this.getElement().getTable().addTableModifiedListener(this);
}
 
@SuppressWarnings("unchecked")
protected void reload() {
@Override
protected void reload(final boolean noCache) {
final Set<Number> ids = getIds();
final String key = this.getElement().getParentForeignField();
 
60,9 → 60,21
 
// cannot just use a SwingWorker, cause some methods (like SQLBrowser#selectPath())
// expect reload() to by synchronous.
this.setAll((List<SQLRow>) source.execute(sel.asString(), this.handler));
@SuppressWarnings("unchecked")
final List<SQLRow> rows = (List<SQLRow>) source.execute(sel.asString(), new IResultSetHandler(this.handler) {
@Override
public boolean readCache() {
return !noCache;
}
 
@Override
public boolean writeCache() {
return true;
}
});
this.setAll(rows);
}
 
/**
* Search the row with the passed <code>id</code> and return its index.
*
86,26 → 98,18
return this.element;
}
 
public void rowAdded(SQLTable table, int id) {
this.reload();
}
 
public void rowModified(SQLTable table, int id) {
@Override
public void tableModified(SQLTableEvent evt) {
// TODO test if that concern us
this.reload();
}
 
public void rowDeleted(SQLTable table, int id) {
// TODO test if that concern us
this.reload();
}
 
public String toString() {
return this.getClass().getName() + " on " + this.getElement();
}
 
protected void die() {
this.getElement().getTable().removeTableListener(this);
this.getElement().getTable().removeTableModifiedListener(this);
}
 
@Override
/trunk/OpenConcerto/src/org/openconcerto/sql/navigator/ElementsSQLListModel.java
44,7 → 44,8
this.elements = new ArrayList<SQLElement>(elements);
}
 
protected void reload() {
@Override
protected void reload(boolean noCache) {
this.counts.clear();
final List<SQLElement> res = new ArrayList<SQLElement>(this.elements.size());
for (final SQLElement elem : this.elements) {
/trunk/OpenConcerto/src/org/openconcerto/sql/navigator/SQLListModel.java
74,8 → 74,12
// more efficient than reload())
}
 
protected abstract void reload();
protected final void reload() {
this.reload(false);
}
 
protected abstract void reload(final boolean noCache);
 
// *** items
 
public final int getSize() {
/trunk/OpenConcerto/src/org/openconcerto/sql/navigator/SQLBrowserColumn.java
22,6 → 22,7
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.ui.KeyLabel;
import org.openconcerto.ui.PopupMouseListener;
import org.openconcerto.ui.list.selection.ListSelectionState;
import org.openconcerto.utils.JImage;
import org.openconcerto.utils.cc.IPredicate;
53,6 → 54,7
import java.util.List;
import java.util.Set;
 
import javax.swing.AbstractAction;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListSelectionModel;
import javax.swing.Icon;
61,6 → 63,7
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
328,10 → 331,20
this.title.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
// On trie
if (e.getButton() == MouseEvent.BUTTON1) {
getModel().sort();
setTitleIcon();
}
}
});
final JPopupMenu menu = new JPopupMenu();
menu.add(new AbstractAction("Recharger") {
@Override
public void actionPerformed(ActionEvent e) {
getModel().reload(true);
}
});
this.title.addMouseListener(new PopupMouseListener(menu));
// this.normalPanel.setBackground(new Color(239, 235, 231));
 
headerPanel.add(this.title, c2);
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRow.java
400,10 → 400,12
}
}
 
@Override
public SQLRow getForeign(String fieldName) {
return this.getForeignRow(fieldName);
}
 
@Override
public boolean isForeignEmpty(String fieldName) {
final SQLRow foreignRow = this.getForeignRow(fieldName, SQLRowMode.NO_CHECK);
return foreignRow == null || foreignRow.isUndefined();
413,7 → 415,7
* Retourne la ligne sur laquelle pointe le champ passé. Elle peut être archivé ou indéfinie.
*
* @param field le nom de la clef externe.
* @return la ligne sur laquelle pointe le champ passé, jamais <code>null</code>.
* @return la ligne sur laquelle pointe le champ passé.
* @throws IllegalArgumentException si <code>field</code> n'est pas une clef étrangère de la
* table de cette ligne.
* @throws IllegalStateException si <code>field</code> contient l'ID d'une ligne inexistante.
949,7 → 951,8
return path.split(",");
}
 
public SQLTableListener createTableListener(SQLDataListener l) {
@Override
public SQLTableModifiedListener createTableListener(SQLDataListener l) {
return new SQLTableListenerData<SQLRow>(this, l);
}
 
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLData.java
15,7 → 15,7
 
public interface SQLData {
 
public SQLTableListener createTableListener(SQLDataListener l);
public SQLTableModifiedListener createTableListener(SQLDataListener l);
 
public SQLTable getTable();
}
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLTableListenerData.java
13,7 → 13,7
package org.openconcerto.sql.model;
 
final class SQLTableListenerData<R extends SQLRowAccessor> implements SQLTableListener {
final class SQLTableListenerData<R extends SQLRowAccessor> implements SQLTableModifiedListener {
 
private final R row;
private final SQLDataListener l;
23,19 → 23,11
this.l = l;
}
 
public void rowAdded(SQLTable table, int id) {
// if the row id was cached as non-existant, now it is
if (this.row.getID() == id)
this.l.dataChanged();
}
 
public void rowDeleted(SQLTable table, int id) {
@Override
public void tableModified(SQLTableEvent evt) {
final int id = evt.getId();
// if the row id was cached as non-existent and evt mode is ADDED, now it is
if (id < SQLRow.MIN_VALID_ID || this.row.getID() == id)
this.l.dataChanged();
}
 
public void rowModified(SQLTable table, int id) {
if (id < SQLRow.MIN_VALID_ID || this.row.getID() == id)
this.l.dataChanged();
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLType.java
17,6 → 17,7
package org.openconcerto.sql.model;
 
import org.openconcerto.utils.CompareUtils;
import org.openconcerto.xml.JDOMUtils;
 
import java.math.BigDecimal;
import java.math.BigInteger;
303,7 → 304,7
sb.append(this.decimalDigits);
}
sb.append("\" typeName=\"");
sb.append(this.typeName);
sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(this.typeName));
sb.append("\"/>");
this.xml = sb.toString();
}
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLField.java
21,6 → 21,7
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.CompareUtils;
import org.openconcerto.utils.ExceptionUtils;
import org.openconcerto.xml.JDOMUtils;
import org.openconcerto.xml.XMLCodecUtils;
 
import java.sql.DatabaseMetaData;
281,7 → 282,7
if (this.xml == null) {
final StringBuilder sb = new StringBuilder(2048);
sb.append("<field name=\"");
sb.append(this.getName());
sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(this.getName()));
sb.append("\" >");
sb.append(this.type.toXML());
sb.append(XMLCodecUtils.encodeSimple(this.metadata));
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowValuesListFetcher.java
454,6 → 454,29
}
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.fieldCount;
result = prime * result + ((this.from == null) ? 0 : this.from.hashCode());
result = prime * result + this.linkIndex;
result = prime * result + this.t.hashCode();
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final GraphNode other = (GraphNode) obj;
return this.fieldCount == other.fieldCount && this.linkIndex == other.linkIndex && this.t.equals(other.t) && CompareUtils.equals(this.from, other.from);
}
 
@Override
public String toString() {
final String link = this.from == null ? "" : " linked to " + getLinkIndex() + " by " + this.getFromName() + (this.isBackwards() ? " backwards" : " forewards");
return this.getFieldCount() + " fields of " + this.getTable() + link;
460,44 → 483,19
}
}
 
/**
* Execute the request transformed by <code>selTransf</code> and return the result as a list of
* SQLRowValues.
*
* @return a list of SQLRowValues, one item per row, each item having the same structure as the
* SQLRowValues passed to the constructor.
*/
public final List<SQLRowValues> fetch() {
return this.fetch(true);
}
static private final class RSH implements ResultSetHandler {
private final List<String> selectFields;
private final List<GraphNode> graphNodes;
 
private final List<SQLRowValues> fetch(final boolean merge) {
final SQLSelect req = this.getReq();
// getName() would take 5% of ResultSetHandler.handle()
final List<String> selectFields = new ArrayList<String>(req.getSelectFields().size());
for (final SQLField f : req.getSelectFields())
selectFields.add(f.getName());
final SQLTable table = getGraph().getTable();
 
// create a flat list of the graph nodes, we just need the table, field count and the index
// in this list of its linked table, eg for CPI -> LOCAL -> BATIMENT -> SITE :
// <LOCAL,2,0>, <BATIMENT,2,0>, <SITE,5,1>, <CPI,4,0>
final int graphSize = this.getGraph().getGraph().size();
final List<GraphNode> l = new ArrayList<GraphNode>(graphSize);
walk(0, new ITransformer<State<Integer>, Integer>() {
@Override
public Integer transformChecked(State<Integer> input) {
final int index = l.size();
l.add(new GraphNode(input));
return index;
private RSH(List<String> selectFields, List<GraphNode> l) {
this.selectFields = selectFields;
this.graphNodes = l;
}
});
assert l.size() == graphSize : "All nodes weren't explored once : " + l.size() + " != " + graphSize;
 
@SuppressWarnings("unchecked")
final List<SQLRowValues> res = (List<SQLRowValues>) table.getBase().getDataSource().execute(req.asString(), new ResultSetHandler() {
@Override
public Object handle(final ResultSet rs) throws SQLException {
final List<GraphNode> l = this.graphNodes;
final int graphSize = l.size();
int nextToLink = 0;
final List<Future<?>> futures = new ArrayList<Future<?>>();
 
510,7 → 508,7
 
// MAYBE cancel() futures
if (Thread.currentThread().isInterrupted())
throw new RTInterruptedException("interrupted while fetching " + SQLRowValuesListFetcher.this);
throw new RTInterruptedException("interrupted while fetching");
final List<SQLRowValues> row = new ArrayList<SQLRowValues>(graphSize);
for (int i = 0; i < graphSize; i++) {
final GraphNode node = l.get(i);
523,7 → 521,7
try {
// -1 since rs starts at 1
// field names checked below
creatingVals.put(selectFields.get(rsIndex - 1), rs.getObject(rsIndex), false);
creatingVals.put(this.selectFields.get(rsIndex - 1), rs.getObject(rsIndex), false);
} catch (SQLException e) {
throw new IllegalStateException("unable to fill " + creatingVals, e);
}
568,7 → 566,70
 
return res;
}
}, false);
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.graphNodes.hashCode();
result = prime * result + this.selectFields.hashCode();
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final RSH other = (RSH) obj;
return this.graphNodes.equals(other.graphNodes) && this.selectFields.equals(other.selectFields);
}
 
}
 
/**
* Execute the request transformed by <code>selTransf</code> and return the result as a list of
* SQLRowValues. NOTE: this method doesn't use the cache of SQLDataSource.
*
* @return a list of SQLRowValues, one item per row, each item having the same structure as the
* SQLRowValues passed to the constructor.
*/
public final List<SQLRowValues> fetch() {
return this.fetch(true);
}
 
private final List<SQLRowValues> fetch(final boolean merge) {
final SQLSelect req = this.getReq();
// getName() would take 5% of ResultSetHandler.handle()
final List<String> selectFields = new ArrayList<String>(req.getSelectFields().size());
for (final SQLField f : req.getSelectFields())
selectFields.add(f.getName());
final SQLTable table = getGraph().getTable();
 
// create a flat list of the graph nodes, we just need the table, field count and the index
// in this list of its linked table, eg for CPI -> LOCAL -> BATIMENT -> SITE :
// <LOCAL,2,0>, <BATIMENT,2,0>, <SITE,5,1>, <CPI,4,0>
final int graphSize = this.getGraph().getGraph().size();
final List<GraphNode> l = new ArrayList<GraphNode>(graphSize);
walk(0, new ITransformer<State<Integer>, Integer>() {
@Override
public Integer transformChecked(State<Integer> input) {
final int index = l.size();
l.add(new GraphNode(input));
return index;
}
});
assert l.size() == graphSize : "All nodes weren't explored once : " + l.size() + " != " + graphSize;
 
// if we wanted to use the cache, we'd need to copy the returned list and its items (i.e.
// deepCopy()), since we modify them afterwards. Or perhaps include the code after this line
// into the result set handler.
final IResultSetHandler rsh = new IResultSetHandler(new RSH(selectFields, l), false);
@SuppressWarnings("unchecked")
final List<SQLRowValues> res = (List<SQLRowValues>) table.getBase().getDataSource().execute(req.asString(), rsh, false);
// e.g. list of batiment pointing to site
final List<SQLRowValues> merged = merge && this.fetchReferents() ? merge(res) : res;
if (this.grafts.size() > 0) {
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLImmutableRowValues.java
80,10 → 80,6
return this.delegate.isForeignEmpty(fieldName);
}
 
public boolean isEmptyLink(String fieldName) {
return this.delegate.isEmptyLink(fieldName);
}
 
public boolean isDefault(String fieldName) {
return this.delegate.isDefault(fieldName);
}
116,7 → 112,7
}
 
@Override
public SQLTableListener createTableListener(SQLDataListener l) {
public SQLTableModifiedListener createTableListener(SQLDataListener l) {
return this.delegate.createTableListener(l);
}
 
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowValues.java
27,6 → 27,7
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.CopyUtils;
import org.openconcerto.utils.ExceptionUtils;
import org.openconcerto.utils.NumberUtils;
import org.openconcerto.utils.RecursionType;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.IClosure;
95,13 → 96,12
}
 
public static final Object SQL_DEFAULT = new Object();
// for now the default is put in the default value of the db
/**
* Empty foreign field value.
*
* @see #putEmptyLink(String)
*/
public static final Object SQL_EMPTY_LINK = SQL_DEFAULT;
public static final Object SQL_EMPTY_LINK = new Object();
 
private static boolean checkValidity = true;
 
167,26 → 167,8
*/
public SQLRowValues(SQLRowValues vals, ForeignCopyMode copyForeigns) {
this(vals.getTable());
final Map<String, Object> toAdd;
if (copyForeigns == ForeignCopyMode.COPY_ROW)
toAdd = vals.values;
else {
final Set<Entry<String, Object>> entrySet = vals.values.entrySet();
toAdd = new LinkedHashMap<String, Object>(entrySet.size());
for (final Map.Entry<String, Object> e : entrySet) {
if (!(e.getValue() instanceof SQLRowValues))
toAdd.put(e.getKey(), e.getValue());
else if (copyForeigns != ForeignCopyMode.NO_COPY) {
final SQLRowValues foreign = (SQLRowValues) e.getValue();
if (foreign.hasID())
toAdd.put(e.getKey(), foreign.getIDNumber());
else if (copyForeigns == ForeignCopyMode.COPY_ID_OR_ROW)
toAdd.put(e.getKey(), foreign);
}
}
}
// setAll() takes care of foreigns and referents
this.setAll(toAdd);
this.setAll(vals.getAllValues(copyForeigns));
}
 
@Override
272,7 → 254,9
* @return the foreign row, eg FAMILLE[1].
*/
public final SQLRowValues grow(String fk) {
if (!(this.getObject(fk) instanceof SQLRowValues)) {
final Object val = this.getContainedObject(fk);
// if fk is in our map with a null value, nothing to grow
if (val != null && !(val instanceof SQLRowValues)) {
final SQLRowValues vals = new SQLRowValues(this.getTable());
vals.putRowValues(fk).setAllToNull();
this.grow(vals, true);
402,16 → 386,53
 
@Override
public Map<String, Object> getAbsolutelyAll() {
return Collections.unmodifiableMap(this.values);
return getAllValues(ForeignCopyMode.COPY_ROW);
}
 
protected final Map<String, Object> getAllValues(ForeignCopyMode copyForeigns) {
final Map<String, Object> toAdd;
if (copyForeigns == ForeignCopyMode.COPY_ROW || this.foreigns.size() == 0) {
toAdd = this.values;
} else {
final Set<Entry<String, Object>> entrySet = this.values.entrySet();
toAdd = new LinkedHashMap<String, Object>(entrySet.size());
for (final Map.Entry<String, Object> e : entrySet) {
if (!(e.getValue() instanceof SQLRowValues)) {
toAdd.put(e.getKey(), e.getValue());
} else if (copyForeigns != ForeignCopyMode.NO_COPY) {
final SQLRowValues foreign = (SQLRowValues) e.getValue();
if (foreign.hasID())
toAdd.put(e.getKey(), foreign.getIDNumber());
else if (copyForeigns == ForeignCopyMode.COPY_ID_OR_ROW)
toAdd.put(e.getKey(), foreign);
}
}
}
return Collections.unmodifiableMap(toAdd);
}
 
/**
* Return the foreign row, if any, for the passed field.
*
* @param fieldName name of the foreign field.
* @return if <code>null</code> or a SQLRowValues one was put at <code>fieldName</code>, return
* it ; else assume that an ID was put at <code>fieldName</code> and return a new SQLRow
* with it.
* @throws IllegalArgumentException if fieldName is not a foreign field or if it isn't contained
* in this instance.
* @throws ClassCastException if the value is neither a SQLRowValues, nor <code>null</code> nor
* a Number.
*/
@Override
public final SQLRowAccessor getForeign(String fieldName) {
public final SQLRowAccessor getForeign(String fieldName) throws IllegalArgumentException, ClassCastException {
// keep getForeignTable at the 1st line since it does the check
final SQLTable foreignTable = this.getForeignTable(fieldName);
if (this.getObject(fieldName) instanceof SQLRowAccessor) {
return (SQLRowAccessor) this.getObject(fieldName);
} else if (this.isEmptyLink(fieldName)) {
final Object val = this.getContainedObject(fieldName);
if (val instanceof SQLRowAccessor) {
return (SQLRowAccessor) val;
} else if (val == null) {
// since we used getContainedObject(), it means that a null was put in our map, not that
// fieldName wasn't there
return null;
} else if (this.isDefault(fieldName)) {
throw new IllegalStateException(fieldName + " is DEFAULT");
420,6 → 441,12
}
}
 
private Object getContainedObject(String fieldName) throws IllegalArgumentException {
if (!this.values.containsKey(fieldName))
throw new IllegalArgumentException("Field not present in this : " + this.getFields());
return this.values.get(fieldName);
}
 
/**
* Returns the foreign table of <i>fieldName</i>.
*
439,18 → 466,12
public boolean isForeignEmpty(String fieldName) {
// keep getForeignTable at the 1st line since it does the check
final SQLTable foreignTable = this.getForeignTable(fieldName);
if (this.getObject(fieldName) instanceof Number) {
return this.getInt(fieldName) == foreignTable.getUndefinedID();
} else if (this.getObject(fieldName) instanceof SQLRowValues) {
return ((SQLRowValues) this.getObject(fieldName)).getID() == foreignTable.getUndefinedID();
} else
return this.getObject(fieldName) == null || this.isEmptyLink(fieldName);
final Object val = this.getContainedObject(fieldName);
final Number id = val instanceof SQLRowValues ? ((SQLRowValues) val).getIDNumber() : (Number) val;
final Number undefID = foreignTable.getUndefinedIDNumber();
return NumberUtils.areNumericallyEqual(id, undefID);
}
 
public boolean isEmptyLink(String fieldName) {
return SQL_EMPTY_LINK.equals(this.getObject(fieldName));
}
 
public boolean isDefault(String fieldName) {
return SQL_DEFAULT.equals(this.getObject(fieldName));
}
478,7 → 499,7
public final SQLRow asRow() {
if (!this.hasID())
throw new IllegalStateException(this + " has no ID");
return new SQLRow(this.getTable(), this.values);
return new SQLRow(this.getTable(), this.getAllValues(ForeignCopyMode.COPY_ID_OR_RM));
}
 
@Override
588,6 → 609,9
}
 
private void _put(String fieldName, Object value) {
if (value == SQL_EMPTY_LINK)
// keep getForeignTable since it does the check
value = this.getForeignTable(fieldName).getUndefinedIDNumber();
// use assertion since check() is not perfect
assert check(fieldName, value);
this.updateLinks(fieldName, this.values.put(fieldName, value), value);
635,8 → 659,6
* @return this.
*/
public SQLRowValues putEmptyLink(String fieldName) {
// keep getForeignTable at the 1st line since it does the check
this.getForeignTable(fieldName);
return this.put(fieldName, SQL_EMPTY_LINK);
}
 
1009,7 → 1031,7
// verifie l'intégrité (a rowValues is obviously correct, as is EMPTY,
// DEFAULT is the responsability of the DB)
final Object fieldVal = this.getObject(fieldName);
if (fk.contains(field) && fieldVal != SQL_DEFAULT && fieldVal != SQL_EMPTY_LINK && !(fieldVal instanceof SQLRowValues)) {
if (fk.contains(field) && fieldVal != SQL_DEFAULT && !(fieldVal instanceof SQLRowValues)) {
final SQLRow pb = this.getTable().checkValidity(field.getName(), (Number) fieldVal);
if (pb != null)
return new Object[] { fieldName, pb };
1371,7 → 1393,7
final Object toIns;
if (value instanceof SQLRowValues) {
// TODO if we already point to some row, archive it
toIns = new Integer(((SQLRowValues) value).insert().getID());
toIns = ((SQLRowValues) value).insert().getIDNumber();
} else
toIns = value;
// sql index start at 1
1390,7 → 1412,8
return value == SQL_DEFAULT ? "DEFAULT" : "?";
}
 
public SQLTableListener createTableListener(SQLDataListener l) {
@Override
public SQLTableModifiedListener createTableListener(SQLDataListener l) {
return new SQLTableListenerData<SQLRowValues>(this, l);
}
 
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowValuesCluster.java
836,6 → 836,7
public Link(final SQLRowValues src, final SQLField f, final SQLRowValues dest) {
if (src == null)
throw new NullPointerException("src is null");
assert (f == null && dest == null) || (dest != null && f.getTable() == src.getTable());
this.src = src;
this.f = f;
this.dest = dest;
857,8 → 858,8
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.src.hashCode();
result = prime * result + ((this.dest == null) ? 0 : this.dest.hashCode());
result = prime * result + System.identityHashCode(this.src);
result = prime * result + System.identityHashCode(this.dest);
result = prime * result + ((this.f == null) ? 0 : this.f.hashCode());
return result;
}
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowAccessor.java
167,6 → 167,14
return res;
}
 
/**
* Return the foreign row, if any, for the passed field.
*
* @param fieldName name of the foreign field.
* @return <code>null</code> if the value of <code>fieldName</code> is <code>null</code>,
* otherwise a SQLRowAccessor with the value of <code>fieldName</code> as its ID.
* @throws IllegalArgumentException if fieldName is not a foreign field.
*/
public abstract SQLRowAccessor getForeign(String fieldName);
 
public abstract boolean isForeignEmpty(String fieldName);
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowValuesMap.java
New file
0,0 → 1,72
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.sql.model;
 
import org.openconcerto.utils.cc.IPredicate;
import org.openconcerto.utils.checks.EmptyObjFromVO;
 
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
 
/**
* Store inserted rows. This class allows to avoid having huge, slow {@link SQLRowValuesCluster} by
* replacing a foreign link with its ID.
*
* @author Sylvain CUAZ
* @param <T> type of source object.
*/
public abstract class SQLRowValuesMap<T> {
 
private final SQLTable t;
private final Map<SQLRowValues, SQLRow> map;
private final IPredicate<? super T> emptyPredicate;
 
public SQLRowValuesMap(final SQLTable t) {
this(t, EmptyObjFromVO.getDefaultPredicate());
}
 
public SQLRowValuesMap(final SQLTable t, final IPredicate<? super T> emptyPredicate) {
this.t = t;
this.map = new HashMap<SQLRowValues, SQLRow>();
this.emptyPredicate = emptyPredicate;
}
 
protected abstract void fill(final SQLRowValues vals, T obj);
 
/**
* Return a non SQLRowValues value, thus avoiding linking two graphs together. If
* <code>obj</code> is empty, returns {@link SQLRowValues#SQL_EMPTY_LINK}, else calls
* {@link #fill(SQLRowValues, Object)} and if these values haven't already been inserted, insert
* them, finally return the ID.
*
* @param obj the source object.
* @return the ID or SQL_EMPTY_LINK.
* @throws SQLException if an error occurs while inserting.
*/
public final Object getValue(final T obj) throws SQLException {
if (this.emptyPredicate.evaluateChecked(obj)) {
return SQLRowValues.SQL_EMPTY_LINK;
} else {
final SQLRowValues key = new SQLRowValues(this.t);
this.fill(key, obj);
SQLRow res = this.map.get(key);
if (res == null) {
res = key.insert();
this.map.put(key, res);
}
return res.getIDNumber();
}
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLTable.java
26,6 → 26,7
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.CompareUtils;
import org.openconcerto.utils.ExceptionUtils;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.IPredicate;
import org.openconcerto.utils.change.CollectionChangeEventCreator;
import org.openconcerto.xml.JDOMUtils;
42,6 → 43,7
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
172,9 → 174,6
// always immutable so that fire can iterate safely ; to modify it, simply copy it before
// (adding listeners is a lot less common than firing events)
private List<SQLTableModifiedListener> tableModifiedListeners;
private final List<SQLTableListener> listeners;
// copy of listeners while dispatching, so that a listener can modify it
private final List<SQLTableListener> dispatchingListeners;
// the id that foreign keys pointing to this, can use instead of NULL
// a null value meaning not yet known
private Integer undefinedID;
186,8 → 185,6
SQLTable(SQLSchema schema, String name) {
super(schema, name);
this.tableModifiedListeners = Collections.emptyList();
this.listeners = new ArrayList<SQLTableListener>();
this.dispatchingListeners = new ArrayList<SQLTableListener>();
// ne pas se soucier de la casse
this.fields = createMap();
// order matters (eg for indexes)
971,15 → 968,27
*/
 
public void addTableModifiedListener(SQLTableModifiedListener l) {
synchronized (this.listeners) {
final List<SQLTableModifiedListener> newListeners = new ArrayList<SQLTableModifiedListener>(this.tableModifiedListeners);
this.addTableModifiedListener(l, false);
}
 
public void addPremierTableModifiedListener(SQLTableModifiedListener l) {
this.addTableModifiedListener(l, true);
}
 
private void addTableModifiedListener(SQLTableModifiedListener l, final boolean before) {
synchronized (this) {
final List<SQLTableModifiedListener> newListeners = new ArrayList<SQLTableModifiedListener>(this.tableModifiedListeners.size() + 1);
if (before)
newListeners.add(l);
newListeners.addAll(this.tableModifiedListeners);
if (!before)
newListeners.add(l);
this.tableModifiedListeners = Collections.unmodifiableList(newListeners);
}
}
 
public void removeTableModifiedListener(SQLTableModifiedListener l) {
synchronized (this.listeners) {
synchronized (this) {
final List<SQLTableModifiedListener> newListeners = new ArrayList<SQLTableModifiedListener>(this.tableModifiedListeners);
if (newListeners.remove(l))
this.tableModifiedListeners = Collections.unmodifiableList(newListeners);
986,6 → 995,37
}
}
 
private static final class BridgeListener implements SQLTableModifiedListener {
 
private final SQLTableListener l;
 
private BridgeListener(SQLTableListener l) {
super();
this.l = l;
}
 
@Override
public void tableModified(SQLTableEvent evt) {
final Mode mode = evt.getMode();
if (mode == Mode.ROW_ADDED)
this.l.rowAdded(evt.getTable(), evt.getId());
else if (mode == Mode.ROW_UPDATED)
this.l.rowModified(evt.getTable(), evt.getId());
else if (mode == Mode.ROW_DELETED)
this.l.rowDeleted(evt.getTable(), evt.getId());
}
 
@Override
public int hashCode() {
return this.l.hashCode();
}
 
@Override
public boolean equals(Object obj) {
return obj instanceof BridgeListener && this.l.equals(((BridgeListener) obj).l);
}
}
 
/**
* Ajoute un listener sur cette table.
*
993,32 → 1033,13
* @deprecated use {@link #addTableModifiedListener(SQLTableModifiedListener)}
*/
public void addTableListener(SQLTableListener l) {
synchronized (this.listeners) {
if (!this.listeners.contains(l)) {
this.listeners.add(l);
} else
Log.get().fine(l + " already in");
this.addTableModifiedListener(new BridgeListener(l));
}
}
 
public void addPremierTableListener(SQLTableListener l) {
synchronized (this.listeners) {
if (!this.listeners.contains(l)) {
this.listeners.add(0, l);
} else
throw new IllegalStateException(l + " is already listener of " + this);
}
}
 
public void removeTableListener(SQLTableListener l) {
synchronized (this.listeners) {
this.listeners.remove(l);
this.removeTableModifiedListener(new BridgeListener(l));
}
}
 
private static final int NOT_DISPATCHING = -2;
private int dispatchingID = NOT_DISPATCHING;
 
/**
* Previent tous les listeners de la table qu'il y a eu une modification ou ajout si modif de
* d'une ligne particuliere.
1046,61 → 1067,55
}
 
public final void fire(SQLTableEvent evt) {
final int id = evt.getId();
synchronized (this.dispatchingListeners) {
// FIXME peut laisser tomber des changements si un notifié rechange la même ligne
if (this.dispatchingID != id) {
this.dispatchingID = id;
final Mode mode = evt.getMode();
this.dispatchingListeners.clear();
synchronized (this.listeners) {
this.dispatchingListeners.addAll(this.listeners);
this.fireTableModified(evt);
}
final int size = this.dispatchingListeners.size();
for (int i = 0; i < size; i++) {
final SQLTableListener obj = this.dispatchingListeners.get(i);
if (mode == Mode.ROW_UPDATED)
obj.rowModified(this, id);
else if (mode == Mode.ROW_ADDED)
obj.rowAdded(this, id);
else if (mode == Mode.ROW_DELETED)
obj.rowDeleted(this, id);
else
throw new IllegalArgumentException("unknown mode: " + mode);
 
static private final ThreadLocal<LinkedList<Tuple2<Iterator<SQLTableModifiedListener>, SQLTableEvent>>> events = new ThreadLocal<LinkedList<Tuple2<Iterator<SQLTableModifiedListener>, SQLTableEvent>>>() {
@Override
protected LinkedList<Tuple2<Iterator<SQLTableModifiedListener>, SQLTableEvent>> initialValue() {
return new LinkedList<Tuple2<Iterator<SQLTableModifiedListener>, SQLTableEvent>>();
}
this.fireTableModified(evt);
this.dispatchingID = NOT_DISPATCHING;
} else {
System.err.println("dropping a SQLTable.fire() : fired in the listener");
Thread.dumpStack();
};
 
// allow to maintain the dispatching of events in order when a listener itself fires an event
static private void fireTableModified(Tuple2<Iterator<SQLTableModifiedListener>, SQLTableEvent> newTuple) {
final LinkedList<Tuple2<Iterator<SQLTableModifiedListener>, SQLTableEvent>> linkedList = events.get();
// add new event
linkedList.addLast(newTuple);
// process all pending events
Tuple2<Iterator<SQLTableModifiedListener>, SQLTableEvent> currentTuple;
while ((currentTuple = linkedList.peekFirst()) != null) {
final Iterator<SQLTableModifiedListener> iter = currentTuple.get0();
final SQLTableEvent currentEvt = currentTuple.get1();
while (iter.hasNext()) {
final SQLTableModifiedListener l = iter.next();
l.tableModified(currentEvt);
}
// not removeFirst() since the item might have been already removed
linkedList.pollFirst();
}
}
 
private void fireTableModified(final SQLTableEvent evt) {
// no need to copy since this.tableModifiedListeners is immutable
final List<SQLTableModifiedListener> dispatchingListeners;
synchronized (this.listeners) {
synchronized (this) {
dispatchingListeners = this.tableModifiedListeners;
}
// no need to synchronize since dispatchingListeners is immutable
// even better, it also works if the same thread calls fireTableModified() in a callback
// (although in that case some listeners might have events in the wrong order)
for (final SQLTableModifiedListener l : dispatchingListeners) {
l.tableModified(evt);
fireTableModified(Tuple2.create(dispatchingListeners.iterator(), evt));
}
}
 
@SuppressWarnings("unchecked")
public String toXML() {
final StringBuilder sb = new StringBuilder(16000);
sb.append("<table name=\"");
sb.append(this.getName());
sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(this.getName()));
sb.append("\"");
 
final String schemaName = this.getSchema().getName();
if (schemaName != null) {
sb.append(" schema=\"");
sb.append(schemaName);
sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(schemaName));
sb.append('"');
}
 
1114,7 → 1129,7
 
if (getType() != null) {
sb.append(" type=\"");
sb.append(getType());
sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(getType()));
sb.append('"');
}
 
1152,21 → 1167,13
return sb.toString();
}
 
public SQLTableListener createTableListener(final SQLDataListener l) {
return new SQLTableListener() {
 
public void rowModified(SQLTable table, int id) {
@Override
public SQLTableModifiedListener createTableListener(final SQLDataListener l) {
return new SQLTableModifiedListener() {
@Override
public void tableModified(SQLTableEvent evt) {
l.dataChanged();
}
 
public void rowAdded(SQLTable table, int id) {
l.dataChanged();
}
 
public void rowDeleted(SQLTable table, int id) {
l.dataChanged();
}
 
};
}
 
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLSchema.java
53,7 → 53,7
sb.append(' ');
sb.append(VERSION_XMLATTR);
sb.append("=\"");
sb.append(version);
sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(version));
sb.append('"');
} catch (IOException e) {
throw new IllegalStateException("Couldn't append version of " + schema, e);
218,7 → 218,7
sb.append("<schema ");
if (this.getName() != null) {
sb.append(" name=\"");
sb.append(this.getName());
sb.append(JDOMUtils.OUTPUTTER.escapeAttributeEntities(this.getName()));
sb.append('"');
}
getVersionAttr(this, sb);
/trunk/OpenConcerto/src/org/openconcerto/sql/users/rights/UserRightsManagerModel.java
19,7 → 19,9
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableEvent.Mode;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.model.Where;
 
import java.sql.SQLException;
55,26 → 57,17
List<SQLRow> rowsRights = (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel2.asString(), new SQLRowListRSH(this.tableRight, true));
this.cache.addAll(rowsRights);
 
this.tableRight.addTableListener(new SQLTableListener() {
this.tableRight.addTableModifiedListener(new SQLTableModifiedListener() {
@Override
public void rowAdded(SQLTable table, int id) {
 
UserRightsManagerModel.this.cache.add(table.getRow(id));
}
 
@Override
public void rowDeleted(SQLTable table, int id) {
 
}
 
@Override
public void rowModified(SQLTable table, int id) {
SQLRow row = table.getRow(id);
 
public void tableModified(SQLTableEvent evt) {
if (evt.getMode() == Mode.ROW_ADDED) {
UserRightsManagerModel.this.cache.add(evt.getRow());
} else {
final SQLRow row = evt.getRow();
for (int i = 0; i < UserRightsManagerModel.this.cache.size(); i++) {
SQLRow row2 = UserRightsManagerModel.this.cache.get(i);
if (row2.getID() == id) {
if (row.isArchived()) {
final SQLRow row2 = UserRightsManagerModel.this.cache.get(i);
if (row2.getID() == row.getID()) {
if (!row.isValid()) {
UserRightsManagerModel.this.cache.remove(i);
} else {
UserRightsManagerModel.this.cache.set(i, row2);
83,15 → 76,24
}
}
}
}
});
 
this.tableUserRight.addTableListener(new SQLTableListener() {
this.tableUserRight.addTableModifiedListener(new SQLTableModifiedListener() {
 
@Override
public void rowAdded(SQLTable table, int id) {
public void tableModified(SQLTableEvent evt) {
if (evt.getMode() == Mode.ROW_ADDED) {
rowAdded(evt);
} else {
rowModified(evt);
}
}
 
SQLRow row = table.getRow(id);
public void rowAdded(SQLTableEvent evt) {
final SQLRow row = evt.getRow();
if (row.getInt("ID_USER_COMMON") == UserRightsManagerModel.this.idUser) {
SQLRowValues rowVals = getSQLRowValuesForID(id);
SQLRowValues rowVals = getSQLRowValuesFor(row);
if (rowVals == null) {
UserRightsManagerModel.this.listRowValues.add(row.createUpdateRow());
fireTableRowsInserted(UserRightsManagerModel.this.listRowValues.size() - 2, UserRightsManagerModel.this.listRowValues.size() - 1);
99,17 → 101,12
}
}
 
@Override
public void rowDeleted(SQLTable table, int id) {
}
 
@Override
public void rowModified(SQLTable table, int id) {
SQLRow row = table.getRow(id);
public void rowModified(SQLTableEvent evt) {
final SQLRow row = evt.getRow();
if (row.getInt("ID_USER_COMMON") == UserRightsManagerModel.this.idUser) {
SQLRowValues rowVals = getSQLRowValuesForID(id);
SQLRowValues rowVals = getSQLRowValuesFor(row);
int index = UserRightsManagerModel.this.listRowValues.indexOf(rowVals);
if (row.isArchived()) {
if (!row.isValid()) {
UserRightsManagerModel.this.listRowValues.removeElement(rowVals);
fireTableRowsDeleted(index - 1, index + 1);
} else {
121,12 → 118,11
});
}
 
private SQLRowValues getSQLRowValuesForID(int id) {
SQLRow row = this.tableUserRight.getRow(id);
private SQLRowValues getSQLRowValuesFor(final SQLRow row) {
final String string2 = row.getString("CODE");
for (SQLRowValues rowVals : this.listRowValues) {
final String string = rowVals.getString("CODE");
if (rowVals.getID() == id || (string != null && string2 != null && string.equalsIgnoreCase(string2))) {
if (rowVals.getID() == row.getID() || (string != null && string2 != null && string.equalsIgnoreCase(string2))) {
return rowVals;
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/changer/correct/FixSharedPrivate.java
17,11 → 17,14
import org.openconcerto.sql.changer.Changer;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.DBSystemRoot;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLSelect.ArchiveMode;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.model.SQLSelect.ArchiveMode;
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.sql.utils.SQLUtils.SQLFactory;
 
41,7 → 44,7
super(b);
}
 
@SuppressWarnings("unchecked")
@Override
protected void changeImpl(final SQLTable t) throws SQLException {
getStream().println(t + "... ");
if (Configuration.getInstance() == null || Configuration.getInstance().getDirectory() == null)
65,9 → 68,14
sel.addBackwardJoin("INNER", "m", t.getField(pff), null);
final String req = sel.asString() + " GROUP BY " + privateTable.getKey().getFieldRef() + " HAVING count(" + privateTable.getKey().getFieldRef() + ")>1";
 
@SuppressWarnings("unchecked")
final List<Number> privateIDs = t.getDBSystemRoot().getDataSource().executeCol(req);
if (privateIDs.size() > 0) {
getStream().println("\t" + pff + " fixing " + privateIDs.size() + " ... ");
final SQLField archF = t.getArchiveField();
final SQLField privateArchF = privateTable.getArchiveField();
if ((archF == null) != (privateArchF == null))
throw new IllegalStateException("Incoherent archive field : " + archF + " / " + privateArchF);
SQLUtils.executeAtomic(t.getDBSystemRoot().getDataSource(), new SQLFactory<Object>() {
@Override
public Object create() throws SQLException {
76,11 → 84,21
final SQLSelect fixSel = new SQLSelect(t.getBase());
fixSel.setArchivedPolicy(ArchiveMode.BOTH);
fixSel.addSelect(t.getKey());
if (archF != null)
fixSel.addSelect(archF);
fixSel.setWhere(new Where(t.getField(pff), "=", privateID));
final List<Number> tIDs = t.getDBSystemRoot().getDataSource().executeCol(fixSel.asString());
final List<SQLRow> tIDs = SQLRowListRSH.execute(fixSel);
for (final SQLRow tID : tIDs) {
// the first one can keep its private
for (final Number tID : tIDs.subList(1, tIDs.size())) {
new SQLRowValues(t).setID(tID).put(pff, privateElement.createCopy(privateID.intValue())).update();
final SQLRowValues reallyPrivate;
if (tID == tIDs.get(0))
reallyPrivate = new SQLRowValues(privateElement.getTable()).setID(privateID);
else
reallyPrivate = privateElement.createCopy(privateID.intValue());
// keep archive coherence
if (archF != null)
reallyPrivate.put(privateArchF.getName(), tID.getObject(archF.getName()));
new SQLRowValues(t).setID(tID.getIDNumber()).put(pff, reallyPrivate).update();
}
}
return null;
/trunk/OpenConcerto/src/org/openconcerto/sql/view/EditFrame.java
40,6 → 40,11
 
public static final EditMode MODIFICATION = EditPanel.MODIFICATION;
public static final EditMode CREATION = EditPanel.CREATION;
/**
* If this system property is true, then the minimum size of an edit frame will match the one
* from its content pane.
*/
public final static String SMALL_MIN_SIZE = "org.openconcerto.sql.editFrame.smallMinSize";
 
private boolean frameResize;
 
103,8 → 108,17
// The minimum size of the frame must be the size when packed
this.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int w = Math.min(d.width - 100, getWidth());
int h = Math.min(d.height - 100, getHeight());
final int wantedW, wantedH;
if (Boolean.getBoolean(SMALL_MIN_SIZE)) {
final Dimension minimumSize = this.getMinimumSize();
wantedW = minimumSize.width;
wantedH = minimumSize.height;
} else {
wantedW = getWidth();
wantedH = getHeight();
}
final int w = Math.min(d.width - 100, wantedW);
final int h = Math.min(d.height - 100, wantedH);
setMinimumSize(new Dimension(w, h));
 
// View resized
/trunk/OpenConcerto/src/org/openconcerto/sql/view/EditPanel.java
257,6 → 257,7
this.p.getVerticalScrollBar().setUnitIncrement(9);
this.p.setOpaque(false);
this.p.getViewport().setOpaque(false);
this.p.setMinimumSize(new Dimension(60, 60));
 
container.add(this.p, c);
 
/trunk/OpenConcerto/src/org/openconcerto/sql/view/FileTransfertHandler.java
19,11 → 19,8
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
 
import javax.swing.JComponent;
import javax.swing.TransferHandler;
30,19 → 27,6
 
public class FileTransfertHandler extends TransferHandler {
 
static private DataFlavor URIListFlavor = null;
 
static public DataFlavor getURIListFlavor() {
if (URIListFlavor == null) {
try {
URIListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}
return URIListFlavor;
}
 
private final SQLTable tableName;
 
public FileTransfertHandler(SQLTable table) {
59,7 → 43,7
if (hasFileFlavor(t.getTransferDataFlavors())) {
list.addAll((List<File>) t.getTransferData(DataFlavor.javaFileListFlavor));
} else if (hasURIListFlavor(t.getTransferDataFlavors())) {
list.addAll(textURIListToFileList((String) t.getTransferData(getURIListFlavor())));
list.addAll(AbstractFileTransfertHandler.textURIListToFileList((String) t.getTransferData(AbstractFileTransfertHandler.getURIListFlavor())));
}
} catch (Exception e) {
e.printStackTrace();
122,7 → 106,7
 
private boolean hasURIListFlavor(DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (getURIListFlavor().equals(flavors[i])) {
if (AbstractFileTransfertHandler.getURIListFlavor().equals(flavors[i])) {
return true;
}
}
133,24 → 117,4
return DropManager.getInstance().getHandlerForTable(this.tableName);
}
 
private static List<File> textURIListToFileList(String data) {
final List<File> list = new ArrayList<File>(1);
for (StringTokenizer st = new StringTokenizer(data, "\r\n"); st.hasMoreTokens();) {
String s = st.nextToken();
if (s.startsWith("#")) {
// the line is a comment (as per the RFC 2483)
continue;
}
try {
final URI uri = new URI(s);
final File file = new File(uri);
list.add(file);
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
return list;
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/view/AbstractFileTransfertHandler.java
New file
0,0 → 1,137
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.sql.view;
 
import org.openconcerto.sql.Log;
import org.openconcerto.sql.model.SQLTable;
 
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
 
import javax.swing.JComponent;
import javax.swing.TransferHandler;
 
public abstract class AbstractFileTransfertHandler extends TransferHandler {
 
static private DataFlavor URIListFlavor = null;
 
static public synchronized DataFlavor getURIListFlavor() {
if (URIListFlavor == null) {
try {
URIListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}
return URIListFlavor;
}
 
public AbstractFileTransfertHandler() {
}
 
public abstract void handleFile(File f);
 
@Override
public boolean importData(final JComponent c, final Transferable t) {
if (!canImport(c, t.getTransferDataFlavors())) {
return false;
}
final List<File> list = new ArrayList<File>();
try {
if (hasFileFlavor(t.getTransferDataFlavors())) {
list.addAll((List<File>) t.getTransferData(DataFlavor.javaFileListFlavor));
} else if (hasURIListFlavor(t.getTransferDataFlavors())) {
list.addAll(textURIListToFileList((String) t.getTransferData(getURIListFlavor())));
}
} catch (Exception e) {
e.printStackTrace();
}
try {
 
final Thread thread = new Thread("AbstractFileTransfertHandler") {
@Override
public void run() {
for (File realFile : list) {
handleFile(realFile);
}
}
};
thread.start();
} catch (Exception e) {
e.printStackTrace();
}
 
return list.size() > 0;
 
}
 
@Override
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
 
@Override
public boolean canImport(JComponent c, DataFlavor[] flavors) {
if (hasFileFlavor(flavors) || hasURIListFlavor(flavors)) {
return true;
}
Log.get().config("No files or URL found in dropped object");
return false;
}
 
private boolean hasFileFlavor(DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (DataFlavor.javaFileListFlavor.equals(flavors[i]) || DataFlavor.javaRemoteObjectMimeType.equals(flavors[i])) {
return true;
}
}
return false;
}
 
private boolean hasURIListFlavor(DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (getURIListFlavor().equals(flavors[i])) {
return true;
}
}
return false;
}
 
static List<File> textURIListToFileList(String data) {
final List<File> list = new ArrayList<File>(1);
for (StringTokenizer st = new StringTokenizer(data, "\r\n"); st.hasMoreTokens();) {
String s = st.nextToken();
if (s.startsWith("#")) {
// the line is a comment (as per the RFC 2483)
continue;
}
try {
final URI uri = new URI(s);
final File file = new File(uri);
list.add(file);
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
return list;
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/RowAction.java
59,6 → 59,9
}
 
public final PredicateRowAction setPredicate(IPredicate<? super IListeEvent> pred) {
if (pred == null) {
throw new IllegalArgumentException("null predicate");
}
this.pred = pred;
return this;
}
69,6 → 72,9
 
@Override
public boolean enabledFor(IListeEvent evt) {
if (pred == null) {
throw new IllegalStateException("No predicate for action:" + this.getAction() + ":" + this.getAction().getValue(Action.NAME));
}
return this.pred.evaluateChecked(evt);
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/KeyTableCellRenderer.java
15,8 → 15,9
 
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableEvent.Mode;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.sqlobject.IComboSelectionItem;
 
import java.util.HashMap;
31,7 → 32,7
private Object toSelect;
private boolean isLoading = false;
private final SQLElement el;
static final Map<SQLElement, Map<Integer, IComboSelectionItem>> cacheMap = new HashMap<SQLElement, Map<Integer, IComboSelectionItem>>();
static private final Map<SQLElement, Map<Integer, IComboSelectionItem>> cacheMap = new HashMap<SQLElement, Map<Integer, IComboSelectionItem>>();
 
public KeyTableCellRenderer(final SQLElement el) {
super();
93,19 → 94,13
m.put(comboSelectionItem.getId(), comboSelectionItem);
}
cacheMap.put(KeyTableCellRenderer.this.el, m);
KeyTableCellRenderer.this.el.getTable().addPremierTableListener(new SQLTableListener() {
KeyTableCellRenderer.this.el.getTable().addPremierTableModifiedListener(new SQLTableModifiedListener() {
@Override
public void rowAdded(SQLTable table, int id) {
m.put(id, KeyTableCellRenderer.this.el.getComboRequest().getComboItem(id));
}
 
@Override
public void rowDeleted(SQLTable table, int id) {
public void tableModified(SQLTableEvent evt) {
final int id = evt.getId();
if (evt.getMode() == Mode.ROW_DELETED)
m.remove(id);
}
 
@Override
public void rowModified(SQLTable table, int id) {
else
m.put(id, KeyTableCellRenderer.this.el.getComboRequest().getComboItem(id));
}
});
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/IListe.java
59,6 → 59,7
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.convertor.StringClobConvertor;
 
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
308,6 → 309,11
// don't auto start, otherwise F2 will trigger the edition
this.jTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
 
// Better look
this.jTable.setShowHorizontalLines(false);
this.jTable.setGridColor(new Color(230, 230, 230));
this.jTable.setRowHeight(this.jTable.getRowHeight() + 4);
 
this.popup = new JPopupMenu();
TablePopupMouseListener.add(this.jTable, new ITransformer<MouseEvent, JPopupMenu>() {
@Override
/trunk/OpenConcerto/src/org/openconcerto/sql/PropsConfiguration.java
31,16 → 31,20
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.FileUtils;
import org.openconcerto.utils.LogUtils;
import org.openconcerto.utils.MultipleOutputStream;
import org.openconcerto.utils.StreamUtils;
import org.openconcerto.utils.cc.IClosure;
 
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
512,6 → 516,10
this.setupLogging(dirName, Boolean.getBoolean(REDIRECT_TO_FILE));
}
 
protected boolean keepStandardStreamsWhenRedirectingToFile() {
return true;
}
 
public void setupLogging(final String dirName, final boolean redirectToFile) {
final File logDir;
try {
542,9 → 550,17
logFile.getParentFile().mkdirs();
try {
System.out.println("Log file: " + logFile.getAbsolutePath());
final PrintStream ps = new PrintStream(new FileOutputStream(logFile, true));
System.setErr(ps);
System.setOut(ps);
final OutputStream fileOut = new FileOutputStream(logFile, true);
final OutputStream out, err;
if (this.keepStandardStreamsWhenRedirectingToFile()) {
out = new MultipleOutputStream(fileOut, new FileOutputStream(FileDescriptor.out));
err = new MultipleOutputStream(fileOut, new FileOutputStream(FileDescriptor.err));
} else {
out = fileOut;
err = fileOut;
}
System.setErr(new PrintStream(new BufferedOutputStream(err, 128), true));
System.setOut(new PrintStream(new BufferedOutputStream(out, 128), true));
} catch (FileNotFoundException e) {
throw new IllegalStateException("unable to write to log file", e);
}
/trunk/OpenConcerto/src/org/openconcerto/utils/StringUtils.java
222,7 → 222,7
 
if (lastString.length() == nbCharMaxLine) {
int esp = lastString.lastIndexOf(" ");
if (result.length() > 0) {
if (result.length() > 0 && result.charAt(result.length() - 1) != '\n') {
result.append("\n");
}
if (esp > 0) {
232,6 → 232,7
result.append(lastString.toString().trim());
lastString = new StringBuffer();
}
result.append("\n");
}
 
char charAt = s.charAt(i);
240,12 → 241,11
result.append(lastString);
lastString = new StringBuffer();
} else {
 
lastString.append(charAt);
}
}
 
if (result.length() > 0) {
if (result.length() > 0 && result.charAt(result.length() - 1) != '\n') {
result.append("\n");
}
 
338,4 → 338,21
}
}
 
public static String rightAlign(String s, int width) {
String r = s;
int n = width - s.length();
for (int i = 0; i < n; i++) {
r = ' ' + r;
}
return r;
}
 
public static String leftAlign(String s, int width) {
String r = s;
int n = width - s.length();
for (int i = 0; i < n; i++) {
r += ' ';
}
return r;
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/ExceptionHandler.java
71,6 → 71,14
clipboard.setContents(data, data);
}
 
/**
* Display the passed message. Note: this method doesn't block.
*
* @param comp the modal parent of the error window.
* @param msg the message to display.
* @param originalExn the cause, can be <code>null</code>.
* @return an exception.
*/
static public RuntimeException handle(Component comp, String msg, Throwable originalExn) {
return new ExceptionHandler(comp, msg, originalExn, false);
}
83,6 → 91,14
return handle(msg, null);
}
 
/**
* Display the passed message and quit. Note: this method blocks until the user closes the
* window (then exits).
*
* @param msg the message to display.
* @param originalExn the cause, can be <code>null</code>.
* @return an exception.
*/
static public RuntimeException die(String msg, Throwable originalExn) {
return new ExceptionHandler(null, msg, originalExn);
}
115,14 → 131,25
if (!GraphicsEnvironment.isHeadless() || forceUI) {
if (SwingUtilities.isEventDispatchThread()) {
showMsg(msg, error);
} else
SwingUtilities.invokeLater(new Runnable() {
} else {
final Runnable run = new Runnable() {
public void run() {
showMsg(msg, error);
}
});
};
if (error) {
try {
SwingUtilities.invokeAndWait(run);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
} else {
SwingUtilities.invokeLater(run);
}
}
}
}
 
protected final void showMsg(final String msg, final boolean quit) {
final JPanel p = new JPanel();
/trunk/OpenConcerto/src/org/openconcerto/utils/TimeUtils.java
New file
0,0 → 1,76
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.utils;
 
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
 
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
 
public class TimeUtils {
static private DatatypeFactory typeFactory = null;
 
static public final DatatypeFactory getTypeFactory() {
if (typeFactory == null)
try {
typeFactory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) {
throw new IllegalStateException(e);
}
return typeFactory;
}
 
/**
* Convert the time part of a calendar to a duration.
*
* @param cal a calendar, e.g. 23/12/2011 11:55:33.066 GMT+02.
* @return a duration, e.g. P0Y0M0DT11H55M33.066S.
*/
public final static Duration timePartToDuration(final Calendar cal) {
final BigDecimal seconds = BigDecimal.valueOf(cal.get(Calendar.SECOND)).add(BigDecimal.valueOf(cal.get(Calendar.MILLISECOND)).movePointLeft(3));
return getTypeFactory().newDuration(true, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.valueOf(cal.get(Calendar.HOUR_OF_DAY)), BigInteger.valueOf(cal.get(Calendar.MINUTE)),
seconds);
}
 
/**
* Normalize <code>cal</code> so that any Calendar with the same local time have the same
* result. If you don't need a Calendar this is faster than
* {@link #copyLocalTime(Calendar, Calendar)}.
*
* @param cal a calendar, e.g. 0:00 CEST.
* @return the time in millisecond of the UTC calendar with the same local time, e.g. 0:00 UTC.
*/
public final static long normalizeLocalTime(final Calendar cal) {
return cal.getTimeInMillis() + cal.getTimeZone().getOffset(cal.getTimeInMillis());
}
 
/**
* Copy the local time from one calendar to another. Except if both calendars have the same time
* zone, from.getTimeInMillis() will be different from to.getTimeInMillis().
*
* @param from the source calendar, e.g. 23/12/2011 11:55:33.066 GMT-12.
* @param to the destination calendar, e.g. 01/01/2000 0:00 GMT+13.
* @return the modified destination calendar, e.g. 23/12/2011 11:55:33.066 GMT+13.
*/
public final static Calendar copyLocalTime(final Calendar from, final Calendar to) {
to.clear();
for (final int field : new int[] { Calendar.YEAR, Calendar.DAY_OF_YEAR, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND }) {
to.set(field, from.get(field));
}
return to;
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/CompareUtils.java
57,6 → 57,32
}
 
/**
* Compare two objects if they're numbers or comparable.
*
* @param o1 first object.
* @param o2 second object.
* @return a negative integer, zero, or a positive integer as o1 is less than, equal to, or
* greater than o2.
* @throws ClassCastException if o1 is neither a {@link Number} nor a {@link Comparable}, or if
* o2's type prevents it from being compared to o1.
* @throws NullPointerException if o1 or o2 is <code>null</code>.
* @see Comparable#compareTo(Object)
* @see NumberUtils#compare(Number, Number)
*/
static public final int compare(final Object o1, final Object o2) throws ClassCastException {
if (o1 == null || o2 == null)
throw new NullPointerException();
if (o1 instanceof Number && o2 instanceof Number) {
return NumberUtils.compare((Number) o1, (Number) o2);
} else {
// see Arrays.mergeSort()
@SuppressWarnings({ "rawtypes", "unchecked" })
final int res = ((Comparable) o1).compareTo(o2);
return res;
}
}
 
/**
* Renvoie un comparateur qui utilise successivement la liste passée tant que les objets sont
* égaux.
*
/trunk/OpenConcerto/src/org/openconcerto/utils/checks/EmptyObjFromVO.java
18,8 → 18,6
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
 
import org.apache.commons.collections.Predicate;
 
/**
* Implement EmptyObj with a ValueObject and a predicate.
*
28,21 → 26,20
*/
public class EmptyObjFromVO<V> implements EmptyObj {
 
/**
* A predicate returning <code>true</code> if the passed object is <code>null</code> or the
* empty string.
*
* @param <T> type of the value object.
* @return a predicate returning <code>true</code> if the object is empty.
*/
@SuppressWarnings("unchecked")
public static final <T> IPredicate<T> getDefaultPredicate() {
return new IPredicate<T>() {
@Override
public boolean evaluateChecked(T input) {
return DEFAULT_PREDICATE.evaluate(input);
return (IPredicate<T>) DEFAULT_PREDICATE;
}
};
}
 
/**
* This predicate returns <code>true</code> if the passed object is <code>null</code> or the
* empty string.
*/
public static final Predicate DEFAULT_PREDICATE = new Predicate() {
public boolean evaluate(Object object) {
private static final IPredicate<Object> DEFAULT_PREDICATE = new IPredicate<Object>() {
public boolean evaluateChecked(Object object) {
if (object instanceof String)
return ((String) object).length() == 0;
else
/trunk/OpenConcerto/src/org/openconcerto/utils/MultipleOutputStream.java
New file
0,0 → 1,68
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.utils;
 
import java.io.IOException;
import java.io.OutputStream;
 
public class MultipleOutputStream extends OutputStream {
private OutputStream[] streams;
 
/**
* OutputStream forwarding writes to multiple OutputStreams
* */
public MultipleOutputStream(OutputStream o1, OutputStream o2) {
this(new OutputStream[] { o1, o2 });
}
 
public MultipleOutputStream(OutputStream[] outputStreams) {
this.streams = outputStreams;
}
 
@Override
public void write(int b) throws IOException {
for (int i = 0; i < streams.length; i++) {
streams[i].write(b);
}
}
 
@Override
public void write(byte[] b) throws IOException {
for (int i = 0; i < streams.length; i++) {
streams[i].write(b);
}
}
 
@Override
public void write(byte[] b, int off, int len) throws IOException {
for (int i = 0; i < streams.length; i++) {
streams[i].write(b, off, len);
}
}
 
@Override
public void close() throws IOException {
for (int i = 0; i < streams.length; i++) {
streams[i].close();
}
}
 
@Override
public void flush() throws IOException {
for (int i = 0; i < streams.length; i++) {
streams[i].flush();
}
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/model/Reloadable.java
New file
0,0 → 1,18
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.utils.model;
 
public interface Reloadable {
void reload();
}
/trunk/OpenConcerto/src/org/openconcerto/utils/FileUtils.java
354,6 → 354,14
}
}
 
public static void copyFile(File in, File out, final boolean useTime) throws IOException {
if (!useTime || in.lastModified() != out.lastModified()) {
copyFile(in, out);
if (useTime)
out.setLastModified(in.lastModified());
}
}
 
public static void copyDirectory(File in, File out) throws IOException {
copyDirectory(in, out, Collections.<String> emptySet());
}
361,6 → 369,10
public static final Set<String> VersionControl = CollectionUtils.createSet(".svn", "CVS");
 
public static void copyDirectory(File in, File out, final Set<String> toIgnore) throws IOException {
copyDirectory(in, out, toIgnore, false);
}
 
public static void copyDirectory(File in, File out, final Set<String> toIgnore, final boolean useTime) throws IOException {
if (toIgnore.contains(in.getName()))
return;
 
371,11 → 383,11
 
String[] children = in.list();
for (int i = 0; i < children.length; i++) {
copyDirectory(new File(in, children[i]), new File(out, children[i]), toIgnore);
copyDirectory(new File(in, children[i]), new File(out, children[i]), toIgnore, useTime);
}
} else {
if (!in.getName().equals("Thumbs.db")) {
copyFile(in, out);
copyFile(in, out, useTime);
}
}
}
404,6 → 416,21
return dir.delete();
}
 
public static void rm_R(File dir) throws IOException {
if (dir.isDirectory()) {
for (final File child : dir.listFiles()) {
rmR(child);
}
}
// The directory is now empty so delete it
rm(dir);
}
 
public static void rm(File f) throws IOException {
if (f.exists() && !f.delete())
throw new IOException("cannot delete " + f);
}
 
public static final File mkdir_p(File dir) throws IOException {
if (!dir.exists()) {
if (!dir.mkdirs()) {
/trunk/OpenConcerto/src/org/openconcerto/task/TodoListPanel.java
236,8 → 236,9
}
 
this.addButton = new JButton("Ajouter une tâche");
 
this.addButton.setOpaque(false);
this.removeButton = new JButton("Effacer");
this.removeButton.setOpaque(false);
this.removeButton.setEnabled(false);
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
263,6 → 264,7
c.anchor = GridBagConstraints.EAST;
c.gridx++;
JMenuBar b = new JMenuBar();
b.setOpaque(false);
b.setBorderPainted(false);
b.add(this.comboUser);
// Pour que le menu ne disparaisse pas quand on rapetisse trop la fenetre en bas
273,6 → 275,7
c.gridx++;
c.weightx = 1;
this.detailCheckBox = new JCheckBox("Affichage détaillé");
this.detailCheckBox.setOpaque(false);
this.detailCheckBox.setSelected(false);
this.add(this.detailCheckBox, c);
 
279,6 → 282,7
//
c.gridx++;
this.hideOldCheckBox = new JCheckBox("Masquer l'historique");
this.hideOldCheckBox.setOpaque(false);
this.hideOldCheckBox.setSelected(true);
this.add(this.hideOldCheckBox, c);
 
286,6 → 290,7
 
c.weightx = 0;
c.anchor = GridBagConstraints.EAST;
this.reloadPanel.setOpaque(false);
this.add(this.reloadPanel, c);
 
// Table
503,7 → 508,10
this.t.setBlockEventOnColumn(false);
this.t.setBlockRepaint(false);
this.t.getColumnModel().getColumn(1).setCellRenderer(this.iconRenderer);
 
// Better look
this.t.setShowHorizontalLines(false);
this.t.setGridColor(new Color(230, 230, 230));
this.t.setRowHeight(this.t.getRowHeight() + 4);
AlternateTableCellRenderer.UTILS.setAllColumns(this.t);
this.t.repaint();
 
/trunk/OpenConcerto/src/org/openconcerto/erp/storage/StorageEngine.java
New file
0,0 → 1,30
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.storage;
 
import java.io.IOException;
import java.io.InputStream;
 
public interface StorageEngine {
public boolean isConfigured();
 
public boolean allowAutoStorage();
 
public void connect() throws IOException;
 
public void disconnect() throws IOException;
 
public void store(final InputStream inStream, String remotePath, String title, boolean synchronous) throws IOException;
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/storage/StorageEngines.java
New file
0,0 → 1,40
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.storage;
 
import java.util.ArrayList;
import java.util.List;
 
public class StorageEngines {
private static final StorageEngines instance = new StorageEngines();
 
public static StorageEngines getInstance() {
return instance;
}
 
private List<StorageEngine> engines = new ArrayList<StorageEngine>();
 
public List<StorageEngine> getActiveEngines() {
// TODO use a map to store active engines;
return engines;
}
 
public void addEngine(StorageEngine e) {
engines.add(e);
}
 
public void removeEngine(StorageEngine e) {
engines.remove(e);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/InstallationPanel.java
228,6 → 228,7
@Override
public Object create() throws SQLException {
fixUnboundedVarchar(root);
fixUnboundedNumeric(root);
updateSocieteSchema(root);
updateToV1Dot2(root);
return null;
424,10 → 425,48
 
// c.gridy++;
// this.add(bd, c);
 
c.gridy++;
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
c.insets = new Insets(10, 3, 2, 2);
this.add(new JLabelBold("Paramètrages de la base de données"), c);
c.gridy++;
c.weightx = 0;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.NONE;
c.insets = DefaultGridBagConstraints.getDefaultInsets();
JButton buttonPL = new JButton("Lancer");
buttonPL.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
if (!finderPanel.getServerConfig().getType().equals(ServerFinderConfig.POSTGRESQL)) {
 
} else {
final ComptaPropsConfiguration conf = ComptaPropsConfiguration.create(true);
try {
final SQLDataSource ds = conf.getSystemRoot().getDataSource();
ds.execute("CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler AS '$libdir/plpgsql' LANGUAGE C;" + "\n"
+ "CREATE FUNCTION plpgsql_validator(oid) RETURNS void AS '$libdir/plpgsql' LANGUAGE C;" + "\n"
+ "CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql HANDLER plpgsql_call_handler VALIDATOR plpgsql_validator;");
} catch (Exception ex) {
System.err.println("Impossible d'ajouter le langage PLPGSQL. Peut etre est il déjà installé.");
}
}
JOptionPane.showConfirmDialog(null, "Paramètrage terminé.");
}
});
this.add(buttonPL, c);
 
c.gridy++;
c.gridx = 0;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.WEST;
c.gridwidth = GridBagConstraints.REMAINDER;
c.insets = new Insets(10, 3, 2, 2);
this.add(new JLabelBold("Mise à niveau de la base OpenConcerto"), c);
c.gridy++;
this.add(this.bar, c);
451,6 → 490,64
this.add(comp, c);
}
 
private void fixUnboundedNumeric(DBRoot root) throws SQLException {
 
final List<AlterTable> alters = new ArrayList<AlterTable>();
{
SQLTable tableAvoir = root.getTable("AVOIR_CLIENT_ELEMENT");
final AlterTable alter = new AlterTable(tableAvoir);
SQLField fieldAcompteAvoir = tableAvoir.getField("POURCENT_ACOMPTE");
if (fieldAcompteAvoir.getType().getSize() > 500) {
final String fName = fieldAcompteAvoir.getName();
alter.alterColumn(fName, EnumSet.allOf(Properties.class), "numeric(6,2)", "100", false);
}
 
SQLField fieldRemiseAvoir = tableAvoir.getField("POURCENT_REMISE");
if (fieldRemiseAvoir.getType().getSize() > 500) {
final String fName = fieldRemiseAvoir.getName();
alter.alterColumn(fName, EnumSet.allOf(Properties.class), "numeric(6,2)", "0", false);
}
 
if (!alter.isEmpty())
alters.add(alter);
}
 
{
SQLTable tableFacture = root.getTable("SAISIE_VENTE_FACTURE_ELEMENT");
final AlterTable alter = new AlterTable(tableFacture);
SQLField fieldAcompteFacture = tableFacture.getField("POURCENT_ACOMPTE");
if (fieldAcompteFacture.getType().getSize() > 500) {
final String fName = fieldAcompteFacture.getName();
alter.alterColumn(fName, EnumSet.allOf(Properties.class), "numeric(6,2)", "100", false);
}
 
SQLField fieldRemiseFacture = tableFacture.getField("POURCENT_REMISE");
if (fieldRemiseFacture.getType().getSize() > 500) {
final String fName = fieldRemiseFacture.getName();
alter.alterColumn(fName, EnumSet.allOf(Properties.class), "numeric(6,2)", "0", false);
}
 
if (tableFacture.getFieldsName().contains("REPARTITION_POURCENT")) {
SQLField fieldRepFacture = tableFacture.getField("REPARTITION_POURCENT");
if (fieldRepFacture.getType().getSize() > 500) {
final String fName = fieldRepFacture.getName();
alter.alterColumn(fName, EnumSet.allOf(Properties.class), "numeric(6,2)", "0", false);
}
}
 
if (!alter.isEmpty())
alters.add(alter);
 
}
if (alters.size() > 0) {
final SQLDataSource ds = root.getDBSystemRoot().getDataSource();
for (final String sql : ChangeTable.cat(alters, root.getName())) {
ds.execute(sql);
}
root.refetch();
}
}
 
private void fixUnboundedVarchar(DBRoot root) throws SQLException {
final Set<String> namesSet = CollectionUtils.createSet("NOM", "PRENOM", "SURNOM", "LOGIN", "PASSWORD");
final List<AlterTable> alters = new ArrayList<AlterTable>();
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ServerFinderConfig.java
31,6 → 31,7
private String ip;
private File file;
private String port;
private String systemRoot = "OpenConcerto";
 
private String dbLogin;
private String dbPassword;
40,6 → 41,14
private String product;
private String error;
 
public String getSystemRoot() {
return systemRoot;
}
 
public void setSystemRoot(String systemRoot) {
this.systemRoot = systemRoot;
}
 
public String getType() {
return type;
}
245,4 → 254,5
return this.getType() + ":" + this.getIp() + ":" + this.getPort() + " file:" + this.getFile() + " " + this.getOpenconcertoLogin() + "/" + this.getOpenconcertoPassword() + " ["
+ this.getDbLogin() + "/" + this.getDbPassword() + "]";
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ComptaPropsConfiguration.java
100,6 → 100,7
import org.openconcerto.erp.core.sales.invoice.element.EcheanceClientSQLElement;
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureItemSQLElement;
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement;
import org.openconcerto.erp.core.sales.invoice.ui.SaisieVenteFactureItemTable;
import org.openconcerto.erp.core.sales.order.element.CommandeClientElementSQLElement;
import org.openconcerto.erp.core.sales.order.element.CommandeClientSQLElement;
import org.openconcerto.erp.core.sales.pos.element.CaisseTicketSQLElement;
148,10 → 149,12
import org.openconcerto.erp.injector.FactureBonSQLInjector;
import org.openconcerto.erp.injector.FactureCommandeSQLInjector;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.erp.preferences.TemplateNXProps;
import org.openconcerto.erp.rights.ComptaTotalUserRight;
import org.jopendocument.link.OOConnexion;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.ShowAs;
import org.openconcerto.sql.element.ElementMapper;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.element.SharedSQLElement;
import org.openconcerto.sql.model.DBRoot;
341,7 → 344,7
@Override
protected String getAppIDSuffix() {
if (inWebstart())
// so we don't remove files of a normal OpenConcerto
// so we don't remove files of a normal GestionNX
return super.getAppIDSuffix() + "-webstart";
else
return super.getAppIDSuffix();
403,7 → 406,6
 
@Override
protected ShowAs createShowAs() {
System.out.println("ComptaPropsConfiguration.createShowAszzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz()");
final ShowAs showAs = super.createShowAs();
 
showAs.show("ADRESSE_COMMON", SQLRow.toList("RUE,VILLE"));
731,6 → 733,7
}
setSocieteShowAs();
setSocieteSQLInjector();
setMapper();
String sfe = DefaultNXProps.getInstance().getStringProperty("ArticleSFE");
Boolean bSfe = Boolean.valueOf(sfe);
boolean isSFE = bSfe != null && bSfe.booleanValue();
740,7 → 743,7
trans.load(rootSociete, inSFE);
}
}
 
TemplateNXProps.getInstance();
// Chargement du graphe
new Thread() {
public void run() {
750,6 → 753,21
}.start();
}
 
private void setMapper() {
ElementMapper mapper = ElementMapper.getInstance();
mapper.map("customerrelationship.name", "Relation client");
mapper.map("customerrelationship.customer.list.table", "CLIENT");
mapper.map("customerrelationship.contact.list.table", "CONTACT");
mapper.map("accounting.name", "Comptabilité");
mapper.map("sales.name", "Gestion commerciale");
mapper.map("sales.invoice.name", "Factures client");
mapper.map("sales.invoice.list.table", "SAISIE_VENTE_FACTURE");
mapper.map("sales.quote.name", "Devis client");
mapper.map("sales.quote.list.table", "DEVIS");
mapper.map("sales.invoice.list.table.editor", SaisieVenteFactureItemTable.class);
mapper.dump();
}
 
private void closeSocieteConnexion() {
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/MainFrame.java
59,6 → 59,8
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesCommerciauxAction;
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesSalariesAction;
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesSecretairesAction;
import org.openconcerto.erp.core.humanresources.employe.action.N4DSAction;
import org.openconcerto.erp.core.humanresources.employe.report.N4DS;
import org.openconcerto.erp.core.humanresources.payroll.action.ClotureMensuellePayeAction;
import org.openconcerto.erp.core.humanresources.payroll.action.EditionFichePayeAction;
import org.openconcerto.erp.core.humanresources.payroll.action.ListeDesProfilsPayeAction;
456,6 → 458,7
menu.add(new JSeparator());
menu.add(new EtatChargeAction());
menu.add(new CompteResultatBilanAction());
menu.add(new N4DSAction());
if (rights.haveRight(ComptaUserRight.MENU)) {
result.add(menu);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/Gestion.java
37,7 → 37,6
import org.openconcerto.ui.component.WaitIndeterminatePanel;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.FileUtils;
import org.openconcerto.utils.cc.IClosure;
import org.openconcerto.utils.protocol.Helper;
 
import java.awt.AWTEvent;
71,6 → 70,8
 
public class Gestion {
 
public static final File MODULES_DIR = new File("Modules");
 
/**
* When this system property is set to <code>true</code>, Gestion will hide most of its normal
* UI. E.g. no SOCIETE selection in the login panel, minimalist menu bar, etc.
212,17 → 213,7
} catch (Exception e) {
System.out.println("Init phase 1 error:" + (System.currentTimeMillis() - t4) + "ms");
ExceptionHandler.die("Erreur de connexion à la base de données", e);
// since we're not in the EDT, the previous call doesn't block,
// so return (it won't quit the VM since a dialog is displaying)
return;
}
try {
final File moduleDir = new File("Modules");
moduleDir.mkdir();
ModuleManager.getInstance().addFactories(moduleDir);
} catch (Throwable e) {
ExceptionHandler.handle("Erreur d'accès aux modules", e);
}
System.out.println("Init phase 1:" + (System.currentTimeMillis() - t1) + "ms");
SwingUtilities.invokeLater(new Runnable() {
 
283,21 → 274,12
 
// needed so that we can uninstall modules
System.setProperty(SQLBase.ALLOW_OBJECT_REMOVAL, "true");
ModuleManager.getInstance().invoke(new IClosure<ModuleManager>() {
@Override
public void executeChecked(ModuleManager mngr) {
try {
final Exception exn = mngr.setup();
// OK to continue without all modules started
if (exn != null)
ExceptionHandler.handle(MainFrame.getInstance(), "Impossible de démarrer les modules", exn);
} catch (Exception e) {
// not OK to continue without required elements
ExceptionHandler.die("Impossible de démarrer les modules requis", e);
ModuleManager.getInstance().addFactories(MODULES_DIR);
} catch (Throwable e) {
ExceptionHandler.handle("Erreur d'accès aux modules", e);
}
}
});
}
 
/**
* Si la base est 127.0.0.1 ou localhost alors on essaye de lancer postgres.
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ServerFinderPanel.java
73,6 → 73,7
private JTextField textIP;
private JTextField textPort;
private JTextField textFile;
private JTextField textBase;
Properties props;
private JButton buttonDir;
private JTabbedPane tabbedPane;
146,6 → 147,7
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Impossible de lire le fichier " + this.confFile + " \n" + e.getLocalizedMessage());
}
 
String serverIp = this.props.getProperty("server.ip", "127.0.0.1:5432");
String serverDriver = this.props.getProperty("server.driver", "postgresql").toLowerCase();
if (serverDriver.startsWith("h2")) {
158,7 → 160,7
updateUIForMode(ServerFinderConfig.POSTGRESQL);
this.textPort.setText("5432");
}
 
this.textBase.setText(this.props.getProperty("systemRoot", "OpenConcerto"));
if (serverIp.contains("file:")) {
this.textFile.setText(serverIp.substring(5));
} else {
405,6 → 407,19
c.gridy++;
c.gridx = 0;
c.weightx = 0;
p.add(new JLabel("Base de données", SwingConstants.RIGHT), c);
c.gridx++;
c.weighty = 0;
c.gridwidth = 1;
this.textBase = new JTextField();
this.textBase.setEditable(false);
p.add(this.textBase, c);
 
// L4: file
c.gridy++;
c.gridx = 0;
c.weightx = 0;
c.gridwidth = 1;
p.add(new JLabel("Dossier de base de données", SwingConstants.RIGHT), c);
c.gridx++;
c.weighty = 0;
648,18 → 663,12
return p;
}
 
private JPanel createPanelInstallation() {
final JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
p.setOpaque(false);
return p;
}
 
public ServerFinderConfig getServerConfig() {
final ServerFinderConfig conf = new ServerFinderConfig();
conf.setType(ServerFinderPanel.this.comboMode.getSelectedItem().toString());
conf.setIp(ServerFinderPanel.this.textIP.getText());
conf.setPort(ServerFinderPanel.this.textPort.getText());
conf.setSystemRoot(this.textBase.getText());
return conf;
}
 
690,6 → 699,7
public ServerFinderConfig createServerFinderConfig() {
ServerFinderConfig conf = new ServerFinderConfig();
conf.setType(this.comboMode.getSelectedItem().toString());
conf.setSystemRoot(this.textBase.getText());
if (!conf.getType().equals(ServerFinderConfig.H2)) {
conf.setIp(this.textIP.getText());
conf.setPort(this.textPort.getText());
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/AvailableModulesPanel.java
13,19 → 13,25
package org.openconcerto.erp.modules;
 
import org.openconcerto.sql.view.AbstractFileTransfertHandler;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.FileUtils;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
 
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
 
public class AvailableModulesPanel extends JPanel {
private final AvailableModuleTableModel tm;
91,8 → 97,47
c.weighty = 1;
c.gridy++;
this.add(space, c);
this.setTransferHandler(new AbstractFileTransfertHandler() {
 
@Override
public void handleFile(File f) {
if (!f.getName().endsWith(".jar")) {
JOptionPane.showMessageDialog(AvailableModulesPanel.this, "Impossible d'installer le module. Le fichier n'est pas un module.");
return;
}
File dir = new File("Modules");
dir.mkdir();
File out = null;
if (dir.canWrite()) {
try {
out = new File(dir, f.getName());
FileUtils.copyFile(f, out);
} catch (IOException e) {
JOptionPane.showMessageDialog(AvailableModulesPanel.this, "Impossible d'installer le module.\n" + f.getAbsolutePath() + " vers " + dir.getAbsolutePath());
return;
}
} else {
JOptionPane.showMessageDialog(AvailableModulesPanel.this, "Impossible d'installer le module.\nVous devez disposer des droits en écriture sur le dossier:\n" + dir.getAbsolutePath());
return;
}
try {
ModuleManager.getInstance().addFactory(new JarModuleFactory(out));
} catch (IOException e) {
JOptionPane.showMessageDialog(AvailableModulesPanel.this, "Impossible d'intégrer le module.\n" + e.getMessage());
return;
}
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
reload();
}
});
 
}
});
}
 
public void reload() {
this.tm.reload();
}
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ComponentsContext.java
85,8 → 85,12
}
 
public final SQLElement getElement(final String tableName) {
return this.dir.getElement(this.getRoot().getTable(tableName));
final SQLElement element = this.dir.getElement(this.getRoot().getTable(tableName));
if (element == null) {
throw new IllegalArgumentException("Not element found for table " + tableName);
}
return element;
}
 
public final void putAdditionalField(final String tableName, final String name) {
final SQLElement elem = checkField(tableName, name);
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/DBContext.java
22,7 → 22,9
import org.openconcerto.sql.utils.SQLCreateTable;
import org.openconcerto.sql.utils.SQLCreateTableBase;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.cc.IClosure;
 
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
39,17 → 41,23
*/
public final class DBContext {
 
private final File dir;
private final ModuleVersion localVersion;
private final ModuleVersion lastInstalledVersion;
private final DBRoot root;
private final List<ChangeTable<?>> changeTables;
private final List<AlterTableRestricted> alterTables;
// Data Manipulation
private final List<IClosure<? super DBRoot>> dm;
 
private final Set<String> tables;
private final CollectionMap<String, SQLField> fields;
 
DBContext(ModuleVersion lastInstalledVersion, DBRoot root, final Set<String> tables, final Set<SQLName> fields) {
DBContext(final File dir, final ModuleVersion localVersion, final DBRoot root, final ModuleVersion dbVersion, final Set<String> tables, final Set<SQLName> fields) {
super();
this.lastInstalledVersion = lastInstalledVersion;
this.dir = dir;
this.localVersion = localVersion;
this.lastInstalledVersion = dbVersion;
this.root = root;
this.tables = Collections.unmodifiableSet(tables);
this.fields = new CollectionMap<String, SQLField>(new HashSet<SQLField>());
59,8 → 67,17
}
this.changeTables = new ArrayList<ChangeTable<?>>();
this.alterTables = new ArrayList<AlterTableRestricted>();
this.dm = new ArrayList<IClosure<? super DBRoot>>();
}
 
public final File getLocalDirectory() {
return this.dir;
}
 
public final ModuleVersion getLocalVersion() {
return this.localVersion;
}
 
public final ModuleVersion getLastInstalledVersion() {
return this.lastInstalledVersion;
}
95,7 → 112,10
SQLTable.setUndefID(getRoot().getSchema(), addedTable, null);
getRoot().refetch();
}
for (final IClosure<? super DBRoot> closure : this.dm) {
closure.executeChecked(getRoot());
}
}
 
// DDL
 
120,6 → 140,36
this.changeTables.add(new DropTable(this.root.getTable(name)));
}
 
// DML
 
/**
* The closure will be executed after the DDL statements. Note: you generally need to undo in
* {@link AbstractModule#uninstall()} what <code>closure</code> does (exceptions include
* inserting rows in a created table, since it will be automatically dropped).
*
* @param closure what to do.
*/
public final void manipulateData(final IClosure<? super DBRoot> closure) {
this.dm.add(closure);
}
 
/**
* The closure will be executed after the DDL statements. E.g. if you called
* {@link #getCreateTable(String)} this allows you to insert rows.
*
* @param name a table name.
* @param closure what to do.
* @see #manipulateData(IClosure)
*/
public final void manipulateTable(final String name, final IClosure<SQLTable> closure) {
this.manipulateData(new IClosure<DBRoot>() {
@Override
public void executeChecked(DBRoot input) {
closure.executeChecked(input.getTable(name));
}
});
}
 
// getter
 
final List<String> getAddedTables() {
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModulePreferencePanel.java
15,7 → 15,6
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.sqlobject.SQLSearchableTextCombo;
import org.openconcerto.sql.sqlobject.SQLSearchableTextCombo.ISQLListModel;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
27,7 → 26,6
import org.openconcerto.utils.PrefType;
 
import java.util.Date;
import java.util.prefs.Preferences;
 
import javax.swing.JCheckBox;
import javax.swing.JComponent;
34,11 → 32,11
 
public abstract class ModulePreferencePanel extends JavaPrefPreferencePanel {
 
static private DBRoot getRoot() {
static public DBRoot getRoot() {
return Configuration.getInstance().getRoot();
}
 
static private String getAppPrefPath() {
static String getAppPrefPath() {
return Configuration.getInstance().getAppID() + '/';
}
 
89,8 → 87,6
}
 
public final void init(final ModuleFactory module, final boolean local) {
final Preferences rootPrefs = local ? Preferences.userRoot() : new SQLPreferences(getRoot());
// ID is a package name, transform to path to avoid bumping into the size limit
this.setPrefs(rootPrefs.node(getAppPrefPath() + module.getID().replace('.', '/')));
this.setPrefs(module.getPreferences(local, getRoot()));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleLauncher.java
New file
0,0 → 1,71
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.modules;
 
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.utils.FileUtils;
 
import java.io.File;
import java.io.IOException;
 
/**
* Package a module from a project and launch it. The system property {@link #MODULE_DIR_PROP} must
* be defined.
*
* @author Sylvain CUAZ
* @see ModulePackager
*/
public class ModuleLauncher {
/**
* Required system property, it must point to a directory with module classes in bin/, this
* class will put the packaged module in the dist/ subdirectory.
*/
public static final String MODULE_DIR_PROP = "module.dir";
/**
* System property to use if the module properties files isn't "module.properties" (this
* property is evaluated relative to {@link #MODULE_DIR_PROP}).
*/
public static final String MODULE_PROPS_FILE_PROP = "module.propsFile";
 
public static void main(String[] args) throws IOException {
final File moduleDir = new File(System.getProperty(MODULE_DIR_PROP));
final File propsFile = new File(moduleDir, System.getProperty(MODULE_PROPS_FILE_PROP, "module.properties"));
final boolean launchFromPackage = !Boolean.getBoolean("module.fromProject");
final File classes = new File(moduleDir, "bin");
 
// always update dist/ to avoid out of date problems
final File distDir = new File(moduleDir, "dist");
FileUtils.mkdir_p(distDir);
final File jar = new ModulePackager(propsFile, classes).writeToDir(distDir);
// to avoid out of date modules from OpenConcerto (e.g. when launching this module, the jars
// of MODULES_DIR are used for dependencies)
FileUtils.copyFile(jar, new File(Gestion.MODULES_DIR, jar.getName()));
 
final ModuleFactory factory;
if (launchFromPackage) {
factory = new JarModuleFactory(jar);
} else {
factory = new RuntimeModuleFactory(propsFile);
try {
Class.forName(factory.getMainClass());
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Module classes are not in the classpath (they should be in " + classes + ")", e);
}
}
 
Gestion.main(args);
// add after main() otherwise we could be overwritten by an older jar
ModuleManager.getInstance().addFactoryAndStart(factory, false);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/AlterTableRestricted.java
34,7 → 34,6
*/
public final class AlterTableRestricted {
 
private final DBContext ctxt;
private final SQLTable table;
private final Set<SQLField> previouslyCreatedFields;
private final AlterTable alter;
41,7 → 40,6
private final Set<String> addedColumns, removedColumns;
 
AlterTableRestricted(DBContext ctxt, String tableName) {
this.ctxt = ctxt;
this.table = ctxt.getRoot().getTable(tableName);
this.previouslyCreatedFields = ctxt.getFieldsPreviouslyCreated(tableName);
this.alter = new AlterTable(this.table);
108,14 → 106,8
}
 
public AlterTable addForeignColumn(String fk, SQLName tableName) {
SQLCreateTableBase<?> createTable;
if (tableName.getItemCount() == 1 && (createTable = this.ctxt.getCreateTables().get(tableName.getFirst())) != null) {
addCol(fk);
return this.alter.addForeignColumn(fk, createTable);
} else {
return this.addForeignColumn(fk, this.table.getDesc(tableName, SQLTable.class));
}
}
 
public AlterTable addForeignColumn(String fk, SQLTable foreignTable) {
addCol(fk);
122,6 → 114,11
return this.alter.addForeignColumn(fk, foreignTable);
}
 
public AlterTable addForeignColumn(String fk, SQLCreateTableBase<?> createTable) {
addCol(fk);
return this.alter.addForeignColumn(fk, createTable);
}
 
public AlterTable addUniqueConstraint(String name, List<String> cols) {
if (!this.addedColumns.containsAll(cols))
throw new IllegalArgumentException("Can only add constraint to added columns : " + CollectionUtils.substract(cols, this.addedColumns));
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/AbstractModule.java
14,8 → 14,11
package org.openconcerto.erp.modules;
 
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.DBRoot;
 
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
53,9 → 56,21
}
 
/**
* Should create permanent items. NOTE: all items created through <code>ctxt</code> will be
* dropped automatically, i.e. no action is necessary in {@link #uninstall()}.
* The directory this module should use while running. During installation use
* {@link DBContext#getLocalDirectory()}.
*
* @return the directory for this module.
*/
protected final File getLocalDirectory() {
return ModuleManager.getInstance().getLocalDirectory(this.getFactory().getID());
}
 
/**
* Should create permanent items. NOTE: all structure items created through <code>ctxt</code>
* will be dropped automatically, and similarly all files created in
* {@link DBContext#getLocalDirectory()} will be deleted automatically, i.e. no action is
* necessary in {@link #uninstall(DBRoot)}.
*
* @param ctxt to create database objects.
*/
protected void install(DBContext ctxt) {
64,9 → 79,9
 
/**
* Should add elements for the tables of this module. It's also the place to
* {@link SQLElement#setAction(String, org.openconcerto.sql.element.SQLElement.ReferenceAction)set actions}
* for foreign keys of this module. NOTE: this method is called as long as the module is
* installed in the database, even if it is stopped.
* {@link SQLElement#setAction(String, SQLElement.ReferenceAction) set actions} for foreign keys
* of this module. NOTE: this method is called as long as the module is installed in the
* database, even if it is stopped.
*
* @param dir the directory where to add elements.
*/
105,7 → 120,7
 
protected abstract void stop();
 
protected void uninstall() {
protected void uninstall(DBRoot root) {
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/JarModuleFactory.java
105,4 → 105,9
public AbstractModule createModule(Map<String, AbstractModule> alreadyCreated) throws Exception {
return createModule(new ModuleClassLoader(alreadyCreated).loadClass(this.getMainClass()));
}
 
@Override
public String toString() {
return super.toString() + " from " + this.jar;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleFactory.java
13,6 → 13,8
package org.openconcerto.erp.modules;
 
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.utils.cc.IPredicate;
 
import java.io.IOException;
23,6 → 25,7
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.prefs.Preferences;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
175,8 → 178,22
return (AbstractModule) c.getConstructor(ModuleFactory.class).newInstance(this);
}
 
public final Preferences getLocalPreferences() {
return this.getPreferences(true, null);
}
 
public final Preferences getSQLPreferences(final DBRoot root) {
return this.getPreferences(false, root);
}
 
public final Preferences getPreferences(final boolean local, final DBRoot root) {
final Preferences rootPrefs = local ? Preferences.userRoot() : new SQLPreferences(root);
// ID is a package name, transform to path to avoid bumping into the size limit
return rootPrefs.node(ModulePreferencePanel.getAppPrefPath() + this.getID().replace('.', '/'));
}
 
@Override
public String toString() {
return super.toString() + " " + getID() + " (" + getMajorVersion() + "." + getMinorVersion() + ")";
return getClass().getSimpleName() + " " + getID() + " (" + getMajorVersion() + "." + getMinorVersion() + ")";
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleManager.java
17,9 → 17,11
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.ConnectionHandlerNoSetup;
import org.openconcerto.sql.model.DBFileCache;
import org.openconcerto.sql.model.DBItemFileCache;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLName;
import org.openconcerto.sql.model.SQLRow;
27,6 → 29,7
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLSyntax;
import org.openconcerto.sql.model.SQLSystem;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.model.graph.DirectedEdge;
37,13 → 40,14
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.sql.utils.SQLUtils.SQLFactory;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.task.config.ComptaBasePropsConfiguration;
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.FileUtils;
import org.openconcerto.utils.StringUtils;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.IClosure;
import org.openconcerto.utils.cc.IdentityHashSet;
import org.openconcerto.utils.cc.IdentitySet;
 
import java.io.File;
import java.io.FileFilter;
60,10 → 64,9
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Map.Entry;
import java.util.logging.Logger;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
 
import javax.swing.JMenuItem;
83,7 → 86,6
private static final Logger L = Logger.getLogger(ModuleManager.class.getPackage().getName());
 
private static final int MIN_VERSION = 0;
private static final int NO_VERSION = MIN_VERSION - 1;
private static final String MODULE_COLNAME = "MODULE_NAME";
private static final String MODULE_VERSION_COLNAME = "MODULE_VERSION";
private static final String TABLE_COLNAME = "TABLE";
105,6 → 107,9
private final Map<String, ComponentsContext> modulesComponents;
private final DirectedGraph<ModuleFactory, DirectedEdge<ModuleFactory>> dependencyGraph;
 
private DBRoot root;
private Configuration conf;
 
public ModuleManager() {
this.factories = new HashMap<String, ModuleFactory>();
this.runningModules = new HashMap<String, AbstractModule>();
116,6 → 121,9
});
this.modulesElements = new HashMap<String, Collection<SQLElement>>();
this.modulesComponents = new HashMap<String, ComponentsContext>();
 
this.root = null;
this.conf = null;
}
 
// *** factories (thread-safe)
122,7 → 130,7
 
public final int addFactories(final File dir) {
if (!dir.exists()) {
System.err.println("Warning: module factory directory not found: " + dir.getAbsolutePath());
L.warning("Module factory directory not found: " + dir.getAbsolutePath());
return 0;
}
final File[] jars = dir.listFiles(new FileFilter() {
138,7 → 146,7
this.addFactory(new JarModuleFactory(jar));
i++;
} catch (Exception e) {
System.err.println("Couldn't add " + jar);
L.warning("Couldn't add " + jar);
e.printStackTrace();
}
}
168,7 → 176,9
 
private final String addFactory(final ModuleFactory f, final boolean start, final boolean persistent) {
synchronized (this.factories) {
this.factories.put(f.getID(), f);
final ModuleFactory prev = this.factories.put(f.getID(), f);
if (prev != null)
L.info("Changing the factory for " + f.getID() + "\nfrom\t" + prev + "\nto\t" + f);
}
if (start)
this.invoke(new IClosure<ModuleManager>() {
185,11 → 195,16
}
 
public final Map<String, ModuleFactory> getFactories() {
return Collections.unmodifiableMap(this.factories);
synchronized (this.factories) {
return new HashMap<String, ModuleFactory>(this.factories);
}
}
 
private ModuleFactory getFactory(final String id) {
final ModuleFactory res = this.factories.get(id);
final ModuleFactory res;
synchronized (this.factories) {
res = this.factories.get(id);
}
if (res == null)
throw new IllegalArgumentException("No factory for " + id);
return res;
235,8 → 250,10
// *** modules (in EDT)
 
/**
* Call the passed closure at a time when modules can be started. In particular the
* {@link MainFrame#getInstance() main frame} has been created.
* Call the passed closure at a time when modules can be started. In particular this manager has
* been set up and the {@link MainFrame#getInstance() main frame} has been created.
*
* @param c the closure to execute.
*/
public void invoke(final IClosure<ModuleManager> c) {
MainFrame.invoke(new Runnable() {
251,14 → 268,14
// (e.g. if a module created a child table, as long as the table is in the database it needs to
// be archived along its parent)
private void registerRequiredModules() throws Exception {
assert SwingUtilities.isEventDispatchThread();
final List<String> modulesToStart = new ArrayList<String>();
try {
final Map<String, ModuleFactory> factories = this.getFactories();
for (final Entry<String, ModuleVersion> e : this.getDBInstalledModules().entrySet()) {
final String moduleID = e.getKey();
// modules that just add non-key fields are not required
if (this.areElementsNeeded(moduleID)) {
final ModuleFactory moduleFactory = this.getFactories().get(moduleID);
final ModuleFactory moduleFactory = factories.get(moduleID);
final String error;
if (moduleFactory == null)
error = "Module '" + moduleID + "' non disponible.";
269,8 → 286,7
error = null;
if (error != null) {
// TODO open GUI to resolve the issue
ExceptionHandler.handle(error);
return;
throw new Exception(error);
} else {
modulesToStart.add(moduleID);
}
277,30 → 293,40
}
}
} catch (Exception e) {
ExceptionHandler.die("Impossible de déterminer les modules requis", e);
return;
throw new Exception("Impossible de déterminer les modules requis", e);
}
final Tuple2<Map<String, AbstractModule>, Set<String>> modules = this.createModules(modulesToStart, false);
final Tuple2<Map<String, AbstractModule>, Set<String>> modules = this.createModules(modulesToStart, false, true);
if (modules.get1().size() > 0)
ExceptionHandler.die("Impossible de créer les modules " + modules.get1());
throw new Exception("Impossible de créer les modules " + modules.get1());
for (final AbstractModule m : modules.get0().values())
this.registerSQLElements(m);
}
 
/**
* Initialize the module manager.
* Initialise the module manager.
*
* @return the exception, if any, thrown when starting previously running modules.
* @param root the root where the modules install.
* @param conf the configuration the modules change.
* @throws Exception if required modules couldn't be registered.
*/
public final Exception setup() throws Exception {
public synchronized final void setup(final DBRoot root, final Configuration conf) throws Exception {
if (root == null || conf == null)
throw new NullPointerException();
if (this.root != null || getConf() != null)
throw new IllegalStateException("Already setup");
// modulesElements can be non empty, if a previous setup() failed
assert this.runningModules.isEmpty() && this.modulesComponents.isEmpty() : "Modules cannot start without root & conf";
this.root = root;
this.conf = conf;
try {
this.registerRequiredModules();
try {
this.startPreviouslyRunningModules();
return null;
} catch (Exception e) {
return e;
// allow setup() to be called again
this.root = null;
this.conf = null;
throw e;
}
assert this.runningModules.isEmpty() && this.modulesComponents.isEmpty() : "registerRequiredModules() should not start modules";
}
 
private Preferences getPrefs() {
307,7 → 333,7
// modules are installed per business entity (perhaps we could add a per user option, i.e.
// for all businesses of all databases)
final StringBuilder path = new StringBuilder(32);
for (final String item : DBFileCache.getJDBCAncestorNames(Configuration.getInstance().getRoot(), true)) {
for (final String item : DBFileCache.getJDBCAncestorNames(getRoot(), true)) {
path.append(StringUtils.getBoundedLengthString(DBItemFileCache.encode(item), Preferences.MAX_NAME_LENGTH));
path.append('/');
}
320,49 → 346,56
return getPrefs().node("toRun");
}
 
private Preferences getInstalledPrefs() {
return getPrefs().node("installed");
}
 
protected final boolean isModuleInstalledLocally(String id) {
return getInstalledPrefs().getLong(id, NO_VERSION) != NO_VERSION;
return getLocalVersionFile(id).exists();
}
 
protected final ModuleVersion getModuleVersionInstalledLocally(String id) {
final long v = getInstalledPrefs().getLong(id, NO_VERSION);
return v == NO_VERSION ? null : new ModuleVersion(v);
final File versionFile = getLocalVersionFile(id);
if (versionFile.exists()) {
try {
return new ModuleVersion(Long.valueOf(FileUtils.read(versionFile)));
} catch (IOException e) {
throw new IllegalStateException("Couldn't get installed version of " + id, e);
}
} else {
return null;
}
}
 
public final Collection<String> getModulesInstalledLocally() {
try {
return Arrays.asList(getInstalledPrefs().keys());
} catch (BackingStoreException e) {
throw new IllegalStateException("Couldn't fetch installed preferences", e);
return getModulesVersionInstalledLocally().keySet();
}
}
 
public final Map<String, ModuleVersion> getModulesVersionInstalledLocally() {
final Preferences prefs = getInstalledPrefs();
final Map<String, ModuleVersion> res = new HashMap<String, ModuleVersion>();
try {
for (final String key : prefs.keys())
res.put(key, new ModuleVersion(prefs.getLong(key, NO_VERSION)));
} catch (BackingStoreException e) {
throw new IllegalStateException("Couldn't fetch installed preferences", e);
final File dir = getLocalDirectory();
for (final File d : dir.listFiles()) {
final String id = d.getName();
final ModuleVersion version = getModuleVersionInstalledLocally(id);
if (version != null)
res.put(id, version);
}
return res;
}
 
private void setModuleInstalledLocally(ModuleFactory f, boolean b) {
try {
if (b) {
final ModuleVersion vers = f.getVersion();
if (vers.getMerged() < MIN_VERSION)
throw new IllegalStateException("Invalid version : " + vers);
getInstalledPrefs().putLong(f.getID(), vers.getMerged());
final File versionFile = getLocalVersionFile(f.getID());
FileUtils.mkdir_p(versionFile.getParentFile());
FileUtils.write(String.valueOf(vers.getMerged()), versionFile);
} else {
getInstalledPrefs().remove(f.getID());
// perhaps add a parameter to only remove the versionFile
FileUtils.rm_R(getLocalDirectory(f.getID()));
}
} catch (IOException e) {
throw new IllegalStateException("Couldn't change installed status of " + f, e);
}
}
 
private SQLTable getInstalledTable(final DBRoot r) throws SQLException {
if (!r.contains(FWK_MODULE_TABLENAME)) {
381,7 → 414,7
 
createTable.addUniqueConstraint("uniqModule", Arrays.asList(MODULE_COLNAME, TABLE_COLNAME, FIELD_COLNAME));
 
SQLUtils.executeAtomic(Configuration.getInstance().getSystemRoot().getDataSource(), new SQLFactory<Object>() {
SQLUtils.executeAtomic(getDS(), new SQLFactory<Object>() {
@Override
public Object create() throws SQLException {
r.getDBSystemRoot().getDataSource().execute(createTable.asString());
395,10 → 428,34
return r.getTable(FWK_MODULE_TABLENAME);
}
 
private DBRoot getRoot() {
return ((ComptaBasePropsConfiguration) Configuration.getInstance()).getRootSociete();
protected final DBRoot getRoot() {
return this.root;
}
 
private SQLDataSource getDS() {
return getRoot().getDBSystemRoot().getDataSource();
}
 
protected final Configuration getConf() {
return this.conf;
}
 
private SQLElementDirectory getDirectory() {
return getConf().getDirectory();
}
 
private final File getLocalDirectory() {
return new File(this.getConf().getConfDir(getRoot()), "modules");
}
 
protected final File getLocalDirectory(final String id) {
return new File(this.getLocalDirectory(), id);
}
 
private final File getLocalVersionFile(final String id) {
return new File(this.getLocalDirectory(id), "version");
}
 
public final ModuleVersion getDBInstalledModuleVersion(final String id) throws SQLException {
return getDBInstalledModules(id).get(id);
}
531,40 → 588,91
return (Boolean) installedTable.getDBSystemRoot().getDataSource().executeScalar(sel.asString());
}
 
private void install(final AbstractModule module) throws SQLException {
private void install(final AbstractModule module) throws Exception {
final ModuleFactory factory = module.getFactory();
if (!isModuleInstalledLocally(factory.getID())) {
final ModuleVersion localVersion = getModuleVersionInstalledLocally(factory.getID());
final ModuleVersion lastInstalledVersion = getDBInstalledModuleVersion(factory.getID());
if (lastInstalledVersion != null && module.getFactory().getVersion().compareTo(lastInstalledVersion) < 0)
throw new IllegalArgumentException("Module older than the one installed in the DB : " + module.getFactory().getVersion() + " < " + lastInstalledVersion);
SQLUtils.executeAtomic(Configuration.getInstance().getSystemRoot().getDataSource(), new SQLFactory<Object>() {
final ModuleVersion moduleVersion = module.getFactory().getVersion();
if (lastInstalledVersion != null && moduleVersion.compareTo(lastInstalledVersion) < 0)
throw new IllegalArgumentException("Module older than the one installed in the DB : " + moduleVersion + " < " + lastInstalledVersion);
if (localVersion != null && moduleVersion.compareTo(localVersion) < 0)
throw new IllegalArgumentException("Module older than the one installed locally : " + moduleVersion + " < " + localVersion);
if (!moduleVersion.equals(localVersion) || !moduleVersion.equals(lastInstalledVersion)) {
// local
final File localDir = getLocalDirectory(factory.getID());
// There are 2 choices to handle the update of files :
// 1. copy dir to a new one and pass it to DBContext, then either rename it to dir or
// rename it failed
// 2. copy dir to a backup, pass dir to DBContext, then either remove backup or rename
// it to dir
// Choice 2 is simpler since the module deals with the same directory in both install()
// and start()
final File backupDir;
// check if we need a backup
if (localDir.exists()) {
backupDir = FileUtils.addSuffix(localDir, ".backup");
FileUtils.rm_R(backupDir);
FileUtils.copyDirectory(localDir, backupDir);
} else {
backupDir = null;
FileUtils.mkdir_p(localDir);
}
assert localDir.exists();
try {
SQLUtils.executeAtomic(getDS(), new ConnectionHandlerNoSetup<Object, IOException>() {
@Override
public Object create() throws SQLException {
public Object handle(SQLDataSource ds) throws SQLException, IOException {
final Tuple2<Set<String>, Set<SQLName>> alreadyCreatedItems = getCreatedItems(factory.getID());
final DBContext ctxt = new DBContext(lastInstalledVersion, getRoot(), alreadyCreatedItems.get0(), alreadyCreatedItems.get1());
final DBContext ctxt = new DBContext(localDir, localVersion, getRoot(), lastInstalledVersion, alreadyCreatedItems.get0(), alreadyCreatedItems.get1());
// install local
module.install(ctxt);
 
// install local
setModuleInstalledLocally(factory, true);
if (!localDir.exists())
throw new IOException("Modules shouldn't remove their directory");
// install in DB
ctxt.execute();
updateModuleFields(factory, ctxt);
 
return null;
}
});
} catch (Exception e) {
// install did not complete successfully
if (getRoot().getServer().getSQLSystem() == SQLSystem.MYSQL)
L.warning("MySQL cannot rollback DDL statements");
// keep failed install files and restore previous files
final File failed = FileUtils.addSuffix(localDir, ".failed");
if (failed.exists() && !FileUtils.rmR(failed))
L.warning("Couldn't remove " + failed);
if (!localDir.renameTo(failed)) {
L.warning("Couldn't move " + localDir + " to " + failed);
} else {
assert !localDir.exists();
// restore if needed
if (backupDir != null && !backupDir.renameTo(localDir))
L.warning("Couldn't restore " + backupDir + " to " + localDir);
}
throw e;
}
// DB transaction was committed, remove backup files
assert localDir.exists();
if (backupDir != null)
FileUtils.rm_R(backupDir);
setModuleInstalledLocally(factory, true);
}
assert moduleVersion.equals(getModuleVersionInstalledLocally(factory.getID())) && moduleVersion.equals(getDBInstalledModuleVersion(factory.getID()));
}
 
private void registerSQLElements(final AbstractModule module) {
final String id = module.getFactory().getID();
synchronized (this.modulesElements) {
if (!this.modulesElements.containsKey(id)) {
final SQLElementDirectory dir = Configuration.getInstance().getDirectory();
final SQLElementDirectory dir = getDirectory();
final Map<SQLTable, SQLElement> beforeElements = new HashMap<SQLTable, SQLElement>(dir.getElementsMap());
module.setupElements(dir);
final Collection<SQLElement> elements = new ArrayList<SQLElement>();
final Collection<SQLElement> newElements = CollectionUtils.substract(new IdentityHashSet<SQLElement>(dir.getElements()), new IdentityHashSet<SQLElement>(beforeElements.values()));
for (final SQLElement elem : newElements) {
// use IdentitySet so as not to call equals() since it triggers initFF()
final IdentitySet<SQLElement> beforeElementsSet = new IdentityHashSet<SQLElement>(beforeElements.values());
for (final SQLElement elem : dir.getElements()) {
if (!beforeElementsSet.contains(elem)) {
// don't let elements be replaced (it's tricky to restore in unregister())
if (beforeElements.containsKey(elem.getTable())) {
L.warning("Trying to replace element for " + elem.getTable() + " with " + elem);
573,14 → 681,16
elements.add(elem);
}
}
}
this.modulesElements.put(id, elements);
}
}
}
 
private void setupComponents(final AbstractModule module) throws SQLException {
final String id = module.getFactory().getID();
if (!this.modulesComponents.containsKey(id)) {
final SQLElementDirectory dir = Configuration.getInstance().getDirectory();
final SQLElementDirectory dir = getDirectory();
final Tuple2<Set<String>, Set<SQLName>> alreadyCreatedItems = getCreatedItems(id);
final ComponentsContext ctxt = new ComponentsContext(dir, getRoot(), alreadyCreatedItems.get0(), alreadyCreatedItems.get1());
module.setupComponents(ctxt);
588,7 → 698,7
}
}
 
protected final void startPreviouslyRunningModules() throws Exception {
public final void startPreviouslyRunningModules() throws Exception {
final List<String> ids = Arrays.asList(getRunningIDsPrefs().keys());
startModules(ids);
}
615,15 → 725,16
}
 
private final Set<String> startModules(final Collection<String> ids) throws Exception {
return this.createModules(ids, true).get1();
return this.createModules(ids, true, false).get1();
}
 
// modules created, and the ones that couldn't
// i.e. if a module was already created it's in neither
private final Tuple2<Map<String, AbstractModule>, Set<String>> createModules(final Collection<String> ids, final boolean start) throws Exception {
assert SwingUtilities.isEventDispatchThread();
private final Tuple2<Map<String, AbstractModule>, Set<String>> createModules(final Collection<String> ids, final boolean start, final boolean inSetup) throws Exception {
// in setup we're not in the EDT, but it's OK since by definition no modules are started
assert SwingUtilities.isEventDispatchThread() || inSetup && this.runningModules.isEmpty();
// add currently running modules so that ModuleFactory can use them
final Map<String, AbstractModule> modules = new LinkedHashMap<String, AbstractModule>(this.runningModules);
final Map<String, AbstractModule> modules = inSetup ? new LinkedHashMap<String, AbstractModule>(ids.size() * 2) : new LinkedHashMap<String, AbstractModule>(this.runningModules);
final Set<String> cannotCreate = new HashSet<String>();
final LinkedHashMap<ModuleFactory, Boolean> map = new LinkedHashMap<ModuleFactory, Boolean>();
synchronized (this.factories) {
640,6 → 751,7
}
}
// only keep modules created by this method
if (!inSetup)
modules.keySet().removeAll(this.runningModules.keySet());
 
if (start) {
667,7 → 779,7
final InputStream labels = module.getClass().getResourceAsStream("labels.xml");
if (labels != null) {
try {
Configuration.getInstance().getTranslator().load(getRoot(), labels);
getConf().getTranslator().load(getRoot(), labels);
} finally {
labels.close();
}
735,13 → 847,15
 
private void unregisterSQLElements(final AbstractModule module) {
final String id = module.getFactory().getID();
synchronized (this.modulesElements) {
if (this.modulesElements.containsKey(id)) {
final Collection<SQLElement> elements = this.modulesElements.remove(id);
final SQLElementDirectory dir = Configuration.getInstance().getDirectory();
final SQLElementDirectory dir = getDirectory();
for (final SQLElement elem : elements)
dir.removeSQLElement(elem);
}
}
}
 
private void tearDownComponents(final AbstractModule module) {
final String id = module.getFactory().getID();
893,22 → 1007,22
 
final AbstractModule module;
if (!this.isModuleRunning(id)) {
module = this.createModules(Collections.singleton(id), false).get0().get(id);
module = this.createModules(Collections.singleton(id), false, false).get0().get(id);
} else {
module = this.runningModules.get(id);
this.stopModule(id, true);
}
 
SQLUtils.executeAtomic(Configuration.getInstance().getSystemRoot().getDataSource(), new SQLFactory<Object>() {
SQLUtils.executeAtomic(getDS(), new SQLFactory<Object>() {
@Override
public Object create() throws SQLException {
module.uninstall();
final DBRoot root = getRoot();
module.uninstall(root);
unregisterSQLElements(module);
setModuleInstalledLocally(module.getFactory(), false);
 
// uninstall from DB
final Tuple2<Set<String>, Set<SQLName>> createdItems = getCreatedItems(id);
final DBRoot root = getRoot();
final List<ChangeTable<?>> l = new ArrayList<ChangeTable<?>>();
final Set<String> tableNames = createdItems.get0();
for (final SQLName field : createdItems.get1()) {
/trunk/OpenConcerto/src/org/openconcerto/erp/action/NouvelleConnexionAction.java
22,6 → 22,7
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.core.humanresources.payroll.element.CaisseCotisationSQLElement;
import org.openconcerto.erp.element.objet.ClasseCompte;
import org.openconcerto.erp.modules.ModuleManager;
import org.openconcerto.erp.panel.ComptaTipsFrame;
import org.openconcerto.erp.utils.NXDatabaseAccessor;
import org.openconcerto.map.model.Ville;
113,7 → 114,16
}
comptaPropsConfiguration.setUpSocieteDataBaseConnexion(selectedSociete);
 
// finish filling the configuration before going any further, otherwise the
// SQLElementDirectory is not coherent
try {
ModuleManager.getInstance().setup(comptaPropsConfiguration.getRootSociete(), comptaPropsConfiguration);
} catch (Exception e) {
// not OK to continue without required elements
ExceptionHandler.die("Impossible de démarrer les modules requis", e);
}
 
 
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
127,6 → 137,15
f.setTitle(comptaPropsConfiguration.getAppName() + " " + version + socTitle);
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
 
// start modules before displaying the frame (e.g. avoid modifying a
// visible menu bar)
try {
ModuleManager.getInstance().startPreviouslyRunningModules();
} catch (Exception exn) {
// OK to continue without all modules started
ExceptionHandler.handle(f, "Impossible de démarrer les modules", exn);
}
 
FrameUtil.show(f);
}
});
/trunk/OpenConcerto/src/org/openconcerto/erp/action/SauvegardeBaseAction.java
28,6 → 28,7
import org.openconcerto.erp.core.sales.order.report.CommandeClientXmlSheet;
import org.openconcerto.erp.core.sales.quote.report.DevisXmlSheet;
import org.openconcerto.erp.core.sales.shipment.report.BonLivraisonXmlSheet;
import org.openconcerto.erp.generationDoc.DocumentLocalStorageManager;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.gestcomm.AvoirClientXmlSheet;
import org.openconcerto.erp.generationDoc.gestcomm.AvoirFournisseurXmlSheet;
74,47 → 75,15
locations.add(serverIp.substring(5));
}
 
final DocumentLocalStorageManager storage = DocumentLocalStorageManager.getInstance();
 
locations.add(defaultLocation);
locations.add(SheetXml.getLocationForTuple(DevisXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(DevisXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(VenteFactureXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(VenteFactureXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(CommandeClientXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(CommandeClientXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(BonLivraisonXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(BonLivraisonXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(AvoirClientXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(AvoirClientXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(AvoirFournisseurXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(AvoirFournisseurXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(CommandeXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(CommandeXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(EtatVentesXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(EtatVentesXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(FicheClientXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(FicheClientXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(FicheRelanceSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(FicheRelanceSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(ReleveChequeSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(ReleveChequeSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(ReleveChequeEmisSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(ReleveChequeEmisSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(ListeFactureXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(ListeFactureXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(ListeVenteXmlSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(ListeVenteXmlSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(EtatChargesPayeSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(EtatChargesPayeSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(FichePayeSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(FichePayeSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(LivrePayeSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(LivrePayeSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(BalanceSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(BalanceSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(GrandLivreSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(GrandLivreSheet.getTuple2Location(), false));
locations.add(SheetXml.getLocationForTuple(JournauxSheet.getTuple2Location(), true));
locations.add(SheetXml.getLocationForTuple(JournauxSheet.getTuple2Location(), false));
for (File f : storage.getAllDocumentDirectories()) {
locations.add(f.getAbsolutePath());
}
for (File f : storage.getAllPDFDirectories()) {
locations.add(f.getAbsolutePath());
}
 
for (String string : locations) {
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractJOOReportsSheet.java
41,7 → 41,6
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
 
 
public abstract class AbstractJOOReportsSheet {
private static final String defaultLocationTemplate = SpreadSheetGenerator.defaultLocationTemplate;
protected static final DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
49,8 → 48,7
protected static final DateFormat yearFormat = new SimpleDateFormat("yyyy");
private String year;
protected String locationTemplate = TemplateNXProps.getInstance().getStringProperty("LocationTemplate");
private String locationOO, locationPDF;
protected String templateFileName;
protected String templateId;
private String printer;
protected boolean askOverwriting = false;
 
61,11 → 59,9
 
abstract public String getFileName();
 
protected void init(String year, String templateFileName, String attributePrinter, Tuple2<String, String> t) {
protected void init(String year, String templateId, String attributePrinter) {
this.year = year;
this.templateFileName = templateFileName;
this.locationOO = SheetXml.getLocationForTuple(t, false) + File.separator + this.year;
this.locationPDF = SheetXml.getLocationForTuple(t, true) + File.separator + this.year;
this.templateId = templateId;
this.printer = PrinterNXProps.getInstance().getStringProperty(attributePrinter);
}
 
88,27 → 84,23
try {
 
String fileName = getFileName();
final InputStream fileTemplate = getStream(this.templateFileName, this.locationTemplate, defaultLocationTemplate);
 
File fileOutOO = new File(this.locationOO, fileName + ".odt");
// File fileOutPDF = new File(locationPropositionPDF, fileName);
 
final InputStream fileTemplate = TemplateManager.getInstance().getTemplate(this.templateId);
File outputDir = DocumentLocalStorageManager.getInstance().getDocumentOutputDirectory(this.templateId);
File fileOutOO = getDocumentFile();
if (fileOutOO.exists() && overwrite) {
if (this.askOverwriting) {
int answer = JOptionPane.showConfirmDialog(null, "Voulez vous écraser le document ?", "Remplacement d'un document", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION) {
SheetUtils.getInstance().convertToOldFile(fileName, new File(this.locationOO), fileOutOO, ".odt");
SheetUtils.convertToOldFile(fileName, outputDir, fileOutOO, ".odt");
}
} else {
SheetUtils.getInstance().convertToOldFile(fileName, new File(this.locationOO), fileOutOO, ".odt");
SheetUtils.convertToOldFile(fileName, outputDir, fileOutOO, ".odt");
}
}
 
if (!fileOutOO.exists()) {
fileOutOO.getParentFile().mkdirs();
Template template;
// try {
template = new Template(new BufferedInputStream(fileTemplate));
Template template = new Template(new BufferedInputStream(fileTemplate));
 
// creation du document
final Map createMap = createMap();
116,11 → 108,7
 
model.putAll(createMap);
template.createDocument(model).saveAs(fileOutOO);
// template.createDocument(model, new BufferedOutputStream(new
// FileOutputStream(fileOutOO)));
// } catch (JDOMException e) {
// e.printStackTrace();
// }
 
}
 
// ouverture de OO
133,9 → 121,10
}
final Component doc = ooConnexion.loadDocument(fileOutOO, !show);
 
if (this.savePDF())
doc.saveToPDF(new File(this.locationPDF, fileName + ".pdf"), "writer_pdf_Export");
 
if (this.savePDF()) {
File pdfOutputDir = DocumentLocalStorageManager.getInstance().getPDFOutputDirectory(templateId);
doc.saveToPDF(new File(pdfOutputDir, fileName + ".pdf"), "writer_pdf_Export");
}
if (print) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("Name", printer);
164,7 → 153,7
}
 
public void showDocument() {
File fileOutOO = new File(this.locationOO, getFileName() + ".odt");
File fileOutOO = getDocumentFile();
if (fileOutOO.exists()) {
try {
final OOConnexion ooConnexion = ComptaPropsConfiguration.getOOConnexion();
183,8 → 172,13
}
}
 
private File getDocumentFile() {
File outputDir = DocumentLocalStorageManager.getInstance().getDocumentOutputDirectory(templateId);
return new File(outputDir, getFileName() + ".odt");
}
 
public void printDocument() {
File fileOutOO = new File(this.locationOO, getFileName() + ".odt");
File fileOutOO = getDocumentFile();
if (fileOutOO.exists()) {
 
try {
211,7 → 205,7
 
public void fastPrintDocument() {
 
final File f = new File(this.locationOO, getFileName() + ".odt");
final File f = getDocumentFile();
 
if (!f.exists()) {
generate(true, false, this.printer);
239,13 → 233,6
}
}
 
public boolean exists() {
 
String fileName = getFileName();
File fileOutOO = new File(this.locationOO, fileName + ".odt");
return fileOutOO.exists();
}
 
protected String getInitiales(SQLRow row) {
String init = "";
if (row != null) {
264,9 → 251,10
public void exportToPdf() {
 
// Export vers PDF
String fileName = getFileName();
File fileOutOO = new File(this.locationOO, fileName + ".odt");
File fileOutPDF = new File(this.locationPDF, fileName);
final String fileName = getFileName();
final File fileOutOO = getDocumentFile();
final File outputPDFDirectory = DocumentLocalStorageManager.getInstance().getPDFOutputDirectory(this.templateId);
final File fileOutPDF = new File(outputPDFDirectory, fileName + ".pdf");
 
if (!fileOutOO.exists()) {
generate(false, false, "");
290,7 → 278,7
int result = JOptionPane.showOptionDialog(null, "Ouvrir le pdf ?", "Ouverture du PDF", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
 
if (result == JOptionPane.YES_OPTION) {
Gestion.openPDF(new File(fileOutPDF.getAbsolutePath() + ".pdf"));
Gestion.openPDF(fileOutPDF);
} else {
try {
FileUtils.openFile(fileOutPDF.getParentFile());
317,10 → 305,6
return ville.getName();
}
 
public String getLocationOO() {
return locationOO;
}
 
protected static String getVilleCP(String name) {
Ville ville = Ville.getVilleFromVilleEtCode(name);
if (ville == null) {
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/DocumentGenerator.java
New file
0,0 → 1,27
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import java.util.Map;
 
public interface DocumentGenerator {
 
/**
* Define the context for the creation of the document Keys of the context are defined in the
* objects implementing the interface
* */
public void setContext(Map<String, Object> context);
 
public void createDocument();
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractLocalTemplateProvider.java
New file
0,0 → 1,73
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
 
public abstract class AbstractLocalTemplateProvider implements TemplateProvider {
 
@Override
public InputStream getTemplate(String templateId, String langage, String type) {
try {
final File templateFile = getTemplateFile(templateId, langage, type);
if (templateFile == null || !templateFile.exists()) {
return null;
}
return new FileInputStream(templateFile);
} catch (FileNotFoundException e) {
return null;
}
}
 
@Override
public InputStream getTemplatePrintConfiguration(String templateId, String langage, String type) {
final File t = getTemplateFile(templateId, langage, type);
final String name = t.getName();
if (name.toLowerCase().endsWith(".ods")) {
final File file = new File(t.getParent(), name.substring(0, name.length() - 4) + ".odsp");
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
System.err.println("No print configuration " + file.getAbsolutePath() + " for template id: " + templateId);
e.printStackTrace();
}
}
return null;
}
 
@Override
public InputStream getTemplateConfiguration(String templateId, String langage, String type) {
final File t = getTemplateFile(templateId, langage, type);
final String name = t.getName();
if (name.toLowerCase().endsWith(".ods")) {
final File file = new File(t.getParent(), name.substring(0, name.length() - 4) + ".xml");
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
System.err.println("No template configuration " + file.getAbsolutePath() + " for template id: " + templateId);
e.printStackTrace();
}
}
return null;
}
 
public abstract File getTemplateFile(String templateId, String langage, String type);
 
@Override
public abstract String getTemplatePath(String templateId, String langage, String type);
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/TemplateProvider.java
New file
0,0 → 1,38
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import java.io.InputStream;
 
public interface TemplateProvider {
/**
* Path: ex ILM/Devis
* */
public String getTemplatePath(String templateId, String language, String type);
 
/**
* Returns the content of template file (ex: the ODS file)
* */
public InputStream getTemplate(String templateId, String language, String type);
 
/**
* Returns the content of template configuration file (ex: the odsp file)
* */
public InputStream getTemplateConfiguration(String templateId, String language, String type);
 
/**
* Returns the content of template print configuration file (ex: the odsp file)
* */
public InputStream getTemplatePrintConfiguration(String templateId, String language, String type);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetInterface.java
18,11 → 18,12
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.utils.StringUtils;
 
import java.io.File;
import java.util.HashMap;
import java.util.Map;
 
 
public abstract class SheetInterface {
 
// SQLRow de l'élément de la table qui est utilisé pour la génération
46,12 → 47,6
// modele du document
protected String modele;
 
// emplacement du fichier OO généré
protected String locationOO;
 
// emplacement du fichier PDF généré
protected String locationPDF;
 
// nom du futur fichier
protected String fileName;
 
64,14 → 59,6
 
protected static final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
 
public String getLocationOO() {
return this.locationOO;
}
 
public String getLocationPDF() {
return this.locationPDF;
}
 
public int getNbPage() {
return this.nbPage;
}
114,6 → 101,17
return this.mCell;
}
 
protected abstract String getYear();
 
public File getDocumentOutputDirectory() {
return new File(DocumentLocalStorageManager.getInstance().getDocumentOutputDirectory(this.getTemplateId()), getYear());
}
 
public File getPDFOutputDirectory() {
return new File(DocumentLocalStorageManager.getInstance().getPDFOutputDirectory(this.getTemplateId()), getYear());
}
 
protected abstract void createMap();
 
public abstract String getTemplateId();
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetUtils.java
13,6 → 13,8
package org.openconcerto.erp.generationDoc;
 
import org.openconcerto.utils.ExceptionHandler;
 
import java.awt.Graphics2D;
import java.io.File;
import java.io.FileOutputStream;
36,16 → 38,8
 
public class SheetUtils {
 
static SheetUtils instance;
 
public static SheetUtils getInstance() {
if (instance == null) {
instance = new SheetUtils();
}
return instance;
}
 
public File convertToOldFile(String fileName, File pathDest, File fDest) {
public static File convertToOldFile(String fileName, File pathDest, File fDest) {
// FIXME: !!!!!!!!
return convertToOldFile(fileName, pathDest, fDest, ".ods");
}
 
57,7 → 51,7
* @param fDest
* @return
*/
public File convertToOldFile(String fileName, File pathDest, File fDest, String extension) {
public static File convertToOldFile(String fileName, File pathDest, File fDest, String extension) {
if (fDest.exists()) {
int i = 0;
String destName = fileName;
92,7 → 86,7
return fDest;
}
 
public List<File> getHistorique(final String fileName, File pathDest) {
public static List<File> getHistorique(final String fileName, File pathDest) {
File pathOld = new File(pathDest, "Historique");
File[] files = pathOld.listFiles(new FilenameFilter() {
 
118,44 → 112,24
return result;
}
 
public static void main(String[] args) {
final OpenDocument doc = new OpenDocument(new File("E:/Facture_FACT1108-5785.ods"));
try {
SheetUtils.getInstance().convert2PDF(doc, new File("E:/test"), "test");
} catch (Exception exn) {
// TODO Bloc catch auto-généré
exn.printStackTrace();
}
}
public static void convert2PDF(final OpenDocument doc, final File pdfFileToCreate) throws Exception {
 
public void convert2PDF(final OpenDocument doc, final File f, final String fileName) throws Exception {
 
SwingUtilities.invokeLater(new Runnable() {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
// TODO Raccord de méthode auto-généré
 
// Open the PDF document
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
File outFile = new File(f.getParent(), fileName + ".pdf");
FileOutputStream fileOutputStream;
 
try {
 
fileOutputStream = new FileOutputStream(outFile);
FileOutputStream fileOutputStream = new FileOutputStream(pdfFileToCreate);
 
// Create the writer
PdfWriter writer = PdfWriter.getInstance(document, fileOutputStream);
writer.setPdfVersion(PdfWriter.VERSION_1_6);
writer.setFullCompression();
// writer.setPageEmpty(true);
 
document.open();
// System.out.println(writer.getPageNumber());
// // Create a template and a Graphics2D object
// com.itextpdf.text.Rectangle pageSize = document.getPageSize();
// int w = (int) (pageSize.getWidth() * 0.9);
// int h = (int) (pageSize.getHeight() * 0.95);
 
PdfContentByte cb = writer.getDirectContent();
 
190,11 → 164,27
// writer.close();
fileOutputStream.close();
 
} catch (Exception exn) {
// TODO Bloc catch auto-généré
exn.printStackTrace();
} catch (Exception originalExn) {
ExceptionHandler.handle("Impossible de créer le PDF " + pdfFileToCreate.getAbsolutePath(), originalExn);
}
}
});
}
 
/**
* Get a new file with an other extension
*
* @param the file (ex: Test.ods)
* @param the extension (ex: pdf)
* */
static File getFileWithExtension(File file, String extension) {
if (!extension.startsWith(".")) {
extension = "." + extension;
}
String name = file.getName();
int i = name.lastIndexOf(".");
name = name.substring(0, i) + extension;
final File f = new File(file.getParent(), name);
return f;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetXml.java
17,7 → 17,8
import org.openconcerto.erp.core.common.ui.FastPrintAskFrame;
import org.openconcerto.erp.core.common.ui.PreviewFrame;
import org.openconcerto.erp.generationDoc.element.TypeModeleSQLElement;
import org.openconcerto.erp.preferences.TemplateNXProps;
import org.openconcerto.erp.storage.StorageEngine;
import org.openconcerto.erp.storage.StorageEngines;
import org.openconcerto.openoffice.OOUtils;
import org.jopendocument.link.Component;
import org.openconcerto.sql.Configuration;
25,13 → 26,17
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.Tuple2;
 
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
46,6 → 51,23
 
public abstract class SheetXml {
 
// return null to keep default value
public interface StorageDirs {
public File getDocumentOutputDirectory(SheetXml sheet);
 
public File getPDFOutputDirectory(SheetXml sheet);
 
public String getStoragePath(SheetXml sheet);
}
 
private static StorageDirs STORAGE_DIRS;
 
// allow to redirect all documents
public static void setStorageDirs(StorageDirs d) {
STORAGE_DIRS = d;
}
 
public static final String DEFAULT_PROPERTY_NAME = "Default";
protected SQLElement elt;
 
// nom de l'imprimante à utiliser
57,16 → 79,6
// Language du document
protected SQLRow rowLanguage;
 
// emplacement du fichier OO généré
protected String locationOO;
 
// emplacement du fichier PDF généré
protected String locationPDF;
 
protected File f;
 
public static final Tuple2<String, String> tupleDefault = Tuple2.create("Default", "Autres");
 
protected static final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
 
// single threaded and kill its thread after 3 seconds (to allow the program to exit)
79,62 → 91,98
}
};
 
public void useOO(final File f, final boolean visu, final boolean impression, final String fileName) {
useOO(f, visu, impression, fileName, true);
public final SQLElement getElement() {
return this.elt;
}
 
public void useOO(final File f, final boolean visu, final boolean impression, final String fileName, boolean exportPDF) {
/**
* Show, print and export the document to PDF. This method is asynchronous, but is executed in a
* single threaded queue shared with createDocument
* */
public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF) {
final Callable<SheetXml> c = new Callable<SheetXml>() {
@Override
public SheetXml call() throws Exception {
showPrintAndExport(showDocument, printDocument, exportToPDF);
return SheetXml.this;
}
};
return runnableQueue.submit(c);
 
if (f == null || fileName.trim().length() == 0) {
ExceptionHandler.handle("Erreur lors de la génération du fichier " + fileName);
}
 
/**
* Show, print and export the document to PDF. This method is synchronous
* */
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF) {
 
final File generatedFile = getGeneratedFile();
final File pdfFile = getGeneratedPDFFile();
if (generatedFile == null || !generatedFile.exists()) {
ExceptionHandler.handle("Fichier généré manquant: " + generatedFile);
return;
}
 
try {
if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(f, !visu);
final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(generatedFile, !showDocument);
 
if (exportPDF) {
doc.saveToPDF(getFilePDF()).get();
}
 
if (impression) {
if (printDocument) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("Name", this.printer);
doc.printDocument(map);
}
if (exportToPDF) {
doc.saveToPDF(pdfFile).get();
}
doc.close();
} else {
final OpenDocument doc = new OpenDocument(f);
final OpenDocument doc = new OpenDocument(generatedFile);
 
if (exportPDF) {
final Thread t = new Thread("PDF Export: " + fileName) {
if (showDocument) {
showPreviewDocument();
}
if (printDocument) {
// Print !
DefaultDocumentPrinter printer = new DefaultDocumentPrinter();
printer.print(doc);
 
}
if (exportToPDF) {
 
try {
SheetUtils.convert2PDF(doc, pdfFile);
 
} catch (Throwable e) {
ExceptionHandler.handle("Impossible de créer le PDF");
}
 
Thread t = new Thread(new Runnable() {
 
@Override
public void run() {
 
List<StorageEngine> engines = StorageEngines.getInstance().getActiveEngines();
for (StorageEngine storageEngine : engines) {
if (storageEngine.isConfigured() && storageEngine.allowAutoStorage()) {
try {
SheetUtils.getInstance().convert2PDF(doc, f, fileName);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
storageEngine.connect();
final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(pdfFile));
final String path = getStoragePath();
storageEngine.store(inStream, path, pdfFile.getName(), true);
inStream.close();
storageEngine.disconnect();
} catch (IOException e) {
ExceptionHandler.handle("Impossible de sauvegarder le PDF");
}
}
};
t.setPriority(Thread.MIN_PRIORITY);
t.start();
 
}
if (visu) {
showPreviewDocument();
}
if (impression) {
// Print !
DefaultDocumentPrinter printer = new DefaultDocumentPrinter();
printer.print(doc);
 
}
});
t.start();
 
}
}
 
} catch (Exception e) {
e.printStackTrace();
142,19 → 190,61
}
}
 
public abstract String getDefaultModele();
public abstract String getDefaultTemplateId();
 
// nom du modele sans extension
public String getModele() {
if (this.row.getTable().getFieldsName().contains("ID_MODELE")) {
/**
* Path of the directory used for storage. Ex: Devis/2010
* */
public final String getStoragePath() {
final String res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getStoragePath(this);
if (res != null)
return res;
else
return this.getStoragePathP();
}
 
public final File getDocumentOutputDirectory() {
final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getDocumentOutputDirectory(this);
if (res != null)
return res;
else
return this.getDocumentOutputDirectoryP();
}
 
public final File getPDFOutputDirectory() {
final File res = STORAGE_DIRS == null ? null : STORAGE_DIRS.getPDFOutputDirectory(this);
if (res != null)
return res;
else
return this.getPDFOutputDirectoryP();
}
 
protected abstract String getStoragePathP();
 
protected abstract File getDocumentOutputDirectoryP();
 
protected abstract File getPDFOutputDirectoryP();
 
/**
* Name of the generated document (without extension), do not rely on this name.
*
* Use getGeneratedFile().getName() to get the generated file name.
* */
public abstract String getName();
 
/**
* @return the template id for this template (ex: "sales.quote")
* */
public String getTemplateId() {
if (this.row != null && this.row.getTable().getFieldsName().contains("ID_MODELE")) {
SQLRow rowModele = this.row.getForeignRow("ID_MODELE");
if (rowModele.isUndefined()) {
TypeModeleSQLElement typeModele = Configuration.getInstance().getDirectory().getElement(TypeModeleSQLElement.class);
String modele = typeModele.getTemplateMapping().get(this.row.getTable());
String modele = typeModele.getTemplateMapping().get(this.row.getTable().getName());
if (modele == null) {
System.err.println("No default modele in table TYPE_MODELE for table " + this.row.getTable().getName());
Thread.dumpStack();
return getDefaultModele();
return getDefaultTemplateId();
} else {
return modele;
}
162,23 → 252,24
return rowModele.getString("NOM");
}
}
return getDefaultModele();
return getDefaultTemplateId();
}
 
public abstract Future<File> genere(final boolean visu, final boolean impression);
public abstract Future<SheetXml> createDocumentAsynchronous();
 
public abstract String getFileName();
 
private String getOOName() {
return getValidFileName(getFileName()) + ".ods";
public void createDocument() throws InterruptedException, ExecutionException {
createDocumentAsynchronous().get();
}
 
private String getPDFName() {
return getValidFileName(getFileName()) + ".pdf";
}
/**
* get the File that is, or must be generated.
*
* @return a file (not null)
* */
public abstract File getGeneratedFile();
 
private String getOO1Name() {
return getValidFileName(getFileName()) + ".sxc";
public File getGeneratedPDFFile() {
return SheetUtils.getFileWithExtension(getGeneratedFile(), ".pdf");
}
 
public SQLRow getRowLanguage() {
190,64 → 281,49
}
 
/**
* retourne l'emplacement de destination d'un Tuple<id (ex:LocationDevis), Nom (ex:Devis)>
*/
public static String getLocationForTuple(Tuple2<String, String> t, boolean pdf) {
 
final String stringProperty = TemplateNXProps.getInstance().getStringProperty(t.get0() + (pdf ? "PDF" : "OO"));
if (stringProperty.equalsIgnoreCase(TemplateNXProps.getInstance().getDefaultStringValue())) {
return stringProperty + File.separator + t.get1();
} else {
return stringProperty;
}
}
 
private File getFile() {
if (this.f != null) {
return f;
}
File f = new File(this.locationOO + File.separator + getOOName());
* Creates the document if needed and returns the generated file (OpenDocument)
* */
public File getOrCreateDocumentFile() throws Exception {
File f = getGeneratedFile();
if (!f.exists()) {
File f2 = new File(this.locationOO + File.separator + getOO1Name());
if (f2.exists()) {
return f2;
return createDocumentAsynchronous().get().getGeneratedFile();
} else {
return f;
}
} else {
return f;
}
}
 
public File getFilePDF() {
File f = new File(this.locationPDF + File.separator + getPDFName());
return f;
}
/**
* Open the document with the native application
*
* @param synchronous
* */
public void openDocument(boolean synchronous) {
Runnable r = new Runnable() {
 
public File getFileWithoutExt() {
File f = new File(this.locationPDF + File.separator + getValidFileName(getFileName()));
return f;
}
 
public File getFileODS() {
File f = new File(this.locationOO + File.separator + getOOName());
return f;
}
 
public void showDocument() {
final File f = getFile();
@Override
public void run() {
File f;
try {
f = getOrCreateDocumentFile();
OOUtils.open(f);
} catch (IOException e) {
ExceptionHandler.handle("Impossible d'ouvrir " + f.getAbsolutePath(), e);
} catch (Exception e) {
ExceptionHandler.handle("Impossible d'ouvrir le document.", e);
}
}
};
if (synchronous) {
r.run();
} else {
Thread thread = new Thread(r, "openDocument: " + getGeneratedFile().getAbsolutePath());
thread.setDaemon(true);
thread.start();
}
 
public void showPreviewDocument() {
if (!isFileOOExist()) {
genere(false, false);
}
final File f = getFile();
 
public void showPreviewDocument() throws Exception {
File f = null;
f = getOrCreateDocumentFile();
PreviewFrame.show(f);
}
 
257,9 → 333,10
}
 
public void fastPrintDocument(short copies) {
final File f = getFile();
 
try {
final File f = getOrCreateDocumentFile();
 
if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
 
final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(f, true);
295,9 → 372,9
}
 
public void printDocument() {
final File f = getFile();
 
try {
final File f = getOrCreateDocumentFile();
 
if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
 
320,20 → 397,10
}
}
 
public boolean isFileOOExist() {
final File f = getFile();
return f.exists();
}
 
public SQLRow getSQLRow() {
return this.row;
}
 
public boolean isFileODSExist() {
final File f = getFileODS();
return f.exists();
}
 
/**
* Remplace tous les caracteres non alphanumeriques (seul le _ est autorisé) par un -. Cela
* permet d'avoir toujours un nom de fichier valide.
341,14 → 408,14
* @param fileName nom du fichier à créer ex:FACTURE_2007/03/001
* @return un nom fichier valide ex:FACTURE_2007-03-001
*/
public static String getValidFileName(String fileName) {
StringBuffer result = new StringBuffer(fileName.length());
static String getValidFileName(String fileName) {
final StringBuffer result = new StringBuffer(fileName.length());
for (int i = 0; i < fileName.length(); i++) {
char c = fileName.charAt(i);
char ch = fileName.charAt(i);
 
// Si c'est un caractere alphanumerique
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '_') || (c == ' ')) {
result.append(c);
if (Character.isLetterOrDigit(ch) || (ch == '_') || (ch == ' ')) {
result.append(ch);
} else {
result.append('-');
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/ReleveChequeEmisSheet.java
41,19 → 41,23
createMap();
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationReleveCheque", "Relevé chéques émis");
public static final String TEMPLATE_ID = "ReleveChequeEmis";
public static final String TEMPLATE_PROPERTY_NAME = "LocationReleveCheque";
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
private void init() {
this.modele = "ReleveChequeEmis.ods";
// this.printer = PrinterNXProps.getInstance().getStringProperty("FacturePrinter");
this.locationOO = SheetXml.getLocationForTuple(tuple, false);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true);
}
 
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
@Override
protected String getYear() {
return "";
}
 
protected void createMap() {
 
long montantTotal = 0;
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/ReleveChequeSheet.java
15,13 → 15,11
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.Tuple2;
 
import java.text.DateFormat;
import java.text.SimpleDateFormat;
39,7 → 37,7
private long total = 0;
private long nb = 0;
private boolean apercu = false;
 
private static final SQLTable tableCheque = base.getTable("CHEQUE_A_ENCAISSER");
private List<Integer> listeIds;
 
public ReleveChequeSheet(List<Integer> listeIds, Date date) {
46,16 → 44,11
this(listeIds, date, false);
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationReleveChequeCli", "Relevé chéques clients");
public static final String TEMPLATE_ID = "ReleveCheque";
public static final String TEMPLATE_PROPERTY_NAME = "LocationReleveChequeCli";
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
public ReleveChequeSheet(List<Integer> listeIds, Date date, boolean apercu) {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.locationOO = SheetXml.getLocationForTuple(tuple, false);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true);
this.date = date;
this.apercu = apercu;
this.listeIds = listeIds;
62,11 → 55,14
}
 
@Override
public String getDefaultModele() {
return "ReleveCheque";
public String getName() {
return "ReleveCheque" + this.date.getTime();
}
 
private static final SQLTable tableCheque = base.getTable("CHEQUE_A_ENCAISSER");
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
protected void createListeValues() {
 
113,8 → 109,4
this.mapAllSheetValues.put(0, values);
}
 
public String getFileName() {
return getValidFileName("ReleveCheque" + this.date.getTime());
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/AvoirClientXmlSheet.java
14,27 → 14,16
package org.openconcerto.erp.generationDoc.gestcomm;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
public class AvoirClientXmlSheet extends AbstractSheetXMLWithDate {
 
public class AvoirClientXmlSheet extends AbstractSheetXml {
public static final String TEMPLATE_ID = "Avoir";
public static final String TEMPLATE_PROPERTY_NAME = "LocationAvoir";
 
private String startName;
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationAvoir", "Avoir");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
@Override
public SQLRow getRowLanguage() {
SQLRow rowClient = this.row.getForeignRow("ID_CLIENT");
49,24 → 38,16
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("AVOIR_CLIENT");
}
 
Calendar cal = Calendar.getInstance();
cal.setTime((Date) row.getObject("DATE"));
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
 
this.startName = "Avoir_";
 
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
@Override
public String getDefaultModele() {
 
return "Avoir";
public String getName() {
return "Avoir_" + this.row.getString("NUMERO");
}
 
public String getFileName() {
 
return getValidFileName(this.startName + this.row.getString("NUMERO"));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/EtatVentesXmlSheet.java
14,6 → 14,7
package org.openconcerto.erp.generationDoc.gestcomm;
 
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.generationDoc.DocumentLocalStorageManager;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
25,6 → 26,7
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
46,12 → 48,12
 
private static final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
 
public static final String TEMPLATE_ID = "EtatVentes";
 
public static final String TEMPLATE_PROPERTY_NAME = DEFAULT_PROPERTY_NAME;
 
private Timestamp du, au;
 
public static Tuple2<String, String> getTuple2Location() {
return tupleDefault;
}
 
public EtatVentesXmlSheet(Date du, Date au) {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
du.setHours(0);
61,18 → 63,18
this.du = new Timestamp(du.getTime());
this.au = new Timestamp(au.getTime());
 
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true);
}
 
 
 
@Override
public String getDefaultModele() {
 
return "EtatVentes";
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
public String getFileName() {
return getValidFileName("EtatVentes" + new Date().getTime());
@Override
public String getName() {
return "EtatVentes" + new Date().getTime();
}
 
protected void createListeValues() {
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/CommandeXmlSheet.java
13,25 → 13,16
package org.openconcerto.erp.generationDoc.gestcomm;
 
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
public class CommandeXmlSheet extends AbstractSheetXMLWithDate {
 
public class CommandeXmlSheet extends AbstractSheetXml {
public static final String TEMPLATE_ID = "Commande";
public static final String TEMPLATE_PROPERTY_NAME = "LocationCmd";
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationCmd", "Commande fournisseur");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
@Override
public SQLRow getRowLanguage() {
SQLRow rowFournisseur = this.row.getForeignRow("ID_FOURNISSEUR");
47,21 → 38,15
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("CmdPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("COMMANDE");
Calendar cal = Calendar.getInstance();
cal.setTime((Date) row.getObject("DATE"));
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
 
}
 
@Override
public String getDefaultModele() {
 
return "Commande";
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
public String getFileName() {
 
return getValidFileName("Commande_" + row.getString("NUMERO"));
@Override
public String getName() {
return "Commande_" + row.getString("NUMERO");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/AvoirFournisseurXmlSheet.java
13,42 → 13,29
package org.openconcerto.erp.generationDoc.gestcomm;
 
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
public class AvoirFournisseurXmlSheet extends AbstractSheetXMLWithDate {
 
public class AvoirFournisseurXmlSheet extends AbstractSheetXml {
public static final String TEMPLATE_ID = "AvoirF";
public static final String TEMPLATE_PROPERTY_NAME = "LocationAvoirF";
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationAvoirF", "Avoir Fournisseur");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
public AvoirFournisseurXmlSheet(SQLRow row) {
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("AVOIR_FOURNISSEUR");
Calendar cal = Calendar.getInstance();
cal.setTime((Date) row.getObject("DATE"));
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
}
 
@Override
public String getDefaultModele() {
// TODO Raccord de méthode auto-généré
return "AvoirF";
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
public String getFileName() {
return getValidFileName("AvoirF_" + this.row.getID());
@Override
public String getName() {
return "AvoirF_" + this.row.getID();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/PointageXmlSheet.java
14,7 → 14,6
package org.openconcerto.erp.generationDoc.gestcomm;
 
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
36,16 → 35,18
 
public class PointageXmlSheet extends AbstractListeSheetXml {
 
public static final String TEMPLATE_ID = "Pointage";
public static final String TEMPLATE_PROPERTY_NAME = DEFAULT_PROPERTY_NAME;
private Map<Integer, List<Map<String, Object>>> listAllSheetValues;
private Map<Integer, Map<Integer, String>> styleAllSheetValues;
private Map<Integer, Map<String, Object>> mapAllSheetValues;
private Calendar c = Calendar.getInstance();
private Date date = new Date();
private final long MILLIS_IN_HOUR = 3600000;
 
public PointageXmlSheet(int mois, int year) {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.mapAllSheetValues = new HashMap<Integer, Map<String, Object>>();
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true);
this.c.set(Calendar.DAY_OF_MONTH, 1);
this.c.set(Calendar.YEAR, year);
this.c.set(Calendar.MONTH, mois);
57,11 → 58,14
}
 
@Override
public String getDefaultModele() {
return "Pointage";
public String getName() {
return "Pointage" + this.date;
}
 
private long oneHour = 3600000;
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
protected void createListeValues() {
SQLElement eltPointage = Configuration.getInstance().getDirectory().getElement("POINTAGE");
124,6 → 128,7
sel.setHaving(Where.createRaw("COUNT (\"POINTAGE\".\"ID_USER_COMMON\") > 0", tablePointage.getField("ID_USER_COMMON")));
sel.addFieldOrder(tableUser.getField("NOM"));
System.err.println(sel.asString());
@SuppressWarnings("unchecked")
List<SQLRow> listUser = (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel, tableUser));
 
String entete = "Horaires de travail du mois de " + formatMonth.format(d1);
142,7 → 147,7
mapSheetValue.put("A1", userName);
mapSheetValue.put("F1", entete);
 
long tempsDePause = this.oneHour;
long tempsDePause = this.MILLIS_IN_HOUR;
 
// calcul du temps de pause si possible
if (row.getObject("HEURE_MATIN_D") != null && row.getObject("MINUTE_MATIN_D") != null && row.getObject("HEURE_MIDI_A") != null && row.getObject("MINUTE_MIDI_A") != null) {
173,8 → 178,8
// Temps travaillé dans la semaine
if (semaine > 0 && semaine != this.c.get(Calendar.WEEK_OF_YEAR)) {
Map<String, Object> mValues2 = new HashMap<String, Object>();
long hour = heureTotalSemaine / this.oneHour;
long minute = (heureTotalSemaine % this.oneHour) / 60000;
long hour = heureTotalSemaine / this.MILLIS_IN_HOUR;
long minute = (heureTotalSemaine % this.MILLIS_IN_HOUR) / 60000;
mValues2.put("HEURE_TOTAL", hour + "h" + minute);
heureTotalSemaine = 0;
listValues.add(mValues2);
207,6 → 212,7
sel2.setWhere(wDay);
sel2.addFieldOrder(table2.getField("DATE"));
 
@SuppressWarnings("unchecked")
List<SQLRow> list2 = (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel2.asString(), SQLRowListRSH.createFromSelect(sel2, table2));
 
if (list2.size() > 2) {
258,8 → 264,8
System.err.println("time " + time + " Worked :" + timeWorked);
heureTotalSemaine += timeWorked;
heureTotalMois += timeWorked;
long hour = timeWorked / this.oneHour;
long minute = (timeWorked % this.oneHour) / 60000;
long hour = timeWorked / this.MILLIS_IN_HOUR;
long minute = (timeWorked % this.MILLIS_IN_HOUR) / 60000;
mValues.put("HEURE_TOTAL", hour + "h" + minute);
 
} else {
278,8 → 284,8
 
// Heure de la derniere semaine
Map<String, Object> mValues2 = new HashMap<String, Object>();
long hour = heureTotalSemaine / this.oneHour;
long minute = (heureTotalSemaine % this.oneHour) / 60000;
long hour = heureTotalSemaine / this.MILLIS_IN_HOUR;
long minute = (heureTotalSemaine % this.MILLIS_IN_HOUR) / 60000;
mValues2.put("HEURE_TOTAL", hour + "h" + minute);
heureTotalSemaine = 0;
listValues.add(mValues2);
289,8 → 295,8
 
// Heure total du mois
Map<String, Object> mValuesMois = new HashMap<String, Object>();
hour = heureTotalMois / this.oneHour;
minute = (heureTotalMois % this.oneHour) / 60000;
hour = heureTotalMois / this.MILLIS_IN_HOUR;
minute = (heureTotalMois % this.MILLIS_IN_HOUR) / 60000;
mValuesMois.put("HEURE_TOTAL", hour + "h" + minute);
heureTotalMois = 0;
 
315,9 → 321,4
 
}
 
Date date = new Date();
 
public String getFileName() {
return getValidFileName("Pointage" + this.date);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/FicheRelanceSheet.java
14,11 → 14,9
package org.openconcerto.erp.generationDoc.gestcomm;
 
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.Tuple2;
 
import java.text.DateFormat;
import java.text.SimpleDateFormat;
31,29 → 29,23
public class FicheRelanceSheet extends AbstractListeSheetXml {
 
private static final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
private SQLRow row;
public static final String TEMPLATE_ID = "FicheRelance";
public static final String TEMPLATE_PROPERTY_NAME = DEFAULT_PROPERTY_NAME;
 
public static Tuple2<String, String> getTuple2Location() {
return tupleDefault;
}
 
public FicheRelanceSheet(SQLRow row) {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.row = row;
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true);
}
 
@Override
public String getDefaultModele() {
return "FicheRelance";
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
@Override
protected void createListeValues() {
// TODO Auto-generated method stub
final Map<String, Object> values = new HashMap<String, Object>();
List<Map<String, Object>> listValues = new ArrayList<Map<String, Object>>();
final List<Map<String, Object>> listValues = new ArrayList<Map<String, Object>>();
 
final SQLRow clientRow = this.row.getForeignRow("ID_CLIENT");
final SQLRow factureRow = this.row.getForeignRow("ID_SAISIE_VENTE_FACTURE");
70,8 → 62,9
 
}
 
public String getFileName() {
return getValidFileName("FicheRelance" + new Date().getTime());
@Override
public String getName() {
return "FicheRelance" + new Date().getTime();
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/CourrierClientSheet.java
15,12 → 15,10
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.AbstractJOOReportsSheet;
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.utils.Tuple2;
 
import java.util.Date;
import java.util.HashMap;
31,24 → 29,21
 
private SQLRow rowCourrier;
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationCourrier", "Courrier");
public static final String TEMPLATE_ID = "Courrier";
public static final String TEMPLATE_PROPERTY_NAME = "LocationCourrier";
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
public CourrierClientSheet(SQLRow row) {
super();
this.rowCourrier = row;
Date d = (Date) this.rowCourrier.getObject("DATE");
String year = yearFormat.format(d);
init(year, "Courrier.odt", "CourrierPrinter", tuple);
init(year, "Courrier.odt", "CourrierPrinter");
}
 
/**
* @return une Map contenant les valeurs à remplacer dans la template
*/
protected Map createMap() {
protected Map<String, Object> createMap() {
 
Map<String, Object> m = new HashMap<String, Object>();
 
84,8 → 79,7
}
 
public String getFileName() {
String fileName = "Courrier_" + AbstractSheetXml.getValidFileName(this.rowCourrier.getString("NUMERO"));
return fileName;
return "Courrier_" + this.rowCourrier.getString("NUMERO");
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/RelanceSheet.java
16,13 → 16,11
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
import org.openconcerto.erp.generationDoc.AbstractJOOReportsSheet;
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.Tuple2;
 
import java.util.Date;
import java.util.HashMap;
33,11 → 31,9
 
private SQLRow rowRelance;
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationRelance", "Relance");
public static final String TEMPLATE_ID = "Relance";
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
public static final String TEMPLATE_PROPERTY_NAME = "LocationRelance";
 
/**
* @return une Map contenant les valeurs à remplacer dans la template
122,10 → 118,11
sel.addSelect(this.rowRelance.getTable().getKey());
sel.setWhere(new Where(this.rowRelance.getTable().getField("ID_SAISIE_VENTE_FACTURE"), "=", this.rowRelance.getInt("ID_SAISIE_VENTE_FACTURE")));
sel.addFieldOrder(this.rowRelance.getTable().getField("DATE").getFullName());
List<Map> listResult = Configuration.getInstance().getBase().getDataSource().execute(sel.asString());
@SuppressWarnings("unchecked")
List<Map<String, Number>> listResult = Configuration.getInstance().getBase().getDataSource().execute(sel.asString());
if (listResult != null && listResult.size() > 0) {
Map o = listResult.get(0);
Number n = (Number) o.get(this.rowRelance.getTable().getKey().getName());
Map<String, Number> o = listResult.get(0);
Number n = o.get(this.rowRelance.getTable().getKey().getName());
SQLRow rowOldRelance = this.rowRelance.getTable().getRow(n.intValue());
Date dOldRelance = (Date) rowOldRelance.getObject("DATE");
map.put("DatePremiereRelance", dateFormat2.format(dOldRelance));
144,7 → 141,7
 
final String string = rowLettre.getString("MODELE");
System.err.println(this.locationTemplate + "/" + string);
init(year, string, "RelancePrinter", tuple);
init(year, string, "RelancePrinter");
}
 
protected boolean savePDF() {
152,7 → 149,6
}
 
public String getFileName() {
String fileName = "Relance_" + AbstractSheetXml.getValidFileName(this.rowRelance.getString("NUMERO"));
return fileName;
return "Relance_" + this.rowRelance.getString("NUMERO");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLField.java
179,7 → 179,7
String condField = this.elt.getAttributeValue("conditionField");
String condValue = this.elt.getAttributeValue("conditionExpValue");
 
boolean bIsCondValid = condValue == null || this.row.getObject(condField).toString().equalsIgnoreCase(condValue);
boolean bIsCondValid = condValue == null || !this.row.getObject(condField).toString().equalsIgnoreCase(condValue);
if (condValue == null) {
boolean bIsBooleanCondValid = false;
if (condField == null) {
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/TemplateManager.java
New file
0,0 → 1,165
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
public class TemplateManager {
private static TemplateManager instance = new TemplateManager();
private List<TemplateProvider> providers = new ArrayList<TemplateProvider>();
private Map<String, TemplateProvider> defaultMap = new HashMap<String, TemplateProvider>();
private TemplateProvider defautProvider;
private List<String> knownTemplateIds = new ArrayList<String>();
 
public static TemplateManager getInstance() {
return instance;
}
 
public void add(TemplateProvider provider) {
this.providers.add(provider);
}
 
public void remove(TemplateProvider provider) {
this.providers.remove(provider);
final Set<String> keys = defaultMap.keySet();
for (String key : keys) {
if (defaultMap.get(key).equals(provider)) {
defaultMap.remove(key);
}
}
}
 
public void setDefaultProvider(String templateId, TemplateProvider provider) {
defaultMap.put(templateId, provider);
knownTemplateIds.add(templateId);
}
 
public void setDefaultProvider(TemplateProvider provider) {
this.defautProvider = provider;
}
 
/**
* Get the template using first the default template providers
*
*
* @return the template file, IllegalStateException if no template is found
* */
public InputStream getTemplate(String templateId, String language, String type) {
TemplateProvider provider = defaultMap.get(templateId);
if (provider == null) {
for (TemplateProvider pr : providers) {
InputStream stream = pr.getTemplate(templateId, language, type);
if (stream != null) {
return stream;
}
}
if (defautProvider == null) {
throw new IllegalStateException("Not default provider registered when using template id:" + templateId + " language:" + language + " type:" + type);
}
return defautProvider.getTemplate(templateId, language, type);
}
return provider.getTemplate(templateId, language, type);
}
 
/**
* Get the template print configuration using first the default template providers
*
*
* @return the template file, IllegalStateException if no template is found
* */
public InputStream getTemplatePrintConfiguration(String templateId, String language, String type) {
TemplateProvider provider = defaultMap.get(templateId);
if (provider == null) {
for (TemplateProvider pr : providers) {
InputStream stream = pr.getTemplatePrintConfiguration(templateId, language, type);
if (stream != null) {
return stream;
}
}
if (defautProvider == null) {
throw new IllegalStateException("Not default provider registered when using template id:" + templateId + " langage:" + language + " type:" + type);
}
return defautProvider.getTemplatePrintConfiguration(templateId, language, type);
}
return provider.getTemplatePrintConfiguration(templateId, language, type);
}
 
/**
* Get the template cofiguration using first the default template providers
*
*
* @return the template file, IllegalStateException if no template is found
* */
public InputStream getTemplateConfiguration(String templateId, String language, String type) {
TemplateProvider provider = defaultMap.get(templateId);
if (provider == null) {
for (TemplateProvider pr : providers) {
InputStream stream = pr.getTemplateConfiguration(templateId, language, type);
if (stream != null) {
return stream;
}
}
if (defautProvider == null) {
throw new IllegalStateException("Not default provider registered when using template id:" + templateId + " langage:" + language + " type:" + type);
}
return defautProvider.getTemplateConfiguration(templateId, language, type);
}
return provider.getTemplateConfiguration(templateId, language, type);
}
 
public InputStream getTemplate(String templateId) {
return getTemplate(templateId, null, null);
}
 
public void register(String templateId) {
knownTemplateIds.add(templateId);
}
 
public void dump() {
System.out.println(this.getClass().getCanonicalName());
System.out.println("Default provider: " + this.defautProvider);
System.out.println("Templates:");
for (String templateId : this.knownTemplateIds) {
try {
InputStream stream = this.getTemplate(templateId);
if (stream == null) {
System.out.println(rightAlign("'" + templateId + "'") + " : stream missing");
} else {
System.out.println(rightAlign("'" + templateId + "'") + " : ok");
}
} catch (Exception e) {
System.out.println(rightAlign("'" + templateId + "'") + ": stream error");
}
}
 
}
 
private String rightAlign(String s) {
String r = s;
int n = 20 - s.length();
for (int i = 0; i < n; i++) {
r = ' ' + r;
}
return r;
}
 
public boolean isKnwonTemplate(String templateId) {
return this.knownTemplateIds.contains(templateId);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/DefaultLocalTemplateProvider.java
New file
0,0 → 1,66
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import java.io.File;
 
public class DefaultLocalTemplateProvider extends AbstractLocalTemplateProvider {
 
private File baseDirectory;
 
public DefaultLocalTemplateProvider() {
baseDirectory = new File("Configuration/Template/Default");
}
 
public void setBaseDirectory(File dir) {
this.baseDirectory = dir;
}
 
@Override
public File getTemplateFile(String templateId, String langage, String type) {
File file = getFile(templateId, langage, type);
if (!file.exists()) {
file = getFile(templateId + ".ods", langage, type);
}
return file;
}
 
private File getFile(String templateId, String langage, String type) {
String path = templateId;
if (type != null) {
path += type;
}
if (langage != null) {
path = langage + File.separatorChar + path;
}
File file = new File(baseDirectory, path);
if (!file.exists()) {
file = new File("Configuration/Template/Default", path);
}
return file;
}
 
@Override
public String getTemplatePath(String templateId, String langage, String type) {
String path = "Configuration/Template/Default";
if (type != null) {
path += type;
}
if (langage != null) {
path = langage + '/' + path;
}
return path;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractSheetXMLWithDate.java
New file
0,0 → 1,47
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.StringUtils;
 
import java.io.File;
import java.util.Calendar;
 
public abstract class AbstractSheetXMLWithDate extends AbstractSheetXml {
 
public AbstractSheetXMLWithDate(SQLRow row) {
super(row);
}
 
protected final String getYear() {
final Calendar cal = this.row.getDate("DATE");
return cal == null ? "Date inconnue" : String.valueOf(cal.get(Calendar.YEAR));
}
 
@Override
public File getDocumentOutputDirectoryP() {
return new File(DocumentLocalStorageManager.getInstance().getDocumentOutputDirectory(this.getTemplateId()), getYear());
}
 
@Override
public File getPDFOutputDirectoryP() {
return new File(DocumentLocalStorageManager.getInstance().getPDFOutputDirectory(this.getTemplateId()), getYear());
}
 
@Override
public String getStoragePathP() {
return StringUtils.firstUp(this.elt.getPluralName() + File.separator + getYear());
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/DocumentLocalStorageManager.java
New file
0,0 → 1,160
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class DocumentLocalStorageManager {
private static DocumentLocalStorageManager instance = new DocumentLocalStorageManager();
private Map<String, File> dirs = new HashMap<String, File>();
private Map<String, File> dirsPDF = new HashMap<String, File>();
private File documentDefaultDirectory;
private File PDFDefaultDirectory;
 
public static DocumentLocalStorageManager getInstance() {
return instance;
}
 
/**
* Returns the directory to store the document created from a template
*
* @param templateId : the id of the template used to create the document
* */
public File getDocumentOutputDirectory(String templateId) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
}
final File f = dirs.get(templateId);
if (f != null) {
return f;
}
return documentDefaultDirectory;
 
}
 
/**
* Returns the directory to store the PDF document created from a template
*
* @param templateId : the id of the template used to create the document
* */
public File getPDFOutputDirectory(String templateId) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
}
final File f = dirsPDF.get(templateId);
if (f != null) {
return f;
}
return PDFDefaultDirectory;
}
 
public void addDocumentDirectory(String templateId, File directory) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
}
this.dirs.put(templateId, directory);
TemplateManager.getInstance().register(templateId);
}
 
public void removeDocumentDirectory(String templateId, File directory) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
}
this.dirs.remove(templateId);
}
 
public void addPDFDirectory(String templateId, File directory) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
}
this.dirsPDF.put(templateId, directory);
TemplateManager.getInstance().register(templateId);
}
 
public void removePDFDirectory(String templateId, File directory) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
}
this.dirsPDF.remove(templateId);
}
 
public void setDocumentDefaultDirectory(File directory) {
this.documentDefaultDirectory = directory;
}
 
public void setPDFDefaultDirectory(File directory) {
this.PDFDefaultDirectory = directory;
}
 
public List<File> getAllPDFDirectories() {
List<File> list = new ArrayList<File>();
for (String id : this.dirsPDF.keySet()) {
list.add(this.dirsPDF.get(id));
}
return list;
}
 
public List<File> getAllDocumentDirectories() {
List<File> list = new ArrayList<File>();
for (String id : this.dirs.keySet()) {
list.add(this.dirs.get(id));
}
return list;
}
 
public void dump() {
System.out.println(this.getClass().getCanonicalName());
System.out.println("Default document directory: " + getAndTest(this.documentDefaultDirectory));
System.out.println("Default PFD directory : " + getAndTest(this.PDFDefaultDirectory));
System.out.println("Document directories:");
for (String key : this.dirs.keySet()) {
System.out.println(rightAlign("'" + key + "'") + " : " + getAndTest(this.dirs.get(key)));
}
System.out.println("PDF directories:");
for (String key : this.dirsPDF.keySet()) {
System.out.println(rightAlign("'" + key + "'") + " : " + getAndTest(this.dirsPDF.get(key)));
}
}
 
private String rightAlign(String s) {
String r = s;
int n = 20 - s.length();
for (int i = 0; i < n; i++) {
r = ' ' + r;
}
return r;
}
 
private String getAndTest(File dir) {
if (dir == null) {
return "null !!!!!!";
}
String r = "'" + dir.getAbsolutePath() + "'";
if (dir.exists()) {
if (!dir.isDirectory()) {
r += " is not a directory!!";
} else if (!dir.canWrite()) {
r += " is write protected!!";
}
} else {
r += " does not exist !!";
}
return r;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationXML.java
73,8 → 73,8
 
private static int answer = JOptionPane.NO_OPTION;
 
public static synchronized File genere(String modele, String pathDest, final String fileDest, SQLRow row, SQLRow rowLanguage) {
 
public static synchronized File createDocument(String templateId, File outputDirectory, final String expectedFileName, SQLRow row, SQLRow rowLanguage) {
final String langage = rowLanguage != null ? rowLanguage.getString("CHEMIN") : null;
cacheStyle.clear();
OOXMLCache.clearCache();
rowsEltCache.clear();
81,7 → 81,7
taxe.clear();
cacheForeign.clear();
 
File fDest = new File(pathDest, fileDest + ".ods");
File fDest = new File(outputDirectory, expectedFileName);
 
if (fDest.exists()) {
 
112,20 → 112,20
SAXBuilder builder = new SAXBuilder();
try {
 
if (needAnnexe(modele, row, rowLanguage)) {
try {
if (needAnnexe(templateId, row, rowLanguage)) {
// check if it exists
getOOTemplate(modele + "_annexe", rowLanguage);
modele += "_annexe";
System.err.println("modele With annexe " + modele);
} catch (FileNotFoundException e) {
 
final String annexeTemplateId = templateId + "_annexe";
InputStream annexeStream = TemplateManager.getInstance().getTemplate(annexeTemplateId, langage, null);
if (annexeStream != null) {
templateId = annexeTemplateId;
System.err.println("modele With annexe " + templateId);
}
}
 
System.err.println("modele " + modele);
System.err.println("Using template id: " + templateId);
final InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, langage, null);
 
Document doc = builder.build(getXmlTemplate(modele, rowLanguage));
Document doc = builder.build(xmlConfiguration);
 
// On initialise un nouvel élément racine avec l'élément racine du document.
Element racine = doc.getRootElement();
134,7 → 134,9
List<Element> listElts = racine.getChildren("element");
 
// Création et génération du fichier OO
SpreadSheet spreadSheet = SpreadSheet.create(new ODPackage(getOOTemplate(modele, rowLanguage)));
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, langage, null);
 
final SpreadSheet spreadSheet = new ODPackage(template).getSpreadSheet();
try {
// On remplit les cellules de la feuille
parseElementsXML(listElts, row, spreadSheet);
147,10 → 149,10
parseTableauXML(tableChild, row, spreadSheet, rowLanguage);
}
} catch (Exception e) {
ExceptionHandler.handle("Impossible de remplir le document " + modele + " " + ((rowLanguage == null) ? "" : rowLanguage.getString("CHEMIN")), e);
ExceptionHandler.handle("Impossible de remplir le document " + templateId + " " + ((rowLanguage == null) ? "" : rowLanguage.getString("CHEMIN")), e);
}
// Sauvegarde du fichier
return saveSpreadSheet(spreadSheet, new File(pathDest), fileDest, modele, rowLanguage);
return saveSpreadSheet(spreadSheet, outputDirectory, expectedFileName, templateId, rowLanguage);
 
} catch (final JDOMException e) {
 
157,7 → 159,7
e.printStackTrace();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ExceptionHandler.handle("Erreur lors de la génération du fichier " + fileDest, e);
ExceptionHandler.handle("Erreur lors de la génération du fichier " + expectedFileName, e);
}
});
} catch (final IOException e) {
165,7 → 167,7
e.printStackTrace();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ExceptionHandler.handle("Erreur lors de la création du fichier " + fileDest, e);
ExceptionHandler.handle("Erreur lors de la création du fichier " + expectedFileName, e);
}
});
}
706,8 → 708,9
* @return un File pointant sur le fichier créé
* @throws IOException
*/
private static File saveSpreadSheet(SpreadSheet ssheet, File pathDest, String fileName, String modele, SQLRow rowLanguage) throws IOException {
 
private static File saveSpreadSheet(SpreadSheet ssheet, File pathDest, String fileName, String templateId, SQLRow rowLanguage) throws IOException {
final String langage = rowLanguage != null ? rowLanguage.getString("CHEMIN") : null;
// Test des arguments
if (ssheet == null || pathDest == null || fileName.trim().length() == 0) {
throw new IllegalArgumentException();
720,7 → 723,7
pathDest.mkdirs();
}
 
fDest = SheetUtils.getInstance().convertToOldFile(fileName, pathDest, fDest);
fDest = SheetUtils.convertToOldFile(fileName, pathDest, fDest);
 
// Sauvegarde
try {
743,7 → 746,7
// Copie de l'odsp
try {
File odspOut = new File(pathDest, fileName + ".odsp");
InputStream odspIn = getTemplate(modele + ".odsp", rowLanguage);
final InputStream odspIn = TemplateManager.getInstance().getTemplatePrintConfiguration(templateId, langage, null);
if (odspIn != null) {
StreamUtils.copy(odspIn, odspOut);
}
753,18 → 756,6
return fDest;
}
 
public static InputStream getOOTemplate(String name, SQLRow language) throws FileNotFoundException {
return OOgenerationListeXML.getOOTemplate(name, language);
}
 
public static InputStream getXmlTemplate(String name, SQLRow language) throws FileNotFoundException {
return OOgenerationListeXML.getXmlTemplate(name, language);
}
 
public static InputStream getTemplate(String name, SQLRow language) throws FileNotFoundException {
return OOgenerationListeXML.getTemplate(name, language);
}
 
/**
* parcourt l'ensemble de la feuille pour trouver les style définit
*/
827,15 → 818,16
return mapStyleDef;
}
 
public static boolean needAnnexe(String modele, SQLRow row, SQLRow rowLanguage) {
 
SAXBuilder builder = new SAXBuilder();
public static boolean needAnnexe(String templateId, SQLRow row, SQLRow rowLanguage) {
final String langage = rowLanguage != null ? rowLanguage.getString("CHEMIN") : null;
final SAXBuilder builder = new SAXBuilder();
try {
final InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, langage, null);
final Document doc = builder.build(xmlConfiguration);
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, langage, null);
 
Document doc = builder.build(getXmlTemplate(modele, rowLanguage));
final SpreadSheet spreadSheet = new ODPackage(template).getSpreadSheet();
 
SpreadSheet spreadSheet = SpreadSheet.create(new ODPackage(getOOTemplate(modele, rowLanguage)));
 
// On initialise un nouvel élément racine avec l'élément racine du document.
Element racine = doc.getRootElement();
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationListeXML.java
49,34 → 49,32
// Cache pour la recherche des styles
private static Map<Sheet, Map<String, Map<Integer, String>>> cacheStyle = new HashMap<Sheet, Map<String, Map<Integer, String>>>();
 
public static File genere(String modele, String pathDest, String fileDest, Map<Integer, List<Map<String, Object>>> liste, Map<Integer, Map<String, Object>> values) {
public static File genere(String modele, File pathDest, String fileDest, Map<Integer, List<Map<String, Object>>> liste, Map<Integer, Map<String, Object>> values) {
return genere(modele, pathDest, fileDest, liste, values, new HashMap<Integer, Map<Integer, String>>(), null, null);
}
 
public static File genere(String modele, String pathDest, String fileDest, Map<Integer, List<Map<String, Object>>> liste, Map<Integer, Map<String, Object>> values,
public static File genere(String templateId, File pathDest, String fileDest, Map<Integer, List<Map<String, Object>>> liste, Map<Integer, Map<String, Object>> values,
Map<Integer, Map<Integer, String>> mapStyle, List<String> sheetName, SQLRow rowLanguage) {
// SQLRow row = elt.getTable().getRow(id);
cacheStyle.clear();
SAXBuilder builder = new SAXBuilder();
final SAXBuilder builder = new SAXBuilder();
try {
Document doc = builder.build(getXmlTemplate(modele, rowLanguage));
InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, rowLanguage != null ? rowLanguage.getString("CHEMIN") : null, null);
Document doc = builder.build(xmlConfiguration);
 
// On initialise un nouvel élément racine avec l'élément racine du
// document.
Element racine = doc.getRootElement();
final Element racine = doc.getRootElement();
 
// Création et génération du fichier OO
SpreadSheet spreadSheet = SpreadSheet.create(new ODPackage(getOOTemplate(modele, rowLanguage)));
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, rowLanguage != null ? rowLanguage.getString("CHEMIN") : null, null);
 
final SpreadSheet spreadSheet = new ODPackage(template).getSpreadSheet();
Sheet sheet0 = spreadSheet.getSheet(0);
if (sheetName != null && sheetName.size() > 0) {
for (int i = 1; i < sheetName.size(); i++) {
sheet0.copy(i, (sheetName != null) ? sheetName.get(i) : "Feuille " + i);
}
 
spreadSheet.getSheet(0).setName(sheetName.get(0));
 
System.err.println("add " + sheetName.size() + " sheet");
 
}
 
for (Integer i : liste.keySet()) {
86,7 → 84,6
children = racine.getChildren("element");
}
parseElementsXML(children, sheet, values.get(i));
 
Element child = racine.getChild("table" + i);
if (child == null) {
child = racine.getChild("table");
94,15 → 91,11
parseListeXML(child, liste.get(i), sheet, mapStyle.get(i));
}
// Sauvegarde du fichier
return saveSpreadSheet(spreadSheet, new File(pathDest), fileDest, modele, rowLanguage);
return saveSpreadSheet(spreadSheet, pathDest, fileDest, templateId, rowLanguage);
 
} catch (JDOMException e) {
 
e.printStackTrace();
ExceptionHandler.handle("Erreur lors de la génération du fichier " + fileDest, e);
} catch (IOException e) {
 
e.printStackTrace();
ExceptionHandler.handle("Erreur lors de la création du fichier " + fileDest, e);
}
return null;
478,7 → 471,7
* @return un File pointant sur le fichier créé
* @throws IOException
*/
private static File saveSpreadSheet(SpreadSheet ssheet, File pathDest, String fileName, String modele, SQLRow rowLanguage) throws IOException {
private static File saveSpreadSheet(SpreadSheet ssheet, File pathDest, String fileName, String templateId, SQLRow rowLanguage) throws IOException {
 
// Test des arguments
if (ssheet == null || pathDest == null || fileName.trim().length() == 0) {
492,7 → 485,7
pathDest.mkdirs();
}
 
SheetUtils.getInstance().convertToOldFile(fileName, pathDest, fDest);
SheetUtils.convertToOldFile(fileName, pathDest, fDest);
 
// Sauvegarde
try {
515,7 → 508,7
// Copie de l'odsp
try {
File odspOut = new File(pathDest, fileName + ".odsp");
InputStream odspIn = getTemplate(modele + ".odsp", rowLanguage);
InputStream odspIn = TemplateManager.getInstance().getTemplatePrintConfiguration(templateId, rowLanguage != null ? rowLanguage.getString("CHEMIN") : null, null);
if (odspIn != null) {
StreamUtils.copy(odspIn, odspOut);
}
526,34 → 519,7
return fDest;
}
 
public static InputStream getOOTemplate(String name, SQLRow rowLanguage) throws FileNotFoundException {
return getTemplate(name + ".ods", rowLanguage);
}
 
public static InputStream getXmlTemplate(String name, SQLRow rowLanguage) throws FileNotFoundException {
return getTemplate(name + ".xml", rowLanguage);
}
 
/**
* Permet d'obtenir l'emplacement du modele passé en argument. Si le modéle ne se pas trouve
* dans le répertoire spécifié dans les préférences alors on recherche dans le répertoire par
* défaut des modéles.
*
* @param name nom du modéle à trouver
* @return le modéle
* @throws FileNotFoundException si le fichier est introuvable
*/
public static InputStream getTemplate(String name, SQLRow rowLanguage) throws FileNotFoundException {
String modelDir = TemplateNXProps.getInstance().getStringProperty("LocationTemplate");
 
if (rowLanguage != null) {
return ComptaBasePropsConfiguration.getStream(name, modelDir + File.separator + rowLanguage.getString("CHEMIN"), modelDir, SpreadSheetGenerator.defaultLocationTemplate);
} else {
return ComptaBasePropsConfiguration.getStream(name, modelDir, SpreadSheetGenerator.defaultLocationTemplate);
}
}
 
/**
* parcourt l'ensemble de la feuille pour trouver les style définit
*/
private static Map<String, Map<Integer, String>> searchStyle(Sheet sheet, int colEnd, int rowEnd) {
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractSheetXml.java
14,8 → 14,10
package org.openconcerto.erp.generationDoc;
 
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.StringUtils;
 
import java.io.File;
import java.io.InputStream;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
 
23,35 → 25,36
import javax.swing.SwingUtilities;
 
public abstract class AbstractSheetXml extends SheetXml {
private File generatedOpenDocumentFile;
 
public AbstractSheetXml(SQLRow row) {
this.row = row;
}
 
public final Future<File> genere(final boolean visu, final boolean impression) {
Callable<File> c = new Callable<File>() {
@Override
public File call() throws Exception {
public final Future<SheetXml> createDocumentAsynchronous() {
Callable<SheetXml> c = new Callable<SheetXml>() {
@Override
public SheetXml call() throws Exception {
try {
String modele = getModele();
final String modeleFinal = modele;
try {
OOgenerationXML.getOOTemplate(modele, getRowLanguage());
} catch (Exception e) {
String templateId = getTemplateId();
final String modeleFinal = templateId;
 
String langage = getRowLanguage() != null ? getRowLanguage().getString("CHEMIN") : null;
InputStream templateStream = TemplateManager.getInstance().getTemplate(templateId, langage, getType());
if (templateStream == null) {
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
// TODO Raccord de méthode auto-généré
JOptionPane.showMessageDialog(null, "Impossible de trouver le modele " + modeleFinal + ". \n Le modéle par défaut sera utilisé!");
}
});
modele = getDefaultModele();
templateId = getDefaultTemplateId();
}
File fGen = OOgenerationXML.genere(modele, AbstractSheetXml.this.locationOO, getFileName(), AbstractSheetXml.this.row, getRowLanguage());
AbstractSheetXml.this.f = fGen;
useOO(fGen, visu, impression, getFileName());
return fGen;
AbstractSheetXml.this.generatedOpenDocumentFile = OOgenerationXML.createDocument(templateId, getDocumentOutputDirectory(), getValidFileName(getName()), AbstractSheetXml.this.row,
getRowLanguage());
 
} catch (Exception e) {
DEFAULT_HANDLER.uncaughtException(null, e);
// rethrow exception so that the unsuspecting caller can use this as the
59,11 → 62,27
throw e;
} catch (Throwable e) {
DEFAULT_HANDLER.uncaughtException(null, e);
return null;
}
 
}
return AbstractSheetXml.this;
}
};
return runnableQueue.submit(c);
}
 
public String getType() {
return null;
}
 
@Override
public String getStoragePathP() {
return StringUtils.firstUp(elt.getPluralName());
}
 
@Override
public File getGeneratedFile() {
if (this.generatedOpenDocumentFile == null)
this.generatedOpenDocumentFile = new File(getDocumentOutputDirectory(), getValidFileName(getName()) + ".ods");
return generatedOpenDocumentFile;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractListeSheetXml.java
13,6 → 13,9
package org.openconcerto.erp.generationDoc;
 
import static org.openconcerto.erp.generationDoc.SheetXml.getValidFileName;
import org.openconcerto.utils.StringUtils;
 
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
35,16 → 38,21
// Nom des feuilles
protected List<String> sheetNames = new ArrayList<String>();
 
public final Future<File> genere(final boolean visu, final boolean impression) {
Callable<File> c = new Callable<File>() {
private File generatedOpenDocumentFile;
 
public AbstractListeSheetXml() {
generatedOpenDocumentFile = new File(getDocumentOutputDirectory(), getValidFileName(getName()) + ".ods");
}
 
public final Future<SheetXml> createDocumentAsynchronous() {
Callable<SheetXml> c = new Callable<SheetXml>() {
@Override
public File call() throws Exception {
public SheetXml call() throws Exception {
try {
createListeValues();
File fGen = OOgenerationListeXML.genere(getModele(), locationOO, getFileName(), listAllSheetValues, mapAllSheetValues, styleAllSheetValues, sheetNames, null);
AbstractListeSheetXml.this.f = fGen;
useOO(fGen, visu, impression, getFileName());
return fGen;
generatedOpenDocumentFile = OOgenerationListeXML.genere(getTemplateId(), getDocumentOutputDirectory(), getValidFileName(getName()), listAllSheetValues, mapAllSheetValues,
styleAllSheetValues, sheetNames, null);
return AbstractListeSheetXml.this;
} catch (Exception e) {
DEFAULT_HANDLER.uncaughtException(null, e);
// rethrow exception so that the unsuspecting caller can use this as the
57,7 → 65,7
 
}
};
return this.runnableQueue.submit(c);
return runnableQueue.submit(c);
}
 
/**
64,4 → 72,24
* To fill listAllSheetValues, styleAllSheetValues, mapAllSheetValues, sheetNames
*/
protected abstract void createListeValues();
 
@Override
public String getStoragePathP() {
return StringUtils.firstUp(elt.getPluralName());
}
 
@Override
public File getGeneratedFile() {
return generatedOpenDocumentFile;
}
 
@Override
public File getDocumentOutputDirectoryP() {
return DocumentLocalStorageManager.getInstance().getDocumentOutputDirectory(this.getTemplateId());
}
 
@Override
public File getPDFOutputDirectoryP() {
return DocumentLocalStorageManager.getInstance().getPDFOutputDirectory(this.getTemplateId());
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SpreadSheetGenerator.java
193,7 → 193,7
return null;
}
}
final SpreadSheet res = SpreadSheet.create(new ODPackage(f));
final SpreadSheet res = new ODPackage(f).getSpreadSheet();
f.close();
return res;
}
250,9 → 250,9
 
this.modele = sheet.modele;
this.mCell = sheet.mCell;
this.destDirOO = new File(sheet.locationOO);
this.destDirOO = sheet.getDocumentOutputDirectory();
this.destDirOO.mkdirs();
this.destDirPDF = new File(sheet.locationPDF);
this.destDirPDF = sheet.getPDFOutputDirectory();
this.destDirPDF.mkdirs();
this.nbPage = sheet.nbPage;
this.nbRowsPerPage = sheet.nbRowsPerPage;
272,7 → 272,7
try {
 
f = generateWithStyle();
 
final File pdfFileToCreate = new File(this.destDirPDF.getAbsolutePath(), this.destFileName + ".pdf");
try {
 
if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
279,7 → 279,8
 
final Component doc = ComptaPropsConfiguration.getOOConnexion().loadDocument(f, !this.visu);
if (this.exportPDF) {
doc.saveToPDF(new File(this.destDirPDF.getAbsolutePath(), this.destFileName + ".pdf"));
 
doc.saveToPDF(pdfFileToCreate);
}
 
if (this.impression) {
295,7 → 296,7
PreviewFrame.show(f);
}
 
SheetUtils.getInstance().convert2PDF(doc, f, this.destFileName);
SheetUtils.convert2PDF(doc, pdfFileToCreate);
if (this.impression) {
// Print !
DefaultNXDocumentPrinter printer = new DefaultNXDocumentPrinter();
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/DocumentGeneratorManager.java
New file
0,0 → 1,66
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.generationDoc;
 
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
 
public class DocumentGeneratorManager {
private static DocumentGeneratorManager instance = new DocumentGeneratorManager();
private Map<String, DocumentGenerator> generators = new HashMap<String, DocumentGenerator>();
private DocumentGenerator defautGenerator;
 
public static DocumentGeneratorManager getInstance() {
return instance;
}
 
public void add(String templateId, DocumentGenerator generator) {
this.generators.put(templateId, generator);
}
 
public void remove(DocumentGenerator generator) {
final Set<String> keys = generators.keySet();
for (String key : keys) {
if (generators.get(key).equals(generator)) {
generators.remove(key);
}
}
}
 
public void setDefaultGenerator(DocumentGenerator generator) {
this.defautGenerator = generator;
}
 
/**
* Returns the document generator a specific templateId
* */
public DocumentGenerator getGenerator(String templateId) {
DocumentGenerator generator = this.generators.get(templateId);
if (generator == null) {
generator = defautGenerator;
}
return generator;
}
 
public void dump() {
System.out.println(this.getClass().getCanonicalName());
System.out.println("Default generator:" + this.defautGenerator);
Set<String> ids = generators.keySet();
for (String templateId : ids) {
System.out.println("'" + templateId + "' : " + generators.get(templateId));
}
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ClientNormalSQLElement.java
44,6 → 44,7
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.TitledSeparator;
import org.openconcerto.ui.component.ITextArea;
 
86,8 → 87,11
protected List<String> getListFields() {
final List<String> l = new ArrayList<String>();
l.add("CODE");
l.add("FORME_JURIDIQUE");
// l.add("FORME_JURIDIQUE");
l.add("NOM");
if (getTable().getFieldsName().contains("LOCALISATION")) {
l.add("LOCALISATION");
}
l.add("RESPONSABLE");
l.add("ID_ADRESSE");
l.add("TEL");
115,9 → 119,13
 
protected List<String> getComboFields() {
final List<String> l = new ArrayList<String>();
l.add("FORME_JURIDIQUE");
// l.add("FORME_JURIDIQUE");
l.add("NOM");
if (getTable().getFieldsName().contains("LOCALISATION")) {
l.add("LOCALISATION");
} else {
l.add("CODE");
}
return l;
}
 
234,7 → 242,20
this.add(boxPays, c);
this.addView(boxPays, "ID_PAYS");
}
 
if (getTable().getFieldsName().contains("LOCALISATION")) {
c.gridy++;
c.gridx = 0;
c.weightx = 0;
JLabel comp2 = new JLabel(getLabelFor("LOCALISATION"));
comp2.setHorizontalAlignment(SwingConstants.RIGHT);
this.add(comp2, c);
JTextField loc = new JTextField();
c.gridx++;
c.weightx = 1;
// DefaultGridBagConstraints.lockMinimumSize(boxPays);
this.add(loc, c);
this.addView(loc, "LOCALISATION");
}
// Numero intracomm
JLabel labelIntraComm = new JLabel("N° TVA");
labelIntraComm.setHorizontalAlignment(SwingConstants.RIGHT);
380,6 → 401,17
// Secteur activité
final boolean customerIsKD;
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = new JPanel();
this.setAdditionalFieldsPanel(new FormLayouter(addP, 1));
this.add(addP, c);
 
c.gridy++;
c.gridwidth = 1;
 
// Adresse
c.gridx = 0;
c.gridy++;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/report/FicheClientXmlSheet.java
13,38 → 13,31
package org.openconcerto.erp.core.customerrelationship.customer.report;
 
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
 
public class FicheClientXmlSheet extends AbstractSheetXml {
public class FicheClientXmlSheet extends AbstractSheetXMLWithDate {
 
public static Tuple2<String, String> getTuple2Location() {
return tupleDefault;
}
public static final String TEMPLATE_ID = "FicheClient";
public static final String TEMPLATE_PROPERTY_NAME = DEFAULT_PROPERTY_NAME;
 
public FicheClientXmlSheet(SQLRow row) {
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("DevisPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("CLIENT");
Calendar cal = Calendar.getInstance();
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true) + File.separator + cal.get(Calendar.YEAR);
}
 
@Override
public String getDefaultModele() {
return "FicheClient";
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
public String getFileName() {
return getValidFileName("FicheClient_" + new Date().getTime());
@Override
public String getName() {
return "FicheClient_" + new Date().getTime();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/ExerciceCommonSQLElement.java
123,6 → 123,9
 
@Override
public synchronized ValidState getValidState() {
if (this.dateDeb.getValue() == null || this.dateFin.getValue() == null) {
return new ValidState(false, "Date de début ou de fin d'exercice non définie");
}
return super.getValidState().and(ValidState.createCached(this.dateDeb.getValue().before(this.dateFin.getValue()), "Date de début après date de fin"));
}
};
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/BalanceSheet.java
14,8 → 14,8
package org.openconcerto.erp.core.finance.accounting.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.DocumentLocalStorageManager;
import org.openconcerto.erp.generationDoc.SheetInterface;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
23,9 → 23,7
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
42,7 → 40,8
private boolean centralClient, centralFourn;
private final static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
private final static DateFormat dateFormatEcr = DateFormat.getDateInstance(DateFormat.SHORT);
 
public static String TEMPLATE_ID = "Balance";
public static String TEMPLATE_PROPERTY_NAME = "LocationBalance";
private Date dateDu, dateAu;
private String compteDeb, compteEnd;
 
56,10 → 55,14
 
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationBalance", "Balance");
@Override
protected String getYear() {
return "";
}
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
public BalanceSheet(Date du, Date au, String compteDeb, String compteEnd, boolean centralClient, boolean centralFourn) {
72,10 → 75,11
this.nbRowsPerPage = 72;
this.printer = PrinterNXProps.getInstance().getStringProperty("BalancePrinter");
this.modele = "Balance.ods";
final String locationForTuple = SheetXml.getLocationForTuple(tuple, false);
System.err.println("Emplacement balance :::: " + locationForTuple);
this.locationOO = locationForTuple + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
 
final DocumentLocalStorageManager storage = DocumentLocalStorageManager.getInstance();
 
// this.locationOO = storage.getDocumentOutputDirectory(TEMPLATE_ID);
// this.locationPDF = storage.getPDFOutputDirectory(TEMPLATE_ID);
this.dateAu = au;
this.dateDu = du;
this.compteDeb = compteDeb;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/BalanceAgeeListeSheetXML.java
15,7 → 15,6
 
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
23,7 → 22,6
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.Tuple2;
 
import java.util.ArrayList;
import java.util.Calendar;
34,33 → 32,26
 
public class BalanceAgeeListeSheetXML extends AbstractListeSheetXml {
 
// private final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
private Date deb, fin;
public static String TEMPLATE_ID = "Balance agée";
 
public static Tuple2<String, String> getTuple2Location() {
return tupleDefault;
}
 
public BalanceAgeeListeSheetXML(Date deb, Date fin) {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.deb = deb;
this.fin = fin;
 
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true);
}
 
@Override
public String getDefaultModele() {
public String getDefaultTemplateId() {
return "BalanceAgee";
}
 
public String getFileName() {
return getValidFileName("BalanceAgee" + new Date().getTime());
@Override
public String getName() {
return "BalanceAgee" + new Date().getTime();
}
 
protected void createListeValues() {
 
SQLElement ecr = Configuration.getInstance().getDirectory().getElement("ECRITURE");
SQLElement cpt = Configuration.getInstance().getDirectory().getElement("COMPTE_PCE");
SQLElement fact = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
106,7 → 97,6
long time = c.getTimeInMillis() - date;
long day = time / 86400000;
if (day < 0) {
// System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
continue;
}
final SQLRow rowCpt = sqlRow.getForeignRow("ID_COMPTE_PCE");
185,7 → 175,7
valuesTab.add(e);
}
}
Map<String, Object> totalMap = new HashMap<String, Object>();
final Map<String, Object> totalMap = new HashMap<String, Object>();
totalMap.put("NOM", "TOTAL");
totalMap.put("30", total30 / 100.0);
totalMap.put("60", total60 / 100.0);
194,29 → 184,7
totalMap.put("TOTAL", totalFull / 100.0);
valuesTab.add(totalMap);
 
// Map<String, Object> values = this.mapAllSheetValues.get(0);
// if (values == null) {
// values = new HashMap<String, Object>();
// }
// valuesHA.put("TOTAL", totalHA);
// valuesE.put("TOTAL_HA", totalHA);
// valuesE.put("TOTAL", totalE);
// valuesE.put("TOTAL_VT", totalTPVTTC);
// values.put("TOTAL", totalVC);
// values.put("TOTAL_MARGE", totalTPVTTC - totalTPA);
//
// valuesE.put("TOTAL_GLOBAL", totalTPVTTC + totalHA);
// values.put("TOTAL_PA", totalTPA);
// values.put("TOTAL_PV_TTC", totalTPVTTC);
//
// String periode = "Période Du " + dateFormat.format(this.du) + " au " +
// dateFormat.format(this.au);
// values.put("DATE", periode);
// valuesHA.put("DATE", periode);
// valuesE.put("DATE", periode);
 
this.listAllSheetValues.put(0, valuesTab);
// this.mapAllSheetValues.put(0, values);
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/JournauxSheet.java
57,6 → 57,9
protected int lettrage;
private String compteDeb, compteEnd;
 
public static String TEMPLATE_ID = "Journaux";
public static String TEMPLATE_PROPERTY_NAME = "LocationJournaux";
 
public static void setSize(int debut, int fin) {
debutFill = debut;
endFill = fin;
66,10 → 69,14
setSize(7, 68);
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationJournaux", "Journaux");
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
@Override
protected String getYear() {
return "";
}
 
public JournauxSheet(int[] id, Date du, Date au, int lettrage, String compteDeb, String compteEnd) {
78,8 → 85,6
cal.setTime(au);
this.printer = PrinterNXProps.getInstance().getStringProperty("JournauxPrinter");
this.modele = "Journaux.ods";
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
this.dateAu = au;
this.dateDu = du;
this.idS = id;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/GrandLivreSheet.java
16,7 → 16,6
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.generationDoc.SheetInterface;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.erp.rights.ComptaUserRight;
import org.openconcerto.sql.Configuration;
28,10 → 27,8
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.ITransformer;
 
import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
66,6 → 63,9
private boolean centralFourn = false;
int idJrnlExclude = -1;
 
public static String TEMPLATE_ID = "Grand Livre";
public static String TEMPLATE_PROPERTY_NAME = "LocationGrandLivre";
 
public static void setSize(int debut, int fin) {
debutFill = debut;
endFill = fin;
75,10 → 75,9
setSize(7, 69);
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationGrandLivre", "Grand Livre");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
@Override
protected String getYear() {
return "";
}
 
public GrandLivreSheet(Date du, Date au, String compteDep, String compteEnd, int lettrage, boolean cumul, boolean excludeCptSolde, boolean centralClient, boolean centralFourn, int idJrnlExclude) {
89,8 → 88,6
this.idJrnlExclude = idJrnlExclude;
this.printer = PrinterNXProps.getInstance().getStringProperty("GrandLivrePrinter");
this.modele = "GrandLivre.ods";
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
this.dateAu = au;
this.dateDu = du;
this.compteDeb = compteDep.trim();
621,4 → 618,10
 
return map;
}
 
@Override
public String getTemplateId() {
// TODO Auto-generated method stub
return TEMPLATE_ID;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/BalanceAgeePanel.java
66,19 → 66,10
BalanceAgeeListeSheetXML l = new BalanceAgeeListeSheetXML(dateDeb.getDate(), dateFin.getDate());
 
try {
l.genere(false, false).get();
// FIXME Probleme avec l'odsviewer
if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
l.showDocument();
} else {
l.showPreviewDocument();
}
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
l.createDocument();
l.openDocument(false);
} catch (Exception e1) {
e1.printStackTrace();
} catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/GenerationPointagePanel.java
13,7 → 13,6
package org.openconcerto.erp.core.finance.accounting.ui;
 
 
import org.openconcerto.erp.generationDoc.gestcomm.PointageXmlSheet;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
69,7 → 68,6
 
this.add(this.spinYear, c);
 
JPanel panelButton = new JPanel();
panelButton.add(this.gen);
panelButton.add(this.close);
100,7 → 98,8
int mois = this.combo.getValue() - 2;
int year = Integer.valueOf(this.spinYear.getValue().toString());
PointageXmlSheet sheet = new PointageXmlSheet(mois, year);
sheet.genere(true, false);
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(true, false, true);
} else {
if (e.getSource() == this.close) {
((JFrame) SwingUtilities.getRoot(this)).dispose();
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/action/ListeDesRelancesAction.java
26,6 → 26,7
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelColumnPath;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.utils.ExceptionHandler;
 
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
103,14 → 104,20
// Impression
AbstractAction actionPrintFact = new AbstractAction("Imprimer la facture") {
public void actionPerformed(ActionEvent e) {
final Thread t = new Thread(new Runnable() {
 
VenteFactureXmlSheet sheet = new VenteFactureXmlSheet(rowRelance.getForeignRow("ID_SAISIE_VENTE_FACTURE"));
if (sheet.getFileODS().exists()) {
sheet.fastPrintDocument();
} else {
sheet.genere(false, true);
@Override
public void run() {
try {
printInvoice(rowRelance);
} catch (Exception e) {
ExceptionHandler.handle("Impression impossible", e);
}
}
});
t.start();
 
}
};
menu.add(actionPrintFact);
 
118,14 → 125,19
 
AbstractAction actionPrintBoth = new AbstractAction("Imprimer la facture et la relance") {
public void actionPerformed(ActionEvent e) {
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
s.fastPrintDocument();
VenteFactureXmlSheet sheet = new VenteFactureXmlSheet(rowRelance.getForeignRow("ID_SAISIE_VENTE_FACTURE"));
if (sheet.getFileODS().exists()) {
sheet.fastPrintDocument();
} else {
sheet.genere(false, true);
printInvoice(rowRelance);
} catch (Exception e) {
ExceptionHandler.handle("Impression impossible", e);
}
}
});
t.start();
}
};
menu.add(actionPrintBoth);
 
138,13 → 150,17
}
});
 
// Générer
// Créer la fiche de relance
menu.add(new AbstractAction("Créer la fiche de relance") {
public void actionPerformed(ActionEvent e) {
 
try {
FicheRelanceSheet sheet = new FicheRelanceSheet(rowRelance);
sheet.genere(true, false);
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(true, false, true);
} catch (Exception ex) {
ExceptionHandler.handle("Impression impossible", ex);
}
}
});
 
menu.show(e.getComponent(), e.getPoint().x, e.getPoint().y);
159,4 → 175,11
 
public void mouseExited(MouseEvent e) {
}
 
private void printInvoice(final SQLRow rowRelance) throws Exception {
final VenteFactureXmlSheet sheet = new VenteFactureXmlSheet(rowRelance.getForeignRow("ID_SAISIE_VENTE_FACTURE"));
sheet.getOrCreateDocumentFile();
sheet.fastPrintDocument();
sheet.showPrintAndExport(false, false, true);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/report/EtatChargesPayeSheet.java
57,19 → 57,24
setSize(7, 66);
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationEtatChargesPaye", "Etat des charges");
public static String TEMPLATE_ID = "Etat des charges";
public static String TEMPLATE_PROPERTY_NAME = "LocationEtatChargesPaye";
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
@Override
protected String getYear() {
return "";
}
 
public EtatChargesPayeSheet(int moisDu, int moisAu, String annee) {
super();
 
this.printer = PrinterNXProps.getInstance().getStringProperty("EtatChargesPayePrinter");
this.modele = "EtatChargesPaye.ods";
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + annee;
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + annee;
this.moisAu = moisAu;
this.moisDu = moisDu;
this.annee = annee;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/report/FichePayeSheet.java
14,8 → 14,8
package org.openconcerto.erp.core.humanresources.payroll.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.DocumentLocalStorageManager;
import org.openconcerto.erp.generationDoc.SheetInterface;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.SpreadSheetGeneratorGestComm;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.map.model.Ville;
26,7 → 26,6
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.text.DateFormat;
163,26 → 162,38
 
// Emplacement des fichiers générés
public static String getLocation(int id, int type) {
 
return getLocation(tableFiche.getRow(id), type);
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationFichePaye", "Fiche de paye");
public static final String TEMPLATE_ID = "Fiche de paye";
public static final String TEMPLATE_PROPERTY_NAME = "LocationFichePaye";
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
@Override
protected String getYear() {
// TODO Auto-generated method stub
return this.row.getString("ANNEE");
}
 
public static String getLocation(SQLRow r, int type) {
DocumentLocalStorageManager storage = DocumentLocalStorageManager.getInstance();
String path;
if (type == FichePayeSheet.typeOO) {
path = storage.getDocumentOutputDirectory(TEMPLATE_ID).getAbsolutePath();
} else {
path = storage.getPDFOutputDirectory(TEMPLATE_ID).getAbsolutePath();
}
 
return SheetXml.getLocationForTuple(tuple, !(type == FichePayeSheet.typeOO)) + File.separator + r.getString("ANNEE");
return path + File.separator + r.getString("ANNEE");
}
 
private void init() {
this.modele = "FichePaye.ods";
this.printer = PrinterNXProps.getInstance().getStringProperty("FichePayePrinter");
this.locationOO = getLocation(this.row, typeOO);
this.locationPDF = getLocation(this.row, typePDF);
}
 
protected void createMap() {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/report/LivrePayeSheet.java
60,18 → 60,18
setSize(8, 65, 3);
}
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationLivrePaye", "Livre de paye");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
@Override
protected String getYear() {
return "";
}
 
public static final String TEMPLATE_ID = "Livre de paye";
public static final String TEMPLATE_PROPERTY_NAME = "LocationLivrePaye";
 
public LivrePayeSheet(int moisDu, int moisAu, String annee) {
super();
this.printer = PrinterNXProps.getInstance().getStringProperty("LivrePayePrinter");
this.modele = "LivrePaye.ods";
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + annee;
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + annee;
this.moisAu = moisAu;
this.moisDu = moisDu;
this.annee = annee;
96,6 → 96,11
this.mCell.put("A" + row, "Période de " + rowMoisDu.getString("NOM") + " à " + rowMoisAu.getString("NOM") + " " + this.annee);
}
 
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
protected void createMap() {
 
this.mapReplace = new HashMap();
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/report/N4DS.java
New file
0,0 → 1,458
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.core.humanresources.employe.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.map.model.Ville;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
 
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.text.DateFormat;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
 
public class N4DS {
 
private static DateFormat format = new SimpleDateFormat("ddMMyyyy");
private ComptaPropsConfiguration conf = ((ComptaPropsConfiguration) Configuration.getInstance());
private long masseSalarialeBrute;
private static final byte[] retour = "'\n".getBytes();
private PrintStream stream = null;
 
// FIXME Salarie renvoye
 
/**
* Déclaration normale (type 51)
* */
public N4DS() {
 
}
 
public void createDocument() {
masseSalarialeBrute = 0;
File f = new File("N4DS_" + format.format(new Date()) + ".txt");
 
try {
 
stream = new PrintStream(f, "ISO-8859-1");
 
SQLElement eltSalarie = this.conf.getDirectory().getElement("SALARIE");
 
// Infos emetteur
SQLRow rowSociete = this.conf.getRowSociete();
 
writeS10(stream, rowSociete);
 
writeS20(stream, rowSociete);
 
SQLSelect sel = new SQLSelect(this.conf.getBase());
sel.addSelect(eltSalarie.getTable().getKey());
 
@SuppressWarnings("unchecked")
List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltSalarie.getTable()));
 
for (SQLRow row : l) {
N4DSSalarie s = new N4DSSalarie(this);
s.write(row, rowSociete);
 
}
writeS80(stream, rowSociete);
writeS90(stream);
 
} catch (IOException e) {
e.printStackTrace();
} finally {
if (stream != null) {
stream.close();
}
}
}
 
private void writeS80(PrintStream stream, SQLRow rowSociete) throws IOException {
 
String siren = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(0, 9);
String nic = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(9);
 
// SIREN
write("S80.G01.00.001.001", siren);
 
// NIC
write("S80.G01.00.001.002", nic);
 
SQLRow rowAdr = rowSociete.getForeignRow("ID_ADRESSE_COMMON");
String voie = rowAdr.getString("RUE");
 
Ville ville = Ville.getVilleFromVilleEtCode(rowAdr.getString("VILLE"));
 
// Complement adresse
if (voie.contains("\n")) {
String[] sVoies = voie.split("\n");
if (sVoies.length > 0) {
voie = sVoies[0];
String complement = "";
for (int i = 1; i < sVoies.length; i++) {
complement += sVoies[i].trim() + " ";
}
if (complement.length() > 0) {
complement = complement.substring(0, complement.length() - 1);
}
 
write("S80.G01.00.003.001", complement);
}
}
 
// Voie
write("S80.G01.00.003.006", voie);
 
// TODO Code INSEE, facultatif
// stream.write("S80.G01.00.003.007",voie);
 
// FIXME Service de distribution
// stream.write("S80.G01.00.003.009",ville.getName());
 
// Code postal
write("S80.G01.00.003.010", ville.getCodepostal());
 
// Localité
write("S80.G01.00.003.012", ville.getName().toUpperCase());
 
// Code Pays, ne doit pas être renseigné pour une adresse en France
// TODO support des autres pays
// write("S80.G01.00.003.013", "");
 
// FIXME effectif déclaré
write("S80.G01.00.004.001", String.valueOf(getEffectifDeclare()));
 
// TODO Code établissement sans salarié
// write( "S80.G01.00.004.001", "2");
 
// TODO Code assujettis taxe sur salaires
write("S80.G01.00.005", "01");
 
// Code NAF etablissement
write("S80.G01.00.006", rowSociete.getString("NUM_APE"));
 
// FIXME Code section prud'homale
write("S80.G01.00.007.001", "04");
 
// TODO stecion principale dérogatoire
// write( "S80.G01.00.004.001", "2");
 
// TODO Institution Prevoyance sans salarie
// write( "S80.G01.01.001", "P0012");
// write( "S80.G01.01.002", "0003");
 
// TODO Institution retraite sans salarie
// write( "S80.G01.02.001", "G022");
 
// FIXME Code assujettissement taxe et contribution apprentissage
write("S80.G62.05.001", "01");
long totalApprentissage = Math.round(this.masseSalarialeBrute * 0.0068);
System.err.println(this.masseSalarialeBrute);
write("S80.G62.05.002.001", String.valueOf(totalApprentissage));
 
write("S80.G62.05.003", "02");
 
// FIXME Code assujettissement formation professionnelle continue
write("S80.G62.10.001", "01");
long totalFormation = Math.round(this.masseSalarialeBrute * 0.0055);
write("S80.G62.10.003.001", String.valueOf(totalFormation));
 
}
 
private void writeS90(PrintStream stream) throws IOException {
// Nombre total de rubrique + S90
write("S90.G01.00.001", String.valueOf(this.nbRubrique + 2));
 
// Nombre total de rubrique S20
write("S90.G01.00.002", String.valueOf(1));
}
 
private int nbRubrique = 0;
 
public void write(String rubriqueName, String value) throws IOException {
String tmp = rubriqueName + ",'";
stream.write(tmp.getBytes());
stream.write(value.getBytes());
stream.write(retour);
 
// if (rubriqueName.startsWith("S20")) {
// this.nbRubriqueS20++;
// }
this.nbRubrique++;
}
 
private int getEffectifDeclare() {
// FIXME ne pas inclure les intérimaires
SQLElement eltSalarie = this.conf.getDirectory().getElement("SALARIE");
SQLElement eltInfos = this.conf.getDirectory().getElement("INFOS_SALARIE_PAYE");
SQLSelect sel = new SQLSelect(eltSalarie.getTable().getBase());
sel.addSelect(eltSalarie.getTable().getKey());
Date d2 = new Date(110, 11, 31);
Where w = new Where(eltSalarie.getTable().getField("ID_INFOS_SALARIE_PAYE"), "=", eltInfos.getTable().getKey());
w = w.and(new Where(eltInfos.getTable().getField("DATE_SORTIE"), "=", (Date) null).or(new Where(eltInfos.getTable().getField("DATE_SORTIE"), ">", d2)));
 
sel.setWhere(w);
System.err.println(sel.asString());
List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltSalarie.getTable()));
 
return (l == null ? 0 : l.size());
}
 
public static String normalizeString2(String s) {
s = s.toUpperCase();
String temp = Normalizer.normalize(s, Form.NFC);
temp = temp.replaceAll("-", " ");
return temp.replaceAll("[^\\p{ASCII}]", "");
}
 
private void writeS20(PrintStream stream, SQLRow rowSociete) throws IOException {
 
// Siren
 
String siren = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(0, 9);
String nic = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(9);
write("S20.G01.00.001", siren);
 
// Raison sociale
write("S20.G01.00.002", rowSociete.getString("NOM"));
 
// FIXME Debut periode
write("S20.G01.00.003.001", "01012011");
 
// FIXME Fin periode
write("S20.G01.00.003.002", "31122011");
 
// Code nature
write("S20.G01.00.004.001", "01");
 
// FIXME Code type (complement, Rectificatif, ...)
write("S20.G01.00.004.002", "51");
 
// fraction
write("S20.G01.00.005", "11");
 
// TODO debut periode rattachement
// stream.write("S20.G01.00.006.001,'","11");
 
// fin periode rattachement
// stream.write("S20.G01.00.006.002,'","11");
 
// Code devise de la déclaration
write("S20.G01.00.007", "01");
 
// NIC
write("S20.G01.00.008", nic);
 
SQLRow rowAdr = rowSociete.getForeignRow("ID_ADRESSE_COMMON");
String voie = rowAdr.getString("RUE");
 
Ville ville = Ville.getVilleFromVilleEtCode(rowAdr.getString("VILLE"));
 
// Complement adresse
if (voie.contains("\n")) {
String[] sVoies = voie.split("\n");
if (sVoies.length > 0) {
voie = sVoies[0];
String complement = "";
for (int i = 1; i < sVoies.length; i++) {
complement += sVoies[i].trim() + " ";
}
if (complement.length() > 0) {
complement = complement.substring(0, complement.length() - 1);
}
 
write("S20.G01.00.009.001", complement);
}
}
 
// Voie
write("S20.G01.00.009.006", voie);
 
// TODO Code INSEE
// stream.write("S20.G01.00.009.007",voie);
 
// FIXME Service de distribution
// stream.write("S20.G01.00.009.009",ville.getName());
 
// Code postal
write("S20.G01.00.009.010", ville.getCodepostal());
 
// Localité
write("S20.G01.00.009.012", ville.getName().toUpperCase());
 
// TODO Code Pays pour les autres pays que la France
// write("S20.G01.00.009.013","");
// write("S20.G01.00.009.016","");
 
write("S20.G01.00.013.002", "1");
// Code periodicite
// TODO déclaration autre que annuelle
write("S20.G01.00.018", "A00");
 
}
 
/**
* Strucuture S10, N4DS
* */
private void writeS10(PrintStream stream, SQLRow rowSociete) throws IOException {
 
// Siren
 
String siren = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(0, 9);
String nic = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(9);
write("S10.G01.00.001.001", siren);
 
// NIC
write("S10.G01.00.001.002", nic);
 
// Raison sociale
write("S10.G01.00.002", rowSociete.getString("NOM"));
 
SQLRow rowAdr = rowSociete.getForeignRow("ID_ADRESSE_COMMON");
String voie = rowAdr.getString("RUE");
 
Ville ville = Ville.getVilleFromVilleEtCode(rowAdr.getString("VILLE"));
 
// Complement adresse
if (voie.contains("\n")) {
String[] sVoies = voie.split("\n");
if (sVoies.length > 0) {
voie = sVoies[0];
String complement = "";
for (int i = 1; i < sVoies.length; i++) {
complement += sVoies[i] + " ";
}
if (complement.length() > 0) {
complement = complement.substring(0, complement.length() - 1);
}
 
write("S10.G01.00.003.001", complement);
}
}
 
// Voie
write("S10.G01.00.003.006", voie);
 
// TODO Code INSEE, facultatif
// stream.write("S10.G01.00.003.007",voie);
 
// TODO: Service de distribution
write("S10.G01.00.003.009", ville.getName());
 
// Code postal
write("S10.G01.00.003.010", ville.getCodepostal());
 
// Localité
write("S10.G01.00.003.012", ville.getName().toUpperCase());
 
// Code Pays, ne doit pas être renseigné pour une adresse en France
// TODO support des autres pays
// write("S10.G01.00.003.013", "");
 
// FIXME Référence de l'envoi
// Incrémenté le numéro
write("S10.G01.00.004,'", "1");
 
// Nom du logiciel
write("S10.G01.00.005", "OpenConcerto");
 
// Nom de l'éditeur
write("S10.G01.00.006", "ILM Informatique");
 
// Numéro version
// FIXME: utiliser le nuémro de version du logiciel
write("S10.G01.00.007", "1.2");
 
// Code service choisi
write("S10.G01.00.009", "40");
 
// Code envoi du fichier essai ou réel
write("S10.G01.00.010", "02");
 
// Norme utilisée
write("S10.G01.00.011", "V01X06");
 
// Code table char
write("S10.G01.00.012", "01");
 
// TODO Contact pour DADS
// Code civilite
write("S10.G01.01.001.001", "01");
// Nom Contact
// TODO Contact pour DADS
write("S10.G01.01.001.002", "MAILLARD GUILLAUME");
 
// Code domaine
// TODO Contact pour DADS
write("S10.G01.01.002", "03");
 
// Adresse mail
// TODO Contact pour DADS
write("S10.G01.01.005", "contact@ilm-informatique.fr");
 
// Tel
// TODO Contact pour DADS
write("S10.G01.01.006", "0322194472");
// TODO Contact pour DADS
 
// Fax
write("S10.G01.01.007", "0322194408");
}
 
private String getNumeroVoie(String voie) {
String numero = "";
voie = voie.trim();
for (int i = 0; i < voie.trim().length(); i++) {
char c = voie.charAt(i);
if (c >= '0' && c <= '9') {
numero += c;
} else {
break;
}
}
return numero;
}
 
private String getVoieWithoutNumber(String voie) {
voie = voie.trim();
String resultVoie = new String(voie);
 
for (int i = 0; i < voie.trim().length(); i++) {
char c = voie.charAt(i);
if (c >= '0' && c <= '9') {
resultVoie = resultVoie.substring(1);
} else {
break;
}
}
return resultVoie.trim();
}
 
public void addMasseSalarialeBrute(long baseBrute) {
this.masseSalarialeBrute += baseBrute;
 
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/report/N4DSSalarie.java
New file
0,0 → 1,508
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.core.humanresources.employe.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.map.model.Ville;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
 
import java.io.IOException;
import java.text.DateFormat;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
 
public class N4DSSalarie {
 
private static DateFormat format = new SimpleDateFormat("ddMMyyyy");
private ComptaPropsConfiguration conf = ((ComptaPropsConfiguration) Configuration.getInstance());
private N4DS n4ds;
 
// FIXME Salarie renvoye
 
public N4DSSalarie(N4DS n4ds) {
this.n4ds = n4ds;
}
 
public void write(SQLRow row, SQLRow rowSociete) throws IOException {
writeS30(row);
writeS41(row, rowSociete);
writeS44(row);
}
 
private void writeS44(SQLRow rowSalarie) throws IOException {
// FIXME
n4ds.write("S44.G01.00.001", "07");
n4ds.write("S44.G01.00.002", "1100");
 
}
 
private void writeS41(SQLRow rowSalarie, SQLRow rowSociete) throws IOException {
 
// FIXME Debut periode
n4ds.write("S40.G01.00.001", "01012011");
// FIXME embauche, etc...
n4ds.write("S40.G01.00.002.001", "097");
 
// FIXME Fin periode
n4ds.write("S40.G01.00.003", "31122010");
// FIXME licenciement, etc...
n4ds.write("S40.G01.00.004.001", "098");
 
// Nic de l'établissment du d'affectation du salarié
String siren = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(0, 9);
String nic = rowSociete.getString("NUM_SIRET").replaceAll(" ", "").substring(9);
n4ds.write("S40.G01.00.005", nic);
 
// Nic de l'établissment du lieu de travail du salarié
// FIXME gerer si different
n4ds.write("S40.G05.00.001", nic);
 
// FIXME n4ds.write("S40.G05.00.002", enseigne);
// Numéro, extension, nature et libellé de la voie
// FIXME n4ds.write("S40.G05.00.060.006", voie);
// Code postal
// FIXME n4ds.write("S40.G05.00.060.010", codePostal);
// FIXME n4ds.write("S40.G05.00.060.012", localite);
 
// TODO siren de l'entreprise du lieu de travail
// A remplir si different de S40.G05.00.001 n4ds.write("S40.G05.00.070",siren);
 
/**
* Situation administrative générale du salarié ou de l'agent. S40.G10.00
*/
 
// TODO: ajouter les codes emplois pour le public, etc...
n4ds.write("S40.G10.00.005", "10");
 
// TODO Code Employeur multiple
// Ici forcé en employeur unique
n4ds.write("S40.G10.00.008.001", "01");
 
// TODO Code Emploi multiple
// Ici forcé en emploi unique
n4ds.write("S40.G10.00.008.002", "01");
 
// TODO Code decalage paie
// Ici, sans décalage de paie
n4ds.write("S40.G10.00.009.001", "01");
// Ici, paiement au mois
n4ds.write("S40.G10.00.009.002", "01");
 
SQLRow rowInfos = rowSalarie.getForeignRow("ID_INFOS_SALARIE_PAYE");
SQLRow rowContrat = rowInfos.getForeignRow("ID_CONTRAT_SALARIE");
 
// Nature de l'emploi
n4ds.write("S40.G10.00.010", rowContrat.getString("NATURE"));
 
// Catégorie socio
SQLRow rowCodeEmploi = rowContrat.getForeignRow("ID_CODE_EMPLOI");
n4ds.write("S40.G10.05.011.001", rowCodeEmploi.getString("CODE"));
 
// code contrat
SQLRow rowCodeContrat = rowContrat.getForeignRow("ID_CODE_CONTRAT_TRAVAIL");
n4ds.write("S40.G10.05.012.001", rowCodeContrat.getString("CODE"));
 
// code droit contrat
SQLRow rowCodeDroitContrat = rowContrat.getForeignRow("ID_CODE_DROIT_CONTRAT");
n4ds.write("S40.G10.05.012.002", rowCodeDroitContrat.getString("CODE"));
 
// FIXME code conjoint salarie
// stream.write("S41.G01.00.012.003",rowCodeDroitContrat.getString("CODE"));
 
// code caracteristique travail
// SQLRow rowCaractAct = rowContrat.getForeignRow("ID_CODE_CARACT_ACTIVITE");
// n4ds.write("S41.G01.00.013", rowCaractAct.getString("CODE"));
 
// code statut prof
// SQLRow rowStatutProf = rowContrat.getForeignRow("ID_CODE_STATUT_PROF");
// n4ds.write("S41.G01.00.014", rowStatutProf.getString("CODE"));
 
// FIXME code statut cat convention
SQLRow rowStatutCat = rowContrat.getForeignRow("ID_CODE_STATUT_CATEGORIEL");
// n4ds.write("S41.G01.00.015.001", "01");
 
// Code statut cat agirc arrco
n4ds.write("S40.G10.05.015.002", rowStatutCat.getString("CODE"));
 
// Convention collective IDCC
SQLRow rowIDCC = rowInfos.getForeignRow("ID_IDCC");
n4ds.write("S40.G10.05.016", rowIDCC.getString("CODE"));
 
// FIXME Classement conventionnel
n4ds.write("S40.G10.05.017", "sans classement conventionnel");
 
/**
* Caisse spécifique de congés payés. S40.G10.06
*/
 
//
 
/**
* Complément salarié sous contrat de droit privé dans le secteur public. S40.G10.08
*/
// TODO secteur public
 
/**
* Situation administrative spécifique de l'agent sous statut d'emploi de droit public.
* S40.G10.10
*/
// TODO secteur public
 
/**
* Emploi supérieur antérieur de l'agent sous statut personnel de droit public. S40.G10.15
* */
// TODO secteur public
 
/**
* Départ ou retour de détachement de l'agent sous statut personnel de droit public.
* S40.G10.24
*/
// TODO secteur public
 
// FIXME Code regime de base obligatoire
// n4ds.write("S41.G01.00.018.001", "200");
 
// TODO rubrique conditionnelle
 
// if (prenom.equalsIgnoreCase("guillaume")) {
// // FIXME Durée anuelle du travail
// n4ds.write( "S41.G01.00.023.001", "99");
//
// // FIXME Durée trimestrielle du travail
// n4ds.write( "S41.G01.00.023.002", "12");
//
// // FIXME Durée mensuelle du travail
// n4ds.write( "S41.G01.00.023.003", "98");
// } else {
 
// FIXME Code unité d'expression du temps de travail
n4ds.write("S40.G15.00.001", "10");
 
// FIXME Code unité d'expression du temps de travail
n4ds.write("S40.G15.00.003", "----------------------");
// }
// TODO Code section accident travail
n4ds.write("S41.G01.00.025", "01");
 
// TODO Code risque accident travail
n4ds.write("S41.G01.00.026", "516GB");
 
// TODO Code bureau
// n4ds.write( "S41.G01.00.027", "B");
 
// Taux accident travail
float f = rowInfos.getFloat("TAUX_AT");
String tauxAT = String.valueOf(Math.round(f * 100.0));
n4ds.write("S41.G01.00.028", tauxAT);
 
// Base brute
final long baseBrute = getBaseBrute(rowSalarie);
n4ds.write("S41.G01.00.029.001", String.valueOf(baseBrute));
n4ds.addMasseSalarialeBrute(baseBrute);
 
// Code nature cotisations
n4ds.write("S41.G01.00.029.003", "01");
 
// FIXME Base brute limité plafond
n4ds.write("S41.G01.00.030.001", String.valueOf(baseBrute));
 
// CSG
n4ds.write("S41.G01.00.032.001", String.valueOf(getCSG(rowSalarie)));
 
// CRDS
n4ds.write("S41.G01.00.033.001", String.valueOf(getCSG(rowSalarie)));
 
// FIXME base brute fiscale
n4ds.write("S41.G01.00.035.001", String.valueOf(baseBrute));
 
long fraisPro = getFraisProfessionels(rowSalarie);
 
if (fraisPro > 0) {
// Montant des frais professionnels
n4ds.write("S41.G01.00.044.001", String.valueOf(fraisPro));
 
// remboursement frais pro
n4ds.write("S41.G01.00.046", "R");
}
 
// revenu d'activite net
n4ds.write("S41.G01.00.063.001", String.valueOf(getNetImp(rowSalarie)));
 
// FIXME Régimes complémentaires
// Mederic
n4ds.write("S41.G01.01.001", "G022");
n4ds.write("S41.G01.01.002", "200339139001002");
 
// UGRR
n4ds.write("S41.G01.01.001", "A700");
n4ds.write("S41.G01.01.002", "800943487");
 
// UGRC
n4ds.write("S41.G01.01.001", "C039");
n4ds.write("S41.G01.01.002", "00095913");
 
// Fillon
if (rowSalarie.getString("PRENOM").equalsIgnoreCase("ludovic") || rowSalarie.getString("PRENOM").equalsIgnoreCase("guillaume")) {
// S41.G01.06.001 Code type exonération O X ..6
n4ds.write("S41.G01.06.001", "33");
// X S41.G01.06.002.001 Base brute soumise à exonération O N ..10
n4ds.write("S41.G01.06.002.001", String.valueOf(baseBrute));
}
 
// FIXME Election Prud'homales
n4ds.write("S41.G02.00.008", String.valueOf("01"));
n4ds.write("S41.G02.00.009", String.valueOf("01"));
n4ds.write("S41.G02.00.010", String.valueOf("04"));
}
 
private long getFraisProfessionels(SQLRow rowSalarie) {
 
SQLElement eltFichePaye = this.conf.getDirectory().getElement("FICHE_PAYE");
SQLElement eltFichePayeElement = this.conf.getDirectory().getElement("FICHE_PAYE_ELEMENT");
SQLElement eltRubriqueNet = this.conf.getDirectory().getElement("RUBRIQUE_NET");
SQLSelect sel = new SQLSelect(rowSalarie.getTable().getBase());
sel.addSelect(eltFichePayeElement.getTable().getKey());
Date d = new Date(110, 0, 1);
Date d2 = new Date(110, 11, 31);
Where w = new Where(eltFichePaye.getTable().getField("DU"), d, d2);
w = w.and(new Where(eltFichePaye.getTable().getField("VALIDE"), "=", Boolean.TRUE));
w = w.and(new Where(eltFichePaye.getTable().getField("ID_SALARIE"), "=", rowSalarie.getID()));
w = w.and(new Where(eltFichePayeElement.getTable().getField("ID_FICHE_PAYE"), "=", eltFichePaye.getTable().getKey()));
w = w.and(new Where(eltFichePayeElement.getTable().getField("SOURCE"), "=", "RUBRIQUE_NET"));
 
sel.setWhere(w);
System.err.println(sel.asString());
List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltFichePayeElement.getTable()));
 
float fraisPro = 0;
for (SQLRow row : l) {
int id = row.getInt("IDSOURCE");
if (id > 1) {
SQLRow rowRubrique = eltRubriqueNet.getTable().getRow(id);
if (rowRubrique.getBoolean("FRAIS_PERS")) {
fraisPro += row.getFloat("MONTANT_SAL_AJ");
}
}
}
 
return Math.round(fraisPro);
}
 
private long getBaseBrute(SQLRow rowSalarie) {
 
SQLElement eltFichePaye = this.conf.getDirectory().getElement("FICHE_PAYE");
SQLSelect sel = new SQLSelect(rowSalarie.getTable().getBase());
sel.addSelect(eltFichePaye.getTable().getKey());
Date d = new Date(110, 0, 1);
Date d2 = new Date(110, 11, 31);
Where w = new Where(eltFichePaye.getTable().getField("DU"), d, d2);
w = w.and(new Where(eltFichePaye.getTable().getField("VALIDE"), "=", Boolean.TRUE));
w = w.and(new Where(eltFichePaye.getTable().getField("ID_SALARIE"), "=", rowSalarie.getID()));
 
sel.setWhere(w);
System.err.println(sel.asString());
List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltFichePaye.getTable()));
 
float brut = 0;
for (SQLRow row : l) {
brut += row.getFloat("SAL_BRUT");
}
 
return Math.round(brut);
}
 
private long getNetImp(SQLRow rowSalarie) {
 
SQLElement eltFichePaye = this.conf.getDirectory().getElement("FICHE_PAYE");
SQLSelect sel = new SQLSelect(rowSalarie.getTable().getBase());
sel.addSelect(eltFichePaye.getTable().getKey());
Date d = new Date(110, 0, 1);
Date d2 = new Date(110, 11, 31);
Where w = new Where(eltFichePaye.getTable().getField("DU"), d, d2);
w = w.and(new Where(eltFichePaye.getTable().getField("VALIDE"), "=", Boolean.TRUE));
w = w.and(new Where(eltFichePaye.getTable().getField("ID_SALARIE"), "=", rowSalarie.getID()));
 
sel.setWhere(w);
List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltFichePaye.getTable()));
 
float brut = 0;
for (SQLRow row : l) {
brut += row.getFloat("NET_IMP");
}
 
return Math.round(brut);
}
 
private long getCSG(SQLRow rowSalarie) {
 
SQLElement eltFichePaye = this.conf.getDirectory().getElement("FICHE_PAYE");
SQLSelect sel = new SQLSelect(rowSalarie.getTable().getBase());
sel.addSelect(eltFichePaye.getTable().getKey());
Date d = new Date(110, 0, 1);
Date d2 = new Date(110, 11, 31);
Where w = new Where(eltFichePaye.getTable().getField("DU"), d, d2);
w = w.and(new Where(eltFichePaye.getTable().getField("VALIDE"), "=", Boolean.TRUE));
w = w.and(new Where(eltFichePaye.getTable().getField("ID_SALARIE"), "=", rowSalarie.getID()));
 
sel.setWhere(w);
List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltFichePaye.getTable()));
 
float brut = 0;
for (SQLRow row : l) {
brut += row.getFloat("CSG");
}
 
return Math.round(brut);
}
 
private void writeS30(SQLRow rowSalarie) throws IOException {
 
SQLRow rowEtatCivil = rowSalarie.getForeignRow("ID_ETAT_CIVIL");
 
// Numero inscription
String nir = rowEtatCivil.getString("NUMERO_SS").replaceAll(" ", "");
 
if (nir.length() >= 13) {
nir = nir.substring(0, 13);
} else {
JOptionPane.showMessageDialog(new JFrame(), "Numéro d'inscription pour le salarié " + rowSalarie.getString("PRENOM") + " " + rowSalarie.getString("NOM") + " incorrect");
 
}
n4ds.write("S30.G01.00.001", nir);
 
// Nom
n4ds.write("S30.G01.00.002", rowSalarie.getString("NOM"));
 
// Prenoms
// FIXME: regarder pour les prénoms pas seulement le 1er
n4ds.write("S30.G01.00.003", rowSalarie.getString("PRENOM"));
 
// Code civilite
final SQLRow rowTitre = rowSalarie.getForeignRow("ID_TITRE_PERSONNEL");
final String civilite = rowTitre.getString("NOM").toLowerCase();
if (civilite.contains("monsieur")) {
n4ds.write("S30.G01.00.007", "01");
} else if (civilite.contains("madame")) {
n4ds.write("S30.G01.00.007", "02");
} else if (civilite.contains("mademoiselle") || civilite.contains("mlle")) {
n4ds.write("S30.G01.00.007", "03");
} else {
JOptionPane.showMessageDialog(new JFrame(), "Civilité incorrecte pour " + rowSalarie.getString("PRENOM") + " " + rowSalarie.getString("NOM") + " (" + civilite + ")");
}
SQLRow rowAdr = rowEtatCivil.getForeignRow("ID_ADRESSE");
String voie = rowAdr.getString("RUE");
 
Ville ville = Ville.getVilleFromVilleEtCode(rowAdr.getString("VILLE"));
 
// Complement adresse
if (voie.contains("\n")) {
String[] sVoies = voie.split("\n");
if (sVoies.length > 0) {
voie = sVoies[0].trim();
String complement = "";
for (int i = 1; i < sVoies.length; i++) {
complement += sVoies[i].trim() + " ";
}
if (complement.length() > 0) {
complement = complement.substring(0, complement.length() - 1);
}
 
n4ds.write("S30.G01.00.008.001", complement);
}
}
 
// Numéro, extension, nature et libellé de la voie
n4ds.write("S30.G01.00.008.006", voie);
 
// Code postal
n4ds.write("S30.G01.00.008.010", ville.getCodepostal());
 
// Commune
String villeFormat = normalizeString2(ville.getName());
n4ds.write("S30.G01.00.008.012", villeFormat);
 
// Date de naissance
Date d = rowEtatCivil.getDate("DATE_NAISSANCE").getTime();
n4ds.write("S30.G01.00.009", format.format(d));
 
// Commune de naissance
String villeFormat2 = normalizeString2(rowEtatCivil.getString("COMMUNE_NAISSANCE"));
n4ds.write("S30.G01.00.010", villeFormat2);
 
SQLRow rowDept = rowEtatCivil.getForeignRow("ID_DEPARTEMENT_NAISSANCE");
 
// Code departement de naissance
n4ds.write("S30.G01.00.011", rowDept.getString("NUMERO"));
 
SQLRow rowPays = rowEtatCivil.getForeignRow("ID_PAYS_NAISSANCE");
 
// Pays naissance
String pays = rowPays.getString("NOM").toUpperCase();
n4ds.write("S30.G01.00.012", pays);
 
// Pays
n4ds.write("S30.G01.00.013", pays);
 
// Matricule Salarie
n4ds.write("S30.G10.05.001", rowSalarie.getString("CODE"));
}
 
public static String normalizeString2(String s) {
s = s.toUpperCase();
String temp = Normalizer.normalize(s, Form.NFC);
temp = temp.replaceAll("-", " ");
return temp.replaceAll("[^\\p{ASCII}]", "");
}
 
private String getNumeroVoie(String voie) {
String numero = "";
voie = voie.trim();
for (int i = 0; i < voie.trim().length(); i++) {
char c = voie.charAt(i);
if (c >= '0' && c <= '9') {
numero += c;
} else {
break;
}
}
return numero;
}
 
private String getVoieWithoutNumber(String voie) {
voie = voie.trim();
String resultVoie = new String(voie);
 
for (int i = 0; i < voie.trim().length(); i++) {
char c = voie.charAt(i);
if (c >= '0' && c <= '9') {
resultVoie = resultVoie.substring(1);
} else {
break;
}
}
return resultVoie.trim();
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/action/N4DSAction.java
New file
0,0 → 1,34
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.core.humanresources.employe.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.core.humanresources.employe.report.N4DS;
 
import javax.swing.Action;
import javax.swing.JFrame;
 
public class N4DSAction extends CreateFrameAbstractAction {
 
public N4DSAction() {
super();
this.putValue(Action.NAME, "Déclaration N4DS");
}
 
@Override
public JFrame createFrame() {
new N4DS().createDocument();
return new JFrame();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/component/SaisieVenteFactureSQLComponent.java
56,6 → 56,7
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.TitledSeparator;
import org.openconcerto.ui.component.ITextArea;
183,6 → 184,17
this.textIdSource = new JTextField();
this.textAvoirTTC = new DeviseField();
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = new JPanel();
this.setAdditionalFieldsPanel(new FormLayouter(addP, 1));
this.add(addP, c);
 
c.gridy++;
c.gridwidth = 1;
 
/*******************************************************************************************
* * RENSEIGNEMENTS
******************************************************************************************/
927,9 → 939,15
 
 
// generation du document
VenteFactureXmlSheet sheet = new VenteFactureXmlSheet(rowFacture);
sheet.genere(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected());
final VenteFactureXmlSheet sheet = new VenteFactureXmlSheet(rowFacture);
 
try {
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(panelOO.isVisualisationSelected(), panelOO.isImpressionSelected(), true);
} catch (Exception e) {
ExceptionHandler.handle("Impossible de générer la facture", e);
}
 
int idMvt = -1;
if (getMode() == Mode.MODIFICATION) {
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/element/SaisieVenteFactureSQLElement.java
50,8 → 50,10
 
public class SaisieVenteFactureSQLElement extends ComptaSQLConfElement {
 
public static final String TABLENAME = "SAISIE_VENTE_FACTURE";
 
public SaisieVenteFactureSQLElement() {
super("SAISIE_VENTE_FACTURE", "une facture", "factures");
super(TABLENAME, "une facture", "factures");
}
 
protected List<String> getListFields() {
244,7 → 246,7
SQLRow rowArticleFind = eltArticle.getTable().getRow(idArticle);
SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCmdElt);
SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticleFind));
 
rowValsElt.put("ID_STYLE", sqlRow.getObject("ID_STYLE"));
rowValsElt.put("QTE", sqlRow.getObject("QTE"));
rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/report/ListeFactureXmlSheet.java
23,6 → 23,7
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
33,25 → 34,26
import java.util.Map;
 
public class ListeFactureXmlSheet extends AbstractListeSheetXml {
public static final String TEMPLATE_ID = "ListeFacture";
public static final String TEMPLATE_PROPERTY_NAME = DEFAULT_PROPERTY_NAME;
 
private List<Map<String, Object>> listValues;
private static final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
 
private List<Integer> listeIds;
 
public static Tuple2<String, String> getTuple2Location() {
return tupleDefault;
}
 
public ListeFactureXmlSheet(List<Integer> listeIds) {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.listeIds = listeIds;
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true);
}
 
@Override
public String getDefaultModele() {
// TODO Raccord de méthode auto-généré
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
@Override
public String getName() {
return "ListeFacture";
}
 
100,7 → 102,4
this.listAllSheetValues.put(0, this.listValues);
}
 
public String getFileName() {
return getValidFileName("ListeFacture");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/report/VenteFactureXmlSheet.java
14,8 → 14,7
package org.openconcerto.erp.core.sales.invoice.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
23,20 → 22,13
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
 
public class VenteFactureXmlSheet extends AbstractSheetXml {
public class VenteFactureXmlSheet extends AbstractSheetXMLWithDate {
 
private String startName;
public static final String TEMPLATE_ID = "VenteFacture";
public static final String TEMPLATE_PROPERTY_NAME = "LocationFacture";
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationFacture", "Factures");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
@Override
public String getReference() {
return this.row.getString("NOM");
43,6 → 35,19
}
 
@Override
public String getName() {
final String startName;
if (row.getBoolean("COMPLEMENT")) {
startName = "FactureComplement_";
} else if (row.getBoolean("ACOMPTE")) {
startName = "FactureAcompte_";
} else {
startName = "Facture_";
}
return startName + this.row.getString("NUMERO");
}
 
@Override
public SQLRow getRowLanguage() {
SQLRow rowClient = this.row.getForeignRow("ID_CLIENT");
if (rowClient.getTable().contains("ID_LANGUE")) {
56,35 → 61,27
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("FacturePrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
Calendar cal = Calendar.getInstance();
cal.setTime((Date) row.getObject("DATE"));
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
getDefaultModele();
getDefaultTemplateId();
}
 
@Override
public String getDefaultModele() {
String modele;
public String getType() {
String type;
if (row.getBoolean("COMPLEMENT")) {
this.startName = "FactureComplement_";
modele = "VenteFactureComplement";
type = "Complement";
} else if (row.getBoolean("ACOMPTE")) {
type = "Acompte";
} else {
if (row.getBoolean("ACOMPTE")) {
this.startName = "FactureAcompte_";
modele = "VenteFactureAcompte";
} else {
this.startName = "Facture_";
modele = "VenteFacture";
type = "null";
 
}
 
return type;
}
 
return modele;
 
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
public String getFileName() {
 
return getValidFileName(this.startName + this.row.getString("NUMERO"));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/report/VenteComptoirSheet.java
29,11 → 29,12
private static final SQLTable tableComptoir = base.getTable("SAISIE_VENTE_COMPTOIR");
private static final SQLTable tableClient = base.getTable("CLIENT");
private static final SQLTable tableAdresse = base.getTable("ADRESSE");
private final static SQLTable tableAdresseCommon = Configuration.getInstance().getBase().getTable("ADRESSE_COMMON");
private static final SQLTable tableArticle = base.getTable("ARTICLE");
private static final SQLTable tableTaxe = base.getTable("TAXE");
private static final SQLTable tableModeRegl = base.getTable("MODE_REGLEMENT");
private static final SQLTable tableTypeRegl = base.getTable("TYPE_REGLEMENT");
public static final String TEMPLATE_ID = "VenteComptoir";
public static final String TEMPLATE_PROPERTY_NAME = "LocationVenteComptoir";
 
public VenteComptoirSheet(int idFact) {
super(idFact, tableComptoir);
43,6 → 44,16
super(rowSaisie);
}
 
@Override
protected String getYear() {
return "";
}
 
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
protected void createMap() {
// TODO Auto-generated method stub
this.mCell = new HashMap();
89,4 → 100,5
 
this.mCell.put("A35", this.row.getObject("INFOS"));
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/report/ListeVenteXmlSheet.java
26,6 → 26,7
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
42,31 → 43,33
 
private static final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
 
public static final String TEMPLATE_ID = "ListeVentes";
public static final String TEMPLATE_PROPERTY_NAME = DEFAULT_PROPERTY_NAME;
 
private Date du, au;
private List<SQLRow> listeIds;
JProgressBar bar;
private JProgressBar bar;
private SQLElement eltAvoir = Configuration.getInstance().getDirectory().getElement("AVOIR_CLIENT");
private SQLElement eltEnc = Configuration.getInstance().getDirectory().getElement("ENCAISSER_MONTANT");
private SQLElement eltEncElt = Configuration.getInstance().getDirectory().getElement("ENCAISSER_MONTANT_ELEMENT");
 
public static Tuple2<String, String> getTuple2Location() {
return tupleDefault;
}
 
public ListeVenteXmlSheet(List<SQLRow> listeIds, Date du, Date au, JProgressBar bar) {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.listeIds = listeIds;
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true);
this.du = du;
this.au = au;
this.bar = bar;
}
 
public String getDefaultModele() {
return "ListeVentes";
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
};
 
SQLElement eltAvoir = Configuration.getInstance().getDirectory().getElement("AVOIR_CLIENT");
SQLElement eltEnc = Configuration.getInstance().getDirectory().getElement("ENCAISSER_MONTANT");
SQLElement eltEncElt = Configuration.getInstance().getDirectory().getElement("ENCAISSER_MONTANT_ELEMENT");
@Override
public String getName() {
return "JournalVentes";
}
 
protected void createListeValues() {
 
172,7 → 175,4
this.mapAllSheetValues.put(0, values);
}
 
public String getFileName() {
return getValidFileName("JournalVentes");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/report/ListeDebiteursXmlSheet.java
15,7 → 15,6
 
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
24,7 → 23,6
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.Tuple2;
 
import java.text.DateFormat;
import java.text.SimpleDateFormat;
37,20 → 35,19
 
private static final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
 
public static Tuple2<String, String> getTuple2Location() {
return tupleDefault;
}
 
public ListeDebiteursXmlSheet() {
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.locationOO = SheetXml.getLocationForTuple(tupleDefault, false);
this.locationPDF = SheetXml.getLocationForTuple(tupleDefault, true);
}
 
public String getDefaultModele() {
public String getDefaultTemplateId() {
return "ListeDebiteur";
}
 
@Override
public String getName() {
return "ListeDebiteurs";
}
 
SQLElement eltEch = Configuration.getInstance().getDirectory().getElement("ECHEANCE_CLIENT");
SQLElement eltVf = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
SQLElement eltMvt = Configuration.getInstance().getDirectory().getElement("MOUVEMENT");
124,22 → 121,9
 
}
 
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// ListeDebiteursXmlSheet.this.bar.setMaximum(ListeDebiteursXmlSheet.this.listeIds.size());
// }
// });
 
// final Map<String, Object> values = new HashMap<String, Object>();
// values.put("DATE", "Du " + dateFormat.format(this.du) + " au " +
// dateFormat.format(this.au));
 
this.listAllSheetValues.put(0, listValues);
this.styleAllSheetValues.put(0, styleValues);
// this.mapAllSheetValues.put(0, values);
 
}
 
public String getFileName() {
return getValidFileName("ListeDebiteurs");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/action/ListeDebiteursAction.java
14,8 → 14,10
package org.openconcerto.erp.core.sales.invoice.action;
 
import org.openconcerto.erp.core.sales.invoice.report.ListeDebiteursXmlSheet;
import org.openconcerto.utils.ExceptionHandler;
 
import java.awt.event.ActionEvent;
import java.util.concurrent.ExecutionException;
 
import javax.swing.AbstractAction;
import javax.swing.Action;
28,8 → 30,17
 
@Override
public void actionPerformed(ActionEvent e) {
new Thread(new Runnable() {
public void run() {
final ListeDebiteursXmlSheet sheet = new ListeDebiteursXmlSheet();
try {
sheet.createDocumentAsynchronous().get();
sheet.showPrintAndExport(true, false, false);
} catch (Exception e) {
ExceptionHandler.handle("Impossible d'afficher la liste des débiteurs");
}
 
ListeDebiteursXmlSheet sheet = new ListeDebiteursXmlSheet();
sheet.genere(true, false);
}
}).start();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/action/ListeSaisieVenteFactureAction.java
25,6 → 25,7
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement;
import org.openconcerto.erp.core.sales.invoice.report.ListeFactureXmlSheet;
import org.openconcerto.erp.core.sales.invoice.report.VenteFactureXmlSheet;
import org.openconcerto.erp.core.sales.invoice.ui.DateEnvoiRenderer;
import org.openconcerto.erp.core.sales.invoice.ui.ListeFactureRenderer;
import org.openconcerto.erp.generationEcritures.GenerationMvtRetourNatexis;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
46,11 → 47,16
import org.openconcerto.sql.view.EditPanelListener;
import org.openconcerto.sql.view.IListFrame;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelColumnPath;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.IClosure;
 
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
60,7 → 66,9
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
 
import javax.sql.rowset.Predicate;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
69,6 → 77,7
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.table.TableColumn;
 
public class ListeSaisieVenteFactureAction extends CreateFrameAbstractAction {
 
90,12 → 99,37
final SQLTableModelSourceOnline src = eltFacture.getTableSource(true);
 
for (SQLTableModelColumn column : src.getColumns()) {
// if (column.getValueClass() == Long.class || column.getValueClass() ==
// if (column.getValueClass() == Long.class ||
// column.getValueClass() ==
// BigInteger.class || column.getValueClass() == BigDecimal.class)
column.setRenderer(ListeFactureRenderer.UTILS.getRenderer(column.getRenderer()));
if (column.getClass().isAssignableFrom(SQLTableModelColumnPath.class)) {
((SQLTableModelColumnPath) column).setEditable(false);
}
}
final SQLTableModelColumn dateEnvoiCol = src.getColumn(eltFacture.getTable().getField("DATE_ENVOI"));
 
((SQLTableModelColumnPath) dateEnvoiCol).setEditable(true);
 
final SQLTableModelColumn dateReglCol = src.getColumn(eltFacture.getTable().getField("DATE_REGLEMENT"));
((SQLTableModelColumnPath) dateReglCol).setEditable(true);
 
dateEnvoiCol.setColumnInstaller(new IClosure<TableColumn>() {
@Override
public void executeChecked(TableColumn columnDateEnvoi) {
columnDateEnvoi.setCellEditor(new org.openconcerto.ui.table.TimestampTableCellEditor());
columnDateEnvoi.setCellRenderer(new DateEnvoiRenderer());
}
});
 
// Edition des dates de reglement
dateReglCol.setColumnInstaller(new IClosure<TableColumn>() {
@Override
public void executeChecked(TableColumn columnDateReglement) {
columnDateReglement.setCellEditor(new org.openconcerto.ui.table.TimestampTableCellEditor());
columnDateReglement.setCellRenderer(new DateEnvoiRenderer());
}
});
this.listeAddPanel = new ListeGestCommEltPanel(eltFacture, new IListe(src)) {
 
 
146,28 → 180,42
this.frame = new IListFrame(this.listeAddPanel);
 
// FIXME Maybe Stock rowSelection in new List
final MouseSheetXmlListeListener mouseListener = new MouseSheetXmlListeListener(this.listeAddPanel.getListe(), VenteFactureXmlSheet.class) {
final MouseSheetXmlListeListener mouseListener = new MouseSheetXmlListeListener(VenteFactureXmlSheet.class) {
@Override
public List<AbstractAction> addToMenu() {
public List<RowAction> addToMenu() {
 
final SQLRow row = liste.getSelectedRow();
List<AbstractAction> l = new ArrayList<AbstractAction>(5);
if (row != null) {
AbstractAction actionAvoir = new AbstractAction("Transférer en avoir") {
// final SQLRow row = liste.getSelectedRow();
List<RowAction> l = new ArrayList<RowAction>(5);
PredicateRowAction actionBL = new PredicateRowAction(new AbstractAction("Transférer en bon de livraison") {
public void actionPerformed(ActionEvent e) {
SaisieVenteFactureSQLElement elt = (SaisieVenteFactureSQLElement) Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
elt.transfertAvoir(row.getID());
elt.transfertBL(IListe.get(e).getSelectedId());
}
};
l.add(actionAvoir);
AbstractAction actionBL = new AbstractAction("Transférer en bon de livraison") {
}, false);
actionBL.setPredicate(IListeEvent.getSingleSelectionPredicate());
l.add(actionBL);
PredicateRowAction actionClone = new PredicateRowAction(new AbstractAction("Créer à partir de ...") {
public void actionPerformed(ActionEvent e) {
 
SQLElement eltFact = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
EditFrame editFrame = new EditFrame(eltFact, EditPanel.CREATION);
 
((SaisieVenteFactureSQLComponent) editFrame.getSQLComponent()).loadFactureExistante(IListe.get(e).getSelectedId());
editFrame.setVisible(true);
}
}, false);
actionClone.setPredicate(IListeEvent.getSingleSelectionPredicate());
l.add(actionClone);
 
PredicateRowAction actionAvoir = new PredicateRowAction(new AbstractAction("Transférer en avoir") {
public void actionPerformed(ActionEvent e) {
SaisieVenteFactureSQLElement elt = (SaisieVenteFactureSQLElement) Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
elt.transfertBL(row.getID());
elt.transfertAvoir(IListe.get(e).getSelectedId());
}
};
l.add(actionBL);
}
}, false);
actionAvoir.setPredicate(IListeEvent.getSingleSelectionPredicate());
l.add(actionAvoir);
 
return l;
// return super.addToMenu();
 
174,7 → 222,7
}
};
// this.frame.getPanel().getListe().addRowActions(mouseListener.getRowActions());
this.frame.getPanel().getListe().getJTable().addMouseListener(mouseListener);
this.frame.getPanel().getListe().addIListeActions(mouseListener.getRowActions());
 
 
return this.frame;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/GenListeVentePanel.java
24,6 → 24,7
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.ExceptionHandler;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
30,7 → 31,6
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.concurrent.ExecutionException;
 
import javax.swing.JButton;
import javax.swing.JFrame;
96,6 → 96,7
if (e.getSource() == this.buttonGen) {
final Thread thread = new Thread(new Runnable() {
public void run() {
try {
SQLTable tableFact = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE").getTable();
SQLTable tableAvoir = Configuration.getInstance().getDirectory().getElement("AVOIR_CLIENT").getTable();
SQLSelect sel = new SQLSelect(Configuration.getInstance().getBase());
110,14 → 111,11
sel2.setDistinct(true);
l.addAll((List<SQLRow>) dataSource.execute(sel2.asString(), SQLRowListRSH.createFromSelect(sel2, tableAvoir)));
ListeVenteXmlSheet sheet = new ListeVenteXmlSheet(l, GenListeVentePanel.this.du.getDate(), GenListeVentePanel.this.au.getDate(), GenListeVentePanel.this.bar);
try {
sheet.genere(true, false).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
 
sheet.createDocumentAsynchronous().get();
sheet.showPrintAndExport(true, false, false);
} catch (Exception e) {
ExceptionHandler.handle("Erreur de traitement", e);
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/InvoiceEditGroup.java
New file
0,0 → 1,48
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.core.sales.invoice.ui;
 
import org.openconcerto.sql.element.Group;
import org.openconcerto.sql.element.LayoutHints;
 
public class InvoiceEditGroup extends Group {
 
public InvoiceEditGroup() {
super("sales.invoice.edit");
final Group g = new Group("sales.invoice.identifier");
g.add("NUMERO");
g.add("DATE");
g.add("NOM", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
g.add("ID_COMMERCIAL");
this.add(g);
 
final Group gCustomer = new Group("sales.invoice.customer");
gCustomer.add("ID_CLIENT", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
add(gCustomer, LayoutHints.DEFAULT_LARGE_GROUP_HINTS);
 
final Group gAddress = new Group("sales.invoice.address");
gAddress.add("ID_ADRESSE");
add(gAddress, LayoutHints.DEFAULT_LARGE_GROUP_HINTS);
 
final Group gElements = new Group("sales.invoice.elements");
gElements.add("(SAISIE_VENTE_FACTURE_ELEMENT)*", LayoutHints.DEFAULT_LIST_HINTS);
add(gElements, LayoutHints.DEFAULT_LIST_HINTS);
 
final Group gInfos = new Group("sales.invoice.info");
gInfos.add("INFOS", new LayoutHints(true, true, true, true));
add(gInfos);
 
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/ListeDesVentesPanel.java
33,7 → 33,10
import org.openconcerto.sql.view.EditPanel;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.ITableModel;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelColumnPath;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
186,45 → 189,45
panelFacture.add(filterDate, cFacture);
tabbedPane.add("Ventes avec facture", panelFacture);
 
tableFact.addMouseListener(new MouseSheetXmlListeListener(this.listeFact.getListe(), VenteFactureXmlSheet.class) {
this.listeFact.getListe().addIListeActions(new MouseSheetXmlListeListener(VenteFactureXmlSheet.class) {
EditFrame edit;
 
@Override
public List<AbstractAction> addToMenu() {
public List<RowAction> addToMenu() {
 
final SQLRow rowFacture = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getTable("SAISIE_VENTE_FACTURE")
.getRow(ListeDesVentesPanel.this.listeFact.getListe().getSelectedId());
AbstractAction actionAvoir = new AbstractAction("Transférer en avoir") {
PredicateRowAction actionAvoir = new PredicateRowAction(new AbstractAction("Transférer en avoir") {
public void actionPerformed(ActionEvent e) {
SaisieVenteFactureSQLElement elt = (SaisieVenteFactureSQLElement) Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
elt.transfertAvoir(rowFacture.getID());
elt.transfertAvoir(IListe.get(e).getSelectedId());
}
};
}, false);
 
AbstractAction actionCommande = new AbstractAction("Transférer en commande") {
PredicateRowAction actionCommande = new PredicateRowAction(new AbstractAction("Transférer en commande") {
public void actionPerformed(ActionEvent e) {
SaisieVenteFactureSQLElement elt = (SaisieVenteFactureSQLElement) Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE");
elt.transfertCommande(rowFacture.getID());
elt.transfertCommande(IListe.get(e).getSelectedId());
}
};
}, false);
 
AbstractAction actionClient = new AbstractAction("Détails client") {
PredicateRowAction actionClient = new PredicateRowAction(new AbstractAction("Détails client") {
public void actionPerformed(ActionEvent e) {
if (edit == null) {
edit = new EditFrame(eltClient, EditMode.READONLY);
}
edit.selectionId(rowFacture.getInt("ID_CLIENT"));
edit.selectionId(IListe.get(e).getSelectedRow().getInt("ID_CLIENT"));
edit.setVisible(true);
}
};
 
List<AbstractAction> l = new ArrayList<AbstractAction>(1);
}, false);
actionAvoir.setPredicate(IListeEvent.getSingleSelectionPredicate());
actionCommande.setPredicate(IListeEvent.getSingleSelectionPredicate());
actionClient.setPredicate(IListeEvent.getSingleSelectionPredicate());
List<RowAction> l = new ArrayList<RowAction>(3);
l.add(actionAvoir);
l.add(actionCommande);
l.add(actionClient);
return l;
}
});
}.getRowActions());
this.listeFact.getListe().addIListener(new org.openconcerto.sql.view.IListener() {
 
public void selectionId(int id, int field) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/EtatVentesPanel.java
137,19 → 137,11
 
EtatVentesXmlSheet sheet = new EtatVentesXmlSheet(this.du.getDate(), this.au.getDate());
try {
sheet.genere(false, false).get();
// FIXME Probleme avec l'odsviewer
if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
sheet.showDocument();
} else {
sheet.showPreviewDocument();
}
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
// FIXME probleme de rendu avec le viewer
sheet.createDocumentAsynchronous().get();
sheet.openDocument(false);
} catch (Exception e1) {
e1.printStackTrace();
} catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/component/DevisSQLComponent.java
37,6 → 37,7
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.TitledSeparator;
import org.openconcerto.ui.VFlowLayout;
92,6 → 93,16
setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = new JPanel();
this.setAdditionalFieldsPanel(new FormLayouter(addP, 1));
this.add(addP, c);
 
c.gridy++;
c.gridwidth = 1;
final JLabel labelNumero = new JLabel(getLabelFor("NUMERO"));
labelNumero.setHorizontalAlignment(SwingConstants.RIGHT);
this.add(labelNumero, c);
530,7 → 541,7
@Override
public int insert(final SQLRow order) {
 
int idDevis = getSelectedID();
final int idDevis;
// on verifie qu'un devis du meme numero n'a pas été inséré entre temps
if (this.numeroUniqueDevis.checkValidation()) {
 
540,9 → 551,13
this.table.createArticle(idDevis, getElement());
 
// generation du document
 
try {
final DevisXmlSheet sheet = new DevisXmlSheet(getTable().getRow(idDevis));
sheet.genere(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected());
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(DevisSQLComponent.this.panelOO.isVisualisationSelected(), DevisSQLComponent.this.panelOO.isImpressionSelected(), true);
} catch (Exception e) {
ExceptionHandler.handle("Impossible de créer le devis", e);
}
 
// incrémentation du numéro auto
if (NumerotationAutoSQLElement.getNextNumero(DevisSQLElement.class).equalsIgnoreCase(this.numeroUniqueDevis.getText().trim())) {
550,7 → 565,6
int val = this.tableNum.getRow(2).getInt("DEVIS_START");
val++;
rowVals.put("DEVIS_START", new Integer(val));
 
try {
rowVals.update(2);
} catch (final SQLException e) {
558,6 → 572,7
}
}
} else {
idDevis = getSelectedID();
ExceptionHandler.handle("Impossible d'ajouter, numéro de devis existant.");
final Object root = SwingUtilities.getRoot(this);
if (root instanceof EditFrame) {
598,10 → 613,17
this.table.createArticle(getSelectedID(), getElement());
 
// generation du document
final DevisXmlSheet dSheet = new DevisXmlSheet(getTable().getRow(getSelectedID()));
dSheet.genere(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected());
 
try {
final DevisXmlSheet sheet = new DevisXmlSheet(getTable().getRow(getSelectedID()));
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(DevisSQLComponent.this.panelOO.isVisualisationSelected(), DevisSQLComponent.this.panelOO.isImpressionSelected(), true);
} catch (Exception e) {
ExceptionHandler.handle("Impossible de créer le devis", e);
}
 
}
 
/**
* Création d'un devis à partir d'un devis existant
*
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/element/DevisSQLElement.java
37,8 → 37,10
 
public class DevisSQLElement extends ComptaSQLConfElement {
 
public static final String TABLENAME = "DEVIS";
 
public DevisSQLElement() {
super("DEVIS", "un devis", "devis");
super(TABLENAME, "un devis", "devis");
}
 
protected List<String> getComboFields() {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/report/DevisXmlSheet.java
13,25 → 13,16
package org.openconcerto.erp.core.sales.quote.report;
 
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
public class DevisXmlSheet extends AbstractSheetXMLWithDate {
 
public class DevisXmlSheet extends AbstractSheetXml {
public static final String TEMPLATE_ID = "Devis";
public static final String TEMPLATE_PROPERTY_NAME = "LocationDevis";
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationDevis", "Devis");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
@Override
public String getReference() {
return this.row.getString("OBJET");
51,19 → 42,16
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("DevisPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("DEVIS");
Calendar cal = Calendar.getInstance();
cal.setTime((Date) row.getObject("DATE"));
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
 
}
 
@Override
public String getDefaultModele() {
return "Devis";
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
public String getFileName() {
 
return getValidFileName("Devis_" + this.row.getString("NUMERO"));
@Override
public String getName() {
return "Devis_" + this.row.getString("NUMERO");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/report/DevisTextSheet.java
115,7 → 115,7
this.askOverwriting = true;
Date d = (Date) this.row.getObject("DATE");
String year = yearFormat.format(d);
init(year, "Devis.odt", "DevisPrinter", DevisXmlSheet.getTuple2Location());
init(year, "Devis.odt", "DevisPrinter");
}
 
protected boolean savePDF() {
122,8 → 122,13
return true;
}
 
@Override
public String getFileName() {
String fileName = "Devis_" + AbstractSheetXml.getValidFileName(this.row.getString("NUMERO"));
String fileName = "Devis_" + this.row.getString("NUMERO");
return fileName;
}
 
public String getTemplateId() {
return "sales.quote.text";
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/action/ListeDesDevisAction.java
21,6 → 21,7
import org.openconcerto.erp.core.sales.quote.element.DevisSQLElement;
import org.openconcerto.erp.core.sales.quote.report.DevisTextSheet;
import org.openconcerto.erp.core.sales.quote.ui.ListeDesDevisPanel;
import org.openconcerto.erp.generationDoc.DocumentLocalStorageManager;
import org.openconcerto.erp.generationDoc.SheetUtils;
import org.jopendocument.link.OOConnexion;
import org.openconcerto.sql.Configuration;
91,7 → 92,8
openItem.setFont(openItem.getFont().deriveFont(Font.BOLD));
menu.add(openItem);
 
List<File> files = SheetUtils.getInstance().getHistorique(s.getFileName(), new File(s.getLocationOO()));
final File outpuDirectory = DocumentLocalStorageManager.getInstance().getDocumentOutputDirectory(s.getTemplateId());
List<File> files = SheetUtils.getHistorique(s.getFileName(), outpuDirectory);
if (files.size() > 0) {
JMenu item = new JMenu("Historique");
int i = 0;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/ui/ListeDesDevisPanel.java
35,11 → 35,14
import org.openconcerto.sql.view.IListener;
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelColumnPath;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ExceptionHandler;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
91,16 → 94,18
// Bouton generer
this.buttonGen = new JButton("Générer le document");
this.add(this.buttonGen, c);
// this.buttonGen.setToolTipText("Générer");
// this.buttonGen.setBorder(null);
this.buttonGen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
final ListeAddPanel selectedPanel = ListeDesDevisPanel.this.map.get(ListeDesDevisPanel.this.tabbedPane.getSelectedIndex());
SQLRow row = selectedPanel.getListe().getSelectedRow();
DevisXmlSheet sheet = new DevisXmlSheet(row);
sheet.genere(true, false);
// genereDoc(row);
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(true, false, true);
} catch (Exception ex) {
ExceptionHandler.handle("Erreur lors de de la génération du document", ex);
}
}
});
 
// Bouton voir le document
111,12 → 116,17
// this.buttonShow.setBorder(null);
this.buttonShow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
final ListeAddPanel selectedPanel = ListeDesDevisPanel.this.map.get(ListeDesDevisPanel.this.tabbedPane.getSelectedIndex());
SQLRow row = selectedPanel.getListe().getSelectedRow();
DevisXmlSheet sheet = new DevisXmlSheet(row);
sheet.showDocument();
// showDoc(row);
sheet.getOrCreateDocumentFile();
sheet.openDocument(false);
} catch (Exception ex) {
ExceptionHandler.handle("Erreur lors de de la génération du document", ex);
}
 
}
});
 
// Bouton Impression
212,7 → 222,8
}
Where wAttente = new Where(this.eltDevis.getTable().getField("ID_ETAT_DEVIS"), "=", idFilter);
lAttente.getReq().setWhere(wAttente);
// one config file per idFilter since they haven't the same number of columns
// one config file per idFilter since they haven't the same number of
// columns
final ListeAddPanel pane = new ListeAddPanel(this.eltDevis, new IListe(lAttente), "idFilter" + idFilter);
 
// Renderer
232,36 → 243,62
}
}
 
pane.getListe().getJTable().addMouseListener(new MouseSheetXmlListeListener(pane.getListe(), DevisXmlSheet.class) {
pane.getListe().addIListeActions(new MouseSheetXmlListeListener(DevisXmlSheet.class) {
@Override
public List<AbstractAction> addToMenu() {
List<AbstractAction> list = new ArrayList<AbstractAction>();
final SQLRow row = pane.getListe().getSelectedRow();
public List<RowAction> addToMenu() {
List<RowAction> list = new ArrayList<RowAction>();
// Transfert vers facture
AbstractAction factureAction = (new AbstractAction("Transfert vers facture") {
PredicateRowAction factureAction = new PredicateRowAction(new AbstractAction("Transfert vers facture") {
public void actionPerformed(ActionEvent e) {
transfertFacture(row);
transfertFacture(IListe.get(e).getSelectedRow());
}
});
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
 
// Voir le document
AbstractAction actionTransfertCmd = new AbstractAction("Transférer en commande") {
PredicateRowAction actionTransfertCmd = new PredicateRowAction(new AbstractAction("Transférer en commande") {
public void actionPerformed(ActionEvent e) {
transfertCommande(row);
transfertCommande(IListe.get(e).getSelectedRow());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
 
// Transfert vers commande
AbstractAction commandeAction = (new AbstractAction("Transfert vers commande client") {
PredicateRowAction commandeAction = new PredicateRowAction(new AbstractAction("Transfert vers commande client") {
public void actionPerformed(ActionEvent e) {
transfertCommandeClient(row);
transfertCommandeClient(IListe.get(e).getSelectedRow());
}
});
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
 
// Marqué accepté
AbstractAction accepteAction = (new AbstractAction("Marquer comme accepté") {
PredicateRowAction accepteAction = new PredicateRowAction(new AbstractAction("Marquer comme accepté") {
public void actionPerformed(ActionEvent e) {
SQLRowValues rowVals = row.createEmptyUpdateRow();
SQLRowValues rowVals = IListe.get(e).getSelectedRow().createEmptyUpdateRow();
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.ACCEPTE);
try {
rowVals.update();
269,22 → 306,34
// TODO Auto-generated catch block
e1.printStackTrace();
}
row.getTable().fireTableModified(row.getID());
IListe.get(e).getSelectedRow().getTable().fireTableModified(IListe.get(e).getSelectedId());
}
});
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.EN_ATTENTE) {
return true;
}
}
return false;
};
};
 
int type = pane.getListe().getSelectedRow().getInt("ID_ETAT_DEVIS");
factureAction.setEnabled(type == EtatDevisSQLElement.ACCEPTE);
commandeAction.setEnabled(type == EtatDevisSQLElement.ACCEPTE);
if (type == EtatDevisSQLElement.EN_ATTENTE) {
list.add(accepteAction);
}
list.add(factureAction);
list.add(commandeAction);
list.add(actionTransfertCmd);
// int type =
// pane.getListe().getSelectedRow().getInt("ID_ETAT_DEVIS");
// factureAction.setEnabled(type ==
// EtatDevisSQLElement.ACCEPTE);
// commandeAction.setEnabled(type ==
// EtatDevisSQLElement.ACCEPTE);
// if (type == EtatDevisSQLElement.EN_ATTENTE) {
// list.add(accepteAction);
// }
// list.add(factureAction);
// list.add(commandeAction);
// list.add(actionTransfertCmd);
return list;
}
});
}.getRowActions());
 
// activation des boutons
pane.getListe().addIListener(new IListener() {
308,8 → 357,8
this.buttonFacture.setEnabled(etat == EtatDevisSQLElement.ACCEPTE);
this.buttonCmd.setEnabled(etat == EtatDevisSQLElement.ACCEPTE);
 
this.buttonPrint.setEnabled(sheet.isFileOOExist());
this.buttonShow.setEnabled(sheet.isFileOOExist());
this.buttonPrint.setEnabled(sheet.getGeneratedFile().exists());
this.buttonShow.setEnabled(sheet.getGeneratedFile().exists());
this.buttonGen.setEnabled(true);
this.buttonClone.setEnabled(true);
 
363,7 → 412,7
SQLRow rowArticleFind = eltArticle.getTable().getRow(idArticle);
SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCmdElt);
SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticleFind));
 
rowValsElt.put("ID_STYLE", sqlRow.getObject("ID_STYLE"));
rowValsElt.put("QTE", sqlRow.getObject("QTE"));
rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * rowValsElt.getInt("QTE"));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/product/component/ReferenceArticleSQLComponent.java
363,6 → 363,7
// Obsolete
c.fill = GridBagConstraints.NONE;
c.weightx = 1;
this.checkObs.setOpaque(false);
panel.add(this.checkObs, c);
 
this.checkObs.setVisible(false);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/Article.java
22,7 → 22,8
int priceInCents;
int idTaxe;
int priceHTInCents;
String code = "empty barcode";
String barCode = "empty barcode";
String code = "";
private static Map<String, Article> codes = new HashMap<String, Article>();
 
public Article(Categorie s1, String string) {
48,7 → 49,7
}
 
public void setBarCode(String bar) {
this.code = bar;
this.barCode = bar;
codes.put(bar, this);
}
 
64,8 → 65,16
return this.name;
}
 
public void setCode(String code) {
this.code = code;
}
 
public String getCode() {
return this.code;
};
 
public String getBarCode() {
return this.barCode;
}
 
public Categorie getCategorie() {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/Ticket.java
107,12 → 107,14
String categorie = element.getAttributeValue("categorie");
String name = element.getValue();
String codebarre = element.getAttributeValue("codebarre");
String codeArt = element.getAttributeValue("code");
Categorie cat = new Categorie(categorie);
Article art = new Article(cat, name);
art.priceInCents = prix_unitaire_cents;
art.setCode(codeArt);
art.setPriceHTInCents(prix_unitaire_cents_ht);
art.setIdTaxe(idTaxe);
art.code = codebarre;
art.barCode = codebarre;
Pair<Article, Integer> line = new Pair<Article, Integer>(art, qte);
t.items.add(line);
 
267,7 → 269,8
e.setAttribute("prixHT", String.valueOf(item.getFirst().getPriceHTInCents()));
e.setAttribute("idTaxe", String.valueOf(item.getFirst().getIdTaxe()));
e.setAttribute("categorie", item.getFirst().getCategorie().getName());
e.setAttribute("codebarre", item.getFirst().getCode());
e.setAttribute("codebarre", item.getFirst().getBarCode());
e.setAttribute("code", item.getFirst().getCode());
e.setText(item.getFirst().getName());
topLevel.addContent(e);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/Caisse.java
41,6 → 41,7
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.utils.DesktopEnvironment;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.Pair;
55,6 → 56,7
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
 
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.jdom.Document;
107,7 → 109,7
return document;
}
 
private static File getConfigFile() {
public static File getConfigFile() {
return getConfigFile(ComptaPropsConfiguration.APP_NAME, new File("."));
}
 
132,8 → 134,12
}
}
 
public static void commitAll(List<Ticket> tickets) {
public static void commitAll(final List<Ticket> tickets) {
// createConnexion();
try {
SQLUtils.executeAtomic(Configuration.getInstance().getSystemRoot().getDataSource(), new SQLUtils.SQLFactory<Object>() {
@Override
public Object create() throws SQLException {
SQLElement elt = Configuration.getInstance().getDirectory().getElement("TICKET_CAISSE");
SQLElement eltFact = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE_ELEMENT");
SQLElement eltEnc = Configuration.getInstance().getDirectory().getElement("ENCAISSER_MONTANT");
204,16 → 210,17
rowValsElt.put("ID_TICKET_CAISSE", rowVals);
}
}
try {
 
SQLRow rowFinal = rowVals.insert();
Thread t = new Thread(new GenerationMvtTicketCaisse(rowFinal));
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException exn) {
// TODO Bloc catch auto-généré
exn.printStackTrace();
}
 
// msie à jour du mouvement
rowFinal = rowFinal.getTable().getRow(rowFinal.getID());
List<SQLRow> rowsEnc = rowFinal.getReferentRows(eltEnc.getTable());
223,8 → 230,8
PrixTTC ttc = new PrixTTC(montant);
totalEnc += montant;
new GenerationReglementVenteNG("Règlement " + sqlRow.getForeignRow("ID_MODE_REGLEMENT").getForeignRow("ID_TYPE_REGLEMENT").getString("NOM") + " Ticket "
+ rowFinal.getString("NUMERO"), getClientCaisse(), ttc, sqlRow.getDate("DATE").getTime(), sqlRow.getForeignRow("ID_MODE_REGLEMENT"), rowFinal,
rowFinal.getForeignRow("ID_MOUVEMENT"), false);
+ rowFinal.getString("NUMERO"), getClientCaisse(), ttc, sqlRow.getDate("DATE").getTime(), sqlRow.getForeignRow("ID_MODE_REGLEMENT"), rowFinal, rowFinal
.getForeignRow("ID_MOUVEMENT"), false);
}
if (totalEnc > total) {
final SQLTable table = Configuration.getInstance().getDirectory().getElement("TYPE_REGLEMENT").getTable();
232,19 → 239,33
if (idComptePceCaisse == table.getUndefinedID()) {
idComptePceCaisse = ComptePCESQLElement.getId(ComptePCESQLElement.getComptePceDefault("VenteEspece"));
}
new GenerationMvtVirement(idComptePceCaisse, getClientCaisse().getInt("ID_COMPTE_PCE"), 0, totalEnc - total,
"Rendu sur règlement " + " Ticket " + rowFinal.getString("NUMERO"), new Date(), JournalSQLElement.CAISSES, " Ticket " + rowFinal.getString("NUMERO")).genereMouvement();
new GenerationMvtVirement(idComptePceCaisse, getClientCaisse().getInt("ID_COMPTE_PCE"), 0, totalEnc - total, "Rendu sur règlement " + " Ticket "
+ rowFinal.getString("NUMERO"), new Date(), JournalSQLElement.CAISSES, " Ticket " + rowFinal.getString("NUMERO")).genereMouvement();
}
 
updateStock(rowFinal.getID());
} catch (SQLException e) {
e.printStackTrace();
 
}
}
}
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
// TODO Raccord de méthode auto-généré
 
JOptionPane.showMessageDialog(null, "Clôture de la caisse terminée.");
}
});
return null;
}
});
} catch (Exception exn) {
// TODO Bloc catch auto-généré
ExceptionHandler.handle("Une erreur est survenue pendant la clôture.", exn);
}
 
}
 
private static SQLRow rowClient = null;
 
private static SQLRow getClientCaisse() throws SQLException {
341,7 → 362,7
 
public static int getID() {
final Document d = getDocument();
return Integer.valueOf(d.getRootElement().getAttributeValue("caisseID", "2"));
return Integer.valueOf(d.getRootElement().getAttributeValue("caisseID", "-1"));
}
 
public static void setID(int caisseId) {
364,7 → 385,7
 
public static int getUserID() {
final Document d = getDocument();
return Integer.valueOf(d.getRootElement().getAttributeValue("userID", "2"));
return Integer.valueOf(d.getRootElement().getAttributeValue("userID", "-1"));
}
 
public static void setUserID(int userId) {
374,7 → 395,7
 
public static int getSocieteID() {
final Document d = getDocument();
return Integer.valueOf(d.getRootElement().getAttributeValue("societeID", "42"));
return Integer.valueOf(d.getRootElement().getAttributeValue("societeID", "-1"));
}
 
public static void setSocieteID(int societeId) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/PaiementPanel.java
31,7 → 31,6
import javax.swing.ImageIcon;
import javax.swing.JPanel;
 
 
public class PaiementPanel extends JPanel implements CaisseListener, MouseListener, BarcodeListener {
private static final int OFFSETY = 50;
private static final int LINE_HEIGHT = 64;
90,13 → 89,14
y += LINE_HEIGHT;
}
drawCalculator(g);
// drawGrid(g);
if (Boolean.getBoolean("sales.pos.debug")) {
drawGrid(g);
}
super.paint(g);
}
 
private void drawGrid(Graphics g) {
g.setColor(Color.RED);
Graphics2D g2 = (Graphics2D) g;
for (int x = 0; x < 320; x += 80) {
for (int y = 28; y < 900; y += 72) {
g.drawLine(x, y, x + 2, y + 2);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/ArticleSelector.java
107,7 → 107,6
this.add(list, c);
list.addListSelectionListener(this);
 
comp.setModel(model);
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CaissePanel.java
41,11 → 41,10
 
public class CaissePanel extends JPanel implements CaisseListener {
private CaisseControler controler;
private CaisseFrame caisseFrame;
 
private StatusBar st;
 
public CaissePanel(final CaisseFrame caisseFrame) {
this.caisseFrame = caisseFrame;
this.setLayout(new GridBagLayout());
this.setBackground(Color.WHITE);
this.setOpaque(isOpaque());
152,6 → 151,7
if (s1 != null) {
Article a = new Article(s1, row.getString("NOM"));
a.setBarCode(row.getString("CODE_BARRE"));
a.setCode(row.getString("CODE"));
a.setIdTaxe(row.getInt("ID_TAXE"));
a.setPriceHTInCents((int) row.getLong("PV_HT"));
a.setPriceInCents((int) row.getLong("PV_TTC"));
224,8 → 224,8
Rectangle2D r;
g.setFont(g.getFont().deriveFont(66f));
final int total = this.controler.getTotal();
euros = this.controler.getEuros(total) + ".";
cents = this.controler.getCents(total);
euros = CaisseControler.getEuros(total) + ".";
cents = CaisseControler.getCents(total);
r = g.getFontMetrics().getStringBounds(euros, g);
x = x - (int) r.getWidth();
g.drawString(euros, x, y);
235,8 → 235,8
y += 40;
x = 300;
final int paye = this.controler.getPaidTotal();
euros = this.controler.getEuros(paye) + ".";
cents = this.controler.getCents(paye);
euros = CaisseControler.getEuros(paye) + ".";
cents = CaisseControler.getCents(paye);
 
g.setFont(g.getFont().deriveFont(18f));
Rectangle2D r2 = g.getFontMetrics().getStringBounds("Payé", g);
266,8 → 266,8
aRendre = -aRendre;
}
 
euros = this.controler.getEuros(aRendre) + ".";
cents = this.controler.getCents(aRendre);
euros = CaisseControler.getEuros(aRendre) + ".";
cents = CaisseControler.getCents(aRendre);
 
g.setFont(g.getFont().deriveFont(18f));
Rectangle2D r3 = g.getFontMetrics().getStringBounds(label, g);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CategorieSelector.java
62,8 → 62,6
this.add(this.list, c);
this.list.getSelectionModel().addListSelectionListener(this);
 
this.comp.setModel(this.model);
 
this.comp.addMouseListener(new MouseAdapter() {
 
@Override
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/StatusBar.java
13,7 → 13,6
package org.openconcerto.erp.core.sales.pos.ui;
 
 
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
24,20 → 23,17
 
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.ListModel;
 
public class StatusBar extends JPanel {
private Image bg;
private Image bg_retour;
private String title = "";
// private Categorie previous;
private ListModel model;
 
private boolean previous;
private int offsetX = 110;
 
StatusBar() {
this("toolbar.png", "toolbar_retour.png");
 
}
 
StatusBar(String fileBg, String fileFg) {
93,8 → 89,4
return new Dimension(320, 44);
}
 
public void setModel(ListModel model) {
this.model = model;
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/ConfigCaissePanel.java
79,7 → 79,22
setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
c.weighty = 0;
// Fichier
c.weightx = 0;
this.add(new JLabel("Fichier de configuration", SwingConstants.RIGHT), c);
c.gridx++;
c.gridwidth = 3;
c.weightx = 1;
JTextField textConfigurationFile = new JTextField("");
if (Caisse.getConfigFile() != null) {
textConfigurationFile.setText(Caisse.getConfigFile().getAbsolutePath());
}
textConfigurationFile.setEditable(false);
this.add(textConfigurationFile, c);
 
// Connexion
c.gridy++;
c.gridx = 0;
final JLabelBold titleConnexion = new JLabelBold("Connexion");
c.gridwidth = 2;
this.add(titleConnexion, c);
275,7 → 290,7
try {
System.out.println("Reloading POS information from: " + config);
SQLServer server = config.createServer("Common");
DBSystemRoot r = server.getSystemRoot("OpenConcerto");
DBSystemRoot r = server.getSystemRoot(config.getSystemRoot());
DBRoot root = r.getRoot("Common");
// Sociétés
SQLSelect sel = new SQLSelect(root.getBase());
287,18 → 302,19
if (societes.size() > 0) {
final String name = societes.get(0).getString("DATABASE_NAME");
server = config.createServer(name);
r = server.getSystemRoot("OpenConcerto");
r = server.getSystemRoot(config.getSystemRoot());
root = r.getRoot(name);
// Caisses
sel = new SQLSelect(root.getBase());
sel.addSelectStar(root.getTable("CAISSE"));
final List<SQLRow> caisses = SQLRowListRSH.execute(sel);
 
server.destroy();
 
// Stock l'id de la caisse pour que la reslectionne soit correcte
final int idCaisseToSelect = this.caisseId;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ConfigCaissePanel.this.caisseId = idCaisseToSelect;
if (caisses.isEmpty()) {
JOptionPane.showMessageDialog(ConfigCaissePanel.this, "Pas de caisses définies dans la société " + name);
}
314,7 → 330,7
}
for (int i = 0; i < stop; i++) {
final SQLRow r = (SQLRow) model.getElementAt(i);
if (r.getID() == ConfigCaissePanel.this.caisseId) {
if (r.getID() == idCaisseToSelect) {
ConfigCaissePanel.this.comboCaisse.setSelectedItem(r);
break;
}
375,11 → 391,10
JOptionPane.showMessageDialog(ConfigCaissePanel.this, "Impossible de se connecter au serveur");
return;
}
String result = "Erreur de connexion. \n";
try {
 
final SQLServer server = config.createServer("Common");
final DBSystemRoot r = server.getSystemRoot("OpenConcerto");
final DBSystemRoot r = server.getSystemRoot(config.getSystemRoot());
final DBRoot root = r.getRoot("Common");
// Sociétés
SQLSelect sel = new SQLSelect(root.getBase());
402,30 → 417,49
ConfigCaissePanel.this.comboSociete.setEnabled(true);
ConfigCaissePanel.this.comboUtilisateur.setEnabled(true);
 
// Societe
ComboBoxModel model = ConfigCaissePanel.this.comboSociete.getModel();
int stop = model.getSize();
boolean societeFound = false;
for (int i = 0; i < stop; i++) {
final SQLRow r = (SQLRow) model.getElementAt(i);
if (r.getID() == ConfigCaissePanel.this.societeId) {
ConfigCaissePanel.this.comboSociete.setSelectedItem(r);
ConfigCaissePanel.this.societeId = r.getID();
societeFound = true;
break;
}
}
 
if (!societeFound && stop > 0) {
ConfigCaissePanel.this.comboSociete.setSelectedItem(model.getElementAt(0));
ConfigCaissePanel.this.societeId = ((SQLRow) model.getElementAt(0)).getID();
}
// Utilisateur
model = ConfigCaissePanel.this.comboUtilisateur.getModel();
stop = model.getSize();
boolean utilisateurFound = false;
for (int i = 0; i < stop; i++) {
final SQLRow r = (SQLRow) model.getElementAt(i);
if (r.getID() == ConfigCaissePanel.this.userId) {
ConfigCaissePanel.this.comboUtilisateur.setSelectedItem(r);
ConfigCaissePanel.this.userId = r.getID();
utilisateurFound = true;
break;
}
}
 
if (!utilisateurFound && stop > 0) {
ConfigCaissePanel.this.comboUtilisateur.setSelectedItem(model.getElementAt(0));
ConfigCaissePanel.this.userId = ((SQLRow) model.getElementAt(0)).getID();
}
 
reloadCaisses();
}
 
});
 
} catch (final Exception e) {
result += e.getMessage();
e.printStackTrace();
}
 
437,6 → 471,12
});
}
 
public void dumpConfiguration() {
System.out.println("Societe: id:" + this.societeId);
System.out.println("Caisse: id:" + this.caisseId);
System.out.println("Utilisateur: id:" + this.userId);
}
 
public void saveConfiguration() {
Caisse.setPrinterType(this.comboType.getSelectedItem().toString());
if (this.comboType.getSelectedIndex() == 0) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/TicketPanel.java
59,18 → 59,15
@Override
public void addListDataListener(final ListDataListener l) {
TicketPanel.this.listeners.add(l);
 
}
 
@Override
public Object getElementAt(final int index) {
 
return controler.getItems().get(index);
}
 
@Override
public int getSize() {
// TODO Auto-generated method stub
return controler.getItems().size();
}
 
77,7 → 74,6
@Override
public void removeListDataListener(final ListDataListener l) {
TicketPanel.this.listeners.remove(l);
 
}
 
};
133,13 → 129,11
 
@Override
public Dimension getMinimumSize() {
// TODO Auto-generated method stub
return new Dimension(480, 707);
}
 
@Override
public Dimension getPreferredSize() {
// TODO Auto-generated method stub
return new Dimension(480, 707);
}
 
169,7 → 163,6
return;
}
} catch (final Exception e) {
// TODO: handle exception
e.printStackTrace();
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/TouchScrollPane.java
32,8 → 32,6
public class TouchScrollPane extends JScrollPane implements MouseListener, MouseMotionListener {
 
private JComponent child;
int dy = 0;
int olddy = 0;
private int mousePressedY;
private double viewY;
private int lastLocationOnscreen;
42,7 → 40,6
super(l);
this.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
this.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
if (!(l instanceof Scrollable)) {
throw new IllegalArgumentException("Argument is not implementing Scrollable");
}
49,7 → 46,6
this.child = l;
child.addMouseListener(this);
child.addMouseMotionListener(this);
 
}
 
@Override
59,13 → 55,6
super.paint(g);
}
 
/*
* @Override public void paint(Graphics g, int x, int y, int width, int height) { int oldOffsetY
* = g.getOffsetY(); g.setColor(Color.RED); g.fillRect(0, 0, this.getWidth(), this.getHeight());
* g.setOffset(g.getOffsetX(), oldOffsetY + dy); child.paint(g, x, y, width, height);
* g.setOffset(g.getOffsetX(), oldOffsetY); }
*/
 
/**
* @param args
*/
83,92 → 72,54
f.setContentPane(t);
f.setSize(200, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.show();
f.setVisible(true);
}
 
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("TouchScrollPane.mouseClicked()");
}
 
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("TouchScrollPane.mouseEntered()");
}
 
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("TouchScrollPane.mouseExited()");
}
 
@Override
public void mousePressed(MouseEvent e) {
this.mousePressedY = e.getLocationOnScreen().y;
System.out.println("TouchScrollPane.mousePressed():" + e.getY());
 
viewY = this.getViewport().getViewPosition().getY();
e.consume();
 
}
 
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("TouchScrollPane.mouseReleased()");
}
 
@Override
public void mouseDragged(MouseEvent e) {
e.consume();
if (e.getLocationOnScreen().y == lastLocationOnscreen) {
return;
}
 
lastLocationOnscreen = e.getLocationOnScreen().y;
System.out.println("TouchScrollPane.mouseDragged()");
// final int newDy = olddy + (e.getY() - this.mousePressedY);
//
// dy = newDy;
// if (dy >= 0) {
// dy = 0;
// }
// if (dy <= -(child.getHeight() - this.getHeight())) {
// dy = -(child.getHeight() - this.getHeight());
// }
//
// this.getViewport().setViewPosition(new Point(0,dy));
int xDiff = 0;
int yDiff = mousePressedY;
System.out.println("DY:" + yDiff);
JViewport jv = this.getViewport();
Point p = jv.getViewPosition();
int newX = 0;// p.x - (e.getX() - xDiff);
final JViewport jv = this.getViewport();
int newX = 0;
int deplacementY = e.getLocationOnScreen().y - yDiff;
int newY = (int) viewY - deplacementY;
System.out.println("View Position:" + p.y);
System.out.println("Decallage depuis mouse pressed:" + deplacementY + "(" + e.getLocationOnScreen().y + " - " + yDiff + ")");
int maxX = child.getWidth() - jv.getWidth();
int maxY = child.getHeight() - jv.getHeight();
/*
* if (newX < 0) newX = 0; if (newX > maxX) newX = maxX;
*/
if (newY < 0)
newY = 0;/*
* if (newY > maxY) newY = maxY;
*/
 
if (newY < 0) {
newY = 0;
}
jv.setViewPosition(new Point(newX, newY));
System.out.println(newY);
e.consume();
}
 
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("TouchScrollPane.mouseMoved()");
}
 
@Override
public void mouseClicked(MouseEvent e) {
}
 
@Override
public void mouseReleased(MouseEvent e) {
}
 
@Override
public void mouseEntered(MouseEvent e) {
}
 
@Override
public void mouseExited(MouseEvent e) {
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/report/BonLivraisonXmlSheet.java
13,25 → 13,16
package org.openconcerto.erp.core.sales.shipment.report;
 
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
public class BonLivraisonXmlSheet extends AbstractSheetXMLWithDate {
 
public class BonLivraisonXmlSheet extends AbstractSheetXml {
public static final String TEMPLATE_ID = "BonLivraison";
public static final String TEMPLATE_PROPERTY_NAME = "LocationBon";
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationBon", "Bon de livraison");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
@Override
public String getReference() {
return this.row.getString("NOM");
51,18 → 42,17
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("BON_DE_LIVRAISON");
Calendar cal = Calendar.getInstance();
cal.setTime((Date) row.getObject("DATE"));
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
 
}
 
@Override
public String getDefaultModele() {
return "BonLivraison";
public String getName() {
return "BonLivraison_" + this.row.getString("NUMERO");
}
 
public String getFileName() {
return getValidFileName("BonLivraison_" + this.row.getString("NUMERO"));
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/action/ListeDesBonsDeLivraisonAction.java
22,6 → 22,10
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.view.IListFrame;
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
import java.awt.GridBagConstraints;
68,20 → 72,21
table.getColumnModel().getColumn(i).setCellRenderer(rend);
}
 
table.addMouseListener(new MouseSheetXmlListeListener(edit1.getPanel().getListe(), BonLivraisonXmlSheet.class) {
edit1.getPanel().getListe().addIListeActions(new MouseSheetXmlListeListener(BonLivraisonXmlSheet.class) {
@Override
public List<AbstractAction> addToMenu() {
AbstractAction actionTransfertFacture = new AbstractAction("Transfert en facture") {
public List<RowAction> addToMenu() {
PredicateRowAction actionTransfertFacture = new PredicateRowAction(new AbstractAction("Transfert en facture") {
public void actionPerformed(ActionEvent ev) {
transfertFactureClient(edit1.getPanel().getListe().getSelectedRow());
transfertFactureClient(IListe.get(ev).getSelectedRow());
}
};
List<AbstractAction> l = new ArrayList<AbstractAction>();
}, false);
actionTransfertFacture.setPredicate(IListeEvent.getSingleSelectionPredicate());
List<RowAction> l = new ArrayList<RowAction>();
l.add(actionTransfertFacture);
 
return l;
}
});
}.getRowActions());
 
return edit1;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/component/BonDeLivraisonSQLComponent.java
36,6 → 36,7
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.TitledSeparator;
104,6 → 105,17
 
final GridBagConstraints c = new DefaultGridBagConstraints();
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = new JPanel();
this.setAdditionalFieldsPanel(new FormLayouter(addP, 1));
this.add(addP, c);
 
c.gridy++;
c.gridwidth = 1;
 
// Numero
JLabel labelNum = new JLabel(getLabelFor("NUMERO"));
labelNum.setHorizontalAlignment(SwingConstants.RIGHT);
423,7 → 435,8
 
// generation du document
BonLivraisonXmlSheet bSheet = new BonLivraisonXmlSheet(getTable().getRow(idBon));
bSheet.genere(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected());
bSheet.createDocumentAsynchronous();
bSheet.showPrintAndExportAsynchronous(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected(), true);
 
// incrémentation du numéro auto
if (NumerotationAutoSQLElement.getNextNumero(BonDeLivraisonSQLElement.class).equalsIgnoreCase(this.textNumeroUnique.getText().trim())) {
480,7 → 493,9
 
// generation du document
BonLivraisonXmlSheet bSheet = new BonLivraisonXmlSheet(getTable().getRow(getSelectedID()));
bSheet.genere(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected());
bSheet.createDocumentAsynchronous();
bSheet.showPrintAndExportAsynchronous(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected(), true);
 
}
 
private void updateTotal() {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/credit/action/ListeDesAvoirsClientsAction.java
66,7 → 66,7
c.anchor = GridBagConstraints.CENTER;
frame.getPanel().add(datePanel, c);
 
frame.getPanel().getListe().getJTable().addMouseListener(new MouseSheetXmlListeListener(frame.getPanel().getListe(), AvoirClientXmlSheet.class));
frame.getPanel().getListe().addIListeActions(new MouseSheetXmlListeListener(AvoirClientXmlSheet.class).getRowActions());
 
frame.getPanel().getListe().setSQLEditable(false);
return frame;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/credit/component/AvoirClientSQLComponent.java
47,6 → 47,7
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.component.ITextArea;
import org.openconcerto.utils.ExceptionHandler;
205,6 → 206,17
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = new JPanel();
this.setAdditionalFieldsPanel(new FormLayouter(addP, 1));
this.add(addP, c);
 
c.gridy++;
c.gridwidth = 1;
 
this.textNom = new JTextField();
this.date = new JDate(true);
this.date.addValueListener(new PropertyChangeListener() {
668,8 → 680,7
gen.genereMouvement();
 
// generation du document
AvoirClientXmlSheet bSheet = new AvoirClientXmlSheet(row);
bSheet.genere(this.checkVisu.isSelected(), this.checkImpr.isSelected());
createAvoirClient(row);
 
} else {
ExceptionHandler.handle("Impossible de modifier, numéro d'avoir existant.");
682,6 → 693,18
return id;
}
 
private void createAvoirClient(final SQLRow row) {
 
final AvoirClientXmlSheet bSheet = new AvoirClientXmlSheet(row);
try {
bSheet.createDocumentAsynchronous();
bSheet.showPrintAndExportAsynchronous(checkVisu.isSelected(), checkImpr.isSelected(), true);
} catch (Exception e) {
ExceptionHandler.handle("Impossible de créer l'avoir", e);
}
 
}
 
@Override
public void select(SQLRowAccessor r) {
if (r != null) {
691,10 → 714,8
this.comboClient.rmValueListener(changeClientListener);
 
if (r != null) {
System.err.println("Selection Avoir");
this.table.insertFrom("ID_AVOIR_CLIENT", r.getID());
 
System.err.println(r);
// Les contacts sont filtrés en fonction du client (ID_AFFAIRE.ID_CLIENT), donc si
// l'ID_CONTACT est changé avant ID_AFFAIRE le contact ne sera pas présent dans la combo
// => charge en deux fois les valeurs
708,7 → 729,6
vals.setID(rVals.getID());
super.select(vals);
rVals.remove("ID_CLIENT");
System.err.println("Select Other vlues");
super.select(rVals);
} else {
super.select(r);
770,8 → 790,7
GenerationMvtAvoirClient gen = new GenerationMvtAvoirClient(getSelectedID(), idMvt);
gen.genereMouvement();
 
AvoirClientXmlSheet bSheet = new AvoirClientXmlSheet(row);
bSheet.genere(this.checkVisu.isSelected(), this.checkImpr.isSelected());
createAvoirClient(row);
} else {
ExceptionHandler.handle("Impossible de modifier, numéro d'avoir existant.");
Object root = SwingUtilities.getRoot(this);
790,18 → 809,6
 
loadItem(this.table, facture, idFacture, factureElt);
 
// if (idFacture > 1) {
// SQLTable factureTable = facture.getTable();
// SQLRow row = factureTable.getRow(idFacture);
//
// int idClient = row.getInt("ID_CLIENT");
// this.selectClient.setValue(String.valueOf(idClient));
//
// Long l = (Long) row.getObject("T_HT");
// this.montantPanel.getMontantHT().setValue(String.valueOf(GestionDevise.currencyToString(l)));
//
// this.textNom.setValue("Avoir annulant Facture " + row.getString("NUMERO"));
// }
}
 
/**
854,7 → 861,7
} catch (SQLException e) {
e.printStackTrace();
}
// }
 
}
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/element/CommandeClientSQLElement.java
172,7 → 172,7
SQLRow rowArticleFind = eltArticle.getTable().getRow(idArticle);
SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCmdElt);
SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticleFind));
 
rowValsElt.put("ID_STYLE", sqlRow.getObject("ID_STYLE"));
rowValsElt.put("QTE", sqlRow.getObject("QTE"));
rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * rowValsElt.getInt("QTE"));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/report/CommandeClientXmlSheet.java
13,23 → 13,22
package org.openconcerto.erp.core.sales.order.report;
 
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.utils.Tuple2;
 
import java.io.File;
import java.util.Calendar;
import java.util.Date;
public class CommandeClientXmlSheet extends AbstractSheetXMLWithDate {
 
public class CommandeClientXmlSheet extends AbstractSheetXml {
public static final String TEMPLATE_ID = "CommandeClient";
public static final String TEMPLATE_PROPERTY_NAME = "LocationCmdCli";
 
private static final Tuple2<String, String> tuple = Tuple2.create("LocationCmdCli", "Commande client");
// FIXME Prefs printer location
public CommandeClientXmlSheet(SQLRow row) {
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("cmdCliPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("COMMANDE_CLIENT");
 
public static Tuple2<String, String> getTuple2Location() {
return tuple;
}
 
@Override
47,24 → 46,13
}
}
 
// FIXME Prefs printer location
public CommandeClientXmlSheet(SQLRow row) {
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("cmdCliPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("COMMANDE_CLIENT");
 
Calendar cal = Calendar.getInstance();
cal.setTime((Date) row.getObject("DATE"));
this.locationOO = SheetXml.getLocationForTuple(tuple, false) + File.separator + cal.get(Calendar.YEAR);
this.locationPDF = SheetXml.getLocationForTuple(tuple, true) + File.separator + cal.get(Calendar.YEAR);
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
@Override
public String getDefaultModele() {
return "CommandeClient";
public String getName() {
return "CommandeClient_" + this.row.getString("NUMERO");
}
 
public String getFileName() {
return getValidFileName("CommandeClient_" + this.row.getString("NUMERO"));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/component/CommandeClientSQLComponent.java
37,6 → 37,7
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.TitledSeparator;
import org.openconcerto.ui.component.ITextArea;
81,6 → 82,17
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = new JPanel();
this.setAdditionalFieldsPanel(new FormLayouter(addP, 1));
this.add(addP, c);
 
c.gridy++;
c.gridwidth = 1;
 
this.comboDevis = new ElementComboBox();
 
// Numero du commande
373,8 → 385,7
}
 
public int insert(SQLRow order) {
 
int idCommande = getSelectedID();
final int idCommande;
// on verifie qu'un devis du meme numero n'a pas été inséré entre temps
if (this.numeroUniqueCommande.checkValidation()) {
 
383,10 → 394,15
 
// Création des articles
this.table.createArticle(idCommande, this.getElement());
// generation du document
 
// generation du document
try {
CommandeClientXmlSheet sheet = new CommandeClientXmlSheet(getTable().getRow(idCommande));
sheet.genere(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected());
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(CommandeClientSQLComponent.this.panelOO.isVisualisationSelected(), CommandeClientSQLComponent.this.panelOO.isImpressionSelected(), true);
} catch (Exception e) {
ExceptionHandler.handle("Impossible de créer la commande", e);
}
 
// incrémentation du numéro auto
if (NumerotationAutoSQLElement.getNextNumero(CommandeClientSQLElement.class).equalsIgnoreCase(this.numeroUniqueCommande.getText().trim())) {
402,6 → 418,7
}
}
} else {
idCommande = getSelectedID();
ExceptionHandler.handle("Impossible d'ajouter, numéro de commande client existant.");
Object root = SwingUtilities.getRoot(this);
if (root instanceof EditFrame) {
443,10 → 460,17
this.table.createArticle(getSelectedID(), this.getElement());
 
// generation du document
CommandeClientXmlSheet dSheet = new CommandeClientXmlSheet(getTable().getRow(getSelectedID()));
dSheet.genere(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected());
 
try {
CommandeClientXmlSheet sheet = new CommandeClientXmlSheet(getTable().getRow(getSelectedID()));
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(CommandeClientSQLComponent.this.panelOO.isVisualisationSelected(), CommandeClientSQLComponent.this.panelOO.isImpressionSelected(), true);
} catch (Exception e) {
ExceptionHandler.handle("Impossible de créer la commande", e);
}
 
}
 
public void setDefaults() {
this.resetValue();
this.numeroUniqueCommande.setText(NumerotationAutoSQLElement.getNextNumero(CommandeClientSQLElement.class));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/element/NumerotationAutoSQLElement.java
39,7 → 39,9
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.model.Where;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.StringUtils;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.text.SimpleDocumentListener;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
50,10 → 52,13
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import javax.swing.Icon;
import javax.swing.JLabel;
94,318 → 99,67
public SQLComponent createComponent() {
return new BaseSQLComponent(this) {
 
private JTextField textDevisFormat = new JTextField(16);
private JTextField textDevisStart = new JTextField(6);
private JTextField textFactStart = new JTextField(6);
private JTextField textFactFormat = new JTextField(16);
private JTextField textBonFormat = new JTextField(16);
private JTextField textBonStart = new JTextField(6);
private JTextField textBonRFormat = new JTextField(16);
private JTextField textBonRStart = new JTextField(6);
private JTextField textSalarieFormat = new JTextField(16);
private JTextField textSalarieStart = new JTextField(6);
private JTextField textPropositionFormat = new JTextField(16);
private JTextField textPropositionStart = new JTextField(6);
private JTextField textRelanceFormat = new JTextField(16);
private JTextField textRelanceStart = new JTextField(6);
private JTextField textCmdCliFormat = new JTextField(16);
private JTextField textCmdCliStart = new JTextField(6);
private JTextField textCmdFormat = new JTextField(16);
private JTextField textCmdStart = new JTextField(6);
private JTextField textAffaireFormat = new JTextField(16);
private JTextField textAffaireStart = new JTextField(6);
private JTextField textAvoirFormat = new JTextField(16);
private JTextField textAvoirStart = new JTextField(6);
private JTextField textCourrierFormat = new JTextField(16);
private JTextField textCourrierStart = new JTextField(6);
 
private Icon iconWarning = ImageIconWarning.getInstance();
 
private JLabel labelNumDevis, labelNumFact, labelNumBon, labelNumSalarie;
private JLabel labelNumRelance, labelNumProposition, labelNumCmdCli;
private JLabel labelNumCmd, labelNumBonR, labelNumAffaire, labelNumAvoir, labelNumCourrier;
// private JLabel labelNextCodeLettrage;
private DocumentListener listenText = new DocumentListener() {
 
public void insertUpdate(DocumentEvent e) {
updateLabels();
}
 
public void removeUpdate(DocumentEvent e) {
updateLabels();
}
 
public void changedUpdate(DocumentEvent e) {
updateLabels();
}
};
 
public void addViews() {
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
 
// Avoir
JLabel labelAvoirFormat = new JLabel("Avoir " + getLabelFor("AVOIR_FORMAT"));
this.add(labelAvoirFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textAvoirFormat, c);
Set<Class<? extends SQLElement>> s = map.keySet();
 
JLabel labelAvoirStart = new JLabel(getLabelFor("AVOIR_START"));
c.gridx++;
c.weightx = 0;
this.add(labelAvoirStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textAvoirStart, c);
final ArrayList<Class<? extends SQLElement>> list = new ArrayList<Class<? extends SQLElement>>(s);
Collections.sort(list, new Comparator<Class<? extends SQLElement>>() {
public int compare(Class<? extends SQLElement> o1, Class<? extends SQLElement> o2) {
return o1.toString().compareTo(o2.toString());
};
});
 
this.labelNumAvoir = new JLabel();
c.gridx++;
c.weightx = 0;
this.add(this.labelNumAvoir, c);
 
// Devis
JLabel labelDevisFormat = new JLabel("Devis " + getLabelFor("DEVIS_FORMAT"));
for (Class<? extends SQLElement> class1 : list) {
c.gridy++;
c.gridx = 0;
this.add(labelDevisFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textDevisFormat, c);
 
JLabel labelDevisStart = new JLabel(getLabelFor("DEVIS_START"));
c.gridx++;
c.weightx = 0;
this.add(labelDevisStart, c);
String prefix = map.get(class1);
SQLElement elt = Configuration.getInstance().getDirectory().getElement(class1);
// Avoir
JLabel labelAvoirFormat = new JLabel(StringUtils.firstUp(elt.getPluralName()) + " " + getLabelFor(prefix + FORMAT));
this.add(labelAvoirFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textDevisStart, c);
final JTextField fieldFormat = new JTextField();
this.add(fieldFormat, c);
 
this.labelNumDevis = new JLabel();
final JLabel labelAvoirStart = new JLabel(getLabelFor(prefix + START));
c.gridx++;
c.weightx = 0;
this.add(this.labelNumDevis, c);
 
// Commande Client
JLabel labelCmdCliFormat = new JLabel("Commande client " + getLabelFor("COMMANDE_CLIENT_FORMAT"));
c.gridy++;
c.gridx = 0;
this.add(labelCmdCliFormat, c);
this.add(labelAvoirStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textCmdCliFormat, c);
final JTextField fieldStart = new JTextField();
this.add(fieldStart, c);
 
JLabel labelCmdCliStart = new JLabel(getLabelFor("COMMANDE_CLIENT_START"));
final JLabel labelResult = new JLabel();
c.gridx++;
c.weightx = 0;
this.add(labelCmdCliStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textCmdCliStart, c);
this.add(labelResult, c);
 
this.labelNumCmdCli = new JLabel();
c.gridx++;
c.weightx = 0;
this.add(this.labelNumCmdCli, c);
// Affichage dynamique du résultat
SimpleDocumentListener listener = new SimpleDocumentListener() {
 
// Commande
JLabel labelCmdFormat = new JLabel("Commande " + getLabelFor("COMMANDE_FORMAT"));
c.gridy++;
c.gridx = 0;
this.add(labelCmdFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textCmdFormat, c);
@Override
public void update(DocumentEvent e) {
updateLabel(fieldStart, fieldFormat, labelResult);
 
JLabel labelCmdStart = new JLabel(getLabelFor("COMMANDE_START"));
c.gridx++;
c.weightx = 0;
this.add(labelCmdStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textCmdStart, c);
}
};
 
this.labelNumCmd = new JLabel();
c.gridx++;
c.weightx = 0;
this.add(this.labelNumCmd, c);
fieldFormat.getDocument().addDocumentListener(listener);
fieldStart.getDocument().addDocumentListener(listener);
 
// Bon
JLabel labelBonFormat = new JLabel("Bon de livraison" + getLabelFor("BON_L_FORMAT"));
c.gridy++;
c.gridx = 0;
this.add(labelBonFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textBonFormat, c);
this.addRequiredSQLObject(fieldFormat, prefix + FORMAT);
this.addRequiredSQLObject(fieldStart, prefix + START);
 
JLabel labelBonStart = new JLabel(getLabelFor("BON_L_START"));
c.gridx++;
c.weightx = 0;
this.add(labelBonStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textBonStart, c);
}
 
this.labelNumBon = new JLabel();
c.gridx++;
c.weightx = 0;
this.add(this.labelNumBon, c);
 
// Bon Reception
JLabel labelBonRFormat = new JLabel("Bon de réception" + getLabelFor("BON_R_FORMAT"));
c.gridy++;
c.gridx = 0;
this.add(labelBonRFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textBonRFormat, c);
 
JLabel labelBonRStart = new JLabel(getLabelFor("BON_R_START"));
c.gridx++;
c.weightx = 0;
this.add(labelBonRStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textBonRStart, c);
 
this.labelNumBonR = new JLabel();
c.gridx++;
c.weightx = 0;
this.add(this.labelNumBonR, c);
 
// Facture
JLabel labelFactFormat = new JLabel("Facture " + getLabelFor("FACT_FORMAT"));
c.gridy++;
c.gridx = 0;
this.add(labelFactFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textFactFormat, c);
 
JLabel labelFactStart = new JLabel(getLabelFor("FACT_START"));
c.gridx++;
c.weightx = 0;
this.add(labelFactStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textFactStart, c);
 
this.labelNumFact = new JLabel();
c.gridx++;
c.weightx = 0;
this.add(this.labelNumFact, c);
 
// Salarie
JLabel labelSalarieFormat = new JLabel("Salarié " + getLabelFor("SALARIE_FORMAT"));
c.gridy++;
c.gridx = 0;
this.add(labelSalarieFormat, c);
c.gridx++;
c.weightx = 1;
this.add(this.textSalarieFormat, c);
 
JLabel labelSalarieStart = new JLabel(getLabelFor("SALARIE_START"));
c.gridx++;
c.weightx = 0;
this.add(labelSalarieStart, c);
c.gridx++;
c.weightx = 1;
this.add(this.textSalarieStart, c);
 
this.labelNumSalarie = new JLabel();