OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 82 → Rev 83

/trunk/OpenConcerto/src/org/openconcerto/utils/GestionDevise.java
29,6 → 29,19
public static long parseLongCurrency(String numStr) {
 
numStr = numStr.trim();
int indexPoint = numStr.indexOf('.');
int indexVirgule = numStr.indexOf(',');
if (indexPoint >= 0 && indexVirgule >= 0) {
if (indexPoint > indexVirgule) {
// 1,000.50 -> 1 000.50
numStr = numStr.replace(',', ' ');
} else {
// 1.000,50 -> 1 000.50
numStr = numStr.replace('.', ' ');
numStr = numStr.replace(',', '.');
}
}
numStr = numStr.replace(',', '.');
StringBuffer b = new StringBuffer(numStr.length());
 
boolean negative = false;
45,7 → 58,6
case '-':
negative = true;
break;
case ',':
case '.':
if (decpl == -1) {
decpl = 0;
82,9 → 94,7
decpl++;
}
 
// if (numStr.length() != b.length()) {
numStr = b.toString();
// }
 
// Si numStr "-"
if (numStr.trim().length() == 0) {
231,10 → 241,4
return s;
}
 
public static void main(String[] args) {
System.err.println(GestionDevise.round(-5155));
System.err.println(GestionDevise.round(-5145));
System.err.println(GestionDevise.round(5155));
System.err.println(GestionDevise.round(5145));
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/CollectionMap2.java
13,6 → 13,8
package org.openconcerto.utils;
 
import org.openconcerto.utils.cc.AbstractMapDecorator;
 
import java.util.AbstractCollection;
import java.util.Arrays;
import java.util.Collection;
34,7 → 36,7
* @param <C> the type of mapped collections
* @param <V> the type of elements of the collections
*/
public abstract class CollectionMap2<K, C extends Collection<V>, V> extends HashMap<K, C> {
public abstract class CollectionMap2<K, C extends Collection<V>, V> extends AbstractMapDecorator<K, C> implements Cloneable, CollectionMap2Itf<K, C, V> {
 
static final int DEFAULT_INITIAL_CAPACITY = 16;
 
62,7 → 64,8
NULL_MEANS_ALL
}
 
static private final Mode DEFAULT_MODE = Mode.NULL_FORBIDDEN;
static protected final Mode DEFAULT_MODE = Mode.NULL_FORBIDDEN;
static private final Boolean DEFAULT_emptyCollSameAsNoColl = null;
 
private final boolean emptyCollSameAsNoColl;
private final Mode mode;
73,27 → 76,71
}
 
public CollectionMap2(final Mode mode) {
this(mode, null);
this(mode, DEFAULT_emptyCollSameAsNoColl);
}
 
public CollectionMap2(final Map<K, C> delegate, final Mode mode) {
this(delegate, mode, DEFAULT_emptyCollSameAsNoColl);
}
 
public CollectionMap2(final Mode mode, final Boolean emptyCollSameAsNoColl) {
this(DEFAULT_INITIAL_CAPACITY, mode, emptyCollSameAsNoColl);
}
 
public CollectionMap2(int initialCapacity) {
this(initialCapacity, DEFAULT_MODE, null);
public CollectionMap2(final int initialCapacity) {
this(initialCapacity, DEFAULT_MODE, DEFAULT_emptyCollSameAsNoColl);
}
 
public CollectionMap2(int initialCapacity, final Mode mode, final Boolean emptyCollSameAsNoColl) {
super(initialCapacity);
public CollectionMap2(final int initialCapacity, final Mode mode, final Boolean emptyCollSameAsNoColl) {
this(new HashMap<K, C>(initialCapacity), mode, emptyCollSameAsNoColl);
}
 
/**
* Create a new instance with the passed delegate. The delegate is *not* cleared, this allows to
* decorate an existing Map but it also means that the existing collections might not be the
* exact same type as those returned by {@link #createCollection(Collection)}.
*
* @param delegate the map to use, it must not be modified afterwards.
* @param mode how to handle null values.
* @param emptyCollSameAsNoColl for {@link #getCollection(Object)} : whether the lack of an
* entry is the same as an entry with an empty collection, can be <code>null</code>.
*/
public CollectionMap2(final Map<K, C> delegate, final Mode mode, final Boolean emptyCollSameAsNoColl) {
super(delegate);
if (mode == null)
throw new NullPointerException("Null mode");
this.mode = mode;
this.emptyCollSameAsNoColl = emptyCollSameAsNoColl == null ? mode == Mode.NULL_MEANS_ALL : emptyCollSameAsNoColl;
checkMode();
}
 
public CollectionMap2(Map<? extends K, ? extends Collection<? extends V>> m) {
private final void checkMode() {
assert this.mode != null : "Called too early";
if (this.mode == Mode.NULL_FORBIDDEN && this.containsValue(null))
throw new IllegalArgumentException("Null collection");
}
 
// ** copy constructors
 
public CollectionMap2(final CollectionMap2<K, C, ? extends V> m) {
this(CopyUtils.copy(m.getDelegate()), m);
}
 
public CollectionMap2(final Map<? extends K, ? extends Collection<? extends V>> m) {
this(new HashMap<K, C>(m.size()), m);
}
 
/**
* Create a new instance with the passed delegate and filling it with the passed map.
*
* @param delegate the map to use, it will be cleared and must not be modified afterwards.
* @param m the values to put in this, if it's an instance of {@link CollectionMap2} the
* {@link #getMode() mode} and {@link #isEmptyCollSameAsNoColl()} will be copied as well.
*/
public CollectionMap2(final Map<K, C> delegate, final Map<? extends K, ? extends Collection<? extends V>> m) {
// don't use super(Map) since it doesn't copy the collections
// also its type is more restrictive
super(m.size());
super(delegate);
if (m instanceof CollectionMap2) {
final CollectionMap2<?, ?, ?> collM = (CollectionMap2<?, ?, ?>) m;
this.mode = collM.getMode();
102,30 → 149,49
this.mode = DEFAULT_MODE;
this.emptyCollSameAsNoColl = this.mode == Mode.NULL_MEANS_ALL;
}
// delegate might not contain the same instances of collections (i.e. LinkedList vs
// ArrayList)
this.clear();
this.putAllCollections(m);
}
 
@Override
public final Mode getMode() {
return this.mode;
}
 
@Override
public final boolean isEmptyCollSameAsNoColl() {
return this.emptyCollSameAsNoColl;
}
 
public final C getNonNullIfMissing(Object key) {
public final C getNonNullIfMissing(final Object key) {
return this.get(key, false, true);
}
 
public final C getNonNull(K key) {
@Override
public final C getNonNull(final K key) {
return this.get(key, false, false);
}
 
private final C getNonNullColl(C res) {
private final C getNonNullColl(final C res) {
return res == null ? this.createCollection(Collections.<V> emptySet()) : res;
}
 
public final C get(Object key, final boolean nullIfMissing, final boolean nullIfPresent) {
/**
* Get the collection mapped to the passed key. Note : <code>get(key, true, true)</code> is
* equivalent to <code>get(key)</code>.
*
* @param key the key whose associated value is to be returned.
* @param nullIfMissing only relevant if the key isn't contained : if <code>true</code>
* <code>null</code> will be returned, otherwise an empty collection.
* @param nullIfPresent only relevant if the key is mapped to <code>null</code> : if
* <code>true</code> <code>null</code> will be returned, otherwise an empty collection.
* @return the non {@code null} value to which the specified key is mapped, otherwise
* {@code null} or empty collection depending on the other parameters.
*/
@Override
public final C get(final Object key, final boolean nullIfMissing, final boolean nullIfPresent) {
if (nullIfMissing == nullIfPresent) {
final C res = super.get(key);
if (res != null || nullIfMissing && nullIfPresent) {
149,7 → 215,8
}
}
 
public final C getCollection(Object key) {
@Override
public final C getCollection(final Object key) {
return this.get(key, !this.isEmptyCollSameAsNoColl(), true);
}
 
167,6 → 234,7
*
* @return a view all values in all entries, <code>null</code> collections are ignored.
*/
@Override
public Collection<V> allValues() {
if (this.allValues == null)
this.allValues = new AllValues();
180,17 → 248,11
}
 
@Override
public boolean isEmpty() {
return !iterator().hasNext();
}
 
@Override
public int size() {
int compt = 0;
final Iterator<V> it = iterator();
while (it.hasNext()) {
it.next();
compt++;
for (final C c : values()) {
if (c != null)
compt += c.size();
}
return compt;
}
244,6 → 306,7
@Override
public Set<Map.Entry<K, C>> entrySet() {
if (getMode() == Mode.NULL_FORBIDDEN) {
// prevent null insertion
// MAYBE cache
return new EntrySet(super.entrySet());
} else {
255,7 → 318,7
 
private final Set<Map.Entry<K, C>> delegate;
 
public EntrySet(Set<java.util.Map.Entry<K, C>> delegate) {
public EntrySet(final Set<java.util.Map.Entry<K, C>> delegate) {
super();
this.delegate = delegate;
}
266,12 → 329,12
}
 
@Override
public boolean contains(Object o) {
public boolean contains(final Object o) {
return this.delegate.contains(o);
}
 
@Override
public boolean remove(Object o) {
public boolean remove(final Object o) {
return this.delegate.remove(o);
}
 
306,7 → 369,7
}
 
@Override
public C setValue(C value) {
public C setValue(final C value) {
if (value == null)
throw new NullPointerException("Putting null collection for " + toStr(getKey()));
return delegate.setValue(value);
322,7 → 385,7
}
 
@Override
public boolean equals(Object o) {
public boolean equals(final Object o) {
return this.delegate.equals(o);
}
 
332,24 → 395,29
}
 
@Override
public boolean removeAll(Collection<?> c) {
public boolean removeAll(final Collection<?> c) {
return this.delegate.removeAll(c);
}
}
 
@Override
public final C put(K key, C value) {
public final C put(final K key, final C value) {
return this.putCollection(key, value);
}
 
// copy passed collection
public final C putCollection(K key, Collection<? extends V> value) {
@Override
public final C putCollection(final K key, final Collection<? extends V> value) {
if (value == null && this.getMode() == Mode.NULL_FORBIDDEN)
throw new NullPointerException("Putting null collection for " + toStr(key));
return super.put(key, value == null ? null : createCollection(value));
}
 
public void putAllCollections(Map<? extends K, ? extends Collection<? extends V>> m) {
public final C putCollection(final K key, final V... value) {
return this.putCollection(key, Arrays.asList(value));
}
 
public void putAllCollections(final Map<? extends K, ? extends Collection<? extends V>> m) {
for (final Map.Entry<? extends K, ? extends Collection<? extends V>> e : m.entrySet()) {
this.putCollection(e.getKey(), e.getValue());
}
357,53 → 425,65
 
// ** add/remove collection
 
public final void add(K k, V v) {
this.addAll(k, Collections.singleton(v));
@Override
public final boolean add(final K k, final V v) {
return this.addAll(k, Collections.singleton(v));
}
 
public final void addAll(K k, V... v) {
this.addAll(k, Arrays.asList(v));
public final boolean addAll(final K k, final V... v) {
return this.addAll(k, Arrays.asList(v));
}
 
public final void addAll(K k, Collection<? extends V> v) {
@Override
public final boolean addAll(final K k, final Collection<? extends V> v) {
final boolean nullIsAll = getMode() == Mode.NULL_MEANS_ALL;
if (v == null && !nullIsAll)
throw new NullPointerException("Adding null collection for " + toStr(k));
if (v == null || !this.containsKey(k)) {
final boolean containsKey = this.containsKey(k);
if (v == null) {
return this.putCollection(k, v) != null;
} else if (!containsKey) {
this.putCollection(k, v);
return true;
} else {
final C currentColl = this.get(k);
if (nullIsAll && currentColl == null) {
// ignore since we can't add something to everything
return false;
} else {
// will throw if currentCol is null
currentColl.addAll(v);
return currentColl.addAll(v);
}
}
}
 
public final void merge(Map<? extends K, ? extends Collection<? extends V>> mm) {
@Override
public final void merge(final Map<? extends K, ? extends Collection<? extends V>> mm) {
for (final Map.Entry<? extends K, ? extends Collection<? extends V>> e : mm.entrySet()) {
this.addAll(e.getKey(), e.getValue());
}
}
 
public final void mergeScalarMap(Map<? extends K, ? extends V> scalarMap) {
@Override
public final void mergeScalarMap(final Map<? extends K, ? extends V> scalarMap) {
for (final Map.Entry<? extends K, ? extends V> e : scalarMap.entrySet()) {
this.add(e.getKey(), e.getValue());
}
}
 
public final void remove(K k, V v) {
this.removeAll(k, Collections.singleton(v));
@Override
public final boolean remove(final K k, final V v) {
return this.removeAll(k, Collections.singleton(v));
}
 
public final void removeAll(K k, Collection<? extends V> v) {
this.removeAll(k, v, null);
@Override
public final boolean removeAll(final K k, final Collection<? extends V> v) {
return this.removeAll(k, v, null);
}
 
private final void removeAll(K k, Collection<? extends V> v, final Iterator<Map.Entry<K, C>> iter) {
private final boolean removeAll(final K k, final Collection<? extends V> v, final Iterator<Map.Entry<K, C>> iter) {
boolean removeK = false;
boolean modified = false;
if (getMode() == Mode.NULL_MEANS_ALL) {
if (v == null) {
removeK = true;
411,7 → 491,7
final C currentColl = this.get(k);
if (currentColl == null)
throw new IllegalStateException("Cannot remove from all for " + toStr(k));
currentColl.removeAll(v);
modified = currentColl.removeAll(v);
if (currentColl.isEmpty())
removeK = true;
}
421,22 → 501,31
// since containsKey() and coll == null
assert getMode() == Mode.NULL_ALLOWED;
removeK = true;
// since we just tested containsKey()
modified = true;
} else {
if (v == null)
throw new NullPointerException("Removing null collection for " + toStr(k));
currentColl.removeAll(v);
modified = currentColl.removeAll(v);
if (currentColl.isEmpty())
removeK = true;
}
}
if (removeK)
if (iter == null)
if (removeK) {
if (iter == null) {
modified |= this.containsKey(k);
this.remove(k);
else
} else {
iter.remove();
modified = true;
}
}
return modified;
}
 
public final void removeAll(Map<? extends K, ? extends Collection<? extends V>> mm) {
@Override
public final boolean removeAll(final Map<? extends K, ? extends Collection<? extends V>> mm) {
boolean modified = false;
// iterate on this to allow mm.removeAll(mm)
final Iterator<Map.Entry<K, C>> iter = this.entrySet().iterator();
while (iter.hasNext()) {
443,21 → 532,25
final Map.Entry<K, C> e = iter.next();
final K key = e.getKey();
if (mm.containsKey(key))
this.removeAll(key, mm.get(key), iter);
modified |= this.removeAll(key, mm.get(key), iter);
}
return modified;
}
 
public final void removeAllScalar(Map<? extends K, ? extends V> m) {
@Override
public final boolean removeAllScalar(final Map<? extends K, ? extends V> m) {
boolean modified = false;
// incompatible types, allowing removal without ConcurrentModificationException
assert m != this;
for (final Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
this.remove(e.getKey(), e.getValue());
modified |= this.remove(e.getKey(), e.getValue());
}
return modified;
}
 
// ** remove empty/null collections
 
public final C removeIfEmpty(K k) {
public final C removeIfEmpty(final K k) {
final C v = this.get(k);
if (v != null && v.isEmpty())
return this.remove(k);
465,15 → 558,17
return null;
}
 
public final void removeIfNull(K k) {
public final void removeIfNull(final K k) {
if (this.get(k) == null)
this.remove(k);
}
 
@Override
public final Set<K> removeAllEmptyCollections() {
return this.removeAll(true);
}
 
@Override
public final Set<K> removeAllNullCollections() {
return this.removeAll(false);
}
496,6 → 591,13
 
@Override
public int hashCode() {
if (this.mode == Mode.NULL_MEANS_ALL)
return this.hashCodeExact();
else
return super.hashCode();
}
 
public int hashCodeExact() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + (this.emptyCollSameAsNoColl ? 1231 : 1237);
503,27 → 605,58
return result;
}
 
/**
* Compares the specified object with this map for equality. Except for
* {@link Mode#NULL_MEANS_ALL}, returns <tt>true</tt> if the given object is also a map and the
* two maps represent the same mappings (as required by {@link Map}).
* <code>NULL_MEANS_ALL</code> maps are tested using {@link #equalsExact(Object)}, meaning they
* don't conform to the Map interface.
*
* @param obj object to be compared for equality with this map
* @return <tt>true</tt> if the specified object is equal to this map
* @see #equalsExact(Object)
*/
@Override
public boolean equals(Object obj) {
public final boolean equals(final Object obj) {
return this.equals(obj, false);
}
 
/**
* Compares the specified object with this map for complete equality. This method not only
* checks for equality of values (as required by {@link Map}) but also the class and attributes.
*
* @param obj object to be compared for equality with this map
* @return <tt>true</tt> if the specified object is exactly equal to this map.
*/
public final boolean equalsExact(final Object obj) {
return this.equals(obj, true);
}
 
private final boolean equals(final Object obj, final boolean forceExact) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
assert obj != null;
final CollectionMap2<?, ?, ?> other = obj instanceof CollectionMap2 ? (CollectionMap2<?, ?, ?>) obj : null;
if (forceExact || this.mode == Mode.NULL_MEANS_ALL || (other != null && other.mode == Mode.NULL_MEANS_ALL)) {
if (getClass() != obj.getClass())
return false;
// no need to test createCollection(), since values are tested by super.equals()
final CollectionMap2<?, ?, ?> other = (CollectionMap2<?, ?, ?>) obj;
return this.emptyCollSameAsNoColl == other.emptyCollSameAsNoColl && this.mode == other.mode;
return this.emptyCollSameAsNoColl == other.emptyCollSameAsNoColl && this.mode == other.mode && this.getDelegate().getClass() == other.getDelegate().getClass();
} else {
return true;
}
}
 
@Override
public CollectionMap2<K, C, V> clone() {
public CollectionMap2<K, C, V> clone() throws CloneNotSupportedException {
@SuppressWarnings("unchecked")
final CollectionMap2<K, C, V> result = (CollectionMap2<K, C, V>) super.clone();
// allValues has a reference to this
result.allValues = null;
// clone each collection value
for (Map.Entry<K, C> entry : result.entrySet()) {
for (final Map.Entry<K, C> entry : result.entrySet()) {
final C coll = entry.getValue();
entry.setValue(createCollection(coll));
}
/trunk/OpenConcerto/src/org/openconcerto/utils/StringUtils.java
16,11 → 16,14
*/
package org.openconcerto.utils;
 
import java.awt.FontMetrics;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
243,6 → 246,25
return l;
}
 
public static final List<String> fastSplitTrimmed(final String string, final char sep) {
final List<String> l = new ArrayList<String>();
final int length = string.length();
final char[] cars = string.toCharArray();
int rfirst = 0;
 
for (int i = 0; i < length; i++) {
if (cars[i] == sep) {
l.add(new String(cars, rfirst, i - rfirst).trim());
rfirst = i + 1;
}
}
 
if (rfirst < length) {
l.add(new String(cars, rfirst, length - rfirst).trim());
}
return l;
}
 
/**
* Split une string s tous les nbCharMaxLine
*
297,6 → 319,20
return result.toString();
}
 
static public int firstIndexOf(final String s, final char[] chars) {
return firstIndexOf(s, 0, chars);
}
 
static public int firstIndexOf(final String s, final int offset, final char[] chars) {
int res = -1;
for (final char c : chars) {
final int index = s.indexOf(c, offset);
if (index >= 0 && (res == -1 || index < res))
res = index;
}
return res;
}
 
static private final Pattern quotePatrn = Pattern.compile("\"", Pattern.LITERAL);
static private final Pattern slashPatrn = Pattern.compile("(\\\\+)");
 
311,6 → 347,59
return '"' + s + '"';
}
 
/**
* Unquote a double quoted string.
*
* @param s the string to unquote, e.g. "foo\\bar".
* @return the unquoted form, e.g. foo\bar.
* @throws IllegalArgumentException if the string is not quoted, or if there's some extra
* content at the end.
*/
static public String unDoubleQuote(String s) {
final Tuple2<String, Integer> res = unDoubleQuote(s, 0);
if (res.get1().intValue() != s.length())
throw new IllegalArgumentException("Extra content at the end : " + s.substring(res.get1()));
return res.get0();
}
 
/**
* Unquote part of a double quoted string.
*
* @param s the string to unquote, e.g. pre"foo\\bar"post.
* @param offset the start index of the quotes, e.g. 3.
* @return the unquoted form and the index after the end quote, e.g. foo\bar and 13.
* @throws IllegalArgumentException if the string is not quoted.
*/
static public Tuple2<String, Integer> unDoubleQuote(String s, int offset) {
if (s.charAt(offset) != '"')
throw new IllegalArgumentException("Expected quote but got : " + s.charAt(offset));
final int l = s.length();
if (offset + 1 < l && s.charAt(offset + 1) == '"')
return Tuple2.create("", offset + 2);
 
offset++;
final char[] chars = new char[] { '"', '\\' };
final StringBuilder sb = new StringBuilder(512);
boolean foundEnd = false;
while (offset < l && !foundEnd) {
final int index = firstIndexOf(s, offset, chars);
if (index < 0)
throw new IllegalArgumentException("End quote not found after " + offset);
sb.append(s.substring(offset, index));
if (s.charAt(index) == '"') {
offset = index + 1;
foundEnd = true;
} else {
assert s.charAt(index) == '\\';
sb.append(s.charAt(index + 1));
offset = index + 2;
}
}
if (!foundEnd)
throw new IllegalArgumentException("End quote not found after " + offset);
return Tuple2.create(sb.toString(), offset);
}
 
public static final class Escaper {
 
// eg '
463,4 → 552,160
}
return builder.toString();
}
 
public static BigDecimal getBigDecimalFromUserText(String text) {
text = text.trim();
if (text.isEmpty() || text.equals("-")) {
return BigDecimal.ZERO;
}
text = removeNonDecimalChars(text);
BigDecimal result = null;
try {
result = new BigDecimal(text);
} catch (Exception e) {
Log.get().info(text + " is not a valid decimal");
}
return result;
}
 
/**
* Returns an array of strings, one for each line in the string after it has been wrapped to fit
* lines of <var>maxWidth</var>. Lines end with any of cr, lf, or cr lf. A line ending at the
* end of the string will not output a further, empty string.
* <p>
* This code assumes <var>str</var> is not <code>null</code>.
*
* @param str the string to split
* @param fm needed for string width calculations
* @param maxWidth the max line width, in points
* @return a non-empty list of strings
*/
public static List<String> wrap(String str, FontMetrics fm, int maxWidth) {
List<String> lines = splitIntoLines(str);
if (lines.size() == 0)
return lines;
 
List<String> strings = new ArrayList<String>();
for (Iterator<String> iter = lines.iterator(); iter.hasNext();) {
wrapLineInto(iter.next(), strings, fm, maxWidth);
}
return strings;
}
 
/**
* Given a line of text and font metrics information, wrap the line and add the new line(s) to
* <var>list</var>.
*
* @param line a line of text
* @param list an output list of strings
* @param fm font metrics
* @param maxWidth maximum width of the line(s)
*/
public static void wrapLineInto(String line, List<String> list, FontMetrics fm, int maxWidth) {
int len = line.length();
int width;
while (len > 0 && (width = fm.stringWidth(line)) > maxWidth) {
// Guess where to split the line. Look for the next space before
// or after the guess.
int guess = len * maxWidth / width;
String before = line.substring(0, guess).trim();
 
width = fm.stringWidth(before);
int pos;
if (width > maxWidth) // Too long
pos = findBreakBefore(line, guess);
else { // Too short or possibly just right
pos = findBreakAfter(line, guess);
if (pos != -1) { // Make sure this doesn't make us too long
before = line.substring(0, pos).trim();
if (fm.stringWidth(before) > maxWidth)
pos = findBreakBefore(line, guess);
}
}
if (pos == -1)
pos = guess; // Split in the middle of the word
 
list.add(line.substring(0, pos).trim());
line = line.substring(pos).trim();
len = line.length();
}
if (len > 0) {
list.add(line);
}
}
 
/**
* Returns the index of the first whitespace character or '-' in <var>line</var> that is at or
* before <var>start</var>. Returns -1 if no such character is found.
*
* @param line a string
* @param start where to star looking
*/
public static int findBreakBefore(String line, int start) {
for (int i = start; i >= 0; --i) {
char c = line.charAt(i);
if (Character.isWhitespace(c) || c == '-')
return i;
}
return -1;
}
 
/**
* Returns the index of the first whitespace character or '-' in <var>line</var> that is at or
* after <var>start</var>. Returns -1 if no such character is found.
*
* @param line a string
* @param start where to star looking
*/
public static int findBreakAfter(String line, int start) {
int len = line.length();
for (int i = start; i < len; ++i) {
char c = line.charAt(i);
if (Character.isWhitespace(c) || c == '-')
return i;
}
return -1;
}
 
/**
* Returns an array of strings, one for each line in the string. Lines end with any of cr, lf,
* or cr lf. A line ending at the end of the string will not output a further, empty string.
* <p>
* This code assumes <var>str</var> is not <code>null</code>.
*
* @param str the string to split
* @return a non-empty list of strings
*/
public static List<String> splitIntoLines(String str) {
List<String> strings = new ArrayList<String>();
 
int len = str.length();
if (len == 0) {
strings.add("");
return strings;
}
 
int lineStart = 0;
 
for (int i = 0; i < len; ++i) {
char c = str.charAt(i);
if (c == '\r') {
int newlineLength = 1;
if ((i + 1) < len && str.charAt(i + 1) == '\n')
newlineLength = 2;
strings.add(str.substring(lineStart, i));
lineStart = i + newlineLength;
if (newlineLength == 2) // skip \n next time through loop
++i;
} else if (c == '\n') {
strings.add(str.substring(lineStart, i));
lineStart = i + 1;
}
}
if (lineStart < len)
strings.add(str.substring(lineStart));
 
return strings;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/sync/SyncClient.java
49,8 → 49,6
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
 
import sun.misc.HexDumpEncoder;
 
public class SyncClient {
private long byteSent;
private long byteReceived;
/trunk/OpenConcerto/src/org/openconcerto/utils/ExceptionHandler.java
16,7 → 16,8
*/
package org.openconcerto.utils;
 
import static java.lang.System.getProperty;
import org.openconcerto.utils.SystemInfo.Info;
import org.openconcerto.utils.cc.IFactory;
import org.openconcerto.utils.io.PercentEncoder;
 
import java.awt.Component;
45,6 → 46,7
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.logging.Level;
76,11 → 78,22
private static final Pattern NL_PATTERN = Pattern.compile("\r?\n");
private static final String ILM_CONTACT = "http://www.ilm-informatique.fr/contact";
private static String ForumURL = null;
private static IFactory<String> SOFTWARE_INFOS = null;
 
public static void setForumURL(String url) {
ForumURL = url;
}
 
public synchronized static void setSoftwareInformations(final IFactory<String> f) {
SOFTWARE_INFOS = f;
}
 
public synchronized static String computeSoftwareInformations() {
if (SOFTWARE_INFOS == null)
return "";
return SOFTWARE_INFOS.createChecked();
}
 
static private void copyToClipboard(final String s) {
final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
final StringSelection data = new StringSelection(s);
301,10 → 314,12
name = productInfo.getName();
version = productInfo.getProperty(ProductInfo.VERSION, version);
}
final String java = getProperty("java.runtime.version") != null ? getProperty("java.runtime.version") : getProperty("java.version");
final String os = getProperty("os.name") + " " + getProperty("os.version") + " (" + getProperty("os.arch") + ")";
 
final Map<Info, String> systemInfos = SystemInfo.get(false);
final String os = systemInfos.remove(Info.OS);
final String java = systemInfos.toString();
final String encodedData = "java=" + PercentEncoder.encode(java, cs) + "&os=" + PercentEncoder.encode(os, cs) + "&software=" + PercentEncoder.encode(name + version, cs)
+ "&stack=" + PercentEncoder.encode(textArea.getText(), cs);
+ "&stack=" + PercentEncoder.encode(computeSoftwareInformations() + "\n\n" + textArea.getText(), cs);
final String request = "http://bugreport.ilm-informatique.fr:5000/bugreport";
final URL url = new URL(request);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
413,8 → 428,13
al.actionPerformed(null);
}
});
try {
f.setVisible(true);
} catch (Exception e) {
// Catch to avoid infinite loop
e.printStackTrace();
}
}
 
private String getTrace() {
return ExceptionUtils.getStackTrace(this);
/trunk/OpenConcerto/src/org/openconcerto/utils/ListAbstractMap.java
New file
0,0 → 1,51
/*
* 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.util.Collection;
import java.util.List;
import java.util.Map;
 
public abstract class ListAbstractMap<K, L extends List<V>, V> extends CollectionMap2<K, L, V> {
 
public ListAbstractMap() {
super();
}
 
public ListAbstractMap(Map<K, L> delegate, Mode mode) {
super(delegate, mode);
}
 
public ListAbstractMap(int initialCapacity) {
super(initialCapacity);
}
 
public ListAbstractMap(int initialCapacity, Mode mode, Boolean emptyCollSameAsNoColl) {
super(initialCapacity, mode, emptyCollSameAsNoColl);
}
 
// ** copy constructors
 
public ListAbstractMap(CollectionMap2<K, L, ? extends V> m) {
super(m);
}
 
public ListAbstractMap(Map<? extends K, ? extends Collection<? extends V>> m) {
super(m);
}
 
public ListAbstractMap(Map<K, L> delegate, Map<? extends K, ? extends Collection<? extends V>> m) {
super(delegate, m);
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/i18n/TranslationManager.java
171,10 → 171,13
Log.get().warning("TranslationManager has no resources to load (" + this.getLocale() + ")");
}
for (Class<?> c : this.classes) {
loadTranslation(this.getLocale(), c);
boolean loaded = loadTranslation(this.getLocale(), c);
if (!loaded) {
Log.get().warning("TranslationManager was unable to load translation " + c.getCanonicalName() + " for locale " + this.getLocale());
}
}
}
}
 
// return all existing (e.g fr_CA only specify differences with fr)
private List<InputStream> findStream(final Locale locale, final Class<?> c, final boolean rootLast) {
195,7 → 198,8
return res;
}
 
private void loadTranslation(final Locale l, Class<?> c) {
private boolean loadTranslation(final Locale l, Class<?> c) {
boolean translationLoaded = false;
// we want more specific translations to replace general ones, i.e. root Locale first
for (final InputStream input : findStream(l, c, false)) {
// create new instances to check if there's no duplicates in each resource
205,7 → 209,9
this.menuTranslation.putAll(menuTranslation);
this.itemTranslation.putAll(itemTranslation);
this.actionTranslation.putAll(actionTranslation);
translationLoaded = true;
}
return translationLoaded;
}
 
static private void loadTranslation(final InputStream input, final Map<String, String> menuTranslation, final Map<String, String> itemTranslation, final Map<String, String> actionTranslation) {
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/IClosure.java
13,8 → 13,9
package org.openconcerto.utils.cc;
 
public interface IClosure<E> {
public interface IClosure<E> extends IExnClosure<E, RuntimeException> {
 
@Override
public abstract void executeChecked(E input);
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/ExnClosure.java
21,7 → 21,7
* @param <E> input type
* @param <X> exception type
*/
public abstract class ExnClosure<E, X extends Exception> extends ExnTransformer<E, Object, X> {
public abstract class ExnClosure<E, X extends Exception> extends ExnTransformer<E, Object, X> implements IExnClosure<E, X> {
 
public final void execute(Object input) {
this.transform(input);
28,8 → 28,7
}
 
/**
* Execute this closure, making sure that an exception of type <code>exnClass</code> is
* thrown.
* Execute this closure, making sure that an exception of type <code>exnClass</code> is thrown.
*
* @param <Y> type of exception to throw.
* @param input the input of the closure.
47,5 → 46,6
return null;
}
 
@Override
public abstract void executeChecked(E input) throws X;
}
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/IExnClosure.java
New file
0,0 → 1,20
/*
* 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.cc;
 
public interface IExnClosure<E, X extends Exception> {
 
public abstract void executeChecked(E input) throws X;
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/AbstractMapDecorator.java
New file
0,0 → 1,127
/*
* 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.cc;
 
import org.openconcerto.utils.CopyUtils;
 
import java.util.Collection;
import java.util.Map;
import java.util.Set;
 
public abstract class AbstractMapDecorator<K, V> implements Map<K, V>, Cloneable {
 
// not final because of clone()
private Map<K, V> delegate;
 
public AbstractMapDecorator(final Map<K, V> delegate) {
super();
this.delegate = delegate;
}
 
protected final Map<K, V> getDelegate() {
return this.delegate;
}
 
@Override
public int size() {
return this.delegate.size();
}
 
@Override
public boolean isEmpty() {
return this.delegate.isEmpty();
}
 
@Override
public boolean containsKey(final Object key) {
return this.delegate.containsKey(key);
}
 
@Override
public boolean containsValue(final Object value) {
return this.delegate.containsValue(value);
}
 
@Override
public V get(final Object key) {
return this.delegate.get(key);
}
 
@Override
public V put(final K key, final V value) {
return this.delegate.put(key, value);
}
 
@Override
public V remove(final Object key) {
return this.delegate.remove(key);
}
 
@Override
public void putAll(final Map<? extends K, ? extends V> m) {
this.delegate.putAll(m);
}
 
@Override
public void clear() {
this.delegate.clear();
}
 
@Override
public Set<K> keySet() {
return this.delegate.keySet();
}
 
@Override
public Collection<V> values() {
return this.delegate.values();
}
 
@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
return this.delegate.entrySet();
}
 
@Override
public boolean equals(final Object o) {
return this.delegate.equals(o);
}
 
@Override
public int hashCode() {
return this.delegate.hashCode();
}
 
@Override
public String toString() {
return this.getClass().getSimpleName() + " " + this.delegate.toString();
}
 
@Override
protected Object clone() throws CloneNotSupportedException {
try {
final Map<K, V> delegate = CopyUtils.copy(this.delegate);
@SuppressWarnings("unchecked")
final AbstractMapDecorator<K, V> res = (AbstractMapDecorator<K, V>) super.clone();
res.delegate = delegate;
return res;
} catch (CloneNotSupportedException e) {
throw e;
} catch (Exception e) {
final CloneNotSupportedException exn = new CloneNotSupportedException();
exn.initCause(e);
throw exn;
}
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/SleepingQueue.java
20,10 → 20,12
import java.beans.PropertyChangeSupport;
import java.util.Collection;
import java.util.Deque;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;
 
/**
* A queue that can be put to sleep. Submitted runnables are converted to FutureTask, that can later
90,7 → 92,7
 
private void add(FutureTask<?> t) {
// no need to synchronize, if die() is called after our test, t won't be executed anyway
if (this.isDead())
if (this.dieCalled())
throw new IllegalStateException("Already dead, cannot exec " + t);
 
this.tasksQueue.put(t);
118,6 → 120,16
}
 
/**
* An exception was thrown by a task. This implementation merely
* {@link Exception#printStackTrace()}.
*
* @param exn the exception thrown.
*/
protected void exceptionThrown(final ExecutionException exn) {
exn.printStackTrace();
}
 
/**
* Cancel all queued tasks and the current task.
*/
protected final void cancel() {
171,7 → 183,7
}
 
private void setBeingRun(final FutureTask<?> beingRun) {
final Future old;
final Future<?> old;
synchronized (this) {
old = this.beingRun;
this.beingRun = beingRun;
187,29 → 199,140
return this.tasksQueue.isSleeping();
}
 
public void setSleeping(boolean sleeping) {
if (this.tasksQueue.setSleeping(sleeping)) {
public boolean setSleeping(boolean sleeping) {
final boolean res = this.tasksQueue.setSleeping(sleeping);
if (res) {
this.support.firePropertyChange("sleeping", null, this.isSleeping());
}
return res;
}
 
/**
* Stops this queue. Once this method returns, it is guaranteed that no other task will be taken
* from the queue to be started, and that this thread will die.
* from the queue to be started, and that this queue will die. But the already executing task
* will complete unless it checks for interrupt.
*
* @return the future killing.
*/
public final void die() {
this.tasksQueue.die();
this.dying();
public final Future<?> die() {
return this.die(true, null, null);
}
 
/**
* Stops this queue. Once the returned future completes successfully then no task is executing (
* {@link #isDead()} will happen sometimes later, the time for the thread to terminate). If the
* returned future throws an exception because of the passed runnables or of {@link #willDie()}
* or {@link #dying()}, one can check with {@link #dieCalled()} to see if the queue is dying.
*
* @param force <code>true</code> if this is guaranteed to die (even if <code>willDie</code> or
* {@link #willDie()} throw an exception).
* @param willDie the last actions to take before killing this queue.
* @param dying the last actions to take before this queue is dead.
* @return the future killing, which will return <code>dying</code> result.
* @see #dieCalled()
*/
public final <V> Future<V> die(final boolean force, final Runnable willDie, final Callable<V> dying) {
// reset sleeping to original value if die not effective
final AtomicBoolean resetSleeping = new AtomicBoolean(false);
final FutureTask<V> res = new FutureTask<V>(new Callable<V>() {
@Override
public V call() throws Exception {
Exception willDieExn = null;
try {
willDie();
if (willDie != null) {
willDie.run();
// handle Future like runnable, i.e. check right away for exception
if (willDie instanceof Future) {
final Future<?> f = (Future<?>) willDie;
assert f.isDone() : "Ran but not done: " + f;
try {
f.get();
} catch (ExecutionException e) {
throw (Exception) e.getCause();
}
}
}
} catch (Exception e) {
if (!force)
throw e;
else
willDieExn = e;
}
try {
// don't interrupt ourselves
SleepingQueue.this.tasksQueue.die(false);
assert SleepingQueue.this.tasksQueue.isDying();
// since there's already been an exception, throw it as soon as possible
// also dying() might itself throw an exception for the same reason or we now
// have 2 exceptions to throw
if (willDieExn != null)
throw willDieExn;
dying();
final V res;
if (dying != null)
res = dying.call();
else
res = null;
 
return res;
} finally {
// if die is effective, this won't have any consequences
if (resetSleeping.get())
SleepingQueue.this.tasksQueue.setSleeping(true);
}
}
});
// die as soon as possible not after all currently queued tasks
this.tasksQueue.itemsDo(new IClosure<Deque<FutureTask<?>>>() {
@Override
public void executeChecked(Deque<FutureTask<?>> input) {
// since we cancel the current task, we might as well remove all of them since they
// might depend on the cancelled one
input.clear();
input.addFirst(res);
// die as soon as possible, even if there's a long task already running
final FutureTask<?> beingRun = getBeingRun();
// since we hold the lock on items
assert beingRun != res : "beingRun: " + beingRun + " ; res: " + res;
if (beingRun != null)
beingRun.cancel(true);
}
});
// force execution of our task
resetSleeping.set(this.setSleeping(false));
return res;
}
 
protected void willDie() {
// nothing by default
}
 
protected void dying() {
// nothing by default
}
 
/**
* Whether this queue is dying, ie if die() has been called.
* Whether this will die. If this method returns <code>true</code>, it is guaranteed that no
* other task will be taken from the queue to be started, and that this queue will die. But the
* already executing task will complete unless it checks for interrupt. Note: this method
* doesn't return <code>true</code> right after {@link #die()} as the method is asynchronous and
* if {@link #willDie()} fails it may not die at all ; as explained in its comment you may use
* its returned future to wait for the killing.
*
* @return <code>true</code> if this queue will not execute any more tasks.
* @return <code>true</code> if this queue will not execute any more tasks (but it may finish
* one last task).
* @see #isDead()
*/
public final boolean dieCalled() {
return this.tasksQueue.dieCalled();
}
 
/**
* Whether this queue is dead, i.e. if die() has been called and all tasks have completed.
*
* @return <code>true</code> if this queue will not execute any more tasks and isn't executing
* any.
* @see #die()
*/
public final boolean isDead() {
275,10 → 398,10
} catch (CancellationException e) {
// don't care
} catch (InterruptedException e) {
// f was interrupted : eg we're dying or f was canceled
// f was interrupted : e.g. we're dying or f was cancelled
} catch (ExecutionException e) {
// f.run() raised an exn
e.printStackTrace();
// f.run() raised an exception
exceptionThrown(e);
}
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/Value.java
27,8 → 27,13
static private final Value NONE = new Value(false) {
@Override
public Object getValue() {
throw new IllegalStateException();
throw new IllegalStateException(this.toString());
}
 
@Override
public String toString() {
return "No Value";
}
};
 
/**
54,6 → 59,11
public V getValue() {
return this.val;
}
 
@Override
public String toString() {
return "Value <" + this.getValue() + '>';
}
};
 
/**
/trunk/OpenConcerto/src/org/openconcerto/utils/TinyMap.java
New file
0,0 → 1,199
/*
* 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.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
public class TinyMap<K, V> implements Map<K, V> {
private final ArrayList<K> keys;
private final ArrayList<V> values;
 
public TinyMap() {
this(10);
}
 
public TinyMap(int initialCapacity) {
keys = new ArrayList<K>(initialCapacity);
values = new ArrayList<V>(initialCapacity);
}
 
@Override
public int size() {
return keys.size();
}
 
@Override
public boolean isEmpty() {
return keys.isEmpty();
}
 
@Override
public boolean containsKey(Object key) {
return keys.contains(key);
}
 
@Override
public boolean containsValue(Object value) {
return values.contains(value);
}
 
@Override
public V get(Object key) {
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
if (this.keys.get(i).equals(key)) {
return this.values.get(i);
}
}
return null;
}
 
@Override
public V put(K key, V value) {
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
if (this.keys.get(i).equals(key)) {
final V old = this.values.get(i);
this.values.set(i, value);
return old;
}
}
this.keys.add(key);
this.values.add(value);
return null;
}
 
@Override
public V remove(Object key) {
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
if (this.keys.get(i).equals(key)) {
this.keys.remove(i);
return this.values.remove(i);
}
}
return null;
}
 
@Override
public void putAll(Map<? extends K, ? extends V> m) {
final Set<? extends K> keySet = m.keySet();
for (Iterator<? extends K> iterator = keySet.iterator(); iterator.hasNext();) {
K key = (K) iterator.next();
put(key, m.get(key));
}
}
 
@Override
public void clear() {
this.keys.clear();
this.values.clear();
}
 
// Views
 
@Override
public Set<K> keySet() {
return new HashSet<K>(this.keys) {
@Override
public boolean remove(Object o) {
TinyMap.this.remove(o);
return super.remove(o);
}
 
@Override
public void clear() {
clear();
super.clear();
}
};
}
 
@Override
public Collection<V> values() {
 
return new ArrayList<V>(this.values()) {
@Override
public V remove(int index) {
keys.remove(index);
values.remove(index);
return super.remove(index);
}
 
@Override
public boolean remove(Object o) {
int index = values.indexOf(o);
if (index >= 0) {
keys.remove(index);
values.remove(index);
}
return super.remove(o);
}
 
@Override
public void clear() {
clear();
super.clear();
}
};
}
 
@Override
public Set<Entry<K, V>> entrySet() {
final Set<Entry<K, V>> set = new HashSet<Map.Entry<K, V>>() {
@Override
public boolean remove(Object o) {
Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
int index = values.indexOf(entry.getValue());
if (index >= 0) {
keys.remove(index);
values.remove(index);
}
return super.remove(o);
}
 
@Override
public boolean removeAll(Collection<?> c) {
for (Iterator iterator = c.iterator(); iterator.hasNext();) {
Entry<K, V> entry = (Entry<K, V>) iterator.next();
int index = values.indexOf(entry.getValue());
if (index >= 0) {
keys.remove(index);
values.remove(index);
}
}
return super.removeAll(c);
}
 
@Override
public void clear() {
clear();
super.clear();
}
 
};
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
set.add(new SimpleImmutableEntry<K, V>(this.keys.get(i), this.values.get(i)));
}
return set;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/cache/ICache.java
13,9 → 13,9
package org.openconcerto.utils.cache;
 
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ExceptionUtils;
import org.openconcerto.utils.Log;
import org.openconcerto.utils.SetMap;
import org.openconcerto.utils.cache.CacheResult.State;
import org.openconcerto.utils.cc.Transformer;
 
53,7 → 53,7
private final String name;
private final Map<K, CacheTimeOut<K>> timeoutTasks;
private Map<D, CacheWatcher<K, D>> watchers;
private final CollectionMap<K, CacheWatcher<K, D>> watchersByKey;
private final SetMap<K, CacheWatcher<K, D>> watchersByKey;
 
private ICache<K, V, D> parent;
 
89,7 → 89,7
this.timeoutTasks = new HashMap<K, CacheTimeOut<K>>();
 
this.watchers = null;
this.watchersByKey = new CollectionMap<K, CacheWatcher<K, D>>(HashSet.class);
this.watchersByKey = new SetMap<K, CacheWatcher<K, D>>();
 
this.parent = null;
}
236,7 → 236,7
if (this.watchers != null) {
final CacheWatcher<K, D> watcher = this.watchers.get(datum);
watcher.add(sel);
this.watchersByKey.put(sel, watcher);
this.watchersByKey.add(sel, watcher);
}
}
 
244,7 → 244,7
this.timeoutTasks.put(sel, timeout);
this.getTimer().schedule(timeout, this.delay * 1000);
 
return (Set<CacheWatcher<K, D>>) this.watchersByKey.getNonNull(sel);
return this.watchersByKey.getNonNull(sel);
}
 
public final synchronized void clear(K select) {
252,7 → 252,7
if (this.cache.containsKey(select)) {
this.cache.remove(select);
this.timeoutTasks.remove(select).cancel();
final Set<CacheWatcher<K, D>> keyWatchers = (Set<CacheWatcher<K, D>>) this.watchersByKey.remove(select);
final Set<CacheWatcher<K, D>> keyWatchers = this.watchersByKey.remove(select);
// a key can specify no watchers at all
if (keyWatchers != null) {
for (final CacheWatcher<K, D> w : keyWatchers) {
/trunk/OpenConcerto/src/org/openconcerto/utils/SetMap.java
13,13 → 13,76
package org.openconcerto.utils;
 
import org.openconcerto.utils.CollectionMap2Itf.SetMapItf;
 
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
 
public class SetMap<K, V> extends CollectionMap2<K, Set<V>, V> {
public class SetMap<K, V> extends CollectionMap2<K, Set<V>, V> implements SetMapItf<K, V> {
 
static private class Unmodifiable<K, V> extends UnmodifiableCollectionMap<K, Set<V>, V> implements SetMapItf<K, V> {
Unmodifiable(CollectionMap2Itf<K, Set<V>, V> delegate) {
super(delegate, new UnmodifiableCollectionMap.UnmodifiableMap<K, Set<V>>(delegate) {
@Override
protected Set<V> toUnmodifiable(Set<V> coll) {
return Collections.unmodifiableSet(coll);
}
});
}
}
 
static public <K, V> SetMapItf<K, V> unmodifiableMap(SetMapItf<K, V> map) {
return new Unmodifiable<K, V>(map);
}
 
@SuppressWarnings({ "unchecked", "rawtypes" })
private static SetMap EMPTY = new SetMap(Collections.emptyMap(), Mode.NULL_FORBIDDEN) {
@Override
public SetMap clone() {
// this instance is immutable and Collections classes might be cloneable
return this;
}
};
 
@SuppressWarnings("unchecked")
public static <K, V> SetMap<K, V> empty() {
return EMPTY;
}
 
public static <K, V> SetMap<K, V> singleton(K key, V... values) {
return singleton(key, Arrays.asList(values));
}
 
public static <K, V> SetMap<K, V> singleton(K key, Collection<? extends V> values) {
return singleton(key, new HashSet<V>(values), false);
}
 
private static <K, V> SetMap<K, V> singleton(K key, Set<V> values, final boolean immutable) {
final Set<V> coll = immutable ? values : Collections.unmodifiableSet(values);
return new SetMap<K, V>(Collections.singletonMap(key, coll), DEFAULT_MODE) {
@Override
public SetMap<K, V> clone() {
// this instance is immutable and Collections classes might be cloneable
return this;
}
};
}
 
// to avoid
// "Type safety : A generic array of Tuple2<String,Boolean> is created for a varargs parameter"
public static <K, V> SetMap<K, V> singleton(K key, V value) {
return singleton(key, Collections.singleton(value), true);
}
 
// static method since one-argument is for copying (see CopyUtils)
static public <K, V> SetMap<K, V> decorate(final Map<K, Set<V>> m) {
return new SetMap<K, V>(m, DEFAULT_MODE);
}
 
public SetMap() {
super();
}
32,10 → 95,6
super(initialCapacity);
}
 
public SetMap(Map<? extends K, ? extends Collection<? extends V>> m) {
super(m);
}
 
public SetMap(Mode mode, boolean emptyCollSameAsNoColl) {
super(mode, emptyCollSameAsNoColl);
}
44,8 → 103,31
super(mode);
}
 
public SetMap(Map<K, Set<V>> delegate, Mode mode) {
super(delegate, mode);
}
 
public SetMap(final Map<K, Set<V>> delegate, final Mode mode, final Boolean emptyCollSameAsNoColl) {
super(delegate, mode, emptyCollSameAsNoColl);
}
 
// ** copy constructors
 
public SetMap(CollectionMap2<K, Set<V>, ? extends V> m) {
super(m);
}
 
public SetMap(Map<? extends K, ? extends Collection<? extends V>> m) {
super(m);
}
 
@Override
public Set<V> createCollection(Collection<? extends V> v) {
return new HashSet<V>(v);
}
 
@Override
public SetMap<K, V> clone() throws CloneNotSupportedException {
return (SetMap<K, V>) super.clone();
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/Backup.java
22,6 → 22,8
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
 
34,6 → 36,7
return Logger.getLogger("org.openconcerto.backup");
}
 
private Set<String> processedDir;
private final File dest;
 
public Backup(File dest) {
113,10 → 116,18
*/
public int applyTo(final File dir) {
getLogger().log(Level.INFO, "Copy start from " + dir + " to " + this.dest);
return applyTo(dir, dir);
processedDir = new HashSet<String>();
final int applyTo = applyTo(dir, dir);
processedDir = null;
return applyTo;
}
 
private int applyTo(final File origine, final File dir) {
final String dirPath = dir.getAbsolutePath();
if (processedDir.contains(dirPath)) {
return 0;
}
processedDir.add(dirPath);
int failed = 0;
if (dir.exists()) {
 
/trunk/OpenConcerto/src/org/openconcerto/utils/ListMap.java
13,23 → 13,113
package org.openconcerto.utils;
 
import org.openconcerto.utils.CollectionMap2Itf.ListMapItf;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
 
public class ListMap<K, V> extends CollectionMap2<K, List<V>, V> {
public class ListMap<K, V> extends ListAbstractMap<K, List<V>, V> implements ListMapItf<K, V> {
 
static private class Unmodifiable<K, V> extends UnmodifiableCollectionMap<K, List<V>, V> implements ListMapItf<K, V> {
Unmodifiable(CollectionMap2Itf<K, List<V>, V> delegate) {
super(delegate, new UnmodifiableCollectionMap.UnmodifiableMap<K, List<V>>(delegate) {
@Override
protected List<V> toUnmodifiable(List<V> coll) {
return Collections.unmodifiableList(coll);
}
});
}
}
 
static public <K, V> ListMapItf<K, V> unmodifiableMap(ListMapItf<K, V> map) {
return new Unmodifiable<K, V>(map);
}
 
@SuppressWarnings({ "unchecked", "rawtypes" })
private static ListMap EMPTY = new ListMap(Collections.emptyMap(), Mode.NULL_FORBIDDEN) {
@Override
public ListMap clone() {
// this instance is immutable and Collections classes might be cloneable
return this;
}
};
 
@SuppressWarnings("unchecked")
public static <K, V> ListMap<K, V> empty() {
return EMPTY;
}
 
public static <K, V> ListMap<K, V> singleton(K key, V... values) {
return singleton(key, Arrays.asList(values), true);
}
 
public static <K, V> ListMap<K, V> singleton(K key, Collection<? extends V> values) {
return singleton(key, new ArrayList<V>(values), false);
}
 
private static <K, V> ListMap<K, V> singleton(K key, List<V> values, final boolean immutable) {
final List<V> coll = immutable ? values : Collections.unmodifiableList(values);
return new ListMap<K, V>(Collections.singletonMap(key, coll), DEFAULT_MODE) {
@Override
public ListMap<K, V> clone() {
// this instance is immutable and Collections classes might be cloneable
return this;
}
};
}
 
// to avoid
// "Type safety : A generic array of Tuple2<String,Boolean> is created for a varargs parameter"
public static <K, V> ListMap<K, V> singleton(K key, V value) {
return singleton(key, Collections.singletonList(value), true);
}
 
// static method since one-argument is for copying (see CopyUtils)
static public <K, V> ListMap<K, V> decorate(final Map<K, List<V>> m) {
return new ListMap<K, V>(m, DEFAULT_MODE);
}
 
public ListMap() {
super();
}
 
public ListMap(Map<K, List<V>> delegate, Mode mode) {
super(delegate, mode);
}
 
public ListMap(int initialCapacity) {
super(initialCapacity);
}
 
public ListMap(int initialCapacity, Mode mode, Boolean emptyCollSameAsNoColl) {
super(initialCapacity, mode, emptyCollSameAsNoColl);
}
 
// ** copy constructors
 
public ListMap(CollectionMap2<K, List<V>, ? extends V> m) {
super(m);
}
 
public ListMap(Map<? extends K, ? extends Collection<? extends V>> m) {
super(m);
}
 
public ListMap(Map<K, List<V>> delegate, Map<? extends K, ? extends Collection<? extends V>> m) {
super(delegate, m);
}
 
@Override
public List<V> createCollection(Collection<? extends V> v) {
return new ArrayList<V>(v);
}
 
@Override
public ListMap<K, V> clone() throws CloneNotSupportedException {
return (ListMap<K, V>) super.clone();
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/Tuple2.java
26,13 → 26,14
*/
public class Tuple2<A, B> {
 
public static final class List2<A> extends Tuple2<A, A> {
public static class List2<A> extends Tuple2<A, A> {
public List2(A a1, A a2) {
super(a1, a2);
}
 
@SuppressWarnings("unchecked")
public List<A> asList() {
@Override
public final List<A> asList() {
return Arrays.asList(get0(), get1());
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/DropperQueue.java
105,14 → 105,57
}
 
/**
* Signal that this thread must stop definitely.
* Signal that this thread must stop indefinitely. This method interrupts
* {@link #process(Object)}.
*
* @see #die(boolean)
*/
public synchronized final void die() {
public final void die() {
this.die(true);
}
 
/**
* Signal that this thread must stop indefinitely. Once this method returns, it is guaranteed
* that no new item will be processed, and that this thread will {@link #isDead() die}. But if
* this thread is currently {@link #process(Object) processing} an item, then the method will
* finish normally if :
* <ul>
* <li><code>mayInterruptIfRunning</code> is <code>false</code></li>
* <li><code>mayInterruptIfRunning</code> is <code>true</code> but the {@link #interrupt()}
* isn't checked by the implementing subclass</li>
* </ul>
*
* @param mayInterruptIfRunning <code>true</code> to interrupt while in {@link #process(Object)}
* @see #isDying()
*/
public synchronized final void die(boolean mayInterruptIfRunning) {
this.stop = true;
this.signalChange(true);
this.signalChange(mayInterruptIfRunning);
}
 
public synchronized final boolean isDead() {
/**
* Whether this queue is dying.
*
* @return <code>true</code> if {@link #die(boolean)} has been called and
* {@link #process(Object)} is still executing.
* @see #isDead()
*/
public synchronized final boolean isDying() {
return this.dieCalled() && this.isExecuting();
}
 
/**
* Whether this queue is active.
*
* @return <code>true</code> if {@link #process(Object)} isn't executed and won't ever be again.
* @see #isDying()
*/
public final boolean isDead() {
// either we're dead because die() has been called, or because process() threw an Error
return !this.isAlive();
}
 
public synchronized final boolean dieCalled() {
return this.stop;
}
 
120,7 → 163,7
 
@Override
public void run() {
while (!this.isDead()) {
while (!this.dieCalled()) {
try {
this.await();
final T item;
/trunk/OpenConcerto/src/org/openconcerto/utils/prog/CorrectPathEncoding.java
583,9 → 583,9
// case 0xEB:
case 0xEC:
case 0xED:
case 0xEE:
cp = cp1252;
break;
// case 0xEE:
// case 0xEF:
 
case 0xF0:
/trunk/OpenConcerto/src/org/openconcerto/utils/prog/cp.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/src/org/openconcerto/utils/ProductInfo.java
110,4 → 110,9
public final String getVersion() {
return this.getProperty(VERSION);
}
 
@Override
public String toString() {
return this.getClass().getSimpleName() + " for " + getName() + " " + getVersion();
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/SystemInfo.java
New file
0,0 → 1,140
/*
* 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 static org.openconcerto.utils.CollectionUtils.join;
import static java.lang.System.getProperty;
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.i18n.TM;
 
import java.io.File;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
 
/**
* Various system informations (e.g. VM version, user name, network address).
*
* @author Sylvain CUAZ
*/
public final class SystemInfo {
 
static public enum Info {
JAVA, OS, USER, NETWORK
}
 
public static final String CLASS_PROTOCOL = "class";
 
static public Map<Info, String> get(final boolean html) {
final Map<Info, String> res = new HashMap<Info, String>(Info.values().length);
 
final String lineBreak = getLineBreak(html);
 
// * Version 1.6.0_13-b03 de Sun Microsystems Inc. ; dossier d'installation
final String version = getProperty("java.runtime.version") != null ? getProperty("java.runtime.version") : getProperty("java.version");
URI vendorURI = null;
final LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
URI lafURI = null;
try {
vendorURI = new URI(getProperty("java.vendor.url"));
lafURI = new URI(CLASS_PROTOCOL, lookAndFeel.getClass().getName(), null);
} catch (URISyntaxException e1) {
// tant pis pas de lien
e1.printStackTrace();
}
final Runtime rt = Runtime.getRuntime();
final String stats = "<i>" + TM.tr("memory") + " :</i> " + formatBytes(rt.freeMemory()) + " / " + formatBytes(rt.totalMemory()) + " ; " + TM.tr("processors", rt.availableProcessors());
final String lafDesc = lookAndFeel == null ? TM.tr("no.laf") : getLink(lookAndFeel.getName(), lafURI, html) + ", " + lookAndFeel.getDescription();
 
final String p = TM.tr("javaVersion", version, getLink(getProperty("java.vendor"), vendorURI, html)) + " ; " + getLink(TM.tr("javaHome"), new File(getProperty("java.home")).toURI(), html)
+ lineBreak + stats + lineBreak + lafDesc;
 
res.put(Info.JAVA, p);
 
// * Windows XP 5.1 (x86)
res.put(Info.OS, "<b>" + getProperty("os.name") + "</b> " + getProperty("os.version") + " (" + getProperty("os.arch") + ")");
 
// * Sylvain ; C:\Documents and Settings\Sylvain ; D:\workspace\CTech
res.put(Info.USER,
getProperty("user.name") + " ; " + getLink(TM.tr("home.dir"), new File(getProperty("user.home")).toURI(), html) + " ; "
+ getLink(TM.tr("cwd"), new File(getProperty("user.dir")).toURI(), html));
 
// * eth0 192.168.28.52/24, état: inactif, nom complet: ""
final List<String> ifs = new ArrayList<String>();
try {
final Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while (en.hasMoreElements()) {
final NetworkInterface ni = en.nextElement();
// on mac both the name and the display name are just "vmnet1"
if (ni.getHardwareAddress() != null && !ni.isLoopback() && !ni.getDisplayName().toLowerCase().contains("vmware") && !ni.getName().toLowerCase().contains("vmnet")) {
final StringBuilder sb = new StringBuilder();
// don't wrap each nic in a <p> or <li> since it offset the first line
sb.append(ni.getName() + " " + join(ni.getInterfaceAddresses(), ", ", new ITransformer<InterfaceAddress, String>() {
@Override
public String transformChecked(InterfaceAddress input) {
return "<b>" + input.getAddress().getHostAddress() + "</b>" + "/" + input.getNetworkPrefixLength();
}
}));
sb.append(" ; <i>" + TM.tr("interfaceState") + " :</i> " + TM.tr(ni.isUp() ? "interfaceStateUp" : "interfaceStateDown"));
sb.append(lineBreak);
sb.append(" <i>" + TM.tr("interfaceFullName") + " :</i> " + ni.getDisplayName());
 
sb.append(lineBreak);
sb.append(" <i>" + TM.tr("hardwareAddress") + " :</i> ");
final Formatter fmt = new Formatter(sb);
final byte[] mac = ni.getHardwareAddress();
for (int i = 0; i < mac.length; i++) {
fmt.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : "");
}
ifs.add(sb.toString());
}
}
} catch (Exception e) {
// affiche l'erreur
e.printStackTrace();
ifs.add(e.getLocalizedMessage());
}
res.put(Info.NETWORK, join(ifs, lineBreak));
 
return res;
}
 
public static final String getLineBreak(final boolean html) {
return html ? "<br>" : "\n";
}
 
public static final String getLink(final String name, final URI uri, final boolean html) {
if (uri == null) {
return name;
} else if (html) {
return "<a href=\"" + uri.toString() + "\" >" + name + "</a>";
} else {
return "[" + name + "](" + uri.toString() + ")";
}
}
 
private static String formatBytes(long b) {
return TM.tr("megabytes", b / 1024 / 1024);
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/UnmodifiableCollectionMap.java
New file
0,0 → 1,258
/*
* 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 org.openconcerto.utils.CollectionMap2.Mode;
import org.openconcerto.utils.cc.AbstractMapDecorator;
 
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
class UnmodifiableCollectionMap<K, C extends Collection<V>, V> extends AbstractMapDecorator<K, C> implements CollectionMap2Itf<K, C, V> {
 
// protect Map methods and Collection values. The mutable CollectionMap2Itf methods are
// protected by the enclosing class
public static abstract class UnmodifiableMap<K, C extends Collection<?>> extends AbstractMapDecorator<K, C> {
 
private final Map<K, C> del;
private transient Collection<C> values;
private transient Set<Map.Entry<K, C>> entrySet;
 
protected UnmodifiableMap(Map<K, C> delegate) {
super(Collections.unmodifiableMap(delegate));
this.del = delegate;
}
 
@Override
public final C get(final Object key) {
return toUnmodifiable(super.get(key));
}
 
@Override
public final Collection<C> values() {
final Collection<C> vs = this.values;
return vs != null ? vs : (this.values = new AbstractCollection<C>() {
 
@Override
public boolean contains(Object o) {
return UnmodifiableMap.this.containsValue(o);
}
 
@Override
public Iterator<C> iterator() {
final Iterator<Map.Entry<K, C>> iter = entrySet().iterator();
return new Iterator<C>() {
 
@Override
public boolean hasNext() {
return iter.hasNext();
}
 
@Override
public C next() {
// our entrySet() is already unmodifiable
return iter.next().getValue();
}
 
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
 
@Override
public int size() {
return UnmodifiableMap.this.size();
}
});
}
 
@Override
public final Set<Map.Entry<K, C>> entrySet() {
final Set<Map.Entry<K, C>> es = this.entrySet;
return es != null ? es : (this.entrySet = new AbstractSet<Map.Entry<K, C>>() {
private final Set<Map.Entry<K, C>> delegateES = UnmodifiableMap.super.entrySet();
 
@Override
public boolean contains(Object o) {
return this.delegateES.contains(o);
}
 
@Override
public Iterator<Map.Entry<K, C>> iterator() {
final Iterator<Map.Entry<K, C>> iter = this.delegateES.iterator();
return new Iterator<Map.Entry<K, C>>() {
 
@Override
public boolean hasNext() {
return iter.hasNext();
}
 
@Override
public Map.Entry<K, C> next() {
final Map.Entry<K, C> orig = iter.next();
return new Map.Entry<K, C>() {
 
@Override
public K getKey() {
return orig.getKey();
}
 
@Override
public C getValue() {
return toUnmodifiable(orig.getValue());
}
 
@Override
public C setValue(C value) {
throw new UnsupportedOperationException();
}
};
}
 
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
 
@Override
public int size() {
return UnmodifiableMap.this.size();
}
 
@Override
public boolean equals(Object o) {
return o == this || this.delegateES.equals(o);
}
 
@Override
public int hashCode() {
return this.delegateES.hashCode();
}
});
}
 
protected abstract C toUnmodifiable(C coll);
}
 
private final CollectionMap2Itf<K, C, V> del;
private transient Collection<V> values;
 
UnmodifiableCollectionMap(final CollectionMap2Itf<K, C, V> delegate, final UnmodifiableMap<K, C> unmodif) {
super(unmodif);
if (unmodif.del != delegate)
throw new IllegalArgumentException("Mismatched arguments");
this.del = delegate;
}
 
private final CollectionMap2Itf<K, C, V> getDel() {
return this.del;
}
 
@Override
public Mode getMode() {
return getDel().getMode();
}
 
@Override
public boolean isEmptyCollSameAsNoColl() {
return getDel().isEmptyCollSameAsNoColl();
}
 
@Override
public C getNonNull(final K key) {
return getDel().getNonNull(key);
}
 
@Override
public C get(final Object key, final boolean nullIfMissing, final boolean nullIfPresent) {
return getDel().get(key, nullIfMissing, nullIfPresent);
}
 
@Override
public C getCollection(final Object key) {
return getDel().getCollection(key);
}
 
@Override
public Collection<V> allValues() {
if (this.values == null) {
this.values = Collections.unmodifiableCollection(getDel().allValues());
}
return this.values;
}
 
@Override
public C putCollection(final K key, final Collection<? extends V> value) {
throw new UnsupportedOperationException();
}
 
@Override
public boolean add(final K k, final V v) {
throw new UnsupportedOperationException();
}
 
@Override
public boolean addAll(final K k, final Collection<? extends V> v) {
throw new UnsupportedOperationException();
}
 
@Override
public void merge(final Map<? extends K, ? extends Collection<? extends V>> mm) {
throw new UnsupportedOperationException();
}
 
@Override
public void mergeScalarMap(final Map<? extends K, ? extends V> scalarMap) {
throw new UnsupportedOperationException();
}
 
@Override
public boolean remove(final K k, final V v) {
throw new UnsupportedOperationException();
}
 
@Override
public boolean removeAll(final K k, final Collection<? extends V> v) {
throw new UnsupportedOperationException();
}
 
@Override
public boolean removeAll(final Map<? extends K, ? extends Collection<? extends V>> mm) {
throw new UnsupportedOperationException();
}
 
@Override
public boolean removeAllScalar(final Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
 
@Override
public Set<K> removeAllEmptyCollections() {
throw new UnsupportedOperationException();
}
 
@Override
public Set<K> removeAllNullCollections() {
throw new UnsupportedOperationException();
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/Tuple3.java
27,13 → 27,14
*/
public class Tuple3<A, B, C> extends Tuple2<A, B> {
 
public static final class List3<A> extends Tuple3<A, A, A> {
public static class List3<A> extends Tuple3<A, A, A> {
public List3(A a1, A a2, A a3) {
super(a1, a2, a3);
}
 
@SuppressWarnings("unchecked")
public List<A> asList() {
@Override
public final List<A> asList() {
return Arrays.asList(get0(), get1(), get2());
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/CollectionUtils.java
25,7 → 25,6
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
37,15 → 36,8
import java.util.NoSuchElementException;
import java.util.RandomAccess;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Pattern;
 
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.TransformerUtils;
 
/**
* Une classe regroupant des méthodes utilitaires pour les collections.
*
238,116 → 230,6
}
 
/**
* Permet d'organiser une collection en une hiérarchie à l'aide de Map. Avec <code>
* Col = [
* Obs1(bat=BAT A, local=A1, num=1),
* Obs2(bat=BAT B, local=B1, num=2),
* Obs3(bat=BAT B, local=B2, num=3),
* Obs4(bat=BAT B, local=B2, num=4)
* ]
* <code>
* ainsi que deux extracteurs pour trouver le batiment et le local, et enfin itemOrdering suivant le numero, on a
* { BAT A => {A1 => {Obs1}}, {BAT B => {B1 => {Obs2}, B2 => {Obs3, Obs4}}}}.
*
* @param col la collection à organiser.
* @param propExtractors les extracteurs de propriétes.
* @param propComp les Comparator pour les propriétés renvoyées par les extracteurs, peut être
* <code>null</code> si les propriétés sont des Comparable.
* @param itemOrdering comment ordonner les éléments dans la dernière tranche, peut être
* <code>null</code> si les éléments sont des Comparable.
* @return une hiérarchie de SortedMap et en dernier un SortedSet.
*/
static public final SortedMap organize(Collection col, List<? extends Transformer> propExtractors, List<? extends Comparator> propComp, Comparator itemOrdering) {
if (propExtractors.size() == 0)
throw new IllegalArgumentException("Empty property extractors");
 
if (propComp == null)
propComp = Collections.nCopies(propExtractors.size(), null);
else if (propExtractors.size() != propComp.size())
throw new IllegalArgumentException("Size mismatch between " + propExtractors + " and " + propComp);
 
final SortedMap res = new TreeMap(propComp.get(0));
 
Iterator iter = col.iterator();
while (iter.hasNext()) {
final Object item = iter.next();
Map m = res;
 
for (int i = 0; i < propExtractors.size() - 1; i++) {
final Transformer extractor = propExtractors.get(i);
final Object property = extractor.transform(item);
Map newM = (Map) m.get(property);
if (newM == null) {
newM = new TreeMap(propComp.get(i + 1));
m.put(property, newM);
}
m = newM;
}
final Object property = propExtractors.get(propExtractors.size() - 1).transform(item);
SortedSet s = (SortedSet) m.get(property);
if (s == null) {
s = new TreeSet(itemOrdering);
m.put(property, s);
}
s.add(item);
}
 
return res;
}
 
/**
* Permet d'aplatir une hiérarchie. Exemple :
*
* <pre>
* A-
* A1
* A2
* B-
* B1
* B11
* B12
* </pre>
*
* devient <code>[A, A1, A2, B, B1, B11, B12]</code>.
*
* @param hierarchy la hiérarchie à aplatir.
* @param itemTransf la transformation à faire sur les feuilles.
* @return la liste correspondante.
*/
static public final List flatten(Map hierarchy, Transformer itemTransf) {
final List res = new ArrayList();
 
final Iterator iter = hierarchy.keySet().iterator();
while (iter.hasNext()) {
final Object obj = iter.next();
res.add(obj);
final Object value = hierarchy.get(obj);
if (value instanceof Map)
res.addAll(flatten((Map) value, itemTransf));
else if (value instanceof Collection) {
final Collection items = (Collection) value;
final Iterator itemIter = items.iterator();
while (itemIter.hasNext()) {
final Object item = itemIter.next();
res.add(itemTransf.transform(item));
}
} else
throw new IllegalArgumentException("Illegal value: " + value);
}
return res;
}
 
/**
* Permet d'aplatir une hiérarchie.
*
* @param hierarchy la hiérarchie à aplatir.
* @return la liste correspondante.
*/
static public final List flatten(Map hierarchy) {
return flatten(hierarchy, TransformerUtils.nopTransformer());
}
 
/**
* Convertit une map en 2 listes, une pour les clefs, une pour les valeurs.
*
* @param map la Map à convertir.
535,6 → 417,22
return lastI;
}
 
public final static <T> int getEqualsCount(final Iterator<? extends T> a, final Iterator<? extends T> b) {
return getEqualsCount(a, b, null);
}
 
public final static <A, B> int getEqualsCount(final Iterator<A> a, final Iterator<B> b, final ITransformer<A, B> transf) {
int res = 0;
while (a.hasNext() && b.hasNext()) {
final A itemA = a.next();
final B itemB = b.next();
if (!CompareUtils.equals(transf == null ? itemA : transf.transformChecked(itemA), itemB))
break;
res++;
}
return res;
}
 
public static <T> Collection<T> select(final Collection<T> a, final IPredicate<? super T> pred) {
return select(a, pred, new ArrayList<T>());
}
653,6 → 551,18
return org.apache.commons.collections.CollectionUtils.subtract(a, b);
}
 
public static final <T> T coalesce(T o1, T o2) {
return o1 != null ? o1 : o2;
}
 
public static final <T> T coalesce(T... objects) {
for (T o : objects) {
if (o != null)
return o;
}
return null;
}
 
/**
* Return the first item of <code>l</code> if it's the only one, otherwise <code>null</code>.
*
727,7 → 637,7
 
@SuppressWarnings("unchecked")
public static <T> Iterator<T> emptyIterator() {
return (Iterator<T>) EMPTY_ITERATOR;
return EMPTY_ITERATOR;
}
 
public static <T> LinkedList<T> toLinkedList(final Iterator<T> iter) {
837,7 → 747,7
 
@SuppressWarnings("unchecked")
public static <T> IdentitySet<T> emptyIdentitySet() {
return (IdentitySet<T>) EMPTY_SET;
return EMPTY_SET;
}
 
private static final class EmptyIdentitySet extends AbstractSet<Object> implements IdentitySet<Object>, Serializable {
910,7 → 820,7
* @param <M> type of map.
* @param m the map to fill.
* @param keys the keys to add.
* @param v the value to put.
* @param val the value to put.
* @return the passed map.
*/
public static <K, V, M extends Map<K, V>> M fillMap(final M m, final Collection<? extends K> keys, final V val) {
/trunk/OpenConcerto/src/org/openconcerto/utils/CollectionMap2Itf.java
New file
0,0 → 1,101
/*
* 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 org.openconcerto.utils.CollectionMap2.Mode;
 
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
public interface CollectionMap2Itf<K, C extends Collection<V>, V> extends Map<K, C> {
 
public static interface ListMapItf<K, V> extends CollectionMap2Itf<K, List<V>, V> {
}
 
public static interface SetMapItf<K, V> extends CollectionMap2Itf<K, Set<V>, V> {
}
 
public Mode getMode();
 
public boolean isEmptyCollSameAsNoColl();
 
public C getNonNull(K key);
 
/**
* Get the collection mapped to the passed key. Note : <code>get(key, true, true)</code> is
* equivalent to <code>get(key)</code>.
*
* @param key the key whose associated value is to be returned.
* @param nullIfMissing only relevant if the key isn't contained : if <code>true</code>
* <code>null</code> will be returned, otherwise an empty collection.
* @param nullIfPresent only relevant if the key is mapped to <code>null</code> : if
* <code>true</code> <code>null</code> will be returned, otherwise an empty collection.
* @return the non {@code null} value to which the specified key is mapped, otherwise
* {@code null} or empty collection depending on the other parameters.
*/
public C get(Object key, final boolean nullIfMissing, final boolean nullIfPresent);
 
public C getCollection(Object key);
 
/**
* Returns a {@link Collection} view of all the values contained in this map. The collection is
* backed by the map, so changes to the map are reflected in the collection, and vice-versa. If
* the map is modified while an iteration over the collection is in progress (except through the
* iterator's own <tt>remove</tt> operation), the results of the iteration are undefined. The
* collection supports element removal, which removes the corresponding values from the map, via
* the <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, <tt>removeAll</tt>,
* <tt>retainAll</tt> and <tt>clear</tt> operations. Note that it doesn't remove entries only
* values : keySet() doesn't change, use {@link #removeAllEmptyCollections()} and
* {@link #removeAllNullCollections()} afterwards. It does not support the <tt>add</tt> or
* <tt>addAll</tt> operations.
*
* @return a view all values in all entries, <code>null</code> collections are ignored.
*/
public Collection<V> allValues();
 
// copy passed collection
public C putCollection(final K key, final Collection<? extends V> value);
 
public boolean add(final K k, final V v);
 
public boolean addAll(final K k, final Collection<? extends V> v);
 
/**
* Call {@link #addAll(Object, Collection)} for each entry.
*
* @param mm the collection map to merge.
*/
public void merge(final Map<? extends K, ? extends Collection<? extends V>> mm);
 
/**
* Call {@link #add(Object, Object)} for each entry.
*
* @param scalarMap the map to merge.
*/
public void mergeScalarMap(final Map<? extends K, ? extends V> scalarMap);
 
public boolean remove(final K k, final V v);
 
public boolean removeAll(final K k, final Collection<? extends V> v);
 
public boolean removeAll(final Map<? extends K, ? extends Collection<? extends V>> mm);
 
public boolean removeAllScalar(final Map<? extends K, ? extends V> m);
 
public Set<K> removeAllEmptyCollections();
 
public Set<K> removeAllNullCollections();
}
/trunk/OpenConcerto/src/org/openconcerto/utils/model/ISearchable.java
New file
0,0 → 1,35
/*
* 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 ISearchable {
 
/**
* Whether <code>setSearch()</code> will be ignored.
*
* @return <code>true</code> if {@link #setSearch(String, Runnable)} will do something.
*/
boolean isSearchable();
 
/**
* Change search.
*
* @param s the new search.
* @param r will be invoked after the search has been carried out.
* @return <code>true</code> if the search has changed, i.e. <code>s</code> has changed and
* {@link #isSearchable()} is <code>true</code>.
*/
boolean setSearch(final String s, final Runnable r);
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/EmailClient.java
357,6 → 357,10
public static abstract class Thunderbird extends EmailClient {
 
public static Thunderbird createFromExe(final File exe) {
if (exe == null)
throw new NullPointerException();
if (!exe.isFile())
return null;
return new ThunderbirdPath(exe);
}
 
452,12 → 456,18
case AppleMail:
return AppleMail;
case Thunderbird:
if (args.length == 2)
return Thunderbird.createFromExe(new File(args[1]));
else if (args.length == 3)
return Thunderbird.createFromCommandLine(args[1], args[2]);
else
EmailClient res = null;
if (args.length == 2) {
final File exe = new File(args[1]);
res = Thunderbird.createFromExe(exe);
if (res == null)
throw new IOException("Invalid exe : " + exe);
} else if (args.length == 3) {
res = Thunderbird.createFromCommandLine(args[1], args[2]);
} else {
throw new IllegalArgumentException(t + " needs 1 or 2 arguments");
}
return res;
default:
throw new IllegalStateException("Unknown type " + t);
}
/trunk/OpenConcerto/src/org/openconcerto/utils/CollectionMap.java
32,8 → 32,11
* @author ILM Informatique 8 sept. 2004
* @param <K> type of the keys
* @param <V> type of elements in collections
* @deprecated this class is not type safe and its superclass has been removed from Apache
* Collections 3.2, use {@link CollectionMap2}
*/
@SuppressWarnings("unchecked")
@Deprecated
public class CollectionMap<K, V> extends MultiHashMap {
 
private static final int DEFAULT_CAPACITY = 16;
180,7 → 183,7
return this.collectionClass;
}
 
public void removeAll(CollectionMap<? extends K, ? extends V> mm) {
public void removeAllFromCollections(CollectionMap<? extends K, ? extends V> mm) {
for (final Map.Entry<? extends K, ?> e : mm.entrySet()) {
final Collection<V> coll = this.getNull(e.getKey());
if (coll != null) {
/trunk/OpenConcerto/src/org/openconcerto/utils/LinkedListMap.java
New file
0,0 → 1,35
/*
* 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.util.Collection;
import java.util.LinkedList;
import java.util.Map;
 
// syntactic sugar to avoid repeating V
public class LinkedListMap<K, V> extends ListAbstractMap<K, LinkedList<V>, V> {
 
public LinkedListMap() {
super();
}
 
public LinkedListMap(Map<? extends K, ? extends Collection<? extends V>> m) {
super(m);
}
 
@Override
public LinkedList<V> createCollection(Collection<? extends V> v) {
return new LinkedList<V>(v);
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/FileUtils.java
13,7 → 13,9
package org.openconcerto.utils;
 
import org.openconcerto.utils.CollectionMap2.Mode;
import org.openconcerto.utils.OSFamily.Unix;
import org.openconcerto.utils.ProcessStreams.Action;
import org.openconcerto.utils.StringUtils.Escaper;
import org.openconcerto.utils.cc.ExnTransformer;
import org.openconcerto.utils.cc.IClosure;
42,6 → 44,7
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.regex.Pattern;
375,19 → 378,23
* @throws IOException if an error occurs.
*/
public static void copyFile(File in, File out, long maxCount) throws IOException {
final FileChannel sourceChannel = new FileInputStream(in).getChannel();
final FileChannel destinationChannel = new FileOutputStream(out).getChannel();
if (maxCount == 0)
maxCount = sourceChannel.size();
final FileInputStream sourceIn = new FileInputStream(in);
FileOutputStream sourceOut = null;
try {
sourceOut = new FileOutputStream(out);
final FileChannel sourceChannel = sourceIn.getChannel();
final long size = sourceChannel.size();
if (maxCount == 0)
maxCount = size;
final FileChannel destinationChannel = sourceOut.getChannel();
long position = 0;
while (position < size) {
position += sourceChannel.transferTo(position, maxCount, destinationChannel);
}
} finally {
sourceChannel.close();
destinationChannel.close();
sourceIn.close();
if (sourceOut != null)
sourceOut.close();
}
}
 
501,7 → 508,7
* @throws IOException if a pb occur while reading.
*/
public static final String read(File f) throws IOException {
return read(f, null);
return read(new InputStreamReader(new FileInputStream(f)));
}
 
/**
508,15 → 515,27
* Read a file line by line and returns the concatenation of these.
*
* @param f the file to read.
* @param charset the encoding of <code>f</code>, <code>null</code> means default encoding.
* @param charset the encoding of <code>f</code>.
* @return the content of f.
* @throws IOException if a pb occur while reading.
*/
public static final String read(File f, String charset) throws IOException {
return read(new InputStreamReader(new FileInputStream(f), charset));
}
 
public static final String readUTF8(File f) throws IOException {
return readUTF8(new FileInputStream(f));
}
 
public static final String readUTF8(InputStream ins) throws IOException {
return read(ins, StringUtils.UTF8);
}
 
public static final String read(File f, Charset charset) throws IOException {
return read(new FileInputStream(f), charset);
}
 
public static final String read(InputStream ins, String charset) throws IOException {
public static final String read(InputStream ins, Charset charset) throws IOException {
final Reader reader;
if (charset == null)
reader = new InputStreamReader(ins);
555,10 → 574,10
* @throws IllegalArgumentException if f is longer than <code>Integer.MAX_VALUE</code>.
*/
public static final byte[] readBytes(File f) throws IOException {
if (f.length() > Integer.MAX_VALUE)
throw new IllegalArgumentException("file longer than Integer.MAX_VALUE" + f.length());
// no need for a Buffer since we read everything at once
final InputStream in = new FileInputStream(f);
if (f.length() > Integer.MAX_VALUE)
throw new IllegalArgumentException("file longer than Integer.MAX_VALUE" + f.length());
final byte[] res = new byte[(int) f.length()];
in.read(res);
in.close();
570,6 → 589,7
}
 
public static void write(String s, File f, String charset, boolean append) throws IOException {
@SuppressWarnings("resource")
final FileOutputStream fileStream = new FileOutputStream(f, append);
final OutputStreamWriter out = charset == null ? new OutputStreamWriter(fileStream) : new OutputStreamWriter(fileStream, charset);
final BufferedWriter w = new BufferedWriter(out);
735,6 → 755,8
ps = Runtime.getRuntime().exec(cmdarray);
res = link;
}
// no need for output, either it succeeds or it fails
ProcessStreams.handle(ps, Action.CLOSE);
try {
final int exitValue = ps.waitFor();
if (exitValue == 0)
762,6 → 784,7
ps = Runtime.getRuntime().exec(new String[] { "readlink", "-f", link.getAbsolutePath() });
}
try {
ps.getErrorStream().close();
final BufferedReader reader = new BufferedReader(new InputStreamReader(ps.getInputStream()));
final String res = reader.readLine();
reader.close();
826,7 → 849,7
for (int i = 0; i < executables.length; i++) {
final String executable = executables[i];
try {
Runtime.getRuntime().exec(new String[] { executable, f.getCanonicalPath() });
ProcessStreams.handle(Runtime.getRuntime().exec(new String[] { executable, f.getCanonicalPath() }), Action.CLOSE);
return;
} catch (IOException e) {
// try the next one
856,9 → 879,11
throw new IOException("unknown way to open " + f);
}
try {
final Process ps = Runtime.getRuntime().exec(cmdarray);
ProcessStreams.handle(ps, Action.CLOSE);
// can wait since the command return as soon as the native application is launched
// (i.e. this won't wait 30s for OpenOffice)
final int res = Runtime.getRuntime().exec(cmdarray).waitFor();
final int res = ps.waitFor();
if (res != 0)
throw new IOException("error (" + res + ") executing " + Arrays.asList(cmdarray));
} catch (InterruptedException e) {
868,7 → 893,10
 
static final boolean gnomeRunning() {
try {
return Runtime.getRuntime().exec(new String[] { "pgrep", "-u", System.getProperty("user.name"), "nautilus" }).waitFor() == 0;
final Process ps = Runtime.getRuntime().exec(new String[] { "pgrep", "-u", System.getProperty("user.name"), "nautilus" });
// no need for output, use exit status
ProcessStreams.handle(ps, Action.CLOSE);
return ps.waitFor() == 0;
} catch (Exception e) {
return false;
}
876,13 → 904,30
 
public static final String XML_TYPE = "text/xml";
private static final Map<String, String> ext2mime;
private static final SetMap<String, String> mime2ext;
 
static {
mime2ext = new SetMap<String, String>(Mode.NULL_FORBIDDEN);
mime2ext.putCollection(XML_TYPE, ".xml");
mime2ext.putCollection("image/jpeg", ".jpg", ".jpeg");
mime2ext.putCollection("image/png", ".png");
mime2ext.putCollection("image/tiff", ".tiff", ".tif");
mime2ext.putCollection("application/pdf", ".pdf");
 
mime2ext.putCollection("application/vnd.oasis.opendocument.spreadsheet", ".ods");
mime2ext.putCollection("application/vnd.oasis.opendocument.text", ".odt");
mime2ext.putCollection("application/vnd.oasis.opendocument.presentation", ".odp");
mime2ext.putCollection("application/vnd.oasis.opendocument.graphics", ".odg");
 
ext2mime = new HashMap<String, String>();
ext2mime.put(".xml", XML_TYPE);
ext2mime.put(".jpg", "image/jpeg");
ext2mime.put(".png", "image/png");
ext2mime.put(".tiff", "image/tiff");
for (final Entry<String, Set<String>> e : mime2ext.entrySet()) {
final String m = e.getKey();
for (final String ext : e.getValue()) {
if (ext2mime.put(ext, m) != null)
Log.get().info("Duplicate extension : " + ext);
}
}
}
 
/**
* Try to guess the media type of the passed file name (see <a
899,6 → 944,10
return null;
}
 
public static final Set<String> getExtensionsFromMimeType(final String mimetype) {
return mime2ext.get(mimetype);
}
 
/**
* Return the string after the last dot.
*
906,8 → 955,12
* @return the extension, e.g. "odt" or <code>null</code>.
*/
public static final String getExtension(String fname) {
return getExtension(fname, false);
}
 
public static final String getExtension(final String fname, final boolean withDot) {
final int lastIndex = fname.lastIndexOf('.');
return lastIndex < 0 ? null : fname.substring(lastIndex + 1);
return lastIndex < 0 ? null : fname.substring(lastIndex + (withDot ? 0 : 1));
}
 
/**
/trunk/OpenConcerto/src/org/openconcerto/utils/ArrayComparator.java
New file
0,0 → 1,55
/*
* 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.util.Comparator;
 
public final class ArrayComparator<C> implements Comparator<Object[]> {
 
static public <T extends Comparable<? super T>> ArrayComparator<T> createNatural(final int i, final Class<T> clazz) {
return new ArrayComparator<T>(i, clazz, CompareUtils.<T> naturalOrder());
}
 
private final int i;
private final Class<C> clazz;
private final Comparator<? super C> comp;
 
/**
* Will compare the item <code>i</code> of arrays.
*
* @param i the index.
* @param clazz the class at the index <code>i</code>, cannot be <code>null</code>.
* @param comp the comparator to use, cannot be <code>null</code>.
* @see #createNatural(int, Class)
*/
public ArrayComparator(final int i, final Class<C> clazz, final Comparator<? super C> comp) {
super();
if (i < 0)
throw new IllegalArgumentException("Negative index : " + i);
this.i = i;
if (clazz == null)
throw new IllegalArgumentException("Null class");
this.clazz = clazz;
if (comp == null)
throw new IllegalArgumentException("Null comparator");
this.comp = comp;
}
 
@Override
public int compare(Object[] o1, Object[] o2) {
final C i1 = this.clazz.cast(o1[this.i]);
final C i2 = this.clazz.cast(o2[this.i]);
return this.comp.compare(i1, i2);
}
}
/trunk/OpenConcerto/src/org/openconcerto/xml/XMLCodecUtils.java
49,9 → 49,9
import java.util.Set;
import java.util.Stack;
 
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
 
/**
* To encode and decode using {@link XMLEncoder} and {@link XMLDecoder}.
365,7 → 365,7
try {
return eval(elem, new Stack<Object>(), new HashMap<String, Object>());
} catch (Exception e) {
throw new IllegalStateException("error decoding " + JDOMUtils.output(javaElem), e);
throw new IllegalStateException("error decoding " + JDOM2Utils.output(javaElem), e);
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/xml/DescendantIterator.java
116,20 → 116,37
}
 
public DescendantIterator(final Parent parent, final IPredicate<? super Content> pred) {
this(parent, new Filter() {
this(parent, createFilter(pred));
}
 
private static Filter createFilter(final IPredicate<? super Content> pred) {
return new Filter() {
@Override
public boolean matches(Object obj) {
return pred.evaluateChecked((Content) obj);
}
});
};
}
 
@SuppressWarnings("unchecked")
public DescendantIterator(final Parent parent, final Filter filter) {
if (parent == null) {
throw new IllegalArgumentException("parent parameter was null");
this(parent.getContent(), filter);
}
 
public DescendantIterator(final List<Content> content) {
this(content, (Filter) null);
}
 
public DescendantIterator(final List<Content> content, final IPredicate<? super Content> pred) {
this(content, createFilter(pred));
}
 
public DescendantIterator(final List<Content> content, final Filter filter) {
if (content == null) {
throw new IllegalArgumentException("content parameter was null");
}
this.filter = filter;
this.iterator = wrapIter(parent.getContent().iterator());
this.iterator = wrapIter(content.iterator());
}
 
private Iterator<?> wrapIter(final Iterator<?> iter) {
/trunk/OpenConcerto/src/org/openconcerto/xml/persistence/PersistenceManager.java
13,7 → 13,6
package org.openconcerto.xml.persistence;
 
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ExceptionHandler;
 
import java.io.File;
25,6 → 24,7
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
272,7 → 272,7
* @param clazz la classe des objets à charger.
* @return une liste d'objets correspondant.
*/
static public List load(Class clazz) {
static public List<Persistent> load(Class clazz) {
final Set<String> ids;
try {
ids = io.getIDs(clazz);
296,9 → 296,9
return result;
}
 
static public CollectionMap<Class, Persistent> loadAll(File rootDir) {
static public Map<Class<?>, List<Persistent>> loadAll(File rootDir) {
final PersistenceIO pio = new SingleXMLIO(rootDir);
final CollectionMap<Class, String> mm;
final Map<Class<?>, Set<String>> mm;
try {
mm = pio.getIDs();
} catch (IOException e) {
305,9 → 305,10
throw ExceptionHandler.die("problème lecture", e);
}
 
final CollectionMap<Class, Persistent> res = new CollectionMap<Class, Persistent>();
for (final Class clazz : mm.keySet()) {
res.putAll(clazz, load(clazz, mm.getNonNull(clazz)));
final Map<Class<?>, List<Persistent>> res = new HashMap<Class<?>, List<Persistent>>();
for (final Entry<Class<?>, Set<String>> e : mm.entrySet()) {
final Class<?> clazz = e.getKey();
res.put(clazz, load(clazz, e.getValue()));
}
 
return res;
/trunk/OpenConcerto/src/org/openconcerto/xml/persistence/BaseXMLIO.java
13,12 → 13,11
package org.openconcerto.xml.persistence;
 
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.SetMap;
 
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.HashSet;
 
import org.jdom.Namespace;
import org.jdom.output.Format;
56,18 → 55,19
return dir;
}
 
public final CollectionMap<Class, String> getIDs() throws IOException {
@Override
public final SetMap<Class<?>, String> getIDs() throws IOException {
final File[] dirs = this.root.listFiles(new FileFilter() {
public boolean accept(File f) {
return f.isDirectory();
}
});
final CollectionMap<Class, String> res = new CollectionMap<Class, String>(HashSet.class);
final SetMap<Class<?>, String> res = new SetMap<Class<?>, String>();
for (int i = 0; i < dirs.length; i++) {
final File dir = dirs[i];
final Class clazz = XMLFactory.getClass(dir.getName());
final Class<?> clazz = XMLFactory.getClass(dir.getName());
if (clazz != null) {
res.putAll(clazz, this.getIDs(clazz));
res.addAll(clazz, this.getIDs(clazz));
}
}
return res;
/trunk/OpenConcerto/src/org/openconcerto/xml/persistence/XMLFactory.java
13,17 → 13,16
package org.openconcerto.xml.persistence;
 
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ListMap;
 
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.MultiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.jdom.Element;
 
92,14 → 91,12
* @param elems une collection d'Element.
* @return un Map indexée par les classes des objets.
*/
public static MultiMap fromXML(Collection elems) {
MultiMap res = new CollectionMap();
Iterator iter = elems.iterator();
while (iter.hasNext()) {
final Element elem = (Element) iter.next();
final Class clazz = getClass(elem.getName());
public static Map<Class<?>, List<XMLable>> fromXML(Collection<? extends Element> elems) {
final ListMap<Class<?>, XMLable> res = new ListMap<Class<?>, XMLable>();
for (final Element elem : elems) {
final Class<?> clazz = getClass(elem.getName());
if (clazz != null)
res.put(clazz, fromXML(elem));
res.add(clazz, fromXML(elem));
}
return res;
}
/trunk/OpenConcerto/src/org/openconcerto/xml/persistence/PersistenceIO.java
13,9 → 13,8
package org.openconcerto.xml.persistence;
 
import org.openconcerto.utils.CollectionMap;
 
import java.io.IOException;
import java.util.Map;
import java.util.Set;
 
/**
47,7 → 46,7
 
public Set<String> getIDs(Class clazz) throws IOException;
 
public CollectionMap<Class, String> getIDs() throws IOException;
public Map<Class<?>, Set<String>> getIDs() throws IOException;
 
public void delete(Class clazz, String id) throws IOException;
 
/trunk/OpenConcerto/src/org/openconcerto/xml/Validator.java
13,14 → 13,25
package org.openconcerto.xml;
 
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ExceptionUtils;
import org.openconcerto.utils.ListMap;
import org.openconcerto.utils.cc.IPredicate;
 
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
 
import javax.xml.validation.Schema;
 
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
28,16 → 39,46
public abstract class Validator {
 
private final Document doc;
private final XMLOutputter outputter;
 
protected Validator(Document doc) {
protected Validator(final Document doc, final IPredicate<Object> foreignPredicate) {
super();
this.doc = doc;
this.outputter = new XMLOutputter(Format.getRawFormat()) {
@Override
protected void printElement(Writer out, Element element, int level, NamespaceStack namespaces) throws IOException {
if (foreignPredicate == null || !foreignPredicate.evaluateChecked(element))
super.printElement(out, element, level, namespaces);
}
 
@SuppressWarnings("unchecked")
@Override
protected void printAttributes(Writer out, @SuppressWarnings("rawtypes") List attributes, Element parent, NamespaceStack namespaces) throws IOException {
final List<Attribute> l;
if (foreignPredicate == null) {
l = attributes;
} else {
final int stop = attributes.size();
l = new ArrayList<Attribute>(stop);
for (int i = 0; i < stop; i++) {
final Attribute attr = (Attribute) attributes.get(i);
if (!foreignPredicate.evaluateChecked(attr))
l.add(attr);
}
}
super.printAttributes(out, l, parent, namespaces);
}
};
}
 
protected final Document getDoc() {
return this.doc;
}
 
protected final String getDocToValidate() {
return this.outputter.outputString(this.getDoc());
}
 
/**
* Validate a document, stopping at the first problem.
*
52,7 → 93,7
* @return all problems (with line number) indexed by type, e.g. ERROR unexpected attribute
* "style:join-border" => [on line 22:50, on line 14901:290].
*/
public abstract CollectionMap<String, String> validateCompletely();
public abstract Map<String, List<String>> validateCompletely();
 
static public final class JAXPValidator extends Validator {
 
62,16 → 103,18
* Validate a document using JAXP.
*
* @param doc the document to validate
* @param foreignPredicate <code>null</code> if <code>doc</code> should be validated as is,
* otherwise content matching it will not be validated.
* @param schema the schema.
*/
public JAXPValidator(final Document doc, final Schema schema) {
super(doc);
public JAXPValidator(final Document doc, final IPredicate<Object> foreignPredicate, final Schema schema) {
super(doc, foreignPredicate);
this.schema = schema;
}
 
@Override
public String isValid() {
final SAXException exn = JDOMUtils.validate(getDoc(), this.schema, null);
final SAXException exn = JDOMUtils.validate(getDocToValidate(), this.schema, null);
if (exn == null)
return null;
else if (exn instanceof SAXParseException)
81,9 → 124,9
}
 
@Override
public CollectionMap<String, String> validateCompletely() {
public Map<String, List<String>> validateCompletely() {
final RecordingErrorHandler recErrorHandler = new RecordingErrorHandler();
final SAXException exn = JDOMUtils.validate(getDoc(), this.schema, recErrorHandler);
final SAXException exn = JDOMUtils.validate(getDocToValidate(), this.schema, recErrorHandler);
assert exn == null : "Exception thrown despite the error handler";
return recErrorHandler.getMap();
}
94,7 → 137,7
private final SAXBuilder b;
 
public DTDValidator(final Document doc) {
this(doc, new SAXBuilder());
this(doc, null, new SAXBuilder());
}
 
/**
101,10 → 144,12
* Validate a document using its DTD.
*
* @param doc the document to validate
* @param foreignPredicate <code>null</code> if <code>doc</code> should be validated as is,
* otherwise content matching it will not be validated.
* @param b a builder which can resolve doc's DTD.
*/
public DTDValidator(final Document doc, final SAXBuilder b) {
super(doc);
public DTDValidator(final Document doc, final IPredicate<Object> foreignPredicate, final SAXBuilder b) {
super(doc, foreignPredicate);
this.b = b;
}
 
111,7 → 156,7
@Override
public String isValid() {
try {
JDOMUtils.validateDTD(getDoc(), this.b, null);
JDOMUtils.validateDTD(getDocToValidate(), this.b, null);
return null;
} catch (JDOMException e) {
return ExceptionUtils.getStackTrace(e);
119,10 → 164,10
}
 
@Override
public CollectionMap<String, String> validateCompletely() {
public Map<String, List<String>> validateCompletely() {
try {
final RecordingErrorHandler recErrorHandler = new RecordingErrorHandler();
JDOMUtils.validateDTD(getDoc(), this.b, recErrorHandler);
JDOMUtils.validateDTD(getDocToValidate(), this.b, recErrorHandler);
return recErrorHandler.getMap();
} catch (JDOMException e) {
throw new IllegalStateException("Unable to read the document", e);
132,17 → 177,17
}
 
private static final class RecordingErrorHandler implements ErrorHandler {
private final CollectionMap<String, String> res;
private final ListMap<String, String> res;
 
private RecordingErrorHandler() {
this(new CollectionMap<String, String>());
this(new ListMap<String, String>());
}
 
private RecordingErrorHandler(CollectionMap<String, String> res) {
private RecordingErrorHandler(ListMap<String, String> res) {
this.res = res;
}
 
public final CollectionMap<String, String> getMap() {
public final ListMap<String, String> getMap() {
return this.res;
}
 
163,7 → 208,7
 
private void addExn(final String level, SAXParseException e) {
// e.g. ERROR unexpected attribute "style:join-border" => on line 14901:290
this.res.put(level + " " + e.getMessage(), getDesc(e));
this.res.add(level + " " + e.getMessage(), getDesc(e));
}
 
static String getDesc(SAXParseException e) {
/trunk/OpenConcerto/src/org/openconcerto/xml/SimpleXMLPath.java
37,6 → 37,9
*/
public final class SimpleXMLPath<T> {
 
private static final SimpleXMLPath<Attribute> ALL_ATTRIBUTES = allAttributes(null, null);
private static final SimpleXMLPath<Element> ALL_ELEMENTS = allElements(null, null);
 
public static <T> SimpleXMLPath<T> create(final List<Step<?>> steps, final Step<T> lastStep) {
return new SimpleXMLPath<T>(Collections.unmodifiableList(new ArrayList<Step<?>>(steps)), lastStep);
}
54,8 → 57,17
}
 
/**
* Create a path searching for all descendant attributes. The returned instance is immutable.
*
* @return a path searching attributes in all {@link Axis#descendantOrSelf} elements.
*/
public static SimpleXMLPath<Attribute> allAttributes() {
return ALL_ATTRIBUTES;
}
 
/**
* Create a path searching for all descendant attributes with the passed name and namespace.
* I.e. in XPath this would be ".//@ns:name".
* I.e. in XPath this would be ".//@ns:name". The returned instance is immutable.
*
* @param name the name of attributes.
* @param ns the namespace of attributes.
66,8 → 78,17
}
 
/**
* Create a path searching for all descendant elements. The returned instance is immutable.
*
* @return a path searching all {@link Axis#descendantOrSelf} elements.
*/
public static SimpleXMLPath<Element> allElements() {
return ALL_ELEMENTS;
}
 
/**
* Create a path searching for all descendant elements with the passed name and namespace. I.e.
* in XPath this would be ".//ns:name".
* in XPath this would be ".//ns:name". The returned instance is immutable.
*
* @param name the name of elements.
* @param ns the namespace of elements.
/trunk/OpenConcerto/src/org/openconcerto/xml/JDOMUtils.java
13,12 → 13,12
package org.openconcerto.xml;
 
import org.openconcerto.utils.StringUtils;
import org.openconcerto.utils.cc.IPredicate;
 
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
209,6 → 209,20
}
 
/**
* Detach the passed element, and if its parent becomes empty, detach it too.
*
* @param elem the element to detach.
* @return the parent.
*/
public static Element detachEmptyParent(final Element elem) {
final Element parent = elem.getParentElement();
elem.detach();
if (parent != null && parent.getChildren().isEmpty())
parent.detach();
return parent;
}
 
/**
* Get the requested child of <code>parent</code> or create one if necessary. The created child
* is {@link Element#addContent(Content) added at the end}.
*
429,14 → 443,32
};
}
 
/**
* The namespace for the passed content.
*
* @param input any JDOM document content.
* @return <code>null</code> if the passed object cannot have a namespace,
* {@link Namespace#NO_NAMESPACE} if it could have one but has none.
*/
static public final Namespace getNamespace(Object input) {
final Namespace res;
if (input instanceof Element) {
res = ((Element) input).getNamespace();
} else if (input instanceof Attribute) {
res = ((Attribute) input).getNamespace();
} else {
res = null;
}
return res;
}
 
// @return SAXException If a SAX error occurs during parsing of doc.
static SAXException validate(final Document doc, final Schema schema, final ErrorHandler errorHandler) {
ByteArrayInputStream ins;
try {
ins = new ByteArrayInputStream(output(doc).getBytes("UTF8"));
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("unicode not found ", e);
return validate(output(doc), schema, errorHandler);
}
 
static SAXException validate(final String doc, final Schema schema, final ErrorHandler errorHandler) {
final ByteArrayInputStream ins = new ByteArrayInputStream(doc.getBytes(StringUtils.UTF8));
final Validator validator = schema.newValidator();
// ATTN workaround : contrary to documentation setting to null swallow exceptions
if (errorHandler != null)
454,12 → 486,16
}
 
static void validateDTD(final Document doc, final SAXBuilder b, final ErrorHandler errorHandler) throws JDOMException {
validateDTD(output(doc), b, errorHandler);
}
 
static void validateDTD(final String doc, final SAXBuilder b, final ErrorHandler errorHandler) throws JDOMException {
final ErrorHandler origEH = b.getErrorHandler();
final boolean origValidation = b.getValidation();
try {
b.setErrorHandler(errorHandler);
b.setValidation(true);
JDOMUtils.parseStringDocument(output(doc), b);
JDOMUtils.parseStringDocument(doc, b);
} finally {
b.setErrorHandler(origEH);
b.setValidation(origValidation);
/trunk/OpenConcerto/src/org/openconcerto/xml/JDOM2Utils.java
New file
0,0 → 1,318
/*
* 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.xml;
 
import org.openconcerto.utils.cc.IPredicate;
 
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;
 
import javax.xml.validation.SchemaFactory;
 
import org.jdom2.Attribute;
import org.jdom2.Content;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.Text;
import org.jdom2.filter.AbstractFilter;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
import org.jdom2.output.Format;
import org.jdom2.output.LineSeparator;
import org.jdom2.output.XMLOutputter;
 
/**
* @author Sylvain
*/
public final class JDOM2Utils {
 
public static final XMLOutputter OUTPUTTER;
private static final SAXBuilder BUILDER;
static {
final Format rawFormat = Format.getRawFormat();
// JDOM defaults to \r\n but \n is shorter and faster (internally used, see LineSeparator
// class comment)
rawFormat.setLineSeparator(LineSeparator.NL);
OUTPUTTER = new XMLOutputter(rawFormat);
 
BUILDER = new SAXBuilder();
BUILDER.setXMLReaderFactory(XMLReaders.NONVALIDATING);
}
 
/**
* Try to set the platform default for {@link SchemaFactory}. {@link SAXBuilder} constructor
* initialize {@link org.jdom2.input.sax.XMLReaders} which calls
* {@link SchemaFactory#newInstance(String)} (this makes JDOM2 a little less fast than JDOM1 on
* the 1st builder creation : about 60ms vs 15ms). The problem is that if xerces.jar is
* referenced in the class path, it specifies org.apache.xerces.jaxp.validation.XMLSchemaFactory
* which is really slow (~700ms to initialize). Alternatively one can create
* <code>META-INF/services/javax.xml.validation.SchemaFactory</code>.
*
* @throws ClassNotFoundException if the platform default cannot be set.
*/
public static void forcePlatformDefaultSchemaFactory() throws ClassNotFoundException {
final String platformClassName = "com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory";
if (Class.forName(platformClassName) != null)
System.setProperty("javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema", platformClassName);
}
 
/**
* Analyse la chaine passée et retourne l'Element correspondant.
*
* @param xml une chaine contenant un élément XML.
* @param namespaces les namespaces utilisés dans la chaine.
* @return l'Element correspondant à la chaine passée.
* @throws JDOMException si l'xml n'est pas bien formé.
*/
public static Element parseElementString(String xml, Namespace[] namespaces) throws JDOMException {
// l'element passé est le seul enfant de dummy
// to be sure that the 0th can be cast use trim(), otherwise we might get a org.jdom2.Text
return (Element) parseString(xml.trim(), namespaces).get(0);
}
 
/**
* Analyse la chaine passée et retourne la liste correspondante.
*
* @param xml une chaine contenant de l'XML.
* @param namespaces les namespaces utilisés dans la chaine.
* @return la liste correspondant à la chaine passée.
* @throws JDOMException si l'xml n'est pas bien formé.
*/
public static List<Content> parseString(String xml, Namespace[] namespaces) throws JDOMException {
// construit le dummy pour déclarer les namespaces
String dummy = "<dummy";
for (int i = 0; i < namespaces.length; i++) {
Namespace ns = namespaces[i];
dummy += " xmlns:" + ns.getPrefix() + "=\"" + ns.getURI() + "\"";
}
xml = dummy + ">" + xml + "</dummy>";
 
return parseStringDocument(xml).getRootElement().removeContent();
}
 
/**
* Analyse la chaine passée et retourne l'Element correspondant.
*
* @param xml une chaine contenant de l'XML.
* @return l'Element correspondant à la chaine passée.
* @throws JDOMException si l'xml n'est pas bien formé.
* @see #parseElementString(String, Namespace[])
*/
public static Element parseString(String xml) throws JDOMException {
return parseElementString(xml, new Namespace[0]);
}
 
/**
* Analyse la chaine passée avec un builder par défaut et retourne le Document correspondant.
*
* @param xml une chaine représentant un document XML.
* @return le document correspondant.
* @throws JDOMException si l'xml n'est pas bien formé.
* @see #parseStringDocument(String, SAXBuilder)
*/
public static synchronized Document parseStringDocument(String xml) throws JDOMException {
// BUILDER is not thread safe
return parseStringDocument(xml, BUILDER);
}
 
/**
* Analyse la chaine passée et retourne le Document correspondant.
*
* @param xml une chaine représentant un document XML.
* @param builder le builder à utiliser.
* @return le document correspondant.
* @throws JDOMException si l'xml n'est pas bien formé.
*/
public static Document parseStringDocument(String xml, SAXBuilder builder) throws JDOMException {
Document doc = null;
try {
doc = builder.build(new StringReader(xml));
} catch (IOException e) {
// peut pas arriver, lis depuis une String
e.printStackTrace();
}
return doc;
}
 
/**
* Ecrit l'XML en chaine, contrairement a toString().
*
* @param xml l'élément à écrire.
* @return l'XML en tant que chaine.
*/
public static String output(Element xml) {
return OUTPUTTER.outputString(xml);
}
 
/**
* Ecrit l'XML en chaine, contrairement a toString().
*
* @param xml l'élément à écrire.
* @return l'XML en tant que chaine.
*/
public static String output(Document xml) {
return OUTPUTTER.outputString(xml);
}
 
/**
* Test if two elements have the same namespace and name.
*
* @param elem1 an element, can be <code>null</code>.
* @param elem2 an element, can be <code>null</code>.
* @return <code>true</code> if both elements have the same name and namespace, or if both are
* <code>null</code>.
*/
public static boolean equals(Element elem1, Element elem2) {
if (elem1 == elem2 || elem1 == null && elem2 == null)
return true;
else if (elem1 == null || elem2 == null)
return false;
else
return elem1.getName().equals(elem2.getName()) && elem1.getNamespace().equals(elem2.getNamespace());
}
 
/**
* Compare two elements and their descendants (only Element and Text). Texts are merged and
* normalized.
*
* @param elem1 first element.
* @param elem2 second element.
* @return <code>true</code> if both elements are equal.
* @see #getContent(Element, IPredicate, boolean)
*/
public static boolean equalsDeep(Element elem1, Element elem2) {
return equalsDeep(elem1, elem2, true);
}
 
public static boolean equalsDeep(Element elem1, Element elem2, final boolean normalizeText) {
return getDiff(elem1, elem2, normalizeText) == null;
}
 
static String getDiff(Element elem1, Element elem2, final boolean normalizeText) {
if (elem1 == elem2)
return null;
if (!equals(elem1, elem2))
return "element name or namespace";
 
// ignore attributes order
final List<Attribute> attr1 = elem1.getAttributes();
final List<Attribute> attr2 = elem2.getAttributes();
if (attr1.size() != attr2.size())
return "attributes count";
for (final Attribute attr : attr1) {
if (!attr.getValue().equals(elem2.getAttributeValue(attr.getName(), attr.getNamespace())))
return "attribute value";
}
 
// use content order
final IPredicate<Content> filter = new IPredicate<Content>() {
@Override
public boolean evaluateChecked(Content input) {
return input instanceof Text || input instanceof Element;
}
};
// only check Element and Text (also merge them)
final Iterator<Content> contents1 = getContent(elem1, filter, true);
final Iterator<Content> contents2 = getContent(elem2, filter, true);
while (contents1.hasNext() && contents2.hasNext()) {
final Content content1 = contents1.next();
final Content content2 = contents2.next();
if (content1.getClass() != content2.getClass())
return "content";
if (content1 instanceof Text) {
final String s1 = normalizeText ? ((Text) content1).getTextNormalize() : content1.getValue();
final String s2 = normalizeText ? ((Text) content2).getTextNormalize() : content2.getValue();
if (!s1.equals(s2))
return "text";
} else {
final String rec = getDiff((Element) content1, (Element) content2, normalizeText);
if (rec != null)
return rec;
}
}
if (contents1.hasNext() || contents2.hasNext())
return "content size";
 
return null;
}
 
/**
* Get the filtered content of an element, optionnaly merging adjacent {@link Text}. Adjacent
* text can only happen programmatically.
*
* @param elem the parent.
* @param pred which content to return.
* @param mergeText <code>true</code> if adjacent Text should be merged into one,
* <code>false</code> to leave the list as it is.
* @return the filtered content (not supportting {@link Iterator#remove()}).
*/
public static Iterator<Content> getContent(final Element elem, final IPredicate<? super Content> pred, final boolean mergeText) {
final Iterator<Content> iter = (Iterator<Content>) elem.getContent(new AbstractFilter<Content>() {
@Override
public Content filter(Object obj) {
final Content c = (Content) obj;
return pred.evaluateChecked(c) ? c : null;
}
}).iterator();
if (!mergeText)
return iter;
 
return new Iterator<Content>() {
 
private Content next = null;
 
@Override
public boolean hasNext() {
return this.next != null || iter.hasNext();
}
 
@Override
public Content next() {
if (this.next != null) {
final Content res = this.next;
this.next = null;
return res;
}
 
Content res = iter.next();
assert res != null;
if (res instanceof Text && iter.hasNext()) {
this.next = iter.next();
Text concatText = null;
while (this.next instanceof Text) {
if (concatText == null) {
concatText = new Text(res.getValue());
}
concatText.append((Text) this.next);
this.next = iter.hasNext() ? iter.next() : null;
}
assert this.next != null;
if (concatText != null)
res = concatText;
}
 
return res;
}
 
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/graph/GraphMargePanel.java
151,6 → 151,7
return axisX.getLabels().get(dayChart.getHighlight().getIndexOnModel()).getLabel() + " " + combo.getSelectedItem() + " " + m.getYear() + ": " + n.longValue() + " €";
}
};
panel.setBackground(Color.WHITE);
GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.NONE;
JPanel p2 = new JPanel(new FlowLayout());
/trunk/OpenConcerto/src/org/openconcerto/erp/graph/GraphSamplePDF.java
New file
0,0 → 1,881
/*
* 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.graph;
 
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import org.jopenchart.Axis;
import org.jopenchart.AxisLabel;
import org.jopenchart.DataModel1D;
import org.jopenchart.DataModel2D;
import org.jopenchart.DataModelMultiple;
import org.jopenchart.DataModelPoint;
import org.jopenchart.Label;
import org.jopenchart.barchart.VerticalBarChart;
import org.jopenchart.barchart.VerticalGroupBarChart;
import org.jopenchart.barchart.VerticalStackBarChart;
import org.jopenchart.gauge.AngularGauge;
import org.jopenchart.linechart.LineChart;
import org.jopenchart.piechart.PieChart;
import org.jopenchart.piechart.PieChartWithSeparatedLabels;
import org.jopenchart.scatterplot.PointChart;
import org.jopenchart.table.SimpleTable;
 
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
 
public class GraphSamplePDF {
 
/**
* @param args
* @throws DocumentException
* @throws IOException
*/
public static void main(String[] args) throws DocumentException, IOException {
 
// ChartPanel panel = new ChartPanel(c);
FileOutputStream baos = new FileOutputStream(new File("OpenConcerto_Chart.pdf"));
Document document = new Document(PageSize.A4);
// PdfWriter writer = new PdfWriter(document, baos);
 
PdfWriter writer = PdfWriter.getInstance(document, baos);
 
document.open();
PdfContentByte cb = writer.getDirectContent();
System.out.println(document.getPageSize());
createPage1(document, cb);
 
document.newPage();
createPage2(document, cb);
document.close();
baos.close();
}
 
private static void createPage1(Document document, PdfContentByte cb) {
Graphics2D graphics2D = cb.createGraphics(document.getPageSize().getWidth(), document.getPageSize().getHeight());
int w = 180;
int h = 200;
int y = 140;
Font font = new Font("Arial", Font.PLAIN, 12);
graphics2D.setFont(font);
int xLogo = 30;
// AngularGauge c = new AngularGauge();
// c.setMinValue(0);
// c.setMaxValue(100);
// c.setValue(30);
// c.setChartRectangle(new Rectangle(0, 100, 150, 150));
// c.render(graphics2D);
 
//
int cX = xLogo;
int cY = y + 30;
// Line 1
table1(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "a) Classique");
cX += w;
 
table2(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "b) Design");
cX += w;
table3(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "c) Maximum par colonne");
// Line 2
cY += h;
cX = xLogo;
line1(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "a) Courbe simple");
cX += w;
 
line2(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "b) Lignes multiples");
cX += w;
line3(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "c) Quantitatif");
 
// Line 3
cY += h;
cX = xLogo;
piechart1(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "a) Simple");
cX += w;
 
piechart2(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "b) Anneau");
cX += w;
piechart3(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "c) Complet avec légende");
// Logo
 
graphics2D.setFont(new Font("Arial", Font.PLAIN, 24));
graphics2D.setColor(new Color(66, 119, 167));
 
graphics2D.drawString("Open", xLogo, 48);
graphics2D.setColor(new Color(178, 81, 81));
graphics2D.drawString("Concerto", xLogo + 59, 48);
graphics2D.setColor(Color.BLACK);
 
// Main title and copyright
drawCopyrightAndFooter(graphics2D, xLogo, 1);
 
// Titles
graphics2D.setFont(graphics2D.getFont().deriveFont(12f));
graphics2D.setFont(graphics2D.getFont().deriveFont(Font.BOLD));
graphics2D.drawString("Tableaux", xLogo, y);
y += h;
graphics2D.drawString("Graphiques", xLogo, y);
y += h;
graphics2D.drawString("Diagrammes circulaires", xLogo, y);
graphics2D.dispose();
}
 
private static void createPage2(Document document, PdfContentByte cb) {
Graphics2D graphics2D = cb.createGraphics(document.getPageSize().getWidth(), document.getPageSize().getHeight());
int w = 180;
int h = 200;
int y = 140;
Font font = new Font("Arial", Font.PLAIN, 12);
graphics2D.setFont(font);
int xLogo = 30;
 
//
int cX = xLogo;
int cY = y + 30;
// Line 1
barchart1(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "a) Simple");
cX += w;
 
barchart2(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "b) Groupé");
cX += w;
barchart3(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "c) Empillé");
// Line 2
cY += h;
cX = xLogo;
gauge1(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "a) Valeur");
cX += w;
 
gauge2(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "b) Pourcentage");
cX += w;
gauge3(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "c) Qualitatif");
 
// Line 3
cY += h;
cX = xLogo;
cloud1(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "a) Points");
cX += w;
 
cloud2(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "b) Bulles");
cX += w;
cloud3(graphics2D, cX, cY);
legend(graphics2D, cX, cY, "c) Zones");
// Logo
 
graphics2D.setFont(new Font("Arial", Font.PLAIN, 24));
graphics2D.setColor(new Color(66, 119, 167));
 
graphics2D.drawString("Open", xLogo, 48);
graphics2D.setColor(new Color(178, 81, 81));
graphics2D.drawString("Concerto", xLogo + 59, 48);
graphics2D.setColor(Color.BLACK);
 
drawCopyrightAndFooter(graphics2D, xLogo, 2);
// Titles
graphics2D.setFont(graphics2D.getFont().deriveFont(12f));
graphics2D.setFont(graphics2D.getFont().deriveFont(Font.BOLD));
graphics2D.drawString("Diagrammes en bâtons", xLogo, y);
y += h;
graphics2D.drawString("Jauge", xLogo, y);
y += h;
graphics2D.drawString("Nuages", xLogo, y);
graphics2D.dispose();
}
 
public static void drawCopyrightAndFooter(Graphics2D graphics2D, int xLogo, int page) {
// Main title and copyright
graphics2D.setFont(graphics2D.getFont().deriveFont(16f));
graphics2D.drawString("Exemples de représentation de données", xLogo, 90);
graphics2D.setColor(Color.BLACK);
graphics2D.setFont(graphics2D.getFont().deriveFont(6f));
graphics2D.drawString("© ILM Informatique. Tous droits réservés. OpenConcerto est une marque déposée.", 30, 810);
graphics2D.setFont(graphics2D.getFont().deriveFont(10f));
graphics2D.drawString("Page " + page + " / 2", 500, 810);
}
 
private static void legend(Graphics2D graphics2D, int cX, int cY, String string) {
Font font = new Font("Arial", Font.ITALIC, 8);
graphics2D.setColor(Color.BLACK);
graphics2D.setFont(font);
graphics2D.drawString(string, cX, cY - 10);
 
}
 
private static void piechart1(Graphics2D graphics2D, int cX, int cY) {
PieChart c = new PieChart();
List<Color> colors = new ArrayList<Color>();
colors.add(new Color(178, 81, 81));
colors.add(new Color(66, 119, 167));
 
c.setColors(colors);
c.addLabel(new Label("PME"));
c.addLabel(new Label("Grands comptes"));
c.addLabel(new Label("TPE"));
 
c.setDimension(new Dimension(160, 120));
 
ArrayList<Number> l = new ArrayList<Number>();
l.add(50);
l.add(20);
l.add(10);
c.setData(l);
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void piechart3(Graphics2D graphics2D, int cX, int cY) {
PieChart c = new PieChartWithSeparatedLabels();
 
c.addLabel(new Label("Open"));
c.addLabel(new Label("Concerto"));
c.addLabel(new Label("GPL"));
 
c.setDimension(new Dimension(90, 80));
 
ArrayList<Number> l = new ArrayList<Number>();
l.add(60);
l.add(50);
l.add(20);
 
c.setData(l);
 
c.setInnerColor(Color.BLACK);
c.setInnerDimension(2, 2);
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void piechart2(Graphics2D graphics2D, int cX, int cY) {
PieChart c = new PieChartWithSeparatedLabels();
 
c.addLabel(new Label("V1"));
c.addLabel(new Label("V2"));
c.addLabel(new Label("V3"));
c.addLabel(new Label("V4"));
c.addLabel(new Label("V5"));
c.addLabel(new Label("V6"));
c.addLabel(new Label("V7"));
c.addLabel(new Label("V8"));
c.addLabel(new Label("V9"));
c.addLabel(new Label("V10"));
c.setDimension(new Dimension(130, 160));
 
ArrayList<Number> l = new ArrayList<Number>();
l.add(60);
l.add(50);
l.add(20);
l.add(20);
l.add(30);
l.add(20);
l.add(20);
l.add(40);
l.add(20);
l.add(20);
l.add(20);
c.setData(l);
 
c.setInnerColor(Color.BLACK);
c.setInnerDimension(40, 40);
 
List<Color> colors = new ArrayList<Color>();
// colors.add(new Color(178, 81, 81));
colors.add(new Color(66, 119, 167));
 
c.setColors(colors);
 
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void line1(Graphics2D graphics2D, int cX, int cY) {
LineChart chart = new LineChart();
 
chart.setLowerRange(0);
chart.setHigherRange(150);
 
List<Number> data = new ArrayList<Number>();
data.add(15);
data.add(5);
data.add(20);
data.add(50);
data.add(60);
data.add(90);
data.add(95);
data.add(60);
data.add(83);
data.add(102);
data.add(123);
data.add(143);
chart.setData(data);
final Axis axis = new Axis("CA");
axis.addLabel(new AxisLabel("0", 0));
axis.addLabel(new AxisLabel("50 000", 50));
axis.addLabel(new AxisLabel("100 000", 100));
axis.setLabelVisible(true);
chart.setLeftAxis(axis);
 
final Axis axis2 = new Axis("CA");
axis2.addLabel(new AxisLabel("0%", 0));
axis2.addLabel(new AxisLabel("50%", 6));
axis2.addLabel(new AxisLabel("100%", 11));
axis2.setLabelVisible(true);
axis2.setMarkerLenght(4);
axis.setMarkerLenght(4);
chart.setGridXStep(50D);
chart.setBottomAxis(axis2);
 
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void line2(Graphics2D graphics2D, int cX, int cY) {
LineChart chart = new LineChart();
 
List<Color> colors = new ArrayList<Color>();
colors.add(new Color(66, 119, 167));
colors.add(new Color(178, 81, 81));
chart.setColors(colors);
chart.setLowerRange(0);
chart.setHigherRange(150);
 
final List<Number> data = new ArrayList<Number>();
data.add(3);
data.add(5);
data.add(20);
data.add(50);
data.add(60);
data.add(90);
data.add(95);
data.add(60);
data.add(83);
data.add(102);
data.add(133);
data.add(143);
final List<Number> data2 = new ArrayList<Number>();
data2.add(24);
data2.add(8);
data2.add(10);
data2.add(60);
data2.add(100);
data2.add(120);
data2.add(130);
data2.add(80);
data2.add(90);
data2.add(50);
data2.add(30);
data2.add(40);
final List<List<Number>> multipleData = new ArrayList<List<Number>>();
multipleData.add(data2);
multipleData.add(data);
 
chart.setDataModel(new DataModelMultiple(multipleData));
 
final Axis axis = new Axis("CA");
axis.addLabel(new AxisLabel("", 0));
axis.addLabel(new AxisLabel("5", 25));
axis.addLabel(new AxisLabel("10", 50));
axis.addLabel(new AxisLabel("15", 75));
axis.addLabel(new AxisLabel("20", 100));
 
axis.setLabelVisible(true);
chart.setLeftAxis(axis);
 
final Axis axis2 = new Axis("CA");
axis2.addLabel(new AxisLabel("2010", 0));
axis2.addLabel(new AxisLabel("2011", 6));
axis2.addLabel(new AxisLabel("2012", 11));
axis2.setLabelVisible(true);
axis2.setMarkerLenght(4);
 
chart.setBottomAxis(axis2);
 
// chart.setChartRectangle(new Rectangle(0, 100, 150, 150));
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void line3(Graphics2D graphics2D, int cX, int cY) {
LineChart chart = new LineChart();
 
chart.setLowerRange(-150);
chart.setHigherRange(150);
List<Color> colors = new ArrayList<Color>();
colors.add(new Color(178, 81, 81));
colors.add(new Color(66, 119, 167));
 
chart.setColors(colors);
chart.setFillColor(new Color(178, 81, 81));
 
chart.setGridYStep(15.0D);
 
List<Number> data = new ArrayList<Number>();
data.add(0);
data.add(5);
data.add(20);
data.add(50);
data.add(60);
data.add(90);
data.add(95);
data.add(60);
data.add(83);
data.add(105);
data.add(60);
data.add(45);
chart.setData(data);
final Axis axis = new Axis("CA");
axis.addLabel(new AxisLabel("0", 0));
axis.addLabel(new AxisLabel("7 kg", 150));
axis.addLabel(new AxisLabel("3 kg", 64));
final AxisLabel label = new AxisLabel("6 kg", 128);
label.setColor(new Color(178, 81, 81));
axis.addLabel(label);
 
axis.setLabelVisible(true);
chart.setLeftAxis(axis);
 
final Axis axis2 = new Axis("CA");
 
axis2.setMarkerLenght(4);
axis2.setLabelVisible(true);
axis2.addLabel(new AxisLabel("Mars", 0));
axis2.addLabel(new AxisLabel("Avril", 6));
axis2.addLabel(new AxisLabel("Mai", 11));
 
chart.setBottomAxis(axis2);
 
// chart.setChartRectangle(new Rectangle(0, 100, 150, 150));
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void table1(Graphics2D graphics2D, int cX, int cY) {
SimpleTable chart = new SimpleTable(new DataModel2D(4, 3));
 
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void table2(Graphics2D graphics2D, int cX, int cY) {
SimpleTable chart = new SimpleTable(new DataModel2D(4, 3));
chart.setGridColor(null);
chart.setLabelColorBackground(null);
Color col = new Color(232, 242, 254);
for (int i = 0; i < 3; i++) {
chart.setBackgoundColor(col, 0, i);
chart.setBackgoundColor(col, 2, i);
}
 
chart.setDimension(new Dimension(160, 110));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void table3(Graphics2D graphics2D, int cX, int cY) {
SimpleTable chart = new SimpleTable(new DataModel2D(6, 3));
chart.setGridColor(Color.WHITE);
chart.setLabelColorBackground(new Color(154, 12, 81));
chart.setLabelColorText(Color.white);
chart.setBackgoundColor(Color.ORANGE, 2, 0);
chart.setForegoundColor(Color.WHITE, 2, 0);
chart.setBackgoundColor(Color.ORANGE, 2, 2);
chart.setForegoundColor(Color.WHITE, 2, 2);
chart.setBackgoundColor(Color.ORANGE, 5, 1);
chart.setForegoundColor(Color.WHITE, 5, 1);
 
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void barchart1(Graphics2D graphics2D, int cX, int cY) {
VerticalBarChart c = new VerticalBarChart();
c.setColor(new Color(0, 155, 100));
// c.setBackgroundRenderer(new SolidAreaRenderer(Color.pink));
Axis axis = new Axis("y");
axis.addLabel(new AxisLabel("0"));
axis.addLabel(new AxisLabel("500 €"));
axis.addLabel(new AxisLabel("1000 €"));
c.setLeftAxis(axis);
 
Axis axisX = new Axis("x");
axisX.addLabel(new AxisLabel("J", 1));
axisX.addLabel(new AxisLabel("F", 2));
axisX.addLabel(new AxisLabel("M", 3));
axisX.addLabel(new AxisLabel("A", 4));
axisX.addLabel(new AxisLabel("M", 5));
axisX.addLabel(new AxisLabel("J", 6));
axisX.addLabel(new AxisLabel("J", 7));
axisX.addLabel(new AxisLabel("A", 8));
axisX.addLabel(new AxisLabel("S", 9));
axisX.addLabel(new AxisLabel("O", 10));
axisX.addLabel(new AxisLabel("N", 11));
axisX.addLabel(new AxisLabel("D", 12));
c.setBottomAxis(axisX);
c.setBarWidth(8);
c.setSpaceBetweenBars(3);
c.addModel(new DataModel1D(new Float[] { 5f, 10f, 50f, 30f, 200f, 20f, 30f, 120f, 180f, 70f, 10f, 120f }));
 
c.setDimension(new Dimension(160, 140));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void barchart2(Graphics2D graphics2D, int cX, int cY) {
VerticalGroupBarChart c = new VerticalGroupBarChart();
List<Color> colors = new ArrayList<Color>();
colors.add(Color.decode("#4A79A5"));
colors.add(Color.decode("#639ACE"));
colors.add(Color.decode("#94BAE7"));
c.setColors(colors);
 
Axis axis = new Axis("y");
axis.addLabel(new AxisLabel("0"));
axis.addLabel(new AxisLabel("100"));
axis.addLabel(new AxisLabel("200"));
c.setLeftAxis(axis);
 
Axis axisX = new Axis("x");
axisX.addLabel(new AxisLabel("Janvier", 1));
axisX.addLabel(new AxisLabel("Février", 2));
axisX.addLabel(new AxisLabel("Mars", 3));
 
c.setBottomAxis(axisX);
 
c.setBarWidth(8);
c.addModel(new DataModel1D(new Float[] { 5f, 10f, 50f }));
c.addModel(new DataModel1D(new Float[] { 20f, 90f, 55f }));
c.addModel(new DataModel1D(new Float[] { 28f, 9f, 60f }));
 
c.setDimension(new Dimension(160, 140));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void barchart3(Graphics2D graphics2D, int cX, int cY) {
VerticalStackBarChart c = new VerticalStackBarChart();
c.setColor(new Color(0, 155, 100));
// c.setBackgroundRenderer(new SolidAreaRenderer(Color.pink));
Axis axis = new Axis("y");
axis.addLabel(new AxisLabel("0 %"));
axis.addLabel(new AxisLabel("100 %"));
axis.addLabel(new AxisLabel("200 %"));
c.setLeftAxis(axis);
 
c.addModel(new DataModel1D(new Float[] { 5f, 10f, 50f, 30f, 190f, 20f, 30f }));
c.addModel(new DataModel1D(new Float[] { 20f, 90f, 50f, 70f, 10f, 180f, 70f }));
 
c.setDimension(new Dimension(160, 125));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void gauge1(Graphics2D graphics2D, int cX, int cY) {
AngularGauge c = new AngularGauge();
c.setMinValue(0);
c.setMaxValue(800);
c.setValue(324);
c.setChartRectangle(new Rectangle(0, 0, 140, 140));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 38);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void gauge2(Graphics2D graphics2D, int cX, int cY) {
AngularGauge c = new AngularGauge() {
@Override
public String getTextValue() {
return super.getTextValue() + "%";
}
};
c.setMinValue(0);
c.setMaxValue(100);
c.setValue(80);
 
c.setColor(new Color(44, 120, 126));
c.setChartRectangle(new Rectangle(0, 0, 140, 140));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 34);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void gauge3(Graphics2D graphics2D, int cX, int cY) {
AngularGauge c = new AngularGauge() {
@Override
public String getTextValue() {
return "Hausse";
}
};
c.setMinValue(0);
c.setMaxValue(100);
c.setValue(68);
c.setBackgroundValueColor(null);
c.setColor(new Color(66, 119, 167));
c.setChartRectangle(new Rectangle(0, 0, 140, 140));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 24);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
c.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void cloud1(Graphics2D graphics2D, int cX, int cY) {
PointChart chart = new PointChart(new DataModelPoint(15));
 
chart.setLowerRange(0);
chart.setHigherRange(150);
 
final Axis axis = new Axis("CA");
axis.addLabel(new AxisLabel("0", 0));
axis.addLabel(new AxisLabel("50 000", 50));
axis.addLabel(new AxisLabel("100 000", 100));
axis.setLabelVisible(true);
chart.setLeftAxis(axis);
 
final Axis axis2 = new Axis("CA");
axis2.addLabel(new AxisLabel("0%", 0));
axis2.addLabel(new AxisLabel("50%", 5.5));
axis2.addLabel(new AxisLabel("100%", 11));
axis2.setLabelVisible(true);
axis2.setMarkerLenght(4);
axis.setMarkerLenght(4);
chart.setGridXStep(50D);
chart.setBottomAxis(axis2);
 
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void cloud2(Graphics2D graphics2D, int cX, int cY) {
PointChart chart = new PointChart(new DataModelPoint(6));
 
chart.setLowerRange(0);
chart.setHigherRange(150);
 
final Axis axis = new Axis("CA");
axis.addLabel(new AxisLabel("0", 0));
axis.addLabel(new AxisLabel("100", 50));
axis.addLabel(new AxisLabel("200", 100));
axis.setLabelVisible(true);
axis.setMarkerLenght(4);
chart.setLeftAxis(axis);
 
final Axis axis2 = new Axis("CA");
axis2.addLabel(new AxisLabel("0", 0));
axis2.addLabel(new AxisLabel("50%", 6));
axis2.addLabel(new AxisLabel("100%", 11));
axis2.setLabelVisible(true);
axis2.setMarkerLenght(4);
chart.setBottomAxis(axis2);
chart.setPointSize(20);
chart.setColor(new Color(66, 119, 167));
chart.setType(PointChart.TYPE_CIRCLE);
 
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
private static void cloud3(Graphics2D graphics2D, int cX, int cY) {
PointChart chart = new PointChart(new DataModelPoint(7));
 
chart.setLowerRange(0);
chart.setHigherRange(150);
 
final Axis axis = new Axis("CA");
axis.addLabel(new AxisLabel("0", 0));
axis.addLabel(new AxisLabel("1", 50));
axis.addLabel(new AxisLabel("2", 100));
axis.setLabelVisible(true);
axis.setMarkerLenght(4);
chart.setLeftAxis(axis);
 
final Axis axis2 = new Axis("CA");
axis2.addLabel(new AxisLabel("2012", 0));
axis2.addLabel(new AxisLabel("2013", 6));
axis2.addLabel(new AxisLabel("2014", 11));
axis2.setLabelVisible(true);
axis2.setMarkerLenght(4);
chart.setBottomAxis(axis2);
chart.setPointSize(40);
 
chart.setColor(new Color(66, 119, 167, 125));
chart.addColor(new Color(66, 119, 167, 125));
chart.addColor(new Color(66, 119, 167, 125));
chart.addColor(new Color(66, 119, 167, 125));
chart.addColor(new Color(66, 119, 167, 125));
chart.addColor(new Color(66, 119, 167, 125));
chart.addColor(new Color(66, 119, 167, 125));
chart.addColor(new Color(66, 119, 167, 125));
chart.setType(PointChart.TYPE_PLAIN);
 
chart.setDimension(new Dimension(160, 130));
AffineTransform saveAT = graphics2D.getTransform();
Font font = new Font("Arial", Font.PLAIN, 10);
 
graphics2D.setFont(font);
graphics2D.transform(AffineTransform.getTranslateInstance(cX, cY));
 
chart.render(graphics2D);
 
graphics2D.setTransform(saveAT);
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/graph/CADataModel.java
29,13 → 29,11
 
public class CADataModel extends DataModel1D {
 
private VerticalBarChart chart;
private Thread thread;
private int year;
private int total;
 
public CADataModel(final VerticalBarChart chart, final int year) {
this.chart = chart;
 
loadYear(year);
}
 
54,6 → 52,7
year = ((Number) value).intValue();
 
thread = new Thread() {
 
@Override
public void run() {
setState(LOADING);
61,6 → 60,7
CADataModel.this.clear();
fireDataModelChanged();
SommeCompte sommeCompte = new SommeCompte();
total = 0;
try {
for (int i = 0; i < 12; i++) {
if (isInterrupted()) {
97,8 → 97,8
vCA = sommeCompte.soldeCompteCrediteur(700, 708, true, d1, d2) - sommeCompte.soldeCompteCrediteur(709, 709, true, d1, d2);
}
 
final float value = vCA / 100;
 
final int value = Math.round(vCA / 100);
total += value;
if (((int) value) != 0) {
CADataModel.this.setValueAt(i, value);
fireDataModelChanged();
128,4 → 128,7
return year;
}
 
public int getTotal() {
return total;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/graph/GraphCAPanel.java
14,6 → 14,7
package org.openconcerto.erp.graph;
 
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.GestionDevise;
 
import java.awt.Color;
42,7 → 43,7
import org.jopenchart.DataModelListener;
import org.jopenchart.barchart.VerticalGroupBarChart;
 
public class GraphCAPanel extends JPanel implements ChangeListener {
public class GraphCAPanel extends JPanel implements ChangeListener, DataModelListener {
private final JSpinner s1 = new JSpinner();
private final JSpinner s2 = new JSpinner();
private final JSpinner s3 = new JSpinner();
50,6 → 51,7
private CADataModel model2;
private CADataModel model3;
private final VerticalGroupBarChart chart = new VerticalGroupBarChart();
private JLabel title = new JLabelBold("-");
 
/**
* Chiffres d'affaires, affichés en barres
59,6 → 61,12
 
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
c.insets = new Insets(4, 6, 4, 4);
this.setBackground(Color.WHITE);
title.setOpaque(false);
this.add(title, c);
c.gridy++;
 
c.insets = new Insets(0, 0, 0, 0);
 
List<Color> colors = new ArrayList<Color>();
116,6 → 124,7
return axisX.getLabels().get(chart.getHighlight().getIndexOnModel()).getLabel() + " " + m.getYear() + ": " + n.longValue() + " €";
}
};
panel.setBackground(Color.WHITE);
this.add(panel, c);
 
c.gridy++;
148,6 → 157,11
s1.addChangeListener(this);
s2.addChangeListener(this);
s3.addChangeListener(this);
 
model1.addDataModelListener(this);
model2.addDataModelListener(this);
model3.addDataModelListener(this);
updateTitle();
}
 
private void addLeftAxisUpdater(final CADataModel model) {
214,4 → 228,25
 
}
}
 
@Override
public void dataChanged() {
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
updateTitle();
 
}
});
 
}
 
protected void updateTitle() {
String s = " ";
s += this.s1.getValue().toString() + " : " + this.model1.getTotal() + " € ";
s += this.s2.getValue().toString() + " : " + this.model2.getTotal() + " € ";
s += this.s3.getValue().toString() + " : " + this.model3.getTotal() + " €";
this.title.setText(s);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/graph/GraphArticleVentePanel.java
46,10 → 46,9
}
 
ChartPanel p = new ChartPanel(chart);
this.setOpaque(true);
p.setOpaque(false);
this.setBackground(Color.WHITE);
this.add(p);
 
}
 
protected void updateDataset(List<String> labels, List<Number> values) {
63,6 → 62,7
 
sel.addSelectFunctionStar("COUNT");
final SQLDataSource dataSource = Configuration.getInstance().getBase().getDataSource();
@SuppressWarnings("unchecked")
List<Object[]> rowsArticle = (List<Object[]>) dataSource.execute(sel.asString() + " GROUP BY \"SAISIE_VENTE_FACTURE_ELEMENT\".\"" + field + "\"", new ArrayListHandler());
 
Collections.sort(rowsArticle, new Comparator<Object[]>() {
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/RowValuesNavigatorPanel.java
21,6 → 21,7
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
 
110,6 → 111,7
row.update();
updateBar();
}
doAfterImport();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
142,4 → 144,7
t.start();
 
}
 
protected void doAfterImport() throws SQLException {
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/ArrayTableModel.java
14,6 → 14,7
package org.openconcerto.erp.importer;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
147,6 → 148,10
 
}
 
public List<Object> getLineValuesAt(int rowIndex) {
return Collections.unmodifiableList(this.dataVector.get(rowIndex));
}
 
public Set<Object> getValueSetForColumn(int column) {
final Set<Object> result = new HashSet<Object>();
final int rowCount = this.getRowCount();
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/DataImporter.java
24,6 → 24,7
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.utils.text.CSVReader;
import org.openconcerto.utils.text.CSVWriter;
import org.openconcerto.utils.text.CharsetHelper;
 
import java.io.BufferedInputStream;
30,9 → 31,11
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.util.ArrayList;
69,7 → 72,6
public static void main(String[] args) throws Exception {
System.setProperty(SQLBase.STRUCTURE_USE_XML, "true");
final ComptaPropsConfiguration conf = ComptaPropsConfiguration.create();
conf.setupLogging("Logs");
Configuration.setInstance(conf);
try {
conf.getBase();
92,7 → 94,7
// ArrayTableModel m = importer.createModelFromODS(new File("c:/products-en.ods"));
// ArrayTableModel m = importer.createModelFromCSV(new File("c:/products-en.csv"));
// ArrayTableModel m = importer.createModelFromCSV(new File("c:/products-en.scsv.csv"));
ArrayTableModel m = importer.createModelFromXLS(new File("c:/products-en.xls"));
ArrayTableModel m = importer.createModelFromXLS(new File("c:/products-en.xls"), 0);
m.dump(0, 4);
m = importer.createConvertedModel(m);
System.out.println("Dump");
111,6 → 113,7
for (SQLRowValues row : this.valuesToUpdate) {
row.update();
}
doAfterImport();
}
 
public List<SQLRowValues> getValuesToInsert() {
164,12 → 167,12
l.add(value);
}
 
public ArrayTableModel createModelFromODS(File odsFile) throws IOException {
public ArrayTableModel createModelFromODS(File odsFile, int sheetNumber) throws IOException {
final SpreadSheet spreadSheet = SpreadSheet.createFromFile(odsFile);
if (spreadSheet.getSheetCount() < 1) {
return null;
}
final Sheet sheet = spreadSheet.getSheet(0);
final Sheet sheet = spreadSheet.getSheet(sheetNumber);
final int rowCount = sheet.getRowCount();
int columnCount = 0;
if (rowCount > 0) {
198,11 → 201,11
return new ArrayTableModel(rows);
}
 
public ArrayTableModel createModelFromXLS(File xlsFile) throws IOException {
public ArrayTableModel createModelFromXLS(File xlsFile, int sheetNumber) throws IOException {
final InputStream inputStream = new FileInputStream(xlsFile);
final POIFSFileSystem fileSystem = new POIFSFileSystem(new BufferedInputStream(inputStream));
final HSSFWorkbook workBook = new HSSFWorkbook(fileSystem);
final HSSFSheet sheet = workBook.getSheetAt(0);
final HSSFSheet sheet = workBook.getSheetAt(sheetNumber);
Iterator<Row> rowsIterator = sheet.rowIterator();
int columnCount = 0;
int rowCount = 0;
317,6 → 320,15
 
}
 
public void exportModelToCSV(File csvFile, List<String[]> lines) throws IOException {
 
char separator = ';';
 
CSVWriter csvReader = new CSVWriter(new OutputStreamWriter(new FileOutputStream(csvFile), "CP1252"), separator);
csvReader.writeAll(lines);
csvReader.close();
}
 
public ArrayTableModel createConvertedModel(ArrayTableModel model) {
final int rowCount = model.getRowCount();
final ArrayList<Integer> colsUsed = new ArrayList<Integer>(map.keySet());
351,6 → 363,10
return new ArrayTableModel(rows);
}
 
protected void customizeRowValuesToFetch(SQLRowValues vals) {
 
}
 
public void importFromModel(ArrayTableModel model) throws IOException {
final int rowCount = model.getRowCount();
// Load existing data for duplication check
366,9 → 382,9
}
}
}
 
customizeRowValuesToFetch(vals);
System.out.println("Fetching values");
SQLRowValuesListFetcher fetcher = new SQLRowValuesListFetcher(vals);
SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(vals);
List<SQLRowValues> existingRows = fetcher.fetch();
System.out.println("Computing cache");
final int existingRowsCount = existingRows.size();
458,28 → 474,47
}
}
}
final SQLRowValues rowVals = new SQLRowValues(table, newValues);
patchRowValues(rowVals, model.getLineValuesAt(i), existingRow);
if (existingRow == null) {
this.valuesToInsert.add(new SQLRowValues(table, newValues));
} else if (!newValues.equals(existingRow.getAbsolutelyAll())) {
this.valuesToUpdate.add(new SQLRowValues(table, newValues));
this.valuesToInsert.add(rowVals);
}
// else if (!newValues.equals(existingRow.getAbsolutelyAll())) {
else {
this.valuesToUpdate.add(rowVals);
// for (SQLRowValues ref : rowVals.getReferentRows()) {
// this.valuesToUpdate.add(ref);
// }
}
}
 
public void doAfterImport() throws SQLException {
 
}
 
protected void patchRowValues(SQLRowValues rowVals, List<Object> lineValues, SQLRowValues existingRow) {
 
}
 
public void setSkipFirstLine(boolean skipFirstLine) {
this.skipFirstLine = skipFirstLine;
}
 
public ArrayTableModel createModelFrom(File file) throws IOException {
return createModelFrom(file, 0);
}
 
public ArrayTableModel createModelFrom(File file, int sheetNumber) throws IOException {
if (!file.exists()) {
throw new IllegalArgumentException(file.getAbsolutePath() + " does not exist");
}
String name = file.getName().toLowerCase();
if (name.endsWith(".ods")) {
return createModelFromODS(file);
return createModelFromODS(file, sheetNumber);
} else if (name.endsWith(".csv")) {
return createModelFromCSV(file);
} else if (name.endsWith(".xls")) {
return createModelFromXLS(file);
return createModelFromXLS(file, sheetNumber);
}
throw new IllegalArgumentException("File format not supported");
 
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/TemplateNXProps.java
120,6 → 120,8
}
 
storage.setPDFDefaultDirectory(new File(propertyDefaultPDFDirectory));
 
 
register(DevisXmlSheet.TEMPLATE_ID, DevisXmlSheet.TEMPLATE_PROPERTY_NAME, AbstractGenerationDocumentPreferencePanel.getLabelFromTable("DEVIS"));
register(VenteFactureXmlSheet.TEMPLATE_ID, VenteFactureXmlSheet.TEMPLATE_PROPERTY_NAME, AbstractGenerationDocumentPreferencePanel.getLabelFromTable("SAISIE_VENTE_FACTURE"));
register(CommandeClientXmlSheet.TEMPLATE_ID, CommandeClientXmlSheet.TEMPLATE_PROPERTY_NAME, AbstractGenerationDocumentPreferencePanel.getLabelFromTable("COMMANDE_CLIENT"));
147,6 → 149,24
 
}
 
public void preventecRegister(String path, String templateId, String defaultSubFolder) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
}
 
if (TemplateManager.getInstance().isKnwonTemplate(templateId)) {
System.err.println("Warning: registering known template id : " + templateId);
}
final DocumentLocalStorageManager storage = DocumentLocalStorageManager.getInstance();
if (defaultSubFolder != null) {
storage.addDocumentDirectory(templateId, new File(path, defaultSubFolder));
storage.addPDFDirectory(templateId, new File(path, defaultSubFolder));
} else {
storage.addDocumentDirectory(templateId, new File(path));
storage.addPDFDirectory(templateId, new File(path));
}
}
 
public void register(String templateId, String propertyBaseName, String defaultSubFolder) {
if (templateId == null) {
throw new IllegalArgumentException("null template id");
193,7 → 213,8
if (!configuration.isOnCloud()) {
provider = new DefaultLocalTemplateProvider();
if (property != null) {
((DefaultLocalTemplateProvider) provider).setBaseDirectory(new File(property));
File storage = new File(property);
((DefaultLocalTemplateProvider) provider).setBaseDirectory(storage);
}
} else {
provider = new DefaultCloudTemplateProvider(configuration.getSocieteID());
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/GestionCommercialeGlobalPreferencePanel.java
New file
0,0 → 1,59
/*
* 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.
*/
/*
* Créé le 6 mars 2012
*/
package org.openconcerto.erp.preferences;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.ui.preferences.JavaPrefPreferencePanel;
import org.openconcerto.ui.preferences.PrefView;
import org.openconcerto.utils.PrefType;
 
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
 
public class GestionCommercialeGlobalPreferencePanel extends JavaPrefPreferencePanel {
public static String TRANSFERT_REF = "TransfertRef";
public static String TRANSFERT_MULTI_REF = "TransfertMultiRef";
public static String TRANSFERT_NO_REF = "TransfertNoRef";
 
public GestionCommercialeGlobalPreferencePanel() {
super("Gestion des pièces commerciales", null);
setPrefs(new SQLPreferences(((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete()));
}
 
@Override
protected void addViews() {
PrefView<Boolean> viewTransfert = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Transférer les numéros des pièces commeriales en tant que référence", TRANSFERT_REF);
viewTransfert.setDefaultValue(Boolean.TRUE);
this.addView(viewTransfert);
 
PrefView<Boolean> viewMultiTransfert = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Transférer les numéros des pièces commerciales dans le corps", TRANSFERT_MULTI_REF);
viewMultiTransfert.setDefaultValue(Boolean.FALSE);
this.addView(viewMultiTransfert);
 
PrefView<Boolean> viewNo = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Ne pas transférer les numéros des pièces commerciales", TRANSFERT_NO_REF);
viewNo.setDefaultValue(Boolean.FALSE);
this.addView(viewNo);
 
ButtonGroup group = new ButtonGroup();
group.add((JCheckBox) viewMultiTransfert.getVW().getComp());
group.add((JCheckBox) viewTransfert.getVW().getComp());
group.add((JCheckBox) viewNo.getVW().getComp());
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/DefaultMenuConfiguration.java
16,6 → 16,7
import org.openconcerto.erp.action.AboutAction;
import org.openconcerto.erp.action.AstuceAction;
import org.openconcerto.erp.action.GestionDroitsAction;
import org.openconcerto.erp.action.ListeBanqueAction;
import org.openconcerto.erp.action.NouvelleSocieteAction;
import org.openconcerto.erp.action.PreferencesAction;
import org.openconcerto.erp.action.SauvegardeBaseAction;
35,12 → 36,14
import org.openconcerto.erp.core.finance.accounting.action.ExportRelationExpertAction;
import org.openconcerto.erp.core.finance.accounting.action.GenerePointageAction;
import org.openconcerto.erp.core.finance.accounting.action.GestionPlanComptableEAction;
import org.openconcerto.erp.core.finance.accounting.action.ImpressionJournauxAnalytiqueAction;
import org.openconcerto.erp.core.finance.accounting.action.ImpressionLivrePayeAction;
import org.openconcerto.erp.core.finance.accounting.action.ListeDesDevisesAction;
import org.openconcerto.erp.core.finance.accounting.action.ListeDesEcrituresAction;
import org.openconcerto.erp.core.finance.accounting.action.ListeDesEcrituresAnalytiquesAction;
import org.openconcerto.erp.core.finance.accounting.action.ListeDesJournauxAction;
import org.openconcerto.erp.core.finance.accounting.action.ListeEcritureParClasseAction;
import org.openconcerto.erp.core.finance.accounting.action.NouveauClotureAction;
import org.openconcerto.erp.core.finance.accounting.action.NouveauJournalAction;
import org.openconcerto.erp.core.finance.accounting.action.NouveauLettrageAction;
import org.openconcerto.erp.core.finance.accounting.action.NouveauPointageAction;
import org.openconcerto.erp.core.finance.accounting.action.NouvelleValidationAction;
55,7 → 58,6
import org.openconcerto.erp.core.finance.payment.action.NouveauDecaissementChequeAvoirAction;
import org.openconcerto.erp.core.finance.payment.action.NouveauListeDesChequesADecaisserAction;
import org.openconcerto.erp.core.finance.payment.action.NouveauListeDesChequesAEncaisserAction;
import org.openconcerto.erp.core.finance.tax.action.DeclarationTVAAction;
import org.openconcerto.erp.core.humanresources.ListeDesContactsAdministratif;
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesCommerciauxAction;
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesSalariesAction;
103,6 → 105,7
import org.openconcerto.erp.core.supplychain.order.action.NouveauSaisieAchatAction;
import org.openconcerto.erp.core.supplychain.order.action.NouvelleCommandeAction;
import org.openconcerto.erp.core.supplychain.order.action.NouvelleFactureFournisseurAction;
import org.openconcerto.erp.core.supplychain.product.action.ListeDesArticlesFournisseurAction;
import org.openconcerto.erp.core.supplychain.receipt.action.ListeDesBonsReceptionsAction;
import org.openconcerto.erp.core.supplychain.receipt.action.NouveauBonReceptionAction;
import org.openconcerto.erp.core.supplychain.stock.action.ListeDesMouvementsStockAction;
121,6 → 124,8
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.users.rights.LockAdminUserRight;
import org.openconcerto.sql.users.rights.UserRights;
import org.openconcerto.sql.users.rights.UserRightsManager;
import org.openconcerto.sql.utils.BackupPanel;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.ui.group.Group;
import org.openconcerto.ui.group.LayoutHints;
192,6 → 197,7
*/
private Group createFilesMenuGroup() {
Group group = new Group(MainFrame.FILE_MENU);
if (UserRightsManager.getCurrentUserRights().haveRight(BackupPanel.RIGHT_CODE))
group.addItem("backup");
group.addItem("export.accounting");
group.addItem("modules");
259,6 → 265,7
gAccounting.addItem("accounting.chart");
gAccounting.addItem("accounting.journal");
gAccounting.addItem("accounting.checkDB");
gAccounting.addItem("accounting.currency");
group.add(gAccounting);
}
 
280,6 → 287,7
 
group.addItem("enterprise.list");
 
group.addItem("divison.bank.list");
group.addItem("enterprise.create");
return group;
}
361,6 → 369,10
group.addItem("accounting.balance");
group.addItem("accounting.client.balance");
group.addItem("accounting.ledger");
Group analytic = new Group("accounting.analytical");
analytic.addItem("accounting.analytical.ledger");
analytic.addItem("accounting.analytical.entries.ledger");
group.add(analytic);
group.addItem("accounting.general.ledger");
group.addItem("accounting.entries.ledger");
group.addItem("accounting.entries.list");
420,6 → 432,7
 
final Group gProduct = new Group("menu.list.product", LayoutHints.DEFAULT_NOLABEL_SEPARATED_GROUP_HINTS);
gProduct.addItem("product.list");
// gProduct.addItem("product.supplychain.list");
gProduct.addItem("stock.io.list");
group.add(gProduct);
 
529,6 → 542,7
}
 
mManager.registerAction("product.list", new ListeDesArticlesAction());
mManager.registerAction("product.supplychain.list", new ListeDesArticlesFournisseurAction());
mManager.registerAction("stock.io.list", new ListeDesMouvementsStockAction());
 
 
537,9 → 551,11
private void registerAccountingMenuActions(final MenuAndActions mManager) {
mManager.registerAction("accounting.balance", new EtatBalanceAction());
mManager.registerAction("accounting.client.balance", new BalanceAgeeAction());
mManager.registerAction("accounting.analytical.ledger", new ImpressionJournauxAnalytiqueAction());
mManager.registerAction("accounting.ledger", new EtatJournauxAction());
mManager.registerAction("accounting.general.ledger", new EtatGrandLivreAction());
mManager.registerAction("accounting.entries.ledger", new ListeDesEcrituresAction());
mManager.registerAction("accounting.analytical.entries.ledger", new ListeDesEcrituresAnalytiquesAction());
mManager.registerAction("accounting.entries.list", new ListeEcritureParClasseAction());
mManager.registerAction("accounting.validating", new NouvelleValidationAction());
mManager.registerAction("accounting.closing", new NouveauClotureAction());
610,8 → 626,9
final UserRights rights = UserManager.getInstance().getCurrentUser().getRights();
final ComptaPropsConfiguration configuration = ComptaPropsConfiguration.getInstanceCompta();
if (rights.haveRight(ComptaUserRight.MENU)) {
mManager.registerAction("accounting.chart", new GestionPlanComptableEAction());
mManager.registerAction("accounting.journal", new ListeDesJournauxAction());
mManager.putAction(new GestionPlanComptableEAction(), "accounting.chart");
mManager.putAction(new ListeDesJournauxAction(), "accounting.journal");
mManager.putAction(new ListeDesDevisesAction(), "accounting.currency");
mManager.putAction(new AbstractAction("Check DB") {
@Override
public void actionPerformed(ActionEvent e) {
637,6 → 654,7
 
mManager.registerAction("enterprise.list", new ListeDesSocietesCommonsAction());
 
mManager.registerAction("divison.bank.list", new ListeBanqueAction());
mManager.registerAction("enterprise.create", new NouvelleSocieteAction());
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/config/translation_fr.xml
28,6 → 28,7
<menu id="supplier.order.create" label="Commande fournisseur" />
<menu id="supplier.receipt.create" label="Bon de réception" />
<menu id="supplier.purchase.create" label="Achat fournisseur" />
<menu id="supplier.invoice.purchase.create" label="Facture fournisseur" />
<menu id="supplier.credit.create" label="Avoir fournisseur" />
<menu id="stock.io.create" label="Mouvement de stock" />
 
62,6 → 63,7
<menu id="supplier.order.list" label="Liste des commandes fournisseur" />
<menu id="supplier.receipt.list" label="Liste des bons de réception" />
<menu id="supplier.purchase.list" label="Liste des saisies d'achat" />
<menu id="supplier.invoice.purchase.list" label="Liste des factures fournisseurs" />
<menu id="supplier.credit.list" label="Liste des avoirs fournisseur" />
<menu id="product.list" label="Liste des articles" />
<menu id="product.reference.list" label="Liste des références" />
159,6 → 161,7
<item id="sales.quote.label" label="Référence" />
<item id="sales.quote.customer" label="Client" />
<item id="sales.quote.saleman" label="Commercial" />
<item id="sales.quote.state" label="Etat" />
<item id="sales.quote.address.alternative" label="Adresse alternative" />
<item id="sales.quote.info.general" label="Informations complémentaires" />
<action id="sales.quote.accept" label="Marquer comme accepté" />
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mappingCompta_fr.xml
9,6 → 9,7
<TABLE name="ADRESSE">
<FIELD name="RAISON_SOCIALE" label="Raison sociale" titlelabel="Raison sociale" />
<FIELD name="RUE" label="Rue" titlelabel="Rue" />
<FIELD name="PROVINCE" label="Province / état" titlelabel="Province" />
<FIELD name="PAYS" label="Pays" titlelabel="Pays" />
<FIELD name="CEDEX" label="Cedex" titlelabel="Cedex" />
<FIELD name="HAS_CEDEX" label="Cedex" titlelabel="Cedex" />
17,6 → 18,8
<FIELD name="DEST" label="Nom du Destinataire" titlelabel="Destinataire" />
<FIELD name="NUMERO_CANTON" label="Numéro canton" titlelabel="Numéro canton" />
<FIELD name="NUMERO_COMMUNE" label="Numéro commune" titlelabel="Numéro commune" />
<FIELD name="TYPE" label="Type" />
<FIELD name="EMAIL_CONTACT" label="Email contact" />
</TABLE>
<TABLE name="AFFACTURAGE">
<FIELD name="NB_FACT" label="Nombre de factures" titlelabel="Nombre de factures" />
26,6 → 29,9
<TABLE name="AFFAIRE">
<FIELD name="ID_CLIENT" label="Client" titlelabel="Client" />
<FIELD name="CCI" label="CCI" titlelabel="CCI" />
<FIELD name="TYPE_ETABLISSEMENT" label="Type d'établissement" />
<FIELD name="DUREE_TRAVAUX" label="Durée des travaux" />
<FIELD name="CCI" label="CCI" titlelabel="CCI" />
<FIELD name="ID_VERIFICATEUR" label="Chargé d'affaire" titlelabel="Chargé d'affaire" />
<FIELD name="DATE_DEMARRAGE" label="Date de démarrage" titlelabel="Date de démarrage" />
<FIELD name="MARCHE" label="Marché" titlelabel="Marché" />
143,6 → 149,10
 
<TABLE name="ASSOCIATION_ANALYTIQUE">
<FIELD name="ID_POSTE_ANALYTIQUE" label="Poste analytique" titlelabel="Poste analytique" />
 
<FIELD name="POURCENT" label="Pourcentage réparti" />
 
<FIELD name="MONTANT" label="Montant réparti" />
</TABLE>
 
<TABLE name="ASSOCIATION_COMPTE_ANALYTIQUE">
299,6 → 309,25
<FIELD name="AFFACTURAGE" label="Banque d'affacturage" titlelabel="Banque d'affacturage" />
<FIELD name="INFOS" label="Informations" titlelabel="Informations" />
</TABLE>
<TABLE name="BANQUE">
<FIELD name="NOM" label="Nom" />
<FIELD name="NUMERO_RUE" label="Numéro de rue" />
<FIELD name="VOIE" label="Voie" />
<FIELD name="RUE" label="Rue" />
<FIELD name="VILLE" label="Ville" />
<FIELD name="CODE_ETS" label="Code Ets" />
<FIELD name="CODE_GUICHET" label="Code guichet" />
<FIELD name="NUMERO_COMPTE" label="N° compte" />
<FIELD name="CLE_RICE" label="Clé rice" />
<FIELD name="ID_JOURNAL" label="Journal" />
<FIELD name="ID_COMPTE_PCE" label="Compte PCE" />
<FIELD name="AFFACTURAGE" label="Affacturage" />
<FIELD name="DOMICILIATION" label="Domiciliation" />
<FIELD name="BIC" label="BIC" />
<FIELD name="IBAN" label="IBAN" />
<FIELD name="CODE" label="Code" />
<FIELD name="INFOS" label="Informations" />
</TABLE>
 
<TABLE name="BON_RECEPTION">
<FIELD name="DATE" label="Date" titlelabel="Date" />
483,6 → 512,7
</TABLE>
 
<TABLE name="CLIENT">
<FIELD name="ID_TARIF_MISSION_LIBELLE" label="Tarif" titlelabel="Tarif" />
<FIELD name="ID_TYPE_CLIENT" label="Type de client" />
<FIELD name="ID_GROUPE_CLIENT" label="Groupe" />
<FIELD name="ID_PAYS" label="Pays" titlelabel="Pays" />
527,6 → 557,8
<FIELD name="MAX_FACTURE" label="Facturation limitée à" titlelabel="Facturation limitée à" />
<FIELD name="COMPTANT" label="Règlement comptant obligatoire" titlelabel="Règlement comptant obligatoire" />
<FIELD name="ID_TARIF" label="Tarif" titlelabel="Tarif" />
<FIELD name="EXTRANET_LOGIN" label="Identifiant extranet" />
<FIELD name="EXTRANET_PASSWORD" label="Mot de passe extranet" />
</TABLE>
 
<TABLE name="CODE_REGIME">
836,6 → 868,32
</TABLE>
 
<TABLE name="DEVIS">
 
<FIELD name="CONTACT_MAIL_RAPPORT" label="Email dest. suppl." />
<FIELD name="SITE_DIFF" label="Site d'intervention différent du donneur d'ordre" titlelabel="Site d'intervention différent du donneur d'ordre" />
<FIELD name="DESIGNATION_SITE" label="Désignation du site" />
<FIELD name="ADRESSE_SITE" label="Adresse du site" />
<FIELD name="VILLE_SITE" label="Ville du site" />
<FIELD name="TEL_SITE" label="Téléphone du site" />
<FIELD name="TEL_P_SITE" label="Téléphone portable du site" />
<FIELD name="FAX_SITE" label="Fax du site" />
<FIELD name="MAIL_SITE" label="Email du site" />
<FIELD name="CONTACT_SITE" label="Contact du site" />
 
<FIELD name="DONNEUR_DIFF" label="Donneur d'ordre différent du client" />
<FIELD name="DESIGNATION_DONNEUR" label="Désignation du donneur d'ordre" />
<FIELD name="ADRESSE_DONNEUR" label="Adresse du donneur d'ordre" />
<FIELD name="VILLE_DONNEUR" label="Ville du donneur d'ordre" />
<FIELD name="TEL_DONNEUR" label="Téléphone du donneur d'ordre" />
<FIELD name="TEL_P_DONNEUR" label="Téléphone portable du donneur d'ordre" />
<FIELD name="FAX_DONNEUR" label="Fax du donneur d'ordre" />
<FIELD name="MAIL_DONNEUR" label="Email du donneur d'ordre" />
<FIELD name="CONTACT_DONNEUR" label="Contact du donneur d'ordre" />
<FIELD name="SIREN_DONNEUR" label="Siren du donneur d'ordre" />
 
<FIELD name="DATE_DEMANDE" label="Date demande client" titlelabel="Date demande client" />
 
<FIELD name="MONTANT_REMISE" label="Remise globale" />
<FIELD name="ID_MODELE" label="Modèle" titlelabel="Modèle" />
<FIELD name="PROBABILITE" label="Probabilité" titlelabel="Probabilité" />
<FIELD name="DATE_VALIDITE" label="Valable jusqu'au" titlelabel="Valable jusqu'au" />
903,6 → 961,34
<FIELD name="NB_COLIS" label="Nb Colis" titlelabel="Nb Colis" />
<FIELD name="POIDS_COLIS_NET" label="Pds Colis" titlelabel="Pds Colis" />
<FIELD name="T_POIDS_COLIS_NET" label="Pds Colis Total" titlelabel="Pds Colis Total" />
 
 
<FIELD name="MONTANT_INITIAL" label="Montant initial" titlelabel="Montant initial" />
<FIELD name="INDICE_0" label="Indice 0" titlelabel="Indice 0" />
<FIELD name="INDICE_N" label="Indice N" titlelabel="Indice N" />
<FIELD name="Q18" label="Extension Q18" titlelabel="Extension Q18" />
<FIELD name="TARIF_Q18_HT" label="Tarif Q18 HT" titlelabel="Tarif Q18 HT" />
<FIELD name="OBJET_INSPECTE" label="Objet inspecté" titlelabel="Objet inspecté" />
<FIELD name="REFERENTIEL_INSPECTION" label="Référentiel inspection" titlelabel="Référentiel inspection" />
<FIELD name="LOCAL_OBJET_INSPECTE" label="Localisation objet" titlelabel="Localisation objet" />
<FIELD name="ID_SECTEUR_ACTIVITE" label="Secteur d'activité" titlelabel="Secteur d'activité" />
<FIELD name="ID_NATURE_MISSION" label="Nature de la mission" titlelabel="Nature de la mission" />
<FIELD name="ID_DOMAINE" label="Domaine" titlelabel="Domaine" />
<FIELD name="MONTANT_REVISABLE" label="Révisable" titlelabel="Révisable" />
<FIELD name="INFOS_OBJET_INSPECTE" label="Commentaires objet" titlelabel="Commentaires objet" />
<FIELD name="ID_SITE_INTERVENTION" label="Site d'intervention" titlelabel="Site d'intervention" />
<FIELD name="ID_PERIODICITE" label="Périodicité" titlelabel="Périodicité" />
<FIELD name="DATE" label="Date d'intervention" titlelabel="Date d'intervention" />
<FIELD name="POURCENT_SERVICE" label="Pourcentage service" titlelabel="Pourcentage service" />
<FIELD name="POURCENT_CCIP" label="CCIP" titlelabel="CCIP" />
<FIELD name="DATE_FIN" label="Date de fin d'intervention" titlelabel="Date de fin d'intervention" />
<FIELD name="ID_DEPARTEMENT" label="Département" />
<FIELD name="POURCENT_ACOMPTE" label="% Acompte" />
<FIELD name="NOM_MISSION" label="Mission" />
<FIELD name="NB_RAPPORT" label="Nb ex. rapports" />
<FIELD name="DUREE_MISSION" label="Durée approx." />
<FIELD name="FONCTION_SIGN" label="Fonction signataire" />
<FIELD name="DATE_SIGN" label="Date de signature" />
</TABLE>
 
<TABLE name="ECHANTILLON_ELEMENT">
1191,6 → 1277,7
<TABLE name="FOURNISSEUR">
<FIELD name="ID_COMPTE_PCE_CHARGE" label="Compte de charge par défaut" titlelabel="Compte de charge par défaut" />
<FIELD name="TYPE" label="Type" titlelabel="Type" />
<FIELD name="ID_DEVISE" label="Devise" titlelabel="Devise" />
<FIELD name="RESPONSABLE" label="Responsable" titlelabel="Responsable" />
<FIELD name="TEL_P" label="Mobile" titlelabel="Mobile" />
<FIELD name="INFOS" label="Informations complèmentaires" titlelabel="Informations complèmentaires" />
1262,6 → 1349,7
<FIELD name="AJOURS" label="à" titlelabel="à" />
<FIELD name="LENJOUR" label="le" titlelabel="le" />
<FIELD name="ID_BANQUE_POLE_PRODUIT" label="Banque" titlelabel="Banque" />
<FIELD name="ID_BANQUE" label="Banque" titlelabel="Banque" />
<FIELD name="ID_TYPE_REGLEMENT" label="Type de règlement" titlelabel="Type de règlement" />
<FIELD name="DATE" label="Daté du" titlelabel="Daté du" />
<FIELD name="ETS" label="Ets" titlelabel="Ets" />
1397,7 → 1485,7
</TABLE>
 
<TABLE name="POSTE_ANALYTIQUE">
<FIELD name="NOM" label="Libellé" titlelabel="Libellé" />
<FIELD name="NOM" label="Nom du Poste" titlelabel="Nom du Poste" />
<FIELD name="ID_AXE_ANALYTIQUE" label="Axe" titlelabel="Axe" />
</TABLE>
 
/trunk/OpenConcerto/src/org/openconcerto/erp/config/Gestion.java
33,6 → 33,7
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.IComboSelectionItem;
import org.openconcerto.sql.ui.SoftwareInfoPanel;
import org.openconcerto.sql.users.rights.UserRightsManager;
import org.openconcerto.sql.view.EditPanel;
import org.openconcerto.sql.view.list.IListe;
186,6 → 187,7
}
 
public static void main(String[] args) {
 
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
 
@Override
198,6 → 200,7
System.out.println(System.getProperty("java.runtime.version", "??") + " - " + System.getProperty("os.name", "??"));
ExceptionHandler.setForceUI(true);
ExceptionHandler.setForumURL("http://www.openconcerto.org/forum");
ExceptionHandler.setSoftwareInformations(SoftwareInfoPanel.FACTORY);
 
System.setProperty(PropsConfiguration.REDIRECT_TO_FILE, "true");
// Mac
272,6 → 275,7
System.setProperty("org.openconcerto.oo.useODSViewer", Boolean.valueOf(conf.getProperty("odsViewer")).toString());
}
 
 
// Restore L&F and colors
UIPreferencePanel.initUIFromPreferences();
 
/trunk/OpenConcerto/src/org/openconcerto/erp/config/fieldmapping.xml
24,7 → 24,18
<field id="sales.quote.saleman" name="ID_COMMERCIAL" />
<field id="sales.quote.address.alternative" name="ID_ADRESSE" />
<field id="sales.quote.info.general" name="INFOS" />
<field id="sales.quote.state" name="ID_ETAT_DEVIS"/>
</table>
<table id="sales.quote.item" name="DEVIS_ELEMENT">
<field id="sales.quote.item.quote" name="ID_DEVIS"/>
<field id="sales.quote.item.style" name="ID_STYLE"/>
<field id="sales.quote.item.code" name="CODE"/>
<field id="sales.quote.item.label" name="NOM"/>
<field id="sales.quote.item.description" name="DESCRIPTIF"/>
<field id="sales.quote.item.purchase.unit.price" name="PA_HT"/>
<field id="sales.quote.item.sales.unit.price" name="PV_HT"/>
<field id="sales.quote.item.quantity" name="QTE"/>
</table>
<table id="sales.product" name="ARTICLE">
<field id="sales.product.code" name="CODE" />
<field id="sales.product.label" name="NOM" />
51,7 → 62,7
<field id="sales.product.sales.account" name="ID_COMPTE_PCE" />
<field id="sales.product.purchase.account" name="ID_COMPTE_PCE_ACHAT" />
<field id="sales.product.deprecated" name="OBSOLETE" />
<field id="sales.product.family" name="ID_FAMILLE_ARTICLE" />
<field id="sales.product.category" name="ID_FAMILLE_ARTICLE" />
<field id="sales.product.info" name="INFOS" />
<field id="sales.product.price1" name="PRIX_METRIQUE_VT_1" />
<field id="sales.product.price2" name="PRIX_METRIQUE_VT_2" />
/trunk/OpenConcerto/src/org/openconcerto/erp/config/translation_en.xml
1,4 → 1,4
<translation lang="fr">
<translation lang="en">
<!-- File -->
<menu id="menu.file" label="File" />
<menu id="backup" label="Backup" />
28,6 → 28,7
<menu id="supplier.order.create" label="Supplier order" />
<menu id="supplier.receipt.create" label="Supplier receipt" />
<menu id="supplier.purchase.create" label="Supplier purchase" />
<menu id="supplier.invoice.purchase.create" label="Supplier invoice" />
<menu id="supplier.credit.create" label="Supplier credit" />
<menu id="stock.io.create" label="Stock" />
 
50,7 → 51,7
<menu id="mission.notice.list" label="" />
<menu id="customer.order.list" label="Orders" />
<menu id="customer.delivery.list" label="Deliveries" />
<menu id="sales.list" label="Sales" />
<menu id="sales.list" label="Invoices" />
<menu id="customer.invoice.list" label="Invoices" />
<menu id="payment.factoring.create" label="" />
<menu id="payment.factoring.list" label="" />
62,6 → 63,7
<menu id="supplier.order.list" label="Supplier orders" />
<menu id="supplier.receipt.list" label="Supplier receipts" />
<menu id="supplier.purchase.list" label="Purchases" />
<menu id="supplier.invoice.purchase.list" label="Supplier invoices" />
<menu id="supplier.credit.list" label="Supplier credits" />
<menu id="product.list" label="Product list" />
<menu id="product.reference.list" label="Reference list" />
115,8 → 117,8
<menu id="supplier.payment.check.list" label="Supplier checks" />
<menu id="supplier.payment.check.pending.list" label="Pending checks to suppliers" />
<!-- Payroll -->
<menu id="menu.payroll" label="Paye" />
<menu id="payroll.list.report.print" label="Apyroll report" />
<menu id="menu.payroll" label="Payroll" />
<menu id="payroll.list.report.print" label="Payroll report" />
<menu id="payroll.profile.list" label="Profiles" />
<menu id="payroll.history" label="History" />
<menu id="payroll.create" label="Payroll" />
145,10 → 147,71
<menu id="mission.sample.list" label="" />
<menu id="mission.code.list" label="" />
<menu id="department.list" label="" />
<!-- Help -->
<!-- Test -->
<menu id="menu.test" label="Tests" />
<!-- Help -->
<menu id="menu.help" label="Help" />
<menu id="information" label="About" />
<menu id="tips" label="Tips" />
<!-- Quote -->
<item id="sales.quote.number" label="Number" />
<item id="sales.quote.date" label="Date" />
<item id="sales.quote.label" label="Reference" />
<item id="sales.quote.customer" label="Customer" />
<item id="sales.quote.saleman" label="Saleman" />
<item id="sales.quote.state" label="State" />
<item id="sales.quote.address.alternative" label="Alternative address" />
<item id="sales.quote.info.general" label="Additional Information" />
<action id="sales.quote.accept" label="Mark as accepted" />
<action id="sales.quote.refuse" label="Mark as refused" />
<action id="sales.quote.create.invoice" label="Transfer to invoice" />
<action id="sales.quote.create.supplier.order" label="Transfer to supplier order" />
<action id="sales.quote.clone" label="Copy from" />
<action id="sales.quote.create.customer.order" label="Transfer to customer order" />
<action id="sales.quote.accept.create.customer.order" label="Mark as accepted and transfer to customer order" />
<!-- Customer -->
<action id="customerrelationship.customer.label.print" label="Print customer label" />
<action id="customerrelationship.customer.info.create" label="Create customer info" />
<action id="customerrelationship.customer.email.send" label="Send an email" />
<!-- Matching -->
<action id="financing.accouning.entries.source.show" label="Show source" />
<action id="financing.accouning.entries.match" label="Match entry" />
<action id="financing.accouning.entries.unmatch" label="Unmatch entry" />
<!-- Invoice -->
<item id="sales.invoice.number" label="Number" />
<item id="sales.invoice.date" label="Date" />
<item id="sales.invoice.label" label="Reference" />
<item id="sales.invoice.customer" label="Customer" />
<item id="sales.invoice.saleman" label="Saleman" />
<item id="sales.invoice.address.alternative" label="Alternative address" />
<item id="sales.invoice.info.general" label="Additional Information" />
<action id="sales.invoice.purchase.update" label="Update purchase total" />
<action id="sales.invoice.comment.add" label="Add a comment" />
<action id="sales.invoice.create.delivery" label="Transfer to delivery order" />
<action id="sales.invoice.create.credit" label="Transfer to credit" />
<action id="sales.invoice.clone" label="Copy from" />
<action id="sales.invoice.info.show" label="Customer info" />
<action id="sales.invoice.create.supplier.order" label="Transfer to supplier order" />
<action id="sales.shipment.create.invoice" label="Transfer to invoice" />
 
<!-- Document -->
<action id="document.quickprint" label="Quick print" />
<action id="document.print" label="Print..." />
<action id="document.print.all" label="Print documents" />
<action id="document.preview" label="Preview document" />
<action id="document.modify" label="Modify docucment with OpenOffice" />
<action id="document.create" label="Create document" />
<action id="document.pdf.send.email" label="Send PDF by email" />
<action id="document.send.email" label="Send by email" />
 
<!-- Supplier order -->
<action id="supplychain.order.create.purchase" label="Transfer to purchase" />
<action id="supplychain.order.create.receipt" label="Transfer to supplier receipt" />
 
<!-- Customer order -->
<action id="sales.order.create.deliverynote" label="Transfer to delivey note" />
<action id="sales.order.create.invoice" label="Transfer to invoice" />
<action id="sales.order.create.supplier.order" label="Transfer to supplier order" />
</translation>
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mappingCompta_en.xml
9,6 → 9,7
<TABLE name="ADRESSE">
<FIELD name="RAISON_SOCIALE" label="Name" />
<FIELD name="RUE" label="Street" />
<FIELD name="PROVINCE" label="State" titlelabel="State" />
<FIELD name="PAYS" label="Country" />
<FIELD name="CEDEX" label="Cedex" />
<FIELD name="HAS_CEDEX" label="Cedex" />
17,6 → 18,8
<FIELD name="DEST" label="Contact" />
<FIELD name="NUMERO_CANTON" label="State code" />
<FIELD name="NUMERO_COMMUNE" label="" />
<FIELD name="TYPE" label="Type" />
<FIELD name="EMAIL_CONTACT" label="Email contact" />
</TABLE>
<TABLE name="AFFACTURAGE">
<FIELD name="NB_FACT" label="Number of invoice" />
68,6 → 71,7
</TABLE>
 
<TABLE name="ARTICLE_TARIF">
<FIELD name="ID_ARTICLE" label="Product" />
<FIELD name="ID_TARIF" label="Price list" />
<FIELD name="ID_TAXE" label="Tax" />
<FIELD name="ID_DEVISE" label="Currency" />
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mapping_fr.xml
31,6 → 31,22
<FIELD name="CODE" label="Code" />
<FIELD name="INFOS" label="Informations" />
</TABLE>
<TABLE name="BANQUE">
<FIELD name="NOM" label="Nom" />
<FIELD name="NUMERO_RUE" label="Numéro de rue" />
<FIELD name="VOIE" label="Voie" />
<FIELD name="RUE" label="Rue" />
<FIELD name="VILLE" label="Ville" />
<FIELD name="CODE_ETS" label="Code Ets" />
<FIELD name="CODE_GUICHET" label="Code guichet" />
<FIELD name="NUMERO_COMPTE" label="N° compte" />
<FIELD name="CLE_RICE" label="Clé rice" />
<FIELD name="DOMICILIATION" label="Domiciliation" />
<FIELD name="BIC" label="BIC" />
<FIELD name="IBAN" label="IBAN" />
<FIELD name="CODE" label="Code" />
<FIELD name="INFOS" label="Informations" />
</TABLE>
<TABLE name="CAISSE_COTISATION">
<FIELD name="NOM" label="Libellé" />
<FIELD name="ID_ADRESSE_COMMON" label="Adresse" />
201,6 → 217,7
<FIELD name="RCS" label="RCS" />
<FIELD name="CAPITAL" label="Capital" />
<FIELD name="NUMERO_URSSAF" label="Numéro URSSAF" />
<FIELD name="ID_DEVISE" label="Devise" />
</TABLE>
<TABLE name="TYPE_MODELE">
<FIELD name="NOM" label="Nom" />
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ServerFinderPanel.java
25,6 → 25,7
import org.openconcerto.utils.DesktopEnvironment;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.FileUtils;
import org.openconcerto.utils.PropertiesUtils;
 
import java.awt.Component;
import java.awt.Dimension;
91,7 → 92,7
PropsConfiguration conf = new PropsConfiguration(new Properties()) {
@Override
protected File createWD() {
return new File(DesktopEnvironment.getDE().getDocumentsFolder().getAbsolutePath() + File.separator + "OpenConcerto");
return new File(DesktopEnvironment.getDE().getDocumentsFolder().getAbsolutePath() + File.separator + ComptaPropsConfiguration.APP_NAME);
}
};
conf.setupLogging();
111,7 → 112,14
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ServerFinderPanel panel = new ServerFinderPanel();
panel.uiInit();
panel.setConfigFile(confFile);
 
boolean loaded = panel.setConfigFile(confFile);
if (!loaded) {
panel.fillWithDefaultH2Config();
panel.updateUIFromProps();
}
// Cloud UI need a loaded config
panel.tabbedPane.addTab("Cloud", new CloudPanel(panel));
f.setContentPane(panel);
f.pack();
f.setMinimumSize(new Dimension(f.getWidth(), f.getHeight()));
121,30 → 129,74
});
}
 
protected void fillWithDefaultH2Config() {
this.props.setProperty("server.driver", "h2");
this.props.setProperty("customer", "Gestion_Default");
this.props.setProperty("systemRoot", "OpenConcerto");
this.props.setProperty("base.root", "Common");
this.props.setProperty("server.ip", "file:${data.dir}/");
}
 
public static final String getDefaultSystemRootName() {
return ComptaPropsConfiguration.APP_NAME;
}
 
public static final boolean containsValidH2DB(File dir) {
if (dir.exists()) {
File db = new File(dir, "OpenConcerto.h2.db");
if (db.exists() && db.length() > 50000) {
return true;
return testH2DBDir(dir) == null;
}
 
public static final String testH2DBDir(File dir) {
final String err;
if (dir == null) {
err = "Dossier de base de données non défini";
} else if (!dir.exists()) {
err = "Dossier de base de données inexistant";
} else {
final String fileName = getDefaultSystemRootName() + ".h2.db";
final File h2File = new File(dir, fileName);
if (!h2File.exists()) {
err = "Le dossier de base de données ne contient pas " + fileName;
} else if (h2File.length() < 50000) {
err = "Le dossier de base de données contient un fichier " + fileName + " vide";
} else {
err = null;
}
return false;
}
return err;
}
 
private void loadConfigFile() {
this.textMainProperties.setText(confFile.getAbsolutePath());
private boolean loadConfigFile() {
this.textMainProperties.setText(this.confFile.getAbsolutePath());
// load defaults since store() only outputs local keys
final Properties defaults = new Properties();
defaults.put("server.driver", "postgresql");
defaults.put("server.ip", "127.0.0.1");
defaults.put("systemRoot", getDefaultSystemRootName());
defaults.put("customer", "Gestion_Default");
this.props.clear();
PropertiesUtils.load(this.props, defaults);
 
if (!this.confFile.exists()) {
System.out.println("Unable to find: " + this.confFile.getAbsolutePath());
 
final File dir1 = new File(Configuration.getDefaultConfDir(), "OpenConcerto-GESTION_DEFAULT/DBData");
final File dir2 = new File(Configuration.getDefaultConfDir(), "OpenConcerto/DBData");
final File dir1 = new File(Configuration.getDefaultConfDir(), ComptaPropsConfiguration.APP_NAME + "-GESTION_DEFAULT/DBData");
final File dir2 = new File(Configuration.getDefaultConfDir(), ComptaPropsConfiguration.APP_NAME + "/DBData");
final File validDir;
if (containsValidH2DB(dir1)) {
this.textFile.setText(dir1.getAbsolutePath());
validDir = dir1;
} else if (containsValidH2DB(dir2)) {
this.textFile.setText(dir2.getAbsolutePath());
validDir = dir2;
} else {
validDir = null;
}
return;
if (validDir != null) {
System.out.println("Found DB in " + validDir);
updateUIForMode(SQLSystem.H2);
this.textFile.setText(validDir.getAbsolutePath());
this.textBase.setText(getDefaultSystemRootName());
}
return validDir != null;
}
System.out.println("Loading: " + this.confFile.getAbsolutePath());
if (!this.confFile.isFile()) {
JOptionPane.showMessageDialog(null, this.confFile + " n'est pas un fichier valide");
154,19 → 206,18
if (!this.confFile.canWrite()) {
JOptionPane.showMessageDialog(null, "Vous n'avez pas les droits de modifier le fichier " + this.confFile);
}
// defaults in constructor so that not every getProperty() needs to provide them (e.g.
// in new ComptaPropsConfiguration())
final Properties defaults = new Properties();
defaults.put("server.ip", "127.0.0.1");
defaults.put("server.driver", "postgresql");
defaults.put("systemRoot", "OpenConcerto");
this.props = new Properties(defaults);
try {
this.props.load(new FileInputStream(this.confFile));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Impossible de lire le fichier " + this.confFile + " \n" + e.getLocalizedMessage());
}
updateUIFromProps();
 
}
return true;
}
 
private void updateUIFromProps() {
try {
updateUIForMode(SQLSystem.get(this.props.getProperty("server.driver")));
} catch (Exception e) {
188,6 → 239,10
}
}
this.textBase.setText(this.props.getProperty("systemRoot"));
if (getToken() != null) {
this.textIP.setText("Cloud OpenConcerto");
this.textPort.setText("");
this.textFile.setText("");
}
}
 
225,7 → 280,9
final String filePath;
if (file.getPath().length() == 0) {
filePath = ComptaPropsConfiguration.DATA_DIR_VAR;
if (getToken() != null) {
JOptionPane.showMessageDialog(null, "Attention. Le dossier de données n'est pas rempli");
}
} else {
// replace getDataDir() by ComptaPropsConfiguration.DATA_DIR_VAR
final File canonFile = file.getCanonicalFile();
240,22 → 297,19
} else {
String ip = config.getIp();
if (ip == null || ip.trim().length() == 0) {
if (getToken() != null) {
ip = "127.0.0.1";
JOptionPane.showMessageDialog(null, "Attention. L'adresse du serveur n'est pas remplie");
}
}
final String port = config.getPort().trim();
serverIp = ip + (port.length() > 0 ? (":" + port) : "");
}
this.props.put("server.driver", serverDriver);
this.props.put("server.ip", serverIp);
if (this.props.getProperty("systemRoot") == null) {
this.props.put("systemRoot", ComptaPropsConfiguration.APP_NAME);
}
if (this.props.getProperty("customer") == null) {
this.props.put("customer", "Gestion_Default");
}
this.props.put("systemRoot", config.getSystemRoot());
out = new FileOutputStream(this.confFile);
this.props.store(out, "OpenConcerto");
this.props.store(out, ComptaPropsConfiguration.APP_NAME);
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Impossible d'écrire le fichier " + this.confFile + " \n" + e.getLocalizedMessage());
282,9 → 336,9
}
}
 
protected void setConfigFile(File f) {
protected boolean setConfigFile(File f) {
this.confFile = f;
this.loadConfigFile();
return this.loadConfigFile();
}
 
private void uiInit() {
297,17 → 351,13
this.add(this.tabbedPane, c);
final JPanel configurationPanel = createPanelConfig();
final JPanel findServerPanel = createPanelFinder();
if (getToken() == null) {
 
this.tabbedPane.addTab("Configuration", configurationPanel);
this.tabbedPane.addTab("Recherche", findServerPanel);
}
 
final ConfigCaissePanel createPanelCaisse = createPanelCaisse();
this.tabbedPane.addTab("Caisse", createPanelCaisse);
this.tabbedPane.addTab("Installation", new InstallationPanel(this));
this.tabbedPane.addTab("Cloud", new CloudPanel(this));
if (getToken() != null) {
this.tabbedPane.setSelectedIndex(2);
}
 
final JPanel buttons = new JPanel();
buttons.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 1));
350,6 → 400,16
}
 
public void updateUIForMode(SQLSystem mode) {
if (getToken() != null) {
// Cloud
this.comboMode.setEnabled(false);
this.comboMode.setSelectedItem(ServerFinderConfig.POSTGRESQL);
this.textIP.setEnabled(false);
this.textPort.setEnabled(false);
this.textFile.setEnabled(false);
this.buttonDir.setEnabled(false);
} else {
this.comboMode.setEnabled(true);
if (mode.equals(ServerFinderConfig.H2)) {
this.comboMode.setSelectedItem(ServerFinderConfig.H2);
this.textIP.setEnabled(false);
372,6 → 432,7
throw new IllegalArgumentException(mode + " is not a valid access mode");
}
}
}
 
private JPanel createPanelConfig() {
JPanel p = new JPanel();
505,6 → 566,7
JOptionPane.showMessageDialog(ServerFinderPanel.this, r);
} catch (InterruptedException ignore) {
} catch (java.util.concurrent.ExecutionException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(ServerFinderPanel.this, e.getMessage());
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/InstallationPanel.java
17,6 → 17,7
import org.openconcerto.erp.modules.ModuleManager;
import org.openconcerto.erp.modules.ModuleReference;
import org.openconcerto.sql.changer.convert.AddFK;
import org.openconcerto.sql.changer.convert.ChangeIDToInt;
import org.openconcerto.sql.changer.correct.CorrectOrder;
import org.openconcerto.sql.changer.correct.FixSerial;
import org.openconcerto.sql.model.AliasedTable;
25,6 → 26,7
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLField.Properties;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLName;
import org.openconcerto.sql.model.SQLRow;
37,11 → 39,10
import org.openconcerto.sql.model.SQLSystem;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.model.SQLField.Properties;
import org.openconcerto.sql.model.graph.SQLKey;
import org.openconcerto.sql.request.Inserter;
import org.openconcerto.sql.request.Inserter.Insertion;
import org.openconcerto.sql.request.UpdateBuilder;
import org.openconcerto.sql.request.Inserter.Insertion;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
import org.openconcerto.sql.utils.AlterTable;
import org.openconcerto.sql.utils.ChangeTable;
294,6 → 295,11
}
updateToV1Dot2(root);
updateToV1Dot3(root);
updateToV1Dot4(root);
updateStyle(root);
createBanque(root);
createAssocAnalytique(root);
updateStock(root);
updateVille(root.getTable("ADRESSE"));
return null;
}
573,6 → 579,103
this.add(comp, c);
}
 
private void addArticleFournisseur(DBRoot root) {
if (!root.contains("ARTICLE_FOURNISSEUR")) {
 
SQLCreateTable createBaseFamille = new SQLCreateTable(root, "FAMILLE_ARTICLE_FOURNISSEUR");
createBaseFamille.addVarCharColumn("CODE", 45);
createBaseFamille.addVarCharColumn("NOM", 2048);
createBaseFamille.addForeignColumn("ID_FAMILLE_ARTICLE_FOURNISSEUR_PERE", createBaseFamille);
final SQLDataSource ds = root.getDBSystemRoot().getDataSource();
 
try {
ds.execute(createBaseFamille.asString());
 
insertUndef(createBaseFamille);
root.refetchTable("FAMILLE_ARTICLE_FOURNISSEUR");
root.getSchema().updateVersion();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table FAMILLE_ARTICLE_FOURNISSEUR", ex);
}
 
SQLCreateTable createBase = new SQLCreateTable(root, "ARTICLE_FOURNISSEUR");
createBase.addVarCharColumn("CODE", 45);
createBase.addVarCharColumn("CODE_BARRE", 45);
createBase.addVarCharColumn("CODE_DOUANIER", 45);
createBase.addVarCharColumn("NOM", 2048);
createBase.addVarCharColumn("DESCRIPTIF", 2048);
createBase.addVarCharColumn("INFOS", 2048);
 
createBase.addColumn("PRIX_METRIQUE_HA_1", "numeric (16,6) DEFAULT 0");
createBase.addColumn("PRIX_METRIQUE_HA_2", "numeric (16,8) DEFAULT 0");
createBase.addColumn("PRIX_METRIQUE_HA_3", "numeric (16,8) DEFAULT 0");
 
createBase.addColumn("PRIX_METRIQUE_VT_1", "numeric (16,8) DEFAULT 0");
createBase.addColumn("PRIX_METRIQUE_VT_2", "numeric (16,8) DEFAULT 0");
createBase.addColumn("PRIX_METRIQUE_VT_3", "numeric (16,8) DEFAULT 0");
 
createBase.addForeignColumn("ID_METRIQUE_1", root.findTable("METRIQUE", true));
createBase.addForeignColumn("ID_METRIQUE_2", root.findTable("METRIQUE", true));
createBase.addForeignColumn("ID_METRIQUE_3", root.findTable("METRIQUE", true));
 
createBase.addColumn("PA_DEVISE", "numeric (16,8) DEFAULT 0");
createBase.addColumn("PV_U_DEVISE", "numeric (16,8) DEFAULT 0");
createBase.addColumn("PA_HT", "numeric (16,8) DEFAULT 0");
createBase.addColumn("PV_HT", "numeric (16,8) DEFAULT 0");
createBase.addColumn("PV_TTC", "numeric (16,2) DEFAULT 0");
 
createBase.addForeignColumn("ID_TAXE", root.findTable("TAXE", true));
createBase.addForeignColumn("ID_FAMILLE_ARTICLE_FOURNISSEUR", root.findTable("FAMILLE_ARTICLE_FOURNISSEUR", true));
createBase.addForeignColumn("ID_MODE_VENTE_ARTICLE", root.findTable("MODE_VENTE_ARTICLE", true));
createBase.addForeignColumn("ID_FOURNISSEUR", root.findTable("FOURNISSEUR", true));
createBase.addForeignColumn("ID_PAYS", root.findTable("PAYS", true));
createBase.addForeignColumn("ID_DEVISE", root.findTable("DEVISE", true));
createBase.addForeignColumn("ID_DEVISE_HA", root.findTable("DEVISE", true));
createBase.addForeignColumn("ID_UNITE_VENTE", root.findTable("UNITE_VENTE", true));
createBase.addForeignColumn("ID_COMPTE_PCE", root.findTable("COMPTE_PCE", true));
createBase.addForeignColumn("ID_COMPTE_PCE_ACHAT", root.findTable("COMPTE_PCE", true));
createBase.addForeignColumn("ID_ARTICLE", root.findTable("ARTICLE", true));
 
createBase.addColumn("POIDS", "real DEFAULT 0");
createBase.addColumn("VALEUR_METRIQUE_1", "real DEFAULT 0");
createBase.addColumn("VALEUR_METRIQUE_2", "real DEFAULT 0");
createBase.addColumn("VALEUR_METRIQUE_3", "real DEFAULT 0");
createBase.addBooleanColumn("SERVICE", Boolean.FALSE, false);
createBase.addBooleanColumn("OBSOLETE", Boolean.FALSE, false);
createBase.addBooleanColumn("GESTION_STOCK", Boolean.FALSE, false);
createBase.addIntegerColumn("QTE_ACHAT", 1);
createBase.addIntegerColumn("QTE_MIN", 1);
 
try {
ds.execute(createBase.asString());
 
insertUndef(createBase);
root.refetchTable("ARTICLE_FOURNISSEUR");
root.getSchema().updateVersion();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table ARTICLE_FOURNISSEUR", ex);
}
}
}
 
private void addContact(DBRoot root) throws SQLException {
 
List<String> tables = Arrays.asList("AVOIR_CLIENT", "DEVIS", "BON_DE_LIVRAISON", "COMMANDE_CLIENT", "SAISIE_VENTE_FACTURE");
for (String tableName : tables) {
 
final SQLTable table = root.getTable(tableName);
final SQLTable tableContact = root.findTable("CONTACT");
if (!table.contains("ID_CONTACT")) {
 
final SQLDataSource dataSource = root.getDBSystemRoot().getDataSource();
final AlterTable alterEcheance = new AlterTable(table);
alterEcheance.addForeignColumn("ID_CONTACT", tableContact);
dataSource.execute(alterEcheance.asString());
table.getSchema().updateVersion();
}
}
}
 
private void addForeignKeyFactureOnEcheance(DBRoot root) {
 
final SQLTable tableEch = root.getTable("ECHEANCE_CLIENT");
658,6 → 761,138
 
}
 
private void createAssocAnalytique(DBRoot root) {
 
if (!root.contains("ASSOCIATION_ANALYTIQUE")) {
 
SQLCreateTable createAssoc = new SQLCreateTable(root, "ASSOCIATION_ANALYTIQUE");
createAssoc.addForeignColumn("ID_ECRITURE", root.findTable("ECRITURE", true));
createAssoc.addForeignColumn("ID_SAISIE_KM_ELEMENT", root.findTable("SAISIE_KM_ELEMENT", true));
createAssoc.addForeignColumn("ID_POSTE_ANALYTIQUE", root.findTable("POSTE_ANALYTIQUE", true));
createAssoc.addColumn("POURCENT", "numeric (16,8) DEFAULT 100");
createAssoc.addColumn("MONTANT", "bigInt DEFAULT 0");
createAssoc.addBooleanColumn("GESTION_AUTO", false, false);
 
final SQLDataSource ds = root.getDBSystemRoot().getDataSource();
 
try {
ds.execute(createAssoc.asString());
 
insertUndef(createAssoc);
root.refetchTable("ASSOCIATION_ANALYTIQUE");
root.getSchema().updateVersion();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table ASSOCIATION_ANALYTIQUE", ex);
}
 
}
}
 
private void updateStock(DBRoot root) throws SQLException {
 
final SQLTable tableStock = root.getTable("STOCK");
final SQLDataSource ds = root.getDBSystemRoot().getDataSource();
if (!tableStock.contains("QTE_RECEPT_ATTENTE")) {
 
try {
 
AlterTable alterElt = new AlterTable(root.getTable("STOCK"));
alterElt.addColumn("QTE_RECEPT_ATTENTE", "real DEFAULT 0");
alterElt.addColumn("QTE_LIV_ATTENTE", "real DEFAULT 0");
ds.execute(alterElt.asString());
 
AlterTable alterMvt = new AlterTable(root.getTable("MOUVEMENT_STOCK"));
alterMvt.addBooleanColumn("REEL", Boolean.TRUE, false);
 
ds.execute(alterMvt.asString());
 
root.getSchema().updateVersion();
 
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la mise à jour des tables de stock", ex);
}
 
}
// if (!root.contains("ARTICLE_ELEMENT")) {
// final SQLCreateTable createTable = new SQLCreateTable(root, "ARTICLE_ELEMENT");
// createTable.addForeignColumn("ARTICLE");
// createTable.addForeignColumn("ID_ARTICLE_PARENT", root.getTable("ARTICLE"));
// createTable.addIntegerColumn("QTE", 1);
// createTable.addDecimalColumn("QTE_UNITAIRE", 16, 6, BigDecimal.valueOf(1), false);
// createTable.addForeignColumn("UNITE_VENTE");
// insertUndef(createTable);
// ds.execute(createTable.asString());
//
// root.getSchema().updateVersion();
// root.refetchTable("ARTICLE_ELEMENT");
//
// }
//
// if (!root.getTable("ARTICLE").contains("COMPOSED")) {
// AlterTable alterMvt = new AlterTable(root.getTable("ARTICLE"));
// alterMvt.addBooleanColumn("COMPOSED", Boolean.FALSE, false);
//
// ds.execute(alterMvt.asString());
//
// root.getSchema().updateVersion();
// }
 
}
 
private void createBanque(DBRoot root) throws SQLException {
 
if (!root.contains("BANQUE") && !root.contains("BANQUE_POLE_PRODUIT")) {
 
SQLCreateTable createBanque = new SQLCreateTable(root, "BANQUE");
createBanque.addForeignColumn("ID_JOURNAL", root.findTable("JOURNAL", true));
createBanque.addVarCharColumn("INFOS", 2048);
createBanque.addVarCharColumn("NUMERO_RUE", 45);
createBanque.addVarCharColumn("RUE", 256);
createBanque.addVarCharColumn("IBAN", 256);
createBanque.addVarCharColumn("BIC", 256);
createBanque.addVarCharColumn("VOIE", 256);
createBanque.addVarCharColumn("VILLE", 256);
createBanque.addVarCharColumn("NOM", 256);
createBanque.addVarCharColumn("DOMICILIATION", 256);
createBanque.addVarCharColumn("CODE", 256);
createBanque.addBooleanColumn("AFFACTURAGE", Boolean.FALSE, false);
createBanque.addForeignColumn("ID_COMPTE_PCE", root.findTable("COMPTE_PCE", true));
 
final SQLDataSource ds = root.getDBSystemRoot().getDataSource();
 
try {
ds.execute(createBanque.asString());
 
insertUndef(createBanque);
root.refetchTable("BANQUE");
{
AlterTable alterElt = new AlterTable(root.getTable("MODE_REGLEMENT"));
alterElt.addForeignColumn("ID_BANQUE", root.getTable("BANQUE"));
 
ds.execute(alterElt.asString());
}
 
{
AlterTable alterElt = new AlterTable(root.getTable("CHEQUE_A_ENCAISSER"));
alterElt.addForeignColumn("ID_BANQUE", root.getTable("BANQUE"));
ds.execute(alterElt.asString());
}
 
{
AlterTable alterElt = new AlterTable(root.getTable("CHEQUE_FOURNISSEUR"));
alterElt.addForeignColumn("ID_BANQUE", root.getTable("BANQUE"));
ds.execute(alterElt.asString());
}
 
root.getSchema().updateVersion();
 
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table BANQUE", ex);
}
 
}
}
 
private void createFactureFournisseur(DBRoot root) throws SQLException {
boolean refetchRoot = false;
if (!root.contains("FACTURE_FOURNISSEUR")) {
819,6 → 1054,7
builds.add(build);
}
 
if (tableAvoir.contains("POURCENT_REMISE")) {
SQLField fieldRemiseAvoir = tableAvoir.getField("POURCENT_REMISE");
if (fieldRemiseAvoir.getType().getSize() > 500) {
final String fName = fieldRemiseAvoir.getName();
829,7 → 1065,7
build.setWhere(new Where(fieldRemiseAvoir, "=", (Object) null));
builds.add(build);
}
 
}
if (!alter.isEmpty())
alters.add(alter);
}
1148,8 → 1384,13
SQLInjector.createTransferTables(root);
// Move transfer info to SAISIE_VENTE_FACTURE
convertTransfer(root, Arrays.asList("COMMANDE_CLIENT", "DEVIS", "BON_DE_LIVRAISON"), "SAISIE_VENTE_FACTURE");
 
// Fix keys
if (root.getServer().getSQLSystem().equals(SQLSystem.H2)) {
final ChangeIDToInt c = new ChangeIDToInt(root.getDBSystemRoot());
c.changeAll(root);
root.getDBSystemRoot().reload(Collections.singleton(root.getName()));
}
}
 
private void convertTransfer(DBRoot root, List<String> tablesSrc, String tableDest) throws SQLException {
final SQLTable tableDestination = root.getTable(tableDest);
1227,6 → 1468,98
}
}
 
private void updateToV1Dot4(final DBRoot root) throws SQLException {
SQLTable tableVFElt = root.getTable("SAISIE_VENTE_FACTURE_ELEMENT");
patchFieldElt1Dot4(tableVFElt, root);
 
SQLTable tableDevisElt = root.getTable("DEVIS_ELEMENT");
patchFieldElt1Dot4(tableDevisElt, root);
 
SQLTable tableCmdElt = root.getTable("COMMANDE_CLIENT_ELEMENT");
patchFieldElt1Dot4(tableCmdElt, root);
 
SQLTable tableBonElt = root.getTable("BON_DE_LIVRAISON_ELEMENT");
patchFieldElt1Dot4(tableBonElt, root);
 
SQLTable tableAvoirElt = root.getTable("AVOIR_CLIENT_ELEMENT");
patchFieldElt1Dot4(tableAvoirElt, root);
 
addContact(root);
 
final SQLTable tableDevis = root.getTable("DEVIS");
if (!tableDevis.contains("MONTANT_REMISE")) {
AlterTable t = new AlterTable(tableDevis);
t.addColumn("POURCENT_REMISE", "numeric (12,8)");
t.addColumn("MONTANT_REMISE", "numeric (16,8)");
tableDevis.getBase().getDataSource().execute(t.asString());
tableDevis.getSchema().updateVersion();
tableDevis.fetchFields();
}
 
final SQLTable tableKmElt = root.getTable("SAISIE_KM_ELEMENT");
if (!tableKmElt.contains("ANALYTIQUE")) {
AlterTable t = new AlterTable(tableKmElt);
t.addVarCharColumn("ANALYTIQUE", 256);
tableKmElt.getBase().getDataSource().execute(t.asString());
tableKmElt.getSchema().updateVersion();
tableKmElt.fetchFields();
 
}
 
final SQLTable tableAdresse = root.getTable("ADRESSE");
if (tableAdresse != null && !tableAdresse.contains("PROVINCE")) {
AlterTable t = new AlterTable(tableAdresse);
t.addVarCharColumn("PROVINCE", 256);
t.addVarCharColumn("TYPE", 256);
t.addVarCharColumn("EMAIL_CONTACT", 256);
tableAdresse.getBase().getDataSource().execute(t.asString());
tableAdresse.getSchema().updateVersion();
tableAdresse.fetchFields();
}
final SQLTable tableClient = root.getTable("CLIENT");
if (tableClient != null && !tableClient.contains("BLOQUE_LIVRAISON")) {
AlterTable t = new AlterTable(tableClient);
t.addBooleanColumn("BLOQUE_LIVRAISON", false, false);
if (!tableClient.contains("BLOQUE")) {
t.addBooleanColumn("BLOQUE", false, false);
}
tableClient.getBase().getDataSource().execute(t.asString());
tableClient.getSchema().updateVersion();
tableClient.fetchFields();
}
final SQLTable tableAssoc = root.getTable("ASSOCIATION_ANALYTIQUE");
if (tableAssoc != null && !tableAssoc.contains("GESTION_AUTO")) {
AlterTable t = new AlterTable(tableAssoc);
t.addBooleanColumn("GESTION_AUTO", false, false);
tableAssoc.getBase().getDataSource().execute(t.asString());
tableAssoc.getSchema().updateVersion();
tableAssoc.fetchFields();
}
 
addArticleFournisseur(root);
}
 
private void updateStyle(final DBRoot root) throws SQLException {
SQLTable style = root.getTable("STYLE");
SQLRowValues rowVals = new SQLRowValues(style);
rowVals.put("NOM", null);
SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(rowVals);
List<SQLRowValues> list = fetcher.fetch();
boolean containsInvisible = false;
for (SQLRowValues sqlRowValues : list) {
if (sqlRowValues.getString("NOM").equals("Invisible")) {
containsInvisible = true;
}
}
if (!containsInvisible) {
SQLRowValues rowValsStyle = new SQLRowValues(style);
rowValsStyle.put("NOM", "Invisible");
rowValsStyle.put("CODE", "INV");
rowValsStyle.insert();
}
 
}
 
private void updateToV1Dot2(final DBRoot root) throws SQLException {
// bigint -> int ID_METRIQUE BON_DE_LIVRAISON_ELEMENT
final SQLTable tableLivraisonElement = root.getTable("BON_DE_LIVRAISON_ELEMENT");
1275,7 → 1608,7
rowValsOrdre.put("ORDRE", new BigDecimal(3.505));
rowValsOrdre.update(EtatDevisSQLElement.REFUSE);
 
rowValsOrdre.put("ORDRE", new BigDecimal(3.505));
rowValsOrdre.put("ORDRE", new BigDecimal(4.505));
rowValsOrdre.update(EtatDevisSQLElement.EN_COURS);
 
// Ajout de la TVA à 0
2048,6 → 2381,36
 
}
 
private void patchFieldElt1Dot4(SQLTable table, DBRoot root) {
 
if (!table.contains("MONTANT_REMISE")) {
AlterTable t = new AlterTable(table);
t.alterColumn("POURCENT_REMISE", EnumSet.allOf(Properties.class), "numeric(12,8)", "0", true);
t.addColumn("MONTANT_REMISE", "numeric (16,8)");
 
try {
 
table.getBase().getDataSource().execute(t.asString());
table.getSchema().updateVersion();
table.fetchFields();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de l'ajout des champs à la table " + table.getName(), ex);
}
}
if (!table.contains("NIVEAU")) {
AlterTable t = new AlterTable(table);
t.addIntegerColumn("NIVEAU", 1);
try {
table.getBase().getDataSource().execute(t.asString());
table.getSchema().updateVersion();
table.fetchFields();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de l'ajout du niveau à la table " + table.getName(), ex);
}
}
 
}
 
private void addHAElementField(SQLTable table, DBRoot root) throws SQLException {
 
boolean alter = false;
2362,6 → 2725,8
} catch (SQLException e1) {
throw new IllegalStateException("Erreur lors de la mise à jour des indéfinis de la table CAISSE", e1);
}
} catch (Exception e) {
ExceptionHandler.handle("updateSocieteSchema on root " + root + " failed", e);
} finally {
// Mise à jour du schéma
root.getSchema().updateVersion();
2621,6 → 2986,11
alter = true;
}
 
if (!table.getFieldsName().contains("ID_DEVISE")) {
t.addForeignColumn("ID_DEVISE", root.getTable("DEVISE"));
alter = true;
}
 
if (!table.getFieldsName().contains("CAPITAL")) {
t.addColumn("CAPITAL", "bigint DEFAULT 0");
alter = true;
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ServerFinderConfig.java
24,7 → 24,6
import java.io.File;
import java.util.Properties;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
 
public class ServerFinderConfig {
90,18 → 89,10
}
 
public void setFile(File file) {
if (file == null) {
JOptionPane.showMessageDialog(new JFrame(), "Dossier de base de données non défini");
} else if (!file.exists()) {
JOptionPane.showMessageDialog(new JFrame(), "Dossier de base de données inexistant");
} else {
final File h2File = new File(file, "OpenConcerto.h2.db");
if (!h2File.exists()) {
JOptionPane.showMessageDialog(new JFrame(), "Le dossier de base de données ne contient pas OpenConcerto.h2.db");
} else if (h2File.length() < 50000) {
JOptionPane.showMessageDialog(new JFrame(), "Le dossier de base de données contient un fichier OpenConcerto.h2.db vide");
final String err = ServerFinderPanel.testH2DBDir(file);
if (err != null) {
JOptionPane.showMessageDialog(null, err);
}
}
this.file = file;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mapping_en.xml
189,6 → 189,7
<FIELD name="RCS" label="RCS" />
<FIELD name="CAPITAL" label="Capital" />
<FIELD name="NUMERO_URSSAF" label="URSSAF number" />
<FIELD name="ID_DEVISE" label="Currency" />
</TABLE>
 
<TABLE name="TYPE_MODELE">
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mapping-KD_fr.xml
New file
0,0 → 1,113
<?xml version="1.0" encoding="UTF-8" ?>
<ROOT>
 
<TABLE name="AFFAIRE_ELEMENT">
<FIELD name="ACTIVITE" label="Domaine" titlelabel="Domaine" />
<FIELD name="SOUS_ACTIVITE" label="Sous domaine" titlelabel="Sous domaine" />
<FIELD name="POURCENT_REALISE" label="% déjà réalisé"
titlelabel="% déjà réalisé" />
<FIELD name="TOTAL_HT_REALISE" label="Total déjà facturé"
titlelabel="Total déjà facturé" />
<FIELD name="ID_CODE_MISSION" label="Code Mission" />
<FIELD name="ID_DEPARTEMENT" label="Département" />
<FIELD name="ID_TARIF_MISSION" label="Code Client" />
</TABLE>
 
<TABLE name="CODE_MISSION">
<FIELD name="ACTIVITE" label="Domaine" titlelabel="Domaine" />
<FIELD name="OBJET_INSPECTE" label="Objet inspecté" />
<FIELD name="DUREE_MISSION" label="Durée prévue" />
<FIELD name="SOUS_TRAITANT" label="Sous traitant" />
<FIELD name="MAQUETTE" label="Maquette" />
<FIELD name="CONDITIONS" label="Conditions d'intervention" />
<FIELD name="SOUS_ACTIVITE" label="Sous domaine" titlelabel="Sous domaine" />
</TABLE>
 
<TABLE name="AVOIR_CLIENT_ELEMENT">
<FIELD name="ID_CODE_MISSION" label="Code Mission" />
<FIELD name="ID_PERIODICITE" label="Pério. Contractuelle" />
<FIELD name="ID_TARIF_MISSION" label="Code Tarif" />
</TABLE>
 
<TABLE name="DEVIS">
<FIELD name="NUMERO" label="Numéro" />
<FIELD name="OBJET" label="Référence cmd client" />
<FIELD name="DATE_PREV" label="Intervention prévue le" />
<FIELD name="INDICE_0" label="Indice Syntec de base" />
</TABLE>
 
<TABLE name="DEVIS_ELEMENT">
<FIELD name="ID_CODE_MISSION" label="Code Mission" />
<FIELD name="ID_PERIODICITE" label="Pério. Contractuelle" />
<FIELD name="ID_TARIF_MISSION" label="Code Tarif" />
</TABLE>
 
 
<TABLE name="FICHE_RENDEZ_VOUS">
<FIELD name="ACTIVITE" label="Domaine" titlelabel="Domaine" />
</TABLE>
 
<TABLE name="FICHE_RENDEZ_VOUS_ELEMENT">
<FIELD name="ACTIVITE" label="Domaine" titlelabel="Domaine" />
<FIELD name="SOUS_ACTIVITE" label="Sous Domaine" titlelabel="Sous Domaine" />
</TABLE>
 
 
<TABLE name="LOG_MAILPROCESSOR">
<FIELD name="DATE" label="Date" />
<FIELD name="SIRET" label="Siret" />
<FIELD name="EXPEDITEUR" label="Expéditeur" />
<FIELD name="MAILBOX" label="Destinataire" />
<FIELD name="INFO" label="Informations" />
</TABLE>
 
 
<TABLE name="PROPOSITION_ELEMENT">
<FIELD name="ACTIVITE" label="Domaine" titlelabel="Domaine" />
<FIELD name="SOUS_ACTIVITE" label="Sous Domaine" titlelabel="Sous Domaine" />
</TABLE>
 
<TABLE name="SAISIE_VENTE_FACTURE_ELEMENT">
<FIELD name="ID_CODE_MISSION" label="Code Mission" />
<FIELD name="ID_DEPARTEMENT" label="Département" />
<FIELD name="ID_PERIODICITE" label="Pério. Contractuelle" />
<FIELD name="ID_TARIF_MISSION" label="Code Tarif" />
<FIELD name="ACTIVITE" label="Domaine" titlelabel="Domaine" />
<FIELD name="SOUS_ACTIVITE" label="Sous Domaine" titlelabel="Sous Domaine" />
<FIELD name="REPARTITION_POURCENT" label="Répartition %"
titlelabel="Répartition %" />
</TABLE>
<TABLE name="AVOIR_CLIENT_ELEMENT">
<FIELD name="ID_CODE_MISSION" label="Code Mission" />
<FIELD name="ID_DEPARTEMENT" label="Département" />
<FIELD name="ID_PERIODICITE" label="Pério. Contractuelle" />
<FIELD name="ID_TARIF_MISSION" label="Code Tarif" />
<FIELD name="ACTIVITE" label="Domaine" titlelabel="Domaine" />
<FIELD name="SOUS_ACTIVITE" label="Sous Domaine" titlelabel="Sous Domaine" />
<FIELD name="REPARTITION_POURCENT" label="Répartition %"
titlelabel="Répartition %" />
</TABLE>
 
<TABLE name="SAISIE_VENTE_FACTURE">
<FIELD name="TYPE_INTERVENTION" label="Numéro Intervention"
titlelabel="Numéro Intervention" />
</TABLE>
 
<TABLE name="TARIF_MISSION_LIBELLE">
<FIELD name="NOM" label="Intitulé tarif" />
</TABLE>
 
<TABLE name="TARIF_MISSION">
<FIELD name="CODE_CLIENT" label="Code Tarif" />
<FIELD name="TARIF_HT" label="Tarif" />
<FIELD name="ID_TARIF_MISSION_LIBELLE" label="Tarif" />
<FIELD name="ID_CODE_MISSION" label="Mission" />
</TABLE>
 
<TABLE name="AVOIR_CLIENT">
<FIELD name="NOM" label="Référence" titlelabel="Référence" />
</TABLE>
 
</ROOT>
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ComptaPropsConfiguration.java
17,6 → 17,7
import org.openconcerto.erp.core.common.component.SocieteCommonSQLElement;
import org.openconcerto.erp.core.common.element.AdresseCommonSQLElement;
import org.openconcerto.erp.core.common.element.AdresseSQLElement;
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.element.DepartementSQLElement;
import org.openconcerto.erp.core.common.element.LangueSQLElement;
import org.openconcerto.erp.core.common.element.MoisSQLElement;
135,6 → 136,8
import org.openconcerto.erp.core.supplychain.order.element.SaisieAchatSQLElement;
import org.openconcerto.erp.core.supplychain.order.element.TransferPurchaseSQLElement;
import org.openconcerto.erp.core.supplychain.order.element.TransferSupplierOrderSQLElement;
import org.openconcerto.erp.core.supplychain.product.element.ArticleFournisseurSQLElement;
import org.openconcerto.erp.core.supplychain.product.element.FamilleArticleFounisseurSQLElement;
import org.openconcerto.erp.core.supplychain.receipt.element.BonReceptionElementSQLElement;
import org.openconcerto.erp.core.supplychain.receipt.element.BonReceptionSQLElement;
import org.openconcerto.erp.core.supplychain.receipt.element.CodeFournisseurSQLElement;
155,6 → 158,9
import org.openconcerto.erp.generationDoc.provider.LabelAccountInvoiceProvider;
import org.openconcerto.erp.generationDoc.provider.MergedGlobalQtyTotalProvider;
import org.openconcerto.erp.generationDoc.provider.ModeDeReglementDetailsProvider;
import org.openconcerto.erp.generationDoc.provider.PaiementRemainedProvider;
import org.openconcerto.erp.generationDoc.provider.PrixUVProvider;
import org.openconcerto.erp.generationDoc.provider.PrixUnitaireProvider;
import org.openconcerto.erp.generationDoc.provider.PrixUnitaireRemiseProvider;
import org.openconcerto.erp.generationDoc.provider.QteTotalProvider;
import org.openconcerto.erp.generationDoc.provider.RefClientValueProvider;
342,7 → 348,10
return new ComptaPropsConfiguration(props, inWebStart, true);
} catch (final IOException e) {
e.printStackTrace();
ExceptionHandler.die("Impossible de lire le fichier de configuration.", e);
String title = "Logiciel non configuré";
String message = "Impossible de lire le fichier de configuration.\nIl est nécessaire d'utiliser le logiciel de Configuration pour paramétrer le logiciel.";
JOptionPane.showMessageDialog(new JFrame(), message, title, JOptionPane.ERROR_MESSAGE);
System.exit(2);
// never reached since we're already dead
return null;
}
440,6 → 449,8
UserModifyInitialsValueProvider.register();
UserCurrentInitialsValueProvider.register();
PrixUnitaireRemiseProvider.register();
PrixUnitaireProvider.register();
PrixUVProvider.register();
TotalAcompteProvider.register();
FacturableValueProvider.register();
TotalCommandeClientProvider.register();
454,6 → 465,7
ModeDeReglementDetailsProvider.register();
FormatedGlobalQtyTotalProvider.register();
MergedGlobalQtyTotalProvider.register();
PaiementRemainedProvider.register();
}
 
@Override
563,15 → 575,15
return new File(this.getConfDir(), "DBData");
}
 
private final void createDB() {
private final void createDB(final DBSystemRoot sysRoot) {
if (!this.isServerless())
return;
// super to avoid infinite recursion, and so we can close it afterwards
final SQLServer tmpServer = super.createServer();
try {
// H2 create the database on connection
final DBSystemRoot sysRoot = tmpServer.getSystemRoot(this.getSystemRootName());
if (!sysRoot.contains(getRootName())) {
// don't create if root explicitly excluded (e.g. map no roots just to quickly test
// connection)
if (sysRoot.shouldMap(getRootName()) && !sysRoot.contains(getRootName())) {
Log.get().warning("Creating DB");
String createScript = null;
try {
createScript = this.getResource("/webstart/create.sql");
581,17 → 593,25
if (createScript == null)
throw new IllegalStateException("Couldn't find database creation script");
final SQLDataSource ds = sysRoot.getDataSource();
ds.execute("RUNSCRIPT from '" + createScript + "' ;");
ds.execute("RUNSCRIPT from '" + createScript + "' CHARSET 'UTF-8' ;");
sysRoot.refetch();
this.setupSystemRoot(sysRoot);
}
} finally {
tmpServer.destroy();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException("Couldn't create database", e);
}
}
 
@Override
protected DBSystemRoot createSystemRoot() {
this.createDB();
return super.createSystemRoot();
final DBSystemRoot res = super.createSystemRoot();
// Don't create a separate server for createDB() as on normal databases just setting up a
// data source can take 2 seconds (e.g. validateConnectionFactory()). And this is for every
// boot.
this.createDB(res);
return res;
}
 
@Override
644,6 → 664,7
SQLElementDirectory dir = this.getDirectory();
dir.addSQLElement(ArticleTarifSQLElement.class);
dir.addSQLElement(ArticleDesignationSQLElement.class);
dir.addSQLElement(BanqueSQLElement.class);
dir.addSQLElement(ContactFournisseurSQLElement.class);
dir.addSQLElement(ContactAdministratifSQLElement.class);
dir.addSQLElement(new TitrePersonnelSQLElement());
679,6 → 700,8
dir.addSQLElement(new AdresseSQLElement());
 
dir.addSQLElement(ReferenceArticleSQLElement.class);
dir.addSQLElement(ArticleFournisseurSQLElement.class);
dir.addSQLElement(FamilleArticleFounisseurSQLElement.class);
 
dir.addSQLElement(new AssociationCompteAnalytiqueSQLElement());
dir.addSQLElement(new AvoirClientSQLElement());
792,6 → 815,8
dir.addSQLElement(new SaisieVenteComptoirSQLElement());
dir.addSQLElement(new SaisieVenteFactureSQLElement());
dir.addSQLElement(new TransferInvoiceSQLElement());
// at the end since it specifies action which initialize foreign keys
dir.addSQLElement(AssociationAnalytiqueSQLElement.class);
dir.addSQLElement(new SaisieVenteFactureItemSQLElement());
 
dir.addSQLElement(SituationFamilialeSQLElement.class);
861,7 → 886,7
private void setSocieteShowAs() {
final ShowAs showAs = this.getShowAs();
showAs.setRoot(getRootSociete());
showAs.show("ARTICLE", "NOM", "ID_FAMILLE_ARTICLE");
 
showAs.show("ACTIVITE", "CODE_ACTIVITE");
showAs.show("ADRESSE", SQLRow.toList("RUE,CODE_POSTAL,VILLE"));
final DBRoot root = this.getRootSociete();
868,6 → 893,15
 
showAs.show("AXE_ANALYTIQUE", "NOM");
 
List<String> lEcr = new ArrayList<String>();
 
lEcr.add("ID_MOUVEMENT");
lEcr.add("ID_JOURNAL");
lEcr.add("ID_COMPTE_PCE");
lEcr.add("DATE");
 
showAs.show(root.getTable("ASSOCIATION_ANALYTIQUE").getField("ID_ECRITURE"), lEcr);
 
showAs.show("CHEQUE_A_ENCAISSER", "MONTANT", "ID_CLIENT");
if (getRootSociete().getTable("CLIENT").getFieldsName().contains("LOCALISATION")) {
showAs.show("CLIENT", "NOM", "LOCALISATION");
875,6 → 909,8
showAs.show("CLIENT", "NOM");
}
 
showAs.show(BanqueSQLElement.TABLENAME, "NOM");
 
showAs.show("CLASSEMENT_CONVENTIONNEL", "NIVEAU", "COEFF");
showAs.show("CODE_EMPLOI", SQLRow.toList("CODE,NOM"));
showAs.show("CODE_CONTRAT_TRAVAIL", SQLRow.toList("CODE,NOM"));
900,9 → 936,13
 
showAs.show("ECRITURE", SQLRow.toList("NOM,DATE,ID_COMPTE_PCE,DEBIT,CREDIT"));
showAs.show("ECHEANCE_CLIENT", SQLRow.toList("ID_CLIENT,ID_MOUVEMENT"));
final List<String> lEchFact = new ArrayList<String>();
lEchFact.add("NUMERO");
lEchFact.add("DATE");
SQLTable tableEch = root.getTable("ECHEANCE_CLIENT");
showAs.show(tableEch.getField("ID_SAISIE_VENTE_FACTURE"), lEchFact);
 
showAs.show("ECHEANCE_FOURNISSEUR", SQLRow.toList("ID_FOURNISSEUR,ID_MOUVEMENT"));
showAs.show("FAMILLE_ARTICLE", "NOM");
showAs.show("FICHE_PAYE", SQLRow.toList("ID_MOIS,ANNEE"));
showAs.show("FOURNISSEUR", "NOM");
 
941,7 → 981,7
showAs.show("SALARIE", SQLRow.toList("CODE,NOM,PRENOM"));
 
showAs.show("SITUATION_FAMILIALE", "NOM");
showAs.show("STOCK", "QTE_REEL");
 
showAs.show("STYLE", "NOM");
 
showAs.show("TAXE", "TAUX");
974,16 → 1014,19
loadTranslations(this.getTranslator(), rootSociete, Arrays.asList("mappingCompta", "mapping-" + customerName));
setSocieteShowAs();
setSocieteSQLInjector();
setMapper();
configureGlobalMapper();
setFieldMapper(new FieldMapper(this.getRootSociete()));
getFieldMapper().addMapperStreamFromClass(Gestion.class);
TemplateNXProps.getInstance();
// Prefetch undefined
rootSociete.getTables().iterator().next().getUndefinedID();
}
 
private void setMapper() {
private void configureGlobalMapper() {
 
FieldMapper fieldMapper = new FieldMapper(this.getRootSociete());
fieldMapper.addMapperStreamFromClass(Gestion.class);
setFieldMapper(fieldMapper);
 
}
 
private void closeSocieteConnexion() {
1005,7 → 1048,6
SQLServer server = super.createServer();
return server;
}
 
InProgressFrame progress = new InProgressFrame();
progress.show("Connexion à votre base de données en cours");
try {
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleManager.java
52,7 → 52,7
import org.openconcerto.sql.utils.SQLCreateTable;
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.sql.utils.SQLUtils.SQLFactory;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.IListeAction;
import org.openconcerto.ui.SwingThreadUtils;
import org.openconcerto.utils.CollectionMap2.Mode;
import org.openconcerto.utils.CollectionUtils;
889,6 → 889,9
for (final String added : ctxt.getAddedTables()) {
vals.put(TABLE_COLNAME, added).put(FIELD_COLNAME, null).insert();
final SQLTable t = ctxt.getRoot().findTable(added);
if (t == null) {
throw new IllegalStateException("Unable to find added table " + added + " in root " + ctxt.getRoot().getName());
}
for (final SQLField field : t.getFields()) {
vals.put(TABLE_COLNAME, added).put(FIELD_COLNAME, field.getName()).put(ISKEY_COLNAME, field.isKey()).insert();
}
1066,7 → 1069,9
final IdentityHashMap<SQLElement, SQLElement> elements = new IdentityHashMap<SQLElement, SQLElement>();
// 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()) {
// copy to be able to restore elements while iterating
final IdentitySet<SQLElement> afterElementsSet = new IdentityHashSet<SQLElement>(dir.getElements());
for (final SQLElement elem : afterElementsSet) {
if (!beforeElementsSet.contains(elem)) {
if (!(elem instanceof ModuleElement))
L.warning("Module added an element that isn't a ModuleElement : " + elem);
1078,11 → 1083,17
// private constructor, final method).
final boolean codeSafe = replacedElem.getClass().isInstance(elem);
 
if (codeSafe && isMngrSafe(module, replacedElem)) {
final boolean mngrSafe = isMngrSafe(module, replacedElem);
if (codeSafe && mngrSafe) {
// store replacedElem so that it can be restored in unregister()
elements.put(elem, replacedElem);
} else {
L.warning("Trying to replace element for " + elem.getTable() + " with " + elem);
final List<String> pbs = new ArrayList<String>(2);
if (!codeSafe)
pbs.add(elem + " isn't a subclass of " + replacedElem);
if (!mngrSafe)
pbs.add(module + " doesn't depend on " + replacedElem);
L.warning("Trying to replace element for " + elem.getTable() + " with " + elem + " but\n" + CollectionUtils.join(pbs, "\n"));
dir.addSQLElement(replacedElem);
}
} else {
1706,7 → 1717,7
final InputStream ins = module.getClass().getResourceAsStream(resourceName);
// do not force to have one mapping for each locale
if (ins != null) {
Log.get().info("module " + module.getName() + " loading translation from " + resourceName);
L.config("module " + module.getName() + " loading translation from " + resourceName);
final Set<SQLTable> loadedTables;
try {
loadedTables = trns.load(getRoot(), mdVariant, ins).get0();
1899,10 → 1910,10
final String id = module.getFactory().getID();
if (this.modulesComponents.containsKey(id)) {
final ComponentsContext ctxt = this.modulesComponents.remove(id);
for (final Entry<SQLElement, Collection<String>> e : ctxt.getFields().entrySet())
for (final Entry<SQLElement, ? extends Collection<String>> e : ctxt.getFields().entrySet())
for (final String fieldName : e.getValue())
e.getKey().removeAdditionalField(fieldName);
for (final Entry<SQLElement, Collection<RowAction>> e : ctxt.getRowActions().entrySet())
for (final Entry<SQLElement, ? extends Collection<IListeAction>> e : ctxt.getRowActions().entrySet())
e.getKey().getRowActions().removeAll(e.getValue());
TranslationManager.getInstance().removeTranslationStreamFromClass(module.getClass());
// can't undo so menu is reset in stopModule()
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ComponentsContext.java
21,8 → 21,7
import org.openconcerto.sql.view.DropManager;
import org.openconcerto.sql.view.FileDropHandler;
import org.openconcerto.sql.view.list.IListeAction;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ListMap;
 
import java.util.Set;
 
38,23 → 37,23
 
private final Set<String> createdTables;
// only for non-created tables
private final CollectionMap<String, String> createdFields;
private final ListMap<String, String> createdFields;
// * module items
private final CollectionMap<SQLElement, String> fields;
private final CollectionMap<SQLElement, RowAction> rowActions;
private final ListMap<SQLElement, String> fields;
private final ListMap<SQLElement, IListeAction> rowActions;
 
ComponentsContext(SQLElementDirectory dir, DBRoot root, final Set<String> tables, final Set<SQLName> fields) {
super(dir, root);
this.createdTables = tables;
this.createdFields = new CollectionMap<String, String>();
this.createdFields = new ListMap<String, String>();
for (final SQLName f : fields) {
assert f.getItemCount() == 2;
final String tableName = f.getFirst();
if (!this.createdTables.contains(tableName))
this.createdFields.put(tableName, f.getItem(1));
this.createdFields.add(tableName, f.getItem(1));
}
this.fields = new CollectionMap<SQLElement, String>();
this.rowActions = new CollectionMap<SQLElement, RowAction>();
this.fields = new ListMap<SQLElement, String>();
this.rowActions = new ListMap<SQLElement, IListeAction>();
}
 
private final SQLElement checkField(final String tableName, final String name) {
68,7 → 67,7
public final void putAdditionalField(final String tableName, final String name) {
final SQLElement elem = checkField(tableName, name);
if (elem.putAdditionalField(name)) {
this.fields.put(elem, name);
this.fields.add(elem, name);
} else {
throw new IllegalStateException("Already added " + name + " in " + elem);
}
77,7 → 76,7
public final void putAdditionalField(final String tableName, final String name, final JTextComponent comp) {
final SQLElement elem = checkField(tableName, name);
if (elem.putAdditionalField(name, comp)) {
this.fields.put(elem, name);
this.fields.add(elem, name);
} else {
throw new IllegalStateException("Already added " + name + " in " + elem);
}
86,13 → 85,13
public final void putAdditionalField(final String tableName, final String name, final SQLTextCombo comp) {
final SQLElement elem = checkField(tableName, name);
if (elem.putAdditionalField(name, comp)) {
this.fields.put(elem, name);
this.fields.add(elem, name);
} else {
throw new IllegalStateException("Already added " + name + " in " + elem);
}
}
 
final CollectionMap<SQLElement, String> getFields() {
final ListMap<SQLElement, String> getFields() {
return this.fields;
}
 
100,11 → 99,11
 
public final void addListAction(final String tableName, final IListeAction action) {
final SQLElement elem = getElement(tableName);
this.rowActions.put(elem, action);
this.rowActions.add(elem, action);
elem.getRowActions().add(action);
}
 
final CollectionMap<SQLElement, RowAction> getRowActions() {
final ListMap<SQLElement, IListeAction> getRowActions() {
return this.rowActions;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/DBContext.java
21,7 → 21,7
import org.openconcerto.sql.utils.DropTable;
import org.openconcerto.sql.utils.SQLCreateTable;
import org.openconcerto.sql.utils.SQLCreateTableBase;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.SetMap;
import org.openconcerto.utils.cc.IClosure;
 
import java.io.File;
28,7 → 28,6
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
51,7 → 50,7
private final List<IClosure<? super DBRoot>> dm;
 
private final Set<String> tables;
private final CollectionMap<String, SQLField> fields;
private final SetMap<String, SQLField> fields;
 
DBContext(final File dir, final ModuleVersion localVersion, final DBRoot root, final ModuleVersion dbVersion, final Set<String> tables, final Set<SQLName> fields) {
super();
60,10 → 59,10
this.lastInstalledVersion = dbVersion;
this.root = root;
this.tables = Collections.unmodifiableSet(tables);
this.fields = new CollectionMap<String, SQLField>(new HashSet<SQLField>());
this.fields = new SetMap<String, SQLField>();
for (final SQLName f : fields) {
final String tableName = f.getItem(0);
this.fields.put(tableName, this.root.getTable(tableName).getField(f.getItem(1)));
this.fields.add(tableName, this.root.getTable(tableName).getField(f.getItem(1)));
}
this.changeTables = new ArrayList<ChangeTable<?>>();
this.alterTables = new ArrayList<AlterTableRestricted>();
91,7 → 90,7
}
 
public final Set<SQLField> getFieldsPreviouslyCreated(String tableName) {
return (Set<SQLField>) this.fields.getNonNull(tableName);
return this.fields.getNonNull(tableName);
}
 
private final List<String> getSQL() {
/trunk/OpenConcerto/src/org/openconcerto/erp/action/SauvegardeBaseAction.java
13,17 → 13,15
package org.openconcerto.erp.action;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.config.Log;
import org.openconcerto.erp.generationDoc.DocumentLocalStorageManager;
import org.openconcerto.erp.preferences.BackupNXProps;
import org.openconcerto.erp.preferences.TemplateNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.utils.BackupPanel;
 
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
 
31,15 → 29,7
import javax.swing.JFrame;
 
public class SauvegardeBaseAction extends CreateFrameAbstractAction {
 
public SauvegardeBaseAction() {
super();
this.putValue(Action.NAME, "Sauvegarde de la base");
}
 
@Override
public JFrame createFrame() {
final JFrame frame = new JFrame();
static public final List<File> getDirs() {
final List<File> dirs = new ArrayList<File>();
TemplateNXProps nxprops = (TemplateNXProps) TemplateNXProps.getInstance();
final String defaultLocation = nxprops.getDefaultStringValue();
49,10 → 39,6
if (defaultLocationFile.exists()) {
dirs.add(defaultLocationFile);
}
final String serverIp = ((ComptaPropsConfiguration) Configuration.getInstance()).getServerIp();
if (serverIp != null && serverIp.startsWith("file:")) {
locations.add(serverIp.substring(5));
}
 
final DocumentLocalStorageManager storage = DocumentLocalStorageManager.getInstance();
 
65,21 → 51,30
}
 
for (String string : locations) {
 
if (!string.startsWith(defaultLocation)) {
final File f = new File(string);
if (f.exists()) {
System.out.println("Directory to backup:" + string);
dirs.add(f);
} else {
System.out.println(string + " not found");
Log.get().config(string + " not found");
}
} else {
System.out.println(string + " already in backup path");
Log.get().config(string + " already in backup path");
}
}
 
frame.setContentPane(new BackupPanel(Arrays.asList("Common", ((ComptaPropsConfiguration) Configuration.getInstance()).getSocieteBaseName()), dirs, false, BackupNXProps.getInstance()));
return dirs;
}
 
public SauvegardeBaseAction() {
super();
this.putValue(Action.NAME, "Sauvegarde de la base");
}
 
@Override
public JFrame createFrame() {
final JFrame frame = new JFrame();
frame.setContentPane(new BackupPanel(null, getDirs(), false, BackupNXProps.getInstance()));
frame.setTitle("Sauvegarde des données");
// so that the application can exit
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
/trunk/OpenConcerto/src/org/openconcerto/erp/action/CreateListFrameAbstractAction.java
New file
0,0 → 1,124
/*
* 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.action;
 
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.ui.light.LightUIDescriptorProvider;
import org.openconcerto.sql.view.list.IListeAction;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.ui.light.ActivationOnSelectionControler;
import org.openconcerto.ui.light.ColumnSpec;
import org.openconcerto.ui.light.ColumnsSpec;
import org.openconcerto.ui.light.CustomEditorProvider;
import org.openconcerto.ui.light.LightUIDescriptor;
import org.openconcerto.ui.light.LightUIElement;
import org.openconcerto.ui.light.LightUILine;
import org.openconcerto.ui.light.ListToolbarLine;
import org.openconcerto.ui.light.TableSpec;
import org.openconcerto.utils.i18n.TranslationManager;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
 
public abstract class CreateListFrameAbstractAction extends CreateFrameAbstractAction implements LightUIDescriptorProvider {
abstract public String getTableName();
 
@Override
public LightUIDescriptor getUIDescriptor(PropsConfiguration configuration) {
SQLElement element = configuration.getDirectory().getElement(getTableName());
String descriptorId = element.getCode() + ".element";
final LightUIDescriptor desc = new LightUIDescriptor(descriptorId);
 
String listId = element.getCode() + ".list";
LightUIElement list = getListCustomEditorProvider(element).createUIElement(listId);
list.setFillWidth(true);
// UI
Collection<IListeAction> actions = element.getRowActions();
LightUILine l0 = new LightUILine();
l0.setGridAlignment(LightUILine.ALIGN_LEFT);
for (Iterator iterator = actions.iterator(); iterator.hasNext();) {
RowAction iListeAction = (RowAction) iterator.next();
if (iListeAction.inHeader()) {
LightUIElement element2 = new LightUIElement();
element2.setType(LightUIElement.TYPE_BUTTON_WITH_CONTEXT);
element2.setValue(iListeAction.getID());
element2.setId(iListeAction.getID());
 
String label = TranslationManager.getInstance().getTranslationForAction(iListeAction.getID());
 
element2.setLabel(label);
 
l0.add(element2);
 
desc.addControler(new ActivationOnSelectionControler(listId, element2.getId()));
 
}
}
desc.addLine(l0);
 
LightUILine l1 = new LightUILine();
l1.setFillHeight(true);
l1.setWeightY(1);
l1.add(list);
desc.addLine(l1);
 
desc.addLine(new ListToolbarLine());
desc.dump(System.out);
return desc;
}
 
public static CustomEditorProvider getListCustomEditorProvider(final SQLElement element) {
// generic list of elements
return new CustomEditorProvider() {
 
@Override
public LightUIElement createUIElement(String id) {
LightUIElement e = new LightUIElement();
e.setId(id);
e.setType(LightUIElement.TYPE_LIST);
List<String> visibleIds = new ArrayList<String>();
List<String> sortedIds = new ArrayList<String>();
 
SQLTableModelSourceOnline source = element.getTableSource();
List<SQLTableModelColumn> columns = source.getColumns();
 
List<ColumnSpec> cols = new ArrayList<ColumnSpec>(columns.size());
for (SQLTableModelColumn column : columns) {
 
// FIXME : recuperer l'info sauvegardée sur le serveur par user (à coder)
int width = column.getName().length() * 20 + 20;
 
ColumnSpec col = new ColumnSpec(column.getIdentifier(), column.getValueClass(), column.getName(), null, width, false, null);
cols.add(col);
visibleIds.add(column.getIdentifier());
}
 
// FIXME : recuperer l'info sauvegardée sur le serveur par user (à coder)
sortedIds.add(visibleIds.get(0));
 
ColumnsSpec columnsSpec = new ColumnsSpec(element.getCode(), cols, visibleIds, sortedIds);
TableSpec tSpec = new TableSpec();
tSpec.setColumns(columnsSpec);
e.setRawContent(tSpec);
 
return e;
}
};
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/action/CreateAndCacheFrameAbstractAction.java
17,6 → 17,7
import org.openconcerto.sql.Configuration;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.ui.state.WindowStateManager;
import org.openconcerto.utils.FileUtils;
 
import java.awt.Dimension;
import java.awt.Toolkit;
37,7 → 38,7
this.frame = createFrame();
this.frame.setLocationRelativeTo(null);
this.stateManager = new WindowStateManager(this.frame, new File(Configuration.getInstance().getConfDir(), "Configuration" + File.separator + "Frame" + File.separator
+ this.getValue(Action.NAME).toString() + ".xml"));
+ FileUtils.sanitize(this.getValue(Action.NAME).toString()) + ".xml"));
this.frame.setIconImages(Gestion.getFrameIcon());
this.frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/action/NouvelleConnexionAction.java
37,7 → 37,6
import org.openconcerto.sql.model.SQLBase;
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.SQLTable;
import org.openconcerto.sql.model.UndefinedRowValuesCache;
51,9 → 50,11
import org.openconcerto.sql.users.rights.TableAllRights;
import org.openconcerto.sql.users.rights.UserRightsManager;
import org.openconcerto.sql.users.rights.UserRightsManager.RightTuple;
import org.openconcerto.sql.utils.BackupPanel;
import org.openconcerto.task.config.ComptaBasePropsConfiguration;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.ui.component.MutableListComboPopupListener;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.JImage;
import org.openconcerto.utils.cc.IClosure;
65,7 → 66,6
import java.awt.Image;
import java.awt.Insets;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
96,8 → 96,6
assert SwingUtilities.isEventDispatchThread();
final ComptaPropsConfiguration comptaPropsConfiguration = ((ComptaPropsConfiguration) Configuration.getInstance());
 
// Vérification de la licence
 
Runnable r = new Runnable() {
 
public void run() {
139,6 → 137,7
}
// needed by openEmergencyModuleManager()
UserRightsManager.getInstance().addRightForAdmins(new RightTuple(ModuleManager.MODULE_DB_RIGHT, true));
UserRightsManager.getInstance().addRightForAdmins(new RightTuple(BackupPanel.RIGHT_CODE, true));
// finish filling the configuration before going any further, otherwise the
// SQLElementDirectory is not coherent
ModuleManager.getInstance().setup(comptaPropsConfiguration.getRootSociete(), comptaPropsConfiguration);
151,7 → 150,7
}
MenuManager.setInstance((Gestion.isMinimalMode() ? new MinimalMenuConfiguration() : new DefaultMenuConfiguration()).createMenuAndActions());
 
User user = UserManager.getInstance().getCurrentUser();
final User user = UserManager.getInstance().getCurrentUser();
// Si l'utilisateur n'est pas superUser ou si il n'a pas de droit d'accéder
// à toutes les société
final int userId = user.getId();
200,6 → 199,8
// even for quick login, check the license before displaying the main
// frame
 
MutableListComboPopupListener.setLockOverridable(user.getRights().isSuperUser());
 
StatusPanel.getInstance().fireStatusChanged();
final MainFrame f = new MainFrame();
String version = comptaPropsConfiguration.getVersion();
249,40 → 250,14
// don't close ConnexionPanel until the main frame is shown
showMainFrame.get();
} catch (Throwable e) {
if (e.getMessage() != null && e.getMessage().contains("TR_BON_DE_LIVRAISON not found")) {
JOptionPane.showMessageDialog(new JFrame(), "Votre base de données n'est pas à jour.\nUtilisez l'outil de configuration et pensez à l'achat du manuel!!!");
return;
}
ExceptionHandler.handle("Erreur de connexion", e);
}
}
 
private void fixEcriture() {
// FIXME Bug archive ecriture (ecriture non archivé ayant un id_mouvement=1)
SQLElement elt = Configuration.getInstance().getDirectory().getElement("ECRITURE");
SQLSelect sel = new SQLSelect();
sel.addSelect(elt.getTable().getKey());
 
Where w = new Where(elt.getTable().getField("ID_MOUVEMENT"), "=", 1);
sel.setWhere(w);
System.err.println(sel.asString());
List<SQLRow> lerrors = (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(elt.getTable()));
for (SQLRow row : lerrors) {
System.err.println("FIX ERROR ID_MOUVEMENT ON ECRITURE ROW " + row.getID());
SQLRowValues rowVals = row.createEmptyUpdateRow();
rowVals.put("ARCHIVE", 1);
try {
rowVals.update();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
 
}
 
if (lerrors.size() > 0) {
System.err.println(lerrors.size() + " erreurs");
Thread.dumpStack();
// JOptionPane.showMessageDialog(null, lerrors.size() +
// " erreurs ont été trouvé et corrigé dans la base.");
}
}
};
 
final JImage image = new JImage(ComptaBasePropsConfiguration.class.getResource("logo.png"));
/trunk/OpenConcerto/src/org/openconcerto/erp/action/ListeBanqueAction.java
New file
0,0 → 1,37
/*
* 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.action;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.view.IListFrame;
import org.openconcerto.sql.view.ListeAddPanel;
 
import javax.swing.Action;
import javax.swing.JFrame;
 
public class ListeBanqueAction extends CreateFrameAbstractAction {
 
public ListeBanqueAction() {
super();
this.putValue(Action.NAME, "Liste des banques");
}
 
public JFrame createFrame() {
 
final ListeAddPanel listeVar = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement(BanqueSQLElement.class));
listeVar.setCloneVisible(true);
return new IListFrame(listeVar);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/DevisCommandeSQLInjector.java
32,11 → 32,11
map(tableDevis.getField("ID_DEVIS"), tableCommande.getField("IDSOURCE"));
map(tableDevis.getField("ID_DEVIS"), tableCommande.getField("ID_DEVIS"));
map(tableDevis.getField("ID_COMMERCIAL"), tableCommande.getField("ID_COMMERCIAL"));
map(tableDevis.getField("OBJET"), tableCommande.getField("NOM"));
map(tableDevis.getField("INFOS"), tableCommande.getField("INFOS"));
if (tableDevis.getTable().contains("ID_POLE_PRODUIT")) {
map(tableDevis.getField("ID_POLE_PRODUIT"), tableCommande.getField("ID_POLE_PRODUIT"));
}
}
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
super.merge(srcRow, rowVals);
45,6 → 45,9
final SQLTable tableElementSource = getSource().getTable("DEVIS_ELEMENT");
final SQLTable tableElementDestination = getSource().getTable("COMMANDE_CLIENT_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
transfertReference(srcRow, rowVals, "OBJET", "NOM");
transfertReference(srcRow, rowVals, "INFOS", "INFOS");
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_COMMANDE_CLIENT");
 
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/DevisFactureSQLInjector.java
16,11 → 16,16
import java.math.BigDecimal;
import java.util.Collection;
 
import org.openconcerto.erp.preferences.GenerationDocGlobalPreferencePanel;
import org.openconcerto.erp.preferences.GestionCommercialeGlobalPreferencePanel;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.UndefinedRowValuesCache;
import org.openconcerto.sql.preferences.SQLPreferences;
 
public class DevisFactureSQLInjector extends SQLInjector {
public DevisFactureSQLInjector(final DBRoot root) {
30,11 → 35,15
map(tableDevis.getField("PORT_HT"), tableFacture.getField("PORT_HT"));
map(tableDevis.getField("REMISE_HT"), tableFacture.getField("REMISE_HT"));
map(tableDevis.getField("ID_CLIENT"), tableFacture.getField("ID_CLIENT"));
map(tableDevis.getField("OBJET"), tableFacture.getField("NOM"));
map(tableDevis.getField("ID_COMMERCIAL"), tableFacture.getField("ID_COMMERCIAL"));
map(tableDevis.getField("ID_DEVIS"), tableFacture.getField("ID_DEVIS"));
map(tableDevis.getField("INFOS"), tableFacture.getField("INFOS"));
if (tableDevis.getTable().contains("ID_POLE_PRODUIT")) {
map(tableDevis.getField("ID_POLE_PRODUIT"), tableFacture.getField("ID_POLE_PRODUIT"));
}
if (tableDevis.getTable().contains("ID_CONTACT")) {
map(tableDevis.getField("ID_CONTACT"), tableFacture.getField("ID_CONTACT"));
}
}
 
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
44,6 → 53,9
final SQLTable tableElementSource = getSource().getTable("DEVIS_ELEMENT");
final SQLTable tableElementDestination = getSource().getTable("SAISIE_VENTE_FACTURE_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
transfertReference(srcRow, rowVals, "OBJET", "NOM");
transfertReference(srcRow, rowVals, "INFOS", "INFOS");
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_SAISIE_VENTE_FACTURE");
 
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/FactureBonSQLInjector.java
28,11 → 28,12
final SQLTable tableFacture = getSource();
final SQLTable tableBon = getDestination();
map(tableFacture.getField("ID_CLIENT"), tableBon.getField("ID_CLIENT"));
map(tableFacture.getField("NOM"), tableBon.getField("NOM"));
map(tableFacture.getField("INFOS"), tableBon.getField("INFOS"));
mapDefaultValues(tableBon.getField("SOURCE"), tableFacture.getName());
map(tableFacture.getKey(), tableBon.getField("IDSOURCE"));
if (tableFacture.contains("ID_POLE_PRODUIT") && tableBon.contains("ID_POLE_PRODUIT")) {
map(tableFacture.getField("ID_POLE_PRODUIT"), tableBon.getField("ID_POLE_PRODUIT"));
}
}
 
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
42,6 → 43,9
final SQLTable tableElementSource = getSource().getTable("SAISIE_VENTE_FACTURE_ELEMENT");
final SQLTable tableElementDestination = getSource().getTable("BON_DE_LIVRAISON_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
transfertReference(srcRow, rowVals, "NOM", "NOM");
transfertReference(srcRow, rowVals, "INFOS", "INFOS");
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_BON_DE_LIVRAISON");
 
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/BonFactureSQLInjector.java
31,9 → 31,10
// map(tableDevis.getField("PORT_HT"), tableCommande.getField("PORT_HT"));
// map(tableDevis.getField("REMISE_HT"), tableCommande.getField("REMISE_HT"));
map(tableBon.getField("ID_CLIENT"), tableFacture.getField("ID_CLIENT"));
map(tableBon.getField("NOM"), tableFacture.getField("NOM"));
map(tableBon.getField("INFOS"), tableFacture.getField("INFOS"));
if (tableBon.getTable().contains("ID_POLE_PRODUIT")) {
map(tableBon.getField("ID_POLE_PRODUIT"), tableFacture.getField("ID_POLE_PRODUIT"));
}
}
 
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
43,6 → 44,9
final SQLTable tableElementSource = getSource().getTable("BON_DE_LIVRAISON_ELEMENT");
final SQLTable tableElementDestination = getSource().getTable("SAISIE_VENTE_FACTURE_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
transfertReference(srcRow, rowVals, "NOM", "NOM");
transfertReference(srcRow, rowVals, "INFOS", "INFOS");
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_SAISIE_VENTE_FACTURE");
 
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/DevisBlSQLInjector.java
30,11 → 30,11
map(tableDevis.getField("ID_CLIENT"), tableBon.getField("ID_CLIENT"));
mapDefaultValues(tableBon.getField("SOURCE"), tableBon.getName());
map(tableDevis.getField("ID_DEVIS"), tableBon.getField("IDSOURCE"));
map(tableDevis.getField("OBJET"), tableBon.getField("NOM"));
map(tableDevis.getField("INFOS"), tableBon.getField("INFOS"));
if (tableDevis.getTable().contains("ID_POLE_PRODUIT")) {
map(tableDevis.getField("ID_POLE_PRODUIT"), tableBon.getField("ID_POLE_PRODUIT"));
}
}
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
super.merge(srcRow, rowVals);
43,6 → 43,9
final SQLTable tableElementSource = getSource().getTable("DEVIS_ELEMENT");
final SQLTable tableElementDestination = getSource().getTable("BON_DE_LIVRAISON_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
transfertReference(srcRow, rowVals, "NOM", "NOM");
transfertReference(srcRow, rowVals, "INFOS", "INFOS");
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_BON_DE_LIVRAISON");
 
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/FactureAvoirSQLInjector.java
32,7 → 32,6
map(tableFacture.getField("ID_COMMERCIAL"), tableAvoir.getField("ID_COMMERCIAL"));
map(tableFacture.getField("REMISE_HT"), tableAvoir.getField("REMISE_HT"));
map(tableFacture.getField("PORT_HT"), tableAvoir.getField("PORT_HT"));
map(tableFacture.getField("NUMERO"), tableAvoir.getField("NOM"));
 
}
 
44,6 → 43,8
final SQLTable tableElementSource = getSource().getTable("SAISIE_VENTE_FACTURE_ELEMENT");
final SQLTable tableElementDestination = getSource().getTable("AVOIR_CLIENT_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
transfertReference(srcRow, rowVals, "NOM", "NOM");
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_AVOIR_CLIENT");
 
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/CommandeFactureClientSQLInjector.java
28,10 → 28,10
final SQLTable tableCommande = getSource();
final SQLTable tableFacture = getDestination();
map(tableCommande.getField("ID_CLIENT"), tableFacture.getField("ID_CLIENT"));
map(tableCommande.getField("NOM"), tableFacture.getField("NOM"));
map(tableCommande.getField("INFOS"), tableFacture.getField("INFOS"));
 
if (tableCommande.getTable().contains("ID_POLE_PRODUIT")) {
map(tableCommande.getField("ID_POLE_PRODUIT"), tableFacture.getField("ID_POLE_PRODUIT"));
}
}
 
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
41,7 → 41,9
final SQLTable tableElementSource = getSource().getTable("COMMANDE_CLIENT_ELEMENT");
final SQLTable tableElementDestination = getSource().getTable("SAISIE_VENTE_FACTURE_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
 
transfertReference(srcRow, rowVals, "NOM", "NOM");
transfertReference(srcRow, rowVals, "INFOS", "INFOS");
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_SAISIE_VENTE_FACTURE");
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
for (SQLRowAccessor rowElt : myListItem) {
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/CommandeBlSQLInjector.java
29,9 → 29,10
final SQLTable tableBl = getDestination();
map(tableCmd.getField("ID_CLIENT"), tableBl.getField("ID_CLIENT"));
map(tableCmd.getField("ID"), tableBl.getField("ID_COMMANDE_CLIENT"));
map(tableCmd.getField("NOM"), tableBl.getField("NOM"));
map(tableCmd.getField("INFOS"), tableBl.getField("INFOS"));
if (tableCmd.getTable().contains("ID_POLE_PRODUIT") && tableBl.contains("ID_POLE_PRODUIT")) {
map(tableCmd.getField("ID_POLE_PRODUIT"), tableBl.getField("ID_POLE_PRODUIT"));
}
}
 
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
42,6 → 43,11
final SQLTable tableElementDestination = getSource().getTable("BON_DE_LIVRAISON_ELEMENT");
final Collection<? extends SQLRowAccessor> myListItem = srcRow.asRow().getReferentRows(tableElementSource);
 
transfertReference(srcRow, rowVals, "NOM", "NOM");
transfertReference(srcRow, rowVals, "INFOS", "INFOS");
 
transfertNumberReference(srcRow, rowVals, tableElementDestination, "ID_BON_DE_LIVRAISON");
 
if (myListItem.size() != 0) {
final SQLInjector injector = SQLInjector.getInjector(tableElementSource, tableElementDestination);
for (SQLRowAccessor rowElt : myListItem) {
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/PrixUnitaireProvider.java
New file
0,0 → 1,52
/*
* 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.provider;
 
import org.openconcerto.erp.core.sales.product.element.UniteVenteArticleSQLElement;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueContext;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProvider;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProviderManager;
import org.openconcerto.sql.model.SQLRowAccessor;
 
import java.math.BigDecimal;
 
public class PrixUnitaireProvider implements SpreadSheetCellValueProvider {
 
public PrixUnitaireProvider() {
}
 
public Object getValue(SpreadSheetCellValueContext context) {
final SQLRowAccessor row = context.getRow();
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (pv.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
 
final int qte = row.getInt("QTE");
if (row.getInt("ID_UNITE_VENTE") == UniteVenteArticleSQLElement.A_LA_PIECE) {
return String.valueOf(qte);
}
 
final BigDecimal qteUV = row.getBigDecimal("QTE_UNITAIRE");
final BigDecimal mergedQty = qteUV.multiply(new BigDecimal(qte));
final BigDecimal pvUnit = mergedQty.multiply(pv);
return pvUnit;
 
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("supplychain.element.unitprice", new PrixUnitaireProvider());
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/FormatedGlobalQtyTotalProvider.java
26,8 → 26,15
 
private final boolean shortName;
 
private FormatedGlobalQtyTotalProvider(boolean shortName) {
private static enum Type {
NORMAL, SHIPMENT
}
 
private final Type type;
 
private FormatedGlobalQtyTotalProvider(Type t, boolean shortName) {
this.shortName = shortName;
this.type = t;
}
 
public Object getValue(SpreadSheetCellValueContext context) {
37,12 → 44,13
return null;
}
 
final int qte = row.getInt("QTE");
final int qte = row.getInt(this.type == Type.NORMAL ? "QTE" : "QTE_LIVREE");
 
if (row.getInt("ID_UNITE_VENTE") == UniteVenteArticleSQLElement.A_LA_PIECE) {
return String.valueOf(qte);
}
String result = "";
if (qte > 0) {
if (qte > 1) {
result += qte + " x ";
}
53,13 → 61,15
result += " " + ((this.shortName) ? rMode.getString("CODE") : rMode.getString("NOM"));
// 3 x 5.5 meters
// 1 x 6.3 meters -> 6.3 meters
}
return result;
 
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.short", new FormatedGlobalQtyTotalProvider(true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit", new FormatedGlobalQtyTotalProvider(false));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.short", new FormatedGlobalQtyTotalProvider(Type.NORMAL, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit", new FormatedGlobalQtyTotalProvider(Type.NORMAL, false));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.deliver.short", new FormatedGlobalQtyTotalProvider(Type.SHIPMENT, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.deliver", new FormatedGlobalQtyTotalProvider(Type.SHIPMENT, false));
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/AdresseClientProvider.java
20,6 → 20,7
 
public abstract class AdresseClientProvider implements SpreadSheetCellValueProvider {
 
public static int ADRESSE_PRINCIPALE = 0;
public static int ADRESSE_FACTURATION = 1;
public static int ADRESSE_LIVRAISON = 2;
 
36,8 → 37,11
}
}
 
// Adresse Facturation
 
SQLRowAccessor rCli = r.getForeign("ID_CLIENT");
SQLRowAccessor adrResult;
adrResult = rCli.getForeign("ID_ADRESSE");
if (type != ADRESSE_PRINCIPALE) {
String field;
if (type == ADRESSE_FACTURATION) {
field = "ID_ADRESSE_F";
46,11 → 50,10
}
SQLRowAccessor rAdr = rCli.getForeign(field);
if (rAdr != null && !rAdr.isUndefined()) {
return rAdr;
adrResult = rAdr;
}
 
return rCli.getForeign("ID_ADRESSE");
 
}
return adrResult;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/AdresseVilleNomClientValueProvider.java
41,6 → 41,7
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("address.customer.country.name", new AdresseVilleNomClientValueProvider(ADRESSE_PRINCIPALE));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.country.name", new AdresseVilleNomClientValueProvider(ADRESSE_FACTURATION));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.country.name", new AdresseVilleNomClientValueProvider(ADRESSE_LIVRAISON));
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/PrixUVProvider.java
New file
0,0 → 1,50
/*
* 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.provider;
 
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueContext;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProvider;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProviderManager;
import org.openconcerto.sql.model.SQLRowAccessor;
 
import java.math.BigDecimal;
import java.text.DecimalFormat;
 
public class PrixUVProvider implements SpreadSheetCellValueProvider {
 
private final boolean shortName;
private final DecimalFormat decimalFormat = new DecimalFormat("##,##0.00#");
 
public PrixUVProvider(boolean shortName) {
this.shortName = shortName;
}
 
public Object getValue(SpreadSheetCellValueContext context) {
final SQLRowAccessor row = context.getRow();
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (pv.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
String result = decimalFormat.format(pv);
final SQLRowAccessor rMode = row.getForeign("ID_UNITE_VENTE");
result += "€ / " + ((this.shortName) ? rMode.getString("CODE") : rMode.getString("NOM"));
return result;
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("supplychain.element.salesunit.price", new PrixUVProvider(false));
SpreadSheetCellValueProviderManager.put("supplychain.element.salesunit.price.short", new PrixUVProvider(true));
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/AdresseRueClientValueProvider.java
30,6 → 30,7
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("address.customer.address", new AdresseRueClientValueProvider(ADRESSE_PRINCIPALE));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.address", new AdresseRueClientValueProvider(ADRESSE_FACTURATION));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.address", new AdresseRueClientValueProvider(ADRESSE_LIVRAISON));
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/AdresseVilleCPClientValueProvider.java
35,6 → 35,7
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("address.customer.country.code", new AdresseVilleCPClientValueProvider(ADRESSE_PRINCIPALE));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.country.code", new AdresseVilleCPClientValueProvider(ADRESSE_FACTURATION));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.country.code", new AdresseVilleCPClientValueProvider(ADRESSE_LIVRAISON));
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/AdresseFullClientValueProvider.java
45,6 → 45,7
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("address.customer.full", new AdresseFullClientValueProvider(ADRESSE_PRINCIPALE));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.full", new AdresseFullClientValueProvider(ADRESSE_FACTURATION));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.full", new AdresseFullClientValueProvider(ADRESSE_LIVRAISON));
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/PaiementRemainedProvider.java
New file
0,0 → 1,49
/*
* 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.provider;
 
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueContext;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProvider;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProviderManager;
import org.openconcerto.sql.model.SQLRowAccessor;
 
import java.math.BigDecimal;
import java.util.Collection;
 
public class PaiementRemainedProvider implements SpreadSheetCellValueProvider {
 
public Object getValue(SpreadSheetCellValueContext context) {
SQLRowAccessor row = context.getRow();
return getRestant(row);
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("invoice.paiement.remained", new PaiementRemainedProvider());
}
 
private BigDecimal getRestant(SQLRowAccessor r) {
Collection<? extends SQLRowAccessor> rows = r.getReferentRows(r.getTable().getTable("ECHEANCE_CLIENT"));
long totalEch = 0;
 
for (SQLRowAccessor row : rows) {
if (!row.getBoolean("REGLE") && !row.getBoolean("REG_COMPTA")) {
totalEch += row.getLong("MONTANT");
}
}
 
return new BigDecimal(totalEch).movePointLeft(2);
 
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/AdresseVilleClientValueProvider.java
45,6 → 45,7
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("address.customer.country", new AdresseVilleClientValueProvider(ADRESSE_PRINCIPALE));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.country", new AdresseVilleClientValueProvider(ADRESSE_FACTURATION));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.country", new AdresseVilleClientValueProvider(ADRESSE_LIVRAISON));
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractJOOReportsSheet.java
37,6 → 37,7
import java.util.HashMap;
import java.util.Map;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
 
public abstract class AbstractJOOReportsSheet {
217,12 → 218,12
return;
}
ooConnexion.loadDocument(fileOutOO, false);
 
} catch (LinkageError e) {
JOptionPane.showMessageDialog(new JFrame(), "Merci d'installer OpenOffice ou LibreOffice");
} catch (Exception e) {
e.printStackTrace();
ExceptionHandler.handle("Impossible de charger le document OpenOffice", e);
}
 
} else {
generate(false, true, "");
}
236,7 → 237,6
public void printDocument() {
File fileOutOO = getDocumentFile();
if (fileOutOO.exists()) {
 
try {
final OOConnexion ooConnexion = ComptaPropsConfiguration.getOOConnexion();
if (ooConnexion == null) {
243,17 → 243,16
return;
}
final Component doc = ooConnexion.loadDocument(fileOutOO, true);
 
Map<String, Object> map = new HashMap<String, Object>();
map.put("Name", printer);
doc.printDocument(map);
doc.close();
 
} catch (LinkageError e) {
JOptionPane.showMessageDialog(new JFrame(), "Merci d'installer OpenOffice ou LibreOffice");
} catch (Exception e) {
e.printStackTrace();
ExceptionHandler.handle("Impossible de charger le document OpenOffice", e);
}
 
} else {
generate(true, false, this.printer);
}
260,13 → 259,10
}
 
public void fastPrintDocument() {
 
final File f = getDocumentFile();
 
if (!f.exists()) {
generate(true, false, this.printer);
} else {
 
try {
final OOConnexion ooConnexion = ComptaPropsConfiguration.getOOConnexion();
if (ooConnexion == null) {
273,7 → 269,6
return;
}
final Component doc = ooConnexion.loadDocument(f, true);
 
Map<String, Object> map = new HashMap<String, Object>();
map.put("Name", this.printer);
Map<String, Object> map2 = new HashMap<String, Object>();
280,7 → 275,8
map2.put("CopyCount", 1);
doc.printDocument(map, map2);
doc.close();
 
} catch (LinkageError e) {
JOptionPane.showMessageDialog(new JFrame(), "Merci d'installer OpenOffice ou LibreOffice");
} catch (Exception e) {
 
ExceptionHandler.handle("Impossible de charger le document OpentOffice", e);
305,7 → 301,6
}
 
public void exportToPdf() {
 
// Export vers PDF
final String fileName = getFileName();
final File fileOutOO = getDocumentFile();
315,9 → 310,7
if (!fileOutOO.exists()) {
generate(false, false, "");
}
 
try {
 
final OOConnexion ooConnexion = ComptaPropsConfiguration.getOOConnexion();
if (ooConnexion == null) {
return;
325,7 → 318,8
final Component doc = ooConnexion.loadDocument(fileOutOO, true);
doc.saveToPDF(fileOutPDF, "writer_pdf_Export");
doc.close();
 
} catch (LinkageError e) {
JOptionPane.showMessageDialog(new JFrame(), "Merci d'installer OpenOffice ou LibreOffice");
} catch (Exception e) {
e.printStackTrace();
ExceptionHandler.handle("Impossible de charger le document OpenOffice", e);
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetXml.java
490,7 → 490,7
* @param fileName nom du fichier à créer ex:FACTURE_2007/03/001
* @return un nom fichier valide ex:FACTURE_2007-03-001
*/
static String getValidFileName(String fileName) {
public static String getValidFileName(String fileName) {
final StringBuffer result = new StringBuffer(fileName.length());
for (int i = 0; i < fileName.length(); i++) {
char ch = fileName.charAt(i);
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/FicheArticleXmlSheet.java
New file
0,0 → 1,41
/*
* 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.gestcomm;
 
import org.openconcerto.erp.generationDoc.AbstractSheetXMLWithDate;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
 
public class FicheArticleXmlSheet extends AbstractSheetXMLWithDate {
 
public static final String TEMPLATE_ID = "FicheArticle";
public static final String TEMPLATE_PROPERTY_NAME = "LocationFicheArticle";
 
public FicheArticleXmlSheet(SQLRow row) {
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("ARTICLE");
}
 
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
@Override
public String getName() {
return "FicheArticle_" + this.row.getID();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLField.java
44,6 → 44,7
import java.util.List;
import java.util.Map;
 
import org.jdom.Attribute;
import org.jdom.Element;
 
public class OOXMLField extends OOXMLElement {
84,8 → 85,8
// {
String field = this.elt.getAttributeValue("name");
 
final SQLField sqlField = this.row.getTable().getField(field);
boolean isForeignField = this.row.getTable().getForeignKeys().contains(sqlField);
final SQLField sqlField = (field == null || field.trim().length() == 0) ? null : this.row.getTable().getField(field);
boolean isForeignField = (sqlField == null) ? false : this.row.getTable().getForeignKeys().contains(sqlField);
 
// le champ est une clef etrangere, on recupere la valeur du sous composant
if (isForeignField && this.elt.getChild("field") != null) {
280,6 → 281,17
}
 
protected Object getSpecialValue(String typeComp) {
 
SpreadSheetCellValueProvider provider = SpreadSheetCellValueProviderManager.get(typeComp);
if (provider != null) {
final SpreadSheetCellValueContext context = new SpreadSheetCellValueContext(this.row);
List<Attribute> attrs = this.elt.getAttributes();
for (Attribute attr : attrs) {
context.put(attr.getName(), attr.getValue());
}
return provider.getValue(context);
}
 
String field = this.elt.getAttributeValue("name");
final Object result = this.row.getObject(field);
 
348,6 → 360,8
} else if (typeComp.equalsIgnoreCase("Ville")) {
stringValue = (result == null) ? "" : result.toString();
return stringValue;
} else if (typeComp.equalsIgnoreCase("Traduction")) {
return getTraduction();
} else if (typeComp.equalsIgnoreCase("VilleCP")) {
// Code postal de la ville
return this.row.getString("CODE_POSTAL");
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationXML.java
14,6 → 14,7
package org.openconcerto.erp.generationDoc;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Log;
import org.openconcerto.erp.core.common.element.StyleSQLElement;
import org.openconcerto.openoffice.ODPackage;
import org.openconcerto.openoffice.spreadsheet.MutableCell;
147,10 → 148,15
List<Element> listElts = racine.getChildren("element");
 
// Création et génération du fichier OO
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, langage, typeTemplate);
final InputStream templateStream = TemplateManager.getInstance().getTemplate(templateId, langage, typeTemplate);
if (templateStream == null) {
ExceptionHandler.handle("Modèle " + templateId + " " + ((rowLanguage == null) ? "" : rowLanguage.getString("CHEMIN")) + " " + typeTemplate + " manquant.");
return null;
}
final SpreadSheet spreadSheet;
try {
spreadSheet = new ODPackage(templateStream).getSpreadSheet();
 
final SpreadSheet spreadSheet = new ODPackage(template).getSpreadSheet();
try {
// On remplit les cellules de la feuille
parseElementsXML(listElts, row, spreadSheet);
 
163,6 → 169,7
}
} catch (Exception e) {
ExceptionHandler.handle("Impossible de remplir le document " + templateId + " " + ((rowLanguage == null) ? "" : rowLanguage.getString("CHEMIN")), e);
return null;
}
 
if (meta != null) {
376,7 → 383,7
// on remplit chaque ligne à partir des rows recuperées
int numeroRef = 0;
for (SQLRowAccessor rowElt : rowsEltCache.get(ref)) {
numeroRef++;
 
if (!cache && rowElt.getTable().getFieldRaw("ID_TAXE") != null) {
SQLRowAccessor rowTaxe = getForeignRow(rowElt, rowElt.getTable().getField("ID_TAXE"));
BigDecimal ht = BigDecimal.ZERO;
398,13 → 405,15
}
 
final boolean included = isIncluded(tableElement.getFilterId(), tableElement.getForeignTableWhere(), tableElement.getFilterId(), tableElement.getFieldWhere(), rowElt);
if (included || tableElement.getTypeStyleWhere()) {
 
String styleName = null;
if (tableElement.getSQLElement().getTable().contains("ID_STYLE")) {
styleName = styleElt.getTable().getRow(rowElt.getInt("ID_STYLE")).getString("NOM");
}
 
if ((included || tableElement.getTypeStyleWhere()) && (styleName == null || !styleName.equalsIgnoreCase("Invisible"))) {
 
numeroRef++;
 
if (included && tableElement.getTypeStyleWhere()) {
styleName = "Titre 1";
}
413,17 → 422,11
styleName = "Normal";
}
 
String tmp;
if (styleName != null && tableElement.getListBlankLineStyle().contains(styleName)) {
tmp = null;
} else {
tmp = styleName;
}
 
// Blank Line Style
boolean first = true;
int toAdd = 0;
if (styleName != null && tableElement.getListBlankLineStyle().contains(styleName) && first) {
 
toAdd++;
currentLine++;
first = false;
587,7 → 590,9
System.err.println("OOgenerationXML.fillTaxe() --> name == null");
} else {
Object value = m.get(name);
if (name.equalsIgnoreCase("MONTANT_TVA")) {
if (name.equalsIgnoreCase("MONTANT_HT")) {
value = ((BigDecimal) m.get("MONTANT_HT"));
} else if (name.equalsIgnoreCase("MONTANT_TVA")) {
// value = Math.round(((Long) m.get("MONTANT_HT") * rowTaxe.getFloat("TAUX")
// / 100.0));
value = ((BigDecimal) m.get("MONTANT_HT")).multiply(new BigDecimal(rowTaxe.getFloat("TAUX")), MathContext.DECIMAL128).movePointLeft(2);
689,7 → 694,8
}
y++;
} catch (IllegalArgumentException e) {
JOptionPane.showMessageDialog(null, "La cellule " + location + " n'existe pas ou est fusionnée.", "Erreur pendant la génération", JOptionPane.ERROR_MESSAGE);
 
ExceptionHandler.handle("La cellule " + location + " n'existe pas ou est fusionnée.", e);
}
}
}
910,13 → 916,9
int nbPage = fillTable(tableau, row, sheet, mapStyle, true, rowLanguage);
 
return nbPage > 1;
} catch (final JDOMException e) {
 
} catch (Throwable e) {
Log.get().severe(e.getMessage());
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationReglementVente.java
13,6 → 13,7
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
58,7 → 59,8
 
this.mEcritures.put("DATE", this.date);
this.mEcritures.put("NOM", this.nom);
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
 
fillJournalBanqueFromRow(modeRegRow);
this.mEcritures.put("ID_MOUVEMENT", Integer.valueOf(this.idMvt));
 
// si paiement comptant
104,11 → 106,16
ajoutEcriture();
 
// compte de reglement, caisse, cheque, ...
if (typeRegRow.getID() == TypeReglementSQLElement.ESPECE) {
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteRegl <= 1) {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteCB");
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteEspece");
}
 
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteRegl));
} else {
fillCompteBanqueFromRow(modeRegRow, "VenteCB", false);
}
this.mEcritures.put("DEBIT", Long.valueOf(prixTTC.getLongValue()));
this.mEcritures.put("CREDIT", Long.valueOf(0));
ajoutEcriture();
196,6 → 203,10
valCheque.put("ID_CLIENT", Integer.valueOf(echeanceRow.getInt("ID_CLIENT")));
}
 
if (!encaisseMontantRow.isForeignEmpty("ID_MODE_REGLEMENT")) {
SQLRow rowModeRegl = encaisseMontantRow.getForeignRow("ID_MODE_REGLEMENT");
valCheque.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
}
valCheque.put("DATE_VENTE", this.date);
SQLRow rowMvtPere = tableMouvement.getRow(echeanceRow.getInt("ID_MOUVEMENT"));
this.idMvt = getNewMouvement("CHEQUE_A_ENCAISSER", 1, rowMvtPere.getID(), rowMvtPere.getInt("ID_PIECE"));
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementVenteFacture.java
13,6 → 13,7
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
83,7 → 84,7
if (typeRegRow.getID() == 4) {
this.mEcritures.put("ID_JOURNAL", GenerationMvtReglementVenteFacture.journalCaisse);
} else {
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
fillJournalBanqueFromRow(modeRegRow);
}
 
this.idMvt = idPere;
106,11 → 107,7
ajoutEcriture();
 
// compte de reglement, caisse, cheque, ...
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteRegl <= 1) {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteCB");
}
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idCompteRegl));
fillCompteBanqueFromRow(modeRegRow, "VenteCB", false);
this.mEcritures.put("DEBIT", new Long(prixTTC.getLongValue()));
this.mEcritures.put("CREDIT", new Long(0));
ajoutEcriture();
180,6 → 177,10
valEncaisse.put("ID_CLIENT", new Integer(saisieRow.getInt("ID_CLIENT")));
valEncaisse.put("DATE_VENTE", new java.sql.Date(this.date.getTime()));
valEncaisse.put("DATE_MIN_DEPOT", new java.sql.Date(dateEch.getTime()));
if (saisieRow.isForeignEmpty("ID_MODE_REGLEMENT")) {
SQLRow rowModeRegl = saisieRow.getForeignRow("ID_MODE_REGLEMENT");
valEncaisse.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
}
SQLRow rowMvtPere = tableMouvement.getRow(idPere);
this.idMvt = getNewMouvement("CHEQUE_A_ENCAISSER", 1, idPere, rowMvtPere.getInt("ID_PIECE"));
valEncaisse.put("ID_MOUVEMENT", new Integer(this.idMvt));
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtFactureFournisseur.java
108,7 → 108,8
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(row.getID()));
this.mEcritures.put("CREDIT", Long.valueOf(0));
this.mEcritures.put("DEBIT", Long.valueOf(b));
int idEcr = ajoutEcriture();
SQLRow rowEcr = ajoutEcriture();
addAssocAnalytiqueFromProvider(rowEcr, saisieRow);
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementVenteComptoir.java
13,10 → 13,12
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ChequeAEncaisserSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement;
import org.openconcerto.erp.model.PrixTTC;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
84,7 → 86,7
if (typeRegRow.getID() == 4) {
this.mEcritures.put("ID_JOURNAL", GenerationMvtReglementVenteComptoir.journalCaisse);
} else {
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
fillJournalBanqueFromRow(modeRegRow);
}
 
// compte Clients
102,11 → 104,16
ajoutEcriture();
 
// compte de reglement
if (typeRegRow.getID() == TypeReglementSQLElement.ESPECE) {
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteRegl <= 1) {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteCB");
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteEspece");
}
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idCompteRegl));
 
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteRegl));
} else {
fillCompteBanqueFromRow(modeRegRow, "VenteCB", false);
}
this.mEcritures.put("DEBIT", new Long(prixTTC.getLongValue()));
this.mEcritures.put("CREDIT", new Long(0));
ajoutEcriture();
172,6 → 179,11
valEncaisse.put("DATE_MIN_DEPOT", new java.sql.Date(dateEch.getTime()));
valEncaisse.put("DATE_DEPOT", new java.sql.Date(this.date.getTime()));
valEncaisse.put("MONTANT", new Long(prixTTC.getLongValue()));
 
if (!saisieRow.isForeignEmpty("ID_MODE_REGLEMENT")) {
SQLRow rowModeRegl = saisieRow.getForeignRow("ID_MODE_REGLEMENT");
valEncaisse.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
}
// on crée un nouveau mouvement pour l'encaissement futur du cheque
SQLRow rowMvtPere = tableMouvement.getRow(idPere);
this.idMvt = getNewMouvement("CHEQUE_A_ENCAISSER", 1, idPere, rowMvtPere.getInt("ID_PIECE"));
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementFactureFournisseur.java
13,6 → 13,7
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
100,9 → 101,7
this.mEcritures.put("ID_JOURNAL", GenerationMvtReglementFactureFournisseur.journalCaisse);
} else {
 
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
 
 
fillJournalBanqueFromRow(modeRegRow);
}
 
// compte Fournisseurs
120,11 → 119,7
ajoutEcriture();
 
// compte de reglement, caisse, CB, ...
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_FOURN");
if (idCompteRegl <= 1) {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteCB");
}
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteRegl));
fillCompteBanqueFromRow(modeRegRow, "VenteCB", true);
this.mEcritures.put("DEBIT", Long.valueOf(0));
this.mEcritures.put("CREDIT", Long.valueOf(prixTTC.getLongValue()));
ajoutEcriture();
196,6 → 191,11
mEncaisse.put("DATE_ACHAT", new java.sql.Date(this.date.getTime()));
mEncaisse.put("DATE_MIN_DECAISSE", new java.sql.Date(dateEch.getTime()));
mEncaisse.put("MONTANT", Long.valueOf(prixTTC.getLongValue()));
if (!saisieRow.isForeignEmpty("ID_MODE_REGLEMENT")) {
SQLRow rowModeRegl = saisieRow.getForeignRow("ID_MODE_REGLEMENT");
mEncaisse.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
}
 
SQLRow rowMvtPere = tableMouvement.getRow(this.idPere);
this.idMvt = getNewMouvement("CHEQUE_FOURNISSEUR", 1, this.idPere, rowMvtPere.getInt("ID_PIECE"));
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieKm.java
51,7 → 51,7
SQLTable tableElt = Configuration.getInstance().getRoot().findTable("SAISIE_KM_ELEMENT");
List<SQLRow> set = saisieRow.getReferentRows(tableElt);
 
SQLTable tableAssoc;
SQLTable tableAssoc = Configuration.getInstance().getRoot().findTable("ASSOCIATION_ANALYTIQUE");
 
for (SQLRow rowElement : set) {
 
62,11 → 62,19
this.mEcritures.put("NOM", rowElement.getString("NOM_ECRITURE"));
this.mEcritures.put("DEBIT", rowElement.getObject("DEBIT"));
this.mEcritures.put("CREDIT", rowElement.getObject("CREDIT"));
int idEcr = ajoutEcriture();
SQLRow rowEcr = ajoutEcriture();
 
List<SQLRow> assocs = rowElement.getReferentRows(tableAssoc);
for (SQLRow sqlRow : assocs) {
if (!sqlRow.isUndefined()) {
addAssocAnalytique(rowEcr, sqlRow.getInt("ID_POSTE_ANALYTIQUE"));
}
}
 
// Mise à jour de la clef étrangère écriture de l'élément saisie au km
if (idEcr > 1) {
if (rowEcr != null && !rowEcr.isUndefined()) {
SQLRowValues vals = rowElement.createEmptyUpdateRow();
vals.put("ID_ECRITURE", new Integer(idEcr));
vals.put("ID_ECRITURE", rowEcr.getID());
vals.update();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/provider/AnalytiqueProviderManager.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.generationEcritures.provider;
 
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
 
public class AnalytiqueProviderManager {
private final static AnalytiqueProviderManager instance = new AnalytiqueProviderManager();
private final Map<String, AnalytiqueProvider> map = new HashMap<String, AnalytiqueProvider>();
 
public static void put(String id, AnalytiqueProvider provider) {
instance.putProvider(id, provider);
}
 
public static AnalytiqueProvider get(String id) {
return instance.getProvider(id);
}
 
public static Collection<AnalytiqueProvider> getAll() {
return instance.getAllProvider();
}
 
private synchronized void putProvider(String id, AnalytiqueProvider provider) {
map.put(id, provider);
 
}
 
private synchronized AnalytiqueProvider getProvider(String id) {
return map.get(id);
}
 
private synchronized Collection<AnalytiqueProvider> getAllProvider() {
return map.values();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/provider/AnalytiqueProvider.java
New file
0,0 → 1,21
/*
* 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.generationEcritures.provider;
 
import org.openconcerto.sql.model.SQLRow;
 
public interface AnalytiqueProvider {
 
public void addAssociation(SQLRow rowEcr, SQLRow rowSource);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementChequeClient.java
60,9 → 60,10
// initialisation des valeurs de la map
this.mEcritures.put("DATE", new java.sql.Date(this.date.getTime()));
this.mEcritures.put("NOM", this.nom);
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
this.mEcritures.put("ID_MOUVEMENT", new Integer(this.idMvt));
 
fillJournalBanqueFromRow(chequeRow);
 
setDateReglement(this.idCheque, this.date);
 
// compte Clients
77,11 → 78,6
}
}
 
int idPce = base.getTable("TYPE_REGLEMENT").getRow(2).getInt("ID_COMPTE_PCE_CLIENT");
if (idPce <= 1) {
idPce = ComptePCESQLElement.getIdComptePceDefault("VenteCheque");
}
 
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idCompteClient));
this.mEcritures.put("DEBIT", new Long(0));
this.mEcritures.put("CREDIT", new Long(this.montant));
89,7 → 85,7
System.err.println("First ECriture for mvt " + this.idMvt);
 
// compte de reglement cheque, ...
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idPce));
fillCompteBanqueFromRow(chequeRow, "VenteCheque", false);
this.mEcritures.put("DEBIT", new Long(this.montant));
this.mEcritures.put("CREDIT", new Long(0));
ajoutEcriture();
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementAvoirChequeClient.java
45,7 → 45,9
this.nom = "Reglement avoir client par chéque";
this.mEcritures.put("DATE", new java.sql.Date(this.date.getTime()));
this.mEcritures.put("NOM", this.nom);
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
 
fillJournalBanqueFromRow(chequeAvoirRow);
 
this.mEcritures.put("ID_MOUVEMENT", new Integer(this.idMvt));
 
// compte Clients
63,11 → 65,7
ajoutEcriture();
 
// compte de reglement cheque, ...
int idPce = base.getTable("TYPE_REGLEMENT").getRow(2).getInt("ID_COMPTE_PCE_CLIENT");
if (idPce <= 1) {
idPce = ComptePCESQLElement.getIdComptePceDefault("VenteCheque");
}
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idPce));
fillCompteBanqueFromRow(chequeAvoirRow, "VenteCheque", false);
this.mEcritures.put("DEBIT", new Long(0));
this.mEcritures.put("CREDIT", new Long(this.montant));
ajoutEcriture();
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationEcritures.java
14,7 → 14,12
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.ui.TotalCalculator;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.generationEcritures.provider.AnalytiqueProvider;
import org.openconcerto.erp.generationEcritures.provider.AnalytiqueProviderManager;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.erp.preferences.GestionPieceCommercialePanel;
import org.openconcerto.sql.Configuration;
28,6 → 33,7
 
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
69,7 → 75,7
* @return Id de l'ecriture crée
* @throws IllegalArgumentException
*/
synchronized public int ajoutEcriture() throws IllegalArgumentException {
synchronized public SQLRow ajoutEcriture() throws IllegalArgumentException {
 
long debit = ((Long) this.mEcritures.get("DEBIT")).longValue();
long credit = ((Long) this.mEcritures.get("CREDIT")).longValue();
78,6 → 84,9
Number n = (Number) this.mEcritures.get("ID_JOURNAL");
if (n != null) {
SQLRow rowJrnl = journalTable.getRow(n.intValue());
if (rowJrnl == null) {
throw new IllegalArgumentException("Le journal qui a pour ID " + n + " a été archivé.");
}
this.mEcritures.put("JOURNAL_NOM", rowJrnl.getString("NOM"));
this.mEcritures.put("JOURNAL_CODE", rowJrnl.getString("CODE"));
}
143,7 → 152,7
if (valEcriture.getInvalid() == null) {
// ajout de l'ecriture
SQLRow ecritureRow = valEcriture.insert();
return ecritureRow.getID();
return ecritureRow;
} else {
System.err.println("GenerationEcritures.java :: Error in values for insert in table " + GenerationEcritures.ecritureTable.getName() + " : " + valEcriture.toString());
throw new IllegalArgumentException("Erreur lors de la génération des écritures données incorrectes. " + valEcriture);
159,10 → 168,36
e.printStackTrace();
}
 
return -1;
return null;
}
 
private static SQLTable tableAssoc = null;
private static SQLTable tablePoste = Configuration.getInstance().getDirectory().getElement("POSTE_ANALYTIQUE").getTable();
 
public void addAssocAnalytique(SQLRow rowEcr, int idPoste) throws SQLException {
if (tablePoste.getUndefinedID() == idPoste) {
return;
}
if (tableAssoc == null) {
tableAssoc = Configuration.getInstance().getDirectory().getElement("ASSOCIATION_ANALYTIQUE").getTable();
}
SQLRowValues rowVals = new SQLRowValues(tableAssoc);
rowVals.put("ID_POSTE_ANALYTIQUE", idPoste);
rowVals.put("POURCENT", 100.0);
rowVals.put("ID_ECRITURE", rowEcr.getID());
rowVals.put("MONTANT", rowEcr.getLong("DEBIT") - rowEcr.getLong("CREDIT"));
rowVals.commit();
 
}
 
public void addAssocAnalytiqueFromProvider(SQLRow rowEcr, SQLRow rowSource) throws SQLException {
 
Collection<AnalytiqueProvider> l = AnalytiqueProviderManager.getAll();
for (AnalytiqueProvider analytiqueProvider : l) {
analytiqueProvider.addAssociation(rowEcr, rowSource);
}
}
 
/**
* Génération d'un groupe d'écritures respectant la partie double.
*
407,4 → 442,42
 
}
 
/**
* Définit le journal en fonction de la banque sélectionnée
*
* @param sqlRow sqlRow contenant la foreignKey Banque
*/
protected void fillJournalBanqueFromRow(SQLRow sqlRow) {
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
if (!sqlRow.isForeignEmpty("ID_" + BanqueSQLElement.TABLENAME)) {
SQLRow rowBanque = sqlRow.getForeignRow("ID_" + BanqueSQLElement.TABLENAME);
if (!rowBanque.isForeignEmpty("ID_JOURNAL")) {
SQLRow rowJournal = rowBanque.getForeignRow("ID_JOURNAL");
this.mEcritures.put("ID_JOURNAL", rowJournal.getID());
}
}
}
 
/**
* Définit le compte en fonction de la banque sélectionnée
*
* @param sqlRow sqlRow contenant la foreignKey Banque
* @throws Exception
*/
protected void fillCompteBanqueFromRow(SQLRow sqlRow, String defaultProps, boolean achat) throws Exception {
 
int idPce = base.getTable("TYPE_REGLEMENT").getRow(2).getInt("ID_COMPTE_PCE_" + (achat ? "FOURN" : "CLIENT"));
if (idPce <= 1) {
idPce = ComptePCESQLElement.getIdComptePceDefault(defaultProps);
}
if (!sqlRow.isForeignEmpty("ID_" + BanqueSQLElement.TABLENAME)) {
SQLRow rowBanque = sqlRow.getForeignRow("ID_" + BanqueSQLElement.TABLENAME);
if (!rowBanque.isForeignEmpty("ID_COMPTE_PCE")) {
SQLRow rowCompteBanque = rowBanque.getForeignRow("ID_COMPTE_PCE");
idPce = rowCompteBanque.getID();
}
}
 
this.mEcritures.put("ID_COMPTE_PCE", idPce);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieAchat.java
101,8 → 101,10
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idCompteAchat));
this.mEcritures.put("DEBIT", new Long(prixHT.getLongValue()));
this.mEcritures.put("CREDIT", new Long(0));
ajoutEcriture();
SQLRow rowEcr = ajoutEcriture();
 
addAssocAnalytiqueFromProvider(rowEcr, saisieRow);
 
// compte TVA
if (prixTVA.getLongValue() > 0) {
int idCompteTVA;
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtAvoirClient.java
102,7 → 102,8
this.mEcritures.put("ID_COMPTE_PCE", row.getID());
this.mEcritures.put("DEBIT", Long.valueOf(b));
this.mEcritures.put("CREDIT", Long.valueOf(0));
ajoutEcriture();
SQLRow rowEcr = ajoutEcriture();
addAssocAnalytiqueFromProvider(rowEcr, avoirRow);
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationReglementVenteNG.java
14,6 → 14,8
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
21,9 → 23,15
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement;
import org.openconcerto.erp.model.PrixTTC;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.cc.ITransformer;
 
import java.sql.SQLException;
import java.sql.Timestamp;
41,6 → 49,8
private static final SQLTable tablePrefCompte = base.getTable("PREFS_COMPTE");
private static final SQLRow rowPrefsCompte = tablePrefCompte.getRow(2);
 
public SQLRow ecrClient = null;
 
public GenerationReglementVenteNG(String label, SQLRow rowClient, PrixTTC ttc, Date d, SQLRow modeReglement, SQLRow source, SQLRow mvtSource) throws Exception {
this(label, rowClient, ttc, d, modeReglement, source, mvtSource, true);
}
58,7 → 68,7
 
this.mEcritures.put("DATE", this.date);
this.mEcritures.put("NOM", this.nom);
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
fillJournalBanqueFromRow(modeReglement);
 
this.mEcritures.put("ID_MOUVEMENT", Integer.valueOf(this.idMvt));
if (source.getTable().getName().equalsIgnoreCase("ENCAISSER_MONTANT")) {
77,7 → 87,7
SQLRow rowEncaisse = source;
 
SQLRow rowEncaisseElt = null;
// On crée un encaissement
// On cre un encaissement
if (createEncaisse) {
SQLRowValues rowVals = new SQLRowValues(tableEncaisse);
rowVals.put("MONTANT", ttc.getLongValue());
150,15 → 160,6
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.CAISSES);
}
 
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteRegl <= 1) {
if (typeRegRow.getID() == TypeReglementSQLElement.ESPECE) {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteEspece");
} else {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteCB");
}
}
 
// compte Clients
 
int idCompteClient = rowClient.getInt("ID_COMPTE_PCE");
172,10 → 173,19
this.mEcritures.put("ID_COMPTE_PCE", idCompteClient);
this.mEcritures.put("DEBIT", Long.valueOf(0));
this.mEcritures.put("CREDIT", Long.valueOf(ttc.getLongValue()));
ajoutEcriture();
this.ecrClient = ajoutEcriture();
 
// compte de reglement, caisse, cheque, ...
if (typeRegRow.getID() == TypeReglementSQLElement.ESPECE) {
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteRegl <= 1) {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteEspece");
}
 
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteRegl));
} else {
fillCompteBanqueFromRow(modeReglement, "VenteCB", false);
}
this.mEcritures.put("DEBIT", Long.valueOf(ttc.getLongValue()));
this.mEcritures.put("CREDIT", Long.valueOf(0));
ajoutEcriture();
185,7 → 195,7
 
Date dateEch = ModeDeReglementSQLElement.calculDate(modeReglement.getInt("AJOURS"), modeReglement.getInt("LENJOUR"), this.date);
 
System.out.println("Echéance client");
System.out.println("Echance client");
 
// Ajout dans echeance
final SQLTable tableEch = base.getTable("ECHEANCE_CLIENT");
237,10 → 247,68
 
}
 
public void doLettrageAuto(final SQLRowAccessor source, Date dateLettrage) {
// A. On lettre les critures client (facture ET reglement)
// A1. Recherche criture client de facturation
 
final SQLRowValues g1 = new SQLRowValues(ecritureTable);
g1.put("DEBIT", null);
final SQLRowValuesListFetcher fetch1 = new SQLRowValuesListFetcher(g1);
fetch1.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
@Override
public SQLSelect transformChecked(SQLSelect input) {
input.setWhere(new Where(ecritureTable.getField("ID_MOUVEMENT"), "=", source.getForeignID("ID_MOUVEMENT")));
input.andWhere(new Where(ecritureTable.getField("ID_COMPTE_PCE"), "=", ecrClient.getForeignID("ID_COMPTE_PCE")));
input.andWhere(new Where(ecritureTable.getField("JOURNAL_CODE"), "=", "VE"));
return input;
}
 
});
final List<SQLRowValues> rowsEcriture1 = fetch1.fetch();
if (rowsEcriture1.size() != 1) {
System.out.println("critures VE trouves. Erreur");
return;
}
final SQLRowValues rEcriture1 = rowsEcriture1.get(0);
System.out.println("Ecriture vente: " + rEcriture1.getID());
System.out.println("Ecriture paiement: " + this.ecrClient);
 
// Récupère lettrage
String codeLettre = NumerotationAutoSQLElement.getNextCodeLettrage();
 
// TODO: vérifier somme = 0
 
// Met à  jour les 2 écritures
SQLRowValues rowVals = new SQLRowValues(ecritureTable);
rowVals.put("LETTRAGE", codeLettre);
rowVals.put("DATE_LETTRAGE", dateLettrage);
try {
rowVals.update(rEcriture1.getID());
rowVals.update(this.ecrClient.getID());
} catch (SQLException e1) {
e1.printStackTrace();
}
 
// Mise à  jour du code de lettrage
SQLElement numElt = Configuration.getInstance().getDirectory().getElement("NUMEROTATION_AUTO");
SQLRowValues rowVals1 = numElt.getTable().getRow(2).createEmptyUpdateRow();
rowVals1.put("CODE_LETTRAGE", codeLettre);
try {
rowVals1.update();
} catch (SQLException e) {
e.printStackTrace();
}
}
 
private void paiementCheque(Date dateEch, SQLRow source, PrixTTC ttc, int idClient, SQLRow modeRegl, SQLRow mvtSource) throws SQLException {
 
SQLRowValues valCheque = new SQLRowValues(base.getTable("CHEQUE_A_ENCAISSER"));
valCheque.put("ID_CLIENT", idClient);
 
final String foreignBanqueFieldName = "ID_" + BanqueSQLElement.TABLENAME;
if (valCheque.getTable().contains(foreignBanqueFieldName))
valCheque.put(foreignBanqueFieldName, modeRegl.getInt(foreignBanqueFieldName));
 
valCheque.put("NUMERO", modeRegl.getObject("NUMERO"));
valCheque.put("DATE", modeRegl.getObject("DATE"));
valCheque.put("ETS", modeRegl.getObject("ETS"));
251,7 → 319,6
valCheque.put("MONTANT", Long.valueOf(ttc.getLongValue()));
 
if (valCheque.getInvalid() == null) {
 
// ajout de l'ecriture
SQLRow row = valCheque.insert();
SQLRowValues rowVals = new SQLRowValues(tableMouvement);
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementAchat.java
13,9 → 13,11
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement;
import org.openconcerto.erp.model.PrixTTC;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
100,10 → 102,7
if (typeRegRow.getID() == 4) {
this.mEcritures.put("ID_JOURNAL", GenerationMvtReglementAchat.journalCaisse);
} else {
 
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
 
 
fillJournalBanqueFromRow(modeRegRow);
}
 
// compte Fournisseurs
121,11 → 120,16
ajoutEcriture();
 
// compte de reglement, caisse, CB, ...
if (typeRegRow.getID() == TypeReglementSQLElement.ESPECE) {
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_FOURN");
if (idCompteRegl <= 1) {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteCB");
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("VenteEspece");
}
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteRegl));
 
} else {
fillCompteBanqueFromRow(modeRegRow, "VenteCB", true);
}
this.mEcritures.put("DEBIT", Long.valueOf(0));
this.mEcritures.put("CREDIT", Long.valueOf(prixTTC.getLongValue()));
ajoutEcriture();
192,19 → 196,30
}
 
// Ajout dans cheque fournisseur
Map<String, Object> mEncaisse = new HashMap<String, Object>();
mEncaisse.put("ID_FOURNISSEUR", Integer.valueOf(saisieRow.getInt("ID_FOURNISSEUR")));
mEncaisse.put("DATE_ACHAT", new java.sql.Date(this.date.getTime()));
mEncaisse.put("DATE_MIN_DECAISSE", new java.sql.Date(dateEch.getTime()));
mEncaisse.put("MONTANT", Long.valueOf(prixTTC.getLongValue()));
Map<String, Object> mCheque = new HashMap<String, Object>();
mCheque.put("ID_FOURNISSEUR", Integer.valueOf(saisieRow.getInt("ID_FOURNISSEUR")));
mCheque.put("DATE_ACHAT", new java.sql.Date(this.date.getTime()));
mCheque.put("DATE_MIN_DECAISSE", new java.sql.Date(dateEch.getTime()));
 
mCheque.put("MONTANT", Long.valueOf(prixTTC.getLongValue()));
if (!saisieRow.isForeignEmpty("ID_MODE_REGLEMENT")) {
SQLRow rowModeRegl = saisieRow.getForeignRow("ID_MODE_REGLEMENT");
mCheque.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
mCheque.put("NUMERO", rowModeRegl.getObject("NUMERO"));
mCheque.put("DATE", rowModeRegl.getObject("DATE"));
mCheque.put("ETS", rowModeRegl.getObject("ETS"));
if (rowModeRegl.getObject("DATE_DEPOT") != null) {
mCheque.put("DATE_MIN_DECAISSE", rowModeRegl.getObject("DATE_DEPOT"));
}
}
SQLRow rowMvtPere = tableMouvement.getRow(this.idPere);
this.idMvt = getNewMouvement("CHEQUE_FOURNISSEUR", 1, this.idPere, rowMvtPere.getInt("ID_PIECE"));
 
mEncaisse.put("ID_MOUVEMENT", Integer.valueOf(this.idMvt));
mCheque.put("ID_MOUVEMENT", Integer.valueOf(this.idMvt));
 
SQLTable chqFournTable = base.getTable("CHEQUE_FOURNISSEUR");
 
SQLRowValues valDecaisse = new SQLRowValues(chqFournTable, mEncaisse);
SQLRowValues valDecaisse = new SQLRowValues(chqFournTable, mCheque);
 
if (valDecaisse.getInvalid() == null) {
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementAvoir.java
13,6 → 13,7
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
66,7 → 67,7
if (typeRegRow.getID() == 4) {
this.mEcritures.put("ID_JOURNAL", GenerationMvtReglementAvoir.journalCaisse);
} else {
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
fillJournalBanqueFromRow(modeRegRow);
}
 
this.idMvt = idPere;
168,6 → 169,11
valEncaisse.put("ID_CLIENT", new Integer(saisieRow.getInt("ID_CLIENT")));
valEncaisse.put("DATE_AVOIR", this.date);
valEncaisse.put("DATE_MIN_DECAISSE", dateEch);
if (!saisieRow.isForeignEmpty("ID_MODE_REGLEMENT")) {
SQLRow rowModeRegl = saisieRow.getForeignRow("ID_MODE_REGLEMENT");
valEncaisse.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
}
 
SQLRow rowMvtPere = tableMouvement.getRow(idPere);
this.idMvt = getNewMouvement("CHEQUE_AVOIR_CLIENT", 1, idPere, rowMvtPere.getInt("ID_PIECE"));
valEncaisse.put("ID_MOUVEMENT", new Integer(this.idMvt));
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtAvoirFournisseur.java
88,9 → 88,9
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteAchat));
this.mEcritures.put("DEBIT", Long.valueOf(0));
this.mEcritures.put("CREDIT", Long.valueOf(prixHT.getLongValue()));
SQLRow rowEcr = ajoutEcriture();
addAssocAnalytiqueFromProvider(rowEcr, avoirRow);
 
ajoutEcriture();
 
if (prixTVA.getLongValue() > 0) {
// compte TVA
int idCompteTVA = rowPrefsCompte.getInt("ID_COMPTE_PCE_TVA_ACHAT");
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementChequeFourn.java
39,7 → 39,8
this.nom = "Reglement cheque " + rowFournisseur.getString("NOM");
this.mEcritures.put("DATE", new java.sql.Date(this.date.getTime()));
this.mEcritures.put("NOM", this.nom);
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
 
fillJournalBanqueFromRow(rowCheque);
this.mEcritures.put("ID_MOUVEMENT", new Integer(this.idMvt));
 
// compte Fournisseurs
58,14 → 59,8
this.mEcritures.put("CREDIT", new Long(0));
ajoutEcriture();
 
int idPce = base.getTable("TYPE_REGLEMENT").getRow(2).getInt("ID_COMPTE_PCE_FOURN");
if (idPce <= 1) {
 
idPce = ComptePCESQLElement.getIdComptePceDefault("AchatCheque");
 
}
// compte de reglement cheque, ...
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idPce));
fillCompteBanqueFromRow(rowCheque, "AchatCheque", true);
this.mEcritures.put("DEBIT", new Long(0));
this.mEcritures.put("CREDIT", new Long(montant));
ajoutEcriture();
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieVenteFacture.java
42,6 → 42,7
private static final String source = "SAISIE_VENTE_FACTURE";
public static final Integer journal = Integer.valueOf(JournalSQLElement.VENTES);
private int idSaisieVenteFacture;
private boolean useComptePCEVente;
private static final SQLTable saisieVFTable = base.getTable("SAISIE_VENTE_FACTURE");
private static final SQLTable mvtTable = base.getTable("MOUVEMENT");
private static final SQLTable ecrTable = base.getTable("ECRITURE");
54,13 → 55,18
* @param idSaisieVenteFacture
* @param idMvt id du mouvement qui est dejà associé à la facture
*/
public GenerationMvtSaisieVenteFacture(int idSaisieVenteFacture, int idMvt) {
public GenerationMvtSaisieVenteFacture(int idSaisieVenteFacture, int idMvt, boolean useComptePCEVente) {
System.err.println("********* init GeneRation");
this.idMvt = idMvt;
this.idSaisieVenteFacture = idSaisieVenteFacture;
this.useComptePCEVente = useComptePCEVente;
new Thread(GenerationMvtSaisieVenteFacture.this).start();
}
 
public GenerationMvtSaisieVenteFacture(int idSaisieVenteFacture, int idMvt) {
this(idSaisieVenteFacture, idMvt, false);
}
 
/**
* Generation de la comptabilité associée à la création d'une saisie de vente facture
*
124,10 → 130,18
for (SQLRowAccessor row : calc.getMapHt().keySet()) {
long b = calc.getMapHt().get(row).setScale(2, RoundingMode.HALF_UP).movePointRight(2).longValue();
if (b != 0) {
this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(row.getID()));
final Integer idComptePCE;
if (this.useComptePCEVente) {
// Utilise le compte de la facture
idComptePCE = saisieRow.getInt("ID_COMPTE_PCE_VENTE");
} else {
idComptePCE = Integer.valueOf(row.getID());
}
this.mEcritures.put("ID_COMPTE_PCE", idComptePCE);
this.mEcritures.put("DEBIT", Long.valueOf(0));
this.mEcritures.put("CREDIT", Long.valueOf(b));
int idEcr = ajoutEcriture();
SQLRow rowEcr = ajoutEcriture();
addAssocAnalytiqueFromProvider(rowEcr, saisieRow);
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationReglementAchat.java
13,6 → 13,7
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement;
86,7 → 87,7
if (typeRegRow.getID() == 4) {
this.mEcritures.put("ID_JOURNAL", GenerationReglementAchat.journalCaisse);
} else {
this.mEcritures.put("ID_JOURNAL", JournalSQLElement.BANQUES);
fillJournalBanqueFromRow(modeRegRow);
}
 
// SQLRow echeanceRow = base.getTable("ECHEANCE_FOURNISSEUR").getRow(idEchFourn);
114,15 → 115,7
ajoutEcriture();
 
// compte de reglement, caisse, CB, ...
int idCompteRegl = typeRegRow.getInt("ID_COMPTE_PCE_FOURN");
if (idCompteRegl <= 1) {
try {
idCompteRegl = ComptePCESQLElement.getIdComptePceDefault("AchatCB");
} catch (Exception e) {
e.printStackTrace();
}
}
this.mEcritures.put("ID_COMPTE_PCE", new Integer(idCompteRegl));
fillCompteBanqueFromRow(modeRegRow, "AchatCB", true);
this.mEcritures.put("DEBIT", new Long(0));
this.mEcritures.put("CREDIT", new Long(prixTTC.getLongValue()));
ajoutEcriture();
176,6 → 169,10
valCheque.put("ID_FOURNISSEUR", idFourn);
valCheque.put("DATE_ACHAT", this.date);
valCheque.put("DATE_MIN_DECAISSE", dateEch);
if (!regMontantRow.isForeignEmpty("ID_MODE_REGLEMENT")) {
SQLRow rowModeRegl = regMontantRow.getForeignRow("ID_MODE_REGLEMENT");
valCheque.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
}
 
this.idMvt = getNewMouvement("CHEQUE_FOURNISSEUR", 1, rowMvtSource.getID(), rowMvtSource.getInt("ID_PIECE"));
valCheque.put("ID_MOUVEMENT", new Integer(this.idMvt));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/reports/history/ui/ListeHistoriquePanel.java
182,7 → 182,7
 
public ListeHistoriquePanel(final String title, final ComboSQLRequest req, Map<String, List<String>> listTableOnglet, JPanel panelBottom, Map<SQLTable, SQLField> listFieldMap,
String undefinedLabel, Where where) {
this(title, req, listTableOnglet, panelBottom, listFieldMap, undefinedLabel, false, where);
this(title, req, listTableOnglet, panelBottom, listFieldMap, undefinedLabel, false, where, null);
}
 
// TODO verifier que les tables contiennent bien la clef etrangere
198,7 → 198,7
* @param where
*/
public ListeHistoriquePanel(final String title, final ComboSQLRequest req, Map<String, List<String>> listTableOnglet, JPanel panelBottom, Map<SQLTable, SQLField> listFieldMap,
String undefinedLabel, final boolean sourceWithOutTransformer, Where where) {
String undefinedLabel, final boolean sourceWithOutTransformer, Where where, SQLTableModelSourceOnline tableSource) {
super();
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
233,7 → 233,12
final SQLElement elt = Configuration.getInstance().getDirectory().getElement(listPanelTable.get(i));
 
IListPanel liste;
SQLTableModelSourceOnline createTableSource = elt.getTableSource(true);
final SQLTableModelSourceOnline createTableSource;
if (tableSource == null) {
createTableSource = elt.getTableSource(true);
} else {
createTableSource = tableSource;
}
final ListSQLRequest request = createTableSource.getReq();
if (sourceWithOutTransformer) {
request.setSelectTransf(null);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/product/component/ArticleFournisseurSQLComponent.java
New file
0,0 → 1,1160
/*
* 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.supplychain.product.component;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.common.ui.CodeFournisseurItemTable;
import org.openconcerto.erp.core.common.ui.TotalPanel;
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.core.sales.product.element.ReferenceArticleSQLElement;
import org.openconcerto.erp.core.sales.product.element.UniteVenteArticleSQLElement;
import org.openconcerto.erp.model.ISQLCompteSelector;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.component.ITextArea;
import org.openconcerto.ui.preferences.DefaultProps;
import org.openconcerto.utils.StringUtils;
import org.openconcerto.utils.text.SimpleDocumentListener;
 
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.util.List;
 
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
 
public class ArticleFournisseurSQLComponent extends BaseSQLComponent {
 
private JTextField textPVHT, textPVTTC, textPAHT;
private JTextField textMetrique1VT, textMetrique1HA;
 
private final JCheckBox boxService = new JCheckBox(getLabelFor("SERVICE"));
private final JCheckBox checkObs = new JCheckBox(getLabelFor("OBSOLETE"));
private JTextField textNom, textCode;
private JTextField textPoids;
private JTextField textValMetrique1, textValMetrique2, textValMetrique3;
private DocumentListener htDocListener, ttcDocListener, detailsListener;
private PropertyChangeListener propertyChangeListener;
private PropertyChangeListener taxeListener;
private final ElementComboBox comboSelTaxe = new ElementComboBox(false, 10);
private final ElementComboBox comboSelModeVente = new ElementComboBox(false, 25);
private JLabel labelMetriqueHA1 = new JLabel(getLabelFor("PRIX_METRIQUE_HA_1"), SwingConstants.RIGHT);
private JLabel labelMetriqueVT1 = new JLabel(getLabelFor("PRIX_METRIQUE_VT_1"), SwingConstants.RIGHT);
 
private final JTextField textMarge = new JTextField(15);
 
private DocumentListener pieceHAArticle = new DocumentListener() {
 
public void changedUpdate(DocumentEvent arg0) {
ArticleFournisseurSQLComponent.this.textMetrique1HA.setText(ArticleFournisseurSQLComponent.this.textPAHT.getText());
}
 
public void insertUpdate(DocumentEvent arg0) {
ArticleFournisseurSQLComponent.this.textMetrique1HA.setText(ArticleFournisseurSQLComponent.this.textPAHT.getText());
}
 
public void removeUpdate(DocumentEvent arg0) {
ArticleFournisseurSQLComponent.this.textMetrique1HA.setText(ArticleFournisseurSQLComponent.this.textPAHT.getText());
}
 
};
private DocumentListener pieceVTArticle = new DocumentListener() {
 
public void changedUpdate(DocumentEvent arg0) {
ArticleFournisseurSQLComponent.this.textMetrique1VT.setText(ArticleFournisseurSQLComponent.this.textPVHT.getText());
}
 
public void insertUpdate(DocumentEvent arg0) {
ArticleFournisseurSQLComponent.this.textMetrique1VT.setText(ArticleFournisseurSQLComponent.this.textPVHT.getText());
}
 
public void removeUpdate(DocumentEvent arg0) {
ArticleFournisseurSQLComponent.this.textMetrique1VT.setText(ArticleFournisseurSQLComponent.this.textPVHT.getText());
}
 
};
 
private DocumentListener listenerMargeTextMarge = new SimpleDocumentListener() {
@Override
public void update(DocumentEvent e) {
ArticleFournisseurSQLComponent.this.textPVHT.getDocument().removeDocumentListener(ArticleFournisseurSQLComponent.this.listenerMargeTextVT);
updateVtFromMarge();
ArticleFournisseurSQLComponent.this.textPVHT.getDocument().addDocumentListener(ArticleFournisseurSQLComponent.this.listenerMargeTextVT);
}
 
};
 
private DocumentListener listenerMargeTextVT = new SimpleDocumentListener() {
@Override
public void update(DocumentEvent e) {
ArticleFournisseurSQLComponent.this.textMarge.getDocument().removeDocumentListener(ArticleFournisseurSQLComponent.this.listenerMargeTextMarge);
if (ArticleFournisseurSQLComponent.this.textPVHT.getText().trim().length() > 0 && ArticleFournisseurSQLComponent.this.textPAHT.getText().trim().length() > 0) {
final BigDecimal vt = StringUtils.getBigDecimalFromUserText(ArticleFournisseurSQLComponent.this.textPVHT.getText());
final BigDecimal ha = StringUtils.getBigDecimalFromUserText(ArticleFournisseurSQLComponent.this.textPAHT.getText());
 
if (vt != null && ha != null) {
if (vt.signum() != 0 && ha.signum() != 0) {
BigDecimal margeHT = vt.subtract(ha);
 
BigDecimal value;
 
if (DefaultNXProps.getInstance().getBooleanValue(TotalPanel.MARGE_MARQUE, false)) {
if (vt.compareTo(BigDecimal.ZERO) > 0) {
value = margeHT.divide(vt, MathContext.DECIMAL128).multiply(BigDecimal.valueOf(100), MathContext.DECIMAL128);
} else {
value = BigDecimal.ZERO;
}
} else {
value = margeHT.divide(ha, MathContext.DECIMAL128).multiply(BigDecimal.valueOf(100), MathContext.DECIMAL128);
}
 
if (value.compareTo(BigDecimal.ZERO) > 0) {
ArticleFournisseurSQLComponent.this.textMarge.setText(value.setScale(6, RoundingMode.HALF_UP).toString());
} else {
ArticleFournisseurSQLComponent.this.textMarge.setText("0");
}
}
}
}
ArticleFournisseurSQLComponent.this.textMarge.getDocument().addDocumentListener(ArticleFournisseurSQLComponent.this.listenerMargeTextMarge);
}
};
 
private DocumentListener listenerMargeTextHA = new SimpleDocumentListener() {
@Override
public void update(DocumentEvent e) {
ArticleFournisseurSQLComponent.this.textPVHT.getDocument().removeDocumentListener(ArticleFournisseurSQLComponent.this.listenerMargeTextVT);
updateVtFromMarge();
ArticleFournisseurSQLComponent.this.textPVHT.getDocument().addDocumentListener(ArticleFournisseurSQLComponent.this.listenerMargeTextVT);
}
};
 
private void updateVtFromMarge() {
if (this.textPAHT.getText().trim().length() > 0) {
 
BigDecimal ha = StringUtils.getBigDecimalFromUserText(this.textPAHT.getText());
if (ha != null && this.textMarge.getText().trim().length() > 0) {
 
BigDecimal d = StringUtils.getBigDecimalFromUserText(this.textMarge.getText());
if (DefaultNXProps.getInstance().getBooleanValue(TotalPanel.MARGE_MARQUE, false)) {
final BigDecimal e = BigDecimal.ONE.subtract(d.divide(BigDecimal.valueOf(100), MathContext.DECIMAL128));
if (e.signum() == 0) {
this.textPVHT.setText("0");
} else {
this.textPVHT.setText(ha.divide(e, MathContext.DECIMAL128).setScale(getTable().getField("PV_HT").getType().getDecimalDigits(), RoundingMode.HALF_UP).toString());
}
} else {
BigDecimal result = ha.multiply(d.divide(BigDecimal.valueOf(100), MathContext.DECIMAL128).add(BigDecimal.ONE));
this.textPVHT.setText(result.setScale(getTable().getField("PV_HT").getType().getDecimalDigits(), RoundingMode.HALF_UP).toString());
}
}
}
}
 
public ArticleFournisseurSQLComponent(SQLElement elt) {
super(elt);
}
 
@Override
public void select(SQLRowAccessor r) {
super.select(r);
if (r != null && r.getID() > getTable().getUndefinedID()) {
this.checkObs.setVisible(true);
if (this.codeFournisseurTable != null) {
this.codeFournisseurTable.insertFrom("ID_ARTICLE", r.getID());
}
}
}
 
public void addViews() {
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
 
this.textPVHT = new JTextField(15);
this.textPVTTC = new JTextField(15);
this.textPAHT = new JTextField(15);
this.textPVHT.getDocument().addDocumentListener(this.listenerMargeTextVT);
 
// Init metrique devise field
this.textMetrique1HA = new JTextField(15);
this.textMetrique1VT = new JTextField(15);
 
// init metrique value field
this.textValMetrique1 = new JTextField(15);
this.textValMetrique2 = new JTextField(15);
this.textValMetrique3 = new JTextField(15);
 
this.textCode = new JTextField();
this.textNom = new JTextField();
this.textPoids = new JTextField(6);
 
// Code
JLabel codelabel = new JLabel(getLabelFor("CODE"));
codelabel.setHorizontalAlignment(SwingConstants.RIGHT);
DefaultGridBagConstraints.lockMinimumSize(codelabel);
this.add(codelabel, c);
c.gridx++;
c.weightx = 1;
DefaultGridBagConstraints.lockMinimumSize(textCode);
this.add(this.textCode, c);
 
// Famille
c.gridx++;
c.gridwidth = 1;
c.weightx = 0;
JLabel labelFamille = new JLabel(getLabelFor("ID_FAMILLE_ARTICLE_FOURNISSEUR"));
labelFamille.setHorizontalAlignment(SwingConstants.RIGHT);
DefaultGridBagConstraints.lockMinimumSize(labelFamille);
this.add(labelFamille, c);
c.gridx++;
c.weightx = 1;
c.gridwidth = 1;
final ElementComboBox comboSelFamille = new ElementComboBox(false, 25);
this.addSQLObject(comboSelFamille, "ID_FAMILLE_ARTICLE_FOURNISSEUR");
DefaultGridBagConstraints.lockMinimumSize(comboSelFamille);
this.add(comboSelFamille, c);
 
// Nom
c.gridy++;
c.gridx = 0;
c.weightx = 0;
JLabel labelNom = new JLabel(getLabelFor("NOM"));
labelNom.setHorizontalAlignment(SwingConstants.RIGHT);
DefaultGridBagConstraints.lockMinimumSize(labelNom);
this.add(labelNom, c);
c.gridx++;
c.weightx = 1;
DefaultGridBagConstraints.lockMinimumSize(textNom);
this.add(this.textNom, c);
 
// Code barre
c.gridx++;
c.weightx = 0;
JLabel labelCodeBarre = new JLabel(getLabelFor("CODE_BARRE"));
labelCodeBarre.setHorizontalAlignment(SwingConstants.RIGHT);
DefaultGridBagConstraints.lockMinimumSize(labelCodeBarre);
this.add(labelCodeBarre, c);
c.gridx++;
c.weightx = 1;
JTextField fieldCodeBarre = new JTextField();
DefaultGridBagConstraints.lockMinimumSize(fieldCodeBarre);
this.add(fieldCodeBarre, c);
this.addView(fieldCodeBarre, "CODE_BARRE");
 
SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
// Gestion des unités de vente
final boolean gestionUV = prefs.getBoolean(GestionArticleGlobalPreferencePanel.UNITE_VENTE, true);
if (gestionUV) {
c.gridy++;
c.gridx = 0;
c.weightx = 0;
this.add(new JLabel(getLabelFor("ID_UNITE_VENTE"), SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
c.fill = GridBagConstraints.NONE;
ElementComboBox boxUnite = new ElementComboBox();
DefaultGridBagConstraints.lockMinimumSize(boxUnite);
this.add(boxUnite, c);
this.addView(boxUnite, "ID_UNITE_VENTE");
c.fill = GridBagConstraints.HORIZONTAL;
}
DefaultProps props = DefaultNXProps.getInstance();
 
// Article détaillé
String modeVente = props.getStringProperty("ArticleModeVenteAvance");
Boolean bModeVente = Boolean.valueOf(modeVente);
boolean modeVenteAvance = (bModeVente == null || bModeVente.booleanValue());
 
if (modeVenteAvance) {
addModeVenteAvance(c);
}
 
getMontantPanel(c, props);
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = ComptaSQLConfElement.createAdditionalPanel();
this.setAdditionalFieldsPanel(new FormLayouter(addP, 2));
this.add(addP, c);
 
JTabbedPane pane = new JTabbedPane();
c.gridy++;
c.weightx = 1;
c.weighty = 1;
 
pane.add("Tarifs de vente", createTarifPanel());
pane.add("Exportation", createExportationPanel());
pane.add("Achat", createAchatPanel());
pane.add("Stock", createStockPanel());
pane.add("Descriptif", createDescriptifPanel());
pane.add("Désignations multilingues", createDesignationPanel());
pane.add("Comptabilité", createComptaPanel());
pane.add(getLabelFor("INFOS"), createInfosPanel());
 
c.fill = GridBagConstraints.BOTH;
this.add(pane, c);
 
this.addSQLObject(this.textMetrique1HA, "PRIX_METRIQUE_HA_1");
this.addSQLObject(this.textMetrique1VT, "PRIX_METRIQUE_VT_1");
this.addSQLObject(this.textValMetrique1, "VALEUR_METRIQUE_1");
this.addSQLObject(this.textValMetrique2, "VALEUR_METRIQUE_2");
this.addSQLObject(this.textValMetrique3, "VALEUR_METRIQUE_3");
this.addSQLObject(this.comboSelModeVente, "ID_MODE_VENTE_ARTICLE");
this.addSQLObject(this.boxService, "SERVICE");
 
this.addRequiredSQLObject(this.textNom, "NOM");
this.addRequiredSQLObject(this.textCode, "CODE");
 
this.addSQLObject(this.textPoids, "POIDS");
 
this.comboSelTaxe.setButtonsVisible(false);
this.propertyChangeListener = new PropertyChangeListener() {
 
public void propertyChange(PropertyChangeEvent evt) {
System.err.println(ArticleFournisseurSQLComponent.this.comboSelModeVente.getSelectedId());
selectModeVente(ArticleFournisseurSQLComponent.this.comboSelModeVente.getSelectedId());
 
}
};
setListenerModeVenteActive(true);
this.comboSelModeVente.setValue(ReferenceArticleSQLElement.A_LA_PIECE);
}
 
private Component createInfosPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
 
c.weightx = 1;
c.weighty = 1;
ITextArea infos = new ITextArea();
c.fill = GridBagConstraints.BOTH;
panel.add(infos, c);
 
this.addSQLObject(infos, "INFOS");
 
return panel;
}
 
private Component createDescriptifPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
 
// Obsolete
c.fill = GridBagConstraints.NONE;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1;
this.checkObs.setOpaque(false);
panel.add(this.checkObs, c);
 
this.checkObs.setVisible(false);
this.addView(this.checkObs, "OBSOLETE");
 
if (getTable().getFieldsName().contains("COLORIS")) {
JTextField fieldColoris = new JTextField();
c.gridy++;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0;
c.gridwidth = 1;
panel.add(new JLabel(getLabelFor("COLORIS")), c);
 
c.weightx = 1;
c.gridx++;
panel.add(fieldColoris, c);
this.addView(fieldColoris, "COLORIS");
}
ITextArea area = new ITextArea();
JLabel sep = new JLabel("Descriptif complet");
c.gridy++;
c.gridx = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(sep, c);
 
c.gridy++;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
panel.add(area, c);
this.addView(area, "DESCRIPTIF");
return panel;
}
 
private Component createDesignationPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
 
// Ajout des
c.gridwidth = 1;
c.weightx = 0;
c.gridy++;
c.gridx = 0;
panel.add(new JLabel("Ajouter une désignation "), c);
 
final ElementComboBox boxDes = new ElementComboBox();
boxDes.init(Configuration.getInstance().getDirectory().getElement("LANGUE"));
 
c.gridx++;
panel.add(boxDes, c);
 
c.fill = GridBagConstraints.NONE;
c.gridx++;
JButton buttonAjouterDes = new JButton("Ajouter");
buttonAjouterDes.setOpaque(false);
panel.add(buttonAjouterDes, c);
c.gridx++;
JButton buttonSupprimerDes = new JButton("Supprimer");
buttonSupprimerDes.setOpaque(false);
panel.add(buttonSupprimerDes, c);
 
c.gridy++;
c.gridx = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.BOTH;
c.weighty = 1;
c.weightx = 1;
 
return panel;
}
 
private Component createStockPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
DefaultProps props = DefaultNXProps.getInstance();
String stockMin = props.getStringProperty("ArticleStockMin");
Boolean bStockMin = !stockMin.equalsIgnoreCase("false");
boolean gestionStockMin = (bStockMin == null || bStockMin.booleanValue());
c.gridx = 0;
c.gridy++;
 
final JCheckBox boxStock = new JCheckBox(getLabelFor("GESTION_STOCK"));
boxStock.setOpaque(false);
panel.add(boxStock, c);
this.addView(boxStock, "GESTION_STOCK");
 
final JTextField fieldQteMin = new JTextField();
final JTextField fieldQteAchat = new JTextField();
boxStock.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
fieldQteMin.setEnabled(boxStock.isSelected());
fieldQteAchat.setEnabled(boxStock.isSelected());
}
});
 
c.gridwidth = 1;
if (gestionStockMin) {
c.gridx = 0;
c.gridy++;
c.weightx = 0;
panel.add(new JLabel(getLabelFor("QTE_MIN")), c);
c.gridx++;
c.weightx = 1;
panel.add(fieldQteMin, c);
this.addView(fieldQteMin, "QTE_MIN");
 
c.gridx = 0;
c.gridy++;
c.weightx = 0;
panel.add(new JLabel(getLabelFor("QTE_ACHAT")), c);
c.gridx++;
c.weightx = 1;
panel.add(fieldQteAchat, c);
this.addView(fieldQteAchat, "QTE_ACHAT");
}
 
c.gridy++;
c.weighty = 1;
c.weightx = 1;
c.fill = GridBagConstraints.BOTH;
final JPanel spacer = new JPanel();
spacer.setOpaque(false);
panel.add(spacer, c);
return panel;
}
 
private Component createComptaPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
c.gridwidth = 1;
c.weighty = 0;
c.weightx = 0;
ISQLCompteSelector sel = new ISQLCompteSelector();
c.fill = GridBagConstraints.BOTH;
panel.add(new JLabel(getLabelFor("ID_COMPTE_PCE")), c);
c.gridx++;
c.weightx = 1;
panel.add(sel, c);
this.addView(sel, "ID_COMPTE_PCE");
 
c.gridwidth = 1;
c.gridy++;
c.weighty = 0;
c.gridx = 0;
c.weightx = 0;
ISQLCompteSelector selAchat = new ISQLCompteSelector();
c.fill = GridBagConstraints.BOTH;
panel.add(new JLabel(getLabelFor("ID_COMPTE_PCE_ACHAT")), c);
c.gridx++;
c.weightx = 1;
panel.add(selAchat, c);
this.addView(selAchat, "ID_COMPTE_PCE_ACHAT");
 
c.gridy++;
c.weighty = 1;
c.weightx = 1;
c.fill = GridBagConstraints.BOTH;
final JPanel spacer = new JPanel();
spacer.setOpaque(false);
panel.add(spacer, c);
return panel;
}
 
private SQLRowValues rowValuesDefaultCodeFournisseur;
private CodeFournisseurItemTable codeFournisseurTable;
 
private Component createAchatPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
// Fournisseur
c.gridy++;
c.gridx = 0;
c.gridwidth = 1;
c.weightx = 0;
JLabel labelFournisseur = new JLabel(getLabelFor("ID_FOURNISSEUR"));
labelFournisseur.setHorizontalAlignment(SwingConstants.RIGHT);
panel.add(labelFournisseur, c);
c.gridx++;
c.weightx = 1;
c.gridwidth = 2;
final ElementComboBox comboSelFournisseur = new ElementComboBox(false, 25);
panel.add(comboSelFournisseur, c);
this.addView(comboSelFournisseur, "ID_FOURNISSEUR");
 
SQLPreferences prefs = new SQLPreferences(ComptaPropsConfiguration.getInstanceCompta().getRootSociete());
final boolean supplierCode = prefs.getBoolean(GestionArticleGlobalPreferencePanel.SUPPLIER_PRODUCT_CODE, false);
 
if (getTable().getSchema().contains("CODE_FOURNISSEUR") && supplierCode) {
this.rowValuesDefaultCodeFournisseur = new SQLRowValues(getTable().getTable("CODE_FOURNISSEUR"));
this.codeFournisseurTable = new CodeFournisseurItemTable(this.rowValuesDefaultCodeFournisseur);
c.gridy++;
c.gridx = 0;
c.gridwidth = 3;
c.weighty = 1;
c.weightx = 1;
c.fill = GridBagConstraints.BOTH;
panel.add(this.codeFournisseurTable, c);
comboSelFournisseur.addValueListener(new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
rowValuesDefaultCodeFournisseur.put("ID_FOURNISSEUR", comboSelFournisseur.getSelectedId());
}
});
} else {
c.gridy++;
c.weighty = 1;
c.weightx = 1;
c.fill = GridBagConstraints.BOTH;
final JPanel spacer = new JPanel();
spacer.setOpaque(false);
panel.add(spacer, c);
}
return panel;
}
 
private JPanel createExportationPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
// Code douanier
c.gridx = 0;
c.weightx = 0;
c.gridy++;
c.gridwidth = 1;
JLabel labelCodeD = new JLabel(getLabelFor("CODE_DOUANIER"));
labelCodeD.setHorizontalAlignment(SwingConstants.RIGHT);
panel.add(labelCodeD, c);
 
c.gridx++;
JTextField fieldCodeDouanier = new JTextField();
c.weightx = 1;
panel.add(fieldCodeDouanier, c);
this.addView(fieldCodeDouanier, "CODE_DOUANIER");
 
// Pays d'origine
c.gridx++;
c.weightx = 0;
JLabel labelPays = new JLabel(getLabelFor("ID_PAYS"));
labelPays.setHorizontalAlignment(SwingConstants.RIGHT);
panel.add(labelPays, c);
c.gridx++;
c.weightx = 1;
final ElementComboBox comboSelPays = new ElementComboBox(false);
panel.add(comboSelPays, c);
this.addView(comboSelPays, "ID_PAYS");
c.gridy++;
c.weighty = 1;
c.weightx = 1;
c.fill = GridBagConstraints.BOTH;
final JPanel spacer = new JPanel();
spacer.setOpaque(false);
panel.add(spacer, c);
return panel;
}
 
private JPanel createTarifPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints c = new DefaultGridBagConstraints();
 
// Ajout tarif
c.gridwidth = 1;
c.weightx = 0;
c.gridy++;
c.gridx = 0;
panel.add(new JLabel("Ajouter le tarif "), c);
 
return panel;
}
 
protected void getMontantPanel(final GridBagConstraints c, DefaultProps props) {
c.gridx = 0;
c.gridy++;
c.gridwidth = 1;
// PA devise
JPanel pDevise = new JPanel(new GridBagLayout());
GridBagConstraints cDevise = new DefaultGridBagConstraints();
cDevise.insets = new Insets(0, 0, 0, 4);
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel("Devise du fournisseur"), c);
final ElementComboBox boxDevise = new ElementComboBox(true, 15);
cDevise.gridx++;
cDevise.weightx = 1;
pDevise.add(boxDevise, cDevise);
this.addView(boxDevise, "ID_DEVISE_HA");
DefaultGridBagConstraints.lockMinimumSize(boxDevise);
 
cDevise.weightx = 0;
cDevise.gridx++;
pDevise.add(new JLabel("Prix d'achat devise"), cDevise);
final JTextField fieldHAD = new JTextField(15);
cDevise.weightx = 1;
cDevise.gridx++;
pDevise.add(fieldHAD, cDevise);
this.addView(fieldHAD, "PA_DEVISE");
DefaultGridBagConstraints.lockMinimumSize(fieldHAD);
 
c.gridx++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.weightx = 1;
c.fill = GridBagConstraints.NONE;
this.add(pDevise, c);
fieldHAD.getDocument().addDocumentListener(new SimpleDocumentListener() {
 
@Override
public void update(DocumentEvent e) {
 
if (!isFilling() && boxDevise != null && boxDevise.getSelectedRow() != null && !boxDevise.getSelectedRow().isUndefined()) {
BigDecimal ha = StringUtils.getBigDecimalFromUserText(fieldHAD.getText());
if (ha == null) {
ha = BigDecimal.ZERO;
}
final BigDecimal taux = (BigDecimal) boxDevise.getSelectedRow().getObject("TAUX");
textPAHT.setText(taux.multiply(ha, MathContext.DECIMAL128).setScale(getTable().getField("PA_DEVISE").getType().getDecimalDigits(), RoundingMode.HALF_UP).toString());
 
}
}
});
 
// PA
JPanel p = new JPanel(new GridBagLayout());
GridBagConstraints cAchat = new DefaultGridBagConstraints();
cAchat.insets = new Insets(0, 0, 0, 4);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
c.gridwidth = 1;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(new JLabel(getLabelFor("PA_HT"), SwingConstants.RIGHT), c);
cAchat.gridx++;
cAchat.weightx = 1;
p.add(this.textPAHT, cAchat);
this.textPAHT.getDocument().addDocumentListener(this.listenerMargeTextHA);
 
// Marge
cAchat.gridx++;
cAchat.weightx = 0;
p.add(new JLabel("Marge"), cAchat);
cAchat.weightx = 1;
cAchat.gridx++;
p.add(this.textMarge, cAchat);
this.textMarge.getDocument().addDocumentListener(this.listenerMargeTextMarge);
cAchat.gridx++;
cAchat.weightx = 0;
p.add(new JLabel("% "), cAchat);
 
// Poids
JLabel labelPds = new JLabel(getLabelFor("POIDS"));
cAchat.gridx++;
cAchat.weightx = 0;
p.add(labelPds, cAchat);
labelPds.setHorizontalAlignment(SwingConstants.RIGHT);
cAchat.weightx = 1;
cAchat.gridx++;
p.add(this.textPoids, cAchat);
DefaultGridBagConstraints.lockMinimumSize(this.textPoids);
 
// Service
String sService = props.getStringProperty("ArticleService");
Boolean bService = Boolean.valueOf(sService);
if (bService != null && bService.booleanValue()) {
cAchat.gridx++;
cAchat.weightx = 0;
p.add(this.boxService, cAchat);
}
 
c.gridx++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.weightx = 1;
c.fill = GridBagConstraints.NONE;
 
this.add(p, c);
 
// PV HT
c.gridx = 0;
c.gridy++;
 
JPanel p2 = new JPanel(new GridBagLayout());
GridBagConstraints cVT = new DefaultGridBagConstraints();
cVT.insets = new Insets(0, 0, 0, 4);
 
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 1;
this.add(new JLabel(getLabelFor("PV_HT"), SwingConstants.RIGHT), c);
cVT.gridx++;
cVT.weightx = 1;
 
p2.add(this.textPVHT, cVT);
 
// Taxe
JLabel labelTaxe = new JLabel(getLabelFor("ID_TAXE"));
cVT.gridx++;
cVT.weightx = 0;
p2.add(labelTaxe, cVT);
labelTaxe.setHorizontalAlignment(SwingConstants.RIGHT);
cVT.gridx++;
// cVT.weightx = 1;
 
p2.add(this.comboSelTaxe, cVT);
 
// PV_TTC
cVT.gridx++;
cVT.weightx = 0;
p2.add(new JLabel(getLabelFor("PV_TTC")), cVT);
cVT.gridx++;
cVT.weightx = 1;
p2.add(this.textPVTTC, cVT);
c.gridx = 1;
 
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.weightx = 1;
c.fill = GridBagConstraints.NONE;
this.add(p2, c);
 
this.addRequiredSQLObject(this.textPAHT, "PA_HT");
this.addRequiredSQLObject(this.textPVHT, "PV_HT");
DefaultGridBagConstraints.lockMinimumSize(this.textPVHT);
this.addRequiredSQLObject(this.comboSelTaxe, "ID_TAXE");
DefaultGridBagConstraints.lockMinimumSize(this.comboSelTaxe);
DefaultGridBagConstraints.lockMaximumSize(this.comboSelTaxe);
this.addRequiredSQLObject(this.textPVTTC, "PV_TTC");
DefaultGridBagConstraints.lockMinimumSize(this.textPVTTC);
DefaultGridBagConstraints.lockMinimumSize(this.textPAHT);
DefaultGridBagConstraints.lockMinimumSize(this.textMarge);
this.ttcDocListener = new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
setTextHT();
}
 
public void insertUpdate(DocumentEvent e) {
setTextHT();
}
 
public void removeUpdate(DocumentEvent e) {
setTextHT();
}
};
 
this.htDocListener = new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
setTextTTC();
}
 
public void insertUpdate(DocumentEvent e) {
setTextTTC();
}
 
public void removeUpdate(DocumentEvent e) {
setTextTTC();
}
 
};
 
this.detailsListener = new SimpleDocumentListener() {
 
@Override
public void update(DocumentEvent e) {
updatePiece();
}
 
};
 
this.taxeListener = new PropertyChangeListener() {
 
public void propertyChange(PropertyChangeEvent evt) {
if (ArticleFournisseurSQLComponent.this.textPVHT.getText().trim().length() > 0) {
setTextTTC();
} else {
setTextHT();
}
}
};
this.textPVHT.getDocument().addDocumentListener(this.htDocListener);
this.textPVTTC.getDocument().addDocumentListener(this.ttcDocListener);
this.comboSelTaxe.addValueListener(this.taxeListener);
 
this.textMetrique1HA.getDocument().addDocumentListener(this.detailsListener);
this.textMetrique1VT.getDocument().addDocumentListener(this.detailsListener);
 
this.textValMetrique1.getDocument().addDocumentListener(this.detailsListener);
this.textValMetrique2.getDocument().addDocumentListener(this.detailsListener);
this.textValMetrique3.getDocument().addDocumentListener(this.detailsListener);
 
}
 
private void setListenerModeVenteActive(boolean b) {
if (b) {
this.comboSelModeVente.addValueListener(this.propertyChangeListener);
} else {
this.comboSelModeVente.removePropertyChangeListener(this.propertyChangeListener);
}
}
 
/**
* @param c
* @param props
*/
private void addModeVenteAvance(GridBagConstraints c) {
DefaultProps props = DefaultNXProps.getInstance();
JSeparator sep = new JSeparator();
JLabel labelDetails = new JLabel("Article détaillé", SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelDetails, c);
c.gridx++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
this.add(sep, c);
 
// Mode de vente
c.gridwidth = 1;
c.weightx = 0;
c.gridx = 0;
c.gridy++;
this.add(new JLabel(getLabelFor("ID_MODE_VENTE_ARTICLE"), SwingConstants.RIGHT), c);
c.weightx = 1;
c.gridx++;
this.add(this.comboSelModeVente, c);
 
// Prix metrique
c.gridx = 0;
c.weightx = 0;
c.gridy++;
this.add(this.labelMetriqueHA1, c);
c.gridx++;
c.weightx = 1;
this.add(this.textMetrique1HA, c);
 
c.gridx++;
c.weightx = 0;
this.add(this.labelMetriqueVT1, c);
c.gridx++;
c.weightx = 1;
this.add(this.textMetrique1VT, c);
 
// Metrique 1
c.weightx = 0;
JLabel labelMetrique1 = new JLabel(getLabelFor("VALEUR_METRIQUE_1"), SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
this.add(labelMetrique1, c);
c.gridx++;
c.weightx = 1;
this.add(this.textValMetrique1, c);
c.gridx++;
c.weightx = 0;
 
Boolean bMetrique1 = Boolean.valueOf(props.getStringProperty("ArticleLongueur"));
labelMetrique1.setVisible(bMetrique1 == null || bMetrique1.booleanValue());
this.textValMetrique1.setVisible(bMetrique1 == null || bMetrique1.booleanValue());
 
// Metrique 2
JLabel labelMetrique2 = new JLabel(getLabelFor("VALEUR_METRIQUE_2"), SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelMetrique2, c);
c.gridx++;
c.weightx = 1;
this.add(this.textValMetrique2, c);
c.gridx++;
c.weightx = 0;
 
Boolean bMetrique2 = Boolean.valueOf(props.getStringProperty("ArticleLargeur"));
labelMetrique2.setVisible(bMetrique2 == null || bMetrique2.booleanValue());
this.textValMetrique2.setVisible(bMetrique2 == null || bMetrique2.booleanValue());
 
// Metrique 3
JLabel labelMetrique3 = new JLabel(getLabelFor("VALEUR_METRIQUE_3"), SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelMetrique3, c);
c.gridx++;
c.weightx = 1;
this.add(this.textValMetrique3, c);
c.gridx++;
 
Boolean bMetrique3 = Boolean.valueOf(props.getStringProperty("ArticlePoids"));
labelMetrique3.setVisible(bMetrique3 == null || bMetrique3.booleanValue());
this.textValMetrique3.setVisible(bMetrique3 == null || bMetrique3.booleanValue());
 
// Article détaillé
JSeparator sep2 = new JSeparator();
JLabel labelPiece = new JLabel("Article pièce", SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelPiece, c);
c.gridx++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
this.add(sep2, c);
 
}
 
@Override
public void update() {
super.update();
if (this.codeFournisseurTable != null) {
this.codeFournisseurTable.updateField("ID_ARTICLE", getSelectedID());
}
}
 
/**
* Sélection d'un mode de vente pour l'article. Affiche les prix metriques requis et fixe les
* valeurs.
*
* @param id id du mode de vente
*/
private void selectModeVente(int id) {
 
this.labelMetriqueHA1.setEnabled(true);
this.labelMetriqueVT1.setEnabled(true);
this.textMetrique1HA.setEnabled(true);
this.textMetrique1VT.setEnabled(true);
 
this.textPAHT.getDocument().removeDocumentListener(this.pieceHAArticle);
this.textPVHT.getDocument().removeDocumentListener(this.pieceVTArticle);
 
switch (id) {
case ReferenceArticleSQLElement.AU_METRE_CARRE:
this.labelMetriqueHA1.setText("Prix d'achat HT au mètre carré");
this.labelMetriqueVT1.setText("Prix de vente HT au mètre carré");
break;
case ReferenceArticleSQLElement.AU_METRE_LARGEUR:
case ReferenceArticleSQLElement.AU_METRE_LONGUEUR:
this.labelMetriqueHA1.setText("Prix d'achat HT au mètre");
this.labelMetriqueVT1.setText("Prix de vente HT au mètre");
break;
 
case ReferenceArticleSQLElement.AU_POID_METRECARRE:
this.labelMetriqueHA1.setText("Prix d'achat HT au kilo");
this.labelMetriqueVT1.setText("Prix de vente HT au kilo");
break;
case -1:
// No break need to enable the listener
default:
this.labelMetriqueHA1.setEnabled(false);
this.labelMetriqueVT1.setEnabled(false);
this.textMetrique1HA.setEnabled(false);
this.textMetrique1VT.setEnabled(false);
 
this.textMetrique1HA.setText(this.textPAHT.getText().trim());
this.textMetrique1VT.setText(this.textPVHT.getText().trim());
this.textPAHT.getDocument().addDocumentListener(this.pieceHAArticle);
this.textPVHT.getDocument().addDocumentListener(this.pieceVTArticle);
break;
}
}
 
@Override
public int insert(SQLRow order) {
int id = super.insert(order);
if (this.codeFournisseurTable != null) {
this.codeFournisseurTable.updateField("ID_ARTICLE", id);
}
return id;
}
 
@Override
protected SQLRowValues createDefaults() {
SQLRowValues rowVals = new SQLRowValues(getTable());
 
SQLRow row = getTable().getRow(getTable().getUndefinedID());
 
rowVals.put("ID_TAXE", row.getInt("ID_TAXE"));
rowVals.put("ID_UNITE_VENTE", UniteVenteArticleSQLElement.A_LA_PIECE);
rowVals.put("ID_MODE_VENTE_ARTICLE", ReferenceArticleSQLElement.A_LA_PIECE);
selectModeVente(ReferenceArticleSQLElement.A_LA_PIECE);
rowVals.put("VALEUR_METRIQUE_1", Float.valueOf("1.0"));
rowVals.put("PA_HT", BigDecimal.ZERO);
rowVals.put("POIDS", Float.valueOf(0));
 
return rowVals;
}
 
private void setTextHT() {
this.textPVHT.getDocument().removeDocumentListener(this.htDocListener);
final BigDecimal ttc = StringUtils.getBigDecimalFromUserText(this.textPVTTC.getText());
if (ttc != null) {
int id = this.comboSelTaxe.getSelectedId();
if (id > 1) {
Float resultTaux = TaxeCache.getCache().getTauxFromId(id);
float taux = (resultTaux == null) ? 0.0F : resultTaux.floatValue() / 100.0F;
this.textPVHT.setText(ttc.divide(BigDecimal.valueOf(taux).add(BigDecimal.ONE), MathContext.DECIMAL128)
.setScale(getTable().getField("PV_HT").getType().getDecimalDigits(), RoundingMode.HALF_UP).toString());
}
}
this.textPVHT.getDocument().addDocumentListener(this.htDocListener);
}
 
private void setTextTTC() {
this.textPVTTC.getDocument().removeDocumentListener(this.ttcDocListener);
final BigDecimal ht = StringUtils.getBigDecimalFromUserText(this.textPVHT.getText());
if (ht != null) {
int id = this.comboSelTaxe.getSelectedId();
if (id > 1) {
final Float resultTaux = TaxeCache.getCache().getTauxFromId(id);
final float taux = (resultTaux == null) ? 0.0F : resultTaux.floatValue() / 100.0F;
this.textPVTTC.setText(ht.multiply(BigDecimal.valueOf(taux).add(BigDecimal.ONE), MathContext.DECIMAL128)
.setScale(getTable().getField("PV_TTC").getType().getDecimalDigits(), RoundingMode.HALF_UP).toString());
}
}
this.textPVTTC.getDocument().addDocumentListener(this.ttcDocListener);
}
 
/**
* calcul du prix achat et vente ainsi que le poids total pour la piece
*/
private void updatePiece() {
if (this.comboSelModeVente.getSelectedId() > 1 && this.comboSelModeVente.getSelectedId() != ReferenceArticleSQLElement.A_LA_PIECE) {
SQLRowValues rowVals = getDetailsRowValues();
float poidsTot = ReferenceArticleSQLElement.getPoidsFromDetails(rowVals);
this.textPoids.setText(String.valueOf(poidsTot));
this.textPAHT.setText(ReferenceArticleSQLElement.getPrixHAFromDetails(rowVals).setScale(getTable().getField("PA_HT").getType().getDecimalDigits(), RoundingMode.HALF_UP).toString());
this.textPVHT.setText(ReferenceArticleSQLElement.getPrixVTFromDetails(rowVals).setScale(getTable().getField("PV_HT").getType().getDecimalDigits(), RoundingMode.HALF_UP).toString());
}
}
 
public int getSelectedTaxe() {
return this.comboSelTaxe.getSelectedId();
}
 
public SQLRowValues getDetailsRowValues() {
final SQLRowValues rowVals = new SQLRowValues(getTable());
 
BigDecimal pAchat = StringUtils.getBigDecimalFromUserText(this.textMetrique1HA.getText());
if (pAchat == null) {
pAchat = BigDecimal.ZERO;
}
rowVals.put("PRIX_METRIQUE_HA_1", pAchat);
 
BigDecimal pVente = StringUtils.getBigDecimalFromUserText(this.textMetrique1VT.getText());
if (pVente == null) {
pVente = BigDecimal.ZERO;
}
rowVals.put("PRIX_METRIQUE_VT_1", pVente);
put(rowVals, this.textValMetrique1);
put(rowVals, this.textValMetrique2);
put(rowVals, this.textValMetrique3);
rowVals.put("ID_MODE_VENTE_ARTICLE", this.comboSelModeVente.getSelectedId());
 
return rowVals;
}
 
private void put(SQLRowValues rowVals, JTextField comp) {
Float f = (comp.getText() == null || comp.getText().trim().length() == 0) ? 0.0F : Float.valueOf(comp.getText());
rowVals.put(this.getView(comp).getField().getName(), f);
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/product/element/FamilleArticleFounisseurSQLElement.java
New file
0,0 → 1,178
/*
* 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.supplychain.product.element;
 
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.utils.CollectionMap;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
 
public class FamilleArticleFounisseurSQLElement extends ComptaSQLConfElement {
 
public FamilleArticleFounisseurSQLElement() {
super("FAMILLE_ARTICLE_FOURNISSEUR", "une famille d'article fournisseur", "familles d'articles fournisseur");
}
 
protected List<String> getListFields() {
final List<String> l = new ArrayList<String>();
l.add("NOM");
return l;
}
 
protected List<String> getComboFields() {
final List<String> l = new ArrayList<String>();
l.add("NOM");
return l;
}
 
@Override
public CollectionMap<String, String> getShowAs() {
final CollectionMap<String, String> res = new CollectionMap<String, String>();
res.put(null, "NOM");
return res;
}
 
/*
* (non-Javadoc)
*
* @see org.openconcerto.devis.SQLElement#getComponent()
*/
public SQLComponent createComponent() {
return new BaseSQLComponent(this) {
public void addViews() {
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
 
// Nom
final JLabel labelNom = new JLabel(getLabelFor("NOM"), SwingConstants.RIGHT);
c.gridx = 0;
c.weightx = 0;
this.add(labelNom, c);
 
final JTextField textNom = new JTextField(15);
c.gridx++;
c.weightx = 1;
DefaultGridBagConstraints.lockMinimumSize(textNom);
this.add(textNom, c);
this.addRequiredSQLObject(textNom, "NOM");
 
// Famille père
final JLabel labelFamille = new JLabel(getLabelFor("ID_FAMILLE_ARTICLE_FOURNISSEUR_PERE"), SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelFamille, c);
 
final ElementComboBox familleBox = new ElementComboBox(true, 25);
DefaultGridBagConstraints.lockMinimumSize(familleBox);
c.gridx++;
c.weightx = 1;
this.add(familleBox, c);
 
this.addSQLObject(familleBox, "ID_FAMILLE_ARTICLE_FOURNISSEUR_PERE");
 
// Champ Module
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
final JPanel addP = ComptaSQLConfElement.createAdditionalPanel();
 
this.setAdditionalFieldsPanel(new FormLayouter(addP, 2));
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
this.add(addP, c);
 
}
 
@Override
public void update() {
// TODO Auto-generated method stub
super.update();
 
SQLRow row = this.getTable().getRow(getSelectedID());
int idPere = row.getInt("ID_FAMILLE_ARTICLE_FOURNISSEUR_PERE");
 
// Création du code de famille --> permet de faciliter le filtre de recherche
StringBuffer code = new StringBuffer();
if (idPere > 1) {
SQLRow rowPere = this.getTable().getRow(idPere);
code.append(rowPere.getString("CODE"));
} else {
code.append('1');
}
code.append("." + getSelectedID());
 
SQLRowValues rowVals = new SQLRowValues(this.getTable());
rowVals.put("CODE", code.toString());
 
try {
rowVals.update(getSelectedID());
} catch (SQLException e) {
e.printStackTrace();
}
 
}
 
@Override
public int insert(SQLRow order) {
 
int id = super.insert(order);
SQLRow row = this.getTable().getRow(id);
int idPere = row.getInt("ID_FAMILLE_ARTICLE_FOURNISSEUR_PERE");
 
// Création du code de famille --> permet de faciliter le filtre de recherche
StringBuffer code = new StringBuffer();
if (idPere > 1) {
SQLRow rowPere = this.getTable().getRow(idPere);
code.append(rowPere.getString("CODE"));
} else {
code.append('1');
}
code.append("." + id);
 
SQLRowValues rowVals = new SQLRowValues(this.getTable());
rowVals.put("CODE", code.toString());
 
try {
rowVals.update(id);
} catch (SQLException e) {
e.printStackTrace();
}
 
return id;
}
};
}
 
@Override
protected String createCode() {
return createCodeFromPackage() + ".family";
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/product/element/ArticleFournisseurSQLElement.java
New file
0,0 → 1,101
/*
* 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.supplychain.product.element;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.supplychain.product.component.ArticleFournisseurSQLComponent;
import org.openconcerto.erp.generationDoc.gestcomm.FicheArticleXmlSheet;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.utils.CollectionMap;
 
import java.util.ArrayList;
import java.util.List;
 
public class ArticleFournisseurSQLElement extends ComptaSQLConfElement {
 
public ArticleFournisseurSQLElement() {
super("ARTICLE_FOURNISSEUR", "un article fournisseur", "articles fournisseurs");
 
getRowActions().addAll(new MouseSheetXmlListeListener(FicheArticleXmlSheet.class).getRowActions());
 
}
 
protected List<String> getListFields() {
final List<String> l = new ArrayList<String>();
 
l.add("CODE");
l.add("NOM");
String articleAdvanced = DefaultNXProps.getInstance().getStringProperty("ArticleModeVenteAvance");
Boolean bArticleAdvanced = Boolean.valueOf(articleAdvanced);
 
if (bArticleAdvanced) {
l.add("POIDS");
l.add("PRIX_METRIQUE_HA_1");
l.add("PRIX_METRIQUE_VT_1");
}
l.add("PA_HT");
l.add("PV_HT");
l.add("ID_TAXE");
l.add("PV_TTC");
l.add("ID_FAMILLE_ARTICLE_FOURNISSEUR");
l.add("ID_FOURNISSEUR");
String val = DefaultNXProps.getInstance().getStringProperty("ArticleService");
Boolean b = Boolean.valueOf(val);
if (b != null && b.booleanValue()) {
l.add("SERVICE");
}
return l;
}
 
@Override
public CollectionMap<String, String> getShowAs() {
final CollectionMap<String, String> res = new CollectionMap<String, String>();
res.put(null, "NOM");
res.put(null, "ID_FAMILLE_ARTICLE_FOURNISSEUR");
return res;
}
 
protected List<String> getComboFields() {
final List<String> l = new ArrayList<String>();
l.add("CODE");
SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
if (prefs.getBoolean(GestionArticleGlobalPreferencePanel.SHOW_PRODUCT_BAR_CODE, false)) {
l.add("CODE_BARRE");
}
 
l.add("NOM");
return l;
}
 
/*
* (non-Javadoc)
*
* @see org.openconcerto.devis.SQLElement#getComponent()
*/
public SQLComponent createComponent() {
 
return new ArticleFournisseurSQLComponent(this);
}
 
@Override
protected String createCode() {
return createCodeFromPackage();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/product/action/FamilleArticleFournisseurAction.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.supplychain.product.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.core.common.ui.PanelFrame;
import org.openconcerto.erp.core.sales.product.ui.FamilleArticlePanel;
import org.openconcerto.sql.Configuration;
 
import javax.swing.Action;
import javax.swing.JFrame;
 
public class FamilleArticleFournisseurAction extends CreateFrameAbstractAction {
 
public FamilleArticleFournisseurAction() {
super();
this.putValue(Action.NAME, "Famille article fournisseur");
}
 
public JFrame createFrame() {
return new PanelFrame(new FamilleArticlePanel(Configuration.getInstance().getDirectory().getElement("FAMILLE_ARTICLE_FOURNISSEUR")), "Famille Articles fournisseur");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/product/action/ListeDesArticlesFournisseurAction.java
New file
0,0 → 1,159
/*
* 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.supplychain.product.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.sales.product.ui.FamilleArticlePanel;
import org.openconcerto.erp.panel.ITreeSelection;
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.sql.model.Where;
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.PanelFrame;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
 
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
 
public class ListeDesArticlesFournisseurAction extends CreateFrameAbstractAction {
 
private PanelFrame panelFrame;
String title = "Liste des articles fournisseurs";
private final SQLTable sqlTableArticle = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("ARTICLE_FOURNISSEUR");
private final SQLTable sqlTableFamilleArticle = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("FAMILLE_ARTICLE_FOURNISSEUR");
 
public ListeDesArticlesFournisseurAction() {
super();
this.putValue(Action.NAME, title);
}
 
public JFrame createFrame() {
final FamilleArticlePanel panelFam = new FamilleArticlePanel(Configuration.getInstance().getDirectory().getElement("FAMILLE_ARTICLE_FOURNISSEUR"));
 
// Renderer pour les devises
// frame.getPanel().getListe().getJTable().setDefaultRenderer(Long.class, new
// DeviseNiceTableCellRenderer());
final SQLElement elt = Configuration.getInstance().getDirectory().getElement(this.sqlTableArticle);
final SQLTableModelSourceOnline createTableSource = elt.createTableSource(getWhere(panelFam));
 
IListe liste = new IListe(createTableSource);
final ListeAddPanel panel = new ListeAddPanel(elt, liste);
 
JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(panelFam), panel);
JPanel panelAll = new JPanel(new GridBagLayout());
GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
c.insets = new Insets(0, 0, 0, 0);
panelAll.add(pane, c);
 
final ITreeSelection tree = panelFam.getFamilleTree();
tree.addValueListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
 
panel.getListe().getRequest().setWhere(getWhere(panelFam));
 
}
});
 
// rafraichir le titre à chaque changement de la liste
panel.getListe().addListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
setTitle(panel);
}
});
panel.getListe().addListenerOnModel(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName() == null || evt.getPropertyName().equals("loading") || evt.getPropertyName().equals("searching"))
setTitle(panel);
}
});
 
panelFam.getCheckObsolete().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
 
panel.getListe().getRequest().setWhere(getWhere(panelFam));
}
});
 
this.panelFrame = new PanelFrame(panelAll, title);
return this.panelFrame;
}
 
protected void setTitle(ListeAddPanel panel) {
String title = this.title;
if (panel.getListe().getModel().isLoading())
title += ", chargement en cours";
if (panel.getListe().getModel().isSearching())
title += ", recherche en cours";
 
this.panelFrame.setTitle(title);
}
 
/**
* Filtre par rapport à la famille sélectionnée
*
* @param panel
* @return le where approprié
*/
public Where getWhere(FamilleArticlePanel panel) {
int id = panel.getFamilleTree().getSelectedID();
 
Where w = null;
 
if (panel.getCheckObsolete().isSelected()) {
w = new Where(this.sqlTableArticle.getField("OBSOLETE"), "=", Boolean.FALSE);
}
 
if (id > 1) {
SQLRow row = this.sqlTableFamilleArticle.getRow(id);
 
Where w2 = new Where(this.sqlTableArticle.getField("ID_FAMILLE_ARTICLE_FOURNISSEUR"), "=", this.sqlTableFamilleArticle.getKey());
 
String code = row.getString("CODE") + ".%";
final Where w3 = new Where(this.sqlTableFamilleArticle.getField("CODE"), "LIKE", code);
w2 = w2.and(w3.or(new Where(this.sqlTableFamilleArticle.getKey(), "=", id)));
 
if (w != null) {
w = w.and(w2);
} else {
w = w2;
}
 
}
return w;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/stock/element/ComposedItemStockUpdater.java
New file
0,0 → 1,225
/*
* 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.supplychain.stock.element;
 
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLSelectJoin;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.UpdateBuilder;
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.utils.cc.ITransformer;
 
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.apache.commons.dbutils.ResultSetHandler;
 
public class ComposedItemStockUpdater {
 
private final List<StockItem> itemsUpdated;
private final DBRoot root;
 
/**
*
* @param root
* @param itemsUpdated liste des StockItem non composés qui ont été mis à jour
*/
public ComposedItemStockUpdater(DBRoot root, List<StockItem> itemsUpdated) {
this.itemsUpdated = itemsUpdated;
this.root = root;
}
 
/**
* Mise à jour des stocks en fonction des composants de l'article
*
* @throws SQLException
*/
public void update() throws SQLException {
// Liste des articles composés
List<StockItem> items = getAllComposedItemToUpdate();
 
// Fecth des articles liés
getAllChildren(items);
 
// Mise à jour des stocks
for (StockItem stockItem : items) {
stockItem.updateQtyFromChildren();
}
 
SQLTable stockTable = root.getTable("STOCK");
List<String> requests = new ArrayList<String>();
for (StockItem stockItem : items) {
if (stockItem.isStockInit()) {
UpdateBuilder update = new UpdateBuilder(stockTable);
update.setWhere(new Where(stockTable.getKey(), "=", stockItem.getArticle().getForeign("ID_STOCK").getID()));
update.setObject("QTE_REEL", stockItem.getRealQty());
update.setObject("QTE_TH", stockItem.getVirtualQty());
update.setObject("QTE_LIV_ATTENTE", stockItem.getDeliverQty());
update.setObject("QTE_RECEPT_ATTENTE", stockItem.getReceiptQty());
requests.add(update.asString());
} else {
SQLRowValues rowVals = new SQLRowValues(stockTable);
rowVals.put("QTE_REEL", stockItem.getRealQty());
rowVals.put("QTE_TH", stockItem.getVirtualQty());
rowVals.put("QTE_LIV_ATTENTE", stockItem.getDeliverQty());
rowVals.put("QTE_RECEPT_ATTENTE", stockItem.getReceiptQty());
SQLRowValues rowValsArt = stockItem.getArticle().createEmptyUpdateRow();
rowValsArt.put("ID_STOCK", rowVals);
rowValsArt.commit();
}
}
 
List<? extends ResultSetHandler> handlers = new ArrayList<ResultSetHandler>(requests.size());
for (String s : requests) {
handlers.add(null);
}
// FIXME FIRE TABLE CHANGED TO UPDATE ILISTE ??
SQLUtils.executeMultiple(stockTable.getDBSystemRoot(), requests, handlers);
}
 
/**
* Associe les StockItems liés aux items passés en parametres
*
* @param items liste des stockitems d'article composé
*/
private void getAllChildren(List<StockItem> items) {
final SQLTable tableArticle = this.root.getTable("ARTICLE");
final SQLRowValues rowValsArt = new SQLRowValues(tableArticle);
rowValsArt.put(tableArticle.getKey().getName(), null);
 
SQLRowValues rowValsStock = new SQLRowValues(tableArticle.getForeignTable("ID_STOCK"));
rowValsStock.put("QTE_REEL", null);
rowValsStock.put("QTE_TH", null);
rowValsStock.put("QTE_RECEPT_ATTENTE", null);
rowValsStock.put("QTE_LIV_ATTENTE", null);
rowValsArt.put("ID_STOCK", rowValsStock);
 
final SQLTable tableArticleElt = this.root.getTable("ARTICLE_ELEMENT");
SQLRowValues rowValsArtItem = new SQLRowValues(tableArticleElt);
rowValsArtItem.put("ID_ARTICLE", rowValsArt);
rowValsArtItem.put("QTE", null);
rowValsArtItem.put("QTE_UNITAIRE", null);
rowValsArtItem.put("ID_ARTICLE_PARENT", null);
 
final List<Integer> ids = new ArrayList<Integer>();
Map<Integer, StockItem> mapItem = new HashMap<Integer, StockItem>();
for (StockItem stockItem : items) {
final int id = stockItem.getArticle().getID();
ids.add(id);
mapItem.put(id, stockItem);
}
 
SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(rowValsArtItem);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
 
@Override
public SQLSelect transformChecked(SQLSelect input) {
Where w = new Where(tableArticleElt.getField("ID_ARTICLE_PARENT"), ids);
input.setWhere(w);
return input;
}
});
 
List<SQLRowValues> values = fetcher.fetch();
for (SQLRowValues sqlRowValues : values) {
 
final SQLRowAccessor article = sqlRowValues.getForeign("ID_ARTICLE");
final SQLRowAccessor articleParent = sqlRowValues.getForeign("ID_ARTICLE_PARENT");
mapItem.get(articleParent.getID()).addItemComponent(new StockItemComponent(new StockItem(article), sqlRowValues.getBigDecimal("QTE_UNITAIRE"), sqlRowValues.getInt("QTE")));
}
}
 
/**
* @return l'ensemble des stockItems composés à mettre à jour
*/
private List<StockItem> getAllComposedItemToUpdate() {
List<Integer> ids = new ArrayList<Integer>(itemsUpdated.size());
for (StockItem stockItem : itemsUpdated) {
ids.add(stockItem.getArticle().getID());
}
List<SQLRowValues> list = getComposedItemToUpdate(ids);
int size = list.size();
 
while (size > 0) {
 
List<SQLRowValues> l = getComposedItemToUpdate(ids);
list.removeAll(l);
list.addAll(l);
size = l.size();
if (size > 0) {
ids.clear();
for (SQLRowValues r : l) {
ids.add(r.getID());
}
}
}
 
List<StockItem> items = new ArrayList<StockItem>(list.size());
for (SQLRowValues rowVals : list) {
 
StockItem item = new StockItem(rowVals);
items.add(item);
}
return items;
}
 
/**
*
* @param ids
* @return l'ensemble des Articles composés avec un des articles en parametres
*/
private List<SQLRowValues> getComposedItemToUpdate(final List<Integer> ids) {
 
final SQLTable tableArticle = this.root.getTable("ARTICLE");
final SQLRowValues rowValsArt = new SQLRowValues(tableArticle);
rowValsArt.put(tableArticle.getKey().getName(), null);
 
SQLRowValues rowValsStock = new SQLRowValues(tableArticle.getForeignTable("ID_STOCK"));
rowValsStock.put("QTE_REEL", null);
rowValsStock.put("QTE_TH", null);
rowValsStock.put("QTE_RECEPT_ATTENTE", null);
rowValsStock.put("QTE_LIV_ATTENTE", null);
rowValsArt.put("ID_STOCK", rowValsStock);
 
final SQLTable tableArticleElt = this.root.getTable("ARTICLE_ELEMENT");
SQLRowValues rowValsArtItem = new SQLRowValues(tableArticleElt);
rowValsArtItem.put("ID_ARTICLE_PARENT", rowValsArt);
// rowValsArtItem.put("QTE", null);
// rowValsArtItem.put("QTE_UNITAIRE", null);
 
SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(rowValsArt);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
 
@Override
public SQLSelect transformChecked(SQLSelect input) {
final SQLSelectJoin joinFromField = input.getJoinFromField(tableArticleElt.getField("ID_ARTICLE_PARENT"));
Where w = new Where(joinFromField.getJoinedTable().getField("ID_ARTICLE"), ids);
joinFromField.setWhere(w);
Where w2 = new Where(joinFromField.getJoinedTable().getKey(), "is not", (Object) null);
input.setWhere(w2);
return input;
}
});
 
return fetcher.fetch();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/stock/element/StockItem.java
New file
0,0 → 1,179
/*
* 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.supplychain.stock.element;
 
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.UpdateBuilder;
 
import java.util.ArrayList;
import java.util.List;
 
public class StockItem {
 
public enum Type {
REEL, THEORIQUE
};
 
private double realQty, virtualQty, receiptQty, deliverQty;
public SQLRowAccessor article;
 
List<StockItemComponent> components = new ArrayList<StockItemComponent>();
 
public StockItem(SQLRowAccessor article) {
this.article = article;
if (this.article.isForeignEmpty("ID_STOCK")) {
this.realQty = 0;
this.virtualQty = 0;
this.receiptQty = 0;
this.deliverQty = 0;
} else {
SQLRowAccessor row = this.article.getForeign("ID_STOCK");
this.realQty = row.getFloat("QTE_REEL");
this.virtualQty = row.getFloat("QTE_TH");
this.receiptQty = row.getFloat("QTE_RECEPT_ATTENTE");
this.deliverQty = row.getFloat("QTE_LIV_ATTENTE");
}
}
 
public void updateQty(double qty, Type t) {
updateQty(qty, t, false);
}
 
public SQLRowAccessor getArticle() {
return article;
};
 
public void addItemComponent(StockItemComponent item) {
this.components.add(item);
};
 
public void updateQtyFromChildren() throws IllegalArgumentException {
if (components.size() == 0) {
throw new IllegalArgumentException("Impossible de calculé les quantités depuis les composants. Cet article n'est pas composé!");
}
StockItemComponent comp = components.get(0);
double real = comp.getItem().getRealQty() == 0 ? 0 : Math.ceil(comp.getItem().getRealQty() / (comp.getQty() * comp.getQtyUnit().doubleValue()));
double virtual = comp.getItem().getVirtualQty() == 0 ? 0 : Math.ceil(comp.getItem().getVirtualQty() / (comp.getQty() * comp.getQtyUnit().doubleValue()));
for (StockItemComponent stockItemComponent : components) {
real = Math.min(
real,
stockItemComponent.getItem().getRealQty() == 0 ? 0 : Math.ceil(stockItemComponent.getItem().getRealQty()
/ (stockItemComponent.getQty() * stockItemComponent.getQtyUnit().doubleValue())));
virtual = Math.min(
virtual,
stockItemComponent.getItem().getVirtualQty() == 0 ? 0 : Math.ceil(stockItemComponent.getItem().getVirtualQty()
/ (stockItemComponent.getQty() * stockItemComponent.getQtyUnit().doubleValue())));
 
}
this.realQty = real;
this.virtualQty = virtual;
}
 
/**
* Mise à jour des quantités de stocks. Stock Reel : inc/dec QTE_REEL, inc/dec
* QTE_LIV_ATTENTE/inc/dec QTE_RECEPT_ATTENTE Stock Th : inc/dec QTE_TH, inc/dec
* QTE_LIV_ATTENTE/inc/dec QTE_RECEPT_ATTENTE
*
* @param qty quantité à ajouter ou à soustraire
* @param t Type de stock à mettre à jour (réel ou virtuel)
* @param archive annulation du stock
*/
public void updateQty(double qty, Type t, boolean archive) {
 
if (t == Type.REEL) {
final double qteNvlle;
final double qteOrigin = this.realQty;
if (archive) {
qteNvlle = qteOrigin - qty;
// Réception
if (qty > 0) {
this.receiptQty += qty;
} else {
// Livraison
this.deliverQty -= qty;
}
} else {
qteNvlle = qteOrigin + qty;
// Réception
if (qty > 0) {
this.receiptQty -= qty;
} else {
// Livraison
this.deliverQty += qty;
}
}
 
this.realQty = qteNvlle;
 
} else {
final double qteNvlle;
final double qteOrigin = this.virtualQty;
if (archive) {
qteNvlle = qteOrigin - qty;
// Réception
if (qty > 0) {
this.receiptQty -= qty;
} else {
// Livraison
this.deliverQty += qty;
}
} else {
qteNvlle = qteOrigin + qty;
// Réception
if (qty > 0) {
this.receiptQty += qty;
} else {
// Livraison
this.deliverQty -= qty;
}
}
 
this.virtualQty = qteNvlle;
}
}
 
public double getDeliverQty() {
return deliverQty;
}
 
public double getRealQty() {
return realQty;
}
 
public double getReceiptQty() {
return receiptQty;
}
 
public double getVirtualQty() {
return virtualQty;
}
 
public boolean isStockInit() {
return !this.article.isForeignEmpty("ID_STOCK");
}
 
public String getUpdateRequest() {
final SQLTable stockTable = this.article.getTable().getForeignTable("ID_STOCK");
UpdateBuilder update = new UpdateBuilder(stockTable);
update.setWhere(new Where(stockTable.getKey(), "=", getArticle().getForeign("ID_STOCK").getID()));
update.setObject("QTE_REEL", getRealQty());
update.setObject("QTE_TH", getVirtualQty());
update.setObject("QTE_LIV_ATTENTE", getDeliverQty());
update.setObject("QTE_RECEPT_ATTENTE", getReceiptQty());
return update.asString();
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/stock/element/StockLabel.java
16,10 → 16,10
*/
package org.openconcerto.erp.core.supplychain.stock.element;
 
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
 
public abstract class StockLabel {
 
abstract public String getLabel(SQLRow rowOrigin, SQLRow rowElt);
abstract public String getLabel(SQLRowAccessor rowOrigin, SQLRowAccessor rowElt);
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/stock/element/StockItemComponent.java
New file
0,0 → 1,41
/*
* 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.supplychain.stock.element;
 
import java.math.BigDecimal;
 
public class StockItemComponent {
 
private final StockItem item;
private final BigDecimal qtyUnit;
private final int qty;
 
public StockItemComponent(StockItem item, BigDecimal qtyUnit, int qty) {
this.item = item;
this.qtyUnit = qtyUnit;
this.qty = qty;
}
 
public int getQty() {
return qty;
}
 
public BigDecimal getQtyUnit() {
return qtyUnit;
}
 
public StockItem getItem() {
return item;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/stock/element/StockItemsUpdater.java
New file
0,0 → 1,216
/*
* 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.supplychain.stock.element;
 
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.utils.RTInterruptedException;
import org.openconcerto.utils.cc.ITransformer;
 
import java.math.BigDecimal;
import java.math.MathContext;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
 
import org.apache.commons.dbutils.ResultSetHandler;
 
public class StockItemsUpdater {
 
private final StockLabel label;
private final List<? extends SQLRowAccessor> items;
private final Type type;
private final boolean createMouvementStock;
private final SQLRowAccessor rowSource;
 
public static enum Type {
 
VIRTUAL_RECEPT(true, true), REAL_RECEPT(true, false), VIRTUAL_DELIVER(false, true), REAL_DELIVER(false, false);
 
private boolean entry, virtual;
 
Type(boolean entry, boolean virtual) {
this.entry = entry;
this.virtual = virtual;
}
 
public boolean isEntry() {
return entry;
}
 
public boolean isVirtual() {
return virtual;
}
};
 
public StockItemsUpdater(StockLabel label, SQLRowAccessor rowSource, List<? extends SQLRowAccessor> items, Type t) {
this(label, rowSource, items, t, true);
}
 
public StockItemsUpdater(StockLabel label, SQLRowAccessor rowSource, List<? extends SQLRowAccessor> items, Type t, boolean createMouvementStock) {
this.label = label;
this.items = items;
this.type = t;
this.createMouvementStock = createMouvementStock;
this.rowSource = rowSource;
}
 
List<String> requests = new ArrayList<String>();
 
public void update() throws SQLException {
final SQLTable stockTable = this.rowSource.getTable().getTable("STOCK");
 
if (this.createMouvementStock) {
clearExistingMvt(this.rowSource);
}
 
// Mise à jour des stocks des articles non composés
List<StockItem> stockItems = fetch();
 
for (StockItem stockItem : stockItems) {
if (stockItem.isStockInit()) {
requests.add(stockItem.getUpdateRequest());
} else {
SQLRowValues rowVals = new SQLRowValues(stockTable);
rowVals.put("QTE_REEL", stockItem.getRealQty());
rowVals.put("QTE_TH", stockItem.getVirtualQty());
rowVals.put("QTE_LIV_ATTENTE", stockItem.getDeliverQty());
rowVals.put("QTE_RECEPT_ATTENTE", stockItem.getReceiptQty());
SQLRowValues rowValsArt = stockItem.getArticle().createEmptyUpdateRow();
rowValsArt.put("ID_STOCK", rowVals);
rowValsArt.commit();
}
}
 
List<? extends ResultSetHandler> handlers = new ArrayList<ResultSetHandler>(requests.size());
for (String s : requests) {
handlers.add(null);
}
// FIXME FIRE TABLE CHANGED TO UPDATE ILISTE ??
SQLUtils.executeMultiple(stockTable.getDBSystemRoot(), requests, handlers);
 
final DBRoot root = this.rowSource.getTable().getDBRoot();
if (root.contains("ARTICLE_ELEMENT")) {
ComposedItemStockUpdater comp = new ComposedItemStockUpdater(root, stockItems);
comp.update();
}
 
}
 
/**
* Suppression des anciens mouvements
*
* @param rowSource
* @throws SQLException
* @throws RTInterruptedException
*/
private void clearExistingMvt(SQLRowAccessor rowSource) throws RTInterruptedException, SQLException {
 
List<String> multipleRequests = new ArrayList<String>();
 
final SQLTable table = this.rowSource.getTable().getTable("MOUVEMENT_STOCK");
SQLRowValues rowVals = new SQLRowValues(table);
rowVals.put("QTE", null);
rowVals.put("REEL", null);
SQLRowValues rowValsArt = new SQLRowValues(this.rowSource.getTable().getTable("ARTICLE"));
SQLRowValues rowValsStock = new SQLRowValues(this.rowSource.getTable().getTable("STOCK"));
rowValsStock.put("QTE_REEL", null);
rowValsStock.put("QTE_TH", null);
rowValsStock.put("QTE_RECEPT_ATTENTE", null);
rowValsStock.put("QTE_LIV_ATTENTE", null);
 
rowValsArt.put("ID_STOCK", rowValsStock);
rowVals.put("ID_ARTICLE", rowValsArt);
 
SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(rowVals);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
 
@Override
public SQLSelect transformChecked(SQLSelect input) {
Where w = new Where(table.getField("SOURCE"), "=", StockItemsUpdater.this.rowSource.getTable().getName());
w = w.and(new Where(table.getField("IDSOURCE"), "=", StockItemsUpdater.this.rowSource.getID()));
input.setWhere(w);
return input;
}
});
 
List<SQLRowValues> result = fetcher.fetch();
for (SQLRowValues sqlRowValues : result) {
StockItem item = new StockItem(sqlRowValues.getForeign("ID_ARTICLE"));
final StockItem.Type t;
if (sqlRowValues.getBoolean("REEL")) {
t = StockItem.Type.REEL;
} else {
t = StockItem.Type.THEORIQUE;
}
item.updateQty(sqlRowValues.getFloat("QTE"), t, true);
String req = "UPDATE " + sqlRowValues.getTable().getSQLName().quote() + " SET \"ARCHIVE\"=1 WHERE \"ID\"=" + sqlRowValues.getID();
multipleRequests.add(req);
multipleRequests.add(item.getUpdateRequest());
}
 
List<? extends ResultSetHandler> handlers = new ArrayList<ResultSetHandler>(multipleRequests.size());
for (String s : multipleRequests) {
handlers.add(null);
}
SQLUtils.executeMultiple(table.getDBSystemRoot(), multipleRequests, handlers);
}
 
/**
* Récupére les stocks associés aux articles non composés et les met à jour
*
* @return la liste des stocks à jour
*/
private List<StockItem> fetch() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
List<StockItem> stockItems = new ArrayList<StockItem>(items.size());
StockItem.Type stockItemType = this.type.isVirtual() ? StockItem.Type.THEORIQUE : StockItem.Type.REEL;
for (SQLRowAccessor item : items) {
 
if (!item.isForeignEmpty("ID_ARTICLE")) {
SQLRowAccessor article = item.getForeign("ID_ARTICLE");
 
// FIXME Create FIELD COMPOSED
// if (!article.getBoolean("COMPOSED") && article.getBoolean("GESTION_STOCK")) {
if (article.getBoolean("GESTION_STOCK")) {
StockItem stockItem = new StockItem(article);
 
final int qte = item.getInt("QTE");
final BigDecimal qteUV = item.getBigDecimal("QTE_UNITAIRE");
double qteFinal = qteUV.multiply(new BigDecimal(qte), MathContext.DECIMAL128).doubleValue();
if (!this.type.isEntry()) {
qteFinal = -qteFinal;
}
stockItem.updateQty(qteFinal, stockItemType);
stockItems.add(stockItem);
if (this.createMouvementStock) {
String mvtStockQuery = "INSERT INTO " + article.getTable().getTable("MOUVEMENT_STOCK").getSQLName().quote()
+ " (\"QTE\",\"DATE\",\"ID_ARTICLE\",\"SOURCE\",\"IDSOURCE\",\"NOM\",\"REEL\") VALUES(" + qteFinal + ",'" + dateFormat.format(this.rowSource.getDate("DATE").getTime())
+ "'," + article.getID() + ",'" + this.rowSource.getTable().getName() + "'," + this.rowSource.getID() + ",'" + this.label.getLabel(this.rowSource, item) + "',"
+ String.valueOf(!this.type.isVirtual()) + ")";
this.requests.add(mvtStockQuery);
}
}
}
}
return stockItems;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/stock/element/MouvementStockSQLElement.java
42,8 → 42,8
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.ui.preferences.DefaultProps;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.ListMap;
 
import java.math.BigDecimal;
import java.math.MathContext;
50,7 → 50,9
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
 
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
67,6 → 69,7
l.add("NOM");
l.add("ID_ARTICLE");
l.add("QTE");
l.add("REEL");
return l;
}
 
94,10 → 97,9
@Override
protected void archive(TreesOfSQLRows trees, boolean cutLinks) throws SQLException {