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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 {
super.archive(trees, cutLinks);
for (SQLRow row : trees.getRows()) {
updateStock(Arrays.asList(row.getID()), true);
updateStock(trees.getRows(), true);
 
}
}
 
// public CollectionMap<SQLRow, List<SQLRowValues>> updateStock(List<Integer> ids) {
// return updateStock(ids, false);
113,9 → 115,10
* @param label label pour les mouvements de stocks
* @param entry true si c'est une entrée de stock
* @throws SQLException
*
* @Deprecated
*/
public void createMouvement(final SQLRow rowOrigin, SQLTable eltTable, StockLabel label, boolean entry) throws SQLException {
public void createMouvement(final SQLRow rowOrigin, SQLTable eltTable, StockLabel label, boolean entry, boolean real) throws SQLException {
 
// TODO: if (SwingUtilities.isEventDispatchThread()) {
// throw new IllegalStateException("This method must be called outside of EDT");
// }
131,7 → 134,7
final boolean createArticle = prefs.getBoolean(GestionArticleGlobalPreferencePanel.CREATE_ARTICLE_AUTO, true);
 
if (lElt != null) {
List<Integer> l = new ArrayList<Integer>();
List<SQLRow> l = new ArrayList<SQLRow>();
for (SQLRow rowElt : lElt) {
SQLRow rowArticleAssocie = (rowElt.getTable().contains("ID_ARTICLE") ? rowElt.getForeign("ID_ARTICLE") : null);
 
173,6 → 176,7
final int qte = rowElt.getInt("QTE");
final BigDecimal qteUV = rowElt.getBigDecimal("QTE_UNITAIRE");
double qteFinal = qteUV.multiply(new BigDecimal(qte), MathContext.DECIMAL128).doubleValue();
 
if (entry) {
rowVals.put("QTE", qteFinal);
} else {
180,18 → 184,20
}
 
rowVals.put("NOM", label.getLabel(rowOrigin, rowElt));
rowVals.put("REEL", real);
rowVals.put("IDSOURCE", rowOrigin.getID());
rowVals.put("SOURCE", rowOrigin.getTable().getName());
rowVals.put("ID_ARTICLE", rowArticleAssocie.getID());
rowVals.put("DATE", rowOrigin.getObject("DATE"));
SQLRow row = rowVals.insert();
l.add(row.getID());
 
l.add(row);
 
}
}
}
final CollectionMap<SQLRow, List<SQLRowValues>> map = updateStock(l, false);
if (map.keySet().size() > 0 && !rowOrigin.getTable().getName().equalsIgnoreCase("TICKET_CAISSE")) {
final ListMap<SQLRow, SQLRowValues> map = updateStock(l, false);
if (map.size() > 0 && !rowOrigin.getTable().getName().equalsIgnoreCase("TICKET_CAISSE")) {
if (!rowOrigin.getTable().contains("ID_TARIF")) {
System.err.println("Attention la table " + rowOrigin.getTable().getName()
+ " ne contient pas le champ ID_TARIF. La création automatique d'une commande fournisseur est donc impossible!");
201,7 → 207,7
 
@Override
public void run() {
if (JOptionPane.showConfirmDialog(null, "Certains articles sont en dessous du stock minimum.\n Voulez créer une commande?") == JOptionPane.YES_OPTION) {
if (JOptionPane.showConfirmDialog(null, "Certains articles sont en dessous du stock minimum.\n Voulez vous créer une commande?") == JOptionPane.YES_OPTION) {
ComptaPropsConfiguration.getInstanceCompta().getNonInteractiveSQLExecutor().execute(new Runnable() {
 
@Override
226,18 → 232,20
* @param id mouvement stock
* @param archive
*/
public CollectionMap<SQLRow, List<SQLRowValues>> updateStock(List<Integer> ids, boolean archive) {
public ListMap<SQLRow, SQLRowValues> updateStock(Collection<SQLRow> rowsMvt, boolean archive) {
// FIXME: if (SwingUtilities.isEventDispatchThread()) {
// throw new IllegalStateException("This method must be called outside of EDT");
// }
CollectionMap<SQLRow, List<SQLRowValues>> map = new CollectionMap<SQLRow, List<SQLRowValues>>();
// 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
 
final ListMap<SQLRow, SQLRowValues> map = new ListMap<SQLRow, SQLRowValues>();
SQLTable tableCmdElt = Configuration.getInstance().getBase().getTable("COMMANDE_ELEMENT");
for (Integer id : ids) {
for (SQLRow rowMvtStock : rowsMvt) {
 
// Mise à jour des stocks
SQLElement eltMvtStock = Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
SQLRow rowMvtStock = eltMvtStock.getTable().getRow(id);
 
SQLTable sqlTableArticle = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("ARTICLE");
SQLElement eltArticle = Configuration.getInstance().getDirectory().getElement(sqlTableArticle);
SQLElement eltStock = Configuration.getInstance().getDirectory().getElement("STOCK");
244,7 → 252,7
final SQLRow rowArticle = rowMvtStock.getForeignRow("ID_ARTICLE");
 
SQLRow rowStock = rowArticle.getForeignRow(("ID_STOCK"));
 
if (rowMvtStock.getBoolean("REEL")) {
float qte = rowStock.getFloat("QTE_REEL");
float qteMvt = rowMvtStock.getFloat("QTE");
 
251,12 → 259,30
SQLRowValues rowVals = new SQLRowValues(eltStock.getTable());
 
float qteNvlle;
float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");
if (archive) {
qteNvlle = qte - qteMvt;
// Réception
if (qteMvt > 0) {
qteNvlleEnAttenteRecept += qteMvt;
} else {
// Livraison
qteNvlleEnAttenteExp -= qteMvt;
}
} else {
qteNvlle = qte + qteMvt;
// Réception
if (qteMvt > 0) {
qteNvlleEnAttenteRecept -= qteMvt;
} else {
// Livraison
qteNvlleEnAttenteExp += qteMvt;
}
}
rowVals.put("QTE_REEL", qteNvlle);
rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);
 
try {
if (rowStock.getID() <= 1) {
299,27 → 325,78
rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * qteElt);
rowValsElt.put("T_PA_TTC", rowValsElt.getLong("T_PA_HT") * (rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0));
 
map.put(rowArticle.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
map.add(rowArticle.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
 
}
} else {
float qte = rowStock.getFloat("QTE_TH");
float qteMvt = rowMvtStock.getFloat("QTE");
 
SQLRowValues rowVals = new SQLRowValues(eltStock.getTable());
 
float qteNvlle;
float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");
 
if (archive) {
qteNvlle = qte - qteMvt;
// CommandeF
if (qteMvt > 0) {
qteNvlleEnAttenteRecept -= qteMvt;
} else {
// CommanceC
qteNvlleEnAttenteExp += qteMvt;
}
} else {
qteNvlle = qte + qteMvt;
// CommandeF
if (qteMvt > 0) {
qteNvlleEnAttenteRecept += qteMvt;
} else {
// CommanceC
qteNvlleEnAttenteExp -= qteMvt;
}
}
rowVals.put("QTE_TH", qteNvlle);
rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);
 
try {
if (rowStock.getID() <= 1) {
SQLRow row = rowVals.insert();
SQLRowValues rowValsArt = new SQLRowValues(eltArticle.getTable());
rowValsArt.put("ID_STOCK", row.getID());
 
final int idArticle = rowArticle.getID();
if (idArticle > 1) {
rowValsArt.update(idArticle);
}
} else {
rowVals.update(rowStock.getID());
}
} catch (SQLException e) {
 
ExceptionHandler.handle("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"));
}
}
 
}
return map;
}
 
public static void createCommandeF(final CollectionMap<SQLRow, List<SQLRowValues>> col, final SQLRow rowDevise) {
public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise) {
createCommandeF(col, rowDevise, "");
}
 
public static void createCommandeF(final CollectionMap<SQLRow, List<SQLRowValues>> col, final SQLRow rowDevise, final String ref) {
public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise, final String ref) {
if (SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("This method must be called outside of EDT");
}
if (col.keySet().size() > 0) {
if (col.size() > 0) {
 
final SQLElement commande = Configuration.getInstance().getDirectory().getElement("COMMANDE");
for (final SQLRow fournisseur : col.keySet()) {
 
for (final Entry<SQLRow, List<SQLRowValues>> e : col.entrySet()) {
final SQLRow fournisseur = e.getKey();
// On regarde si il existe une commande en cours existante
final SQLSelect sel = new SQLSelect();
sel.addSelectStar(commande.getTable());
368,7 → 445,7
}
 
final RowValuesTableModel model = cmp.getRowValuesTable().getRowValuesTableModel();
for (SQLRowValues rowValsElt : (List<SQLRowValues>) col.get(fournisseur)) {
for (SQLRowValues rowValsElt : e.getValue()) {
SQLRowValues rowValsMatch = null;
int index = 0;
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/stock/element/StockSQLElement.java
17,6 → 17,7
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.CollectionMap;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
46,6 → 47,16
return l;
}
 
@Override
public CollectionMap<String, String> getShowAs() {
final CollectionMap<String, String> res = new CollectionMap<String, String>();
res.put(null, "QTE_TH");
res.put(null, "QTE_REEL");
res.put(null, "QTE_LIV_ATTENTE");
res.put(null, "QTE_RECEPT_ATTENTE");
return res;
}
 
/*
* (non-Javadoc)
*
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/supplier/component/MouvementStockSQLComponent.java
108,7 → 108,7
@Override
public int insert(SQLRow order) {
int id = super.insert(order);
((MouvementStockSQLElement) getElement()).updateStock(Arrays.asList(id), false);
((MouvementStockSQLElement) getElement()).updateStock(Arrays.asList(getTable().getRow(id)), false);
return id;
}
 
115,9 → 115,9
@Override
public void update() {
int id = getSelectedID();
((MouvementStockSQLElement) getElement()).updateStock(Arrays.asList(id), true);
((MouvementStockSQLElement) getElement()).updateStock(Arrays.asList(getTable().getRow(id)), true);
super.update();
((MouvementStockSQLElement) getElement()).updateStock(Arrays.asList(id), false);
((MouvementStockSQLElement) getElement()).updateStock(Arrays.asList(getTable().getRow(id)), false);
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/supplier/component/FournisseurSQLComponent.java
181,6 → 181,17
JCheckBox boxUE = new JCheckBox(getLabelFor("UE"));
this.add(boxUE, c);
 
if (getTable().contains("ID_DEVISE")) {
c.gridx++;
c.weightx = 0;
this.add(new JLabel(getLabelFor("ID_DEVISE"), SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 0.5;
ElementComboBox devise = new ElementComboBox(true, 35);
this.add(devise, c);
this.addView(devise, "ID_DEVISE");
}
 
// Champ Module
c.gridx = 0;
c.gridy++;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/component/SaisieAchatSQLComponent.java
251,7 → 251,7
this.comboAvoir.setAddIconVisible(false);
panelAvoir.add(this.comboAvoir);
 
panelAvoir.add(new JLabel("Montant réglé"));
panelAvoir.add(new JLabel("Montant à régler"));
panelAvoir.add(this.fieldMontantRegle);
this.fieldMontantRegle.setEditable(false);
c.gridx = 0;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/component/CommandeSQLComponent.java
23,6 → 23,9
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.core.supplychain.order.element.CommandeSQLElement;
import org.openconcerto.erp.core.supplychain.order.ui.CommandeItemTable;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater.Type;
import org.openconcerto.erp.core.supplychain.stock.element.StockLabel;
import org.openconcerto.erp.generationDoc.gestcomm.CommandeXmlSheet;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.sql.Configuration;
33,6 → 36,7
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.sqlobject.ElementComboBox;
59,6 → 63,7
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.sql.SQLException;
import java.util.List;
 
import javax.swing.JCheckBox;
import javax.swing.JLabel;
72,6 → 77,8
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
 
import org.apache.commons.dbutils.handlers.ArrayListHandler;
 
public class CommandeSQLComponent extends TransfertBaseSQLComponent {
 
private CommandeItemTable table = new CommandeItemTable();
649,6 → 656,12
// Création des articles
this.table.createArticle(idCommande, this.getElement());
 
try {
updateStock(idCommande);
} catch (SQLException e) {
ExceptionHandler.handle("Erreur lors de la mise à jour du stock!", e);
}
 
// generation du document
final CommandeXmlSheet sheet = new CommandeXmlSheet(getTable().getRow(idCommande));
sheet.createDocumentAsynchronous();
714,16 → 727,68
}
 
super.update();
this.table.updateField("ID_COMMANDE", getSelectedID());
this.table.createArticle(getSelectedID(), this.getElement());
final int id = getSelectedID();
this.table.updateField("ID_COMMANDE", id);
this.table.createArticle(id, this.getElement());
ComptaPropsConfiguration.getInstanceCompta().getNonInteractiveSQLExecutor().execute(new Runnable() {
 
@Override
public void run() {
try {
// On efface les anciens mouvements de stocks
SQLRow row = getTable().getRow(id);
SQLElement eltMvtStock = Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
SQLSelect sel = new SQLSelect();
sel.addSelect(eltMvtStock.getTable().getField("ID"));
Where w = new Where(eltMvtStock.getTable().getField("IDSOURCE"), "=", row.getID());
Where w2 = new Where(eltMvtStock.getTable().getField("SOURCE"), "=", getTable().getName());
sel.setWhere(w.and(w2));
 
List l = (List) eltMvtStock.getTable().getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
if (l != null) {
for (int i = 0; i < l.size(); i++) {
Object[] tmp = (Object[]) l.get(i);
 
eltMvtStock.archive(((Number) tmp[0]).intValue());
 
}
}
// Mise à jour du stock
updateStock(id);
} catch (Exception e) {
ExceptionHandler.handle("Update error", e);
}
}
});
// generation du document
final CommandeXmlSheet sheet = new CommandeXmlSheet(getTable().getRow(getSelectedID()));
final CommandeXmlSheet sheet = new CommandeXmlSheet(getTable().getRow(id));
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(this.checkVisu.isSelected(), this.checkImpression.isSelected(), true);
 
}
 
protected String getLibelleStock(SQLRowAccessor row, SQLRowAccessor rowElt) {
return "Commande fournisseur N°" + row.getString("NUMERO");
}
 
/**
* Mise à jour des stocks pour chaque article composant la facture
*
* @throws SQLException
*/
private void updateStock(int id) throws SQLException {
 
SQLRow row = getTable().getRow(id);
StockItemsUpdater stockUpdater = new StockItemsUpdater(new StockLabel() {
@Override
public String getLabel(SQLRowAccessor rowOrigin, SQLRowAccessor rowElt) {
return getLibelleStock(rowOrigin, rowElt);
}
}, row, row.getReferentRows(getTable().getTable("COMMANDE_ELEMENT")), Type.REAL_RECEPT);
 
stockUpdater.update();
}
 
public void setDefaults() {
this.resetValue();
this.numeroUniqueCommande.setText(NumerotationAutoSQLElement.getNextNumero(CommandeSQLElement.class));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/element/CommandeSQLElement.java
20,6 → 20,10
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.TreesOfSQLRows;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
26,6 → 30,7
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
 
import java.awt.event.ActionEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
35,6 → 40,8
import javax.swing.ImageIcon;
import javax.swing.JFrame;
 
import org.apache.commons.dbutils.handlers.ArrayListHandler;
 
public class CommandeSQLElement extends ComptaSQLConfElement {
 
public CommandeSQLElement() {
119,4 → 126,27
editFactureFrame.setState(JFrame.NORMAL);
editFactureFrame.setVisible(true);
}
 
@Override
protected void archive(SQLRow row, boolean cutLinks) throws SQLException {
// TODO Auto-generated method stub
super.archive(row, cutLinks);
// Mise à jour des stocks
SQLElement eltMvtStock = Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
SQLSelect sel = new SQLSelect();
sel.addSelect(eltMvtStock.getTable().getField("ID"));
Where w = new Where(eltMvtStock.getTable().getField("IDSOURCE"), "=", row.getID());
Where w2 = new Where(eltMvtStock.getTable().getField("SOURCE"), "=", getTable().getName());
sel.setWhere(w.and(w2));
 
@SuppressWarnings("rawtypes")
List l = (List) eltMvtStock.getTable().getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
if (l != null) {
for (int i = 0; i < l.size(); i++) {
Object[] tmp = (Object[]) l.get(i);
eltMvtStock.archive(((Number) tmp[0]).intValue());
}
}
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/receipt/component/BonReceptionSQLComponent.java
21,12 → 21,12
import org.openconcerto.erp.core.sales.product.element.ReferenceArticleSQLElement;
import org.openconcerto.erp.core.supplychain.receipt.element.BonReceptionSQLElement;
import org.openconcerto.erp.core.supplychain.receipt.ui.BonReceptionItemTable;
import org.openconcerto.erp.core.supplychain.stock.element.MouvementStockSQLElement;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater.Type;
import org.openconcerto.erp.core.supplychain.stock.element.StockLabel;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
376,6 → 376,9
idBon = super.insert(order);
try {
this.tableBonItem.updateField("ID_BON_RECEPTION", idBon);
 
this.tableBonItem.createArticle(idBon, this.getElement());
 
// incrémentation du numéro auto
if (NumerotationAutoSQLElement.getNextNumero(BonReceptionSQLElement.class).equalsIgnoreCase(this.textNumeroUnique.getText().trim())) {
SQLRowValues rowVals = new SQLRowValues(this.tableNum);
442,6 → 445,7
// Mise à jour de l'élément
super.update();
this.tableBonItem.updateField("ID_BON_RECEPTION", getSelectedID());
this.tableBonItem.createArticle(getSelectedID(), this.getElement());
final int id = getSelectedID();
ComptaPropsConfiguration.getInstanceCompta().getNonInteractiveSQLExecutor().execute(new Runnable() {
 
547,7 → 551,7
}
}
 
protected String getLibelleStock(SQLRow row, SQLRow rowElt) {
protected String getLibelleStock(SQLRowAccessor row, SQLRowAccessor rowElt) {
return "Bon de réception N°" + row.getString("NUMERO");
}
 
557,16 → 561,17
* @throws SQLException
*/
private void updateStock(int id) throws SQLException {
if (SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("This method must be called outside of EDT");
}
MouvementStockSQLElement mvtStock = (MouvementStockSQLElement) Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
mvtStock.createMouvement(getTable().getRow(id), getTable().getTable("BON_RECEPTION_ELEMENT"), new StockLabel() {
 
SQLRow row = getTable().getRow(id);
StockItemsUpdater stockUpdater = new StockItemsUpdater(new StockLabel() {
 
@Override
public String getLabel(SQLRow rowOrigin, SQLRow rowElt) {
public String getLabel(SQLRowAccessor rowOrigin, SQLRowAccessor rowElt) {
 
return getLibelleStock(rowOrigin, rowElt);
}
}, true);
}, row, row.getReferentRows(getTable().getTable("BON_RECEPTION_ELEMENT")), Type.REAL_RECEPT);
 
stockUpdater.update();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ClientNormalSQLComponent.java
17,6 → 17,8
package org.openconcerto.erp.core.customerrelationship.customer.element;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.component.AdresseSQLComponent;
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.common.ui.DeviseField;
39,15 → 41,18
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.UndefinedRowValuesCache;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.request.SQLRowItemView;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.ITextWithCompletion;
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.sqlobject.SQLSearchableTextCombo;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
import org.openconcerto.sql.sqlobject.itemview.VWRowItemView;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JComponentUtils;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.TitledSeparator;
import org.openconcerto.ui.component.ComboLockedMode;
import org.openconcerto.ui.component.ITextArea;
 
import java.awt.Component;
62,9 → 67,7
import java.beans.PropertyChangeListener;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import javax.swing.ButtonGroup;
import javax.swing.Icon;
79,6 → 82,7
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
 
// Client without CTech link (i.e. there's one and only table in the DB)
public class ClientNormalSQLComponent extends BaseSQLComponent {
 
int idDefaultCompteClient = 1;
89,15 → 93,6
 
protected boolean showMdr = true;
 
private JTabbedPane tabbedAdresse = new JTabbedPane() {
public void insertTab(String title, Icon icon, Component component, String tip, int index) {
if (component instanceof JComponent) {
((JComponent) component).setOpaque(false);
}
super.insertTab(title, icon, component, tip, index);
}
 
};
ElementSQLObject componentPrincipale, componentLivraison, componentFacturation;
AdresseClientItemTable adresseTable = new AdresseClientItemTable();
JCheckBox boxGestionAutoCompte;
105,7 → 100,7
private JCheckBox boxAffacturage, boxComptant;
private DeviseField fieldMontantFactMax;
ISQLCompteSelector compteSel;
JComponent textNom;
private SQLRowItemView textNom;
// ITextWithCompletion textNom;
final ElementComboBox comboPole = new ElementComboBox();
DecimalFormat format = new DecimalFormat("000");
116,6 → 111,7
private SQLRowItemView eltModeRegl;
private JUniqueTextField textCode;
private JLabel labelCpt;
private ModeDeReglementSQLComponent modeReglComp;
 
public ClientNormalSQLComponent(SQLElement elt) {
super(elt);
125,11 → 121,6
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
 
this.addView("ID_MODE_REGLEMENT", REQ + ";" + DEC + ";" + SEP);
this.eltModeRegl = this.getView("ID_MODE_REGLEMENT");
final ElementSQLObject comp = (ElementSQLObject) this.eltModeRegl.getComp();
final ModeDeReglementSQLComponent modeReglComp = (ModeDeReglementSQLComponent) comp.getSQLChild();
 
// Raison sociale
JLabel labelRS = new JLabel(getLabelFor("FORME_JURIDIQUE"));
labelRS.setHorizontalAlignment(SwingConstants.RIGHT);
168,9 → 159,10
c.gridwidth = 1;
c.weightx = 0.5;
 
this.textNom = new ITextArea();
DefaultGridBagConstraints.lockMinimumSize(textNom);
this.add(this.textNom, c);
final JComponent nomComp;
nomComp = new JTextField();
DefaultGridBagConstraints.lockMinimumSize(nomComp);
this.add(nomComp, c);
 
if (getTable().getFieldsName().contains("ID_PAYS")) {
c.gridx++;
339,8 → 331,6
 
});
 
// Secteur activité
final boolean customerIsKD;
 
// Champ Module
c.gridx = 0;
353,80 → 343,26
c.gridy++;
c.gridwidth = 1;
 
// Adresse
final JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Adresses", createAdressesComponent());
tabs.addTab("Contacts", createContactComponent());
JPanel pReglement = createReglementComponent();
if (showMdr) {
tabs.addTab("Mode de règlement", pReglement);
}
tabs.addTab("Comptabilité", createComptabiliteComponent());
 
tabs.setMinimumSize(new Dimension(tabs.getPreferredSize().width, tabs.getPreferredSize().height));
 
c.gridx = 0;
c.gridy++;
c.weightx = 1;
c.weighty = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
TitledSeparator sep = new TitledSeparator("Adresse");
this.add(sep, c);
 
// Adr principale
this.addView("ID_ADRESSE", REQ + ";" + DEC + ";" + SEP);
this.componentPrincipale = (ElementSQLObject) this.getView("ID_ADRESSE");
this.componentPrincipale.setOpaque(false);
this.tabbedAdresse.add(getLabelFor("ID_ADRESSE"), this.componentPrincipale);
 
// Adr facturation
JPanel panelFacturation = new JPanel(new GridBagLayout());
panelFacturation.setOpaque(false);
GridBagConstraints cPanelF = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 1, 2, 1), 0, 0);
 
this.addView("ID_ADRESSE_F", DEC + ";" + SEP);
this.componentFacturation = (ElementSQLObject) this.getView("ID_ADRESSE_F");
this.componentFacturation.setOpaque(false);
panelFacturation.add(this.componentFacturation, cPanelF);
this.checkAdrFacturation = new JCheckBox("Adresse de facturation identique à la principale");
this.checkAdrFacturation.setOpaque(false);
cPanelF.gridy++;
panelFacturation.add(this.checkAdrFacturation, cPanelF);
this.tabbedAdresse.add(getLabelFor("ID_ADRESSE_F"), panelFacturation);
// Adr livraison
JPanel panelLivraison = new JPanel(new GridBagLayout());
panelLivraison.setOpaque(false);
GridBagConstraints cPanelL = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 1, 2, 1), 0, 0);
 
this.addView("ID_ADRESSE_L", DEC + ";" + SEP);
this.componentLivraison = (ElementSQLObject) this.getView("ID_ADRESSE_L");
this.componentLivraison.setOpaque(false);
panelLivraison.add(this.componentLivraison, cPanelL);
 
this.checkAdrLivraison = new JCheckBox("Adresse de livraison identique à l'adresse principale");
this.checkAdrLivraison.setOpaque(false);
cPanelL.gridy++;
panelLivraison.add(this.checkAdrLivraison, cPanelL);
this.tabbedAdresse.add(getLabelFor("ID_ADRESSE_L"), panelLivraison);
String labelAdrSuppl = "Adresses supplémentaires";
this.tabbedAdresse.add(labelAdrSuppl, this.adresseTable);
 
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
this.tabbedAdresse.setOpaque(false);
this.add(this.tabbedAdresse, c);
 
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(tabs, c);
 
// Contact
 
TitledSeparator sepContact = new TitledSeparator("Contacts client");
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridx = 0;
c.gridy++;
this.add(sepContact, c);
 
this.table = new ContactItemTable(this.defaultContactRowVals);
this.table.setPreferredSize(new Dimension(this.table.getSize().width, 150));
c.gridx = 0;
c.gridy++;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weighty = 0.7;
this.add(this.table, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 1;
c.weighty = 0;
434,26 → 370,10
 
// Mode de régelement
 
TitledSeparator reglSep = new TitledSeparator(getLabelFor("ID_MODE_REGLEMENT"));
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridy++;
c.gridx = 0;
this.add(reglSep, c);
 
c.gridy++;
c.gridx = 0;
this.add(comp, c);
 
if (!showMdr) {
reglSep.setVisible(false);
comp.setCreated(false);
comp.setVisible(false);
}
 
if (getTable().getFieldsName().contains("ID_TARIF")) {
 
// Tarif
TitledSeparator tarifSep = new TitledSeparator("Tarif spécial à appliquer");
JLabel tarifSep = new JLabel("Tarif spécial à appliquer");
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridy++;
c.gridx = 0;
463,7 → 383,7
c.gridx = 0;
c.gridwidth = 1;
c.weightx = 0;
this.add(new JLabel(getLabelFor("ID_TARIF")), c);
this.add(new JLabel(getLabelFor("ID_TARIF"), SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
473,7 → 393,7
}
if (getTable().getFieldsName().contains("ID_LANGUE")) {
// Tarif
TitledSeparator langueSep = new TitledSeparator("Langue à appliquer sur les documents");
JLabel langueSep = new JLabel("Langue à appliquer sur les documents");
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridy++;
c.gridx = 0;
483,7 → 403,7
c.gridx = 0;
c.gridwidth = 1;
c.weightx = 0;
this.add(new JLabel(getLabelFor("ID_LANGUE")), c);
this.add(new JLabel(getLabelFor("ID_LANGUE"), SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
509,44 → 429,9
c.gridy++;
this.add(addOnPanel, c);
}
// Compte associé
this.compteSel = new ISQLCompteSelector(true);
this.boxGestionAutoCompte = new JCheckBox("Gestion Automatique des comptes");
TitledSeparator sepCompte = new TitledSeparator("Compte associé");
this.labelCpt = new JLabel(getLabelFor("ID_COMPTE_PCE"));
 
if (!Boolean.valueOf(DefaultNXProps.getInstance().getProperty("HideCompteClient"))) {
 
c.gridx = 0;
c.gridy++;
c.weightx = 1;
c.weighty = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
 
this.add(sepCompte, c);
 
c.gridwidth = 1;
c.gridy++;
c.gridx = 0;
c.weightx = 0;
this.add(this.labelCpt, c);
 
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridx++;
c.weightx = 1;
 
this.add(this.compteSel, c);
 
this.boxGestionAutoCompte.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
 
setCompteVisible(!(boxGestionAutoCompte.isSelected() && getSelectedID() <= 1));
}
});
}
// Infos
TitledSeparator infosSep = new TitledSeparator(getLabelFor("INFOS"));
JLabel infosSep = new JLabel(getLabelFor("INFOS"));
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridy++;
c.gridx = 0;
579,7 → 464,8
});
 
this.addSQLObject(textType, "FORME_JURIDIQUE");
this.addView(this.textNom, "NOM", REQ);
this.addView(nomComp, "NOM", REQ);
this.textNom = this.getView(nomComp);
this.addSQLObject(this.textCode, "CODE");
this.addSQLObject(textFax, "FAX");
this.addSQLObject(textSiren, "SIRET");
596,6 → 482,143
 
}
 
private Component createAdressesComponent() {
final JTabbedPane tabbedAdresse = new JTabbedPane() {
public void insertTab(String title, Icon icon, Component component, String tip, int index) {
if (component instanceof JComponent) {
((JComponent) component).setOpaque(false);
}
super.insertTab(title, icon, component, tip, index);
}
 
};
final GridBagConstraints c = new DefaultGridBagConstraints();
// Adr principale
this.addView("ID_ADRESSE", REQ + ";" + DEC + ";" + SEP);
this.componentPrincipale = (ElementSQLObject) this.getView("ID_ADRESSE");
this.componentPrincipale.setOpaque(false);
tabbedAdresse.add(getLabelFor("ID_ADRESSE"), this.componentPrincipale);
tabbedAdresse.setOpaque(false);
// Adr facturation
JPanel panelFacturation = new JPanel(new GridBagLayout());
panelFacturation.setOpaque(false);
GridBagConstraints cPanelF = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 1, 2, 1), 0, 0);
 
this.addView("ID_ADRESSE_F", DEC + ";" + SEP);
this.componentFacturation = (ElementSQLObject) this.getView("ID_ADRESSE_F");
this.componentFacturation.setOpaque(false);
panelFacturation.add(this.componentFacturation, cPanelF);
this.checkAdrFacturation = new JCheckBox("Adresse de facturation identique à la principale");
this.checkAdrFacturation.setOpaque(false);
cPanelF.gridy++;
panelFacturation.add(this.checkAdrFacturation, cPanelF);
tabbedAdresse.add(getLabelFor("ID_ADRESSE_F"), panelFacturation);
// Adr livraison
JPanel panelLivraison = new JPanel(new GridBagLayout());
panelLivraison.setOpaque(false);
GridBagConstraints cPanelL = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 1, 2, 1), 0, 0);
 
this.addView("ID_ADRESSE_L", DEC + ";" + SEP);
this.componentLivraison = (ElementSQLObject) this.getView("ID_ADRESSE_L");
((AdresseSQLComponent) this.componentLivraison.getSQLChild()).setDestinataireVisible(true);
this.componentLivraison.setOpaque(false);
 
panelLivraison.add(this.componentLivraison, cPanelL);
 
this.checkAdrLivraison = new JCheckBox("Adresse de livraison identique à l'adresse principale");
this.checkAdrLivraison.setOpaque(false);
cPanelL.gridy++;
panelLivraison.add(this.checkAdrLivraison, cPanelL);
tabbedAdresse.add(getLabelFor("ID_ADRESSE_L"), panelLivraison);
String labelAdrSuppl = "Adresses supplémentaires";
tabbedAdresse.add(labelAdrSuppl, this.adresseTable);
 
c.gridx = 0;
c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
 
return tabbedAdresse;
}
 
private JPanel createContactComponent() {
 
this.table = new ContactItemTable(this.defaultContactRowVals);
this.table.setPreferredSize(new Dimension(this.table.getSize().width, 150));
this.table.setOpaque(false);
return table;
}
 
private JPanel createReglementComponent() {
 
this.addView("ID_MODE_REGLEMENT", REQ + ";" + DEC + ";" + SEP);
this.eltModeRegl = this.getView("ID_MODE_REGLEMENT");
 
final JPanel p = new JPanel();
p.setOpaque(false);
p.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
final ElementSQLObject comp = (ElementSQLObject) this.eltModeRegl.getComp();
this.modeReglComp = (ModeDeReglementSQLComponent) comp.getSQLChild();
 
final JLabelBold label = new JLabelBold(getLabelFor("ID_MODE_REGLEMENT"));
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1;
c.fill = GridBagConstraints.NONE;
c.gridy++;
c.gridx = 0;
p.add(label, c);
c.gridy++;
c.gridx = 0;
// FIXME: comp?
comp.setOpaque(false);
p.add(comp, c);
return p;
}
 
private Component createComptabiliteComponent() {
final JPanel p = new JPanel();
p.setOpaque(false);
p.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
// Compte associé
this.compteSel = new ISQLCompteSelector(true);
this.boxGestionAutoCompte = new JCheckBox("Gestion Automatique des comptes");
JLabelBold sepCompte = new JLabelBold("Compte associé");
this.labelCpt = new JLabel(getLabelFor("ID_COMPTE_PCE"));
 
if (!Boolean.valueOf(DefaultNXProps.getInstance().getProperty("HideCompteClient"))) {
 
c.gridx = 0;
c.gridy++;
c.weightx = 1;
c.weighty = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
 
p.add(sepCompte, c);
 
c.gridwidth = 1;
c.gridy++;
c.gridx = 0;
c.weightx = 0;
p.add(this.labelCpt, c);
 
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridx++;
c.weightx = 1;
 
p.add(this.compteSel, c);
 
this.boxGestionAutoCompte.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
 
setCompteVisible(!(boxGestionAutoCompte.isSelected() && getSelectedID() <= 1));
}
});
}
return p;
}
 
private void setCompteVisible(boolean b) {
 
this.labelCpt.setVisible(b);
617,15 → 640,7
SQLRow rowCpt = row.getForeignRow("ID_COMPTE_PCE");
String num = rowCpt.getString("NUMERO");
String initialClient = "";
String text;
if (this.textNom instanceof ITextArea) {
ITextArea textNomArea = (ITextArea) this.textNom;
text = textNomArea.getText();
} else {
ITextWithCompletion textNomArea = (ITextWithCompletion) this.textNom;
text = textNomArea.getValue();
}
// final String text = (String) this.textNom.getText();
final String text = getNameValue();
if (text != null && text.trim().length() > 1) {
initialClient += text.trim().toUpperCase().charAt(0);
}
643,20 → 658,17
}
}
 
private String getNameValue() {
return (String) ((VWRowItemView<?>) this.textNom).getWrapper().getValue();
}
 
@Override
public void select(SQLRowAccessor r) {
 
int idAdrL = 1;
int idAdrF = 1;
if (r != null && r.getID() > 1) {
final SQLRow row = this.getTable().getRow(r.getID());
idAdrL = row.getInt("ID_ADRESSE_L");
idAdrF = row.getInt("ID_ADRESSE_F");
}
super.select(r);
 
this.checkAdrLivraison.setSelected(idAdrL == 1);
this.checkAdrFacturation.setSelected(idAdrF == 1);
this.checkAdrLivraison.setSelected(r == null || r.isForeignEmpty("ID_ADRESSE_L"));
this.checkAdrFacturation.setSelected(r == null || r.isForeignEmpty("ID_ADRESSE_F"));
if (r != null) {
this.table.insertFrom("ID_CLIENT", r.asRowValues());
this.adresseTable.insertFrom("ID_CLIENT", r.getID());
669,14 → 681,7
private void createCompteClientAuto(int idClient) {
SQLRowValues rowVals = getTable().getRow(idClient).createEmptyUpdateRow();
String initialClient = "";
String text;
if (this.textNom instanceof ITextArea) {
ITextArea textNomArea = (ITextArea) this.textNom;
text = textNomArea.getText();
} else {
ITextWithCompletion textNomArea = (ITextWithCompletion) this.textNom;
text = textNomArea.getValue();
}
final String text = getNameValue();
if (text != null && text.trim().length() > 1) {
initialClient += text.trim().toUpperCase().charAt(0);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ContactSQLElementBase.java
18,7 → 18,10
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.UISQLComponent;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.ui.EmailComposer;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ExceptionHandler;
 
import java.util.ArrayList;
import java.util.Collections;
176,4 → 179,20
}
}
 
protected void sendMail(List<SQLRowAccessor> l) {
 
String mail = "";
for (SQLRowAccessor rowCli : l) {
String string = rowCli.getString("EMAIL");
if (string != null && string.trim().length() > 0) {
mail += string + ";";
}
}
try {
EmailComposer.getInstance().compose(mail, "", "");
} catch (Exception exn) {
ExceptionHandler.handle(null, "Impossible de créer le courriel", exn);
}
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ClientNormalSQLElement.java
17,7 → 17,6
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.customerrelationship.customer.report.FicheClientXmlSheet;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.map.model.Ville;
import org.openconcerto.ql.LabelCreator;
import org.openconcerto.ql.QLPrinter;
import org.openconcerto.sql.Configuration;
60,10 → 59,7
for (String string2 : s) {
c.addLineNormal(string2);
}
 
Ville v = Ville.getVilleFromVilleEtCode(foreignRow.getString("VILLE"));
c.addLineNormal(v.getCodepostal() + " " + v.getName());
 
c.addLineNormal(foreignRow.getString("CODE_POSTAL") + " " + foreignRow.getString("VILLE"));
final QLPrinter prt = new QLPrinter(property);
try {
prt.print(c.getImage());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ContactItemTable.java
42,6 → 42,7
}
 
private ContactItemTable(SQLRowValues defaultRow, SQLElement elt) {
this.setOpaque(false);
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = 1;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/CourrierClientSQLElement.java
34,7 → 34,6
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.ISQLElementWithCodeSelector;
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
import org.openconcerto.sql.users.UserManager;
101,7 → 100,7
JUniqueTextField textNumero;
JDate date;
SQLTextCombo objet;
ISQLElementWithCodeSelector selAffaire;
ElementComboBox selAffaire;
ElementComboBox comboModele = new ElementComboBox();
ElementComboBox boxAdresse;
JCheckBox checkImpression = new JCheckBox("Impression");
133,7 → 132,6
c.fill = GridBagConstraints.HORIZONTAL;
this.add(this.date, c);
 
final SQLElement eltAffaire;
// Objet
c.gridy++;
c.gridx = 0;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ContactSQLElement.java
13,7 → 13,14
package org.openconcerto.erp.core.customerrelationship.customer.element;
 
import java.awt.event.ActionEvent;
 
import javax.swing.AbstractAction;
 
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
 
public class ContactSQLElement extends ContactSQLElementBase {
 
31,10 → 38,21
 
public ContactSQLElement() {
this("CONTACT");
 
}
 
protected ContactSQLElement(String tableName) {
super(tableName);
this.setL18nLocation(Gestion.class);
PredicateRowAction action = new PredicateRowAction(new AbstractAction() {
 
@Override
public void actionPerformed(ActionEvent e) {
sendMail(IListe.get(e).getSelectedRows());
 
}
}, true, "customerrelationship.customer.email.send");
action.setPredicate(IListeEvent.getNonEmptySelectionPredicate());
getRowActions().add(action);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/action/ListeDesContactsAction.java
13,7 → 13,7
package org.openconcerto.erp.core.customerrelationship.customer.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.action.CreateListFrameAbstractAction;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.view.IListFrame;
import org.openconcerto.sql.view.ListeAddPanel;
22,9 → 22,8
import javax.swing.Action;
import javax.swing.JFrame;
 
public class ListeDesContactsAction extends CreateListFrameAbstractAction {
 
public class ListeDesContactsAction extends CreateFrameAbstractAction {
 
public ListeDesContactsAction() {
super();
this.putValue(Action.NAME, "Liste des contacts");
34,4 → 33,9
final ComptaBasePropsConfiguration conf = ((ComptaBasePropsConfiguration) Configuration.getInstance());
return new IListFrame(new ListeAddPanel(conf.getDirectory().getElement("CONTACT")));
}
 
@Override
public String getTableName() {
return "CONTACT";
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/action/ListeDesClientsAction.java
14,6 → 14,7
package org.openconcerto.erp.core.customerrelationship.customer.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.action.CreateListFrameAbstractAction;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.customerrelationship.customer.report.FicheClientXmlSheet;
import org.openconcerto.erp.core.sales.invoice.ui.EcheanceRenderer;
40,8 → 41,7
import javax.swing.JFrame;
import javax.swing.JTable;
 
public class ListeDesClientsAction extends CreateFrameAbstractAction {
private static SQLTable tableModeReglement = Configuration.getInstance().getDirectory().getElement("MODE_REGLEMENT").getTable();
public class ListeDesClientsAction extends CreateListFrameAbstractAction {
 
public ListeDesClientsAction() {
super();
48,6 → 48,11
this.putValue(Action.NAME, "Liste des clients");
}
 
@Override
public String getTableName() {
return "CLIENT";
}
 
protected SQLTableModelSource getTableSource() {
SQLTable tableClient = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("CLIENT");
return Configuration.getInstance().getDirectory().getElement(tableClient).getTableSource(true);
55,6 → 60,8
 
public JFrame createFrame() {
SQLTable tableClient = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("CLIENT");
SQLTable tableModeReglement = Configuration.getInstance().getDirectory().getElement("MODE_REGLEMENT").getTable();
 
final ListeAddPanel panel = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement(tableClient), new IListe(getTableSource()));
IListFrame frame = new IListFrame(panel);
 
73,7 → 80,6
}
}
 
panel.setSearchFullMode(true);
panel.setSelectRowOnAdd(false);
return frame;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/ui/AdresseClientItemTable.java
40,7 → 40,7
 
public class AdresseClientItemTable extends JPanel {
private RowValuesTable table;
private SQLTableElement dest, cedex, hasCedex, ville, rue;
private SQLTableElement type, dest, rue, cedex, ville, province, pays, email;
private RowValuesTableModel model;
private SQLRowValues defaultRowVals;
 
61,6 → 61,10
final List<SQLTableElement> list = new Vector<SQLTableElement>();
 
// Destinataire
this.type = new SQLTableElement(e.getTable().getField("TYPE"));
list.add(this.type);
 
// Destinataire
this.dest = new SQLTableElement(e.getTable().getField("DEST"));
list.add(this.dest);
 
88,13 → 92,25
list.add(this.ville);
 
// has cedex
this.hasCedex = new SQLTableElement(e.getTable().getField("HAS_CEDEX"));
list.add(this.hasCedex);
// this.hasCedex = new SQLTableElement(e.getTable().getField("HAS_CEDEX"));
// list.add(this.hasCedex);
 
// cedex
this.cedex = new SQLTableElement(e.getTable().getField("CEDEX"));
list.add(this.cedex);
 
// Province
this.province = new SQLTableElement(e.getTable().getField("PROVINCE"));
list.add(this.province);
 
// Pays
this.pays = new SQLTableElement(e.getTable().getField("PAYS"));
list.add(this.pays);
 
// Emails
this.email = new SQLTableElement(e.getTable().getField("EMAIL_CONTACT"));
list.add(this.email);
 
this.model = new RowValuesTableModel(e, list, e.getTable().getField("VILLE"));
 
this.table = new RowValuesTable(this.model, null, true);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/SaisieKmSQLElement.java
45,8 → 45,11
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
207,6 → 210,9
// depends on inner table, at creation it's empty and thus valid
private ValidState validState = ValidState.getTrueInstance();
 
private ValidState validStateCloture = ValidState.getTrueInstance();
private final SQLRow rowExercice = ComptaPropsConfiguration.getInstanceCompta().getRowSociete().getForeign("ID_EXERCICE_COMMON");
 
private TableModelListener tableListener = new TableModelListener() {
public void tableChanged(TableModelEvent e) {
SaisieKmComponent.this.tableChanged(e);
227,7 → 233,22
this.labelTotalCredit = new JLabel("0.00", SwingConstants.RIGHT);
this.labelTotalDebit = new JLabel("0.00", SwingConstants.RIGHT);
this.date = new JDate();
this.date.addValueListener(new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
Calendar cDeb = rowExercice.getDate("DATE_DEB");
Calendar cClo = rowExercice.getDate("DATE_CLOTURE");
if (date.getValue() != null && cDeb.getTime().after(date.getValue())) {
validStateCloture = new ValidState(false, "La date de saisie doit être supérieure à celle du début de l'exercice!");
} else if (date.getValue() != null && cClo != null && cClo.getTime().after(date.getValue())) {
validStateCloture = new ValidState(false, "La date de saisie doit être supérieure à celle de la période de clôture définie dans l'exercice courant!");
} else {
validStateCloture = ValidState.getTrueInstance();
}
fireValidChange();
}
});
this.comboJrnl = new ElementComboBox(false, 20);
 
// Libellé
535,7 → 556,7
@Override
public synchronized ValidState getValidState() {
assert SwingUtilities.isEventDispatchThread();
return super.getValidState().and(this.validState);
return super.getValidState().and(this.validState).and(this.validStateCloture);
}
 
private void updateValidState() {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/AssociationAnalytiqueSQLElement.java
14,11 → 14,21
package org.openconcerto.erp.core.finance.accounting.element;
 
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.map.model.Ville;
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.model.FieldPath;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.graph.Path;
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.utils.CollectionUtils;
 
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
 
import javax.swing.JTextField;
 
40,6 → 50,7
final List<String> list = new ArrayList<String>(2);
list.add("ID_ECRITURE");
list.add("ID_POSTE_ANALYTIQUE");
// list.add("MONTANT");
return list;
}
 
63,4 → 74,54
protected String createCode() {
return createCodeFromPackage() + ".analytic.relation";
}
 
@Override
protected SQLTableModelSourceOnline createTableSource() {
SQLTableModelSourceOnline table = super.createTableSource();
BaseSQLTableModelColumn debit = new BaseSQLTableModelColumn("Débit", BigDecimal.class) {
 
@Override
protected Object show_(SQLRowAccessor r) {
 
long montant = r.getLong("MONTANT");
if (montant > 0) {
return new BigDecimal(montant).movePointLeft(2);
} else {
return BigDecimal.ZERO;
}
}
 
@Override
public Set<FieldPath> getPaths() {
Path p = new Path(getTable());
return CollectionUtils.createSet(new FieldPath(p, "MONTANT"));
}
};
 
table.getColumns().add(debit);
 
BaseSQLTableModelColumn credit = new BaseSQLTableModelColumn("Crédit", BigDecimal.class) {
 
@Override
protected Object show_(SQLRowAccessor r) {
 
long montant = r.getLong("MONTANT");
if (montant < 0) {
return new BigDecimal(-montant).movePointLeft(2);
} else {
return BigDecimal.ZERO;
}
}
 
@Override
public Set<FieldPath> getPaths() {
Path p = new Path(getTable());
return CollectionUtils.createSet(new FieldPath(p, "MONTANT"));
}
};
 
table.getColumns().add(credit);
 
return table;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/AssociationCompteAnalytiqueSQLElement.java
17,14 → 17,11
import org.openconcerto.erp.core.finance.accounting.model.AssociationAnalytiqueModel;
import org.openconcerto.erp.core.finance.accounting.ui.PlanComptableCellRenderer;
import org.openconcerto.erp.element.objet.ClasseCompte;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableListener;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/EcritureSQLElement.java
33,6 → 33,7
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.ListSQLRequest;
import org.openconcerto.sql.request.UpdateBuilder;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.utils.SQLUtils;
467,6 → 468,7
} else {
 
System.err.println("Suppression du mouvement d'id 1 impossible.");
JOptionPane.showMessageDialog(null, "Impossible d'archiver, le mouvement est indéfini.");
}
}
 
549,6 → 551,17
rowVals.put("IDUSER_DELETE", UserManager.getInstance().getCurrentUser().getId());
rowVals.update(row.getID());
 
// Annulation du lettrage si l'ecriture est lettrée pour ne pas avoir de lettrage
// déséquilibré
final String codeLettrage = row.getString("LETTRAGE");
if (codeLettrage != null && codeLettrage.trim().length() > 0) {
UpdateBuilder builder = new UpdateBuilder(getTable());
builder.setObject("LETTRAGE", "");
builder.setObject("DATE_LETTRAGE", null);
builder.setWhere(new Where(getTable().getField("LETTRAGE"), "=", codeLettrage));
getTable().getDBSystemRoot().getDataSource().execute(builder.asString());
}
 
super.archive(row, true);
} else {
System.err.println("Impossible de supprimer une ecriture validée");
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/VentilationAnalytiqueSheetXML.java
New file
0,0 → 1,327
/*
* 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.finance.accounting.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.erp.rights.ComptaUserRight;
import org.openconcerto.sql.Configuration;
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.sql.users.UserManager;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.cc.ITransformer;
 
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.apache.commons.dbutils.handlers.ArrayListHandler;
 
public class VentilationAnalytiqueSheetXML extends AbstractListeSheetXml {
 
private static int debutFill, endFill;
protected final static SQLTable tableAssoc = base.getTable("ASSOCIATION_ANALYTIQUE");
protected final static SQLTable tablePoste = base.getTable("POSTE_ANALYTIQUE");
private final static SQLTable tableEcriture = base.getTable("ECRITURE");
private final static SQLTable tableJournal = base.getTable("JOURNAL");
private final static SQLTable tableMvt = base.getTable("MOUVEMENT");
private final static SQLTable tableCompte = base.getTable("COMPTE_PCE");
 
private final static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
private final static DateFormat dateFormatEcr = DateFormat.getDateInstance(DateFormat.SHORT);
private SQLRow rowSociete = ((ComptaPropsConfiguration) Configuration.getInstance()).getRowSociete();
 
private Date dateDu, dateAu;
private String compteDeb, compteEnd;
private SQLRow rowPoste;
 
public static String TEMPLATE_ID = "VentilationAnalytique";
public static String TEMPLATE_PROPERTY_NAME = "LocationJournaux";
 
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
Date date;
 
@Override
public String getName() {
if (this.date == null) {
this.date = new Date();
}
return "VentilationAnalytique" + date.getTime();
}
 
@Override
protected String getStoragePathP() {
return "Ventilation Analytique";
}
 
public VentilationAnalytiqueSheetXML(Date du, Date au, SQLRow rowPoste) {
super();
Calendar cal = Calendar.getInstance();
cal.setTime(au);
this.printer = PrinterNXProps.getInstance().getStringProperty("JournauxPrinter");
this.dateAu = au;
this.dateDu = du;
this.rowPoste = rowPoste;
}
 
private String toDay = dateFormat.format(new Date());
private int size;
 
private void makeSousTotal(Map<String, Object> line, Map<Integer, String> style, int pos, long debit, long credit) {
style.put(pos, "Titre 1");
 
line.put("DATE", "");
line.put("JOURNAL", "");
line.put("MOUVEMENT", "");
line.put("LIBELLE", "Sous total");
line.put("DEBIT", Double.valueOf(GestionDevise.currencyToString(debit, false)));
line.put("CREDIT", Double.valueOf(GestionDevise.currencyToString(credit, false)));
line.put("SOLDE", Double.valueOf(GestionDevise.currencyToString(debit - credit, false)));
}
 
protected void createListeValues() {
final SQLRowValues vals = new SQLRowValues(tableEcriture);
 
vals.put("ID_JOURNAL", null);
vals.put("ID_COMPTE_PCE", null);
vals.put("COMPTE_NUMERO", null);
vals.put("COMPTE_NOM", null);
vals.put("JOURNAL_CODE", null);
vals.put("JOURNAL_NOM", null);
vals.putRowValues("ID_MOUVEMENT").put("NUMERO", null);
 
vals.put("CREDIT", null);
vals.put("DEBIT", null);
vals.put("DATE", null);
vals.put("NOM", null);
 
final SQLRowValues valsAnalytique = new SQLRowValues(tableAssoc);
valsAnalytique.put("ID_ECRITURE", vals);
valsAnalytique.putRowValues("ID_POSTE_ANALYTIQUE").put("NOM", null);
valsAnalytique.put("POURCENT", null);
valsAnalytique.put("MONTANT", null);
valsAnalytique.put("ID_ECRITURE", vals);
 
final SQLRowValuesListFetcher fetcher = new SQLRowValuesListFetcher(valsAnalytique);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
@Override
public SQLSelect transformChecked(SQLSelect sel) {
 
Where w = (new Where(sel.getJoinFromField(tableAssoc.getField("ID_ECRITURE")).getJoinedTable().getField("DATE"), VentilationAnalytiqueSheetXML.this.dateDu,
VentilationAnalytiqueSheetXML.this.dateAu));
 
// if (rowPoste != null && !rowPoste.isUndefined()) {
 
w = w.and(new Where(tableAssoc.getField("ID_POSTE_ANALYTIQUE"), "=", rowPoste.getID()));
// }
 
sel.setWhere(w);
sel.addFieldOrder(tableAssoc.getField("ID_POSTE_ANALYTIQUE"));
sel.addFieldOrder(sel.getJoinFromField(tableAssoc.getField("ID_ECRITURE")).getJoinedTable().getField("COMPTE_NUMERO"));
 
return sel;
}
});
 
List<SQLRowValues> list = fetcher.fetch();
size = list.size();
 
long totalDebit, totalCredit, sousTotalDebit, sousTotalCredit, totalCreditAntC, totalDebitAntC, totalCreditAntF, totalDebitAntF;
 
totalDebit = 0;
totalCredit = 0;
sousTotalCredit = 0;
sousTotalDebit = 0;
totalCreditAntC = 0;
totalDebitAntC = 0;
totalCreditAntF = 0;
totalDebitAntF = 0;
SQLRowAccessor rowFirstEcr = null;
int idCptFirstEcr = 1;
 
boolean setTitle = true;
boolean setLine = false;
boolean setCumuls = true;
boolean firstEcrCentC = true;
boolean firstEcrCentF = true;
String numCptFirstEcr = "";
 
final String titre3 = "Titre 3";
// int j = 0;
 
// Valeur de la liste
// listAllSheetValues ;
 
// Style des lignes
// styleAllSheetValues;
 
// Valeur à l'extérieur de la liste
// mapAllSheetValues
 
List<Map<String, Object>> tableauVals = new ArrayList<Map<String, Object>>();
this.listAllSheetValues.put(0, tableauVals);
 
Map<Integer, String> style = new HashMap<Integer, String>();
this.styleAllSheetValues.put(0, style);
 
// Affiche le nom du compte
setTitle = true;
// ligne vide avant de mettre le setTitle
setLine = false;
for (int i = 0; i < size;) {
// System.err.println(i);
// // System.err.println("START NEW PAGE; POS : " + posLine);
//
// /***************************************************************************************
// * ENTETE
// **************************************************************************************/
// // makeEntete(posLine);
// // posLine += debutFill - 1;
 
/***************************************************************************************
* CONTENU
**************************************************************************************/
final Double doubleZero = Double.valueOf("0");
 
final SQLRowValues sqlRowValuesAnalytique = list.get(i);
SQLRowAccessor rowEcr = sqlRowValuesAnalytique.getForeign("ID_ECRITURE");
 
int idCpt = rowEcr.getInt("ID_COMPTE_PCE");
String nomCpt = rowEcr.getString("COMPTE_NOM");
String numCpt = rowEcr.getString("COMPTE_NUMERO");
 
Map<String, Object> ooLine = new HashMap<String, Object>();
tableauVals.add(ooLine);
 
// Titre
if (setTitle) {
if (!setLine) {
style.put(tableauVals.size() - 1, "Titre 1");
 
ooLine.put("DATE", numCpt);
ooLine.put("CODE_JOURNAL", nomCpt);
ooLine.put("JOURNAL", "");
ooLine.put("NUMERO_COMPTE", "");
ooLine.put("LIBELLE_COMPTE", "");
ooLine.put("NUMERO_MOUVEMENT", "");
ooLine.put("LIBELLE", "");
ooLine.put("DEBIT", "");
ooLine.put("CREDIT", "");
ooLine.put("SOLDE", "");
setTitle = false;
setLine = true;
 
if (rowFirstEcr == null) {
rowFirstEcr = rowEcr;
idCptFirstEcr = rowEcr.getInt("ID_COMPTE_PCE");
numCptFirstEcr = rowEcr.getString("COMPTE_NUMERO");
}
 
} else {
style.put(tableauVals.size() - 1, "Normal");
setLine = false;
}
} else {
 
// si on change de compte alors on applique le style Titre 1
if (rowFirstEcr != null && idCptFirstEcr != idCpt) {
 
rowFirstEcr = rowEcr;
idCptFirstEcr = rowFirstEcr.getInt("ID_COMPTE_PCE");
numCptFirstEcr = rowEcr.getString("COMPTE_NUMERO");
makeSousTotal(ooLine, style, tableauVals.size() - 1, sousTotalDebit, sousTotalCredit);
 
sousTotalCredit = 0;
sousTotalDebit = 0;
setTitle = true;
setCumuls = true;
} else {
long cred = rowEcr.getLong("CREDIT");
long deb = rowEcr.getLong("DEBIT");
// Centralisation fournisseur
 
ooLine.put("DATE", dateFormatEcr.format((Date) rowEcr.getObject("DATE")));
 
ooLine.put("CODE_JOURNAL", rowEcr.getString("JOURNAL_CODE"));
ooLine.put("JOURNAL", rowEcr.getString("JOURNAL_NOM"));
ooLine.put("NUMERO_MOUVEMENT", rowEcr.getForeign("ID_MOUVEMENT").getObject("NUMERO"));
ooLine.put("LIBELLE", rowEcr.getObject("NOM"));
ooLine.put("CODE_LETTRAGE", rowEcr.getObject("LETTRAGE"));
ooLine.put("CODE_POINTAGE", rowEcr.getObject("POINTEE"));
ooLine.put("DATE_LETTRAGE", rowEcr.getObject("DATE_LETTRAGE"));
ooLine.put("DATE_POINTAGE", rowEcr.getObject("DATE_LETTRAGE"));
 
totalCredit += cred;
totalDebit += deb;
 
sousTotalCredit += cred;
sousTotalDebit += deb;
long solde = sousTotalDebit - sousTotalCredit;
 
ooLine.put("DEBIT", (deb == 0) ? doubleZero : Double.valueOf(GestionDevise.currencyToString(deb, false)));
ooLine.put("CREDIT", (cred == 0) ? doubleZero : Double.valueOf(GestionDevise.currencyToString(cred, false)));
ooLine.put("SOLDE", (solde == 0) ? doubleZero : Double.valueOf(GestionDevise.currencyToString(solde, false)));
 
style.put(tableauVals.size() - 1, "Normal");
i++;
}
 
}
 
}
 
Map<String, Object> sheetVals = new HashMap<String, Object>();
this.mapAllSheetValues.put(0, sheetVals);
 
if (size > 0) {
Map<String, Object> ooLine = new HashMap<String, Object>();
tableauVals.add(ooLine);
makeSousTotal(ooLine, style, tableauVals.size() - 1, sousTotalDebit, sousTotalCredit);
 
sheetVals.put("TOTAL_DEBIT", (totalDebit == 0) ? 0 : new Double(GestionDevise.currencyToString(totalDebit, false)));
sheetVals.put("TOTAL_CREDIT", (totalCredit == 0) ? 0 : new Double(GestionDevise.currencyToString(totalCredit, false)));
sheetVals.put("TOTAL_SOLDE", (totalDebit - totalCredit == 0) ? 0 : new Double(GestionDevise.currencyToString(totalDebit - totalCredit, false)));
}
 
sheetVals.put("TITRE_1", "Ventilation analytique " + this.rowSociete.getString("TYPE") + " " + this.rowSociete.getString("NOM"));
sheetVals.put("DATE_EDITION", new Date());
sheetVals.put("TITRE_2", "Poste analytique : " + this.rowPoste.getString("NOM") + ". Période du " + dateFormatEcr.format(this.dateDu) + " au " + dateFormatEcr.format(this.dateAu) + ".");
 
}
 
@Override
public String getTemplateId() {
return TEMPLATE_ID;
}
 
public int getSize() {
return size;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/GrandLivreSheetXML.java
148,6 → 148,10
vals.put("DEBIT", null);
vals.put("DATE", null);
vals.put("NOM", null);
vals.put("LETTRAGE", null);
vals.put("POINTEE", null);
vals.put("DATE_LETTRAGE", null);
vals.put("DATE_POINTEE", null);
 
final List<Integer> lCompteSolde;
if (GrandLivreSheetXML.this.excludeCompteSolde) {
417,6 → 421,10
ooLine.put("JOURNAL", rowEcr.getString("JOURNAL_CODE"));
ooLine.put("MOUVEMENT", rowEcr.getForeign("ID_MOUVEMENT").getObject("NUMERO"));
ooLine.put("LIBELLE", rowEcr.getObject("NOM"));
ooLine.put("CODE_LETTRAGE", rowEcr.getObject("LETTRAGE"));
ooLine.put("CODE_POINTAGE", rowEcr.getObject("POINTEE"));
ooLine.put("DATE_LETTRAGE", rowEcr.getObject("DATE_LETTRAGE"));
ooLine.put("DATE_POINTAGE", rowEcr.getObject("DATE_LETTRAGE"));
 
totalCredit += cred;
totalDebit += deb;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/VentilationAnalytiquePanel.java
New file
0,0 → 1,136
/*
* 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 23 avr. 2012
*/
package org.openconcerto.erp.core.finance.accounting.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JDate;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ExecutionException;
 
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
 
import org.jopenchart.Chart;
 
public class VentilationAnalytiquePanel extends JPanel {
 
private final JDate dateDeb, dateEnd;
 
public VentilationAnalytiquePanel() {
super(new GridBagLayout());
 
SQLRow rowSociete = ((ComptaPropsConfiguration) Configuration.getInstance()).getRowSociete();
SQLRow rowExercice = Configuration.getInstance().getBase().getTable("EXERCICE_COMMON").getRow(rowSociete.getInt("ID_EXERCICE_COMMON"));
 
this.dateDeb = new JDate();
this.dateEnd = new JDate();
 
JLabel labelPoste = new JLabel("Poste Analytique");
final ElementComboBox box = new ElementComboBox(false);
SQLElement element = Configuration.getInstance().getDirectory().getElement("POSTE_ANALYTIQUE");
ComboSQLRequest comboRequest = element.getComboRequest(true);
box.init(element, comboRequest);
 
GridBagConstraints c = new DefaultGridBagConstraints();
this.add(labelPoste, c);
c.gridx++;
this.add(box, c);
 
c.gridx++;
this.add(new JLabel("Période du", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
this.add(this.dateDeb, c);
// Chargement des valeurs par défaut
// String valueDateDeb = DefaultNXProps.getInstance().getStringProperty("JournauxDateDeb");
// if (valueDateDeb.trim().length() > 0) {
// Long l = new Long(valueDateDeb);
// this.dateDeb.setValue(new Date(l.longValue()));
// } else {
this.dateDeb.setValue((Date) rowExercice.getObject("DATE_DEB"));
// }
 
c.gridx++;
c.weightx = 0;
this.add(new JLabel("Au"), c);
c.gridx++;
c.weightx = 1;
this.add(this.dateEnd, c);
 
final JButton buttonValid = new JButton(new AbstractAction("Valider") {
 
@Override
public void actionPerformed(ActionEvent e) {
 
new Thread() {
public void run() {
SQLRow poste = box.getSelectedRow();
VentilationAnalytiqueSheetXML sheet = new VentilationAnalytiqueSheetXML(dateDeb.getDate(), dateEnd.getDate(), poste);
try {
sheet.createDocument();
sheet.showPrintAndExport(true, false, false);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
 
}
});
c.gridx++;
this.add(buttonValid, c);
 
// Check validity
buttonValid.setEnabled(false);
final PropertyChangeListener listener = new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
buttonValid.setEnabled(box.getSelectedRow() != null && !box.getSelectedRow().isUndefined() && dateDeb.getValue() != null && dateEnd.getValue() != null);
 
}
};
box.addValueListener(listener);
dateEnd.addValueListener(listener);
dateDeb.addValueListener(listener);
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/JournauxAnalytiqueSheetXML.java
New file
0,0 → 1,210
/*
* 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.finance.accounting.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.sql.Configuration;
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.GestionDevise;
import org.openconcerto.utils.cc.ITransformer;
 
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class JournauxAnalytiqueSheetXML extends AbstractListeSheetXml {
 
private final static SQLTable tableEcriture = base.getTable("ECRITURE");
protected final static SQLTable tableJournal = base.getTable("JOURNAL");
protected final static SQLTable tableAssoc = base.getTable("ASSOCIATION_ANALYTIQUE");
protected final static SQLTable tablePoste = base.getTable("POSTE_ANALYTIQUE");
private final static SQLTable tableMvt = base.getTable("MOUVEMENT");
protected final static SQLTable tableCompte = base.getTable("COMPTE_PCE");
public final static int MODEALL = 1;
public final static int MODELETTREE = 2;
public final static int MODENONLETTREE = 3;
 
private final static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
private final static DateFormat dateFormatEcr = DateFormat.getDateInstance(DateFormat.SHORT);
protected Date dateDu, dateAu;
private SQLRow rowPoste;
 
public static String TEMPLATE_ID = "JournauxAnalytique";
public static String TEMPLATE_PROPERTY_NAME = "LocationJournaux";
 
private SQLRow rowSociete = ((ComptaPropsConfiguration) Configuration.getInstance()).getRowSociete();
 
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
@Override
public String getStoragePathP() {
return "Journaux";
}
 
Date date;
 
@Override
public String getName() {
if (this.date == null) {
this.date = new Date();
}
return "JournalAnalytique" + date.getTime();
}
 
public JournauxAnalytiqueSheetXML(Date du, Date au, SQLRow rowPoste) {
super();
Calendar cal = Calendar.getInstance();
cal.setTime(au);
this.printer = PrinterNXProps.getInstance().getStringProperty("JournauxPrinter");
this.dateAu = au;
this.dateDu = du;
this.rowPoste = rowPoste;
}
 
protected void makeEntete(Map<String, Object> line, String nomJournal) {
line.put("TITRE_1", "JournalAnalytique " + nomJournal + " - " + rowSociete.getObject("TYPE") + " " + rowSociete.getObject("NOM"));
line.put("TITRE_2", "Edition du " + dateFormat.format(new Date()) + " Période du " + dateFormatEcr.format(this.dateDu) + " au " + dateFormatEcr.format(this.dateAu));
}
 
protected void createListeValues() {
 
final SQLRowValues vals = new SQLRowValues(tableEcriture);
 
vals.put("ID_JOURNAL", null);
vals.put("ID_COMPTE_PCE", null);
vals.put("COMPTE_NUMERO", null);
vals.put("COMPTE_NOM", null);
vals.put("JOURNAL_CODE", null);
vals.put("JOURNAL_NOM", null);
vals.putRowValues("ID_MOUVEMENT").put("NUMERO", null);
 
vals.put("CREDIT", null);
vals.put("DEBIT", null);
vals.put("DATE", null);
vals.put("NOM", null);
 
final SQLRowValues valsAnalytique = new SQLRowValues(tableAssoc);
valsAnalytique.put("ID_ECRITURE", vals);
valsAnalytique.putRowValues("ID_POSTE_ANALYTIQUE").put("NOM", null);
valsAnalytique.put("POURCENT", null);
valsAnalytique.put("MONTANT", null);
valsAnalytique.put("ID_ECRITURE", vals);
 
final SQLRowValuesListFetcher fetcher = new SQLRowValuesListFetcher(valsAnalytique);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
@Override
public SQLSelect transformChecked(SQLSelect sel) {
 
Where w = (new Where(sel.getJoinFromField(tableAssoc.getField("ID_ECRITURE")).getJoinedTable().getField("DATE"), JournauxAnalytiqueSheetXML.this.dateDu,
JournauxAnalytiqueSheetXML.this.dateAu));
 
// if (rowPoste != null && !rowPoste.isUndefined()) {
 
w = w.and(new Where(tableAssoc.getField("ID_POSTE_ANALYTIQUE"), "=", rowPoste.getID()));
// }
 
sel.setWhere(w);
sel.addFieldOrder(tableAssoc.getField("ID_POSTE_ANALYTIQUE"));
sel.addFieldOrder(sel.getJoinFromField(tableAssoc.getField("ID_ECRITURE")).getJoinedTable().getField("COMPTE_NUMERO"));
 
return sel;
}
});
 
List<SQLRowValues> list = fetcher.fetch();
 
System.err.println("START CREATE JOURNAUX, NB ecritures " + list.size());
 
long totalDebit, totalCredit;
 
totalDebit = 0;
totalCredit = 0;
int prevIdMvt = 0;
 
String firstJournal = rowPoste.getString("NOM");
 
List<Map<String, Object>> tableauVals = new ArrayList<Map<String, Object>>();
this.listAllSheetValues.put(0, tableauVals);
 
Map<Integer, String> style = new HashMap<Integer, String>();
this.styleAllSheetValues.put(0, style);
 
for (int i = 0; i < list.size(); i++) {
 
Map<String, Object> values = new HashMap<String, Object>();
 
SQLRowValues rowValsAnalytique = list.get(i);
SQLRowAccessor rowEcr = rowValsAnalytique.getForeign("ID_ECRITURE");
 
SQLRowAccessor rowMvt = rowEcr.getForeign("ID_MOUVEMENT");
 
// si on change de mouvement alors on applique le style Titre 1
if (prevIdMvt != rowMvt.getID()) {
prevIdMvt = rowMvt.getID();
style.put(tableauVals.size(), "Titre 1");
} else {
style.put(tableauVals.size(), "Normal");
}
values.put("DATE", dateFormatEcr.format(rowEcr.getDate("DATE").getTime()));
 
values.put("NUMERO_COMPTE", rowEcr.getString("COMPTE_NUMERO"));
 
values.put("NUMERO_MOUVEMENT", rowMvt.getObject("NUMERO"));
Object libelle = rowEcr.getObject("NOM");
values.put("LIBELLE", libelle);
 
long l = rowValsAnalytique.getLong("MONTANT");
 
long deb = (l > 0 ? l : 0);
long cred = (l < 0 ? -l : 0);
 
long solde = deb - cred;
 
totalCredit += cred;
totalDebit += deb;
 
values.put("DEBIT", (deb == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(deb, false)));
values.put("CREDIT", (cred == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(cred, false)));
values.put("SOLDE", (solde == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(solde, false)));
 
tableauVals.add(values);
 
}
 
Map<String, Object> sheetVals = new HashMap<String, Object>();
this.mapAllSheetValues.put(0, sheetVals);
 
makeEntete(sheetVals, firstJournal);
 
sheetVals.put("TOTAL_DEBIT", (totalDebit == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(totalDebit, false)));
sheetVals.put("TOTAL_CREDIT", (totalCredit == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(totalCredit, false)));
sheetVals.put("TOTAL_SOLDE", (totalDebit - totalCredit == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(totalDebit - totalCredit, false)));
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/Map2033A.java
17,9 → 17,10
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.core.finance.accounting.model.SommeCompte;
import org.openconcerto.erp.preferences.TemplateNXProps;
import org.openconcerto.map.model.Ville;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.GestionDevise;
 
import java.io.File;
30,7 → 31,6
import java.util.HashMap;
import java.util.Map;
 
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
 
152,7 → 152,7
// 030 -SommeSolde( 281, 289* )-SommeSolde( 290, 295* )
// RacineDap = "2810-2815, 2818, 2930-2931, 291"
// S030=-2811-2812-2911-2813-2814-2815-2818-282-292-2931
long v030 = -(this.sommeCompte.soldeCompte(2811, 2815, true, this.dateDebut, this.dateFin)) - this.sommeCompte.sommeCompteFils("2818", this.dateDebut, this.dateFin)
long v030 = -(this.sommeCompte.soldeCompte(2810, 2815, true, this.dateDebut, this.dateFin)) - this.sommeCompte.sommeCompteFils("2818", this.dateDebut, this.dateFin)
- (this.sommeCompte.soldeCompte(2931, 2931, true, this.dateDebut, this.dateFin)) - this.sommeCompte.sommeCompteFils("2911", this.dateDebut, this.dateFin);
this.m.put("ACTIF2.2", GestionDevise.currencyToString(v030, false));
 
286,7 → 286,7
this.m.put("ACTIF2.7", "");
 
// 065
long v065 = 0;
long v065 = v064;
this.m.put("ACTIF3.7", GestionDevise.currencyToString(v064, false));
 
// 067
339,7 → 339,8
// 4566d-4567d, 458d, 462,
// 465, 467d, 4680d, 4687, 471d-475d, 478d"
// S072=4096(D)+4097(D)+4098(D)+40(D)...401+40A(D)...40Z+42(D)..47
long v072 = this.sommeCompte.soldeCompteDebiteur(400, 408, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompte(4096, 4098, true, this.dateDebut, this.dateFin)
long v072 = this.sommeCompte.soldeCompteDebiteur(4455, 4455, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(421, 421, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteDebiteur(400, 408, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompte(4096, 4098, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.sommeCompteFils("425", this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("4287", this.dateDebut, this.dateFin)
+ this.sommeCompte.sommeCompteFils("4374", this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("4387", this.dateDebut, this.dateFin)
+ this.sommeCompte.sommeCompteFils("441", this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(443, 444, true, this.dateDebut, this.dateFin)
400,7 → 401,7
// S084=511+512(D)...517+5187+54+58(D)+53
long v084 = this.sommeCompte.soldeCompteDebiteur(510, 517, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(5180, 5185, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteDebiteur(5187, 5189, true, this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("54", this.dateDebut, this.dateFin)
+ this.sommeCompte.sommeCompteFils("53", this.dateDebut, this.dateFin);
+ this.sommeCompte.sommeCompteFils("53", this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("58", this.dateDebut, this.dateFin);
 
this.m.put("ACTIF1.11", GestionDevise.currencyToString(v084, false));
 
459,7 → 460,7
this.m.put("ACTIF2.13", GestionDevise.currencyToString(v098, false));
 
// 097 051+061+065+069+073+081+085+093
long v097 = v051 + v061 + v069 + v073 + v081 + v085 + v093;
long v097 = v051 + v061 + +v065 + v069 + v073 + v081 + v085 + v093;
this.m.put("ACTIF3.13", GestionDevise.currencyToString(v097, false));
 
// 099
674,12 → 675,13
* this.sommeCompte.sommeCompteFils("5186") ;
*/
long v156 = -this.sommeCompte.sommeCompteFils("161", this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(163, 166, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(1680, 1680, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(1682, 1682, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(1680, 1681, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(1682, 1682, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(1684, 1689, true, this.dateDebut, this.dateFin) - this.sommeCompte.sommeCompteFils("17", this.dateDebut, this.dateFin)
- this.sommeCompte.sommeCompteFils("426", this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(450, 456, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(458, 459, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(512, 512, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(514, 514, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(517, 517, true, this.dateDebut, this.dateFin)
- this.sommeCompte.sommeCompteFils("5186", this.dateDebut, this.dateFin) - this.sommeCompte.sommeCompteFils("519", this.dateDebut, this.dateFin);
- this.sommeCompte.sommeCompteFils("426", this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(450, 454, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(456, 456, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(458, 459, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(512, 512, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(514, 514, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(517, 517, true, this.dateDebut, this.dateFin) - this.sommeCompte.sommeCompteFils("5186", this.dateDebut, this.dateFin)
- this.sommeCompte.sommeCompteFils("519", this.dateDebut, this.dateFin);
this.m.put("PASSIF3.25", GestionDevise.currencyToString(v156, false));
 
// 151
786,11 → 788,12
+ this.sommeCompte.soldeCompteCrediteur(444, 444, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(4455, 4455, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(44586, 44586, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(4457, 4457, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(44584, 44584, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(44587, 44587, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(446, 447, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(4482, 4482, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(4486, 4486, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(457, 457, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(269, 269, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(279, 279, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(404, 405, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(4084, 4084, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(4088, 4088, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(4196, 4198, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(455, 455, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(446, 447, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(4482, 4482, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(4486, 4486, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(457, 457, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(269, 269, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(279, 279, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(404, 405, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(4084, 4084, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompte(4088, 4088, true, this.dateDebut, this.dateFin)
- this.sommeCompte.soldeCompte(4196, 4198, true, this.dateDebut, this.dateFin)
 
- this.sommeCompte.soldeCompte(464, 464, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(467, 467, true, this.dateDebut, this.dateFin)
+ this.sommeCompte.soldeCompteCrediteur(4686, 4686, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(478, 478, true, this.dateDebut, this.dateFin)
851,6 → 854,7
this.m.put("PASSIF4.32", "");
this.m.put("PASSIF4.33", "");
this.m.put("PASSIF4.34", "");
 
p.generateFrom(this.m);
 
SwingUtilities.invokeLater(new Runnable() {
890,6 → 894,7
this.dateDebut = dateDeb;
this.dateFin = dateFin;
this.sommeCompte = new SommeCompte(posteAnalytique);
 
}
 
public Map2033A(JProgressBar bar) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/JournauxMoisSheet.java
48,11 → 48,11
this.mapStyleRow = new HashMap();
String schema = ((ComptaPropsConfiguration) Configuration.getInstance()).getSocieteBaseName();
 
String select = "SELECT SUM(\"DEBIT\"), SUM(\"CREDIT\"), date_part('month', \"DATE\"), date_part('year', \"DATE\"),\"JOURNAL\".\"ID\" FROM \"" + schema + "\".\"ECRITURE\" , \"" + schema
String select = "SELECT SUM(\"DEBIT\"), SUM(\"CREDIT\"), EXTRACT(MONTH FROM \"DATE\"), EXTRACT(YEAR FROM \"DATE\"),\"JOURNAL\".\"ID\" FROM \"" + schema + "\".\"ECRITURE\" , \"" + schema
+ "\".\"JOURNAL\" ";
 
String groupBy = " GROUP BY date_part('year', \"DATE\"), date_part('month', \"DATE\"),\"JOURNAL\".\"ID\"";
String orderBy = " ORDER BY \"JOURNAL\".\"ID\",date_part('year', \"DATE\"), date_part('month', \"DATE\")";
String groupBy = " GROUP BY EXTRACT(YEAR FROM \"DATE\"), EXTRACT(MONTH FROM \"DATE\"),\"JOURNAL\".\"ID\"";
String orderBy = " ORDER BY \"JOURNAL\".\"ID\",EXTRACT(YEAR FROM \"DATE\"), EXTRACT(MONTH FROM \"DATE\")";
if (this.idS != null && this.idS.length > 0) {
select += " WHERE";
for (int i = 0; i < this.idS.length; i++) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/action/ListeDesEcrituresAnalytiquesAction.java
New file
0,0 → 1,104
/*
* 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.finance.accounting.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.ui.IListFilterDatePanel;
import org.openconcerto.erp.core.common.ui.IListTotalPanel;
import org.openconcerto.erp.core.common.ui.ListeViewPanel;
import org.openconcerto.erp.core.common.ui.PanelFrame;
import org.openconcerto.erp.core.finance.accounting.ui.AssociationAnalytiquePanel;
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.view.IListFrame;
import org.openconcerto.sql.view.list.SQLTableModelColumn;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.Tuple2;
 
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
 
public class ListeDesEcrituresAnalytiquesAction extends CreateFrameAbstractAction {
 
public ListeDesEcrituresAnalytiquesAction() {
super();
this.putValue(Action.NAME, "Liste des écritures analytiques");
}
 
public JFrame createFrame() {
 
final SQLElement analytique = Configuration.getInstance().getDirectory().getElement("ASSOCIATION_ANALYTIQUE");
 
final ListeViewPanel panel = new ListeViewPanel(analytique) {
 
@Override
protected GridBagConstraints createConstraints() {
GridBagConstraints c = super.createConstraints();
c.gridwidth = 2;
return c;
}
 
@Override
protected void handleAction(JButton source, ActionEvent evt) {
if (source == this.buttonModifier) {
 
PanelFrame frameAssoc = new PanelFrame(new AssociationAnalytiquePanel(getListe().getSelectedRow().getForeign("ID_ECRITURE").asRow()), "Association analytique");
frameAssoc.setVisible(true);
}
}
};
panel.setTextButton("Gérer");
final IListFrame frame = new IListFrame(panel);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getPanel().setSearchFullMode(true);
 
GridBagConstraints c = new DefaultGridBagConstraints();
c.gridy = 4;
c.gridx = 0;
c.gridwidth = 1;
c.weightx = 1;
 
SQLRow rowExercice = Configuration.getInstance().getBase().getTable("EXERCICE_COMMON").getRow(ComptaPropsConfiguration.getInstanceCompta().getRowSociete().getInt("ID_EXERCICE_COMMON"));
 
final SQLTable ecritureTable = analytique.getTable().getForeignTable("ID_ECRITURE");
final IListFilterDatePanel comp = new IListFilterDatePanel(frame.getPanel().getListe(), ecritureTable.getField("DATE"), IListFilterDatePanel.getDefaultMap());
comp.setDateDu((Date) rowExercice.getObject("DATE_DEB"));
c.weightx = 1;
frame.getPanel().add(comp, c);
 
List<Tuple2<? extends SQLTableModelColumn, IListTotalPanel.Type>> fields = new ArrayList<Tuple2<? extends SQLTableModelColumn, IListTotalPanel.Type>>(2);
List<SQLTableModelColumn> l = frame.getPanel().getListe().getSource().getColumns();
fields.add(Tuple2.create(l.get(l.size() - 2), IListTotalPanel.Type.SOMME));
fields.add(Tuple2.create(l.get(l.size() - 1), IListTotalPanel.Type.SOMME));
// fields.add(eltCmd.getTable().getField("T_TTC"));
IListTotalPanel comp2 = new IListTotalPanel(frame.getPanel().getListe(), fields, null, "Total");
 
c.gridx++;
c.weightx = 0;
frame.getPanel().add(comp2, c);
 
return frame;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/action/ListeDesEcrituresAction.java
20,6 → 20,7
import org.openconcerto.erp.core.common.ui.PanelFrame;
import org.openconcerto.erp.core.finance.accounting.element.EcritureSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
import org.openconcerto.erp.core.finance.accounting.ui.AssociationAnalytiquePanel;
import org.openconcerto.erp.core.finance.accounting.ui.SuppressionEcrituresPanel;
import org.openconcerto.erp.rights.ComptaUserRight;
import org.openconcerto.sql.Configuration;
156,6 → 157,13
}
});
 
menuDroit.add(new AbstractAction("Gérer l'analytique") {
public void actionPerformed(ActionEvent event) {
PanelFrame frameAssoc = new PanelFrame(new AssociationAnalytiquePanel(frame.getPanel().getListe().getSelectedRow().asRow()), "Association analytique");
frameAssoc.setVisible(true);
}
});
 
menuDroit.add(new AbstractAction("Voir la source") {
public void actionPerformed(ActionEvent event) {
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/action/ImpressionJournauxAnalytiqueAction.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.finance.accounting.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.core.common.ui.PanelFrame;
import org.openconcerto.erp.core.finance.accounting.report.VentilationAnalytiquePanel;
 
import javax.swing.Action;
import javax.swing.JFrame;
 
public class ImpressionJournauxAnalytiqueAction extends CreateFrameAbstractAction {
 
public ImpressionJournauxAnalytiqueAction() {
super();
this.putValue(Action.NAME, "Ventilation Analytique par poste...");
}
 
@Override
public JFrame createFrame() {
return new PanelFrame(new VentilationAnalytiquePanel(), "Impression de la ventilation analytique");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/action/ListeDesDevisesAction.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.finance.accounting.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
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 ListeDesDevisesAction extends CreateFrameAbstractAction {
 
public ListeDesDevisesAction() {
super();
this.putValue(Action.NAME, "Liste des devises");
}
 
public JFrame createFrame() {
return new IListFrame(new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("DEVISE")));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/DeviseKmRowValuesRenderer.java
38,10 → 38,9
}
 
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
 
if (value.getClass() == Long.class) {
if (value != null && value.getClass() == Long.class) {
this.setText(GestionDevise.currencyToString(((Long) value).longValue()));
this.setHorizontalAlignment(SwingConstants.RIGHT);
}
58,11 → 57,6
TableCellRendererUtils.setColors(this, table, isSelected);
}
 
// TableCellEditor cellEditor = table.getColumnModel().getColumn(column).getCellEditor();
// cellEditor.addCellEditorListener(this);
//
// jumpToNextEditCell(table, hasFocus, isSelected, row, column);
 
return this;
}
 
78,15 → 72,4
}
}
 
// @Override
// public void editingCanceled(ChangeEvent e) {
// // TODO Auto-generated method stub
//
// }
//
// @Override
// public void editingStopped(ChangeEvent e) {
// // TODO Auto-generated method stub
// setEditingMode(true);
// }
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/AssociationAnalytiqueItemModel.java
New file
0,0 → 1,103
/*
* 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.finance.accounting.ui;
 
import org.openconcerto.erp.core.common.ui.DeviseCellEditor;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.view.list.CellDynamicModifier;
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableControlPanel;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.List;
import java.util.Vector;
 
import javax.swing.JScrollPane;
import javax.swing.ToolTipManager;
 
public class AssociationAnalytiqueItemModel {
 
private final DeviseKmRowValuesRenderer deviseRenderer = new DeviseKmRowValuesRenderer();
private final DeviseCellEditor deviseCellEditor = new DeviseCellEditor();
 
RowValuesTableModel model;
 
public AssociationAnalytiqueItemModel() {
 
final SQLElement elt = Configuration.getInstance().getDirectory().getElement("ASSOCIATION_ANALYTIQUE");
 
final List<SQLTableElement> list = new Vector<SQLTableElement>();
final SQLTable tableElement = elt.getTable();
 
final SQLTableElement tableElementNomCompte = new SQLTableElement(tableElement.getField("ID_POSTE_ANALYTIQUE"));
list.add(tableElementNomCompte);
 
final SQLTableElement tableElementPourcent = new SQLTableElement(tableElement.getField("POURCENT"));
list.add(tableElementPourcent);
 
final SQLTableElement tableElementMontant = new SQLTableElement(tableElement.getField("MONTANT"), Long.class, this.deviseCellEditor);
list.add(tableElementMontant);
 
this.model = new RowValuesTableModel(elt, list, tableElement.getField("ID_POSTE_ANALYTIQUE"), false);
 
tableElementMontant.addModificationListener(tableElementPourcent);
tableElementPourcent.setModifier(new CellDynamicModifier() {
@Override
public Object computeValueFrom(SQLRowValues row) {
long montant = row.getLong("MONTANT");
 
long total = row.getForeign("ID_ECRITURE").getLong("DEBIT") - row.getForeign("ID_ECRITURE").getLong("CREDIT");
 
BigDecimal pourcent = new BigDecimal(montant).divide(new BigDecimal(total), MathContext.DECIMAL128).abs().movePointRight(2)
.setScale(tableElementPourcent.getDecimalDigits(), RoundingMode.HALF_UP);
return pourcent;
}
 
});
 
tableElementPourcent.addModificationListener(tableElementMontant);
tableElementMontant.setModifier(new CellDynamicModifier() {
@Override
public Object computeValueFrom(SQLRowValues row) {
BigDecimal percent = row.getBigDecimal("POURCENT");
 
long total = row.getForeign("ID_ECRITURE").getLong("DEBIT") - row.getForeign("ID_ECRITURE").getLong("CREDIT");
 
BigDecimal montant = percent.movePointLeft(2).multiply(new BigDecimal(total)).setScale(0, RoundingMode.HALF_UP);
 
return montant.longValue();
}
 
});
 
tableElementMontant.setRenderer(this.deviseRenderer);
 
}
 
public RowValuesTableModel getModel() {
return this.model;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/AnalytiqueItemTable.java
New file
0,0 → 1,130
/*
* 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.finance.accounting.ui;
 
import org.openconcerto.erp.core.common.ui.DeviseCellEditor;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.view.list.CellDynamicModifier;
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableControlPanel;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.List;
import java.util.Vector;
 
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ToolTipManager;
 
public class AnalytiqueItemTable extends JPanel {
 
private final RowValuesTable table;
private final DeviseKmRowValuesRenderer deviseRenderer = new DeviseKmRowValuesRenderer();
private final DeviseCellEditor deviseCellEditor = new DeviseCellEditor();
 
public AnalytiqueItemTable() {
setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
c.weightx = 1;
 
final SQLElement elt = Configuration.getInstance().getDirectory().getElement("ASSOCIATION_ANALYTIQUE");
 
final List<SQLTableElement> list = new Vector<SQLTableElement>();
final SQLTable tableElement = elt.getTable();
 
final SQLTableElement tableElementNomCompte = new SQLTableElement(tableElement.getField("ID_POSTE_ANALYTIQUE"));
list.add(tableElementNomCompte);
 
final SQLTableElement tableElementPourcent = new SQLTableElement(tableElement.getField("POURCENT"));
list.add(tableElementPourcent);
 
final SQLTableElement tableElementMontant = new SQLTableElement(tableElement.getField("MONTANT"), Long.class, this.deviseCellEditor);
list.add(tableElementMontant);
 
final RowValuesTableModel model = new RowValuesTableModel(elt, list, tableElement.getField("ID_POSTE_ANALYTIQUE"), false);
 
this.table = new RowValuesTable(model, null);
ToolTipManager.sharedInstance().unregisterComponent(this.table);
ToolTipManager.sharedInstance().unregisterComponent(this.table.getTableHeader());
 
this.add(new RowValuesTableControlPanel(this.table), c);
 
tableElementMontant.addModificationListener(tableElementPourcent);
tableElementPourcent.setModifier(new CellDynamicModifier() {
@Override
public Object computeValueFrom(SQLRowValues row) {
long montant = row.getLong("MONTANT");
 
long total = row.getForeign("ID_ECRITURE").getLong("DEBIT") - row.getForeign("ID_ECRITURE").getLong("CREDIT");
 
BigDecimal pourcent = new BigDecimal(montant).divide(new BigDecimal(total), MathContext.DECIMAL128).abs().movePointRight(2)
.setScale(tableElementPourcent.getDecimalDigits(), RoundingMode.HALF_UP);
return pourcent;
}
 
});
 
tableElementPourcent.addModificationListener(tableElementMontant);
tableElementMontant.setModifier(new CellDynamicModifier() {
@Override
public Object computeValueFrom(SQLRowValues row) {
BigDecimal percent = row.getBigDecimal("POURCENT");
 
long total = row.getForeign("ID_ECRITURE").getLong("DEBIT") - row.getForeign("ID_ECRITURE").getLong("CREDIT");
 
BigDecimal montant = percent.movePointLeft(2).multiply(new BigDecimal(total)).setScale(0, RoundingMode.HALF_UP);
 
return montant.longValue();
}
 
});
 
c.gridy++;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
this.add(new JScrollPane(this.table), c);
 
tableElementMontant.setRenderer(this.deviseRenderer);
 
}
 
public void updateField(final String field, final int id) {
this.table.updateField(field, id);
}
 
public void insertFrom(final String field, final int id) {
this.table.insertFrom(field, id);
}
 
public void insertFrom(final SQLRowAccessor row) {
this.table.insertFrom(row);
}
 
public RowValuesTableModel getModel() {
return this.table.getRowValuesTableModel();
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/AssociationAnalytiqueTable.java
58,10 → 58,13
 
final List<SQLTableElement> list = new ArrayList<SQLTableElement>();
 
final SQLTableElement tableElementAnalytique = new SQLTableElement(ELEMENT.getTable().getField("ID_POSTE_ANALYTIQUE"));
list.add(tableElementAnalytique);
// final SQLTableElement tableElementAnalytique = new
// SQLTableElement(ELEMENT.getTable().getField("ID_POSTE_ANALYTIQUE"));
// list.add(tableElementAnalytique);
 
final RowValuesTableModel model = new RowValuesTableModel(ELEMENT, list, ELEMENT.getTable().getField("ID_POSTE_ANALYTIQUE"), true, defaultRow);
// final RowValuesTableModel model = new RowValuesTableModel(ELEMENT, list,
// ELEMENT.getTable().getField("ID_POSTE_ANALYTIQUE"), true, defaultRow);
final RowValuesTableModel model = new AssociationAnalytiqueItemModel().getModel();
 
this.table = new RowValuesMultiLineEditTable(model, null, "ANALYTIQUE") {
@Override
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/BalanceCellRenderer.java
20,7 → 20,6
 
import javax.swing.JTable;
 
 
public class BalanceCellRenderer extends CompteCellRenderer {
 
private int colNumeroCompte;
31,11 → 30,11
 
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
 
String numeroCompte = table.getValueAt(row, this.colNumeroCompte).toString();
String numeroCompte = table.getValueAt(row, this.colNumeroCompte).toString().trim();
String numeroCompteSuiv = null;
 
if (row < table.getRowCount() - 1) {
numeroCompteSuiv = table.getValueAt(row + 1, this.colNumeroCompte).toString();
numeroCompteSuiv = table.getValueAt(row + 1, this.colNumeroCompte).toString().trim();
}
 
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
42,23 → 41,18
 
if (!isSelected) {
// si le numéro compte est composé d'un seul chiffre
if (numeroCompte.trim().length() == 1) {
final int length = numeroCompte.length();
if (length == 1) {
this.setBackground(couleurCompteClasse);
this.setForeground(Color.BLACK);
} else {
 
} else if ((numeroCompteSuiv != null) && (length < numeroCompteSuiv.length()) && (numeroCompte.equalsIgnoreCase(numeroCompteSuiv.substring(0, length)))) {
// si le compte est racine
if ((numeroCompteSuiv != null) && (numeroCompte.trim().length() < numeroCompteSuiv.trim().length())
&& (numeroCompte.trim().equalsIgnoreCase(numeroCompteSuiv.trim().substring(0, numeroCompte.length())))) {
 
// on affiche le numero et le libellé pas le reste
// compte racine à 2 chiffres
if (numeroCompte.trim().length() == 2) {
if (length == 2) { // compte racine à 2 chiffres
this.setBackground(couleurCompte2);
this.setForeground(Color.BLACK);
} else {
} else if (length == 3) {
// compte racine à 3 chiffres
if (numeroCompte.trim().length() == 3) {
this.setBackground(couleurCompte3);
this.setForeground(Color.BLACK);
} else {
66,17 → 60,15
this.setBackground(couleurCompteRacine);
this.setForeground(Color.BLACK);
}
}
 
} else {
// compte normaux
this.setBackground(Color.WHITE);
this.setForeground(Color.BLACK);
}
 
}
}
 
if (value.getClass() == Long.class) {
if (value != null && value.getClass() == Long.class) {
this.setText(GestionDevise.currencyToString(((Long) value).longValue()));
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/ComptaPrefTreeNode.java
26,6 → 26,7
import org.openconcerto.erp.preferences.GenerationDocumentGestCommPreferencePanel;
import org.openconcerto.erp.preferences.GenerationDocumentPayePreferencePanel;
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
import org.openconcerto.erp.preferences.GestionCommercialeGlobalPreferencePanel;
import org.openconcerto.erp.preferences.GestionPieceCommercialePanel;
import org.openconcerto.erp.preferences.ImpressionGestCommPreferencePanel;
import org.openconcerto.erp.preferences.ModeReglementDefautPrefPanel;
111,8 → 112,8
nsGlobale.add(nNum);
 
nsGlobale.add(new PrefTreeNode(GestionArticleGlobalPreferencePanel.class, "Gestion des articles", new String[] { "articles", "stock" }));
 
nsGlobale.add(new PrefTreeNode(GenerationDocGlobalPreferencePanel.class, "Génération des Documents", new String[] { "documents" }));
nsGlobale.add(new PrefTreeNode(GestionCommercialeGlobalPreferencePanel.class, "Gestion des piéces commericales", new String[] { "transfert", "numéro" }));
 
// Impression
final PrefTreeNode nPrint = new PrefTreeNode(EmptyPreferencePanel.class, "Impression", new String[] { "Impressions" });
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/AssociationAnalytiquePanel.java
New file
0,0 → 1,133
/*
* 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.finance.accounting.ui;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.sqlobject.SQLRequestComboBox;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.utils.GestionDevise;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
 
public class AssociationAnalytiquePanel extends JPanel {
 
public AssociationAnalytiquePanel(final SQLRowAccessor rowEcr) {
super(new GridBagLayout());
 
final long debit = rowEcr.getObject("DEBIT") == null ? 0 : rowEcr.getLong("DEBIT");
final long credit = rowEcr.getObject("CREDIT") == null ? 0 : rowEcr.getLong("CREDIT");
final long solde = debit - credit;
 
final GridBagConstraints c = new DefaultGridBagConstraints();
final AnalytiqueItemTable table = new AnalytiqueItemTable();
final SQLRequestComboBox box = new SQLRequestComboBox();
box.uiInit(Configuration.getInstance().getDirectory().getElement("ECRITURE").getComboRequest());
box.setEnabled(false);
box.setValue(rowEcr);
 
c.weightx = 0;
this.add(new JLabel("Ecriture associée"), c);
c.weightx = 1;
c.gridx++;
this.add(box, c);
c.gridwidth = 2;
c.gridx = 0;
c.gridy++;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
this.add(table, c);
 
final JLabel labelTotal = new JLabelBold("Total réparti : 0/" + solde);
c.fill = GridBagConstraints.NONE;
c.weightx = 0;
c.weighty = 0;
c.gridwidth = 1;
c.gridy++;
c.gridx = 1;
c.anchor = GridBagConstraints.EAST;
this.add(labelTotal, c);
 
table.insertFrom("ID_ECRITURE", rowEcr.getID());
 
c.fill = GridBagConstraints.NONE;
c.weightx = 0;
c.weighty = 0;
c.gridwidth = 1;
c.gridy++;
c.gridx = 1;
c.anchor = GridBagConstraints.EAST;
final JButton buttonApply = new JButton("Enregistrer les modifications");
JButton buttonClose = new JButton("Annuler");
JPanel panelButton = new JPanel();
panelButton.add(buttonApply);
panelButton.add(buttonClose);
this.add(panelButton, c);
 
buttonClose.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
((JFrame) SwingUtilities.getRoot(AssociationAnalytiquePanel.this)).dispose();
 
}
});
buttonApply.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
table.updateField("ID_ECRITURE", rowEcr.getID());
((JFrame) SwingUtilities.getRoot(AssociationAnalytiquePanel.this)).dispose();
}
});
 
final RowValuesTableModel model = table.getModel();
model.addTableModelListener(new TableModelListener() {
 
@Override
public void tableChanged(TableModelEvent e) {
 
final int count = model.getRowCount();
long soldeRows = 0;
for (int i = 0; i < count; i++) {
SQLRowValues rowVals = model.getRowValuesAt(i);
soldeRows += rowVals.getLong("MONTANT");
}
buttonApply.setEnabled(soldeRows == solde);
if (!buttonApply.isEnabled()) {
buttonApply.setToolTipText("La répartition analytique de l'écriture n'est pas totale!");
} else {
buttonApply.setToolTipText(null);
}
labelTotal.setText("Répartition totale : " + GestionDevise.currencyToString(soldeRows) + "/" + GestionDevise.currencyToString(solde));
}
});
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/ui/ChequeListPanel.java
13,16 → 13,11
package org.openconcerto.erp.core.finance.payment.ui;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
import org.openconcerto.erp.core.finance.payment.element.ChequeType;
import org.openconcerto.erp.model.GestionChequesModel;
import org.openconcerto.erp.rights.ComptaTotalUserRight;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.IListe;
40,7 → 35,6
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.sql.SQLException;
import java.util.Date;
 
import javax.swing.AbstractAction;
47,7 → 41,6
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.text.JTextComponent;
 
218,50 → 211,17
getListe().addRowAction(actionSource);
getListe().addIListeAction(new PredicateRowAction(new AbstractAction("Sélectionner tout") {
public void actionPerformed(ActionEvent e) {
 
ChequeListPanel.this.model.selectionDecaisseAll();
}
}, false, true).setPredicate(IPredicate.truePredicate()));
getListe().addIListeAction(new PredicateRowAction(new AbstractAction("Désélectionner tout") {
public void actionPerformed(ActionEvent e) {
 
ChequeListPanel.this.model.deselectionAll();
}
}, false, true).setPredicate(IPredicate.truePredicate()));
 
if (UserManager.getInstance().getCurrentUser().getRights().haveRight(ComptaTotalUserRight.MENU)) {
 
getListe().addRowAction(new AbstractAction("Régularisation en comptabilité") {
 
public void actionPerformed(ActionEvent e) {
final SQLRow rowCheque = IListe.get(e).fetchSelectedRow();
 
String price = GestionDevise.currencyToString(rowCheque.getLong("MONTANT"));
SQLRow rowClient = rowCheque.getForeignRow("ID_CLIENT");
String nomClient = rowClient.getString("NOM");
String piece = "";
SQLRow rowMvt = rowCheque.getForeignRow("ID_MOUVEMENT");
if (rowMvt != null) {
SQLRow rowPiece = rowMvt.getForeignRow("ID_PIECE");
piece = rowPiece.getString("NOM");
}
int answer = JOptionPane.showConfirmDialog(ChequeListPanel.this, "Etes vous sûr de vouloir régulariser ce cheque de " + nomClient + " d'un montant de " + price
+ "€ avec une saisie au kilometre?\nNom de la piéce : " + piece + "\nAttention, cette opération est irréversible.");
if (answer == JOptionPane.YES_OPTION) {
 
SQLRowValues rowVals = rowCheque.asRowValues();
rowVals.put("REG_COMPTA", Boolean.TRUE);
try {
rowVals.commit();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
});
}
}
 
protected abstract String getDepositLabel();
 
/**
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/component/EncaisserMontantSQLComponent.java
13,6 → 13,7
package org.openconcerto.erp.core.finance.payment.component;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement;
216,6 → 217,7
rowVals.put("COMPTANT", Boolean.TRUE);
rowVals.put("AJOURS", 0);
rowVals.put("LENJOUR", 0);
rowVals.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
eltModeRegl.setValue(rowVals);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/component/ModeDeReglementSQLComponent.java
13,11 → 13,10
package org.openconcerto.erp.core.finance.payment.component;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Log;
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement;
import org.openconcerto.erp.model.BanqueModifiedListener;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBackgroundTableCache;
143,6 → 142,21
* SELECTION DU MODE DE REGLEMENT
******************************************************************************************/
this.comboA = new SQLTextCombo(false);
 
final GridBagConstraints cB = new DefaultGridBagConstraints();
this.panelBanque.setOpaque(false);
this.panelBanque.add(new JLabel(getLabelFor("ID_" + BanqueSQLElement.TABLENAME)), cB);
cB.weightx = 1;
cB.gridx++;
this.panelBanque.add(this.boxBanque, cB);
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(this.panelBanque, c);
 
c.gridwidth = 1;
c.weightx = 0;
c.fill = GridBagConstraints.NONE;
c.gridy++;
c.gridheight = 1;
this.add(new JLabel("Règlement par"), c);
156,6 → 170,7
// Mode de règlement
c.gridx++;
DefaultGridBagConstraints.lockMinimumSize(this.checkboxComptant);
this.checkboxComptant.setOpaque(false);
this.add(this.checkboxComptant, c);
 
// Infos sur le reglement, depend du type de reglement et du comptant oui/non
192,20 → 207,27
 
// Listeners
 
this.addSQLObject(this.boxBanque, "ID_" + BanqueSQLElement.TABLENAME);
this.boxBanque.setButtonsVisible(false);
this.boxBanque.setOpaque(false);
this.boxBanque.addModelListener("wantedID", new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent evt) {
final Integer i = ModeDeReglementSQLComponent.this.boxBanque.getWantedID();
final int value = (i == null) ? -1 : Integer.valueOf(i);
fireBanqueIdChange(value);
}
});
 
this.comboTypeReglement.addValueListener(new PropertyChangeListener() {
 
@Override
public void propertyChange(final PropertyChangeEvent evt) {
final Integer id = ModeDeReglementSQLComponent.this.comboTypeReglement.getValue();
// System.err.println("value changed to " + id);
if (id != null && id > 1) {
 
final SQLRow ligneTypeReg = SQLBackgroundTableCache.getInstance().getCacheForTable(getTable().getBase().getTable("TYPE_REGLEMENT")).getRowFromId(id);
 
setComponentModeEnabled(ligneTypeReg);
 
// setEcheanceEnabled(!ModeDeReglementNGSQLComponent.this.checkboxComptant.isSelected());
 
}
}
});
328,6 → 350,7
this.infosCheque.add(this.dateDepot, cCheque);
this.m.put(Mode.CHEQUE, this.infosCheque);
this.infosCheque.setVisible(false);
this.infosCheque.setOpaque(false);
DefaultGridBagConstraints.lockMinimumSize(this.infosCheque);
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/element/ChequeAEncaisserSQLElement.java
14,6 → 14,7
package org.openconcerto.erp.core.finance.payment.element;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.erp.generationDoc.gestcomm.ReleveChequeSheet;
import org.openconcerto.erp.generationEcritures.GenerationMvtReglementChequeClient;
49,6 → 50,7
 
l.add("ID_MOUVEMENT");
l.add("ID_CLIENT");
l.add("ID_" + BanqueSQLElement.TABLENAME);
l.add("DATE");
l.add("ETS");
l.add("NUMERO");
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/element/ReglerMontantSQLComponent.java
13,6 → 13,7
package org.openconcerto.erp.core.finance.payment.element;
 
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
import org.openconcerto.erp.core.finance.payment.ui.RegleMontantTable;
213,6 → 214,7
rowVals.put("COMPTANT", Boolean.TRUE);
rowVals.put("AJOURS", 0);
rowVals.put("LENJOUR", 0);
rowVals.put("ID_" + BanqueSQLElement.TABLENAME, rowModeRegl.getInt("ID_" + BanqueSQLElement.TABLENAME));
eltModeRegl.setValue(rowVals);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/element/EncaisserMontantSQLElement.java
28,11 → 28,17
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.model.graph.Path;
import org.openconcerto.sql.model.graph.PathBuilder;
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.CollectionUtils;
 
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/element/ChequeFournisseurSQLElement.java
96,6 → 96,11
// TYPE, NOM
l.add("ID_FOURNISSEUR");
l.add("ID_MOUVEMENT");
 
l.add("ETS");
l.add("NUMERO");
l.add("DATE");
 
l.add("DATE_ACHAT");
l.add(getMinDateFieldName());
l.add(getDoneFieldName());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/element/VariablePayeSQLElement.java
22,7 → 22,6
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.ConfSQLElement;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/report/FichePayeSheet.java
36,6 → 36,7
import java.util.List;
import java.util.Map;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
 
110,13 → 111,13
return;
}
final Component doc = ooConnexion.loadDocument(f, true);
 
Map<String, Object> map = new HashMap<String, Object>();
map.put("Name", PrinterNXProps.getInstance().getStringProperty("FichePayePrinter"));
doc.printDocument(map);
doc.close();
} catch (LinkageError e) {
JOptionPane.showMessageDialog(new JFrame(), "Merci d'installer OpenOffice ou LibreOffice");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
ExceptionHandler.handle("Impossible de charger le document OpenOffice", e);
}
133,6 → 134,8
return;
}
ooConnexion.loadDocument(f, false);
} catch (LinkageError e) {
JOptionPane.showMessageDialog(new JFrame(), "Merci d'installer OpenOffice ou LibreOffice");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/ui/EditionFichePayePanel.java
150,9 → 150,19
this.add(this.bar, c);
 
// Button
JButton buttonValid = new JButton("Valider");
JButton buttonFermer = new JButton("Fermer");
final JButton buttonValid = new JButton("Valider");
final JButton buttonFermer = new JButton("Fermer");
 
PropertyChangeListener dateListener = new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
buttonValid.setEnabled(dateDeb.getValue() != null && dateFin.getValue() != null && dateDeb.getValue().before(dateFin.getValue()));
}
};
dateDeb.addValueListener(dateListener);
dateFin.addValueListener(dateListener);
 
c.gridy++;
c.gridwidth = 1;
c.anchor = GridBagConstraints.EAST;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/panel/ListAnneeModel.java
40,6 → 40,7
sel.addSelect(tableObjectif.getField("ANNEE"));
sel.setWhere(new Where(tableObjectif.getField("ID_COMMERCIAL"), "=", idCommercial));
sel.setDistinct(true);
sel.addFieldOrder(sel.getAlias(tableObjectif.getField("ANNEE")));
 
List<Object[]> listAnnee = (List<Object[]>) Configuration.getInstance().getBase().getDataSource().executeA(sel.asString());
clear();
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/ui/BonDeLivraisonItemTable.java
15,7 → 15,6
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.ui.AbstractVenteArticleItemTable;
import org.openconcerto.erp.core.common.ui.DeviseNumericCellEditor;
import org.openconcerto.erp.core.common.ui.DeviseNumericHTConvertorCellEditor;
import org.openconcerto.erp.core.common.ui.DeviseTableCellRenderer;
import org.openconcerto.erp.core.common.ui.QteCellEditor;
304,6 → 303,8
 
SQLRowValues defautRow = new SQLRowValues(UndefinedRowValuesCache.getInstance().getDefaultRowValues(e.getTable()));
defautRow.put("ID_TAXE", TaxeCache.getCache().getFirstTaxe().getID());
defautRow.put("CODE", "");
defautRow.put("NOM", "");
model = new RowValuesTableModel(e, list, e.getTable().getField("NOM"), false, defautRow);
 
this.table = new RowValuesTable(model, getConfigurationFile());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/component/BonDeLivraisonSQLComponent.java
24,13 → 24,13
import org.openconcerto.erp.core.sales.shipment.element.BonDeLivraisonSQLElement;
import org.openconcerto.erp.core.sales.shipment.report.BonLivraisonXmlSheet;
import org.openconcerto.erp.core.sales.shipment.ui.BonDeLivraisonItemTable;
import org.openconcerto.erp.core.supplychain.stock.element.MouvementStockSQLElement;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater.Type;
import org.openconcerto.erp.core.supplychain.stock.element.StockLabel;
import org.openconcerto.erp.panel.PanelOOSQLComponent;
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
581,7 → 581,7
 
}
 
protected String getLibelleStock(SQLRow row, SQLRow rowElt) {
protected String getLibelleStock(SQLRowAccessor row, SQLRowAccessor rowElt) {
return "BL N°" + row.getString("NUMERO");
}
 
595,13 → 595,15
SQLPreferences prefs = new SQLPreferences(getTable().getDBRoot());
if (!prefs.getBoolean(GestionArticleGlobalPreferencePanel.STOCK_FACT, true)) {
 
MouvementStockSQLElement mvtStock = (MouvementStockSQLElement) Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
mvtStock.createMouvement(getTable().getRow(id), getTable().getTable("BON_DE_LIVRAISON_ELEMENT"), new StockLabel() {
SQLRow row = getTable().getRow(id);
StockItemsUpdater stockUpdater = new StockItemsUpdater(new StockLabel() {
@Override
public String getLabel(SQLRow rowOrigin, SQLRow rowElt) {
public String getLabel(SQLRowAccessor rowOrigin, SQLRowAccessor rowElt) {
return getLibelleStock(rowOrigin, rowElt);
}
}, false);
}, row, row.getReferentRows(getTable().getTable("BON_DE_LIVRAISON_ELEMENT")), Type.REAL_DELIVER);
 
stockUpdater.update();
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/credit/component/AvoirClientSQLComponent.java
17,6 → 17,7
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.component.SocieteCommonSQLElement;
import org.openconcerto.erp.core.common.component.TransfertBaseSQLComponent;
import org.openconcerto.erp.core.common.element.BanqueSQLElement;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.common.ui.AbstractArticleItemTable;
28,8 → 29,6
import org.openconcerto.erp.core.sales.credit.element.AvoirClientSQLElement;
import org.openconcerto.erp.core.sales.credit.ui.AvoirItemTable;
import org.openconcerto.erp.core.sales.invoice.component.SaisieVenteFactureSQLComponent;
import org.openconcerto.erp.core.supplychain.stock.element.MouvementStockSQLElement;
import org.openconcerto.erp.core.supplychain.stock.element.StockLabel;
import org.openconcerto.erp.generationDoc.gestcomm.AvoirClientXmlSheet;
import org.openconcerto.erp.generationEcritures.GenerationMvtAvoirClient;
import org.openconcerto.erp.model.ISQLCompteSelector;
691,7 → 690,7
 
rowVals2.update();
 
updateStock(id);
// updateStock(id);
 
GenerationMvtAvoirClient gen = new GenerationMvtAvoirClient(id);
gen.genereMouvement();
784,7 → 783,7
rowVals2.update();
 
// On met à jour le stock
updateStock(getSelectedID());
// updateStock(getSelectedID());
 
int idMvt = row.getInt("ID_MOUVEMENT");
 
811,27 → 810,30
}
}
 
protected String getLibelleStock(SQLRow row, SQLRow rowElt) {
return "Avoir client N°" + row.getString("NUMERO");
}
// Su^prression de la methode, retour de marchandise à gérer avec les Mouvements de stocks
// protected String getLibelleStock(SQLRowAccessor row, SQLRowAccessor rowElt) {
// return "Avoir client N°" + row.getString("NUMERO");
// }
//
// /**
// * Mise à jour des stocks pour chaque article composant la facture d'avoir
// *
// * @throws SQLException
// */
// private void updateStock(int id) throws SQLException {
//
// MouvementStockSQLElement mvtStock = (MouvementStockSQLElement)
// Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
// mvtStock.createMouvement(getTable().getRow(id), getTable().getTable("AVOIR_CLIENT_ELEMENT"),
// new StockLabel() {
// @Override
// public String getLabel(SQLRowAccessor rowOrigin, SQLRowAccessor rowElt) {
// return getLibelleStock(rowOrigin, rowElt);
// }
// }, true, true);
//
// }
 
/**
* Mise à jour des stocks pour chaque article composant la facture d'avoir
*
* @throws SQLException
*/
private void updateStock(int id) throws SQLException {
 
MouvementStockSQLElement mvtStock = (MouvementStockSQLElement) Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
mvtStock.createMouvement(getTable().getRow(id), getTable().getTable("AVOIR_CLIENT_ELEMENT"), new StockLabel() {
@Override
public String getLabel(SQLRow rowOrigin, SQLRow rowElt) {
return getLibelleStock(rowOrigin, rowElt);
}
}, true);
 
}
 
public void actionPerformed(ActionEvent e) {
if (e.getSource() == this.boxAdeduire) {
if (this.eltModeRegl != null) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/element/CommandeClientSQLElement.java
24,17 → 24,22
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.ListMap;
 
import java.math.BigDecimal;
import java.math.MathContext;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import org.apache.commons.dbutils.handlers.ArrayListHandler;
 
public class CommandeClientSQLElement extends ComptaSQLConfElement {
 
public CommandeClientSQLElement() {
85,6 → 90,27
}
 
@Override
protected void archive(SQLRow row, boolean cutLinks) throws SQLException {
super.archive(row, cutLinks);
// Mise à jour des stocks
SQLElement eltMvtStock = Configuration.getInstance().getDirectory().getElement("MOUVEMENT_STOCK");
SQLSelect sel = new SQLSelect();
sel.addSelect(eltMvtStock.getTable().getField("ID"));
Where w = new Where(eltMvtStock.getTable().getField("IDSOURCE"), "=", row.getID());
Where w2 = new Where(eltMvtStock.getTable().getField("SOURCE"), "=", getTable().getName());
sel.setWhere(w.and(w2));
 
@SuppressWarnings("rawtypes")
List l = (List) eltMvtStock.getTable().getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
if (l != null) {
for (int i = 0; i < l.size(); i++) {
Object[] tmp = (Object[]) l.get(i);
eltMvtStock.archive(((Number) tmp[0]).intValue());
}
}
}
 
@Override
protected SQLTableModelSourceOnline createTableSource() {
final SQLTableModelSourceOnline source = super.createTableSource();
// TODO: refaire un renderer pour les commandes transférées en BL
120,7 → 146,7
SQLElement eltArticle = Configuration.getInstance().getDirectory().getElement("ARTICLE");
SQLRow rowCmd = getTable().getRow(commandeID);
List<SQLRow> rows = rowCmd.getReferentRows(elt.getTable());
CollectionMap<SQLRow, List<SQLRowValues>> map = new CollectionMap<SQLRow, List<SQLRowValues>>();
final ListMap<SQLRow, SQLRowValues> map = new ListMap<SQLRow, SQLRowValues>();
for (SQLRow sqlRow : rows) {
// on récupére l'article qui lui correspond
SQLRowValues rowArticle = new SQLRowValues(eltArticle.getTable());
141,7 → 167,7
rowValsElt.put("T_PA_TTC",
((BigDecimal) rowValsElt.getObject("T_PA_HT")).multiply(new BigDecimal((rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0)), MathContext.DECIMAL128));
 
map.put(rowArticleFind.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
map.add(rowArticleFind.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
 
}
MouvementStockSQLElement.createCommandeF(map, rowCmd.getForeignRow("ID_TARIF").getForeignRow("ID_DEVISE"), rowCmd.getString("NUMERO") + " - " + rowCmd.getString("NOM"));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/component/CommandeClientSQLComponent.java
23,6 → 23,10
import org.openconcerto.erp.core.sales.order.element.CommandeClientSQLElement;
import org.openconcerto.erp.core.sales.order.report.CommandeClientXmlSheet;
import org.openconcerto.erp.core.sales.order.ui.CommandeClientItemTable;
import org.openconcerto.erp.core.supplychain.stock.element.MouvementStockSQLElement;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater;
import org.openconcerto.erp.core.supplychain.stock.element.StockItemsUpdater.Type;
import org.openconcerto.erp.core.supplychain.stock.element.StockLabel;
import org.openconcerto.erp.panel.PanelOOSQLComponent;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.sql.Configuration;
32,7 → 36,9
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
54,6 → 60,7
import java.beans.PropertyChangeListener;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
 
import javax.swing.JLabel;
import javax.swing.JOptionPane;
67,6 → 74,8
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
 
import org.apache.commons.dbutils.handlers.ArrayListHandler;
 
public class CommandeClientSQLComponent extends TransfertBaseSQLComponent {
 
private CommandeClientItemTable table;
409,7 → 418,11
 
idCommande = super.insert(order);
this.table.updateField("ID_COMMANDE_CLIENT", idCommande);
 
try {
updateStock(idCommande);
} catch (SQLException e1) {
ExceptionHandler.handle("Erreur lors de la mise à du stock!", e1);
}
// Création des articles
this.table.createArticle(idCommande, this.getElement());
// generation du document
486,13 → 499,20
return;
}
super.update();
this.table.updateField("ID_COMMANDE_CLIENT", getSelectedID());
this.table.createArticle(getSelectedID(), this.getElement());
final int id = getSelectedID();
this.table.updateField("ID_COMMANDE_CLIENT", id);
this.table.createArticle(id, this.getElement());
 
final SQLRow row = getTable().getRow(id);
try {
updateStock(id);
} catch (SQLException e1) {
ExceptionHandler.handle("Erreur lors de la mise à du stock!", e1);
}
 
// generation du document
 
try {
CommandeClientXmlSheet sheet = new CommandeClientXmlSheet(getTable().getRow(getSelectedID()));
CommandeClientXmlSheet sheet = new CommandeClientXmlSheet(row);
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(CommandeClientSQLComponent.this.panelOO.isVisualisationSelected(), CommandeClientSQLComponent.this.panelOO.isImpressionSelected(), true);
} catch (Exception e) {
501,6 → 521,28
 
}
 
protected String getLibelleStock(SQLRowAccessor row, SQLRowAccessor rowElt) {
return "Commande client N°" + row.getString("NUMERO");
}
 
/**
* Mise à jour des stocks pour chaque article composant la facture
*
* @throws SQLException
*/
private void updateStock(int id) throws SQLException {
 
SQLRow row = getTable().getRow(id);
StockItemsUpdater stockUpdater = new StockItemsUpdater(new StockLabel() {
@Override
public String getLabel(SQLRowAccessor rowOrigin, SQLRowAccessor rowElt) {
return getLibelleStock(rowOrigin, rowElt);
}
}, row, row.getReferentRows(getTable().getTable("COMMANDE_CLIENT_ELEMENT")), Type.VIRTUAL_DELIVER);
 
stockUpdater.update();
}
 
public void setDefaults() {
this.resetValue();
this.numeroUniqueCommande.setText(NumerotationAutoSQLElement.getNextNumero(CommandeClientSQLElement.class, new Date()));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/account/VenteFactureSoldeSQLComponent.java
16,12 → 16,15
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.common.ui.Acompte;
import org.openconcerto.erp.core.common.ui.AcompteField;
import org.openconcerto.erp.core.common.ui.AbstractVenteArticleItemTable.TypeCalcul;
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement;
import org.openconcerto.erp.core.sales.invoice.ui.FactureSituationItemTable;
import org.openconcerto.sql.element.GlobalMapper;
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.ui.group.Group;
import org.openconcerto.utils.Tuple2;
 
import java.math.BigDecimal;
37,7 → 40,7
public static final String ID = "sales.invoice.partial.balance";
 
public VenteFactureSoldeSQLComponent(SQLElement element) {
super(element, new VenteFactureSoldeEditGroup());
super(element, (Group) GlobalMapper.getInstance().get(ID));
}
 
@Override
74,7 → 77,7
final Acompte a = new Acompte(null, new BigDecimal(t.get0() - t.get1()).movePointLeft(2));
field.setValue(a);
final FactureSituationItemTable table = ((FactureSituationItemTable) getEditor("sales.invoice.partial.items.list"));
table.calculPourcentage(a);
table.calculPourcentage(a, TypeCalcul.CALCUL_FACTURABLE);
}
 
public Tuple2<Long, Long> getTotalFacture(List<SQLRowValues> context) {
105,4 → 108,15
return l;
}
 
// @Override
// public Component addView(MutableRowItemView rowItemView, String fields, Object specObj) {
//
// if (fields.contains("ID_POLE_PRODUIT") && countPole == 0) {
// countPole++;
// return null;
// } else {
// return super.addView(rowItemView, fields, specObj);
// }
// }
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/account/VenteFactureSituationSQLComponent.java
21,6 → 21,7
import org.openconcerto.erp.core.common.ui.AcompteRowItemView;
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.erp.core.common.ui.TotalPanel;
import org.openconcerto.erp.core.common.ui.AbstractVenteArticleItemTable.TypeCalcul;
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement;
import org.openconcerto.erp.core.sales.invoice.report.VenteFactureXmlSheet;
import org.openconcerto.erp.core.sales.invoice.ui.FactureSituationItemTable;
27,6 → 28,7
import org.openconcerto.erp.generationEcritures.GenerationMvtSaisieVenteFacture;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.ElementSQLObject;
import org.openconcerto.sql.element.GlobalMapper;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
63,7 → 65,7
public static final String ID = "sales.invoice.partial";
 
public VenteFactureSituationSQLComponent(SQLElement element) {
super(element, new PartialInvoiceEditGroup());
super(element, (Group) GlobalMapper.getInstance().get(ID));
}
 
public VenteFactureSituationSQLComponent(SQLElement element, Group p) {
145,7 → 147,7
@Override
public void update(DocumentEvent e) {
Acompte a = acompteField.getValue();
table.calculPourcentage(a);
table.calculPourcentage(a,TypeCalcul.CALCUL_FACTURABLE);
}
});
final TotalPanel total = ((TotalPanel) getEditor("sales.invoice.partial.total.amount"));
160,6 → 162,19
 
}
 
int countPole = 0;
 
// @Override
// public Component addView(MutableRowItemView rowItemView, String fields, Object specObj) {
//
// if (fields.contains("ID_POLE_PRODUIT") && countPole == 0) {
// countPole++;
// return null;
// } else {
// return super.addView(rowItemView, fields, specObj);
// }
// }
 
@Override
public JComponent getLabel(String id) {
if (id.equals("sales.invoice.partial.amount")) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/element/SaisieVenteFactureSQLElement.java
20,7 → 20,9
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.erp.core.common.ui.PanelFrame;
import org.openconcerto.erp.core.finance.accounting.element.EcritureSQLElement;
import org.openconcerto.erp.core.sales.account.PartialInvoiceEditGroup;
import org.openconcerto.erp.core.sales.account.VenteFactureSituationSQLComponent;
import org.openconcerto.erp.core.sales.account.VenteFactureSoldeEditGroup;
import org.openconcerto.erp.core.sales.account.VenteFactureSoldeSQLComponent;
import org.openconcerto.erp.core.sales.invoice.component.SaisieVenteFactureSQLComponent;
import org.openconcerto.erp.core.sales.invoice.report.VenteFactureXmlSheet;
29,11 → 31,14
import org.openconcerto.erp.core.supplychain.stock.element.MouvementStockSQLElement;
import org.openconcerto.erp.generationEcritures.GenerationMvtRetourNatexis;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
import org.openconcerto.erp.rights.NXRights;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.GlobalMapper;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.FieldPath;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
43,6 → 48,7
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.model.graph.Path;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.request.ListSQLRequest;
import org.openconcerto.sql.sqlobject.ElementComboBox;
51,13 → 57,18
import org.openconcerto.sql.view.EditPanel;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.sql.view.EditPanelListener;
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.table.PercentTableCellRenderer;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.ListMap;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.i18n.TranslationManager;
68,8 → 79,12
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
106,6 → 121,7
public SaisieVenteFactureSQLElement() {
super(TABLENAME, "une facture", "factures");
 
GlobalMapper.getInstance().map(VenteFactureSituationSQLComponent.ID, new PartialInvoiceEditGroup());
addComponentFactory(VenteFactureSituationSQLComponent.ID, new ITransformer<Tuple2<SQLElement, String>, SQLComponent>() {
 
@Override
114,6 → 130,7
return new VenteFactureSituationSQLComponent(SaisieVenteFactureSQLElement.this);
}
});
GlobalMapper.getInstance().map(VenteFactureSoldeSQLComponent.ID, new VenteFactureSoldeEditGroup());
addComponentFactory(VenteFactureSoldeSQLComponent.ID, new ITransformer<Tuple2<SQLElement, String>, SQLComponent>() {
 
@Override
202,6 → 219,7
 
protected List<String> getListFields() {
final List<String> l = new ArrayList<String>();
 
l.add("NUMERO");
l.add("DATE");
l.add("NOM");
240,6 → 258,59
};
}
 
private BigDecimal getAvancement(SQLRowAccessor r) {
Collection<? extends SQLRowAccessor> rows = r.getReferentRows(r.getTable().getTable("ECHEANCE_CLIENT"));
long totalEch = 0;
 
for (SQLRowAccessor row : rows) {
if (!row.getBoolean("REGLE")