Dépôt officiel du code source de l'ERP OpenConcerto
/trunk/OpenConcerto/lib/poi-3.17.jar |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/lib/poi-3.17.jar |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/lib/jOpenDocument-1.4rc2.badSecurity.jar |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/lib/jOpenDocument-1.4rc2.badSecurity.jar |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/lib/jOpenCalendar.jar |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/Configuration/Template/Default/FichePayeSimplifiee.odsp |
---|
1,9 → 1,6 |
<odsp> |
<spliteveryrow> |
<sheet number="0">60</sheet> |
<sheet number="0">61</sheet> |
</spliteveryrow> |
<offset x="20" y ="20"/> |
<resize percent="92"/> |
</odsp> |
/trunk/OpenConcerto/Configuration/Template/Default/FichePayeSimplifiee.xml |
---|
126,50 → 126,54 |
<field name="NET_A_PAYER"/> |
</element> |
<element location="D57" type="fill"> |
<element location="I55" type="fill"> |
<field name="REDUCTION_GVT" /> |
</element> |
<element location="D58" type="fill"> |
<field name="SAL_BRUT"/> |
</element> |
<element location="E57" type="fill"> |
<element location="E58" type="fill"> |
<field name="COT_SAL"/> |
</element> |
<element location="F57" type="fill"> |
<element location="F58" type="fill"> |
<field name="COT_PAT"/> |
</element> |
<element location="G57" type="fill"> |
<element location="G58" type="fill"> |
<field name="AVANTAGE_NATURE"/> |
</element> |
<element location="H57" type="fill"> |
<element location="H58" type="fill"> |
<field name="NET_IMP"/> |
</element> |
<element location="I57" type="fill"> |
<element location="I58" type="fill"> |
<field name="ALLEGEMENT_COTISATION"/> |
</element> |
<element location="D58" type="fill"> |
<element location="D59" type="fill"> |
<field name="SAL_BRUT" type="cumulPaye"/> |
</element> |
<element location="E58" type="fill"> |
<element location="E59" type="fill"> |
<field name="COT_SAL" type="cumulPaye"/> |
</element> |
<element location="F58" type="fill"> |
<element location="F59" type="fill"> |
<field name="COT_PAT" type="cumulPaye"/> |
</element> |
<element location="G58" type="fill"> |
<element location="G59" type="fill"> |
<field name="AVANTAGE_NATURE" type="cumulPaye"/> |
</element> |
<element location="H58" type="fill"> |
<element location="H59" type="fill"> |
<field name="NET_IMP" type="cumulPaye"/> |
</element> |
<element location="I58" type="fill"> |
<element location="I59" type="fill"> |
<field name="ALLEGEMENT_COTISATION" type="cumulPaye"/> |
</element> |
<table endPageLine="60" firstLine="15" endLine="51" lastColumn="J" base="Societe" table="FICHE_PAYE_ELEMENT" |
<table endPageLine="61" firstLine="15" endLine="51" lastColumn="J" base="Societe" table="FICHE_PAYE_ELEMENT" |
blankLineBeforeStyle="Titre 1,Titre 2" fieldWhere="IMPRESSION" orderBy="POSITION"> |
<element location="B" type="fill" cellSize="52"> |
<field name="NOM" /> |
/trunk/OpenConcerto/Configuration/Template/Default/FichePayeSimplifiee.ods |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/utils/text/CSVReader.java |
---|
29,6 → 29,7 |
import java.io.BufferedReader; |
import java.io.Closeable; |
import java.io.FileReader; |
import java.io.IOException; |
import java.io.Reader; |
import java.util.ArrayList; |
247,4 → 248,11 |
br.close(); |
} |
public static void main(String[] args) throws IOException { |
CSVReader reader = new CSVReader(new FileReader("n:\\Sans nom 1.csv")); |
String[] s = reader.readNext(); |
for (int i = 0; i < s.length; i++) { |
System.err.println("CSVReader.main() :" + i + " : " + s[i]); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/utils/prog/SVNUtils.java |
---|
50,20 → 50,23 |
} |
// match placeholder $Rev$ fixed length $Rev:: $ and of course with value $Rev: 12 $ |
private static final Pattern KEYWORD_PATTERN = Pattern.compile("^\\$\\p{Alpha}+:{0,2}\\p{Blank}*(.*?)\\p{Blank}*\\$$"); |
// don't require to match to the end to allow callers to only know the start of the substitute |
// and to not bother with the pattern |
private static final Pattern KEYWORD_PATTERN = Pattern.compile("^\\$\\p{Alpha}+:{0,2}\\p{Blank}*(.*?)\\p{Blank}*\\$"); |
/** |
* Return the value of the svn keyword. E.g. use with |
* Return the value of the subversion keyword. E.g. use with |
* <code>private static final String REV = getKeywordValue("$Rev$")</code> (don't forget to |
* <code>svn propset svn:keywords</code>). |
* |
* @param substitute the svn substitute, e.g. "$Rev: 12 $". |
* @param substitute the svn substitute, trailing characters not part of the keyword will be |
* ignored, e.g. "$Rev: 12 $ other chars". |
* @return the value, empty string if none, e.g. "12". |
* @throws IllegalArgumentException if substitute is not valid. |
*/ |
public static String getKeywordValue(String substitute) throws IllegalArgumentException { |
final Matcher matcher = KEYWORD_PATTERN.matcher(substitute); |
if (!matcher.matches()) |
if (!matcher.find()) |
throw new IllegalArgumentException("SVN format not recognized"); |
return matcher.group(1); |
/trunk/OpenConcerto/src/org/openconcerto/utils/FeatureMode.java |
---|
New file |
0,0 → 1,29 |
/* |
* 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; |
public enum FeatureMode { |
/** |
* The feature is required. |
*/ |
REQUIRED, |
/** |
* The feature is used if available. |
*/ |
ALLOWED, |
/** |
* The feature won't be used. |
*/ |
FORBIDDEN |
} |
/trunk/OpenConcerto/src/org/openconcerto/task/ui/UserRightsPrefPanel.java |
---|
72,8 → 72,8 |
l.setCellRenderer(new UserListCellRenderer()); |
l.setBorder(BorderFactory.createEmptyBorder()); |
final JScrollPane scrollPane = new JScrollPane(l); |
scrollPane.setMinimumSize(new Dimension(120, 120)); |
scrollPane.setPreferredSize(new Dimension(120, 120)); |
scrollPane.setMinimumSize(new Dimension(10 * getFont().getSize(), 120)); |
scrollPane.setPreferredSize(new Dimension(12 * getFont().getSize(), 120)); |
this.add(scrollPane, c); |
scrollPane.setBorder(BorderFactory.createEmptyBorder()); |
// Separator |
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/ITreeSelection.java |
---|
25,6 → 25,7 |
import org.openconcerto.sql.request.SQLRowItemView; |
import org.openconcerto.sql.sqlobject.itemview.RowItemViewComponent; |
import org.openconcerto.sql.view.EditFrame; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.FrameUtil; |
import org.openconcerto.ui.valuewrapper.ValueWrapper; |
import org.openconcerto.utils.ExceptionHandler; |
83,7 → 84,9 |
renderer.setClosedIcon(null); |
renderer.setLeafIcon(null); |
this.setCellRenderer(renderer); |
// HighDPI |
this.setRowHeight(FontUtils.getPreferredRowHeight(this)); |
// Selection |
this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); |
this.element = element; |
/trunk/OpenConcerto/src/org/openconcerto/erp/model/EditionFichePayeModel.java |
---|
86,6 → 86,7 |
public void setDateLimit(java.util.Date dateLimit) { |
this.dateLimit = dateLimit; |
fill(); |
updateAll(); |
fireTableDataChanged(); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/model/FamilleArticleTree.java |
---|
22,6 → 22,7 |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.model.SQLTableListener; |
import org.openconcerto.sql.view.EditFrame; |
import org.openconcerto.ui.FontUtils; |
import java.awt.event.ActionEvent; |
import java.awt.event.MouseEvent; |
64,6 → 65,7 |
this.addMouseListener(this); |
this.setTableListener(); |
this.setDragEnabled(true); |
this.setRowHeight(FontUtils.getPreferredRowHeight(this)); |
} |
/** |
/trunk/OpenConcerto/src/org/openconcerto/erp/model/FichePayeModel.java |
---|
72,7 → 72,8 |
private SQLJavaEditor javaEdit = new SQLJavaEditor(VariablePayeSQLElement.getMapTree()); |
// liste des variable de paye à calculer |
private BigDecimal salBrut, salBrutBase, salBrutCotis, salBrutTaxable, cotPat, cotSal, taxCmPat, taxCmSal, netImp, netAPayer, csg, csgSansAbattement, cice, allegmentCotisation, avantage; |
private BigDecimal salBrut, salBrutBase, salBrutCotis, salBrutTaxable, cotPat, cotSal, taxCmPat, taxCmSal, netImp, netAPayer, csg, csgSansAbattement, cice, allegmentCotisation, avantage, |
reduction; |
private Map<Integer, String> mapField; |
82,7 → 83,6 |
private int mois; |
public FichePayeModel(int idFiche) { |
System.err.println("NEW FICHE PAYE MODEL"); |
this.javaEdit.setModel(this); |
this.idFiche = idFiche; |
127,6 → 127,8 |
SQLPreferences prefs = new SQLPreferences(tableFichePaye.getTable().getDBRoot()); |
this.tauxCSG = new BigDecimal(prefs.getDouble(PayeGlobalPreferencePanel.ASSIETTE_CSG, 0.9825D)); |
final SQLTable tableValidite = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getTable("PERIODE_VALIDITE"); |
SQLBackgroundTableCache.getInstance().getCacheForTable(tableValidite).reloadFromDbIfNeeded(); |
// loadElement(); |
// methodeTmp(); |
193,6 → 195,7 |
*/ |
this.cice = null; |
this.allegmentCotisation = BigDecimal.ZERO; |
this.reduction = BigDecimal.ZERO; |
this.avantage = BigDecimal.ZERO; |
this.salBrut = BigDecimal.ZERO; |
this.salBrutCotis = BigDecimal.ZERO; |
770,6 → 773,7 |
} |
rowValsFiche.put("CICE", this.cice); |
rowValsFiche.put("ALLEGEMENT_COTISATION", this.allegmentCotisation); |
rowValsFiche.put("REDUCTION_GVT", this.reduction); |
rowValsFiche.put("AVANTAGE_NATURE", this.avantage); |
try { |
rowValsFiche.update(this.idFiche); |
1134,13 → 1138,24 |
rowVals.put("TAUX_SAL", (tauxSalOb == null) ? null : new BigDecimal(tauxSalOb.toString())); |
rowVals.put("TAUX_PAT", (tauxPatOb == null) ? null : new BigDecimal(tauxPatOb.toString())); |
rowVals.put("MONTANT_PAT", (montantPatOb == null) ? null : new BigDecimal(montantPatOb.toString())); |
rowVals.put("MONTANT_SAL_AJ", (montantAdOb == null) ? null : new BigDecimal(montantAdOb.toString())); |
rowVals.put("MONTANT_SAL_DED", (montantDedOb == null) ? null : new BigDecimal(montantDedOb.toString())); |
final BigDecimal montantAj = (montantAdOb == null) ? null : new BigDecimal(montantAdOb.toString()); |
rowVals.put("MONTANT_SAL_AJ", montantAj); |
final BigDecimal montantDed = (montantDedOb == null) ? null : new BigDecimal(montantDedOb.toString()); |
rowVals.put("MONTANT_SAL_DED", montantDed); |
boolean b = isEltImprimable(rowSource, rowVals); |
// System.err.println("Impression --- > " + b); |
rowVals.put("IMPRESSION", Boolean.valueOf(b)); |
if (rowSource.getBoolean("REDUCTION_GVT_COM")) { |
if (montantAj != null) { |
this.reduction = this.reduction.subtract(montantAj); |
} |
if (montantDed != null) { |
this.reduction = this.reduction.add(montantDed); |
} |
} |
this.vectRubrique.add(rowVals); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/translation/messages_fr.properties |
---|
1,3 → 1,5 |
add=Ajouter |
modify.or.delete=Modifier/Supprimer |
address=Adresse |
address.type.invoice=Facturation |
address.type.delivery=Livraison |
20,4 → 22,13 |
</ul><p>Si ce n'est pas le cas, merci de vérifier qu'il n'y ait pas plusieurs installations configurées avec le même numéro de caisse (n° {0}).\ |
<p>Voulez-vous ignorer message et continuer ou alors quitter l\u2019application ?</html> |
register.moved.ignore=Ignorer |
register.moved.quit=Quitter |
register.moved.quit=Quitter |
sddMessage.generation.noneNeeded=Aucune facture ne nécessite {msgElem__de__singular}. |
sddMessage.generation.noneIgnored={msgElem__singularDefiniteArticle} généré inclut {invoiceElem__definiteNumeral}. |
sddMessage.generation.someIgnored={invoiceElemCount, plural, =0 {Toutes les factures nécessitant {msgElem__singularIndefiniteArticle} ont été ignorées :}\ |
other {{msgElem__singularDefiniteArticle} généré inclut {invoiceElem__indefiniteNumeral}, d'autres ont été ignorées :}} |
sddMessage.generation.someIgnored.future={futureCount, plural, =1 {une car sa date d\u2019échéance est trop éloignée} other {# car leurs dates d\u2019échéance sont trop éloignées}} |
sddMessage.generation.someIgnored.duplicateMandate={duplicateCount, plural, =1 {une car son mandat est partagé avec une autre facture}\ |
other {# car leurs mandats sont partagés avec d\u2019autres factures}}. Vous devez générer à nouveau {msgElem__singularIndefiniteArticle}. |
sddMessage.generation.someIgnored.missingInfo={missingInfoCount, plural, =1 {une car il manquait des informations} other {# car il manquait des informations}} |
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/translation/messages_en.properties |
---|
1,3 → 1,5 |
add=Add |
modify.or.delete=Modify/Delete |
address=Address |
address.type.invoice=Invoice |
address.type.delivery=Shipment |
20,4 → 22,14 |
</ul><p>If this isn\u2019t the case, please check that there isn\u2019t multiple installations with the same register number (n° {0}).\ |
<p>Do you want to ignore the message and continue or else quit the application?</html> |
register.moved.ignore=Ignore |
register.moved.quit=Quit |
register.moved.quit=Quit |
sddMessage.generation.noneNeeded=No invoice needs {msgElem__singularIndefiniteArticle}. |
sddMessage.generation.noneIgnored=The generated {msgElem__singular} includes {invoiceElem__definiteNumeral}. |
sddMessage.generation.someIgnored={invoiceElemCount, plural, =0 {All invoices needing {msgElem__singularIndefiniteArticle} were ignored :}\ |
other {The generated {msgElem__singular} includes {invoiceElem__indefiniteNumeral}, others were ignored :}} |
sddMessage.generation.someIgnored.future={futureCount, plural, =1 {one because its due date was too far} other {# because their due dates were too far}} |
sddMessage.generation.someIgnored.duplicateMandate={duplicateCount, plural, =1 {one because its mandate was shared with another invoice}\ |
other {# because their mandates were shared with other invoices}}. You must generate again {msgElem__singularIndefiniteArticle}. |
sddMessage.generation.someIgnored.missingInfo={missingInfoCount, plural, =1 {one because some information was missing} other {# because some information was missing}} |
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/HeadlessGestion.java |
---|
17,7 → 17,6 |
import org.openconcerto.erp.config.MainFrame; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.users.UserManager; |
import org.openconcerto.utils.i18n.TranslationManager; |
import java.util.Locale; |
29,7 → 28,25 |
this.comptaPropsConfiguration = ComptaPropsConfiguration.create(); |
} |
public HeadlessGestion setup(int userId, int companyId) { |
try { |
this.comptaPropsConfiguration.getUserManager().setCurrentUserID(userId); |
this.comptaPropsConfiguration.setUpSocieteDataBaseConnexion(companyId); |
} catch (Exception e) { |
e.printStackTrace(); |
throw new IllegalStateException("Unable to configure connection for userId: " + userId + " companyId: " + companyId); |
} |
return this; |
} |
public HeadlessGestion setupGlobalState(int userId, int companyId) { |
setupGlobalState(userId, companyId); |
setGlobalState(); |
return this; |
} |
public HeadlessGestion setGlobalState() { |
System.setProperty("java.awt.headless", "true"); |
TranslationManager.getInstance().addTranslationStreamFromClass(MainFrame.class); |
36,14 → 53,6 |
TranslationManager.getInstance().setLocale(Locale.getDefault()); |
Configuration.setInstance(this.comptaPropsConfiguration); |
try { |
UserManager.getInstance().setCurrentUserID(userId); |
this.comptaPropsConfiguration.setUpSocieteDataBaseConnexion(companyId); |
} catch (Exception e) { |
e.printStackTrace(); |
throw new IllegalStateException("Unable to configure connection for userId: " + userId + " companyId: " + companyId); |
} |
System.out.println("HeadlessOpenConcerto ready"); |
System.out.println( |
"Connected to " + this.comptaPropsConfiguration.getServerIp() + " on " + this.comptaPropsConfiguration.getSystemRootName() + "/" + this.comptaPropsConfiguration.getSocieteBaseName()); |
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/UIPreferencePanel.java |
---|
27,6 → 27,7 |
import java.awt.event.MouseEvent; |
import java.util.ArrayList; |
import java.util.Collections; |
import java.util.Enumeration; |
import java.util.List; |
import java.util.Properties; |
45,9 → 46,10 |
private static final String ALTERNATE_COLOR_BLUE = "ui.list.alternate.color.blue"; |
private static final String ALTERNATE_COLOR_GREEN = "ui.list.alternate.color.green"; |
private static final String ALTERNATE_COLOR_RED = "ui.list.alternate.color.red"; |
private static final String UI_DPI = "ui.default.dpi"; |
private static final String UI_LOOK = "ui.look"; |
private JLabel selectedButton; |
private JComboBox comboLook; |
private JComboBox comboLook, comboDPI; |
public UIPreferencePanel() { |
super("Interface graphique", UI_PROPERTIES); |
69,6 → 71,19 |
c.gridx++; |
this.add(comboLook, c); |
c.gridy++; |
c.gridx = 0; |
this.add(new JLabel("High DPI"), c); |
this.comboDPI = new JComboBox(new String[] { "Désactivé", "x1.3", "x2", "x3", "x4" }); |
String dpi = this.properties.getProperty(UI_DPI); |
if (dpi != null && !dpi.equals("1")) { |
comboDPI.setSelectedIndex(Float.valueOf(dpi).intValue()); |
} |
c.gridx++; |
this.add(comboDPI, c); |
final JLabel labelAlternate = new JLabel("Couleur de fond dans les liste pour l'alternance"); |
c.gridx = 0; |
c.gridwidth = 2; |
199,6 → 214,19 |
} else { |
properties.setProperty(UI_LOOK, "nimbus"); |
} |
if (this.comboDPI.getSelectedIndex() == 1) { |
properties.setProperty(UI_DPI, "1.3"); |
} else if (this.comboDPI.getSelectedIndex() == 2) { |
properties.setProperty(UI_DPI, "2"); |
} else if (this.comboDPI.getSelectedIndex() == 3) { |
properties.setProperty(UI_DPI, "3"); |
} else if (this.comboDPI.getSelectedIndex() == 4) { |
properties.setProperty(UI_DPI, "4"); |
} else { |
properties.setProperty(UI_DPI, "1"); |
} |
super.storeValues(); |
} |
254,12 → 282,32 |
} else { |
useNimbusLF(); |
} |
final String dpi = properties.getProperty(UI_DPI); |
if (dpi != null && dpi.length() > 0 && !dpi.equalsIgnoreCase("1")) { |
setUIFont(Float.valueOf(dpi)); |
UIManager.put("dpi.scale", Float.valueOf(dpi)); |
} else { |
UIManager.put("dpi.scale", Float.valueOf(1)); |
} |
} catch (Exception e) { |
ExceptionHandler.handle("Unable to restore UI preferences", e); |
} |
} |
public static void setUIFont(float factor) { |
Enumeration<Object> keys = UIManager.getDefaults().keys(); |
while (keys.hasMoreElements()) { |
Object key = keys.nextElement(); |
Object value = UIManager.get(key); |
if (value instanceof javax.swing.plaf.FontUIResource) { |
javax.swing.plaf.FontUIResource r = (javax.swing.plaf.FontUIResource) value; |
UIManager.put(key, r.deriveFont(r.getSize() * factor)); |
} |
} |
} |
private static void useSystemLF() throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { |
LAFUtils.setLookAndFeel(); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/TemplateNXProps.java |
---|
18,6 → 18,7 |
import org.openconcerto.erp.core.edm.AttachmentSQLElement; |
import org.openconcerto.erp.core.finance.accounting.report.BalanceSheet; |
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheet; |
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheetXML; |
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheetXML; |
import org.openconcerto.erp.core.humanresources.payroll.report.EtatChargesPayeSheet; |
import org.openconcerto.erp.core.humanresources.payroll.report.FichePayeSheetXML; |
148,7 → 149,7 |
register(ReleveChequeSheet.TEMPLATE_ID, ReleveChequeSheet.TEMPLATE_PROPERTY_NAME, null); |
register(ListeVenteXmlSheet.TEMPLATE_ID, ListeVenteXmlSheet.TEMPLATE_PROPERTY_NAME, null); |
register(BalanceSheet.TEMPLATE_ID, BalanceSheet.TEMPLATE_PROPERTY_NAME, BalanceSheet.TEMPLATE_ID); |
register(GrandLivreSheet.TEMPLATE_ID, GrandLivreSheet.TEMPLATE_PROPERTY_NAME, GrandLivreSheet.TEMPLATE_ID); |
register(GrandLivreSheetXML.TEMPLATE_ID, GrandLivreSheetXML.TEMPLATE_PROPERTY_NAME, GrandLivreSheetXML.TEMPLATE_ID); |
register(JournauxSheetXML.TEMPLATE_ID, JournauxSheetXML.TEMPLATE_PROPERTY_NAME, JournauxSheetXML.TEMPLATE_ID); |
register(EtatChargesPayeSheet.TEMPLATE_ID, EtatChargesPayeSheet.TEMPLATE_PROPERTY_NAME, "Etat des charges"); |
register(FichePayeSheetXML.TEMPLATE_ID, FichePayeSheetXML.TEMPLATE_PROPERTY_NAME, "Fiche paye"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/GenerationDocumentComptaPreferencePanel.java |
---|
14,7 → 14,7 |
package org.openconcerto.erp.preferences; |
import org.openconcerto.erp.core.finance.accounting.report.BalanceSheet; |
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheet; |
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheetXML; |
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheetXML; |
import org.openconcerto.utils.Tuple2; |
22,7 → 22,7 |
public GenerationDocumentComptaPreferencePanel() { |
super(); |
this.mapKeyLabel.put(Tuple2.create(GrandLivreSheet.TEMPLATE_ID, GrandLivreSheet.TEMPLATE_PROPERTY_NAME), GrandLivreSheet.TEMPLATE_ID); |
this.mapKeyLabel.put(Tuple2.create(GrandLivreSheetXML.TEMPLATE_ID, GrandLivreSheetXML.TEMPLATE_PROPERTY_NAME), GrandLivreSheetXML.TEMPLATE_ID); |
this.mapKeyLabel.put(Tuple2.create(JournauxSheetXML.TEMPLATE_ID, JournauxSheetXML.TEMPLATE_PROPERTY_NAME), JournauxSheetXML.TEMPLATE_ID); |
this.mapKeyLabel.put(Tuple2.create(BalanceSheet.TEMPLATE_ID, BalanceSheet.TEMPLATE_PROPERTY_NAME), BalanceSheet.TEMPLATE_ID); |
// uiInit(); |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/Gestion.java |
---|
58,6 → 58,8 |
import java.awt.event.HierarchyEvent; |
import java.awt.event.WindowAdapter; |
import java.awt.event.WindowEvent; |
import java.beans.PropertyChangeEvent; |
import java.beans.PropertyChangeListener; |
import java.io.BufferedReader; |
import java.io.ByteArrayOutputStream; |
import java.io.File; |
77,7 → 79,9 |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Enumeration; |
import java.util.HashSet; |
import java.util.List; |
import java.util.Set; |
import javax.swing.ImageIcon; |
import javax.swing.JDialog; |
384,6 → 388,9 |
// ITableModel.setDefaultOrderEditable(true); |
AWTEventListener awtListener = new AWTEventListener() { |
Set<Integer> frames = new HashSet<Integer>(); |
String prefix; |
@Override |
public final void eventDispatched(final AWTEvent event) { |
assert event != null; |
393,13 → 400,32 |
final HierarchyEvent hevent = (HierarchyEvent) event; |
final Component changed = hevent.getChanged(); |
if (changed instanceof JFrame && ((hevent.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) && changed.isDisplayable()) { |
JFrame frame = (JFrame) changed; |
final JFrame frame = (JFrame) changed; |
frame.setIconImages(getFrameIcon()); |
if (!frames.contains(frame.hashCode())) { |
frames.add(frame.hashCode()); |
frame.addPropertyChangeListener(new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
if (prefix == null) { |
if (ComptaPropsConfiguration.getInstance() != null && ComptaPropsConfiguration.getInstanceCompta().getRowSociete() != null) { |
prefix = "[" + ComptaPropsConfiguration.getInstanceCompta().getRowSociete().getString("NOM") + "] "; |
} else { |
return; |
} |
} |
String title = frame.getTitle(); |
if (title != null && !title.startsWith(prefix)) { |
frame.setTitle(prefix + title); |
} |
} |
}); |
} |
} |
} |
} |
}; |
final Toolkit toolkit = Toolkit.getDefaultToolkit(); |
assert toolkit != null; |
toolkit.addAWTEventListener(awtListener, AWTEvent.HIERARCHY_EVENT_MASK); |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/SQLElementNames_en.xml |
---|
2,5 → 2,7 |
<element refid="CONTACT" name="contact" /> |
<element refid="CONTACT_FOURNISSEUR" name="supplier contact" namePlural="suppliers contacts" /> |
<element refid="CONTACT_ADMINISTRATIF" name="administrative contact" /> |
<element refid="CATEGORIE_CLIENT" nameClass="feminine" name="Customer category" /> |
<element refid="customerrelationship.customer.category" nameClass="feminine" name="customer category" /> |
<element refid="finance.payment.SDDMessage" name="SDD message" /> |
<element refid="finance.payment.SEPAMandate" name="SEPA mandate" /> |
</translations> |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ComptaPropsConfiguration.java |
---|
65,6 → 65,8 |
import org.openconcerto.erp.core.finance.payment.element.ModeDeReglementSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.ReglerMontantElementSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.ReglerMontantSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.SDDMessageSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.SEPAMandateSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement; |
import org.openconcerto.erp.core.finance.tax.element.EcoTaxeSQLElement; |
import org.openconcerto.erp.core.finance.tax.element.TaxeComplementaireSQLElement; |
1039,6 → 1041,8 |
dir.addSQLElement(new TypeComptePCGSQLElement()); |
dir.addSQLElement(new TypeLettreRelanceSQLElement()); |
dir.addSQLElement(new TypeReglementSQLElement()); |
dir.addSQLElement(new SDDMessageSQLElement(this)); |
dir.addSQLElement(new SEPAMandateSQLElement(this)); |
dir.addSQLElement(new VariableSalarieSQLElement()); |
dir.addSQLElement(UniteVenteArticleSQLElement.class); |
1178,9 → 1182,9 |
showAs.show("CODE_REGIME", SQLRow.toList("CODE,NOM")); |
showAs.show("COMMANDE", "NUMERO", "DATE", "DATE_RECEPTION_DEMANDEE", "NOM", "ID_FOURNISSEUR"); |
if (root.contains("AFFAIRE")) { |
showAs.show("COMMANDE_CLIENT", "NUMERO", "DATE", "ID_AFFAIRE", "NOM", "T_HT"); |
showAs.show("COMMANDE_CLIENT", "NUMERO", "DATE", "ID_CLIENT", "ID_AFFAIRE", "NOM", "T_HT"); |
} else { |
showAs.show("COMMANDE_CLIENT", "NUMERO", "DATE", "NOM", "T_HT"); |
showAs.show("COMMANDE_CLIENT", "NUMERO", "DATE", "NOM", "ID_CLIENT", "T_HT"); |
} |
showAs.show("COMPTE_PCE", "NUMERO", "NOM"); |
showAs.show("COMPTE_PCG", "NUMERO", "NOM"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/translation_en.xml |
---|
110,6 → 110,7 |
<menu id="customer.payment.followup.list" label="Followup" /> |
<menu id="customer.payment.check.pending.list" label="Customer checks" /> |
<menu id="customer.payment.check.pending.create" label="Pending checks" /> |
<menu id="customer.payment.sddMessage.list" label="SEPA Direct debit messages" /> |
<menu id="customer.credit.check.list" label="Credit checks" /> |
<menu id="customer.credit.check.create" label="Pending credit checks" /> |
<menu id="menu.payment.supplier" label="Supplier" /> |
226,6 → 227,7 |
<!-- Customer --> |
<item id="customerrelationship.customer.address" label="Addresses" /> |
<item id="customerrelationship.customer.contact" label="Contacts" /> |
<item id="customerrelationship.customer.lead" label="Lead" /> |
<item id="customerrelationship.customer.sales" label="Sales" /> |
<item id="customerrelationship.customer.payment" label="Payment" /> |
<item id="customerrelationship.customer.contacts" label="Contacts" /> |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mappingCompta_en.xml |
---|
428,6 → 428,10 |
<FIELD name="TEL_P" label="Mobile" /> |
<FIELD name="FAX" label="Fax" /> |
<FIELD name="MAIL" label="Email" /> |
<FIELD name="ACCEPTE_EMAIL" label="Allow e-mail" titlelabel="E-mail OK" /> |
<FIELD name="ACCEPTE_COURRIER" label="Allow mail" titlelabel="Mail OK" /> |
<FIELD name="ACCEPTE_SMS" label="Allow SMS" titlelabel="SMS OK" /> |
<FIELD name="ACCEPTE_TEL" label="Allow voice call" titlelabel="Voice call OK" /> |
<FIELD name="RESPONSABLE" label="Manager" /> |
<FIELD name="RESPONSABLE_TECH" label="Technician" /> |
<FIELD name="RESPONSABLE_COM" label="Saleman" /> |
449,7 → 453,9 |
<FIELD name="MARCHE_PUBLIC" label="Public sector" /> |
<FIELD name="MARCHE_PRIVE" label="Private sector" /> |
<FIELD name="ID_ADRESSE_L" label="Delivery address" /> |
<FIELD name="RIB" label="RIB" titlelabel="RIB" /> |
<FIELD name="RIB" label="RIB" /> |
<FIELD name="IBAN" label="IBAN" /> |
<FIELD name="BIC" label="BIC" /> |
<FIELD name="SIRET" label="SIRET" titlelabel="SIRET" /> |
<FIELD name="ID_SECTEUR_ACTIVITE" label="Activity" /> |
<FIELD name="INFOS" label="Additionnal information" /> |
537,6 → 543,7 |
<FIELD name="SERVICE" label="Department" /> |
<FIELD name="PAYS" label="Country" /> |
<FIELD name="ID_ADRESSE" label="Address" /> |
<FIELD name="DATE_NAISSANCE" label="Date of birth" /> |
</TABLE> |
<TABLE name="CONTACT_FOURNISSEUR"> |
1684,4 → 1691,19 |
<FIELD name="NOM" label="Label" /> |
</TABLE> |
<TABLE name="SEPA_MANDATE"> |
<FIELD name="ID_CLIENT" label="Client" /> |
<FIELD name="MandateIdentification" label="Identifier" /> |
<FIELD name="DateOfSignature" label="Date of signature" titlelabel="Sign. date" /> |
<FIELD name="SequenceType" label="Sequence type" titlelabel="Seq. type" /> |
<FIELD name="ACTIVE" label="Active" /> |
</TABLE> |
<TABLE name="SEPA_DIRECT_DEBIT_MESSAGE"> |
<FIELD name="MessageIdentification" label="Message identifier" /> |
<FIELD name="CreationDateTime" label="Creation date" /> |
<FIELD name="NumberOfTransactions" label="Number of transactions" /> |
<FIELD name="ControlSum" label="Control sum" /> |
<FIELD name="XML" label="XML message" /> |
</TABLE> |
</ROOT> |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/DefaultMenuConfiguration.java |
---|
102,11 → 102,13 |
import org.openconcerto.erp.core.sales.invoice.action.ListeDesElementsFactureAction; |
import org.openconcerto.erp.core.sales.invoice.action.ListeDesFactureItemsAction; |
import org.openconcerto.erp.core.sales.invoice.action.ListeDesVentesAction; |
import org.openconcerto.erp.core.sales.invoice.action.ListeSDDMessageAction; |
import org.openconcerto.erp.core.sales.invoice.action.ListeSaisieVenteFactureAction; |
import org.openconcerto.erp.core.sales.invoice.action.ListesFacturesClientsImpayeesAction; |
import org.openconcerto.erp.core.sales.invoice.action.NouveauSaisieVenteComptoirAction; |
import org.openconcerto.erp.core.sales.invoice.action.NouveauSaisieVenteFactureAction; |
import org.openconcerto.erp.core.sales.order.action.ListeDesCommandesClientAction; |
import org.openconcerto.erp.core.sales.order.action.ListeDesCommandesClientItemsAction; |
import org.openconcerto.erp.core.sales.order.action.ListeDesElementsACommanderClientAction; |
import org.openconcerto.erp.core.sales.order.action.ListeDesFacturationCommandesClientAction; |
import org.openconcerto.erp.core.sales.order.action.NouvelleCommandeClientAction; |
371,6 → 373,7 |
gCustomer.addItem("customer.payment.followup.list"); |
gCustomer.addItem("customer.payment.check.pending.list"); |
gCustomer.addItem("customer.payment.check.pending.create"); |
gCustomer.addItem("customer.payment.sddMessage.list"); |
gCustomer.addItem("customer.credit.check.list"); |
gCustomer.addItem("customer.credit.check.create"); |
group.add(gCustomer); |
472,6 → 475,7 |
gCustomer.addItem("customer.order.list"); |
gCustomer.addItem("customer.order.invoice.list"); |
gCustomer.addItem("customer.order.list.details"); |
gCustomer.addItem("customer.delivery.list"); |
if (configuration.getRootSociete().contains("RELIQUAT_BR")) { |
gCustomer.addItem("customer.delivery.reliquat.list"); |
606,6 → 610,7 |
mManager.putAction(new ListeDesCommandesClientAction(), "customer.order.list"); |
mManager.putAction(new ListeDesFacturationCommandesClientAction(), "customer.order.invoice.list"); |
mManager.putAction(new ListeDesCommandesClientItemsAction(), "customer.order.list.details"); |
mManager.putAction(new ListeDesBonsDeLivraisonAction(), "customer.delivery.list"); |
if (configuration.getRootSociete().contains("RELIQUAT_BL")) { |
mManager.registerAction("customer.delivery.reliquat.list", new ListeDesReliquatsBonsLivraisonsAction()); |
730,6 → 735,7 |
mManager.putAction(new ListeDesRelancesAction(), "customer.payment.followup.list"); |
mManager.putAction(new ListeDesChequesAEncaisserAction(), "customer.payment.check.pending.list"); |
mManager.putAction(new NouveauListeDesChequesAEncaisserAction(), "customer.payment.check.pending.create"); |
mManager.putAction(new ListeSDDMessageAction(configuration.getDirectory()), "customer.payment.sddMessage.list"); |
mManager.putAction(new ListeDesChequesAvoirAction(), "customer.credit.check.list"); |
mManager.putAction(new NouveauDecaissementChequeAvoirAction(), "customer.credit.check.create"); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mapping_fr.xml |
---|
283,6 → 283,7 |
<FIELD name="NUMERO_URSSAF" label="Identifiant personnel URSSAF" /> |
<FIELD name="ID_DEVISE" label="Devise" /> |
<FIELD name="ORG_PROTECTION_SOCIAL_ID" label="Siret URSSAF" /> |
<FIELD name="SEPA_CREDITOR_ID" label="Identifiant Créancier SEPA" /> |
</TABLE> |
<TABLE name="TYPE_MODELE"> |
<FIELD name="NOM" label="Nom" /> |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/update/Updater_1_5.java |
---|
14,6 → 14,10 |
package org.openconcerto.erp.config.update; |
import org.openconcerto.erp.config.InstallationPanel; |
import org.openconcerto.erp.core.finance.payment.element.SDDMessageSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.SEPAMandateSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.TypeReglementSQLElement; |
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement; |
import org.openconcerto.erp.core.sales.order.ui.TypeFactureCommandeClient; |
import org.openconcerto.erp.core.sales.pos.element.TicketCaisseSQLElement; |
import org.openconcerto.erp.core.sales.product.element.ReferenceArticleSQLElement; |
32,6 → 36,7 |
import org.openconcerto.sql.utils.ChangeTable; |
import org.openconcerto.sql.utils.SQLCreateTable; |
import org.openconcerto.sql.utils.UniqueConstraintCreatorHelper; |
import org.openconcerto.utils.CollectionUtils; |
import java.math.BigDecimal; |
import java.sql.SQLException; |
80,6 → 85,13 |
tClient.getSchema().updateVersion(); |
tClient.fetchFields(); |
} |
if (!tClient.contains("DATE")) { |
final AlterTable alterClient = new AlterTable(tClient); |
alterClient.addColumn("DATE", "date"); |
tClient.getBase().getDataSource().execute(alterClient.asString()); |
tClient.getSchema().updateVersion(); |
tClient.fetchFields(); |
} |
if (!tClient.contains("COMMENTAIRES")) { |
final AlterTable alterClient = new AlterTable(tClient); |
alterClient.addVarCharColumn("COMMENTAIRES", 2048); |
235,7 → 247,7 |
tableAttachment.fetchFields(); |
} |
List<String> gedTable = Arrays.asList("CLIENT", "MOUVEMENT", "FOURNISSEUR", "ARTICLE", "SALARIE"); |
List<String> gedTable = Arrays.asList("CLIENT", "MOUVEMENT", "FOURNISSEUR", "ARTICLE", "FACTURE_FOURNISSEUR", "SAISIE_VENTE_FACTURE", "SALARIE"); |
for (String string : gedTable) { |
SQLTable tableGED = root.getTable(string); |
if (!tableGED.contains("ATTACHMENTS")) { |
273,7 → 285,7 |
if (!tableCmdElt.contains("LIVRE")) { |
AlterTable t = new AlterTable(tableCmdElt); |
t.addBooleanColumn("LIVRE_FORCED", Boolean.FALSE, false); |
t.addBooleanColumn("LIVRE", Boolean.TRUE, false); |
t.addBooleanColumn("LIVRE", Boolean.FALSE, false); |
t.addDecimalColumn("QTE_LIVREE", 16, 6, BigDecimal.ZERO, true); |
tableCmdElt.getBase().getDataSource().execute(t.asString()); |
root.refetchTable(tableCmdElt.getName()); |
299,6 → 311,15 |
// \"ID_COMMANDE_CLIENT\" IN []"; |
} |
// Fix bad default value |
if (tableCmdElt.contains("LIVRE")) { |
AlterTable t = new AlterTable(tableCmdElt); |
t.alterColumnDefault("LIVRE", "false"); |
tableCmdElt.getBase().getDataSource().execute(t.asString()); |
root.refetchTable(tableCmdElt.getName()); |
root.getSchema().updateVersion(); |
} |
// Achat |
SQLTable tableBRElt = root.getTable("BON_RECEPTION_ELEMENT"); |
864,6 → 885,14 |
tableArt.fetchFields(); |
} |
if (!tableArt.contains("ADDITIONAL_TICKET_COPY")) { |
final AlterTable alterArt = new AlterTable(tableArt); |
alterArt.addBooleanColumn("ADDITIONAL_TICKET_COPY", Boolean.FALSE, false); |
tableArt.getBase().getDataSource().execute(alterArt.asString()); |
tableArt.getSchema().updateVersion(); |
tableArt.fetchFields(); |
} |
SQLTable tableDevisAcompte = root.getTable("DEVIS"); |
if (!tableDevisAcompte.contains("T_ACOMPTE")) { |
1017,9 → 1046,9 |
} |
// Prefs compte AN |
SQLTable table = root.findTable("PREFS_COMPTE"); |
AlterTable t = new AlterTable(table); |
if (!table.getFieldsName().contains("ID_JOURNAL_AN")) { |
AlterTable t = new AlterTable(table); |
t.addForeignColumn("ID_JOURNAL_AN", root.getTable("JOURNAL")); |
t.addBooleanColumn("CREATE_NUL_SOLDE_ECR", Boolean.TRUE, false); |
table.getBase().getDataSource().execute(t.asString()); |
1027,6 → 1056,14 |
table.fetchFields(); |
} |
if (!table.getFieldsName().contains("AUTO_LETTRAGE")) { |
AlterTable t = new AlterTable(table); |
t.addBooleanColumn("AUTO_LETTRAGE", Boolean.FALSE, false); |
table.getBase().getDataSource().execute(t.asString()); |
table.getSchema().updateVersion(); |
table.fetchFields(); |
} |
SQLTable tableEcr = root.getTable("ECRITURE"); |
if (!tableEcr.contains("CLOTURE")) { |
final AlterTable alter = new AlterTable(tableEcr); |
1046,15 → 1083,72 |
tkmElt.getSchema().updateVersion(); |
tkmElt.fetchFields(); |
} |
// Ref bancaires fournisseurs |
if (!tableFournisseur.contains("IBAN")) { |
final AlterTable alter = new AlterTable(tableFournisseur); |
// Ref bancaires fournisseurs et clients |
for (final SQLTable bankT : Arrays.asList(tableFournisseur, tClient)) { |
if (!bankT.contains("IBAN")) { |
final AlterTable alter = new AlterTable(bankT); |
alter.addVarCharColumn("IBAN", 128); |
alter.addVarCharColumn("BIC", 128); |
tableFournisseur.getBase().getDataSource().execute(alter.asString()); |
tableFournisseur.getSchema().updateVersion(); |
tableFournisseur.fetchFields(); |
bankT.getDBSystemRoot().getDataSource().execute(alter.asString()); |
bankT.getSchema().updateVersion(); |
bankT.fetchFields(); |
} |
} |
final SQLTable typeReglT = root.getTable("TYPE_REGLEMENT"); |
if (typeReglT.getRow(TypeReglementSQLElement.PRELEVEMENT) == null) { |
final SQLRowValues directDebitVals = new SQLRowValues(typeReglT).put("NOM", "Prélèvement"); |
directDebitVals.put("COMPTANT", Boolean.FALSE).put("ECHEANCE", Boolean.FALSE); |
directDebitVals.setID(TypeReglementSQLElement.PRELEVEMENT).insertVerbatim(); |
} |
if (!tableClient.contains("ACCEPTE_EMAIL")) { |
final AlterTable alter = new AlterTable(tableClient); |
alter.addBooleanColumn("ACCEPTE_EMAIL", Boolean.FALSE, false); |
alter.addBooleanColumn("ACCEPTE_COURRIER", Boolean.FALSE, false); |
alter.addBooleanColumn("ACCEPTE_SMS", Boolean.FALSE, false); |
alter.addBooleanColumn("ACCEPTE_TEL", Boolean.FALSE, false); |
exec(alter); |
} |
final SQLTable contactT = root.getTable("CONTACT"); |
if (!contactT.contains("DATE_NAISSANCE")) { |
final AlterTable alter = new AlterTable(contactT); |
alter.addColumn("DATE_NAISSANCE", "date"); |
exec(alter); |
} |
final SQLCreateTable createSDDMsgTable = SDDMessageSQLElement.getCreateTable(root); |
if (createSDDMsgTable != null) { |
final SQLCreateTable createMandate = SEPAMandateSQLElement.getCreateTable(root); |
root.createTables(createSDDMsgTable, createMandate); |
final SQLTable msgT = root.getTable(createSDDMsgTable.getName()); |
final SQLTable mandateT = root.getTable(createMandate.getName()); |
final AlterTable alterFact = new AlterTable(root.getTable(SaisieVenteFactureSQLElement.TABLENAME)); |
alterFact.addForeignColumn(SaisieVenteFactureSQLElement.MESSAGE_FIELD_NAME, msgT); |
alterFact.addVarCharColumn(SaisieVenteFactureSQLElement.END2END_FIELD_NAME, 35); |
final AlterTable alterModeRegl = new AlterTable(root.getTable("MODE_REGLEMENT")); |
alterModeRegl.addForeignColumn(null, mandateT); |
for (final String sql : ChangeTable.cat(Arrays.asList(alterFact, alterModeRegl))) { |
root.getDBSystemRoot().getDataSource().execute(sql); |
} |
root.getSchema().updateVersion(); |
root.refetch(CollectionUtils.createSet(alterFact.getName(), alterModeRegl.getName())); |
root.setMetadata(SDDMessageSQLElement.SERIAL_MD, "0"); |
} |
final SQLTable vcT = root.getTable("SAISIE_VENTE_COMPTOIR"); |
if (!vcT.contains("ID_COMPTE_PCE_PRODUIT")) { |
final AlterTable alter = new AlterTable(vcT); |
alter.addForeignColumn("ID_COMPTE_PCE_PRODUIT", root.getTable("COMPTE_PCE")); |
alter.addForeignColumn("ID_COMPTE_PCE_SERVICE", root.getTable("COMPTE_PCE")); |
exec(alter); |
} |
} |
public static void exec(final AlterTable alter) throws SQLException { |
alter.getTable().getDBSystemRoot().getDataSource().execute(alter.asString()); |
alter.getTable().getSchema().updateVersion(); |
alter.getTable().fetchFields(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/InstallationPanel.java |
---|
903,7 → 903,7 |
size = 2048; |
else |
// e.g. IDCC.NOM > 350 |
size = 1024; |
size = 512; |
alter.alterColumn(fName, EnumSet.allOf(Properties.class), "varchar(" + size + ")", "''", false); |
} |
} |
918,12 → 918,8 |
} |
for (final String sql : ChangeTable.cat(alters, root.getName())) { |
try { |
// ds.execute(sql); |
} catch (Exception e) { |
e.printStackTrace(); |
ds.execute(sql); |
} |
} |
root.refetch(); |
} |
3748,37 → 3744,6 |
if (ProductInfo.getInstance().getName().equalsIgnoreCase("OpenConcerto")) { |
final SQLTable tableExercice = root.getTable("EXERCICE_COMMON"); |
// FIXME UPDATE Base ILM 1.2->1.3 la table EXERCERCIE ne contenait pas la clef |
// ID_SOCIETE_COMMON |
// if (tableExercice.contains("ID_SOCIETE_COMMON")) { |
String reqUp = "UPDATE " + tableExercice.getSQLName().quote() + " SET \"ID_SOCIETE_COMMON\"=1 WHERE "; |
reqUp += new Where(tableExercice.getKey(), 3, 49).getClause(); |
root.getDBSystemRoot().getDataSource().execute(reqUp); |
String reqUp2 = "UPDATE " + tableExercice.getSQLName().quote() + " SET \"ID_SOCIETE_COMMON\"=1 WHERE "; |
reqUp2 += new Where(tableExercice.getKey(), 53, 57).getClause(); |
root.getDBSystemRoot().getDataSource().execute(reqUp2); |
// } |
// rm ID 43 - 47 de SOCIETE_COMMON |
final SQLTable tableSociete = root.getTable("SOCIETE_COMMON"); |
String req3 = "DELETE FROM " + tableSociete.getSQLName().quote() + " WHERE "; |
req3 += new Where(tableSociete.getKey(), 43, 47).getClause(); |
root.getDBSystemRoot().getDataSource().execute(req3); |
// rm ID 3 à 49 de EXERCICE_COMMON |
String req1a = "DELETE FROM " + tableExercice.getSQLName().quote() + " WHERE "; |
req1a += new Where(tableExercice.getKey(), 3, 49).getClause(); |
root.getDBSystemRoot().getDataSource().execute(req1a); |
// et 53-57 |
root.getDBSystemRoot().getDataSource().execute(req1a); |
String req1b = "DELETE FROM " + tableExercice.getSQLName().quote() + " WHERE "; |
req1b += new Where(tableExercice.getKey(), 53, 57).getClause(); |
root.getDBSystemRoot().getDataSource().execute(req1b); |
// |
// TACHE_COMMON, ID_USER_COMMON_*=0 -> 1 |
for (final String f : Arrays.asList("ID_USER_COMMON_TO", "ID_USER_COMMON_CREATE", "ID_USER_COMMON_ASSIGN_BY")) { |
final SQLTable tableTache = root.getTable("TACHE_COMMON"); |
3799,6 → 3764,13 |
} |
} |
final SQLTable sociétéT = root.getTable("SOCIETE_COMMON"); |
if (!sociétéT.contains("SEPA_CREDITOR_ID")) { |
final AlterTable alter = new AlterTable(sociétéT); |
alter.addVarCharColumn("SEPA_CREDITOR_ID", 16); |
Updater_1_5.exec(alter); |
} |
// FK |
new AddFK(root.getDBSystemRoot()).changeAll(root); |
} |
3935,8 → 3907,19 |
} |
} |
if (!table.getFieldsName().contains("SITE_WEB")) { |
AlterTable t2 = new AlterTable(table); |
t2.addVarCharColumn("SITE_WEB", 128); |
t2.alterColumn("CAPITAL", EnumSet.allOf(Properties.class), "numeric(16,2)", "0", false); |
table.getBase().getDataSource().execute(t2.asString()); |
table.getSchema().updateVersion(); |
table.fetchFields(); |
} |
} |
private void updateVille(SQLTable tableAdresse) throws SQLException { |
if (tableAdresse != null && tableAdresse.getField("CODE_POSTAL").getType().getJavaType() == Integer.class) { |
4034,7 → 4017,73 |
} |
// Paye simplifiee |
List<SQLRow> rowRubriqueReduGvt = new ArrayList<>(); |
{ |
final SQLTable tableRCom = conf.getRoot().getTable("RUBRIQUE_COMM"); |
if (!tableRCom.contains("REDUCTION_GVT_COM")) { |
final AlterTable alter = new AlterTable(tableRCom); |
alter.addBooleanColumn("REDUCTION_GVT_COM", Boolean.FALSE, false); |
final String req = alter.asString(); |
conf.getRoot().getDBSystemRoot().getDataSource().execute(req); |
conf.getRoot().refetchTable(tableRCom.getName()); |
conf.getRoot().getSchema().updateVersion(); |
SQLRowValues rowValsCommChom = new SQLRowValues(tableRCom); |
rowValsCommChom.put("TAUX_SAL", "1.45;"); |
rowValsCommChom.put("NB_BASE", "SAL_BRUT;"); |
rowValsCommChom.put("NOM", "Assurance chômage reduction 2018"); |
rowValsCommChom.put("CODE", "OC_REDUCTION_CHOMAGE"); |
rowValsCommChom.put("MONTANT_SAL_DED", "SAL_BRUT * 0.0145;"); |
rowValsCommChom.put("NB_BASE", "SAL_BRUT;"); |
rowValsCommChom.put("ID_IMPRESSION_RUBRIQUE", 4); |
rowValsCommChom.put("REDUCTION_GVT_COM", Boolean.TRUE); |
rowValsCommChom.putRowValues("ID_PERIODE_VALIDITE").put("JANVIER", Boolean.TRUE); |
rowRubriqueReduGvt.add(rowValsCommChom.commit()); |
SQLRowValues rowValsCommMaladie = new SQLRowValues(tableRCom); |
rowValsCommMaladie.put("TAUX_SAL", "0.75;"); |
rowValsCommMaladie.put("NB_BASE", "SAL_BRUT;"); |
rowValsCommMaladie.put("NOM", "Assurance maladie reduction 2018"); |
rowValsCommMaladie.put("CODE", "OC_REDUCTION_MALADIE"); |
rowValsCommMaladie.put("MONTANT_SAL_DED", "SAL_BRUT * 0.0075;"); |
rowValsCommMaladie.put("NB_BASE", "SAL_BRUT;"); |
rowValsCommMaladie.put("ID_IMPRESSION_RUBRIQUE", 4); |
rowValsCommMaladie.put("REDUCTION_GVT_COM", Boolean.TRUE); |
rowValsCommMaladie.putRowValues("ID_PERIODE_VALIDITE").put("JANVIER", Boolean.TRUE); |
rowRubriqueReduGvt.add(rowValsCommMaladie.commit()); |
SQLRowValues rowValsCommCSG = new SQLRowValues(tableRCom); |
rowValsCommCSG.put("TAUX_SAL", "1.7;"); |
rowValsCommCSG.put("NB_BASE", "CSG;"); |
rowValsCommCSG.put("NOM", "CSG augmentation 2018"); |
rowValsCommCSG.put("CODE", "OC_AUGMENTATION_CSG"); |
rowValsCommCSG.put("MONTANT_SAL_AJ", "CSG * 0.017;"); |
rowValsCommCSG.put("NB_BASE", "CSG;"); |
rowValsCommCSG.put("ID_IMPRESSION_RUBRIQUE", 4); |
rowValsCommCSG.put("REDUCTION_GVT_COM", Boolean.TRUE); |
rowValsCommCSG.putRowValues("ID_PERIODE_VALIDITE").put("JANVIER", Boolean.TRUE); |
rowRubriqueReduGvt.add(rowValsCommCSG.commit()); |
SQLSelect sel = new SQLSelect(); |
sel.addSelect(conf.getRoot().getTable("PROFIL_PAYE").getKey()); |
List<SQLRow> rowsProfil = SQLRowListRSH.execute(sel); |
int pos = 70; |
for (SQLRow rowRub : rowRubriqueReduGvt) { |
for (SQLRow rowProfil : rowsProfil) { |
SQLRowValues rowValsRubGvt = new SQLRowValues(conf.getRoot().getTable("PROFIL_PAYE_ELEMENT")); |
rowValsRubGvt.put("ID_PROFIL_PAYE", rowProfil.getID()); |
rowValsRubGvt.put("POSITION", pos); |
rowValsRubGvt.put("IDSOURCE", rowRub.getID()); |
rowValsRubGvt.put("SOURCE", rowRub.getTable().getName()); |
rowValsRubGvt.put("NOM", rowRub.getString("NOM")); |
rowValsRubGvt.commit(); |
} |
pos++; |
} |
} |
final SQLTable tableRB = conf.getRoot().getTable("RUBRIQUE_BRUT"); |
if (!tableRB.contains("AVANTAGE_NATURE")) { |
final AlterTable alter = new AlterTable(tableRB); |
4125,7 → 4174,7 |
alter.addVarCharColumn("NUMERO_COMPTE_PCE_CHARGES", 128); |
final String req = alter.asString(); |
conf.getRoot().getDBSystemRoot().getDataSource().execute(req); |
conf.getRoot().refetchTable(tableCaisse.getName()); |
conf.getRoot().refetchTable(tableRnet.getName()); |
conf.getRoot().getSchema().updateVersion(); |
} |
4314,6 → 4363,37 |
updateVille(root.getTable("ADRESSE")); |
Updater_1_5.update(root); |
SQLTable tableFpaye = root.getTable("FICHE_PAYE"); |
if (!tableFpaye.contains("REDUCTION_GVT")) { |
final AlterTable alterB = new AlterTable(tableFpaye); |
alterB.addDecimalColumn("REDUCTION_GVT", 16, 2, BigDecimal.ZERO, false); |
root.getBase().getDataSource().execute(alterB.asString()); |
root.refetchTable("FICHE_PAYE"); |
root.getSchema().updateVersion(); |
SQLSelect sel = new SQLSelect(); |
sel.addSelect(root.getTable("SALARIE").getKey()); |
sel.addSelect(root.getTable("SALARIE").getField("ID_FICHE_PAYE")); |
List<SQLRow> rowsSal = SQLRowListRSH.execute(sel); |
int pos = 70; |
for (SQLRow rowRub : rowRubriqueReduGvt) { |
for (SQLRow rowSal : rowsSal) { |
SQLRowValues rowValsRubGvt = new SQLRowValues(root.getTable("FICHE_PAYE_ELEMENT")); |
rowValsRubGvt.put("ID_FICHE_PAYE", rowSal.getForeignID("ID_FICHE_PAYE")); |
rowValsRubGvt.put("POSITION", pos); |
rowValsRubGvt.put("IDSOURCE", rowRub.getID()); |
rowValsRubGvt.put("SOURCE", rowRub.getTable().getName()); |
rowValsRubGvt.put("NOM", rowRub.getString("NOM")); |
rowValsRubGvt.put("IN_PERIODE", Boolean.TRUE); |
rowValsRubGvt.put("IMPRESSION", Boolean.FALSE); |
rowValsRubGvt.put("VALIDE", Boolean.FALSE); |
rowValsRubGvt.commit(); |
} |
pos++; |
} |
} |
return null; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mapping_en.xml |
---|
192,6 → 192,7 |
<FIELD name="CAPITAL" label="Capital" /> |
<FIELD name="NUMERO_URSSAF" label="URSSAF number" /> |
<FIELD name="ID_DEVISE" label="Currency" /> |
<FIELD name="SEPA_CREDITOR_ID" label="SEPA Creditor Identifier" /> |
</TABLE> |
<TABLE name="TYPE_MODELE"> |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/SQLElementNames_fr.xml |
---|
2,6 → 2,8 |
<element refid="CONTACT" nameClass="masculine" name="contact" /> |
<element refid="CONTACT_FOURNISSEUR" nameClass="masculine" name="contact fournisseur" namePlural="contacts fournisseurs" /> |
<element refid="CONTACT_ADMINISTRATIF" nameClass="masculine" name="contact administratif" namePlural="contacts administratifs" /> |
<element refid="CATEGORIE_CLIENT" nameClass="feminine" name="Catégorie de client" /> |
<element refid="customerrelationship.customer.category" nameClass="feminine" name="catégorie de client" /> |
<element refid="FAMILLE_ECO_CONTRIBUTION" nameClass="feminine" name="Famille d'éco contribution" /> |
<element refid="finance.payment.SDDMessage" nameClass="masculine" name="ordre de prélèvement SEPA" namePlural="ordres de prélèvement SEPA" /> |
<element refid="finance.payment.SEPAMandate" nameClass="masculine" name="mandat SEPA" namePlural="mandats SEPA" /> |
</translations> |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/translation_fr.xml |
---|
110,6 → 110,7 |
<menu id="customer.payment.followup.list" label="Liste des relances" /> |
<menu id="customer.payment.check.pending.list" label="Chèques des clients" /> |
<menu id="customer.payment.check.pending.create" label="Chèques à encaisser" /> |
<menu id="customer.payment.sddMessage.list" label="Liste des ordres de prélèvement SEPA" /> |
<menu id="customer.credit.check.list" label="Chèques d'avoir" /> |
<menu id="customer.credit.check.create" label="Chèques d'avoir à décaisser" /> |
<menu id="menu.payment.supplier" label="Fournisseurs" /> |
247,6 → 248,7 |
<item id="invoice.address.same.main.address" label="Adresse identique à l'adresse du siège" /> |
<item id="customerrelationship.customer.address" label="Adresses" /> |
<item id="customerrelationship.customer.contact" label="Contacts" /> |
<item id="customerrelationship.customer.lead" label="Prospection" /> |
<item id="customerrelationship.customer.sales" label="Ventes" /> |
<item id="customerrelationship.customer.payment" label="Paiements" /> |
<item id="customerrelationship.customer.contacts" label="Personnes à contacter chez le client" /> |
290,7 → 292,7 |
<item id="retraite.trancheC" label="Complémentaire Tranche C" /> |
<item id="retraite.supplementaire" label="Supplémentaire" /> |
<item id="famille.famille.allocations" label="Allocations familiales" /> |
<item id="famille.famille.securite" label="Famille-SECURITE SOCIALE" /> |
<item id="famille.famille.securite" label="FAMILLE" /> |
<item id="chomage.chomage" label="Chômage" /> |
<item id="chomage.apec" label="APEC" /> |
298,7 → 300,7 |
<item id="autres.contributions.ligne" label="Autres contributions dues par l'employeur" /> |
<item id="csg.nonimp.ligne" label="CSG non imposable à l'impôt sur le revenu" /> |
<item id="csg.imp.ligne" label="CSG/CRDS imposable à l'impôt sur le revenu" /> |
<item id="allegement.cotisations.ligne" label="Allégement de cotisations" /> |
<item id="allegement.cotisations.ligne" label="Exonération de cotisations employeur" /> |
<item id="paye.simplifie.ignore" label="Ligne ignorée" /> |
<!-- Groupe Paye Simplifiée --> |
311,8 → 313,8 |
<item id="chomage.cadre" label="ASSURANCE CHÔMAGE" /> |
<item id="autres" label="AUTRES CONTRIBUTIONS DUES PAR L'EMPLOYEUR" /> |
<item id="cotisations.convention" label="COTISATIONS DE CONVENTION COLLECTIVE OU STATUAIRES" /> |
<item id="csg.nonimp" label="CSG/CRDS non imposable à l'impôt sur le revenu" /> |
<item id="csg.imp" label="CSG/CRDS imposable à l'impôt sur le revenu" /> |
<item id="csg.nonimp" label="CSG/CRDS déductible de l'impôt sur le revenu" /> |
<item id="csg.imp" label="CSG/CRDS non déductible à l'impôt sur le revenu" /> |
<item id="allegement" label="ALLEGEMENT DE COTISATIONS" /> |
</translation> |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mappingCompta_fr.xml |
---|
581,6 → 581,9 |
<FIELD name="NUMERO" label="Numéro" /> |
</TABLE> |
<TABLE name="CATEGORIE_CLIENT"> |
<FIELD name="NOM" label="Catégorie client" /> |
</TABLE> |
<TABLE name="CATEGORIE_COMPTABLE"> |
<FIELD name="NOM" label="Nom" titlelabel="Catégorie" /> |
676,6 → 679,10 |
<FIELD name="TEL_P" label="Portable" titlelabel="Portable" /> |
<FIELD name="FAX" label="Fax" titlelabel="Fax" /> |
<FIELD name="MAIL" label="Mail" titlelabel="Mail" /> |
<FIELD name="ACCEPTE_EMAIL" label="Accepte e-mail" titlelabel="E-mail OK" /> |
<FIELD name="ACCEPTE_COURRIER" label="Accepte courrier" titlelabel="Courrier OK" /> |
<FIELD name="ACCEPTE_SMS" label="Accepte SMS" titlelabel="SMS OK" /> |
<FIELD name="ACCEPTE_TEL" label="Accepte appel téléphonique" titlelabel="Appel tél. OK" /> |
<FIELD name="RESPONSABLE" label="Responsable" titlelabel="Responsable" /> |
<FIELD name="RESPONSABLE_TECH" label="Responsable tech." titlelabel="Responsable tech." /> |
<FIELD name="RESPONSABLE_COM" label="Responsable comm." titlelabel="Responsable comm." /> |
699,7 → 706,9 |
<FIELD name="ID_ADRESSE_L" label="Adresse de livraison" titlelabel="Adresse livraison" /> |
<FIELD name="ID_ADRESSE_L_2" label="Adresse de livraison" titlelabel="Adresse livraison 2" /> |
<FIELD name="ID_ADRESSE_L_3" label="Adresse de livraison" titlelabel="Adresse livraison 3" /> |
<FIELD name="RIB" label="RIB" titlelabel="RIB" /> |
<FIELD name="RIB" label="RIB" /> |
<FIELD name="IBAN" label="IBAN" /> |
<FIELD name="BIC" label="BIC" /> |
<FIELD name="SIRET" label="SIRET" titlelabel="SIRET" /> |
<FIELD name="ID_SECTEUR_ACTIVITE" label="Secteur d'activité" titlelabel="Secteur d'activité" /> |
<FIELD name="ID_BANQUE_POLE_PRODUIT" label="Banque" titlelabel="Banque" /> |
822,6 → 831,7 |
<FIELD name="SERVICE" label="Service" /> |
<FIELD name="PAYS" label="Pays" /> |
<FIELD name="ID_ADRESSE" label="Adresse" /> |
<FIELD name="DATE_NAISSANCE" label="Date de naissance" /> |
</TABLE> |
<TABLE name="CONTACT_FOURNISSEUR"> |
2202,6 → 2212,8 |
<TABLE name="SAISIE_VENTE_COMPTOIR"> |
<FIELD name="ID_COMPTE_PCE_PRODUIT" label="Cpt spécifique produit" /> |
<FIELD name="ID_COMPTE_PCE_SERVICE" label="Cpt spécifique service" /> |
<FIELD name="NOM" label="Libellé" /> |
<FIELD name="ID_ARTICLE" label="Article" titlelabel="Article" /> |
<FIELD name="DATE" label="Date" titlelabel="Date" /> |
2273,6 → 2285,7 |
<FIELD name="COMPTE_SERVICE_AUTO" label="Gestion automatique du compte de service" titlelabel="Gestion automatique du compte de service" /> |
<FIELD name="ID_TARIF" label="Tarif à appliquer" /> |
<FIELD name="T_ECO_CONTRIBUTION" label="Dont Eco-Contrib." /> |
<FIELD name="ID_SDD_MESSAGE" label="Ordre de prélèvement SEPA" titlelabel="Prélèv. SEPA" /> |
</TABLE> |
<TABLE name="SAISIE_VENTE_FACTURE_ELEMENT"> |
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" /> |
2439,6 → 2452,8 |
<FIELD name="ID_COMPTE_PCE_DED" label="Compte TVA déductible" /> |
<FIELD name="ID_COMPTE_PCE_VENTE" label="Compte produits par défaut (classe 7)" /> |
<FIELD name="ID_COMPTE_PCE_SERVICE" label="Compte services par défaut (classe 7)" /> |
<FIELD name="ID_COMPTE_PCE_COLLECTE_INTRA" label="Compte TVA collectée intra." /> |
<FIELD name="ID_COMPTE_PCE_DED_INTRA" label="Compte TVA déductible intra." /> |
</TABLE> |
<TABLE name="TAXE_COMPLEMENTAIRE"> |
2497,4 → 2512,19 |
<FIELD name="NOM" label="Libellé" /> |
</TABLE> |
<TABLE name="SEPA_MANDATE"> |
<FIELD name="ID_CLIENT" label="Client" /> |
<FIELD name="MandateIdentification" label="Identifiant" /> |
<FIELD name="DateOfSignature" label="Date de signature" titlelabel="Date sign." /> |
<FIELD name="SequenceType" label="Type de séquence" titlelabel="Type de séq." /> |
<FIELD name="ACTIVE" label="Actif" /> |
</TABLE> |
<TABLE name="SEPA_DIRECT_DEBIT_MESSAGE"> |
<FIELD name="MessageIdentification" label="Identifiant du message" /> |
<FIELD name="CreationDateTime" label="Date de création" /> |
<FIELD name="NumberOfTransactions" label="Nombre de prélèvements" /> |
<FIELD name="ControlSum" label="Total des prélèvements" /> |
<FIELD name="XML" label="Message XML" /> |
</TABLE> |
</ROOT> |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/DBContext.java |
---|
24,7 → 24,7 |
import org.openconcerto.sql.utils.SQLCreateTableBase; |
import org.openconcerto.utils.CollectionUtils; |
import org.openconcerto.utils.SetMap; |
import org.openconcerto.utils.cc.IClosure; |
import org.openconcerto.utils.cc.IExnClosure; |
import java.io.File; |
import java.sql.SQLException; |
48,9 → 48,9 |
private final DBRoot root; |
private final SQLElementDirectory elemDir; |
private final List<ChangeTable<?>> changeTables; |
private int changeTablesIndex = 0; |
// subset of this.changeTables |
private final List<AlterTableRestricted> alterTables; |
// Data Manipulation |
private final List<IClosure<? super DBRoot>> dm; |
private final Set<String> tables; |
private final SetMap<String, SQLField> fields; |
71,7 → 71,6 |
this.elemDir = elemDir; |
this.changeTables = new ArrayList<ChangeTable<?>>(); |
this.alterTables = new ArrayList<AlterTableRestricted>(); |
this.dm = new ArrayList<IClosure<? super DBRoot>>(); |
} |
public final File getLocalDirectory() { |
102,12 → 101,17 |
return this.fields.getNonNull(tableName); |
} |
private final List<String> getSQL() { |
return ChangeTable.cat(this.changeTables, this.root.getName()); |
} |
final void execute() throws SQLException { |
final List<String> sql = this.getSQL(); |
/** |
* Allow to execute all pending DDL changes. Automatically called at the end of |
* {@link AbstractModule#install(DBContext)} by {@link ModuleManager}. For example, one could |
* create a new field, call this method, fill the new field with a function needing another old |
* field, and finally drop the old field. |
* |
* @throws SQLException if an error occurs. |
*/ |
public final void executeSQL() throws SQLException { |
final List<ChangeTable<?>> toDo = this.changeTables.subList(this.changeTablesIndex, this.changeTables.size()); |
final List<String> sql = ChangeTable.cat(toDo, this.root.getName()); |
// refetch() is costly |
if (sql.size() > 0) { |
for (final String s : sql) |
115,16 → 119,14 |
// perhaps add a Map parameter to getCreateTable() for the undefined row |
// for now OK to not use an undefined row since we can't modify List/ComboSQLRequet |
SQLTable.setUndefIDs(getRoot().getSchema(), CollectionUtils.<String, Number> createMap(getAddedTables())); |
SQLTable.setUndefIDs(getRoot().getSchema(), CollectionUtils.<String, Number> createMap(getCreateTables(toDo).keySet())); |
// always updateVersion() after setUndefID(), see DBRoot.createTables() |
getRoot().getSchema().updateVersion(); |
getRoot().refetch(); |
} |
for (final IClosure<? super DBRoot> closure : this.dm) { |
closure.executeChecked(getRoot()); |
this.changeTablesIndex = this.changeTables.size(); |
} |
} |
// DDL |
165,9 → 167,12 |
* inserting rows in a created table, since it will be automatically dropped). |
* |
* @param closure what to do. |
* @throws SQLException if an error occurs. |
* @deprecated no longer needed, just call {@link #executeSQL()} before accessing the DB. |
*/ |
public final void manipulateData(final IClosure<? super DBRoot> closure) { |
this.dm.add(closure); |
public final void manipulateData(final IExnClosure<? super DBRoot, SQLException> closure) throws SQLException { |
executeSQL(); |
closure.executeChecked(getRoot()); |
} |
/** |
176,26 → 181,24 |
* |
* @param name a table name. |
* @param closure what to do. |
* @see #manipulateData(IClosure) |
* @throws SQLException if an error occurs. |
* @deprecated no longer needed, just call {@link #executeSQL()} before accessing the DB. |
* @see #manipulateData(IExnClosure) |
*/ |
public final void manipulateTable(final String name, final IClosure<SQLTable> closure) { |
this.manipulateData(new IClosure<DBRoot>() { |
@Override |
public void executeChecked(DBRoot input) { |
closure.executeChecked(input.getTable(name)); |
public final void manipulateTable(final String name, final IExnClosure<? super SQLTable, SQLException> closure) throws SQLException { |
executeSQL(); |
closure.executeChecked(getRoot().getTable(name)); |
} |
}); |
} |
// getter |
final List<String> getAddedTables() { |
return new ArrayList<String>(getCreateTables().keySet()); |
return new ArrayList<String>(getCreateTables(this.changeTables).keySet()); |
} |
final Map<String, SQLCreateTableBase<?>> getCreateTables() { |
private static final Map<String, SQLCreateTableBase<?>> getCreateTables(final List<ChangeTable<?>> l) { |
final Map<String, SQLCreateTableBase<?>> res = new LinkedHashMap<String, SQLCreateTableBase<?>>(); |
for (final ChangeTable<?> a : this.changeTables) { |
for (final ChangeTable<?> a : l) { |
if (a instanceof SQLCreateTableBase<?>) { |
res.put(a.getName(), (SQLCreateTableBase<?>) a); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ElementContext.java |
---|
39,4 → 39,12 |
} |
return element; |
} |
public final <T extends SQLElement> T getElement(final Class<T> clazz) { |
final T element = this.dir.getElement(clazz); |
if (element == null) { |
throw new IllegalArgumentException("Not element found for " + clazz); |
} |
return element; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModulePanel.java |
---|
18,6 → 18,7 |
import org.openconcerto.erp.modules.ModuleTableModel.Columns; |
import org.openconcerto.erp.modules.ModuleTableModel.ModuleRow; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.table.AlternateTableCellRenderer; |
import org.openconcerto.ui.table.TableCellRendererDecorator.TableCellRendererDecoratorUtils; |
import org.openconcerto.utils.ExceptionHandler; |
90,6 → 91,7 |
t.setRowSelectionAllowed(false); |
t.setColumnSelectionAllowed(false); |
t.setCellSelectionEnabled(false); |
t.setRowHeight(FontUtils.getPreferredRowHeight(t)); |
final TableColumnModel columnModel = t.getColumnModel(); |
final TableCellRenderer headerDefaultRenderer = t.getTableHeader().getDefaultRenderer(); |
final EnumSet<Columns> booleanCols = EnumSet.of(ModuleTableModel.Columns.LOCAL, ModuleTableModel.Columns.REMOTE, ModuleTableModel.Columns.DB_REQUIRED, ModuleTableModel.Columns.ADMIN_REQUIRED); |
244,13 → 246,14 |
} |
if (deniedRefs.size() > 0) { |
JOptionPane |
.showMessageDialog(ModulePanel.this, "Désinstallation refusée pour les modules :" + formatList(deniedRefs), dialogTitle, JOptionPane.WARNING_MESSAGE); |
JOptionPane.showMessageDialog(ModulePanel.this, "Désinstallation refusée pour les modules :" + formatList(deniedRefs), dialogTitle, |
JOptionPane.WARNING_MESSAGE); |
return; |
} |
final int selectAnswer = JOptionPane.showConfirmDialog(ModulePanel.this, "Les modules suivants doivent être désinstallés : \n" + formatList(dependentModules) |
+ ".\nVoulez-vous également désinstaller ces modules ?", dialogTitle, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); |
final int selectAnswer = JOptionPane.showConfirmDialog(ModulePanel.this, |
"Les modules suivants doivent être désinstallés : \n" + formatList(dependentModules) + ".\nVoulez-vous également désinstaller ces modules ?", dialogTitle, |
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); |
if (selectAnswer == JOptionPane.NO_OPTION) |
return; |
} |
311,8 → 314,8 |
throw new IllegalArgumentException(action + " is neither START nor STOP"); |
this.action = action; |
this.start = action == ModuleAction.START; |
this.putValue(Action.SHORT_DESCRIPTION, this.start ? "Démarrer le(s) module(s), maintenir CTRL pour rendre obligatoire le démarrage" |
: "Arrête le(s) module(s), maintenir CTRL pour rendre facultatif le démarrage"); |
this.putValue(Action.SHORT_DESCRIPTION, |
this.start ? "Démarrer le(s) module(s), maintenir CTRL pour rendre obligatoire le démarrage" : "Arrête le(s) module(s), maintenir CTRL pour rendre facultatif le démarrage"); |
} |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/AbstractModule.java |
---|
20,6 → 20,7 |
import java.io.File; |
import java.io.IOException; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Collections; |
import java.util.HashMap; |
82,8 → 83,10 |
* necessary in {@link #uninstall(DBRoot)}. |
* |
* @param ctxt to create database objects. |
* @throws SQLException if a DB error occurs. |
* @throws IOException if a local error occurs. |
*/ |
protected void install(DBContext ctxt) { |
protected void install(DBContext ctxt) throws SQLException, IOException { |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleManager.java |
---|
492,8 → 492,8 |
SQLPreferences.getPrefTable(this.getRoot()); |
final List<ModuleReference> requiredModules = this.getDBRequiredModules(); |
requiredModules.addAll(getAdminRequiredModules()); |
final List<ModuleReference> requiredModules = new ArrayList<>(this.getAdminRequiredModules()); |
final List<ModuleReference> dbRequiredModules = new ArrayList<>(this.getDBRequiredModules()); |
// add modules previously chosen (before restart) |
final File toInstallFile = this.getToInstallFile(); |
Set<ModuleReference> toInstall = Collections.emptySet(); |
549,6 → 549,20 |
} |
} |
} |
// handle upgrades : the old version was not uninstalled and thus still in |
// dbRequiredModules, and the new version is in toInstall, so the DepSolver will error out |
// since both can't be installed at the same time. |
for (final ModuleReference toInstallRef : toInstall) { |
final Iterator<ModuleReference> iter = dbRequiredModules.iterator(); |
while (iter.hasNext()) { |
final ModuleReference dbReqRef = iter.next(); |
if (dbReqRef.getID().equals(toInstallRef.getID())) { |
L.config("Ignoring DB required " + dbReqRef + " because " + toInstallRef + " was requested from the last exit"); |
iter.remove(); |
} |
} |
} |
requiredModules.addAll(dbRequiredModules); |
requiredModules.addAll(toInstall); |
// if there's some choice to make, let the user make it |
584,8 → 598,17 |
} |
public final boolean needExit(final ModulesStateChange solution) { |
return solution.getReferencesToRemove().size() > 0; |
final Set<ModuleReference> refsToRemove = solution.getReferencesToRemove(); |
if (!refsToRemove.isEmpty()) { |
// only need to exit if the module is loaded into memory |
final Set<ModuleReference> registeredModules = this.getRegisteredModules(); |
for (final ModuleReference toRemove : refsToRemove) { |
if (registeredModules.contains(toRemove)) |
return true; |
} |
} |
return false; |
} |
// Preferences is thread-safe |
private Preferences getPrefs() { |
1023,8 → 1046,7 |
if (!localDir.exists()) |
throw new IOException("Modules shouldn't remove their directory"); |
// install in DB |
if (!dbOK) |
ctxt.execute(); |
ctxt.executeSQL(); |
updateModuleFields(factory, graph, ctxt); |
return null; |
} |
1056,7 → 1078,7 |
assert moduleVersion.equals(getModuleVersionInstalledLocally(factory.getID())) && moduleVersion.equals(getDBInstalledModuleVersion(factory.getID())); |
} |
private void registerSQLElements(final AbstractModule module) throws IOException { |
private void registerSQLElements(final AbstractModule module, Map<SQLTable, SQLElement> beforeElements) throws IOException { |
final ModuleReference id = module.getFactory().getReference(); |
synchronized (this.modulesElements) { |
// perhaps check that no other version of the module has been registered |
1066,7 → 1088,6 |
final Set<SQLTable> tablesWithMD = loadTranslations(getConf().getTranslator(), module, mdVariant); |
final SQLElementDirectory dir = getDirectory(); |
final Map<SQLTable, SQLElement> beforeElements = new HashMap<SQLTable, SQLElement>(dir.getElementsMap()); |
module.setupElements(dir); |
final IdentityHashMap<SQLElement, SQLElement> elements = new IdentityHashMap<SQLElement, SQLElement>(); |
// use IdentitySet so as not to call equals() since it triggers initFF() |
1159,6 → 1180,15 |
} |
} |
final Set<SQLElement> getRegisteredElements(final ModuleReference ref) { |
synchronized (this.modulesElements) { |
final IdentityHashMap<SQLElement, SQLElement> map = this.modulesElements.get(ref); |
if (map == null || map.isEmpty()) |
return Collections.emptySet(); |
return Collections.unmodifiableSet(new HashSet<SQLElement>(map.keySet())); |
} |
} |
private void setupComponents(final AbstractModule module, final Tuple2<Set<String>, Set<SQLName>> alreadyCreatedItems, final MenuAndActions ma) throws SQLException { |
assert SwingUtilities.isEventDispatchThread(); |
final String id = module.getFactory().getID(); |
1513,6 → 1543,9 |
throw new IllegalStateException("Installation state has changed since getSolutions()"); |
} |
// call it before stopping/uninstalling |
final boolean exit = this.isExitAllowed() && this.needExit(change); |
final Set<ModuleReference> toRemove = change.getReferencesToRemove(); |
final Set<ModuleReference> removed; |
if (toRemove.size() > 0) { |
1535,7 → 1568,7 |
// MAYBE compare states with targetState to avoid going further (e.g ids are all started) |
if (this.isExitAllowed() && this.needExit(change)) { |
if (exit) { |
// restart to make sure the uninstalled modules are really gone from the memory and |
// none of its effects present. We could check that the class loader for the module |
// is garbage collected, but |
1748,6 → 1781,9 |
private final void installAndRegister(final AbstractModule module, DepSolverGraph graph) throws Exception { |
assert Thread.holdsLock(this); |
assert !isModuleRunning(module.getFactory().getID()); |
// Snapshot now to allow install() to register and use its own elements |
// Also needed for checks, since install() can do arbitrary changes to the directory |
final Map<SQLTable, SQLElement> beforeElements = new HashMap<SQLTable, SQLElement>(getDirectory().getElementsMap()); |
try { |
install(module, graph); |
} catch (Exception e) { |
1754,7 → 1790,7 |
throw new Exception("Couldn't install module " + module, e); |
} |
try { |
this.registerSQLElements(module); |
this.registerSQLElements(module, beforeElements); |
} catch (Exception e) { |
throw new Exception("Couldn't register module " + module, e); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/DmdPrixCmdSQLInjector.java |
---|
New file |
0,0 → 1,27 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.injector; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.model.SQLInjector; |
public class DmdPrixCmdSQLInjector extends SQLInjector { |
public DmdPrixCmdSQLInjector(final DBRoot root) { |
super(root, "DEMANDE_PRIX", "COMMANDE", true); |
createDefaultMap(); |
remove(getSource().getField("DATE"), getDestination().getField("DATE")); |
remove(getSource().getField("NUMERO"), getDestination().getField("NUMERO")); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SpreadSheetCellValueContext.java |
---|
64,4 → 64,8 |
public void put(String name, String value) { |
map.put(name, value); |
} |
public Object get(String name) { |
return map.get(name); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetXml.java |
---|
326,7 → 326,7 |
*/ |
public String getTemplateId() { |
if (this.row != null && this.row.getTable().getFieldsName().contains("ID_MODELE")) { |
if (row.isForeignEmpty("ID_MODELE")) { |
if (row.getObject("ID_MODELE") == null || row.isForeignEmpty("ID_MODELE")) { |
TypeModeleSQLElement typeModele = Configuration.getInstance().getDirectory().getElement(TypeModeleSQLElement.class); |
String modele = typeModele.getTemplateMapping().get(this.row.getTable().getName()); |
if (modele == null) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractSheetXMLWithDate.java |
---|
27,9 → 27,13 |
protected final String getYear() { |
Calendar cal = null; |
if (this.row.getTable().contains("DATE")) { |
cal = this.row.getDate("DATE"); |
} |
if (this.row.getTable().contains("DU")) { |
cal = this.row.getDate("DU"); |
} |
return cal == null ? "Date inconnue" : String.valueOf(cal.get(Calendar.YEAR)); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/TotalAcompteProvider.java |
---|
16,7 → 16,6 |
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueContext; |
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProvider; |
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProviderManager; |
import org.openconcerto.sql.model.SQLRow; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import java.math.BigDecimal; |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementChequeClient.java |
---|
22,10 → 22,13 |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.utils.StringUtils; |
import java.sql.SQLException; |
import java.sql.Timestamp; |
import java.util.ArrayList; |
import java.util.Date; |
import java.util.List; |
public class GenerationMvtReglementChequeClient extends GenerationEcritures { |
60,6 → 63,8 |
SQLRow chequeRow = base.getTable("CHEQUE_A_ENCAISSER").getRow(this.idCheque); |
SQLRow clientRow = base.getTable("CLIENT").getRow(chequeRow.getInt("ID_CLIENT")); |
this.nom = this.nom + " " + StringUtils.limitLength(clientRow.getString("NOM"), 20); |
// initialisation des valeurs de la map |
this.putValue("DATE", new java.sql.Date(this.date.getTime())); |
this.putValue("NOM", this.nom); |
104,6 → 109,11 |
this.putValue("DEBIT", new Long(this.montant)); |
this.putValue("CREDIT", new Long(0)); |
ajoutEcriture(); |
List<Integer> pieceIDs = new ArrayList<Integer>(); |
pieceIDs.add(mouvementTable.getRow(idMvt).getForeignID("ID_PIECE")); |
lettrageAuto(pieceIDs, this.date); |
System.err.println("Ecritures générées pour le mouvement " + this.idMvt); |
} |
122,9 → 132,7 |
rowValsUpdateVF.put("DATE_REGLEMENT", new Timestamp(d.getTime())); |
rowValsUpdateVF.update(); |
} |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationEcritures.java |
---|
15,6 → 15,7 |
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.common.ui.TotalCalculator; |
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement; |
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement; |
23,12 → 24,16 |
import org.openconcerto.erp.preferences.DefaultNXProps; |
import org.openconcerto.erp.preferences.GestionPieceCommercialePanel; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.element.SQLElement; |
import org.openconcerto.sql.model.SQLBackgroundTableCache; |
import org.openconcerto.sql.model.SQLBase; |
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.SQLTable; |
import org.openconcerto.sql.model.Where; |
import org.openconcerto.sql.users.UserManager; |
import org.openconcerto.utils.ExceptionHandler; |
579,4 → 584,66 |
this.mEcritures.put("ID_COMPTE_PCE", idPce); |
} |
protected void lettrageAuto(List<Integer> pieceIDs, Date d) { |
final SQLTable tablePrefCompte = base.getTable("PREFS_COMPTE"); |
final SQLRow rowPrefsCompte = SQLBackgroundTableCache.getInstance().getCacheForTable(tablePrefCompte).getRowFromId(2); |
if (rowPrefsCompte.getBoolean("AUTO_LETTRAGE")) { |
SQLSelect selEcr = new SQLSelect(); |
SQLTable tableEcr = base.getTable("ECRITURE"); |
selEcr.addSelect(tableEcr.getKey()); |
selEcr.addSelect(tableEcr.getField("DEBIT")); |
selEcr.addSelect(tableEcr.getField("CREDIT")); |
selEcr.addSelect(tableEcr.getField("LETTRAGE")); |
SQLTable tableCpte = base.getTable("COMPTE_PCE"); |
Where w2 = new Where(base.getTable("MOUVEMENT").getField("ID_PIECE"), pieceIDs); |
w2 = w2.and(new Where(tableEcr.getField("ID_MOUVEMENT"), "=", base.getTable("MOUVEMENT").getKey())); |
w2 = w2.and(new Where(tableEcr.getField("ID_COMPTE_PCE"), "=", tableCpte.getKey())); |
w2 = w2.and(new Where(tableCpte.getField("NUMERO"), "LIKE", "40%").or(new Where(tableCpte.getField("NUMERO"), "LIKE", "41%"))); |
w2 = w2.and(new Where(tableEcr.getField("DATE_LETTRAGE"), "=", (Object) null)); |
selEcr.setWhere(w2); |
long solde = -1; |
List<SQLRow> ecr = SQLRowListRSH.execute(selEcr); |
if (!ecr.isEmpty()) { |
solde = 0; |
for (SQLRow sqlRow2 : ecr) { |
solde += sqlRow2.getLong("DEBIT"); |
solde -= sqlRow2.getLong("CREDIT"); |
} |
} |
if (solde == 0) { |
String codeLettre = NumerotationAutoSQLElement.getNextCodeLettrage(); |
for (SQLRow sqlRow2 : ecr) { |
SQLRowValues rowValsEcr = sqlRow2.asRowValues(); |
// Lettrage |
// On lettre ou relettre la ligne avec le code saisi |
if (codeLettre.length() > 0) { |
rowValsEcr.put("LETTRAGE", codeLettre); |
rowValsEcr.put("DATE_LETTRAGE", d); |
try { |
rowValsEcr.update(); |
} catch (SQLException e1) { |
e1.printStackTrace(); |
} |
} |
// Mise à jour du code de lettrage |
SQLElement elt = Configuration.getInstance().getDirectory().getElement("NUMEROTATION_AUTO"); |
SQLRowValues rowVals = elt.getTable().getRow(2).createEmptyUpdateRow(); |
rowVals.put("CODE_LETTRAGE", codeLettre); |
try { |
rowVals.update(); |
} catch (SQLException ex) { |
ex.printStackTrace(); |
} |
} |
} |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationReglementVenteNG.java |
---|
214,8 → 214,18 |
this.putValue("CREDIT", Long.valueOf(0)); |
ajoutEcriture(); |
List<Integer> pieceIDs = new ArrayList<Integer>(); |
if (source.getTable().getName().equals("ENCAISSER_MONTANT")) { |
List<SQLRow> l = source.getReferentRows(base.getTable("ENCAISSER_MONTANT_ELEMENT")); |
for (SQLRow sqlRow : l) { |
pieceIDs.add(sqlRow.getForeign("ID_MOUVEMENT_ECHEANCE").getForeignID("ID_PIECE")); |
} |
} else { |
pieceIDs.add(mvtSource.getForeignID("ID_PIECE")); |
} |
lettrageAuto(pieceIDs, d); |
} |
} else { |
Date dateEch = ModeDeReglementSQLElement.calculDate(modeReglement.getInt("AJOURS"), modeReglement.getInt("LENJOUR"), this.date); |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieVenteFacture.java |
---|
59,6 → 59,10 |
* @param idMvt id du mouvement qui est dejà associé à la facture |
*/ |
public GenerationMvtSaisieVenteFacture(int idSaisieVenteFacture, int idMvt, boolean useComptePCEVente, boolean genereReglement) { |
this(idSaisieVenteFacture, idMvt, useComptePCEVente, genereReglement, false); |
} |
public GenerationMvtSaisieVenteFacture(int idSaisieVenteFacture, int idMvt, boolean useComptePCEVente, boolean genereReglement, boolean threadSafe) { |
System.err.println("********* init GeneRation"); |
this.idMvt = idMvt; |
this.idSaisieVenteFacture = idSaisieVenteFacture; |
65,6 → 69,7 |
this.useComptePCEVente = useComptePCEVente; |
this.genereReglement = genereReglement; |
// Submit in sheetxml queue in order to get the good paiement in document |
if (!threadSafe) |
SheetXml.submitInQueue(GenerationMvtSaisieVenteFacture.this); |
} |
82,11 → 87,15 |
* @param idSaisieVenteFacture |
*/ |
public GenerationMvtSaisieVenteFacture(int idSaisieVenteFacture) { |
this(idSaisieVenteFacture, 1); |
this(idSaisieVenteFacture, false); |
} |
private void genereMouvement() throws Exception { |
public GenerationMvtSaisieVenteFacture(int idSaisieVenteFacture, final boolean threadSafe) { |
this(idSaisieVenteFacture, 1, false, true, threadSafe); |
} |
public final void genereMouvement() throws Exception { |
SQLRow saisieRow = GenerationMvtSaisieVenteFacture.saisieVFTable.getRow(this.idSaisieVenteFacture); |
setRowAnalytiqueSource(saisieRow); |
SQLRow clientRow = saisieRow.getForeignRow("ID_CLIENT"); |
104,6 → 113,7 |
} else { |
this.nom = "Fact. vente " + saisieRow.getObject("NUMERO").toString(); |
} |
this.nom += " " + StringUtils.limitLength(clientRow.getString("NOM"), 20); |
this.putValue("NOM", this.nom); |
// iniatilisation des valeurs de la map |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieVenteComptoir.java |
---|
77,7 → 77,17 |
} |
this.putValue("ID_MOUVEMENT", new Integer(this.idMvt)); |
// generation des ecritures + maj des totaux du compte associe |
// Détermination du compte de produits |
int idCompteVenteProduit = rowPrefsCompte.getInt("ID_COMPTE_PCE_VENTE_PRODUIT"); |
if (idCompteVenteProduit <= 1) { |
idCompteVenteProduit = ComptePCESQLElement.getIdComptePceDefault("VentesProduits"); |
} |
if (clientRow.getObject("ID_COMPTE_PCE_PRODUIT") != null && !clientRow.isForeignEmpty("ID_COMPTE_PCE_PRODUIT")) { |
idCompteVenteProduit = clientRow.getInt("ID_COMPTE_PCE_PRODUIT"); |
} |
if (saisieRow.getObject("ID_COMPTE_PCE_PRODUIT") != null && !saisieRow.isForeignEmpty("ID_COMPTE_PCE_PRODUIT")) { |
idCompteVenteProduit = saisieRow.getInt("ID_COMPTE_PCE_PRODUIT"); |
} |
// compte Vente |
if (service != 0) { |
86,6 → 96,13 |
if (idCompteVenteService <= 1) { |
idCompteVenteService = ComptePCESQLElement.getIdComptePceDefault("VentesServices"); |
} |
if (clientRow.getObject("ID_COMPTE_PCE_SERVICE") != null && !clientRow.isForeignEmpty("ID_COMPTE_PCE_SERVICE")) { |
idCompteVenteService = clientRow.getInt("ID_COMPTE_PCE_SERVICE"); |
} |
if (saisieRow.getObject("ID_COMPTE_PCE_SERVICE") != null && !saisieRow.isForeignEmpty("ID_COMPTE_PCE_SERVICE")) { |
idCompteVenteService = saisieRow.getInt("ID_COMPTE_PCE_SERVICE"); |
} |
this.putValue("ID_COMPTE_PCE", new Integer(idCompteVenteService)); |
this.putValue("DEBIT", new Long(0)); |
this.putValue("CREDIT", new Long(service)); |
92,10 → 109,7 |
ajoutEcriture(); |
if ((prixHT.getLongValue() - service) > 0) { |
int idCompteVenteProduit = rowPrefsCompte.getInt("ID_COMPTE_PCE_VENTE_PRODUIT"); |
if (idCompteVenteProduit <= 1) { |
idCompteVenteProduit = ComptePCESQLElement.getIdComptePceDefault("VentesProduits"); |
} |
this.putValue("ID_COMPTE_PCE", new Integer(idCompteVenteProduit)); |
this.putValue("DEBIT", new Long(0)); |
this.putValue("CREDIT", new Long(prixHT.getLongValue() - service)); |
104,10 → 118,6 |
} else { |
int idCompteVenteProduit = rowPrefsCompte.getInt("ID_COMPTE_PCE_VENTE_PRODUIT"); |
if (idCompteVenteProduit <= 1) { |
idCompteVenteProduit = ComptePCESQLElement.getIdComptePceDefault("VentesProduits"); |
} |
this.putValue("ID_COMPTE_PCE", new Integer(idCompteVenteProduit)); |
this.putValue("DEBIT", new Long(0)); |
this.putValue("CREDIT", new Long(prixHT.getLongValue())); |
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/provider/SalesInvoiceAccountingRecordsProvider.java |
---|
18,6 → 18,7 |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.utils.StringUtils; |
import java.util.Map; |
39,6 → 40,7 |
} else { |
nom = "Fact. vente " + rowSource.getObject("NUMERO").toString(); |
} |
nom += " " + StringUtils.limitLength(rowSource.getForeign("ID_CLIENT").getString("NOM"), 20); |
values.put("NOM", nom); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/edm/FilePanel.java |
---|
103,9 → 103,9 |
label.setOpaque(false); |
label.setPreferredSize(new Dimension(label.getPreferredSize().width, new JTextField("a").getPreferredSize().height)); |
this.add(label, BorderLayout.SOUTH); |
this.setPreferredSize(new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT)); |
this.setMinimumSize(new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT)); |
int fontSize = label.getFont().getSize(); |
this.setPreferredSize(new Dimension(10 * fontSize, PREFERRED_HEIGHT)); |
this.setMinimumSize(new Dimension(10 * fontSize, PREFERRED_HEIGHT)); |
updateBackgroundFromState(); |
this.addMouseMotionListener(new MouseAdapter() { |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/action/ListeDesElementsPropositionsAction.java |
---|
32,7 → 32,7 |
final ListeAddPanel listeAddPanel = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("PROPOSITION_ELEMENT")); |
IListFrame frame = new IListFrame(listeAddPanel); |
frame.setTextTitle("Liste des missions par propositions"); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
frame.getPanel().setAddVisible(false); |
frame.getPanel().setSearchFullMode(true); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/action/ListeDesElementsDevisAction.java |
---|
55,7 → 55,7 |
IListFrame frame = new IListFrame(listeAddPanel); |
frame.setTextTitle("Liste des missions proposées"); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
frame.getPanel().setAddVisible(false); |
frame.getPanel().setShowReadOnlyFrameOnDoubleClick(false); |
frame.getPanel().setModifyVisible(false); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/ui/ListeDesDevisPanel.java |
---|
52,6 → 52,7 |
import org.openconcerto.utils.CollectionUtils; |
import org.openconcerto.utils.DecimalUtils; |
import org.openconcerto.utils.Tuple2; |
import org.openconcerto.utils.cc.IClosure; |
import org.openconcerto.utils.cc.ITransformer; |
import java.awt.Color; |
243,7 → 244,14 |
if (!this.eltDevis.getTable().contains("DATE_REMISE_DOSSIER")) { |
dateEnvoiCol = new SQLTableModelColumnPath(this.eltDevis.getTable().getField("DATE_ENVOI")); |
lAttente.getColumns().add(dateEnvoiCol); |
dateEnvoiCol.setRenderer(new DateEnvoiRenderer()); |
dateEnvoiCol.setColumnInstaller(new IClosure<TableColumn>() { |
@Override |
public void executeChecked(TableColumn columnDateEnvoi) { |
columnDateEnvoi.setCellEditor(new org.openconcerto.ui.table.TimestampTableCellEditor()); |
columnDateEnvoi.setCellRenderer(new DateEnvoiRenderer()); |
} |
}); |
dateEnvoiCol.setEditable(true); |
final BaseSQLTableModelColumn colAvancementCmd = new BaseSQLTableModelColumn("Commande", BigDecimal.class) { |
364,7 → 372,7 |
if (idFilter == EtatDevisSQLElement.ACCEPTE) { |
pane.getListe().setSQLEditable(true); |
pane.getListe().setModificationAllowed(true); |
// Edition des dates d'envois |
TableColumn columnDateEnvoi = pane.getListe().getJTable().getColumnModel().getColumn(table.getColumnCount() - 1); |
columnDateEnvoi.setCellEditor(new org.openconcerto.ui.table.TimestampTableCellEditor()); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/component/DevisSQLComponent.java |
---|
467,8 → 467,10 |
if (this.getTable().getFieldsName().contains("DUNNING_DATE")) { |
c.gridx++; |
c.weightx = 0; |
c.fill = GridBagConstraints.HORIZONTAL; |
this.add(new JLabel(getLabelFor("DUNNING_DATE"), SwingConstants.RIGHT), c); |
c.gridx++; |
c.fill = GridBagConstraints.NONE; |
JDate dateRelance = new JDate(); |
this.add(dateRelance, c); |
if (getTable().getDBRoot().contains("TARIF_AGENCE")) { |
592,8 → 594,8 |
cRemise.weightx = 0; |
this.textRemiseHT = new DeviseField(); |
panelRemise.add(this.textRemiseHT, cRemise); |
this.textRemiseHT.setMinimumSize(new Dimension(150, 20)); |
this.textRemiseHT.setPreferredSize(new Dimension(150, 20)); |
this.textRemiseHT.setMinimumSize(new Dimension(150, this.textRemiseHT.getMinimumSize().height)); |
this.textRemiseHT.setPreferredSize(new Dimension(150, this.textRemiseHT.getPreferredSize().height)); |
if (prefs.getBoolean(GestionCommercialeGlobalPreferencePanel.ACOMPTE_DEVIS, false)) { |
// Acompte |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/element/DevisSQLElement.java |
---|
617,6 → 617,7 |
@Override |
protected synchronized void _initTableSource(final SQLTableModelSource table) { |
super._initTableSource(table); |
final BaseSQLTableModelColumn colAdrLiv = new BaseSQLTableModelColumn("Adresse de livraison", String.class) { |
@Override |
655,7 → 656,6 |
} |
}; |
table.getColumns().add(3, colAdrLiv); |
} |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/product/ui/ProductItemListTable.java |
---|
28,6 → 28,7 |
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.SQLTable; |
81,8 → 82,11 |
if (object == null) { |
return null; |
} |
SQLRowAccessor r = row.getForeign("ID_ARTICLE"); |
return r.getForeignIDNumber("ID_UNITE_VENTE"); |
final SQLRowAccessor r = row.getForeign("ID_ARTICLE"); |
final SQLRow rArticle = r.asRow(); |
// TODO faire en sorte que l'on ne fasse pas de requete dans la thread swing |
rArticle.fetchValues(); |
return rArticle.getForeignIDNumber("ID_UNITE_VENTE"); |
} else { |
return row.getObject("ID_UNITE_VENTE"); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/POSConfiguration.java |
---|
260,6 → 260,7 |
SQLUtils.executeAtomic(Configuration.getInstance().getSystemRoot().getDataSource(), new SQLUtils.SQLFactory<Object>() { |
@Override |
public Object create() throws SQLException { |
final int imported = importReceipts(tickets, null); |
// mark imported |
378,7 → 379,7 |
// Paiements |
for (Paiement paiement : ticket.getPaiements()) { |
if (paiement.getMontantInCents() > 0 && paiement.getType() != Paiement.SOLDE) { |
if (paiement.getMontantInCents() != 0 && paiement.getType() != Paiement.SOLDE) { |
SQLRowValues rowValsElt = new SQLRowValues(eltEnc.getTable()); |
SQLRowValues rowValsEltMode = new SQLRowValues(eltMode.getTable()); |
685,10 → 686,14 |
} |
public void print(Printable ticket) { |
print(ticket, this.ticketPrinterConf1); |
print(ticket, this.ticketPrinterConf2); |
print(ticket, 0); |
} |
public void print(Printable ticket, int additionnalCopy) { |
print(ticket, this.ticketPrinterConf1, additionnalCopy); |
print(ticket, this.ticketPrinterConf2, additionnalCopy); |
} |
public void printOnceOnFirstPrinter(Printable ticket) { |
if (this.ticketPrinterConf1.isValid()) { |
final TicketPrinter prt = this.ticketPrinterConf1.createTicketPrinter(); |
697,9 → 702,14 |
} |
public void print(Printable ticket, TicketPrinterConfiguration conf) { |
if (conf.isValid() && conf.getCopyCount() > 0) { |
print(ticket, conf, 0); |
} |
public void print(Printable ticket, TicketPrinterConfiguration conf, int additionnalCopy) { |
int copyCount = conf.getCopyCount() + additionnalCopy; |
if (conf.isValid() && copyCount > 0) { |
final TicketPrinter prt = conf.createTicketPrinter(); |
for (int i = 0; i < conf.getCopyCount(); i++) { |
for (int i = 0; i < copyCount; i++) { |
ticket.print(prt, conf.getTicketWidth()); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/element/SaisieVenteComptoirSQLElement.java |
---|
278,6 → 278,38 |
c.weightx = 0; |
// this.add(this.comboAvoir, c); |
// Compte spec de produit |
JLabel labelCptProduit = new JLabel(getLabelFor("ID_COMPTE_PCE_PRODUIT")); |
c.gridy++; |
c.gridx = 0; |
c.gridwidth = 1; |
c.weightx = 0; |
labelCptProduit.setHorizontalAlignment(SwingConstants.RIGHT); |
this.add(labelCptProduit, c); |
c.gridx++; |
c.gridwidth = GridBagConstraints.REMAINDER; |
c.weightx = 0; |
ElementComboBox comboCptProduit = new ElementComboBox(); |
this.add(comboCptProduit, c); |
addView(comboCptProduit, "ID_COMPTE_PCE_PRODUIT"); |
// Compte spec de produit |
JLabel labelCptService = new JLabel(getLabelFor("ID_COMPTE_PCE_SERVICE")); |
c.gridy++; |
c.gridx = 0; |
c.gridwidth = 1; |
c.weightx = 0; |
labelCptService.setHorizontalAlignment(SwingConstants.RIGHT); |
this.add(labelCptService, c); |
c.gridx++; |
c.gridwidth = GridBagConstraints.REMAINDER; |
c.weightx = 0; |
ElementComboBox comboCptService = new ElementComboBox(); |
this.add(comboCptService, c); |
addView(comboCptService, "ID_COMPTE_PCE_SERVICE"); |
/*********************************************************************************** |
* * MONTANT |
**********************************************************************************/ |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/action/ListeDesCaissesTicketAction.java |
---|
31,7 → 31,7 |
public JFrame createFrame() { |
final IListFrame frame = new IListFrame(new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("CAISSE"))); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
return frame; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CaisseControler.java |
---|
158,7 → 158,7 |
} |
// Articles |
void addArticle(Article a) { |
public void addArticle(Article a) { |
this.t.addArticle(a); |
fire(); |
String price = TicketCellRenderer.centsToString(a.getPriceWithTax().movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue()); |
310,7 → 310,7 |
return false; |
for (int i = 0; i < paiementCount; i++) { |
Paiement p = this.t.getPaiements().get(i); |
if (p.getType() == type && p.getMontantInCents() <= 0) { |
if (p.getType() == type && p.getMontantInCents() != 0) { |
return false; |
} |
} |
324,7 → 324,7 |
} |
public static String getCents(int cents) { |
String s = String.valueOf(cents % 100); |
String s = String.valueOf(Math.abs(cents) % 100); |
if (s.length() < 2) { |
s = "0" + s; |
} |
471,7 → 471,7 |
} |
public boolean isTicketValid() { |
return (!this.t.getArticles().isEmpty()) && (this.getPaidTotal() >= this.getTotal()); |
return (!this.t.getArticles().isEmpty()) && ((this.getTotal() >= 0 && this.getPaidTotal() >= this.getTotal()) || (this.getTotal() < 0 && this.getPaidTotal() == this.getTotal())); |
} |
public Set<Integer> loadFavoriteProductsIds() { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/RegisterSummary.java |
---|
20,8 → 20,8 |
import org.openconcerto.erp.core.sales.pos.model.Paiement; |
import org.openconcerto.erp.core.sales.pos.model.RegisterLog; |
import org.openconcerto.erp.core.sales.pos.model.RegisterState; |
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status; |
import org.openconcerto.erp.core.sales.pos.model.Ticket; |
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status; |
import java.math.BigDecimal; |
import java.text.DateFormat; |
31,8 → 31,8 |
import java.util.LinkedHashMap; |
import java.util.List; |
import java.util.Map; |
import java.util.Map.Entry; |
import java.util.TreeMap; |
import java.util.Map.Entry; |
import java.util.logging.Level; |
abstract class RegisterSummary implements Printable { |
92,6 → 92,7 |
total = total.add(receiptValue); |
totalPaid = totalPaid.add(receiptPaid); |
} |
final BigDecimal rendu = totalPaid.subtract(total); |
prt.addToBuffer(title, TicketPrinter.BOLD_LARGE); |
prt.addToBuffer(""); |
104,12 → 105,12 |
prt.addToBuffer(""); |
Paiement espece = new Paiement(Paiement.ESPECES); |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total des ventes", totalPaid.toPlainString()), TicketPrinter.BOLD); |
// TODO same name as "Total TTC" |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total des ventes", total.toPlainString()), TicketPrinter.BOLD); |
for (final Entry<String, BigDecimal> e2 : totalByType.entrySet()) { |
final String typePayment = e2.getKey(); |
if (typePayment.equals(espece.getTypeAsString())) { |
BigDecimal value = e2.getValue(); |
BigDecimal rendu = totalPaid.subtract(total); |
value = value.subtract(rendu); |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, " " + typePayment, value.toPlainString())); |
} else { |
122,7 → 123,7 |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, " " + e2.getKey(), e2.getValue().toPlainString())); |
} |
prt.addToBuffer(""); |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total rendu", totalPaid.subtract(total).toPlainString()), TicketPrinter.BOLD); |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total rendu", rendu.toPlainString()), TicketPrinter.BOLD); |
prt.addToBuffer(""); |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Total TTC (Euros)", total.toPlainString()), TicketPrinter.BOLD); |
prt.addToBuffer(DefaultTicketPrinter.formatSides(ticketWidth, "Nombre de tickets", "" + receipts.size())); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/TicketPanel.java |
---|
124,6 → 124,9 |
if (selectedValue != null) { |
final Article a = ((Pair<Article, Integer>) selectedValue).getFirst(); |
controler.setArticleSelected(a); |
// If the category of the selected article does not match the current category of the categories list, |
// then the corresponding article is not selected. |
controler.setArticleSelected(a); // Dirty fix : use two refresh |
} |
} |
137,6 → 140,12 |
g.drawImage(this.bg, 0, 0, null); |
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
try { |
// Display caisse and Vendor ID |
String InfoCaisseVendeur = "Caisse "+POSConfiguration.getInstance().getPosID() + " Vendeur " + POSConfiguration.getInstance().getUserID(); |
g.setColor(new Color(230, 230, 230)); |
g.setFont(getFont().deriveFont(28.0f)); |
g.drawString(InfoCaisseVendeur, 20, this.getHeight() - 50); |
g.setColor(Color.LIGHT_GRAY); |
g.setFont(getFont().deriveFont(18.0f)); |
final RegisterState registerState = this.controler.getCaisseFrame().getFiles().getLastLog().getRegisterState(); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/TicketCellRenderer.java |
---|
114,7 → 114,7 |
} |
public static String centsToString(int cents) { |
final int c = cents % 100; |
final int c = Math.abs(cents) % 100; |
String sc = String.valueOf(c); |
if (c < 10) { |
sc = "0" + sc; |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CaisseMenuPanel.java |
---|
139,7 → 139,7 |
@Override |
public void actionPerformed(ActionEvent e) { |
JPanel p = new JPanel(); |
final JPanel p = new JPanel(); |
p.setOpaque(true); |
p.setLayout(new GridBagLayout()); |
final GridBagConstraints c = new GridBagConstraints(); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/NumericKeypadPanel.java |
---|
New file |
0,0 → 1,203 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.core.sales.pos.ui; |
import org.openconcerto.erp.core.common.ui.NumericTextField; |
import java.awt.Color; |
import java.awt.Dimension; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.Insets; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.math.BigDecimal; |
import java.util.HashMap; |
import java.util.Map; |
import javax.swing.JPanel; |
public class NumericKeypadPanel extends JPanel { |
private NumericTextField numericTextField; |
private Map<String, POSButton> buttonMap = new HashMap<>(); |
private transient NumericKeyListener evt = new NumericKeyListener(); |
private int maxDecimalDigits; |
private static final int INSET = 2; |
private static final int PANEL_HEIGHT = (68 * 5) + (INSET * 4); |
private static final int PANEL_WIDTH = (68 * 3) + (INSET * 2); |
private static final int BUTTON_SIZE = 64; |
public NumericKeypadPanel() { |
this(null, 2); |
} |
public NumericKeypadPanel(NumericTextField dataSource) { |
this(dataSource, 2); |
} |
public NumericKeypadPanel(NumericTextField dataSource, int maxDecimalDigits) { |
this.setLayout(new GridBagLayout()); |
drawCalculator(); |
setNumericTextField(dataSource); |
setMaxDecimalDigits(maxDecimalDigits); |
} |
public final int getMaxDecimalDigits() { |
return this.maxDecimalDigits; |
} |
public final void setMaxDecimalDigits(int maxDecimalDigits) { |
this.maxDecimalDigits = maxDecimalDigits; |
updateButtonsValidity(); |
} |
public final NumericTextField getNumericTextField() { |
return this.numericTextField; |
} |
public final void setNumericTextField(NumericTextField dataSource) { |
if (dataSource != null) { |
this.numericTextField = dataSource; |
final BigDecimal value = dataSource.getValue(); |
if (value == null || Math.abs(value.longValue()) <= 0) { |
this.numericTextField.setText(""); |
} |
updateButtonsValidity(); |
} |
} |
private void drawCalculator() { |
this.setForeground(new Color(250, 250, 250)); |
// line 1 |
addKey("C", 0, 0, 3, 1).setBackground(CaissePanel.LIGHT_BLUE); |
// line 2 |
addKey("7", 0, 1, 1, 1); |
addKey("8", 1, 1, 1, 1); |
addKey("9", 2, 1, 1, 1); |
// line 3 |
addKey("4", 0, 2, 1, 1); |
addKey("5", 1, 2, 1, 1); |
addKey("6", 2, 2, 1, 1); |
// line 4 |
addKey("1", 0, 3, 1, 1); |
addKey("2", 1, 3, 1, 1); |
addKey("3", 2, 3, 1, 1); |
// line 5 |
addKey("0", 0, 4, 2, 1); |
addKey(".", 2, 4, 1, 1); |
} |
private POSButton addKey(String buttonTitle, int col, int row, int colSpawn, int rowSpawn) { |
final GridBagConstraints c = new GridBagConstraints(); |
c.fill = GridBagConstraints.HORIZONTAL; |
c.anchor = GridBagConstraints.CENTER; |
c.weightx = 0; |
c.weighty = 0; |
c.gridwidth = colSpawn; |
c.gridheight = rowSpawn; |
c.gridx = col; |
c.gridy = row; |
c.insets = new Insets(2, 2, 2, 2); |
final POSButton button = new POSButton(buttonTitle); |
button.setPreferredSize(new Dimension(BUTTON_SIZE * colSpawn, BUTTON_SIZE * rowSpawn)); |
button.addActionListener(evt); |
buttonMap.put(buttonTitle, button); |
this.add(button, c); |
return button; |
} |
@Override |
public Dimension getPreferredSize() { |
return new Dimension(PANEL_WIDTH, PANEL_HEIGHT); |
} |
@Override |
public Dimension getMinimumSize() { |
return getPreferredSize(); |
} |
private void updateButtonsValidity() { |
if (numericTextField != null) { |
final String currentTextValue = numericTextField.getText(); |
final int length = currentTextValue.length(); |
final int posDecimalSeparator = currentTextValue.indexOf('.'); |
final boolean hasDecimalSeparator = (maxDecimalDigits == 0) || (posDecimalSeparator >= 0); |
final boolean hasEnoughtDecimals = posDecimalSeparator > 0 && (posDecimalSeparator < (length - maxDecimalDigits)); |
for (Map.Entry<String, POSButton> entry : buttonMap.entrySet()) { |
final String k = entry.getKey(); |
final POSButton button = entry.getValue(); |
switch (k) { |
case "C": |
button.setEnabled((length > 0)); |
break; |
case ".": |
// Disabled if dot is already present or if text is empty |
button.setEnabled(!hasDecimalSeparator && !currentTextValue.isEmpty()); |
break; |
case "0": |
case "1": |
case "2": |
case "3": |
case "4": |
case "5": |
case "6": |
case "7": |
case "8": |
case "9": |
button.setEnabled(!hasEnoughtDecimals); |
break; |
default: |
break; |
} |
} |
} |
} |
private class NumericKeyListener implements ActionListener { |
@Override |
public void actionPerformed(ActionEvent e) { |
final String digit = e.getActionCommand(); // Get text from button |
final String currentTextValue = numericTextField.getText(); |
switch (digit) { |
case "C": |
final int length = currentTextValue.length(); |
if (length > 0) { |
numericTextField.setText(currentTextValue.substring(0, length - 1)); |
} |
break; |
case "0": |
case "1": |
case "2": |
case "3": |
case "4": |
case "5": |
case "6": |
case "7": |
case "8": |
case "9": |
case ".": |
numericTextField.setText(currentTextValue + digit); |
break; |
default: |
break; |
} |
updateButtonsValidity(); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/PaiementPanel.java |
---|
256,8 → 256,8 |
Graphics2D g2 = (Graphics2D) g; |
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
int cents = p.getMontantInCents() % 100; |
int euros = p.getMontantInCents() / 100; |
int cents = p.getCents(); |
int euros = p.getEuros(); |
// Background |
g.setColor(new Color(240, 240, 240)); |
g.fillRect(3, y - 36, this.getWidth() - 5, 44); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CaisseFrame.java |
---|
189,12 → 189,16 |
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
f.pack(); |
if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) { |
f.setLocation(0, 24); |
} else { |
f.setLocation(0, 0); |
} |
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
if (POSConfiguration.getInstance().getScreenWidth() > 0 && POSConfiguration.getInstance().getScreenHeight() > 0) { |
f.setSize(new Dimension(POSConfiguration.getInstance().getScreenWidth(), POSConfiguration.getInstance().getScreenHeight())); |
f.setSize(new Dimension(POSConfiguration.getInstance().getScreenWidth() - f.getX(), POSConfiguration.getInstance().getScreenHeight() - f.getY())); |
} else { |
f.setSize(screenSize); |
f.setSize(new Dimension(screenSize.getSize().width - f.getX(), screenSize.getSize().height - f.getY())); |
} |
System.out.println("Affichage de l'interface"); |
f.setVisible(true); |
375,7 → 379,7 |
} |
public void showPanel(JPanel panel) { |
public void showPanel(final JPanel panel) { |
this.invalidate(); |
final int x = (getWidth() - panel.getPreferredSize().width) / 2; |
final int y = 100; |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/ListeDesTicketsPanel.java |
---|
15,18 → 15,16 |
import org.openconcerto.erp.core.sales.pos.POSConfiguration; |
import org.openconcerto.erp.core.sales.pos.TicketPrinterConfiguration; |
import org.openconcerto.erp.core.sales.pos.io.DefaultTicketPrinter; |
import org.openconcerto.erp.core.sales.pos.io.Printable; |
import org.openconcerto.erp.core.sales.pos.io.TicketPrinter; |
import org.openconcerto.erp.core.sales.pos.model.Paiement; |
import org.openconcerto.erp.core.sales.pos.model.Article; |
import org.openconcerto.erp.core.sales.pos.model.RegisterFiles; |
import org.openconcerto.erp.core.sales.pos.model.RegisterLog; |
import org.openconcerto.erp.core.sales.pos.model.RegisterState; |
import org.openconcerto.erp.core.sales.pos.model.RegisterState.Status; |
import org.openconcerto.erp.core.sales.pos.model.Ticket; |
import org.openconcerto.ui.DefaultListModel; |
import org.openconcerto.ui.touch.ScrollableList; |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.Pair; |
import java.awt.Color; |
import java.awt.Component; |
42,18 → 40,10 |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.io.IOException; |
import java.math.BigDecimal; |
import java.text.DateFormat; |
import java.text.ParseException; |
import java.text.SimpleDateFormat; |
import java.util.Calendar; |
import java.util.Date; |
import java.util.LinkedHashMap; |
import java.util.List; |
import java.util.Map; |
import java.util.Map.Entry; |
import java.util.TreeMap; |
import java.util.logging.Level; |
import javax.swing.JLabel; |
import javax.swing.JList; |
250,7 → 240,7 |
c.weighty = 0; |
c.fill = GridBagConstraints.NONE; |
final Font font = new Font(ARIAL_FONT, Font.PLAIN, 46); |
l = new JList(new String[] { "Imprimer" }); |
l = new JList(new String[] { "Imprimer", "Annuler" }); |
l.setCellRenderer(new ListCellRenderer() { |
@Override |
273,7 → 263,7 |
l.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
l.getSelectionModel().addListSelectionListener(this); |
l.setFixedCellHeight(80); |
l.setFixedCellHeight(160); |
this.add(l, c); |
setFont(new Font(ARIAL_FONT, Font.BOLD, 24)); |
299,7 → 289,16 |
int selectedIndex = l.getSelectedIndex(); |
if (selectedIndex == 0 && selectedValue != null) { |
POSConfiguration.getInstance().printOnceOnFirstPrinter(((Printable) selectedValue)); |
} else if (selectedIndex == 1 && selectedValue != null) { |
// Annulation du ticket |
Ticket t = (Ticket) selectedValue; |
for (Pair<Article, Integer> a : t.getArticles()) { |
frame.getControler().addArticle(a.getFirst()); |
frame.getControler().setArticleCount(a.getFirst(), -a.getSecond()); |
frame.getControler().setArticleHT(a.getFirst(), a.getFirst().getPriceWithoutTax()); |
} |
frame.showCaisse(); |
} |
l.clearSelection(); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CaissePanel.java |
---|
155,7 → 155,7 |
// Valider |
CaissePanel.this.controler.setLCD("Impression de", "votre ticket...", 0); |
try { |
POSConfiguration.getInstance().print(savedReceipt); |
POSConfiguration.getInstance().print(savedReceipt, (savedReceipt.isAdditionnalCopyRequested() ? 1 : 0)); |
} catch (UnsatisfiedLinkError ex) { |
JOptionPane.showMessageDialog(CaissePanel.this, "Erreur de configuration de la liaison à l'imprimante"); |
} catch (Throwable ex) { |
230,7 → 230,7 |
final SQLSelect selArticle = new SQLSelect(); |
final SQLTable tableArticle = eltArticle.getTable(); |
selArticle.addAllSelect(tableArticle.getFields(VirtualFields.PRIMARY_KEY.union(VirtualFields.ARCHIVE))); |
selArticle.addAllSelect(tableArticle, Arrays.asList("ID_FAMILLE_ARTICLE", "NOM", "CODE", "CODE_BARRE", "ID_TAXE", "PV_HT", "PV_TTC")); |
selArticle.addAllSelect(tableArticle, Arrays.asList("ID_FAMILLE_ARTICLE", "NOM", "CODE", "CODE_BARRE", "ID_TAXE", "PV_HT", "PV_TTC", "ADDITIONAL_TICKET_COPY")); |
selArticle.setWhere(new Where(tableArticle.getField("OBSOLETE"), "=", Boolean.FALSE).and(new Where(tableArticle.getField("MASQUE_CAISSE"), "=", Boolean.FALSE))); |
final Categorie cUnclassified = new Categorie("Non classés", true); |
252,6 → 252,7 |
a.setIdTaxe(row.getInt("ID_TAXE")); |
a.setPriceWithoutTax(row.getBigDecimal("PV_HT")); |
a.setPriceWithTax(row.getBigDecimal("PV_TTC")); |
a.setAdditionalCopyRequested(row.getBoolean("ADDITIONAL_TICKET_COPY")); |
final Integer idProduct = a.getId(); |
if (favoriteProductsIds.contains(idProduct)) { |
favoriteProducts.add(a); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/POSButton.java |
---|
19,11 → 19,15 |
import javax.swing.JButton; |
public class POSButton extends JButton { |
private Color enabledBackgroundColor = null; |
private Color disabledBackgroundColor = null; |
public POSButton(String label) { |
super(label); |
final Font f = getFont().deriveFont(20f); |
this.setForeground(Color.WHITE); |
this.setBackground(CaissePanel.DARK_BLUE); |
this.setDisabledBackground(Color.LIGHT_GRAY); |
this.setFont(f); |
this.setFocusPainted(false); |
this.setBorderPainted(false); |
30,4 → 34,52 |
this.setContentAreaFilled(false); |
this.setOpaque(true); |
} |
public void setDisabledBackground(Color bg) { |
if (bg == null) { |
disabledBackgroundColor = this.getBackground(); |
} else { |
disabledBackgroundColor = bg; |
} |
} |
/** |
* Enables (or disables) the button changing his background color. + * @param b true to enable |
* the button, otherwise false + |
*/ |
@Override |
public void setEnabled(boolean b) { |
super.setEnabled(b); |
if (b) { |
if ((enabledBackgroundColor != null) && !(enabledBackgroundColor.equals(this.getBackground()))) { |
super.setBackground(enabledBackgroundColor); |
} |
} else { |
if ((disabledBackgroundColor != null) && !(disabledBackgroundColor.equals(this.getBackground()))) { |
super.setBackground(disabledBackgroundColor); |
} |
} |
} |
/** |
* Sets the background color of this component. |
* <p> |
* The background color affects each component differently and the parts of the component that |
* are affected by the background color may differ between operating systems. |
* |
* @param c the color to become this component's color; if this parameter is <code>null</code>, |
* then this component will inherit the background color of its parent |
* |
*/ |
@Override |
public void setBackground(Color bg) { |
super.setBackground(bg); |
if (this.isEnabled()) { |
enabledBackgroundColor = this.getBackground(); |
} else { |
disabledBackgroundColor = this.getBackground(); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/PriceEditorPanel.java |
---|
19,6 → 19,7 |
import java.awt.Color; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.GridLayout; |
import java.awt.Insets; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
26,22 → 27,25 |
import javax.swing.ButtonGroup; |
import javax.swing.JPanel; |
import javax.swing.SwingUtilities; |
import javax.swing.event.DocumentEvent; |
import javax.swing.event.DocumentListener; |
public class PriceEditorPanel extends JPanel { |
CaisseFrame frame; |
private POSLabel labelPrice; |
private Article article; |
final POSRadioButton rHT, rTTC, rDiscountPercent, rDiscount; |
private NumericTextField htTextField; |
private NumericTextField ttcTextField; |
private NumericTextField discountPercentTextField; |
private NumericTextField discountTextField; |
private final transient Article article; |
private final POSLabel labelPrice; |
private final POSRadioButton rHT; |
private final POSRadioButton rTTC; |
private final POSRadioButton rDiscountPercent; |
private final POSRadioButton rDiscount; |
private final NumericTextField htTextField; |
private final NumericTextField ttcTextField; |
private final NumericTextField discountPercentTextField; |
private final NumericTextField discountTextField; |
private final NumericKeypadPanel keyPad; |
public PriceEditorPanel(final CaisseFrame caisseFrame, final Article article) { |
this.article = article; |
this.frame = caisseFrame; |
this.setBackground(Color.WHITE); |
this.setOpaque(true); |
this.setLayout(new GridBagLayout()); |
49,7 → 53,7 |
c.fill = GridBagConstraints.HORIZONTAL; |
c.anchor = GridBagConstraints.EAST; |
c.weightx = 0; |
c.weighty = 0; |
c.weighty = 1; |
c.gridx = 0; |
c.gridy = 0; |
c.insets = new Insets(20, 20, 30, 20); |
60,8 → 64,21 |
// Line 2 |
c.gridy++; |
c.gridwidth = 1; |
rTTC = new POSRadioButton("prix TTC"); |
rTTC.setSelected(true); |
c.weightx = 0; |
this.add(rTTC, c); |
ttcTextField = new NumericTextField(); |
ttcTextField.setFont(title.getFont()); |
ttcTextField.setValue(article.getPriceWithTax()); |
ttcTextField.requestFocusInWindow(); |
c.gridx++; |
c.weightx = 1; |
this.add(ttcTextField, c); |
// Line 3 |
c.gridy++; |
rHT = new POSRadioButton("prix HT"); |
rHT.setSelected(true); |
c.gridx = 0; |
c.weightx = 0; |
this.add(rHT, c); |
htTextField = new NumericTextField(); |
70,18 → 87,6 |
c.gridx++; |
c.weightx = 1; |
this.add(htTextField, c); |
// Line 3 |
c.gridy++; |
rTTC = new POSRadioButton("prix TTC"); |
htTextField.setValue(article.getPriceWithTax()); |
c.gridx = 0; |
c.weightx = 0; |
this.add(rTTC, c); |
ttcTextField = new NumericTextField(); |
ttcTextField.setFont(title.getFont()); |
c.gridx++; |
c.weightx = 1; |
this.add(ttcTextField, c); |
// Line 4 |
c.gridy++; |
rDiscountPercent = new POSRadioButton("remise en %"); |
118,9 → 123,7 |
c.gridx = 0; |
c.gridwidth = 2; |
final POSLabel labelPriceOld = new POSLabel("Ancien Prix : "); |
final BigDecimal ttc = Article.computePriceWithTax(this.article.getPriceWithoutTax(), this.article.getIdTaxe()); |
ttcTextField.setValue(ttc); |
labelPriceOld.setText("Ancien Prix : " + TicketCellRenderer.toString(this.article.getPriceWithoutTax()) + " HT, " + TicketCellRenderer.toString(ttc)); |
labelPriceOld.setText("Ancien Prix : " + TicketCellRenderer.toString(article.getPriceWithTax()) + "€ TTC, " + TicketCellRenderer.toString(article.getPriceWithoutTax()) + "€ HT"); |
this.add(labelPriceOld, c); |
c.gridy++; |
133,12 → 136,12 |
c.fill = GridBagConstraints.NONE; |
c.anchor = GridBagConstraints.SOUTHEAST; |
final JPanel buttons = new JPanel(); |
final JPanel buttons = new JPanel(new GridLayout(1, 2, 10, 0)); |
buttons.setOpaque(false); |
POSButton bCancel = new POSButton("Annuler"); |
buttons.add(bCancel, c); |
POSButton bApply = new POSButton("Appliquer"); |
buttons.add(bApply, c); |
POSButton bCancel = new POSButton("Annuler"); |
buttons.add(bCancel, c); |
bApply.addActionListener(new ActionListener() { |
@Override |
156,6 → 159,18 |
}); |
this.add(buttons, c); |
c.anchor = GridBagConstraints.CENTER; |
c.weightx = 0; |
c.weighty = 0; |
c.gridx = 3; |
c.gridy = 2; |
c.insets = new Insets(20, 20, 30, 20); |
// Line 1 |
c.gridheight = 5; |
keyPad = new NumericKeypadPanel(ttcTextField); |
this.add(keyPad, c); |
updatePrice(article.getPriceWithoutTax()); |
updateTextFields(); |
// |
197,7 → 212,13 |
this.htTextField.getDocument().addDocumentListener(docListener); |
this.discountPercentTextField.getDocument().addDocumentListener(docListener); |
this.discountTextField.getDocument().addDocumentListener(docListener); |
SwingUtilities.invokeLater(new Runnable() { |
public void run() { |
updateTextFields();// This will set focus on the text field |
} |
}); |
} |
protected BigDecimal getHTFromUI() { |
BigDecimal r = null; |
221,12 → 242,12 |
return r; |
} |
void updatePrice(BigDecimal ht) { |
private void updatePrice(BigDecimal ht) { |
BigDecimal ttc = Article.computePriceWithTax(ht, this.article.getIdTaxe()); |
labelPrice.setText("Nouveau Prix : " + TicketCellRenderer.toString(ht) + " HT, " + TicketCellRenderer.toString(ttc)); |
labelPrice.setText("Nouveau Prix : " + TicketCellRenderer.toString(ttc) + "€ TTC, " + TicketCellRenderer.toString(ht) + "€ HT"); |
} |
public void updateTextFields() { |
private void updateTextFields() { |
this.invalidate(); |
htTextField.setVisible(false); |
ttcTextField.setVisible(false); |
233,15 → 254,21 |
discountPercentTextField.setVisible(false); |
discountTextField.setVisible(false); |
if (rHT.isSelected()) { |
htTextField.setVisible(true); |
enableTextField(htTextField); |
} else if (rTTC.isSelected()) { |
ttcTextField.setVisible(true); |
enableTextField(ttcTextField); |
} else if (rDiscountPercent.isSelected()) { |
discountPercentTextField.setVisible(true); |
enableTextField(discountPercentTextField); |
} else if (rDiscount.isSelected()) { |
discountTextField.setVisible(true); |
enableTextField(discountTextField); |
} |
this.validate(); |
repaint(); |
} |
private void enableTextField(NumericTextField field) { |
field.setVisible(true); |
field.requestFocusInWindow(); |
this.keyPad.setNumericTextField(field); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/RegisterFiles.java |
---|
514,15 → 514,21 |
@Override |
protected Object updateDir(final Path stagingDir, final RegisterLog lastLog) throws IOException { |
final Date now = new Date(); |
final String lastHash; |
try { |
lastHash = lastLog.getLastReceiptHash(); |
// Closure cannot be done (or undone) manually (opening is just a row in |
// CAISSE_JOURNAL) so check as much as possible |
final RegisterLogEntry lastEvent = lastLog.getLastEvent(); |
if (isNotChronological(lastEvent.getDate(), now)) |
throw new IllegalStateException("Previous event date is in the future : " + lastEvent); |
} catch (ParseException e) { |
throw new IOException("Couldn't find last receipt hash", e); |
} |
// TODO verify that receipts' files match the log's content |
final Document doc = lastLog.getDocument().clone(); |
doc.getRootElement().addContent(new RegisterLogEntry.RegisterEntry(EventType.REGISTER_CLOSURE, new Date(), userID, getPosID(), lastHash, null).toXML()); |
doc.getRootElement().addContent(new RegisterLogEntry.RegisterEntry(EventType.REGISTER_CLOSURE, now, userID, getPosID(), lastHash, null).toXML()); |
save(doc, stagingDir.resolve(LOG_FILENAME)); |
return null; |
} |
569,6 → 575,9 |
throw new IllegalStateException("Non consecutive number"); |
if (!CompareUtils.equals(expectedHash, t.getPreviousHash())) |
throw new IllegalStateException("Previous hash mismatch, expected " + expectedHash + " but previous of receipt was " + t.getPreviousHash()); |
final RegisterLogEntry lastEvent = lastLog.getLastEvent(); |
if (isNotChronological(lastEvent.getDate(), t.getCreationDate())) |
throw new IllegalStateException("Previous event (" + lastEvent + ") is after the receipt : " + t.getCreationDate()); |
} catch (ParseException e) { |
throw new IOException("Couldn't parse last receipt of log", e); |
} |
587,4 → 596,9 |
} |
}); |
} |
static final boolean isNotChronological(final Date d1, final Date d2) { |
// allow equal dates to support programmatic creation (faster than millisecond) |
return d1.after(d2); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/RegisterLogEntry.java |
---|
49,6 → 49,8 |
this.userID = userID; |
this.registerID = registerID; |
this.lastReceiptHash = lastReceiptHash; |
if (previousDate != null && RegisterFiles.isNotChronological(previousDate, date)) |
throw new IllegalArgumentException("Previous date (" + previousDate + ") is after " + date); |
this.previousDate = previousDate; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/CheckIntegrity.java |
---|
105,6 → 105,7 |
System.out.println("OK for " + logFile); |
} catch (Exception e) { |
// keep checking other files |
System.err.println("Error for " + logFile); |
e.printStackTrace(); |
} |
lastLog = Value.getSome(log); |
126,7 → 127,7 |
final RegisterEntry previousLogClosure = (RegisterEntry) lastEntry; |
if (!Objects.equals(previousLogClosure.getLastReceiptHash(), log.getFirstRegisterEvent().getLastReceiptHash())) |
throw new IllegalStateException("Register opening hash mismatch, chain broken"); |
if (log.getFirstRegisterEvent().getDate().compareTo(previousLogClosure.getDate()) < 0) |
if (RegisterFiles.isNotChronological(previousLogClosure.getDate(), log.getFirstRegisterEvent().getDate())) |
throw new IllegalStateException("Register opening before previous closure"); |
cal = previousLogClosure.getDate(); |
} else { |
148,7 → 149,7 |
final List<RegisterLogEntry> allEvents = log.getAllEvents(); |
for (final RegisterLogEntry e : allEvents) { |
final Date newDate = e.getDate(); |
if (cal != null && newDate.compareTo(cal) < 0) |
if (cal != null && RegisterFiles.isNotChronological(cal, newDate)) |
throw new IllegalStateException("Later event before last one"); |
cal = newDate; |
} |
221,6 → 222,7 |
final SQLRow row = iter.next(); |
final ReceiptEntry receiptEvent = receiptEventsIter.next(); |
try { |
if (!row.getString("NUMERO").equals(receipt.getCode())) |
throw new IllegalStateException("Code in the DB doesn't match log"); |
if (row.getDate("DATE").compareTo(receipt.getCreationCal()) != 0) |
230,8 → 232,11 |
if (!Objects.equals(row.getString("FILE_HASH_PREVIOUS"), receipt.getPreviousHash())) |
throw new IllegalStateException("Previous file hash in the DB doesn't match log"); |
if (row.getLong("TOTAL_TTC") != receipt.getPaidTotal()) |
throw new IllegalStateException("TTC in the DB doesn't match log"); |
throw new IllegalStateException("TTC in the DB " + row.getLong("TOTAL_TTC") + " doesn't match log " + receipt.getPaidTotal()); |
} catch (Exception exn) { |
throw new IllegalStateException("Error while checking " + row + " against " + receipt + " in " + log, exn); |
} |
} |
assert !iter.hasNext() && !receiptEventsIter.hasNext(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/Paiement.java |
---|
24,12 → 24,19 |
} |
public int getEuros() { |
return this.montantInCents / 100; |
} |
public int getCents() { |
return Math.abs(this.montantInCents) % 100; |
} |
public int getMontantInCents() { |
return montantInCents; |
} |
public void setMontantInCents(int montantInCents) { |
if (montantInCents >= 0) |
this.montantInCents = montantInCents; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/Article.java |
---|
24,6 → 24,7 |
public class Article { |
private Categorie s; |
private String name; |
private boolean additionalCopyRequested = false; |
private BigDecimal priceTTC; |
private int idTaxe; |
private BigDecimal priceHT; |
50,6 → 51,14 |
this.s.addArticle(this); |
} |
public boolean isAdditionalCopyRequested() { |
return additionalCopyRequested; |
} |
public void setAdditionalCopyRequested(boolean additionalCopyRequested) { |
this.additionalCopyRequested = additionalCopyRequested; |
} |
public int getId() { |
return this.id; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/Ticket.java |
---|
72,6 → 72,7 |
private Client client = Client.NONE; |
private final int number; |
private final String previousHash; |
private boolean additionnalCopyRequested = false; |
// Propre à la caisse |
private final int caisseNumber; |
162,7 → 163,7 |
final String type = element.getAttributeValue("type"); |
final int montant_cents = Integer.parseInt(element.getAttributeValue("montant")); |
if (montant_cents > 0) { |
if (montant_cents != 0) { |
int tp = Paiement.ESPECES; |
if (type.equals("CB")) { |
tp = Paiement.CB; |
269,7 → 270,7 |
// Paiements |
for (final Paiement paiement : this.paiements) { |
final int montantInCents = paiement.getMontantInCents(); |
if (montantInCents > 0) { |
if (montantInCents != 0) { |
final Element e = new Element("paiement"); |
String type = ""; |
if (paiement.getType() == Paiement.CB) { |
357,7 → 358,7 |
// Date |
prt.addToBuffer(""); |
final SimpleDateFormat df = new SimpleDateFormat("EEEE d MMMM yyyy à HH:mm", Locale.FRENCH); |
prt.addToBuffer(DefaultTicketPrinter.formatRight(maxWidth, "Le " + df.format(getCreationDate()))); |
prt.addToBuffer(DefaultTicketPrinter.formatCenter(maxWidth, "Le " + df.format(getCreationDate()))); |
prt.addToBuffer(""); |
List<Pair<Article, Integer>> itemsToPrint = new ArrayList<>(this.items); |
Collections.sort(itemsToPrint, new Comparator<Pair<Article, Integer>>() { |
385,7 → 386,7 |
Categorie currentCategorie = null; |
for (final Pair<Article, Integer> item : this.items) { |
final Article article = item.getFirst(); |
if (currentCategorie == null || !currentCategorie.equals(article.getCategorie())) { |
if (currentCategorie == null || !currentCategorie.getName().equals(article.getCategorie().getName())) { |
// Print category name, except for unknown |
currentCategorie = article.getCategorie(); |
if (!currentCategorie.isUnknown()) { |
395,22 → 396,26 |
final Integer nb = item.getSecond(); |
final Float tauxFromId = TaxeCache.getCache().getTauxFromId(article.getIdTaxe()); |
final BigDecimal tauxTVA = new BigDecimal(tauxFromId).movePointLeft(2).add(BigDecimal.ONE); |
final BigDecimal unitPrice = article.getPriceWithoutTax().multiply(tauxTVA, DecimalUtils.HIGH_PRECISION); |
final BigDecimal multiply = article.getPriceWithoutTax().multiply(new BigDecimal(nb), DecimalUtils.HIGH_PRECISION).multiply(tauxTVA, DecimalUtils.HIGH_PRECISION); |
final String qtyString = DefaultTicketPrinter.formatRight(MAX_QTE_WIDTH, String.valueOf(nb)); |
final String priceString = DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(multiply.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue())); |
String unitPriceString = ""; |
if (nb != 1) { |
unitPriceString = DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(unitPrice.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue())); |
} |
if (article.getCode() != null && !article.getCode().isEmpty()) { |
// 2 lines |
final String qtyString = DefaultTicketPrinter.formatRight(MAX_QTE_WIDTH, String.valueOf(nb)); |
final String codeString = DefaultTicketPrinter.formatLeft(maxWidth - 2 - MAX_PRICE_WIDTH - MAX_QTE_WIDTH, article.getCode()); |
final String priceString = DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(multiply.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue())); |
prt.addToBuffer(qtyString + " " + codeString + " " + priceString); |
final String codeString = DefaultTicketPrinter.formatLeft(maxWidth - 2 - MAX_PRICE_WIDTH - MAX_QTE_WIDTH - 1 - unitPriceString.length(), article.getCode()); |
prt.addToBuffer(qtyString + " " + codeString + " " + unitPriceString + " " + priceString); |
final String nameString = DefaultTicketPrinter.formatLeft(maxWidth - MAX_QTE_WIDTH - 1, article.getName()); |
prt.addToBuffer(" " + nameString); |
} else { |
// 1 line |
final String qtyString = DefaultTicketPrinter.formatRight(MAX_QTE_WIDTH, String.valueOf(nb)); |
final String nameString = DefaultTicketPrinter.formatLeft(maxWidth - 2 - MAX_PRICE_WIDTH - MAX_QTE_WIDTH, article.getName()); |
final String priceString = DefaultTicketPrinter.formatRight(MAX_PRICE_WIDTH, TicketCellRenderer.centsToString(multiply.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue())); |
prt.addToBuffer(qtyString + " " + nameString + " " + priceString); |
final String nameString = DefaultTicketPrinter.formatLeft(maxWidth - 2 - MAX_PRICE_WIDTH - MAX_QTE_WIDTH - 1 - unitPriceString.length(), article.getName()); |
prt.addToBuffer(qtyString + " " + nameString + " " + unitPriceString + " " + priceString); |
} |
} |
447,17 → 452,22 |
for (final Paiement paiement : this.paiements) { |
String type = ""; |
final int montantInCents = paiement.getMontantInCents(); |
if (montantInCents != 0) { |
if (montantInCents > 0) { |
type = "Paiement "; |
} else { |
type = "Remboursement "; |
} |
if (paiement.getType() == Paiement.CB) { |
type = "Paiement CB"; |
type = "CB"; |
} else if (paiement.getType() == Paiement.CHEQUE) { |
type = "Paiement par chèque"; |
type = "par chèque"; |
} else if (paiement.getType() == Paiement.ESPECES) { |
type = "Paiement en espèces"; |
type = "en espèces"; |
} else if (paiement.getType() == Paiement.SOLDE) { |
type = "Paiement depuis solde"; |
type = "depuis solde"; |
} |
final int montantInCents = paiement.getMontantInCents(); |
if (montantInCents > 0) { |
type += " de " + TicketCellRenderer.centsToString(montantInCents); |
if (montantInCents > 100) { |
type += " euros"; |
514,8 → 524,15 |
} |
public boolean isAdditionnalCopyRequested() { |
return additionnalCopyRequested; |
} |
public void addArticle(final Article a) { |
boolean alreadyExist = false; |
if (a.isAdditionalCopyRequested()) { |
this.additionnalCopyRequested = true; |
} |
for (final Pair<Article, Integer> line : this.items) { |
if (line.getFirst().equals(a)) { |
alreadyExist = true; |
522,6 → 539,7 |
break; |
} |
} |
if (!alreadyExist) { |
final Pair<Article, Integer> line = new Pair<Article, Integer>(new Article(a), 1); |
this.items.add(line); |
595,10 → 613,11 |
} |
public void setArticleCount(final Article article, final int count) { |
if (count <= 0) { |
this.clearArticle(article); |
return; |
} |
// TODO Allow only if annulation? |
// if (count <= 0) { |
// this.clearArticle(article); |
// return; |
// } |
Pair<Article, Integer> toModify = null; |
for (final Pair<Article, Integer> line : this.items) { |
if (line.getFirst().equals(article)) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/ui/BonDeLivraisonItemTable.java |
---|
61,6 → 61,7 |
import org.openconcerto.ui.table.XTableColumnModel; |
import org.openconcerto.utils.DecimalUtils; |
import org.openconcerto.utils.Tuple3; |
import org.openconcerto.utils.cc.ITransformer; |
import org.openconcerto.utils.i18n.TranslationManager; |
import java.awt.Component; |
182,6 → 183,11 |
final SQLTableElement tableElementDesc = new SQLTableElement(e.getTable().getField("DESCRIPTIF")); |
list.add(tableElementDesc); |
if (e.getTable().getFieldsName().contains("DELAI")) { |
final SQLTableElement tableElementDelai = new SQLTableElement(e.getTable().getField("DELAI")); |
list.add(tableElementDelai); |
} |
// Valeur des métriques |
final SQLTableElement tableElement_ValeurMetrique2 = new SQLTableElement(e.getTable().getField("VALEUR_METRIQUE_2"), Float.class) { |
@Override |
403,6 → 409,10 |
return new DeliveredQtyRowValuesRenderer(); |
} |
protected Object getDefaultNullValue() { |
return Integer.valueOf(0); |
} |
}; |
list.add(tableElement_QuantiteLivree); |
643,9 → 653,32 |
for (String string : completionField) { |
m.fill(string, string); |
} |
final Where w = new Where(sqlTableArticle.getField("OBSOLETE"), "=", Boolean.FALSE); |
m.setWhere(w); |
// final Where w = new Where(sqlTableArticle.getField("OBSOLETE"), "=", Boolean.FALSE); |
// m.setWhere(w); |
ITransformer<SQLSelect, SQLSelect> selTrans = new ITransformer<SQLSelect, SQLSelect>() { |
@Override |
public SQLSelect transformChecked(SQLSelect input) { |
// FIXME utiliser le stock sélectionné sur la ligne et non le stock par défaut de |
// l'article |
final SQLTable tableStock = sqlTableArticle.getTable("STOCK"); |
input.andWhere(new Where(tableStock.getKey(), "=", sqlTableArticle.getField("ID_STOCK"))); |
input.setExcludeUndefined(false, tableStock); |
Where w = new Where(sqlTableArticle.getField("OBSOLETE"), "=", Boolean.FALSE).or(new Where(input.getAlias(tableStock.getKey()), "=", tableStock.getUndefinedID())) |
.or(new Where(input.getAlias(tableStock.getField("QTE_REEL")), ">", 0)); |
if (input.getWhere() != null) { |
input.setWhere(input.getWhere().and(w)); |
} else { |
input.setWhere(w); |
} |
input.asString(); |
return input; |
} |
}; |
m.setSelectTransformer(selTrans); |
if (prefs.getBoolean(GestionArticleGlobalPreferencePanel.CAN_EXPAND_NOMENCLATURE_VT, true)) { |
table.addMouseListener(new MouseAdapter() { |
711,7 → 744,8 |
m2.fill(string, string); |
} |
m2.setWhere(w); |
// m2.setWhere(w); |
m2.setSelectTransformer(selTrans); |
final AutoCompletionManager m3 = new AutoCompletionManager(tableElementArticle, sqlTableArticle.getField("NOM"), this.table, this.table.getRowValuesTableModel(), |
ITextWithCompletion.MODE_CONTAINS, true, true, new ValidStateChecker()) { |
731,7 → 765,8 |
m3.fill(string, string); |
} |
m3.setWhere(w); |
// m3.setWhere(w); |
m3.setSelectTransformer(selTrans); |
// ECO Contribution |
if (this.tableElementEco != null && this.tableElementEcoTotal != null && this.tableElementEcoID != null) { |
770,7 → 805,8 |
tableElement_PrixVente_HT.addModificationListener(totalHT); |
this.totalHT.setModifier(new CellDynamicModifier() { |
public Object computeValueFrom(final SQLRowValues row, SQLTableElement source) { |
int qte = Integer.parseInt(row.getObject("QTE_LIVREE").toString()); |
final Object qteL = row.getObject("QTE_LIVREE"); |
int qte = qteL == null ? 0 : Integer.parseInt(qteL.toString()); |
BigDecimal f = (BigDecimal) row.getObject("PV_HT"); |
System.out.println("Qte:" + qte + " et PV_HT:" + f); |
BigDecimal b = (row.getObject("QTE_UNITAIRE") == null) ? BigDecimal.ONE : (BigDecimal) row.getObject("QTE_UNITAIRE"); |
788,7 → 824,8 |
}); |
this.totalHA.setModifier(new CellDynamicModifier() { |
public Object computeValueFrom(final SQLRowValues row, SQLTableElement source) { |
int qte = Integer.parseInt(row.getObject("QTE_LIVREE").toString()); |
final Object qteL = row.getObject("QTE_LIVREE"); |
int qte = qteL == null ? 0 : Integer.parseInt(qteL.toString()); |
BigDecimal f = (BigDecimal) row.getObject("PA_HT"); |
BigDecimal b = (row.getObject("QTE_UNITAIRE") == null) ? BigDecimal.ONE : (BigDecimal) row.getObject("QTE_UNITAIRE"); |
BigDecimal r = b.multiply(f.multiply(BigDecimal.valueOf(qte)), DecimalUtils.HIGH_PRECISION).setScale(totalHA.getDecimalDigits(), BigDecimal.ROUND_HALF_UP); |
881,6 → 918,11 |
return row.getObject("PRIX_METRIQUE_VT_1"); |
} |
} |
// On ne recalcule pas le tarif si la ligne vient d'une commande |
boolean noCmdElt = row.getObject("ID_COMMANDE_CLIENT_ELEMENT") == null || row.isForeignEmpty("ID_COMMANDE_CLIENT_ELEMENT"); |
if (!noCmdElt) { |
return row.getObject("PRIX_METRIQUE_VT_1"); |
} |
return tarifCompletion(row.getForeign("ID_ARTICLE"), "PRIX_METRIQUE_VT_1", row); |
} |
} |
909,9 → 951,14 |
} else if (source != null && source.getField().getName().equalsIgnoreCase("PRIX_METRIQUE_VT_1")) { |
return row.getObject("PRIX_METRIQUE_VT_1"); |
} |
// On ne recalcule pas le tarif si la ligne vient d'une commande |
boolean noCmdElt = row.getObject("ID_COMMANDE_CLIENT_ELEMENT") == null || row.isForeignEmpty("ID_COMMANDE_CLIENT_ELEMENT"); |
if (!noCmdElt) { |
return row.getObject("PV_U_DEVISE"); |
} |
return row.getObject("PV_U_DEVISE"); |
} |
} |
}); |
tableElementRemise.addModificationListener(this.tableElementTotalDevise); |
989,13 → 1036,12 |
if (filterFamilleArticle) { |
if (row.isForeignEmpty("ID_FAMILLE_ARTICLE")) { |
m.setWhere(w); |
m2.setWhere(w); |
m.setWhere(null); |
m2.setWhere(null); |
} else { |
m.setWhere(w.and(new Where(sqlTableArticle.getField("ID_FAMILLE_ARTICLE"), "=", row.getForeignID("ID_FAMILLE_ARTICLE")))); |
m2.setWhere(w.and(new Where(sqlTableArticle.getField("ID_FAMILLE_ARTICLE"), "=", row.getForeignID("ID_FAMILLE_ARTICLE")))); |
m.setWhere(new Where(sqlTableArticle.getField("ID_FAMILLE_ARTICLE"), "=", row.getForeignID("ID_FAMILLE_ARTICLE"))); |
m2.setWhere(new Where(sqlTableArticle.getField("ID_FAMILLE_ARTICLE"), "=", row.getForeignID("ID_FAMILLE_ARTICLE"))); |
} |
} |
SQLRowAccessor foreign = row.getForeign("ID_ARTICLE"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/credit/action/ListeDesAvoirsClientsAction.java |
---|
69,7 → 69,7 |
datePanel.setFilterOnDefault(); |
frame.getPanel().add(datePanel, c); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
return frame; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/element/CommandeClientSQLElement.java |
---|
157,7 → 157,7 |
public void actionPerformed(ActionEvent e) { |
transfertBonLivraisonClient(IListe.get(e).getSelectedRows()); |
} |
}, false, "sales.order.create.deliverynote"); |
}, true, "sales.order.create.deliverynote"); |
// Transfert vers facture |
RowAction factureAction = new RowAction(new AbstractAction() { |
164,7 → 164,7 |
public void actionPerformed(ActionEvent e) { |
transfertFactureClient(IListe.get(e).getSelectedRows()); |
} |
}, false, "sales.order.create.invoice") { |
}, true, "sales.order.create.invoice") { |
@Override |
public boolean enabledFor(List<SQLRowValues> selection) { |
661,7 → 661,7 |
return TransfertGroupSQLComponent.openTransfertFrame(rows, "SAISIE_VENTE_FACTURE", VenteFactureSoldeSQLComponent.ID); |
} |
private BigDecimal getAvancement(SQLRowAccessor r) { |
public BigDecimal getAvancement(SQLRowAccessor r) { |
Collection<? extends SQLRowAccessor> rows = r.getReferentRows(r.getTable().getTable("TR_COMMANDE_CLIENT")); |
long totalFact = 0; |
long total = r.getLong("T_HT"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/element/CommandeClientElementSQLElement.java |
---|
93,6 → 93,9 |
l.add("ID_ARTICLE"); |
l.add("PA_HT"); |
l.add("PV_HT"); |
l.add("T_PA_HT"); |
l.add("T_PV_HT"); |
l.add("T_PV_TTC"); |
l.add("QTE"); |
l.add("QTE_UNITAIRE"); |
l.add("QTE_LIVREE"); |
192,7 → 195,7 |
@Override |
public ListMap<String, String> getShowAs() { |
final ListMap<String, String> res = new ListMap<String, String>(); |
res.putCollection("ID_COMMANDE_CLIENT", "NUMERO", "DATE", "DATE_LIVRAISON_PREV"); |
res.putCollection("ID_COMMANDE_CLIENT", "NUMERO", "ID_CLIENT", "DATE", "DATE_LIVRAISON_PREV"); |
if (getTable().contains("ID_ARTICLE")) { |
res.putCollection("ID_ARTICLE", "ID_FAMILLE_ARTICLE", "ID_FOURNISSEUR"); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/order/action/ListeDesCommandesClientItemsAction.java |
---|
New file |
0,0 → 1,109 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.core.sales.order.action; |
import org.openconcerto.erp.action.CreateFrameAbstractAction; |
import org.openconcerto.erp.core.common.ui.IListFilterDatePanel; |
import org.openconcerto.erp.core.common.ui.IListTotalPanel; |
import org.openconcerto.erp.core.common.ui.IListTotalPanel.Type; |
import org.openconcerto.erp.core.common.ui.ListeViewPanel; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.element.SQLElement; |
import org.openconcerto.sql.model.FieldPath; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.sql.model.Where; |
import org.openconcerto.sql.model.graph.Path; |
import org.openconcerto.sql.view.IListFrame; |
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn; |
import org.openconcerto.sql.view.list.IListe; |
import org.openconcerto.sql.view.list.SQLTableModelColumn; |
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.utils.CollectionUtils; |
import org.openconcerto.utils.Tuple2; |
import java.awt.GridBagConstraints; |
import java.math.BigDecimal; |
import java.util.ArrayList; |
import java.util.List; |
import java.util.Set; |
import javax.swing.Action; |
import javax.swing.JFrame; |
public class ListeDesCommandesClientItemsAction extends CreateFrameAbstractAction { |
public ListeDesCommandesClientItemsAction() { |
super(); |
this.putValue(Action.NAME, "Liste des articles commandés"); |
} |
public JFrame createFrame() { |
final SQLElement element = Configuration.getInstance().getDirectory().getElement("COMMANDE_CLIENT_ELEMENT"); |
final SQLTableModelSourceOnline tableSource = element.getTableSource(true); |
IListe liste = new IListe(tableSource); |
final ListeViewPanel listeAddPanel = new ListeViewPanel(element, liste); |
listeAddPanel.getListe().getRequest().setWhere(new Where(element.getTable().getField("ID_COMMANDE_CLIENT"), ">", 1)); |
BaseSQLTableModelColumn colStockR = new BaseSQLTableModelColumn("Qté restante à livrer", BigDecimal.class) { |
@Override |
protected Object show_(SQLRowAccessor r) { |
BigDecimal qteAlivrer = r.getBigDecimal("QTE_UNITAIRE").multiply(new BigDecimal(r.getInt("QTE"))); |
BigDecimal qteLivree = BigDecimal.ZERO; |
if (r.getObject("QTE_LIVREE") != null) { |
qteLivree = r.getBigDecimal("QTE_LIVREE"); |
} |
return qteAlivrer.subtract(qteLivree); |
} |
@Override |
public Set<FieldPath> getPaths() { |
Path p = new Path(element.getTable()); |
return CollectionUtils.createSet(new FieldPath(p, "QTE"), new FieldPath(p, "QTE_UNITAIRE"), new FieldPath(p, "QTE_LIVREE")); |
} |
}; |
tableSource.getColumns().add(colStockR); |
List<Tuple2<? extends SQLTableModelColumn, Type>> listField = new ArrayList<Tuple2<? extends SQLTableModelColumn, Type>>(); |
listField.add(Tuple2.create(tableSource.getColumn(element.getTable().getField("QTE")), IListTotalPanel.Type.SOMME_QTE)); |
listField.add(Tuple2.create(colStockR, IListTotalPanel.Type.SOMME_QTE)); |
listField.add(Tuple2.create(tableSource.getColumn(element.getTable().getField("T_PA_HT")), IListTotalPanel.Type.SOMME)); |
listField.add(Tuple2.create(tableSource.getColumn(element.getTable().getField("T_PV_HT")), IListTotalPanel.Type.SOMME)); |
listField.add(Tuple2.create(tableSource.getColumn(element.getTable().getField("T_PV_TTC")), IListTotalPanel.Type.SOMME)); |
IListTotalPanel total = new IListTotalPanel(listeAddPanel.getListe(), listField, null, "Total"); |
GridBagConstraints c = new DefaultGridBagConstraints(); |
c.gridy = 2; |
c.weightx = 0; |
c.weighty = 0; |
c.anchor = GridBagConstraints.EAST; |
c.fill = GridBagConstraints.NONE; |
listeAddPanel.add(total, c); |
IListFrame frame = new IListFrame(listeAddPanel); |
frame.setTextTitle("Liste des articles commandés"); |
frame.getPanel().getListe().setModificationAllowed(false); |
frame.getPanel().setAddVisible(false); |
frame.getPanel().setSearchFullMode(true); |
// Date panel |
IListFilterDatePanel datePanel = new IListFilterDatePanel(frame.getPanel().getListe(), element.getTable().getTable("COMMANDE_CLIENT").getField("DATE"), IListFilterDatePanel.getDefaultMap()); |
c.gridy++; |
c.anchor = GridBagConstraints.CENTER; |
frame.getPanel().add(datePanel, c); |
return frame; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/element/SaisieVenteFactureSQLElement.java |
---|
20,6 → 20,7 |
import org.openconcerto.erp.core.common.ui.AbstractVenteArticleItemTable; |
import org.openconcerto.erp.core.common.ui.DeviseField; |
import org.openconcerto.erp.core.common.ui.PanelFrame; |
import org.openconcerto.erp.core.edm.AttachmentAction; |
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; |
127,6 → 128,8 |
public class SaisieVenteFactureSQLElement extends ComptaSQLConfElement { |
public static final String TABLENAME = "SAISIE_VENTE_FACTURE"; |
static public final String MESSAGE_FIELD_NAME = "ID_SDD_MESSAGE"; |
static public final String END2END_FIELD_NAME = "SDD_EndToEndId"; |
public SaisieVenteFactureSQLElement() { |
super(TABLENAME, "une facture", "factures"); |
159,6 → 162,12 |
}, false, "sales.invoice.create.delivery"); |
actionBL.setPredicate(IListeEvent.getSingleSelectionPredicate()); |
l.add(actionBL); |
if (getTable().contains("ATTACHMENTS")) { |
PredicateRowAction actionAttachment = new PredicateRowAction(new AttachmentAction().getAction(), true); |
actionAttachment.setPredicate(IListeEvent.getSingleSelectionPredicate()); |
getRowActions().add(actionAttachment); |
} |
PredicateRowAction actionAvoir = new PredicateRowAction(new AbstractAction() { |
public void actionPerformed(ActionEvent e) { |
TransfertBaseSQLComponent.openTransfertFrame(IListe.get(e).getSelectedRows(), "AVOIR_CLIENT"); |
188,7 → 197,7 |
((SaisieVenteFactureSQLComponent) editFrame.getSQLComponent()).loadFactureExistante(IListe.get(e).getSelectedId()); |
editFrame.setVisible(true); |
} |
}, false, "sales.invoice.clone") { |
}, true, "sales.invoice.clone") { |
public boolean enabledFor(IListeEvent evt) { |
List<? extends SQLRowAccessor> l = evt.getSelectedRows(); |
if (l != null && l.size() == 1) { |
249,7 → 258,6 |
@Override |
protected void setupLinks(SQLElementLinksSetup links) { |
super.setupLinks(links); |
if (getTable().contains("ID_ADRESSE")) { |
links.get("ID_ADRESSE").setType(LinkType.ASSOCIATION); |
257,6 → 265,7 |
if (getTable().contains("ID_ADRESSE_LIVRAISON")) { |
links.get("ID_ADRESSE_LIVRAISON").setType(LinkType.ASSOCIATION); |
} |
links.get(MESSAGE_FIELD_NAME).setType(LinkType.ASSOCIATION, ReferenceAction.RESTRICT); |
} |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/element/EcheanceClientSQLElement.java |
---|
25,6 → 25,7 |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.element.BaseSQLComponent; |
import org.openconcerto.sql.element.SQLComponent; |
import org.openconcerto.sql.element.SQLElement; |
import org.openconcerto.sql.model.FieldPath; |
import org.openconcerto.sql.model.SQLBase; |
import org.openconcerto.sql.model.SQLField; |
37,6 → 38,8 |
import org.openconcerto.sql.request.ListSQLRequest; |
import org.openconcerto.sql.sqlobject.ElementComboBox; |
import org.openconcerto.sql.users.rights.UserRightsManager; |
import org.openconcerto.sql.view.EditFrame; |
import org.openconcerto.sql.view.EditPanel.EditMode; |
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn; |
import org.openconcerto.sql.view.list.IListe; |
import org.openconcerto.sql.view.list.IListeAction.IListeEvent; |
77,6 → 80,23 |
public EcheanceClientSQLElement() { |
super("ECHEANCE_CLIENT", "une échéance client", "échéances clients"); |
{ |
PredicateRowAction action = new PredicateRowAction(new AbstractAction("Détails client") { |
@Override |
public void actionPerformed(ActionEvent arg0) { |
SQLElement eltClient = Configuration.getInstance().getDirectory().getElement(((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("CLIENT")); |
EditFrame edit = new EditFrame(eltClient, EditMode.MODIFICATION); |
edit.selectionId(IListe.get(arg0).getSelectedRow().asRow().getInt("ID_CLIENT")); |
edit.setVisible(true); |
} |
}, false); |
action.setPredicate(IListeEvent.getSingleSelectionPredicate()); |
getRowActions().add(action); |
} |
{ |
PredicateRowAction action = new PredicateRowAction(new AbstractAction("Voir la source") { |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/action/ListeDesElementsFactureAction.java |
---|
58,7 → 58,7 |
listeAddPanel.add(total, c); |
IListFrame frame = new IListFrame(listeAddPanel); |
frame.setTextTitle("Liste des missions facturées"); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
frame.getPanel().setAddVisible(false); |
frame.getPanel().setSearchFullMode(true); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/action/ListeDesFactureItemsAction.java |
---|
46,6 → 46,7 |
final ListeViewPanel listeAddPanel = new ListeViewPanel(element, liste); |
listeAddPanel.getListe().getRequest().setWhere(new Where(element.getTable().getField("ID_SAISIE_VENTE_FACTURE"), ">", 1)); |
List<SQLField> l = new ArrayList<SQLField>(); |
l.add(element.getTable().getField("QTE")); |
l.add(element.getTable().getField("T_PA_HT")); |
l.add(element.getTable().getField("T_PV_HT")); |
l.add(element.getTable().getField("T_PV_TTC")); |
59,7 → 60,7 |
listeAddPanel.add(total, c); |
IListFrame frame = new IListFrame(listeAddPanel); |
frame.setTextTitle("Liste des articles facturés"); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
frame.getPanel().setAddVisible(false); |
frame.getPanel().setSearchFullMode(true); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/action/ListeSDDMessageAction.java |
---|
New file |
0,0 → 1,43 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.core.sales.invoice.action; |
import org.openconcerto.erp.action.CreateFrameAbstractAction; |
import org.openconcerto.erp.core.finance.payment.element.SDDMessageSQLElement; |
import org.openconcerto.sql.element.SQLElementDirectory; |
import org.openconcerto.sql.view.IListFrame; |
import org.openconcerto.sql.view.ListeAddPanel; |
import javax.swing.JFrame; |
public class ListeSDDMessageAction extends CreateFrameAbstractAction { |
private final SDDMessageSQLElement elem; |
public ListeSDDMessageAction(SQLElementDirectory dir) { |
super(); |
this.elem = dir.getElement(SDDMessageSQLElement.class); |
} |
public final SDDMessageSQLElement getElem() { |
return this.elem; |
} |
@Override |
public JFrame createFrame() { |
final IListFrame res = new IListFrame(new ListeAddPanel(getElem())); |
res.getPanel().setReadWriteButtonsVisible(false); |
return res; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/ListPanelEcheancesClients.java |
---|
128,7 → 128,7 |
final SQLTableModelSource src = ListPanelEcheancesClients.this.getListe().getSource(); |
ListPanelEcheancesClients.this.getListe().setSQLEditable(true); |
ListPanelEcheancesClients.this.getListe().setModificationAllowed(true); |
SQLField fieldDateEch = elementEchT.getField("DATE"); |
for (SQLTableModelColumn column : src.getColumns()) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/ListeDesVentesPanel.java |
---|
18,19 → 18,25 |
import org.openconcerto.erp.core.common.ui.IListTotalPanel; |
import org.openconcerto.erp.core.common.ui.ListeViewPanel; |
import org.openconcerto.erp.core.finance.accounting.ui.ListeGestCommEltPanel; |
import org.openconcerto.erp.core.sales.invoice.component.SaisieVenteFactureSQLComponent; |
import org.openconcerto.erp.core.finance.payment.element.SDDMessageSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.SDDMessageSQLElement.GenerationResult; |
import org.openconcerto.erp.core.finance.payment.element.SDDMessageSQLElement.IgnoreReason; |
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement; |
import org.openconcerto.erp.core.sales.pos.ui.TextAreaTicketPanel; |
import org.openconcerto.erp.utils.TM; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.element.SQLElement; |
import org.openconcerto.sql.model.FieldPath; |
import org.openconcerto.sql.model.SQLField; |
import org.openconcerto.sql.model.SQLRow; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.model.Where; |
import org.openconcerto.sql.view.EditFrame; |
import org.openconcerto.sql.view.EditPanel; |
import org.openconcerto.sql.model.graph.Path; |
import org.openconcerto.sql.view.list.IListe; |
import org.openconcerto.sql.view.list.IListeAction.IListeEvent; |
import org.openconcerto.sql.view.list.ITableModel; |
import org.openconcerto.sql.view.list.RowAction; |
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction; |
import org.openconcerto.sql.view.list.SQLTableModelColumn; |
import org.openconcerto.sql.view.list.SQLTableModelColumnPath; |
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline; |
40,28 → 46,34 |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.TableSorter; |
import org.openconcerto.utils.cc.IClosure; |
import org.openconcerto.utils.i18n.Grammar_fr; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.Insets; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.math.BigInteger; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Collections; |
import java.util.Date; |
import java.util.HashMap; |
import java.util.List; |
import java.util.Map; |
import javax.swing.AbstractAction; |
import javax.swing.JButton; |
import javax.swing.JOptionPane; |
import javax.swing.JPanel; |
import javax.swing.JTabbedPane; |
import javax.swing.JTable; |
import javax.swing.SwingWorker; |
import javax.swing.table.TableColumn; |
public class ListeDesVentesPanel extends JPanel implements ActionListener { |
public class ListeDesVentesPanel extends JPanel { |
private ListeGestCommEltPanel listeFact; |
private JButton buttonEnvoye, buttonRegle, buttonDupliquer; |
// private JButton buttonEnvoye, buttonRegle, buttonDupliquer; |
private JLabelBold textField = new JLabelBold("0"); |
private JLabelBold textField2 = new JLabelBold("0"); |
112,7 → 124,9 |
dateEnvoiCol.setColumnInstaller(new IClosure<TableColumn>() { |
@Override |
public void executeChecked(TableColumn columnDateEnvoi) { |
columnDateEnvoi.setCellEditor(new org.openconcerto.ui.table.TimestampTableCellEditor()); |
final org.openconcerto.ui.table.TimestampTableCellEditor cellEditor = new org.openconcerto.ui.table.TimestampTableCellEditor(); |
cellEditor.setAllowNull(true); |
columnDateEnvoi.setCellEditor(cellEditor); |
columnDateEnvoi.setCellRenderer(new DateEnvoiRenderer()); |
} |
}); |
120,17 → 134,88 |
// Edition des dates de reglement |
if (dateReglCol != null) { |
dateReglCol.setColumnInstaller(new IClosure<TableColumn>() { |
@Override |
public void executeChecked(TableColumn columnDateReglement) { |
columnDateReglement.setCellEditor(new org.openconcerto.ui.table.TimestampTableCellEditor()); |
final org.openconcerto.ui.table.TimestampTableCellEditor cellEditor = new org.openconcerto.ui.table.TimestampTableCellEditor(); |
cellEditor.setAllowNull(true); |
columnDateReglement.setCellEditor(cellEditor); |
columnDateReglement.setCellRenderer(new DateEnvoiRenderer()); |
} |
}); |
} |
src.getColumns().add(new SQLTableModelColumnPath(new FieldPath(new Path(eltFacture.getTable()).addForeignField(SaisieVenteFactureSQLElement.MESSAGE_FIELD_NAME), "MessageIdentification"))); |
this.listeFact = new ListeGestCommEltPanel(eltFacture, new IListe(src), true); |
final SDDMessageSQLElement sepaMsgElem = eltFacture.getDirectory().getElement(SDDMessageSQLElement.class); |
final String aMessageLabel = sepaMsgElem.getName().getVariant(Grammar_fr.INDEFINITE_ARTICLE_SINGULAR); |
this.listeFact.getListe().addIListeAction(new RowAction.PredicateRowAction(new AbstractAction("Générer " + aMessageLabel, null) { |
@Override |
public void actionPerformed(ActionEvent e) { |
final IListe l = IListe.get(e); |
final List<Integer> selectedIDs = l.getSelection().getSelectedIDs(); |
// TODO dialog with label informing of the successful creation of message for n |
// invoices/n2 messages too far in the future/n3 messages with collection date |
// changed and having a button to open the file chooser |
new SwingWorker<GenerationResult, Object>() { |
@Override |
protected GenerationResult doInBackground() throws Exception { |
return sepaMsgElem.generateXML(selectedIDs); |
} |
@Override |
protected void done() { |
final GenerationResult genRes; |
try { |
genRes = this.get(); |
} catch (Exception e) { |
ExceptionHandler.handle(l, "Impossible de générer " + aMessageLabel, e); |
return; |
} |
final int includedInvoicesCount = genRes.getIncludedInvoicesCount(); |
final Map<String, Object> tmMap = new HashMap<>(); |
tmMap.put("msgElem", sepaMsgElem.getName()); |
tmMap.put("invoiceElem", elementVF.getName()); |
tmMap.put("invoiceElemCount", includedInvoicesCount); |
if (genRes.getDDInvoicesWithoutMessage().isEmpty()) { |
JOptionPane.showMessageDialog(l, TM.getTM().trM("sddMessage.generation.noneNeeded", tmMap)); |
} else if (genRes.getIgnoredInvoices().isEmpty()) { |
JOptionPane.showMessageDialog(l, TM.getTM().trM("sddMessage.generation.noneIgnored", tmMap)); |
} else { |
final int futureCount = genRes.getIgnoredInvoices().getNonNull(IgnoreReason.TOO_FAR_IN_FUTURE).size(); |
final int duplicateCount = genRes.getIgnoredInvoices().getNonNull(IgnoreReason.DUPLICATE_MANDATE).size(); |
final int missingInfoCount = genRes.getIgnoredInvoices().getNonNull(IgnoreReason.MISSING_INFO).size(); |
tmMap.put("futureCount", futureCount); |
tmMap.put("duplicateCount", duplicateCount); |
tmMap.put("missingInfoCount", missingInfoCount); |
final StringBuilder msg = new StringBuilder(256); |
msg.append(TM.getTM().trM("sddMessage.generation.someIgnored", tmMap)); |
msg.append('\n'); |
if (futureCount > 0) { |
msg.append("- "); |
msg.append(TM.getTM().trM("sddMessage.generation.someIgnored.future", tmMap)); |
} |
if (duplicateCount > 0) { |
msg.append("- "); |
msg.append(TM.getTM().trM("sddMessage.generation.someIgnored.duplicateMandate", tmMap)); |
} |
if (missingInfoCount > 0) { |
msg.append("- "); |
msg.append(TM.getTM().trM("sddMessage.generation.someIgnored.missingInfo", tmMap)); |
} |
final int messageType = duplicateCount == 0 ? JOptionPane.WARNING_MESSAGE : JOptionPane.ERROR_MESSAGE; |
JOptionPane.showMessageDialog(l, msg.toString(), null, messageType); |
} |
if (genRes.getInsertedMessage() != null) { |
sepaMsgElem.exportXML(l, Collections.singletonList(genRes.getInsertedMessage())); |
} |
} |
}.execute(); |
} |
}, false, true).setPredicate(IListeEvent.getNonEmptySelectionPredicate())); |
this.listeFact.setOpaque(false); |
this.listeFact.getListe().setSQLEditable(true); |
this.listeFact.getListe().setModificationAllowed(true); |
final JTable tableFact = this.listeFact.getListe().getJTable(); |
final SQLTableModelColumn numeroCol = src.getColumn(eltFacture.getTable().getField("NUMERO")); |
((TableSorter) tableFact.getModel()).setSortingStatus(src.getColumns().indexOf(numeroCol), TableSorter.ASCENDING); |
137,25 → 222,6 |
JPanel panelFacture = new JPanel(new GridBagLayout()); |
GridBagConstraints cFacture = new DefaultGridBagConstraints(); |
this.buttonEnvoye = new JButton("Facture envoyée"); |
cFacture.fill = GridBagConstraints.NONE; |
this.buttonEnvoye.addActionListener(this); |
this.buttonEnvoye.setEnabled(false); |
panelFacture.setOpaque(false); |
panelFacture.add(this.buttonEnvoye, cFacture); |
// Reglé |
this.buttonRegle = new JButton("Facture réglée"); |
this.buttonRegle.addActionListener(this); |
this.buttonRegle.setEnabled(false); |
cFacture.gridx++; |
panelFacture.add(this.buttonRegle, cFacture); |
// |
this.buttonDupliquer = new JButton("Créer à partir de"); |
cFacture.fill = GridBagConstraints.NONE; |
this.buttonDupliquer.addActionListener(this); |
this.buttonDupliquer.setEnabled(false); |
cFacture.gridx++; |
panelFacture.add(this.buttonDupliquer, cFacture); |
cFacture.gridy++; |
cFacture.gridx = 0; |
188,21 → 254,43 |
panelFacture.add(filterDate, cFacture); |
tabbedPane.add("Ventes avec facture", panelFacture); |
this.listeFact.getListe().addIListener(new org.openconcerto.sql.view.IListener() { |
PredicateRowAction actionRegle = new PredicateRowAction(new AbstractAction("Facture réglée") { |
public void selectionId(int id, int field) { |
ListeDesVentesPanel.this.buttonEnvoye.setEnabled(id > 1); |
ListeDesVentesPanel.this.buttonRegle.setEnabled(id > 1); |
if (id > 1) { |
final ITableModel model = ListeDesVentesPanel.this.listeFact.getListe().getModel(); |
@Override |
public void actionPerformed(ActionEvent e) { |
final List<SQLRowValues> selectedRows = IListe.get(e).getSelectedRows(); |
for (SQLRowAccessor sqlRowAccessor : selectedRows) { |
final SQLRowValues rowVals = sqlRowAccessor.asRow().createEmptyUpdateRow(); |
rowVals.put("DATE_REGLEMENT", new Date()); |
try { |
rowVals.update(); |
} catch (SQLException e1) { |
ExceptionHandler.handle("Modification impossible", e1); |
} |
} |
} |
}, true); |
actionRegle.setPredicate(IListeEvent.getNonEmptySelectionPredicate()); |
this.listeFact.getListe().addIListeAction(actionRegle); |
SQLRowAccessor r = model.getRow(model.indexFromID(id)).getRow(); |
ListeDesVentesPanel.this.buttonDupliquer.setEnabled(!r.getBoolean("PARTIAL") && !r.getBoolean("SOLDE")); |
} else { |
ListeDesVentesPanel.this.buttonDupliquer.setEnabled(false); |
PredicateRowAction actionEnvoye = new PredicateRowAction(new AbstractAction("Facture envoyée") { |
@Override |
public void actionPerformed(ActionEvent e) { |
final List<SQLRowValues> selectedRows = IListe.get(e).getSelectedRows(); |
for (SQLRowAccessor sqlRowAccessor : selectedRows) { |
final SQLRowValues rowVals = sqlRowAccessor.asRow().createEmptyUpdateRow(); |
rowVals.put("DATE_ENVOI", new Date()); |
try { |
rowVals.update(); |
} catch (SQLException e1) { |
ExceptionHandler.handle("Modification impossible", e1); |
} |
} |
}); |
} |
}, true); |
actionEnvoye.setPredicate(IListeEvent.getNonEmptySelectionPredicate()); |
this.listeFact.getListe().addIListeAction(actionEnvoye); |
{ |
249,7 → 337,7 |
// Tab Vente comptoir |
{ |
final ListeGestCommEltPanel listeVC = new ListeGestCommEltPanel(Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_COMPTOIR"), true); |
listeVC.getListe().setSQLEditable(false); |
listeVC.getListe().setModificationAllowed(false); |
listeVC.setOpaque(false); |
final JTable table = listeVC.getListe().getJTable(); |
289,43 → 377,4 |
this.add(tabbedPane, c); |
} |
private EditFrame editFrame; |
public void actionPerformed(ActionEvent e) { |
if (e.getSource() == this.buttonEnvoye) { |
final List<SQLRowValues> selectedRows = this.listeFact.getListe().getSelectedRows(); |
for (SQLRowAccessor sqlRowAccessor : selectedRows) { |
final SQLRowValues rowVals = sqlRowAccessor.asRow().createEmptyUpdateRow(); |
rowVals.put("DATE_ENVOI", new Date()); |
try { |
rowVals.update(); |
} catch (SQLException e1) { |
ExceptionHandler.handle("Modification impossible", e1); |
} |
} |
} else if (e.getSource() == this.buttonRegle) { |
final List<SQLRowValues> selectedRows = this.listeFact.getListe().getSelectedRows(); |
for (SQLRowAccessor sqlRowAccessor : selectedRows) { |
final SQLRowValues rowVals = sqlRowAccessor.asRow().createEmptyUpdateRow(); |
rowVals.put("DATE_REGLEMENT", new Date()); |
try { |
rowVals.update(); |
} catch (SQLException e1) { |
ExceptionHandler.handle("Modification impossible", e1); |
} |
} |
} else { |
if (e.getSource() == this.buttonDupliquer) { |
if (this.editFrame == null) { |
SQLElement eltFact = Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE"); |
this.editFrame = new EditFrame(eltFact, EditPanel.CREATION); |
} |
final SQLRow selectedRow = this.listeFact.getListe().getSelectedRow().asRow(); |
((SaisieVenteFactureSQLComponent) this.editFrame.getSQLComponent()).loadFactureExistante(selectedRow.getID()); |
this.editFrame.setVisible(true); |
} |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/element/ComptaSQLConfElement.java |
---|
16,17 → 16,9 |
import org.openconcerto.erp.config.Gestion; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.view.list.RowAction; |
import org.openconcerto.sql.view.list.TableAction; |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.task.config.ComptaBasePropsConfiguration; |
import java.awt.event.ActionEvent; |
import java.util.ArrayList; |
import java.util.List; |
import javax.swing.AbstractAction; |
/** |
* SQLElement de la base société |
* |
35,7 → 27,6 |
*/ |
public abstract class ComptaSQLConfElement extends SocieteSQLConfElement { |
private static DBRoot baseSociete; |
private static DBRoot getBaseSociete() { |
53,12 → 44,19 |
} |
public ComptaSQLConfElement(String tableName) { |
super(getBaseSociete().findTable(tableName, true), null); |
this(tableName, null); |
} |
public ComptaSQLConfElement(String tableName, String code) { |
super(getBaseSociete().findTable(tableName, true), code); |
this(getBaseSociete().findTable(tableName, true), code); |
} |
public ComptaSQLConfElement(SQLTable table) { |
this(table, null); |
} |
public ComptaSQLConfElement(SQLTable table, String code) { |
super(table, code); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractAchatArticleItemTable.java.mine |
---|
File deleted |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractAchatArticleItemTable.java.r23577 |
---|
File deleted |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractAchatArticleItemTable.java.r23597 |
---|
File deleted |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/IListTotalPanel.java |
---|
52,6 → 52,8 |
MOYENNE_DEVISE, |
// Somme total d'une colonne |
SOMME, |
// Somme total d'une colonne |
SOMME_QTE, |
// Marge en pourcentage requiert dans la liste la colonne achat en premier et vente en |
// deuxieme |
MOYENNE_MARGE, |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/component/SocieteCommonSQLElement.java |
---|
13,22 → 13,6 |
package org.openconcerto.erp.core.common.component; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.Insets; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Collections; |
import java.util.Date; |
import java.util.List; |
import javax.swing.BorderFactory; |
import javax.swing.JComboBox; |
import javax.swing.JLabel; |
import javax.swing.JPanel; |
import javax.swing.JTextField; |
import javax.swing.SwingConstants; |
import org.openconcerto.erp.config.ComptaPropsConfiguration; |
import org.openconcerto.erp.core.common.ui.PanelFrame; |
import org.openconcerto.erp.panel.ChargementCreationSocietePanel; |
52,6 → 36,22 |
import org.openconcerto.ui.component.InteractionMode; |
import org.openconcerto.utils.ListMap; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.Insets; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Collections; |
import java.util.Date; |
import java.util.List; |
import javax.swing.BorderFactory; |
import javax.swing.JComboBox; |
import javax.swing.JLabel; |
import javax.swing.JPanel; |
import javax.swing.JTextField; |
import javax.swing.SwingConstants; |
/** |
* Sociétés existantes avec le nom de la base associée |
*/ |
278,7 → 278,7 |
this.add(fieldIban, c); |
this.addView(fieldIban, "IBAN"); |
// Capital |
// BIC |
c.gridx++; |
c.weightx = 0; |
JLabel labelBIC = new JLabel(getLabelFor("BIC")); |
291,6 → 291,20 |
this.add(fieldBIC, c); |
this.addView(fieldBIC, "BIC"); |
// SEPA creditor |
c.gridx = 0; |
c.gridy++; |
c.weightx = 0; |
JLabel labelICS = new JLabel(getLabelFor("SEPA_CREDITOR_ID")); |
labelICS.setHorizontalAlignment(SwingConstants.RIGHT); |
this.add(labelICS, c); |
c.gridx++; |
c.weightx = 1; |
JTextField fieldICS = new JTextField(); |
this.add(fieldICS, c); |
this.addView(fieldICS, "SEPA_CREDITOR_ID"); |
// Assurance |
if (getTable().contains("NUMERO_POLICE")) { |
c.gridy++; |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/credit/action/ListeDesAvoirsFournisseurAction.java |
---|
70,7 → 70,7 |
final IListFrame frame = new IListFrame(panel); |
frame.getPanel().setAddVisible(true); |
frame.getPanel().getListe().addIListeActions(new MouseSheetXmlListeListener(AvoirFournisseurXmlSheet.class).getRowActions()); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
return frame; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/element/FactureFournisseurSQLElement.java |
---|
13,18 → 13,19 |
package org.openconcerto.erp.core.supplychain.order.element; |
import java.util.ArrayList; |
import java.util.HashSet; |
import java.util.List; |
import java.util.Set; |
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement; |
import org.openconcerto.erp.core.edm.AttachmentAction; |
import org.openconcerto.erp.core.supplychain.order.component.FactureFournisseurSQLComponent; |
import org.openconcerto.erp.generationDoc.gestcomm.FactureFournisseurXmlSheet; |
import org.openconcerto.erp.model.MouseSheetXmlListeListener; |
import org.openconcerto.sql.element.SQLComponent; |
import org.openconcerto.sql.view.list.IListeAction.IListeEvent; |
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction; |
import org.openconcerto.utils.ListMap; |
import java.util.ArrayList; |
import java.util.List; |
public class FactureFournisseurSQLElement extends ComptaSQLConfElement { |
public FactureFournisseurSQLElement() { |
33,7 → 34,12 |
mouseSheetXmlListeListener.setGenerateHeader(true); |
mouseSheetXmlListeListener.setShowHeader(true); |
getRowActions().addAll(mouseSheetXmlListeListener.getRowActions()); |
if (getTable().contains("ATTACHMENTS")) { |
PredicateRowAction actionAttachment = new PredicateRowAction(new AttachmentAction().getAction(), true); |
actionAttachment.setPredicate(IListeEvent.getSingleSelectionPredicate()); |
getRowActions().add(actionAttachment); |
} |
} |
protected List<String> getListFields() { |
final List<String> l = new ArrayList<String>(); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/ui/ListPanelEcheancesFourn.java |
---|
86,7 → 86,7 |
} |
this.getListe().getRequest().setWhere(wNotRegle); |
this.getListe().setSQLEditable(false); |
this.getListe().setModificationAllowed(false); |
final JTable jTable = this.getListe().getJTable(); |
final int columnCount = jTable.getColumnCount(); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/CustomerGroup.java |
---|
61,9 → 61,18 |
gContact.addItem("customerrelationship.customer.contacts", new LayoutHints(true, true, true, true, true, true, true, true)); |
this.add(gContact); |
final Group gProspect = new Group("customerrelationship.customer.lead", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS); |
gProspect.addItem("ACCEPTE_TEL"); |
gProspect.addItem("ACCEPTE_SMS"); |
gProspect.addItem("ACCEPTE_EMAIL"); |
gProspect.addItem("ACCEPTE_COURRIER"); |
this.add(gProspect); |
final Group gPayment = new Group("customerrelationship.customer.payment", LayoutHints.DEFAULT_SEPARATED_GROUP_HINTS); |
gPayment.addItem("RIB", LayoutHints.DEFAULT_LARGE_FIELD_HINTS); |
gPayment.addItem("CENTRE_GESTION", LayoutHints.DEFAULT_LARGE_FIELD_HINTS); |
gPayment.addItem("IBAN", LayoutHints.DEFAULT_LARGE_FIELD_HINTS); |
gPayment.addItem("BIC", LayoutHints.DEFAULT_FIELD_HINTS); |
gPayment.addItem("ID_MODE_REGLEMENT", new LayoutHints(true, true, true, true, true, false, true, true)); |
gPayment.addItem("ID_COMPTE_PCE"); |
gPayment.addItem("ENCOURS_MAX"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ContactSQLElementBase.java |
---|
195,6 → 195,9 |
if (getTable().contains("N4DS")) { |
addView("N4DS"); |
} |
if (getTable().contains("DATE_NAISSANCE")) |
this.addView("DATE_NAISSANCE"); |
} |
public void setIdClient(int idClient) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/ContactItemTable.java |
---|
21,10 → 21,15 |
import org.openconcerto.sql.view.list.RowValuesTableModel; |
import org.openconcerto.sql.view.list.RowValuesTableRenderer; |
import org.openconcerto.sql.view.list.SQLTableElement; |
import org.openconcerto.ui.FormatEditor; |
import org.openconcerto.utils.FormatGroup; |
import org.openconcerto.utils.convertor.DateToSQLConvertor; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.io.File; |
import java.text.DateFormat; |
import java.util.Date; |
import java.util.List; |
import java.util.Vector; |
104,6 → 109,20 |
list.add(tableElementNoMailing); |
} |
if (elt.getTable().contains("DATE_NAISSANCE")) { |
list.add(new SQLTableElement(elt.getTable().getField("DATE_NAISSANCE")) { |
private final DateToSQLConvertor conv = new DateToSQLConvertor(); |
{ |
this.setEditor(new FormatEditor( |
new FormatGroup(DateFormat.getDateInstance(DateFormat.SHORT), DateFormat.getDateInstance(DateFormat.MEDIUM), DateFormat.getDateInstance(DateFormat.LONG)))); |
} |
@Override |
public Object convertEditorValueToModel(Object value, SQLRowValues row) { |
return this.conv.convert((Date) value); |
} |
}); |
} |
final RowValuesTableModel model = new RowValuesTableModel(elt, list, elt.getTable().getField("NOM"), false, defaultRow); |
this.table = new RowValuesTable(model, new File(Configuration.getInstance().getConfDir(), "Table" + File.separator + "Table_Contact.xml")); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/customerrelationship/customer/element/CustomerSQLComponent.java |
---|
141,7 → 141,7 |
} |
}); |
t.addAction(new AbstractAction("Modifier/Supprimer") { |
t.addAction(new AbstractAction(TM.tr("modify.or.delete")) { |
@Override |
public void actionPerformed(ActionEvent e) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/ComptePCESQLElement.java |
---|
27,6 → 27,7 |
import org.openconcerto.sql.model.SQLField; |
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.SQLTable; |
344,12 → 345,20 |
if (field == null) { |
throw new IllegalArgumentException("no field NUMERO in table " + compteTable.getName()); |
} |
numero = numero.trim(); |
SQLRow res = cacheForTable.getFirstRowContains(numero, field); |
SQLRow res = cacheForTable.getFirstRowContains(numero.trim(), field); |
if (res != null) { |
return res; |
} else { |
// Verification en BD |
SQLSelect sel = new SQLSelect(); |
sel.addSelectStar(compteTable); |
sel.setWhere(new Where(compteTable.getField("NUMERO"), "=", numero)); |
List<SQLRow> resultInDb = SQLRowListRSH.execute(sel); |
if (!resultInDb.isEmpty()) { |
return cacheForTable.getRows().get(0); |
} else { |
SQLRowValues rowVals = new SQLRowValues(compteTable); |
rowVals.put("NUMERO", numero); |
360,9 → 369,9 |
ExceptionHandler.handle("Erreur lors de la création du compte numéro : " + numero, e); |
return null; |
} |
} |
} |
} |
/** |
* retourne l'id d'un compte en fonction de son numero, si le compte n'existe pas il sera créé |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/EcritureSQLElement.java |
---|
169,7 → 169,7 |
Where w = new Where(ecrTable.getField("ID_JOURNAL"), "=", rowEcr.getInt("ID_JOURNAL")); |
f2.getPanel().getListe().getRequest().setWhere(w); |
f2.getPanel().getListe().setSQLEditable(false); |
f2.getPanel().getListe().setModificationAllowed(false); |
f2.pack(); |
f2.setVisible(true); |
} |
202,7 → 202,7 |
Where w = new Where(ecrTable.getField("ID_COMPTE_PCE"), "=", rowCpt.getID()); |
f.getPanel().getListe().getRequest().setWhere(w); |
f.getPanel().getListe().setSQLEditable(false); |
f.getPanel().getListe().setModificationAllowed(false); |
f.pack(); |
f.setVisible(true); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/Map2033A.java |
---|
18,9 → 18,7 |
import org.openconcerto.erp.core.finance.accounting.model.SommeCompte; |
import org.openconcerto.erp.preferences.TemplateNXProps; |
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; |
349,15 → 347,12 |
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) |
+ this.sommeCompte.sommeCompteFils("4456", this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompte(44581, 44583, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteDebiteur(44586, 44586, true, this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("4487", this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteDebiteur(43, 43, true, this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("441", this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteDebiteur(443, 445, true, this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("4487", this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteDebiteur(451, 451, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(455, 455, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteDebiteur(4560, 4561, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(4563, 4569, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteDebiteur(458, 458, true, this.dateDebut, this.dateFin) + this.sommeCompte.sommeCompteFils("462", this.dateDebut, this.dateFin) |
+ this.sommeCompte.sommeCompteFils("465", this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(467, 467, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.sommeCompteFils("4687", this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(478, 478, true, this.dateDebut, this.dateFin); |
+ this.sommeCompte.soldeCompteDebiteur(458, 458, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteDebiteur(46, 46, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteDebiteur(478, 478, true, this.dateDebut, this.dateFin); |
this.m.put("ACTIF1.9", GestionDevise.currencyToString(v072, false)); |
// 074 -SommeSolde( 495, 499 ) |
714,7 → 709,7 |
// Racine = "400-401, 403, 4080-4081, 4088" |
// S166=-40(C)...405-40A(C)...40Z-403-4081-4084-4088 |
long v166 = this.sommeCompte.soldeCompteCrediteur(403, 403, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(401, 401, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteCrediteur(4081, 4081, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(4088, 4088, true, this.dateDebut, this.dateFin); |
+ this.sommeCompte.soldeCompteCrediteur(408, 408, true, this.dateDebut, this.dateFin); |
// float v166 = this.sommeCompte.soldeCompteCrediteur(400, 401, true) - |
// this.sommeCompte.sommeCompteFils("403") + |
// this.sommeCompte.soldeCompte(4080, 4081, false) |
790,20 → 785,13 |
+ this.sommeCompte.soldeCompteCrediteur(422, 422, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(424, 424, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteCrediteur(427, 427, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(4282, 4282, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteCrediteur(4284, 4284, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(4286, 4286, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteCrediteur(43, 43, true, this.dateDebut, this.dateFin) - this.sommeCompte.soldeCompteCrediteur(4387, 4387, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteCrediteur(442, 442, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(443, 443, true, this.dateDebut, this.dateFin) |
+ 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.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) |
+ this.sommeCompte.soldeCompteCrediteur(43, 43, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(442, 442, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteCrediteur(443, 445, 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(4196, 4198, true, this.dateDebut, this.dateFin) |
+ this.sommeCompte.soldeCompteCrediteur(46, 46, true, this.dateDebut, this.dateFin) + this.sommeCompte.soldeCompteCrediteur(478, 478, true, this.dateDebut, this.dateFin) |
- this.sommeCompte.soldeCompte(509, 509, true, this.dateDebut, this.dateFin); |
this.m.put("PASSIF3.28", GestionDevise.currencyToString(v172, false)); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/GrandLivreSheetXML.java |
---|
380,13 → 380,14 |
} else { |
// si on change de compte alors on applique le style Titre 1 |
if (rowFirstEcr != null && idCptFirstEcr != idCpt && (!this.centralFourn || (!(numCptFirstEcr.startsWith("401") && numCpt.startsWith("401")))) |
if (rowFirstEcr != null && !numCptFirstEcr.equals(numCpt) && (!this.centralFourn || (!(numCptFirstEcr.startsWith("401") && numCpt.startsWith("401")))) |
&& (!this.centralClient || (!(numCptFirstEcr.startsWith("411") && numCpt.startsWith("411"))))) { |
makeSousTotal(rowFirstEcr.getString("COMPTE_NUMERO"), rowFirstEcr.getString("COMPTE_NOM"), ooLine, style, tableauVals.size() - 1, sousTotalDebit, sousTotalCredit); |
rowFirstEcr = rowEcr; |
idCptFirstEcr = rowFirstEcr.getInt("ID_COMPTE_PCE"); |
numCptFirstEcr = rowEcr.getString("COMPTE_NUMERO"); |
makeSousTotal(numCpt, nomCpt, ooLine, style, tableauVals.size() - 1, sousTotalDebit, sousTotalCredit); |
sousTotalCredit = 0; |
sousTotalDebit = 0; |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/action/ListeDesEcrituresAction.java |
---|
139,7 → 139,7 |
frame.getPanel().setAddVisible(false); |
frame.getPanel().setModifyVisible(false); |
frame.getPanel().setReloadVisible(true); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
table.addMouseListener(new MouseAdapter() { |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/LettragePanel.java |
---|
36,6 → 36,7 |
import org.openconcerto.sql.users.rights.UserRightsManager; |
import org.openconcerto.sql.view.list.IListe; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.JDate; |
import org.openconcerto.ui.TitledSeparator; |
import org.openconcerto.ui.warning.JLabelWarning; |
285,7 → 286,7 |
c.gridheight = 3; |
this.model = new LettrageModel(this.selCompte.getSelectedId()); |
JTable table = new JTable(this.model); |
table.setRowHeight(FontUtils.getPreferredRowHeight(table)); |
// AlternateTableCellRenderer.setAllColumns(table); |
for (int i = 0; i < table.getColumnCount(); i++) { |
// if (table.getColumnClass(i) == Long.class || table.getColumnClass(i) == |
693,7 → 694,7 |
} |
this.ecriturePanel.getListe().getRequest().setWhere(w); |
this.ecriturePanel.getListe().setSQLEditable(false); |
this.ecriturePanel.getListe().setModificationAllowed(false); |
this.model.setIdCompte(Integer.parseInt(idCpt.toString())); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/BalancePanel.java |
---|
17,6 → 17,7 |
import org.openconcerto.erp.core.finance.accounting.model.BalanceModel; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.state.JTableStateManager; |
import org.openconcerto.utils.GestionDevise; |
62,6 → 63,7 |
final BalanceModel model = new BalanceModel(); |
final JTable table = new JTable(model); |
table.setRowHeight(FontUtils.getPreferredRowHeight(table)); |
new SwingWorker<String, Object>() { |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/PlanComptableEPanel.java |
---|
25,6 → 25,7 |
import org.openconcerto.sql.view.EditFrame; |
import org.openconcerto.sql.view.EditPanel; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.TitledSeparator; |
import java.awt.Dimension; |
181,7 → 182,7 |
final PlanComptableEModel model = new PlanComptableEModel(ccTmp); |
final JTable table = new JTable(model); |
table.setRowHeight(FontUtils.getPreferredRowHeight(table)); |
table.getColumnModel().getColumn(0).setCellRenderer(new PlanComptableCellRenderer(0)); |
table.getColumnModel().getColumn(1).setCellRenderer(new PlanComptableCellRenderer(0)); |
// table.getColumnModel().getColumn(0).setPreferredWidth(30); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/PlanComptableGPanel.java |
---|
22,6 → 22,7 |
import org.openconcerto.sql.model.SQLSelect; |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.JMultiLineToolTip; |
import org.openconcerto.ui.TitledSeparator; |
251,7 → 252,7 |
return t; |
} |
}; |
table.setRowHeight(FontUtils.getPreferredRowHeight(table)); |
table.getColumnModel().getColumn(0).setCellRenderer(new PlanComptableCellRenderer(0)); |
table.getColumnModel().getColumn(1).setCellRenderer(new PlanComptableCellRenderer(0)); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/PointagePanel.java |
---|
34,6 → 34,7 |
import org.openconcerto.sql.users.rights.UserRightsManager; |
import org.openconcerto.sql.view.list.IListe; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.JDate; |
import org.openconcerto.ui.TitledSeparator; |
import org.openconcerto.ui.warning.JLabelWarning; |
289,7 → 290,7 |
c.gridheight = 3; |
this.model = new PointageModel(this.selCompte.getSelectedId()); |
JTable table = new JTable(this.model); |
table.setRowHeight(FontUtils.getPreferredRowHeight(table)); |
// AlternateTableCellRenderer.setAllColumns(table); |
final DeviseNiceTableCellRenderer cellRenderer = new DeviseNiceTableCellRenderer(); |
for (int i = 0; i < table.getColumnCount(); i++) { |
620,7 → 621,7 |
} |
this.ecriturePanel.getListe().getRequest().setWhere(w); |
this.ecriturePanel.getListe().setSQLEditable(false); |
this.ecriturePanel.getListe().setModificationAllowed(false); |
this.model.setIdCompte(Integer.parseInt(idCpt.toString())); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/ImportEcriturePanel.java |
---|
21,6 → 21,7 |
import org.openconcerto.openoffice.ContentTypeVersioned; |
import org.openconcerto.sql.model.ConnectionHandlerNoSetup; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.model.SQLBackgroundTableCache; |
import org.openconcerto.sql.model.SQLDataSource; |
import org.openconcerto.sql.model.SQLRow; |
import org.openconcerto.sql.model.SQLRowListRSH; |
141,9 → 142,11 |
} |
final DateFormat format = new SimpleDateFormat("dd/MM/yyyy"); |
final String mouvementName = "Import " + format.format(new Date()); |
SQLBackgroundTableCache.getInstance().getCacheForTable(rootSociete.getTable("COMPTE_PCE")).setEnableReloadIfTableModified(false); |
// Vérification des données |
boolean ok = importTableModel(model, mouvementName, frame, true); |
if (ok) { |
// Importation des données |
importTableModel(model, mouvementName, frame, false); |
SwingUtilities.invokeLater(new Runnable() { |
155,6 → 158,8 |
} |
} catch (Exception exn) { |
ExceptionHandler.handle("Erreur pendant l'importation", exn); |
} finally { |
SQLBackgroundTableCache.getInstance().getCacheForTable(rootSociete.getTable("COMPTE_PCE")).setEnableReloadIfTableModified(true); |
} |
return null; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/CompteGestCommPreferencePanel.java |
---|
46,6 → 46,7 |
private final static SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete(); |
private static final SQLTable tablePrefCompte = base.getTable("PREFS_COMPTE"); |
private SQLRowValues rowPrefCompteVals = new SQLRowValues(tablePrefCompte); |
private JCheckBox checkLettrageAuto = new JCheckBox("Activer le lettrage automatique."); |
private JCheckBox checkHideCompteFacture = new JCheckBox("Ne pas afficher les comptes dans les factures."); |
private JCheckBox checkHideCompteClient = new JCheckBox("Ne pas afficher les comptes dans les clients."); |
private JCheckBox checkHideAnalytique = new JCheckBox("Ne pas afficher l'analytique dans les saisies au kilomètre."); |
73,7 → 74,8 |
c.weighty = 0; |
c.gridwidth = GridBagConstraints.REMAINDER; |
this.add(this.checkLettrageAuto, c); |
c.gridy++; |
this.add(this.checkHideCompteClient, c); |
c.gridy++; |
this.add(this.checkHideCompteFacture, c); |
330,6 → 332,7 |
this.rowPrefCompteVals.put("ID_COMPTE_PCE_TVA_IMMO", this.selCompteTVAImmo.getValue()); |
this.rowPrefCompteVals.put("ID_COMPTE_PCE_PORT_SOUMIS", this.selComptePortSoumis.getValue()); |
this.rowPrefCompteVals.put("ID_COMPTE_PCE_PORT_NON_SOUMIS", this.selComptePortNonSoumis.getValue()); |
this.rowPrefCompteVals.put("AUTO_LETTRAGE", this.checkLettrageAuto.isSelected()); |
DefaultNXProps.getInstance().setProperty("HideCompteClient", String.valueOf(this.checkHideCompteClient.isSelected())); |
DefaultNXProps.getInstance().setProperty("HideCompteFacture", String.valueOf(this.checkHideCompteFacture.isSelected())); |
DefaultNXProps.getInstance().setProperty("HideAnalytique", String.valueOf(this.checkHideAnalytique.isSelected())); |
349,6 → 352,8 |
compte = ComptePCESQLElement.getComptePceDefault("Achats"); |
this.checkLettrageAuto.setSelected(false); |
int value = ComptePCESQLElement.getId(compte); |
this.selCompteAchat.setValue(value); |
458,6 → 463,7 |
setComboValues(selCompteTVADed, "ID_COMPTE_PCE_TVA_ACHAT", "TVADeductible"); |
setComboValues(selCompteTVAIntraComm, "ID_COMPTE_PCE_TVA_INTRA", "TVAIntraComm"); |
setComboValues(selCompteTVAImmo, "ID_COMPTE_PCE_TVA_IMMO", "TVAImmo"); |
this.checkLettrageAuto.setSelected(rowPrefCompteVals.getBoolean("AUTO_LETTRAGE")); |
this.checkHideCompteClient.setSelected(Boolean.valueOf(DefaultNXProps.getInstance().getProperty("HideCompteClient"))); |
this.checkHideCompteFacture.setSelected(Boolean.valueOf(DefaultNXProps.getInstance().getProperty("HideCompteFacture"))); |
this.checkHideAnalytique.setSelected(Boolean.valueOf(DefaultNXProps.getInstance().getProperty("HideAnalytique"))); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/ListPanelEcritures.java |
---|
45,7 → 45,7 |
super(element, l); |
this.buttonAjouter.setVisible(false); |
this.getListe().setSQLEditable(false); |
this.getListe().setModificationAllowed(false); |
// TODO verifier que ca fonctionne, si selection d'une ecriture valide alors bouton disable |
this.getListe().addIListener(new IListener() { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/EtatJournauxPanel.java |
---|
303,7 → 303,7 |
this.listEcriture.setModificationVisible(false); |
this.listEcriture.setAjoutVisible(false); |
this.listEcriture.setSuppressionVisible(false); |
this.listEcriture.getListe().setSQLEditable(false); |
this.listEcriture.getListe().setModificationAllowed(false); |
Dimension d; |
// Taille limitée à 200 maximum |
323,7 → 323,7 |
c.weighty = 1; |
c.fill = GridBagConstraints.BOTH; |
this.listEcriture.getListe().setSQLEditable(false); |
this.listEcriture.getListe().setModificationAllowed(false); |
panelMoisCompte.add(this.listEcriture, c); |
this.listEcriture.getListe().getJTable().addMouseListener(new MouseAdapter() { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/element/SDDMessageSQLElement.java |
---|
New file |
0,0 → 1,673 |
/* |
* 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.payment.element; |
import org.openconcerto.erp.config.ComptaPropsConfiguration; |
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement; |
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement; |
import org.openconcerto.sql.element.SQLComponent; |
import org.openconcerto.sql.element.UISQLComponent; |
import org.openconcerto.sql.model.ConnectionHandlerNoSetup; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.model.SQLDataSource; |
import org.openconcerto.sql.model.SQLField; |
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.SQLRowValuesListFetcher; |
import org.openconcerto.sql.model.SQLSchema; |
import org.openconcerto.sql.model.SQLSelect; |
import org.openconcerto.sql.model.SQLSelect.LockStrength; |
import org.openconcerto.sql.model.SQLSelectJoin; |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.model.Where; |
import org.openconcerto.sql.preferences.SQLPreferences; |
import org.openconcerto.sql.request.SQLFieldTranslator; |
import org.openconcerto.sql.utils.SQLCreateTable; |
import org.openconcerto.sql.utils.SQLUtils; |
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.utils.CollectionMap2Itf.ListMapItf; |
import org.openconcerto.utils.DecimalUtils; |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.FileUtils; |
import org.openconcerto.utils.ListMap; |
import org.openconcerto.utils.StringUtils; |
import org.openconcerto.utils.TimeUtils; |
import org.openconcerto.utils.Tuple2; |
import org.openconcerto.utils.XMLDateFormat; |
import org.openconcerto.utils.cc.ITransformer; |
import org.openconcerto.utils.i18n.Grammar_fr; |
import org.openconcerto.xml.JDOM2Utils; |
import java.awt.Component; |
import java.awt.event.ActionEvent; |
import java.io.File; |
import java.io.IOException; |
import java.math.BigDecimal; |
import java.sql.Clob; |
import java.sql.SQLException; |
import java.text.DateFormat; |
import java.text.SimpleDateFormat; |
import java.util.ArrayList; |
import java.util.Calendar; |
import java.util.Collection; |
import java.util.Collections; |
import java.util.Date; |
import java.util.HashMap; |
import java.util.HashSet; |
import java.util.List; |
import java.util.Map; |
import java.util.Map.Entry; |
import java.util.NavigableMap; |
import java.util.Set; |
import java.util.TreeMap; |
import java.util.prefs.Preferences; |
import javax.swing.AbstractAction; |
import javax.swing.JFileChooser; |
import org.jdom2.Document; |
import org.jdom2.Element; |
import org.jdom2.Namespace; |
public final class SDDMessageSQLElement extends ComptaSQLConfElement { |
static final String TABLE_NAME = "SEPA_DIRECT_DEBIT_MESSAGE"; |
static public final String XML_LOCATION_PREF_KEY = "SDD.XML.location"; |
public static final String SERIAL_MD = "SDD_MESSAGE_SERIAL"; |
public static SQLCreateTable getCreateTable(final DBRoot root) { |
if (root.contains(TABLE_NAME)) |
return null; |
final SQLCreateTable res = new SQLCreateTable(root, TABLE_NAME); |
res.addVarCharColumn("MessageIdentification", 35); |
res.addColumn("CreationDateTime", res.getSyntax().getDateAndTimeType(), null, false); |
res.addIntegerColumn("NumberOfTransactions", 0); |
res.addDecimalColumn("ControlSum", 16, 6, BigDecimal.ZERO, false); |
res.addColumn("XML", res.getSyntax().getTypeNames(Clob.class).iterator().next(), null, false); |
return res; |
} |
private final String prefsPath; |
private final SQLRow rowSociété; |
private final SQLPreferences dbPrefs; |
private final SQLFieldTranslator fieldTranslator; |
public SDDMessageSQLElement(final ComptaPropsConfiguration conf) { |
super(conf.getRootSociete().findTable(TABLE_NAME, true)); |
this.prefsPath = conf.getAppID() + '/' + this.getCode().replace('.', '/'); |
this.getRowActions().add(new RowAction.PredicateRowAction(new AbstractAction("Exporter…") { |
@Override |
public void actionPerformed(ActionEvent e) { |
final IListe l = IListe.get(e); |
// XML field values are quite large so only fetch them when needed |
final SQLTable t = l.getSource().getPrimaryTable(); |
final SQLSelect sel = new SQLSelect().addSelectStar(t); |
sel.setWhere(new Where(t.getKey(), l.getSelection().getUserSelectedIDs())); |
exportXML(l, SQLRowListRSH.execute(sel)); |
} |
}, true, false).setPredicate(IListeEvent.getNonEmptySelectionPredicate())); |
this.rowSociété = conf.getRowSociete(); |
this.dbPrefs = new SQLPreferences(conf.getRootSociete()); |
this.fieldTranslator = conf.getTranslator(); |
} |
public final Preferences getPreferences() { |
return Preferences.userRoot().node(this.prefsPath); |
} |
@Override |
protected List<String> getListFields() { |
final List<String> l = new ArrayList<String>(); |
l.add("MessageIdentification"); |
l.add("CreationDateTime"); |
l.add("NumberOfTransactions"); |
l.add("ControlSum"); |
return l; |
} |
@Override |
protected List<String> getComboFields() { |
final List<String> l = new ArrayList<String>(); |
l.add("MessageIdentification"); |
l.add("CreationDateTime"); |
l.add("ControlSum"); |
return l; |
} |
@Override |
public Set<String> getReadOnlyFields() { |
return this.getTable().getFieldsName(); |
} |
@Override |
protected SQLComponent createComponent() { |
return new UISQLComponent(this) { |
@Override |
protected void addViews() { |
this.addView("MessageIdentification"); |
this.addView("CreationDateTime"); |
this.addView("NumberOfTransactions"); |
this.addView("ControlSum"); |
this.addView("XML"); |
} |
}; |
} |
@Override |
protected String createCode() { |
// TODO rename createCodeFromPackage() to createCodeOfPackage() and change createCode() |
// implementation to use a new createCodeFromPackage() which uses the class name (w/o |
// SQLElement suffix) |
return this.createCodeFromPackage() + ".SDDMessage"; |
} |
public final void exportXML(final Component comp, final List<? extends SQLRowAccessor> messages) { |
final Preferences sddMsgPrefs = getPreferences(); |
final String storedPath = sddMsgPrefs.get(XML_LOCATION_PREF_KEY, ""); |
final JFileChooser fileChooser = new JFileChooser(storedPath); |
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); |
final int answer = fileChooser.showDialog(comp, "Exporter " + getName().getVariant(Grammar_fr.DEFINITE_ARTICLE_PLURAL)); |
if (answer == JFileChooser.APPROVE_OPTION) { |
final String newPath = fileChooser.getSelectedFile().getAbsolutePath(); |
sddMsgPrefs.put(XML_LOCATION_PREF_KEY, newPath); |
final File directDebitDir = new File(newPath); |
try { |
for (final SQLRowAccessor messageRow : messages) { |
FileUtils.write(messageRow.getString("XML"), new File(directDebitDir, messageRow.getString("MessageIdentification") + ".xml"), StringUtils.UTF8, false); |
} |
} catch (IOException exn) { |
ExceptionHandler.handle(comp, "Impossible d'exporter", exn); |
} |
} |
} |
protected static BigDecimal getInvoiceAmount(final SQLRowValues invoice) { |
return BigDecimal.valueOf(invoice.getLong("NET_A_PAYER")).movePointLeft(2); |
} |
static private final class InvoiceElem extends Tuple2<SQLRowValues, Element> { |
protected InvoiceElem(SQLRowValues a, Element b) { |
super(a, b); |
} |
} |
// Un lot est obligatoirement homogène sur les critères suivants : |
// - Même type de prélèvement SEPA (index 2.11 « LocalInstrument ») : SDD Core ou |
// SDD B2B |
// - Même séquence de présentation (index 2.14 « SequenceType ») : FRST ou RCUR |
static private final class PaymentInfo { |
private final Date collectionDate; |
private final String seqType; |
private final List<InvoiceElem> invoices; |
private final BigDecimal sum; |
protected PaymentInfo(Date collectionDate, String seqType, List<InvoiceElem> invoices) { |
super(); |
this.collectionDate = collectionDate; |
if (!SEPAMandateSQLElement.SEQ_VALUES.contains(seqType)) |
throw new IllegalArgumentException("Invalid sequence type : " + seqType); |
this.seqType = seqType; |
this.invoices = invoices; |
BigDecimal d = BigDecimal.ZERO; |
for (final InvoiceElem invoice : invoices) { |
d = d.add(getInvoiceAmount(invoice.get0())); |
} |
this.sum = d; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName() + " for " + this.invoices.size() + " " + this.seqType + " invoices at " + this.collectionDate; |
} |
} |
static private final class InvoicesByPaymentInfo { |
private final Date lowerBound, upperBound; |
private final NavigableMap<Date, ListMap<String, InvoiceElem>> map = new TreeMap<>(); |
private final Set<Number> lockedInvoicesIDs = new HashSet<>(); |
private BigDecimal sum = BigDecimal.ZERO; |
private final Set<String> invoiceNumbers = new HashSet<>(); |
private final Set<String> invoiceMandates = new HashSet<>(); |
private final ElementCreator elemCreator; |
protected InvoicesByPaymentInfo(Date lowerBound, Date upperBound, final ElementCreator elemCreator) { |
super(); |
if (lowerBound.compareTo(upperBound) >= 0) |
throw new IllegalArgumentException("Lower date after upper date : " + lowerBound + " >= " + upperBound); |
this.lowerBound = lowerBound; |
this.upperBound = upperBound; |
this.elemCreator = elemCreator; |
} |
final IgnoreReason addInvoice(final SQLRowValues invoice) { |
Date dueDate = ModeDeReglementSQLElement.calculDate(invoice.getForeign("ID_MODE_REGLEMENT"), invoice.getObjectAs("DATE", Date.class)); |
// don't ask direct debit too far in advance |
if (dueDate.after(this.upperBound)) { |
return IgnoreReason.TOO_FAR_IN_FUTURE; |
} else if (dueDate.before(this.lowerBound)) { |
dueDate = this.lowerBound; |
} |
final Element elem; |
try { |
elem = createDDTx(this.elemCreator, invoice); |
} catch (MissingInfoException e) { |
return IgnoreReason.MISSING_INFO; |
} |
// needed so that EndToEndId is unique |
if (!this.invoiceNumbers.add(invoice.getString("NUMERO"))) |
throw new IllegalStateException("Duplicate invoice number : " + invoice); |
final SQLRowAccessor mandate = invoice.getForeign("ID_MODE_REGLEMENT").getForeign("ID_SEPA_MANDATE"); |
if (!mandate.getBoolean("ACTIVE")) |
throw new IllegalStateException("Inactive mandate for " + invoice); |
// needed otherwise would have to update seqType while generating |
if (!this.invoiceMandates.add(mandate.getString("MandateIdentification"))) |
return IgnoreReason.DUPLICATE_MANDATE; |
this.lockedInvoicesIDs.add(invoice.getIDNumber()); |
ListMap<String, InvoiceElem> bySeqType = this.map.get(dueDate); |
if (bySeqType == null) { |
bySeqType = new ListMap<>(); |
this.map.put(dueDate, bySeqType); |
} |
bySeqType.add(mandate.getString("SequenceType"), new InvoiceElem(invoice, elem)); |
this.sum = this.sum.add(getInvoiceAmount(invoice)); |
return IgnoreReason.NONE; |
} |
public final int getTransactionCount() { |
return this.lockedInvoicesIDs.size(); |
} |
public final List<PaymentInfo> getPaymentInfos() { |
final List<PaymentInfo> res = new ArrayList<>(); |
for (final Entry<Date, ListMap<String, InvoiceElem>> e : this.map.entrySet()) { |
final Date collectionDate = e.getKey(); |
for (final Entry<String, List<InvoiceElem>> e2 : e.getValue().entrySet()) { |
final String seqType = e2.getKey(); |
res.add(new PaymentInfo(collectionDate, seqType, e2.getValue())); |
} |
} |
return res; |
} |
} |
public static enum IgnoreReason { |
NONE, TOO_FAR_IN_FUTURE, DUPLICATE_MANDATE, MISSING_INFO; |
} |
public static final class GenerationResult { |
private final Collection<? extends Number> passedIDs; |
private final List<SQLRowValues> withDDWithoutMessage; |
private final ListMapItf<IgnoreReason, SQLRowValues> ignoredInvoices; |
private final SQLRow insertedMessage; |
private final int invoiceCount; |
protected GenerationResult(Collection<? extends Number> passedIDs, List<SQLRowValues> withDDWithoutMessage, ListMap<IgnoreReason, SQLRowValues> ignoredInvoices, SQLRow insertedMessage) { |
super(); |
this.passedIDs = passedIDs; |
this.withDDWithoutMessage = Collections.unmodifiableList(withDDWithoutMessage); |
assert !ignoredInvoices.containsKey(null) && !ignoredInvoices.containsKey(IgnoreReason.NONE); |
this.ignoredInvoices = ListMap.unmodifiableMap(ignoredInvoices); |
this.insertedMessage = insertedMessage; |
this.invoiceCount = insertedMessage == null ? 0 : insertedMessage.getInt("NumberOfTransactions"); |
assert this.withDDWithoutMessage.size() - this.ignoredInvoices.allValues().size() == this.invoiceCount; |
} |
// OK since both the list and the SQLRowValues are immutable |
public final List<SQLRowValues> getDDInvoicesWithoutMessage() { |
return this.withDDWithoutMessage; |
} |
// OK since both the list and the SQLRowValues are immutable |
public final ListMapItf<IgnoreReason, SQLRowValues> getIgnoredInvoices() { |
return this.ignoredInvoices; |
} |
public final SQLRow getInsertedMessage() { |
return this.insertedMessage; |
} |
public final int getIncludedInvoicesCount() { |
return this.invoiceCount; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName() + ": of the " + this.passedIDs.size() + " passed, " + this.withDDWithoutMessage.size() + " needed a SDD message, of those " |
+ this.ignoredInvoices.allValues().size() + " were ignored (either being too far in the future or duplicate mandates) ; the inserted row was " + this.insertedMessage; |
} |
} |
public GenerationResult generateXML(Collection<? extends Number> invoiceIDs) throws SQLException { |
final Namespace painNS = Namespace.getNamespace("urn:iso:std:iso:20022:tech:xsd:pain.008.001.02"); |
final Element rootElem = new Element("Document", painNS); |
final Namespace xsiNS = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); |
rootElem.setAttribute("schemaLocation", "urn:iso:std:iso:20022:tech:xsd:pain.008.001.02 pain.008.001.02.xsd", xsiNS); |
final Document doc = new Document(rootElem); |
final Element ddElem = new Element("CstmrDrctDbtInitn", painNS); |
rootElem.addContent(ddElem); |
// Lead Time / Time cycle |
// https://www.ecb.europa.eu/paym/retpaym/undpaym/qa/html/index.en.html |
final Calendar now = Calendar.getInstance(); |
final Calendar cal = (Calendar) now.clone(); |
TimeUtils.clearTime(cal); |
// perhaps handle business days and difference between FRST/OOFF (5 days) and RCURR/FNAL (2 |
// days). |
cal.add(Calendar.DAY_OF_YEAR, this.dbPrefs.getInt(getCode() + ".leadDays", 7)); |
final Date lowerBound = cal.getTime(); |
cal.setTime(now.getTime()); |
cal.add(Calendar.DAY_OF_YEAR, 30); |
final Date upperBound = cal.getTime(); |
// TODO use createFetcher() |
final SQLRowValuesListFetcher selSociété = SQLRowValuesListFetcher.create(this.getDirectory().getElement(this.rowSociété.getTable()).createGraph()); |
selSociété.setFullOnly(true); |
selSociété.appendSelTransf(new ITransformer<SQLSelect, SQLSelect>() { |
@Override |
public SQLSelect transformChecked(SQLSelect sel) { |
sel.setLockStrength(LockStrength.SHARE); |
return sel; |
} |
}); |
final SQLTable invoiceT = getDirectory().getElement(SaisieVenteFactureSQLElement.class).getTable(); |
final SQLField invoiceSDDMessageF = invoiceT.getField(SaisieVenteFactureSQLElement.MESSAGE_FIELD_NAME); |
return SQLUtils.executeAtomic(getTable().getDBSystemRoot().getDataSource(), new ConnectionHandlerNoSetup<GenerationResult, SQLException>() { |
@Override |
public GenerationResult handle(SQLDataSource ds) throws SQLException { |
final SQLRowValues lockedSociété = selSociété.fetchOne(SDDMessageSQLElement.this.rowSociété.getIDNumber()); |
if (lockedSociété == null) |
throw new IllegalStateException("Missing société " + SDDMessageSQLElement.this.rowSociété); |
// find and lock invoices with TYPE_REGLEMENT direct debit and no message |
final SQLRowValues invoiceVals = new SQLRowValues(invoiceT); |
invoiceVals.putRowValues("ID_CLIENT").putNulls("NOM", "BIC", "IBAN"); |
invoiceVals.putRowValues("ID_MODE_REGLEMENT").putNulls("AJOURS", "LENJOUR").putRowValues("ID_SEPA_MANDATE").setAllToNull(); |
invoiceVals.putNulls("NET_A_PAYER", "DATE", "NUMERO"); |
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(invoiceVals); |
fetcher.setReturnedRowsUnmodifiable(true); |
// required for locking rows and to make sure that there's a SEPA Mandate |
fetcher.setFullOnly(true); |
fetcher.appendSelTransf(new ITransformer<SQLSelect, SQLSelect>() { |
@Override |
public SQLSelect transformChecked(SQLSelect sel) { |
// we will update FACTURE.ID_MESSAGE |
sel.setLockStrength(LockStrength.UPDATE); |
final SQLSelectJoin join = sel.getJoin(invoiceT.getField("ID_MODE_REGLEMENT")); |
join.setWhere(new Where(join.getJoinedTable().getField("ID_TYPE_REGLEMENT"), "=", TypeReglementSQLElement.PRELEVEMENT)); |
return sel; |
} |
}); |
final List<SQLRowValues> ddInvoices = fetcher |
.fetch(new Where(invoiceT.getKey(), invoiceIDs).and(new Where(invoiceSDDMessageF, "=", invoiceSDDMessageF.getForeignTable().getUndefinedIDNumber()))); |
final InvoicesByPaymentInfo map = new InvoicesByPaymentInfo(lowerBound, upperBound, new ElementCreator(painNS, SDDMessageSQLElement.this.fieldTranslator)); |
final ListMap<IgnoreReason, SQLRowValues> ignoredInvoices = new ListMap<>(); |
for (final SQLRowValues invoice : ddInvoices) { |
final IgnoreReason ignoredReason = map.addInvoice(invoice); |
if (ignoredReason != IgnoreReason.NONE) { |
ignoredInvoices.add(ignoredReason, invoice); |
} |
} |
final SQLRow newMsg; |
final int txCount = map.getTransactionCount(); |
if (txCount == 0) { |
newMsg = null; |
} else { |
// find and lock message serial |
final SQLTable mdT = getTable().getTable(SQLSchema.METADATA_TABLENAME); |
final SQLSelect sel = new SQLSelect(true).addSelect(mdT.getField("VALUE")); |
sel.setWhere(new Where(mdT.getField("NAME"), "=", SERIAL_MD)); |
sel.setLockStrength(LockStrength.UPDATE); |
final String msgSerial = String.valueOf(Integer.parseInt((String) getTable().getDBSystemRoot().getDataSource().executeScalar(sel.asString())) + 1); |
// generate XML |
final BigDecimal totalSum = map.sum; |
final Element groupHeaderElem = createGroupHeader(painNS, lockedSociété, now, msgSerial, txCount, totalSum); |
ddElem.addContent(groupHeaderElem); |
final String msgID = groupHeaderElem.getChild("MsgId", painNS).getText(); |
final Map<SQLRow, String> end2endIDs = new HashMap<>(); |
int index = 1; |
for (final PaymentInfo info : map.getPaymentInfos()) { |
try { |
createPaymentInfo(ddElem, end2endIDs, map.elemCreator, lockedSociété, info, msgID, index++); |
} catch (Exception e) { |
throw new IllegalStateException("Couldn't create XML for " + info, e); |
} |
} |
assert end2endIDs.size() == txCount : "Expected " + txCount + " transactions but got " + end2endIDs.size() + " rows : " + end2endIDs; |
// insert message in DB |
final SQLRowValues msgVals = new SQLRowValues(getTable()); |
msgVals.put("MessageIdentification", msgID); |
msgVals.put("CreationDateTime", now.getTime()); |
msgVals.put("NumberOfTransactions", txCount); |
msgVals.put("ControlSum", totalSum); |
msgVals.put("XML", JDOM2Utils.output(doc)); |
newMsg = msgVals.insert(); |
// update invoices with new message |
for (final Entry<SQLRow, String> e : end2endIDs.entrySet()) { |
final SQLRowValues vals = e.getKey().createEmptyUpdateRow(); |
vals.putForeignID(invoiceSDDMessageF.getName(), newMsg); |
vals.put(SaisieVenteFactureSQLElement.END2END_FIELD_NAME, e.getValue()); |
vals.update(); |
} |
// update message serial |
getTable().getDBRoot().setMetadata(SERIAL_MD, msgSerial); |
} |
return new GenerationResult(invoiceIDs, ddInvoices, ignoredInvoices, newMsg); |
} |
}); |
} |
static private Element createGroupHeader(final Namespace painNS, final SQLRowValues lockedSociété, final Calendar now, final String msgSerial, final int txCount, final BigDecimal total) { |
final Element res = new Element("GrpHdr", painNS); |
res.addContent(new Element("MsgId", painNS).setText("openconcerto-" + now.get(Calendar.YEAR) + "-" + msgSerial)); |
res.addContent(new Element("CreDtTm", painNS).setText(new XMLDateFormat().format(now))); |
res.addContent(new Element("NbOfTxs", painNS).setText(String.valueOf(txCount))); |
if (DecimalUtils.decimalDigits(total) > 2) |
throw new IllegalArgumentException("Too many decimals : " + total); |
res.addContent(new Element("CtrlSum", painNS).setText(total.toPlainString())); |
res.addContent(new Element("InitgPty", painNS).addContent(new Element("Nm", painNS).setText(getCompanyName(lockedSociété)))); |
return res; |
} |
static private String getCompanyName(final SQLRowValues lockedSociété) { |
final String companyName = lockedSociété.getString("NOM"); |
if (StringUtils.isEmpty(companyName)) |
throw new IllegalStateException("Empty company name : " + lockedSociété); |
return lockedSociété.getString("TYPE") + ' ' + companyName; |
} |
static private final DateFormat XML_DATE_FMT = new SimpleDateFormat("yyyy-MM-dd"); |
static synchronized private final String formatDate(final Date date) { |
return XML_DATE_FMT.format(date); |
} |
static private void createPaymentInfo(Element ddElem, Map<SQLRow, String> end2endIDs, final ElementCreator elemCreator, final SQLRowValues lockedSociété, final PaymentInfo info, |
final String msgID, final int index) throws SQLException, MissingInfoException { |
if (info.invoices.isEmpty()) |
return; |
final Namespace painNS = elemCreator.painNS; |
final String formattedDate = formatDate(info.collectionDate); |
final Element res = new Element("PmtInf", painNS); |
res.addContent(new Element("PmtInfId", painNS).setText("openconcerto-" + formattedDate + '.' + index)); |
res.addContent(new Element("PmtMtd", painNS).setText("DD")); |
res.addContent(new Element("BtchBookg", painNS).setText("false")); |
res.addContent(new Element("NbOfTxs", painNS).setText(String.valueOf(info.invoices.size()))); |
if (DecimalUtils.decimalDigits(info.sum) > 2) |
throw new IllegalArgumentException("Too many decimals : " + info.sum); |
res.addContent(new Element("CtrlSum", painNS).setText(info.sum.toPlainString())); |
final Element typeInformation = new Element("PmtTpInf", painNS); |
typeInformation.addContent(new Element("SvcLvl", painNS).addContent(new Element("Cd", painNS).setText("SEPA"))); |
typeInformation.addContent(new Element("LclInstrm", painNS).addContent(new Element("Cd", painNS).setText("CORE"))); |
typeInformation.addContent(new Element("SeqTp", painNS).setText(info.seqType)); |
res.addContent(typeInformation); |
res.addContent(new Element("ReqdColltnDt", painNS).setText(formattedDate)); |
final Element creditor = new Element("Cdtr", painNS); |
creditor.addContent(new Element("Nm", painNS).setText(getCompanyName(lockedSociété))); |
final Element postalAddr = new Element("PstlAdr", painNS); |
final SQLRowAccessor addr = lockedSociété.getNonEmptyForeign("ID_ADRESSE_COMMON"); |
final String country = addr.getString("PAYS"); |
final String country2; |
if (StringUtils.isEmpty(country, true) || country.trim().equalsIgnoreCase("France")) { |
country2 = "FR"; |
} else { |
// TODO map to 2 letter code |
throw new IllegalStateException("Unknown country : " + country); |
} |
postalAddr.addContent(new Element("Ctry", painNS).setText(country2)); |
postalAddr.addContent(new Element("AdrLine", painNS).setText(addr.getString("RUE"))); |
postalAddr.addContent(new Element("AdrLine", painNS).setText(addr.getString("CODE_POSTAL") + " " + addr.getString("VILLE"))); |
creditor.addContent(postalAddr); |
res.addContent(creditor); |
final Element creditorAccount = new Element("CdtrAcct", painNS); |
creditorAccount.addContent(new Element("Id", painNS).addContent(elemCreator.createWithNonEmptyText("IBAN", lockedSociété, "IBAN"))); |
res.addContent(creditorAccount); |
final Element creditorAgent = new Element("CdtrAgt", painNS); |
creditorAgent.addContent(new Element("FinInstnId", painNS).addContent(elemCreator.createWithNonEmptyText("BIC", lockedSociété, "BIC"))); |
res.addContent(creditorAgent); |
res.addContent(new Element("ChrgBr", painNS).setText("SLEV")); |
final Element creditorID = new Element("CdtrSchmeId", painNS); |
final Element other = new Element("Othr", painNS); |
other.addContent(elemCreator.createWithNonEmptyText("Id", lockedSociété, "SEPA_CREDITOR_ID")); |
other.addContent(new Element("SchmeNm", painNS).addContent(new Element("Prtry", painNS).setText("SEPA"))); |
creditorID.addContent(new Element("Id", painNS).addContent(new Element("PrvtId", painNS).addContent(other))); |
res.addContent(creditorID); |
for (final InvoiceElem invoice : info.invoices) { |
final String end2endID = msgID + '.' + invoice.get0().getString("NUMERO"); |
if (end2endIDs.put(invoice.get0().asRow(), end2endID) != null) |
throw new IllegalStateException("Duplicate invoice : " + invoice); |
try { |
res.addContent(fillDDTx(invoice, elemCreator, end2endID)); |
} catch (Exception e) { |
throw new IllegalStateException("Couldn't create XML for " + invoice, e); |
} |
} |
ddElem.addContent(res); |
} |
static private Element fillDDTx(final InvoiceElem invoiceElem, final ElementCreator elemCreator, final String end2endID) throws SQLException, MissingInfoException { |
final Element paymentId = new Element("PmtId", elemCreator.painNS); |
paymentId.addContent(elemCreator.createWithNonEmptyText("InstrId", end2endID)); |
paymentId.addContent(elemCreator.createWithNonEmptyText("EndToEndId", end2endID)); |
invoiceElem.get1().addContent(0, paymentId); |
// update mandate fields |
final SQLRowAccessor mandate = invoiceElem.get0().getForeign("ID_MODE_REGLEMENT").getForeign("ID_SEPA_MANDATE"); |
final String seqType = mandate.getString("SequenceType"); |
if (seqType.equals(SEPAMandateSQLElement.SEQ_FIRST)) { |
mandate.createEmptyUpdateRow().put("SequenceType", SEPAMandateSQLElement.SEQ_RECURRENT).update(); |
} else if (seqType.equals(SEPAMandateSQLElement.SEQ_FINAL) || seqType.equals(SEPAMandateSQLElement.SEQ_ONEOFF)) { |
mandate.createEmptyUpdateRow().put("ACTIVE", Boolean.FALSE).update(); |
} // else SEQ_RECURRENT |
return invoiceElem.get1(); |
} |
static private Element createDDTx(final ElementCreator elemCreator, final SQLRowValues invoice) throws MissingInfoException { |
final Namespace painNS = elemCreator.painNS; |
final Element res = new Element("DrctDbtTxInf", painNS); |
res.addContent(new Element("InstdAmt", painNS).setAttribute("Ccy", "EUR").setText(getInvoiceAmount(invoice).toPlainString())); |
final Element mandateRltdInfo = new Element("MndtRltdInf", painNS); |
final SQLRowAccessor mandate = invoice.getForeign("ID_MODE_REGLEMENT").getForeign("ID_SEPA_MANDATE"); |
assert !mandate.isUndefined() : "Undefined mandate returned by fetcher"; |
mandateRltdInfo.addContent(elemCreator.createWithNonEmptyText("MndtId", mandate, "MandateIdentification")); |
mandateRltdInfo.addContent(elemCreator.createWithNonEmptyText("DtOfSgntr", formatDate(mandate.getObjectAs("DateOfSignature", Date.class)))); |
mandateRltdInfo.addContent(elemCreator.createWithNonEmptyText("AmdmntInd", "false")); |
res.addContent(new Element("DrctDbtTx", painNS).addContent(mandateRltdInfo)); |
final SQLRowAccessor clientRow = invoice.getForeign("ID_CLIENT"); |
res.addContent(new Element("DbtrAgt", painNS).addContent(new Element("FinInstnId", painNS).addContent(elemCreator.createWithNonEmptyText("BIC", clientRow, "BIC")))); |
res.addContent(new Element("Dbtr", painNS).addContent(elemCreator.createWithNonEmptyText("Nm", clientRow, "NOM"))); |
res.addContent(new Element("DbtrAcct", painNS).addContent(new Element("Id", painNS).addContent(elemCreator.createWithNonEmptyText("IBAN", clientRow, "IBAN")))); |
res.addContent(new Element("Purp", painNS).addContent(new Element("Cd", painNS).setText("OTHR"))); |
// TODO <RmtInf><Ustrd>ligne de facture avec n° d'abonnement et indice de paiement. |
return res; |
} |
static public final class MissingInfoException extends Exception { |
private final String label; |
protected MissingInfoException(final String label) { |
super("Empty " + label); |
this.label = label; |
} |
public final String getLabel() { |
return this.label; |
} |
} |
static private final class ElementCreator { |
private final Namespace painNS; |
private final SQLFieldTranslator fieldTrans; |
protected ElementCreator(Namespace painNS, final SQLFieldTranslator fieldTrans) { |
super(); |
this.painNS = painNS; |
this.fieldTrans = fieldTrans; |
} |
protected Element create(final String elemName) { |
return new Element(elemName, this.painNS); |
} |
protected Element createWithNonEmptyText(final String elemName, final SQLRowAccessor r, final String field) throws MissingInfoException { |
return this.createWithNonEmptyText(elemName, r.getString(field), this.fieldTrans.getDescFor(r.getTable(), field).getLabel()); |
} |
protected Element createWithNonEmptyText(final String elemName, final String text) throws MissingInfoException { |
return this.createWithNonEmptyText(elemName, text, null); |
} |
protected Element createWithNonEmptyText(final String elemName, final String text, final String label) throws MissingInfoException { |
if (StringUtils.isEmpty(text)) |
throw new MissingInfoException(label == null ? elemName : label); |
return create(elemName).setText(text); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/element/SEPAMandateSQLElement.java |
---|
New file |
0,0 → 1,170 |
/* |
* 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.payment.element; |
import org.openconcerto.erp.config.ComptaPropsConfiguration; |
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement; |
import org.openconcerto.sql.element.SQLComponent; |
import org.openconcerto.sql.element.SQLElementLink.LinkType; |
import org.openconcerto.sql.element.SQLElementLinksSetup; |
import org.openconcerto.sql.element.UISQLComponent; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.utils.SQLCreateTable; |
import org.openconcerto.ui.component.ITextCombo; |
import org.openconcerto.ui.component.ImmutableITextComboCache; |
import org.openconcerto.utils.CollectionUtils; |
import java.nio.ByteBuffer; |
import java.util.ArrayList; |
import java.util.Arrays; |
import java.util.Base64; |
import java.util.Date; |
import java.util.List; |
import java.util.Objects; |
import java.util.Set; |
import java.util.UUID; |
public final class SEPAMandateSQLElement extends ComptaSQLConfElement { |
static final String TABLE_NAME = "SEPA_MANDATE"; |
static public final String SEQ_FIRST = "FRST"; |
static public final String SEQ_RECURRENT = "RCUR"; |
static public final String SEQ_FINAL = "FNAL"; |
static public final String SEQ_ONEOFF = "OOFF"; |
static public final List<String> SEQ_VALUES = Arrays.asList(SEQ_FIRST, SEQ_RECURRENT, SEQ_FINAL, SEQ_ONEOFF); |
private static final int IDENTIFICATION_MAX_LENGTH = 35; |
public static SQLCreateTable getCreateTable(final DBRoot root) { |
if (root.contains(TABLE_NAME)) |
return null; |
final SQLCreateTable res = new SQLCreateTable(root, TABLE_NAME); |
res.addForeignColumn(null, root.getTable("CLIENT")); |
res.addVarCharColumn("MandateIdentification", IDENTIFICATION_MAX_LENGTH); |
res.addColumn("DateOfSignature", "date", null, true); |
res.addVarCharColumn("SequenceType", 8); |
res.addBooleanColumn("ACTIVE", Boolean.TRUE, false); |
return res; |
} |
public SEPAMandateSQLElement(final ComptaPropsConfiguration conf) { |
super(conf.getRootSociete().findTable(TABLE_NAME, true)); |
} |
@Override |
protected void setupLinks(SQLElementLinksSetup links) { |
super.setupLinks(links); |
links.get("ID_CLIENT").setType(LinkType.PARENT); |
} |
@Override |
protected List<String> getListFields() { |
final List<String> l = new ArrayList<String>(); |
l.add("ID_CLIENT"); |
l.add("MandateIdentification"); |
l.add("DateOfSignature"); |
l.add("SequenceType"); |
l.add("ACTIVE"); |
return l; |
} |
@Override |
protected List<String> getComboFields() { |
final List<String> l = new ArrayList<String>(); |
l.add("MandateIdentification"); |
l.add("DateOfSignature"); |
l.add("SequenceType"); |
return l; |
} |
@Override |
public Set<String> getReadOnlyFields() { |
return CollectionUtils.createSet("ID_CLIENT", "MandateIdentification"); |
} |
@Override |
protected SQLComponent createComponent() { |
return new UISQLComponent(this) { |
@Override |
protected void addViews() { |
this.addView("ID_CLIENT"); |
this.addView("MandateIdentification"); |
this.addView("DateOfSignature"); |
final ITextCombo seqTypeCombo = new ITextCombo(true); |
seqTypeCombo.initCache(new ImmutableITextComboCache(SEQ_VALUES)); |
this.addView(seqTypeCombo, "SequenceType"); |
this.addView("ACTIVE"); |
} |
}; |
} |
@Override |
protected String createCode() { |
// TODO rename createCodeFromPackage() to createCodeOfPackage() and change createCode() |
// implementation to use a new createCodeFromPackage() which uses the class name (w/o |
// SQLElement suffix) |
return this.createCodeFromPackage() + ".SEPAMandate"; |
} |
public final SQLRowValues createRecurrent(final Number idClient, final String mandateIdent, final Date dateOfSignature) { |
final SQLRowValues res = new SQLRowValues(getTable()); |
res.put("ID_CLIENT", Objects.requireNonNull(idClient)); |
if (mandateIdent.length() > IDENTIFICATION_MAX_LENGTH) |
throw new IllegalArgumentException("Identification too long (>" + IDENTIFICATION_MAX_LENGTH + ") : " + mandateIdent); |
res.put("MandateIdentification", mandateIdent); |
res.put("DateOfSignature", Objects.requireNonNull(dateOfSignature)); |
res.put("SequenceType", SEPAMandateSQLElement.SEQ_FIRST); |
res.put("ACTIVE", Boolean.TRUE); |
return res; |
} |
public String generateMandateIdentification(String label, final char pad, final boolean padStart, final boolean truncateStart) { |
final UUID uuid = UUID.randomUUID(); |
final ByteBuffer byteBuffer = ByteBuffer.allocate(16); |
byteBuffer.putLong(uuid.getMostSignificantBits()); |
byteBuffer.putLong(uuid.getLeastSignificantBits()); |
// slash should be legal but don't take any chances |
final String uuidS = Base64.getEncoder().withoutPadding().encodeToString(byteBuffer.array()).replace('/', '.'); |
assert uuidS.length() == 22; |
// don't add space |
if (Character.isSpaceChar(pad)) |
throw new IllegalArgumentException("Invalid pad : spaces can be hard to debug : '" + pad + "'"); |
// don't accept space |
label = label.trim(); |
final int numberL = 10; |
final int zeroesToAdd = numberL - label.length(); |
final String fixedLNumber; |
if (zeroesToAdd == 0) { |
fixedLNumber = label; |
} else if (zeroesToAdd > 0) { |
final StringBuilder sb = new StringBuilder(numberL); |
if (!padStart) |
sb.append(label); |
for (int i = 0; i < zeroesToAdd; i++) { |
sb.append(pad); |
} |
if (padStart) |
sb.append(label); |
fixedLNumber = sb.toString(); |
} else { |
fixedLNumber = truncateStart ? label.substring(-zeroesToAdd, label.length()) : label.substring(0, numberL); |
} |
assert fixedLNumber.length() == numberL; |
// use both UUID and a meaningful label |
final String res = uuidS + '-' + fixedLNumber; |
assert res.length() <= IDENTIFICATION_MAX_LENGTH; |
return res; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/element/TypeReglementSQLElement.java |
---|
39,6 → 39,7 |
public static final int INDEFINI = 7; |
public static final int VIREMENT = 8; |
public static final int CESU = 9; |
public static final int PRELEVEMENT = 10; |
public TypeReglementSQLElement() { |
super("TYPE_REGLEMENT", "Type de règlement", "Type de règlement"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/action/ListeDesRelancesAction.java |
---|
80,7 → 80,7 |
final SQLTableModelSourceOnline src = (SQLTableModelSourceOnline) this.frame.getPanel().getListe().getModel().getReq(); |
this.frame.getPanel().getListe().setSQLEditable(true); |
this.frame.getPanel().getListe().setModificationAllowed(true); |
for (SQLTableModelColumn column : src.getColumns()) { |
if (column.getClass().isAssignableFrom(SQLTableModelColumnPath.class)) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/action/ListeDesChequesAction.java |
---|
60,7 → 60,7 |
} |
} |
}); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
frame.getPanel().setAddVisible(false); |
return frame; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/action/ListeDesTraitesAbstractAction.java |
---|
54,7 → 54,7 |
IListFrame frame = new IListFrame(new ListeViewPanel(elt, new IListe(src))); |
frame.getPanel().setAddVisible(false); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
return frame; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/ui/ChequeListPanel.java |
---|
13,6 → 13,7 |
package org.openconcerto.erp.core.finance.payment.ui; |
import org.openconcerto.erp.core.common.element.BanqueSQLElement; |
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement; |
import org.openconcerto.erp.core.finance.payment.element.ChequeType; |
import org.openconcerto.erp.model.GestionChequesModel; |
57,7 → 58,7 |
super(elem, new IListe(((ChequeType) elem).createDepositTableSource())); |
this.setReadWriteButtonsVisible(false); |
this.getListe().setSQLEditable(false); |
this.getListe().setModificationAllowed(false); |
// Model |
this.model = new GestionChequesModel(getListe(), (ChequeType) elem); |
100,7 → 101,7 |
c.gridx++; |
res.add(new JLabel(", sur la banque"), c); |
c.gridx++; |
banqueSelect.uiInit(element.getDirectory().getElement("BANQUE").getComboRequest()); |
banqueSelect.uiInit(element.getDirectory().getElement(BanqueSQLElement.class).getComboRequest()); |
res.add(banqueSelect, c); |
} else { |
banqueSelect = null; |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/component/EncaisserMontantSQLComponent.java |
---|
41,6 → 41,7 |
import org.openconcerto.ui.warning.JLabelWarning; |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.GestionDevise; |
import org.openconcerto.utils.StringUtils; |
import org.openconcerto.utils.text.SimpleDocumentListener; |
import java.awt.GridBagConstraints; |
308,11 → 309,11 |
String s = row.getString("NOM"); |
SQLRow rowModeRegl = row.getForeignRow("ID_MODE_REGLEMENT"); |
SQLRow rowTypeRegl = rowModeRegl.getForeignRow("ID_TYPE_REGLEMENT"); |
String label = "Règlement vente " + ((s == null) ? "" : s) + " (" + rowTypeRegl.getString("NOM") + ")"; |
// Compte Client |
SQLRow clientRow = row.getForeignRow("ID_CLIENT"); |
String label = "Règlement vente " + ((s == null) ? "" : s) + " (" + rowTypeRegl.getString("NOM") + ") " + StringUtils.limitLength(clientRow.getString("NOM"), 20); |
long montant = row.getLong("MONTANT"); |
PrixTTC ttc = new PrixTTC(montant); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/element/ContratSalarieSQLElement.java |
---|
377,12 → 377,12 |
addSQLObject(textDateFin, "DATE_PREV_FIN"); |
this.addRequiredSQLObject(selCodeCatSocio, "ID_CODE_EMPLOI"); |
this.addSQLObject(selContratTravail, "ID_CODE_CONTRAT_TRAVAIL"); |
this.addSQLObject(selCaractActivite, "ID_CODE_CARACT_ACTIVITE"); |
this.addSQLObject(selDroitContrat, "ID_CODE_DROIT_CONTRAT"); |
this.addSQLObject(selStatutProf, "ID_CODE_STATUT_PROF"); |
this.addSQLObject(selStatutCat, "ID_CODE_STATUT_CATEGORIEL"); |
this.addSQLObject(selStatutCatConv, "ID_CODE_STATUT_CAT_CONV"); |
this.addRequiredSQLObject(selContratTravail, "ID_CODE_CONTRAT_TRAVAIL"); |
this.addRequiredSQLObject(selCaractActivite, "ID_CODE_CARACT_ACTIVITE"); |
this.addRequiredSQLObject(selDroitContrat, "ID_CODE_DROIT_CONTRAT"); |
this.addRequiredSQLObject(selStatutProf, "ID_CODE_STATUT_PROF"); |
this.addRequiredSQLObject(selStatutCat, "ID_CODE_STATUT_CATEGORIEL"); |
this.addRequiredSQLObject(selStatutCatConv, "ID_CODE_STATUT_CAT_CONV"); |
this.addRequiredSQLObject(textNature, "NATURE"); |
} |
}; |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/element/FichePayeSQLElement.java |
---|
16,10 → 16,14 |
import org.openconcerto.erp.config.ComptaPropsConfiguration; |
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement; |
import org.openconcerto.erp.core.common.ui.JNiceButton; |
import org.openconcerto.erp.core.common.ui.PanelFrame; |
import org.openconcerto.erp.core.humanresources.payroll.component.VariableRowTreeNode; |
import org.openconcerto.erp.core.humanresources.payroll.report.FichePayeSheetXML; |
import org.openconcerto.erp.core.humanresources.payroll.ui.FichePayeRenderer; |
import org.openconcerto.erp.core.humanresources.payroll.ui.PanelCumulsPaye; |
import org.openconcerto.erp.generationEcritures.GenerationMvtFichePaye; |
import org.openconcerto.erp.model.FichePayeModel; |
import org.openconcerto.erp.model.MouseSheetXmlListeListener; |
import org.openconcerto.erp.model.RubriquePayeTree; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.element.BaseSQLComponent; |
40,6 → 44,9 |
import org.openconcerto.sql.sqlobject.ElementComboBox; |
import org.openconcerto.sql.view.EditFrame; |
import org.openconcerto.sql.view.IListFrame; |
import org.openconcerto.sql.view.list.IListe; |
import org.openconcerto.sql.view.list.IListeAction.IListeEvent; |
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.JDate; |
import org.openconcerto.ui.component.ITextArea; |
79,8 → 86,25 |
public FichePayeSQLElement() { |
super("FICHE_PAYE", "une fiche de paye", "fiches de paye"); |
MouseSheetXmlListeListener l = new MouseSheetXmlListeListener(FichePayeSheetXML.class); |
getRowActions().addAll(l.getRowActions()); |
PredicateRowAction actionCumuls = new PredicateRowAction(new AbstractAction("Détails cumuls et variables") { |
@Override |
public void actionPerformed(ActionEvent e) { |
final PanelCumulsPaye pCumuls = new PanelCumulsPaye(); |
final PanelFrame p = new PanelFrame(pCumuls, "Détails cumuls et variables"); |
pCumuls.selectFiche(IListe.get(e).getSelectedRow().asRow()); |
p.setVisible(true); |
} |
}, true); |
actionCumuls.setPredicate(IListeEvent.getSingleSelectionPredicate()); |
getRowActions().add(actionCumuls); |
} |
protected List<String> getListFields() { |
final List<String> l = new ArrayList<String>(); |
l.add("ID_SALARIE"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/element/InfosSalariePayeSQLElement.java |
---|
428,7 → 428,7 |
c.gridx++; |
c.weightx = 1; |
panelBase.add(CodeAT, c); |
addView(CodeAT, "CODE_AT"); |
addView(CodeAT, "CODE_AT", REQ); |
// Code section AT |
JLabel labelSectionAT = new JLabel(getLabelFor("CODE_SECTION_AT")); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/element/RubriqueCommSQLElement.java |
---|
241,6 → 241,16 |
cPanel.weightx = 1; |
panelProp.add(comboSelTypeImpression, cPanel); |
// Impression |
JCheckBox boxReduction = new JCheckBox("Avantage baisse des cotisations"); |
cPanel.gridy++; |
cPanel.gridx = 1; |
cPanel.gridwidth = 2; |
cPanel.weightx = 0; |
addView(boxReduction, "REDUCTION_GVT_COM"); |
panelProp.add(boxReduction, cPanel); |
cPanel.gridwidth = 1; |
// Tabbed Pane |
JTabbedPane tab = new JTabbedPane(); |
tab.add("Calcul", new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, paneTree, panelCalcul)); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/action/ListeDesFichesDePayeAction.java |
---|
62,7 → 62,7 |
final IListFrame frame = new IListFrame(liste); |
frame.getPanel().getListe().setSQLEditable(false); |
frame.getPanel().getListe().setModificationAllowed(false); |
frame.getPanel().setAddVisible(false); |
final PanelCumulsPaye pCumuls = new PanelCumulsPaye(); |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/action/ListeDesVariablesPayes.java |
---|
45,7 → 45,7 |
} |
} |
}; |
listeVar.getListe().setSQLEditable(false); |
listeVar.getListe().setModificationAllowed(false); |
return new IListFrame(listeVar); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/ui/HistoriqueFichePayePanel.java |
---|
76,7 → 76,7 |
w = w.and(new Where(table.getField("ID_" + HistoriqueFichePayePanel.this.jListPanel.getModel().getTable().getName()), "=", id)); |
} |
HistoriqueFichePayePanel.this.listePanel.getListe().getRequest().setWhere(w); |
HistoriqueFichePayePanel.this.listePanel.getListe().setSQLEditable(false); |
HistoriqueFichePayePanel.this.listePanel.getListe().setModificationAllowed(false); |
} |
}; |
107,7 → 107,7 |
this.listePanel = new ListeFichePayeAddPanel(eltFiche, new IListe(src)); |
this.listePanel.setAddVisible(false); |
this.listePanel.getListe().setSQLEditable(false); |
this.listePanel.getListe().setModificationAllowed(false); |
this.listePanel.setOpaque(false); |
this.listePanel.setBorder(null); |
139,50 → 139,6 |
} |
}); |
final PanelCumulsPaye pCumuls = new PanelCumulsPaye(); |
final PanelFrame p = new PanelFrame(pCumuls, "Détails cumuls et variables"); |
this.listePanel.getListe().addIListener(new IListener() { |
public void selectionId(int id, int field) { |
pCumuls.selectFicheFromId(id); |
} |
}); |
// Menu Clic droit Génération documents |
this.listener = new MouseAdapter() { |
public void mousePressed(MouseEvent mouseEvent) { |
if (mouseEvent.getButton() == MouseEvent.BUTTON3 && HistoriqueFichePayePanel.this.listePanel.getListe().getSelectedId() > 1) { |
JPopupMenu menuDroit = new JPopupMenu(); |
final SQLRow rowFiche = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getTable("FICHE_PAYE") |
.getRow(HistoriqueFichePayePanel.this.listePanel.getListe().getSelectedId()); |
MouseSheetXmlListeListener l = new MouseSheetXmlListeListener(FichePayeSheetXML.class); |
for (RowAction action : l.getRowActions()) { |
menuDroit.add(action.getAction()); |
} |
menuDroit.add(new AbstractAction("Détails cumuls et variables") { |
public void actionPerformed(ActionEvent e) { |
pCumuls.selectFiche(rowFiche); |
p.setVisible(true); |
} |
}); |
menuDroit.pack(); |
menuDroit.show(mouseEvent.getComponent(), mouseEvent.getPoint().x, mouseEvent.getPoint().y); |
menuDroit.setVisible(true); |
} |
} |
}; |
this.listePanel.getListe().getJTable().addMouseListener(this.listener); |
this.jListPanel.addListSelectionListener(this.listListener); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/ui/ListeDesRubriquesPanel.java |
---|
41,7 → 41,7 |
private void addPane(final JTabbedPane tabbedPane, final String tableName, final String title) { |
final ListeAddPanel listeBrut = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement(tableName)); |
listeBrut.getListe().setSQLEditable(false); |
listeBrut.getListe().setModificationAllowed(false); |
tabbedPane.add(title, listeBrut); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/action/ListeDesSalariesAction.java |
---|
31,7 → 31,7 |
public JFrame createFrame() { |
ListeAddPanel listeSal = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("SALARIE")); |
listeSal.getListe().setSQLEditable(false); |
listeSal.getListe().setModificationAllowed(false); |
return new IListFrame(listeSal); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/action/ListeDesAyantsDroitsAction.java |
---|
30,7 → 30,7 |
public JFrame createFrame() { |
ListeAddPanel listeSal = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("AYANT_DROIT")); |
listeSal.getListe().setSQLEditable(false); |
listeSal.getListe().setModificationAllowed(false); |
return new IListFrame(listeSal); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/action/ListeDesContratsPrevoyanceAction.java |
---|
30,7 → 30,7 |
public JFrame createFrame() { |
ListeAddPanel listeSal = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("CONTRAT_PREVOYANCE")); |
listeSal.getListe().setSQLEditable(false); |
listeSal.getListe().setModificationAllowed(false); |
return new IListFrame(listeSal); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/action/ListeDesSecretairesAction.java |
---|
31,7 → 31,7 |
public JFrame createFrame() { |
ListeAddPanel listeSecr = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("SECRETAIRE")); |
listeSecr.getListe().setSQLEditable(false); |
listeSecr.getListe().setModificationAllowed(false); |
return new IListFrame(listeSecr); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/employe/action/ListeDesCaissesCotisationsAction.java |
---|
30,7 → 30,7 |
public JFrame createFrame() { |
ListeAddPanel listeSal = new ListeAddPanel(Configuration.getInstance().getDirectory().getElement("CAISSE_COTISATION")); |
listeSal.getListe().setSQLEditable(false); |
listeSal.getListe().setModificationAllowed(false); |
return new IListFrame(listeSal); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/ftp/updater/UpdateManager.java |
---|
284,7 → 284,8 |
} |
String jHome = System.getProperty("java.home"); |
jHome += File.separatorChar + "bin" + File.separatorChar + "java"; |
Runtime.getRuntime().exec("\"" + jHome + "\" -jar " + updaterFilename); |
ProcessBuilder process = new ProcessBuilder(jHome, "-jar", updaterFilename); |
process.start(); |
JOptionPane.showMessageDialog(null, "Mise à jour terminée"); |
System.exit(0); |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/fleche_d_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/fleche_d_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/fleche_g_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/fleche_g_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/PrefTree.java |
---|
13,6 → 13,7 |
package org.openconcerto.ui.preferences; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.ui.clipboard.ClipboardItems; |
import java.awt.Color; |
72,10 → 73,15 |
c.gridx++; |
c.weightx = 0; |
this.button = new JButton(new ImageIcon(PrefTree.class.getResource("clear.png"))); |
String iconNameClear = "clear.png"; |
if (textComponent.getFont().getSize() > 16) { |
iconNameClear = "clear_2x.png"; |
} |
final ImageIcon icon = new ImageIcon(PrefTree.class.getResource(iconNameClear)); |
this.button = new JButton(icon); |
this.button.setDisabledIcon(new ImageIcon(PrefTree.class.getResource("blank.png"))); |
this.button.setPreferredSize(new Dimension(20, 20)); |
this.button.setMinimumSize(new Dimension(20, 20)); |
this.button.setPreferredSize(new Dimension(icon.getIconWidth() + 4, icon.getIconHeight() + 4)); |
this.button.setMinimumSize(new Dimension(icon.getIconWidth() + 4, icon.getIconHeight() + 4)); |
this.button.setEnabled(false); |
this.button.setBorderPainted(false); |
this.button.setFocusPainted(false); |
96,6 → 102,8 |
c.fill = GridBagConstraints.BOTH; |
this.tree = new JTree(this.root); |
// HighDPI |
this.tree.setRowHeight(FontUtils.getPreferredRowHeight(tree)); |
// Set the renderer |
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer() { |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/MainPrefPanel.java |
---|
38,6 → 38,7 |
import javax.swing.JPanel; |
import javax.swing.JSeparator; |
import javax.swing.SwingUtilities; |
import javax.swing.UIManager; |
import javax.swing.event.TreeSelectionEvent; |
import javax.swing.event.TreeSelectionListener; |
55,7 → 56,7 |
} |
}; |
private JLabel titleLabel; |
private final Vector<PrefTreeNode> history = new Vector<PrefTreeNode>(); |
private final Vector<PrefTreeNode> history = new Vector<>(); |
private JButton buttonLeft; |
private JButton buttonRight; |
private PrefTree tree; |
155,7 → 156,7 |
c.fill = GridBagConstraints.HORIZONTAL; |
c.weightx = 1; |
this.titleLabel = new JLabel(TM.tr("prefs.main")); |
Font fontTitre = new Font("Arial Gras", Font.PLAIN, 12); |
Font fontTitre = titleLabel.getFont().deriveFont(Font.BOLD); |
this.titleLabel.setFont(fontTitre); |
p.add(this.titleLabel, c); |
165,7 → 166,14 |
c.weightx = 0; |
c.gridx += 2; |
c.gridwidth = 1; |
this.buttonLeft = new JButton(new ImageIcon(MainPrefPanel.class.getResource("fleche_g.png"))); |
String leftIconName = "fleche_g.png"; |
String rightIconName = "fleche_d.png"; |
if (titleLabel.getFont().getSize() > 16) { |
leftIconName = "fleche_g_2x.png"; |
rightIconName = "fleche_d_2x.png"; |
} |
this.buttonLeft = new JButton(new ImageIcon(MainPrefPanel.class.getResource(leftIconName))); |
this.buttonLeft.setBorderPainted(false); |
this.buttonLeft.setFocusPainted(false); |
this.buttonLeft.setContentAreaFilled(false); |
174,7 → 182,8 |
this.buttonLeft.setEnabled(false); |
p.add(this.buttonLeft, c); |
c.gridx++; |
this.buttonRight = new JButton(new ImageIcon(MainPrefPanel.class.getResource("fleche_d.png"))); |
this.buttonRight = new JButton(new ImageIcon(MainPrefPanel.class.getResource(rightIconName))); |
this.buttonRight.setBorderPainted(false); |
this.buttonRight.setFocusPainted(false); |
this.buttonRight.setContentAreaFilled(false); |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/PreferenceFrame.java |
---|
50,8 → 50,9 |
c.weighty = 1; |
PrefTree prefTree = new PrefTree(root); |
prefTree.setMinimumSize(new Dimension(250, 200)); |
prefTree.setPreferredSize(new Dimension(250, 200)); |
final int fontSize = prefTree.getFont().getSize(); |
prefTree.setMinimumSize(new Dimension(fontSize * 23, fontSize * 18)); |
prefTree.setPreferredSize(new Dimension(fontSize * 23, fontSize * 18)); |
this.getContentPane().add(prefTree, c); |
c.gridx++; |
85,8 → 86,8 |
this.getContentPane().add(p1, c); |
this.setBackground(p1.getBackground()); |
this.getContentPane().setBackground(p1.getBackground()); |
this.setMinimumSize(new Dimension(880, 680)); |
this.setPreferredSize(new Dimension(880, 680)); |
this.setMinimumSize(new Dimension(fontSize * 80, fontSize * 62)); |
this.setPreferredSize(new Dimension(fontSize * 80, fontSize * 62)); |
prefTree.addTreeSelectionListener(this.mainPrefPanel); |
buttonClose.addActionListener(new ActionListener() { |
public void actionPerformed(ActionEvent e) { |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/clear_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/clear_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/ui/light/ColumnsSpec.java |
---|
45,6 → 45,7 |
private Boolean allowMove = false; |
private Boolean allowResize = false; |
// ATTENTION : il y a des setters public pour la serialization JSON |
public ColumnsSpec() { |
// Serialization |
} |
81,10 → 82,22 |
return this.id; |
} |
public void setId(String id) { |
this.id = id; |
} |
public void setPossibleColumnIds(List<String> possibleColumnIds) { |
this.possibleColumnIds = possibleColumnIds; |
} |
public final List<String> getPossibleColumnIds() { |
return this.possibleColumnIds; |
} |
public void setSortedIds(List<String> sortedIds) { |
this.sortedIds = sortedIds; |
} |
public final List<String> getSortedIds() { |
return this.sortedIds; |
} |
94,6 → 107,10 |
} |
public void setFixedColumns(int fixedColumns) { |
this.fixedColumns = fixedColumns; |
} |
public final int getColumnCount() { |
return this.columns.size(); |
139,6 → 156,14 |
return result; |
} |
public void setColumns(List<ColumnSpec> columns) { |
this.columns = columns; |
} |
public List<ColumnSpec> getColumns() { |
return columns; |
} |
public final boolean setUserPrefs(final Document columnsPrefs) { |
if (columnsPrefs != null) { |
// user preferences application |
163,22 → 188,23 |
if (!xmlColumn.getName().equals("column")) { |
throw new IllegalArgumentException("ColumnSpec setPrefs - Invalid xml, element node column expected but " + xmlColumn.getName() + " found"); |
} |
if (xmlColumn.getAttribute("width") == null || xmlColumn.getAttribute("min-width") == null || xmlColumn.getAttribute("max-width") == null) { |
throw new IllegalArgumentException("ColumnSpec setPrefs - Invalid column node for " + columnId + ", it must have attribute width, min-width, max-width"); |
if (xmlColumn.getAttribute("width") == null) { |
throw new IllegalArgumentException("ColumnSpec setPrefs - Invalid column node for " + columnId + " : missing width"); |
} |
final double width = Double.parseDouble(xmlColumn.getAttribute("width").getValue()); |
final double maxWidth = Double.parseDouble(xmlColumn.getAttribute("max-width").getValue()); |
final double minWidth = Double.parseDouble(xmlColumn.getAttribute("min-width").getValue()); |
columnSpec.setPrefs(width, maxWidth, minWidth); |
if (width <= columnSpec.getMaxWidth() && width >= columnSpec.getMinWidth() && this.allowResize) { |
// Only apply valid width |
columnSpec.setWidth(width); |
} |
if (i != j) { |
if (this.allowMove) { |
final ColumnSpec swap = this.columns.get(i); |
this.columns.set(i, this.columns.get(j)); |
this.columns.set(j, swap); |
i--; |
} |
} |
find = true; |
break; |
} |
/trunk/OpenConcerto/src/org/openconcerto/ui/light/LightUIRadioButtons.java |
---|
60,6 → 60,10 |
this.choices.addAll(choices); |
} |
public List<String> getChoices() { |
return choices; |
} |
@Override |
public JSONObject toJSON() { |
final JSONObject json = super.toJSON(); |
/trunk/OpenConcerto/src/org/openconcerto/ui/TimestampEditorPanel.java |
---|
13,8 → 13,6 |
package org.openconcerto.ui; |
import org.openconcerto.ui.table.TimestampTableCellEditor; |
import java.awt.Color; |
import java.awt.Dimension; |
import java.awt.Font; |
29,6 → 27,7 |
import java.awt.event.KeyEvent; |
import java.beans.PropertyChangeEvent; |
import java.beans.PropertyChangeListener; |
import java.sql.Time; |
import java.sql.Timestamp; |
import java.util.ArrayList; |
import java.util.Calendar; |
56,7 → 55,6 |
private JPanel panelHour; |
private DatePickerPanel pickerPanel; |
private List<ActionListener> listeners = new ArrayList<>(); |
private TimestampTableCellEditor aCellEditor; |
private Calendar calendar = Calendar.getInstance(); |
private JDate dateEditor; |
65,6 → 63,10 |
} |
public TimestampEditorPanel(boolean useSpinner) { |
this(useSpinner, null); |
} |
public TimestampEditorPanel(boolean useSpinner, final ActionListener validateListener) { |
calendar.set(Calendar.SECOND, 0); |
calendar.set(Calendar.MILLISECOND, 0); |
setLayout(new GridBagLayout()); |
97,14 → 99,8 |
c.gridx++; |
final JButton buttonClose = new JButton(new ImageIcon(TimestampEditorPanel.class.getResource("validate_popup.png"))); |
buttonClose.addActionListener(new ActionListener() { |
public void actionPerformed(ActionEvent e) { |
if (TimestampEditorPanel.this.aCellEditor != null) { |
TimestampEditorPanel.this.aCellEditor.stopCellEditing(); |
} |
} |
}); |
if (validateListener != null) |
buttonClose.addActionListener(validateListener); |
buttonClose.setBorderPainted(false); |
buttonClose.setOpaque(false); |
buttonClose.setFocusPainted(false); |
141,12 → 137,15 |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
final Calendar c = Calendar.getInstance(); |
c.setTimeInMillis(dateEditor.getDate().getTime()); |
final Date date = dateEditor.getDate(); |
if (date != null) { |
c.setTimeInMillis(date.getTime()); |
pickerPanel.setSelectedDate(c); |
calendar.set(Calendar.YEAR, c.get(Calendar.YEAR)); |
calendar.set(Calendar.MONTH, c.get(Calendar.MONTH)); |
calendar.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH)); |
dateOrTimeChanged(); |
} |
} |
}); |
206,8 → 205,8 |
@Override |
public void keyReleased(KeyEvent e) { |
if ((e.getKeyCode() == KeyEvent.VK_TAB || e.getKeyCode() == KeyEvent.VK_ENTER) && aCellEditor != null) { |
aCellEditor.stopCellEditing(); |
if ((e.getKeyCode() == KeyEvent.VK_TAB || e.getKeyCode() == KeyEvent.VK_ENTER) && validateListener != null) { |
validateListener.actionPerformed(new ActionEvent(e.getSource(), e.getID(), null)); |
} |
} |
230,10 → 229,18 |
} |
} |
public Timestamp getTime() { |
return new Timestamp(calendar.getTimeInMillis()); |
public final Timestamp getTimestamp() { |
return new Timestamp(this.calendar.getTimeInMillis()); |
} |
public final Time getTime() { |
return Time.valueOf(this.calendar.get(Calendar.HOUR_OF_DAY) + ":" + this.calendar.get(Calendar.MINUTE) + ":00"); |
} |
public final java.sql.Date getDate() { |
return java.sql.Date.valueOf(this.calendar.get(Calendar.YEAR) + "-" + (this.calendar.get(Calendar.MONTH) + 1) + "-" + this.calendar.get(Calendar.DAY_OF_MONTH)); |
} |
public void actionPerformed(ActionEvent e) { |
dateOrTimeChanged(); |
} |
272,10 → 279,6 |
this.listeners.remove(listener); |
} |
public void setCellEditor(TimestampTableCellEditor editor) { |
this.aCellEditor = editor; |
} |
public void setHourVisible(boolean b) { |
this.panelHour.setVisible(b); |
} |
303,8 → 306,9 |
@Override |
public void actionPerformed(ActionEvent e) { |
System.out.println("TimestampEditorPanel got :" + t.getTime()); |
System.out.println("TimestampEditorPanel got timestamp :" + t.getTimestamp()); |
System.out.println("TimestampEditorPanel got date :" + t.getDate()); |
System.out.println("TimestampEditorPanel got time :" + t.getTime()); |
} |
}); |
f.setContentPane(t); |
/trunk/OpenConcerto/src/org/openconcerto/ui/date/DateRangePlannerPanel.java |
---|
1184,6 → 1184,10 |
} |
public static String getDescriptionFromXML(String xml) { |
return getDescriptionFromXML(xml, true); |
} |
public static String getDescriptionFromXML(String xml, final boolean includeTimes) { |
String result = ""; |
try { |
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
1190,11 → 1194,13 |
final DocumentBuilder db = dbf.newDocumentBuilder(); |
final Document dom = db.parse(new StringInputStream(xml, "UTF8")); |
// Schedule |
if (includeTimes) { |
final NodeList l1 = dom.getElementsByTagName("schedule"); |
final Node nSchedule = l1.item(0); |
final long tStart = getAttributeAsLong(nSchedule, "start"); |
final long tStop = getAttributeAsLong(nSchedule, "end"); |
result += "De " + formatTime(tStart) + " à " + formatTime(tStop) + " "; |
} |
// Period |
final NodeList l2 = dom.getElementsByTagName("period"); |
/trunk/OpenConcerto/src/org/openconcerto/ui/date/DateRangeTable.java |
---|
69,13 → 69,13 |
private static final PropertyChangeListener FOCUS_LISTENER = new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
Component c = ((KeyboardFocusManager) evt.getSource()).getPermanentFocusOwner(); |
if (c == null) { |
Component focusOwner = ((KeyboardFocusManager) evt.getSource()).getPermanentFocusOwner(); |
if (focusOwner == null) { |
// Personne n'a encore le focus, on ne stoppe pas l'édition dans les tables |
// car on est dans ce cas quand on démarre l'édition |
return; |
} |
final Component rootOfNewFocusOwner = SwingUtilities.getRoot(c); |
final Component rootOfNewFocusOwner = SwingUtilities.getRoot(focusOwner); |
for (final JTable t : FOCUS_TABLES) { |
final Component rootOfTable = SwingUtilities.getRoot(t); |
if (rootOfNewFocusOwner != rootOfTable) { |
82,6 → 82,7 |
// le focus est dans un autre fenetre, la table doit donc stopper son édition |
stopTableCellEditing(t); |
} else { |
Component c = focusOwner; |
while (c != null) { |
if (c == t) { |
// le focus reste "dans" la table, on ne fait rien |
112,7 → 113,9 |
final String propertyName = "permanentFocusOwner"; |
if (c.isDisplayable()) { |
final boolean wasEmpty = FOCUS_TABLES.isEmpty(); |
if (!FOCUS_TABLES.contains(c)) { |
FOCUS_TABLES.add((JTable) c); |
} |
if (wasEmpty) { |
final KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); |
focusManager.addPropertyChangeListener(propertyName, FOCUS_LISTENER); |
288,6 → 291,7 |
} |
// enableFocusLogging(); |
final JFrame f = new JFrame(); |
f.setTitle("DateRangeTable"); |
f.setContentPane(new DateRangeTable(true, false)); |
f.setSize(400, 300); |
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
/trunk/OpenConcerto/src/org/openconcerto/ui/table/TimestampTableCellEditor.java |
---|
51,8 → 51,13 |
private Calendar calendar; |
private JPopupMenu aPopup; |
private boolean popupOpen = false; |
private final TimestampEditorPanel content = new TimestampEditorPanel(); |
private boolean allowNull = true; |
private final TimestampEditorPanel content = new TimestampEditorPanel(false, new ActionListener() { |
@Override |
public void actionPerformed(ActionEvent e) { |
stopCellEditing(); |
} |
}); |
private boolean allowNull = false; |
public TimestampTableCellEditor(boolean showHour) { |
this(); |
96,10 → 101,12 |
this.aPopup.addPropertyChangeListener(new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
if (!allowNull) { |
if (evt.getPropertyName().equals("visible") && Boolean.FALSE.equals(evt.getNewValue())) { |
stopCellEditing(); |
} |
} |
} |
}); |
this.popupOpen = true; |
134,7 → 141,6 |
} |
}); |
this.content.setCellEditor(this); |
this.content.addActionListener(this); |
return c; |
} |
215,7 → 221,7 |
} |
public void actionPerformed(ActionEvent e) { |
this.delegate.setValue(this.content.getTime()); |
this.delegate.setValue(this.content.getTimestamp()); |
} |
public static void main(String[] args) { |
/trunk/OpenConcerto/src/org/openconcerto/ui/FontUtils.java |
---|
18,6 → 18,9 |
import java.awt.Component; |
import java.awt.Font; |
import javax.swing.JTable; |
import javax.swing.JTree; |
public class FontUtils { |
public static Font setFontFor(Component comp, String toDisplay) { |
25,8 → 28,8 |
} |
/** |
* If the current font for <code>comp</code> cannot handle <code>toDisplay</code>, this |
* method set the font to the system LAF (which should have appropriate fallbacks). |
* If the current font for <code>comp</code> cannot handle <code>toDisplay</code>, this method |
* set the font to the system LAF (which should have appropriate fallbacks). |
* |
* @param comp the component, eg a JComboBox. |
* @param name the name of system LAF font, eg ComboBox. |
54,4 → 57,11 |
return res; |
} |
public static int getPreferredRowHeight(JTree tree) { |
return 2 + (int) (tree.getFont().getSize() * 1.4f); |
} |
public static int getPreferredRowHeight(JTable table) { |
return 4 + (int) (table.getFont().getSize() * 1.4f); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/ui/DefaultGridBagConstraints.java |
---|
18,6 → 18,7 |
import java.awt.Insets; |
import javax.swing.JComponent; |
import javax.swing.UIManager; |
public class DefaultGridBagConstraints extends GridBagConstraints { |
35,6 → 36,10 |
} |
public static Insets getDefaultInsets() { |
if (UIManager.get("dpi.scale") != null) { |
float f = (Float) UIManager.get("dpi.scale"); |
return new Insets((int) (2 * f), (int) (3 * f), (int) (2 * f), (int) (2 * f)); |
} |
return new Insets(2, 3, 2, 2); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/ui/light/LightRowValuesTableOnline.java |
---|
14,7 → 14,7 |
package org.openconcerto.sql.ui.light; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.model.SQLField; |
import org.openconcerto.sql.model.IFieldPath; |
import org.openconcerto.sql.model.SQLFunctionField; |
import org.openconcerto.sql.model.SQLFunctionField.SQLFunction; |
import org.openconcerto.sql.model.SQLRowValues; |
115,19 → 115,19 |
*/ |
private final void setWhere(final SQLSelect sel, final SearchInfo sInfo, final List<SQLTableModelColumn> cols) { |
if (sInfo != null) { |
final Set<SQLField> fields = new HashSet<SQLField>(); |
final Set<IFieldPath> fields = new HashSet<>(cols.size() * 2); |
for (final SQLTableModelColumn sqlTableModelColumn : cols) { |
fields.addAll(sqlTableModelColumn.getFields()); |
fields.addAll(sqlTableModelColumn.getPaths()); |
} |
final List<Where> wheres = new ArrayList<Where>(); |
final List<Where> wFields = new ArrayList<Where>(); |
final List<Where> wheres = new ArrayList<>(); |
final List<Where> wFields = new ArrayList<>(); |
final List<String> texts = sInfo.getTexts(); |
for (String string : texts) { |
wFields.clear(); |
for (final SQLField sqlField : fields) { |
if (sqlField.getType().getJavaType().equals(String.class)) { |
final Where w = new Where(new SQLFunctionField(SQLFunction.LOWER, sel.getAlias(sqlField)), "LIKE", "%" + string.toLowerCase() + "%"); |
for (final IFieldPath fpath : fields) { |
if (fpath.getField().getType().getJavaType().equals(String.class)) { |
final Where w = new Where(new SQLFunctionField(SQLFunction.LOWER, sel.followFieldPath(fpath)), "LIKE", "%" + string.toLowerCase() + "%"); |
wFields.add(w); |
} |
} |
141,7 → 141,6 |
w = Where.and(wheres); |
} |
sel.setWhere(w); |
System.err.println(sel.asString()); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/ui/light/LightEditFrame.java |
---|
292,16 → 292,29 |
} |
} |
final protected void setMetaData(final int userId) { |
// FIXME use SQLRowValues method |
protected final void setMetaData(final int userId) { |
final SQLTable sqlTable = this.sqlRow.getTable(); |
final Date now = new Date(); |
// FIXME only set those fields at insertion time |
if (this.sqlRow.getObject(sqlTable.getCreationUserField().getName()) == null || this.sqlRow.getObject(sqlTable.getCreationDateField().getName()) == null) { |
this.sqlRow.put(sqlTable.getCreationUserField().getName(), userId); |
this.sqlRow.put(sqlTable.getCreationDateField().getName(), new Date()); |
setFieldValue(this.sqlRow, sqlTable.getCreationUserField(), false, userId); |
setFieldValue(this.sqlRow, sqlTable.getCreationDateField(), false, now); |
} |
this.sqlRow.put(sqlTable.getModifUserField().getName(), userId); |
this.sqlRow.put(sqlTable.getModifDateField().getName(), new Date()); |
setFieldValue(this.sqlRow, sqlTable.getModifUserField(), false, userId); |
setFieldValue(this.sqlRow, sqlTable.getModifDateField(), false, now); |
} |
static private boolean setFieldValue(final SQLRowValues vals, final SQLField f, final boolean remove, final Object val) { |
if (f == null) |
return false; |
if (remove) |
vals.remove(f.getName()); |
else |
vals.put(f.getName(), val); |
return true; |
} |
@Override |
public String getClassName() { |
return this.getClass().getName(); |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/warning_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/warning_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/ElementComboBox.java |
---|
26,6 → 26,7 |
import org.openconcerto.sql.view.EditPanelListener; |
import org.openconcerto.sql.view.IListButton; |
import org.openconcerto.sql.view.IListFrame; |
import org.openconcerto.sql.view.IListPanel; |
import org.openconcerto.sql.view.ListeAddPanel; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FrameUtil; |
44,9 → 45,9 |
import javax.swing.AbstractAction; |
import javax.swing.Icon; |
import javax.swing.ImageIcon; |
import javax.swing.JButton; |
import javax.swing.JFrame; |
import javax.swing.UIManager; |
/** |
* A SQLRequestComboBox with an SQLElement allowing it to have buttons for zooming on a selected |
61,9 → 62,10 |
*/ |
public static final String CAN_MODIFY = "org.openconcerto.sql.comboCanModify"; |
private static ImageIcon icon = null; |
private static ImageIcon iconModif = null; |
private static ImageIcon iconAdd = null; |
private static Icon icon = null; |
private static Icon iconModif = null; |
private static Icon iconAdd = null; |
static int iconSize; |
private static ITransformer<ElementComboBox, Boolean> globalRowDisplayer = null; |
70,9 → 72,11 |
// no need for synchronization, all in EDT |
private static void checkLoaded() { |
if (icon == null) { |
icon = new ImageIcon(ElementComboBox.class.getResource("loupe.png")); |
iconAdd = new ImageIcon(ElementComboBox.class.getResource("plus.png")); |
iconModif = new ImageIcon(ElementComboBox.class.getResource("pen.png")); |
final boolean twoX = UIManager.get("dpi.scale") != null && ((Float) UIManager.get("dpi.scale")) >= 2f; |
iconSize = twoX ? 32 : 16; |
icon = IListPanel.getIcon(ElementComboBox.class, "loupe.png", twoX); |
iconAdd = IListPanel.getIcon(ElementComboBox.class, "plus.png", twoX); |
iconModif = IListPanel.getIcon(ElementComboBox.class, "pen.png", twoX); |
} |
} |
182,10 → 186,13 |
if (this.isModif) { |
this.viewButton.setToolTipText("Modifier"); |
this.viewButton.setIcon(getModifIcon()); |
} else { |
this.viewButton.setToolTipText("Voir plus de détails"); |
this.viewButton.setIcon(getDetailsIcon()); |
} |
this.viewButton.setPreferredSize(new Dimension(iconSize + 8, iconSize)); |
DefaultGridBagConstraints.lockMinimumSize(this.viewButton); |
// each time its icon change, otherwise (at least on Mac) the opacity is wrong |
IListButton.initButton(this.viewButton); |
} |
216,18 → 223,14 |
if (!this.minimal) { |
c.weightx = 0; |
c.gridx++; |
this.viewButton.setPreferredSize(new Dimension(24, 16)); |
this.setCanModify(Boolean.getBoolean(CAN_MODIFY)); |
DefaultGridBagConstraints.lockMinimumSize(this.viewButton); |
add(this.viewButton, c); |
c.gridx++; |
this.listButton.setToolTipText(TM.getInstance().trM("combo.list", "element", this.element.getName())); |
DefaultGridBagConstraints.lockMinimumSize(this.listButton); |
add(this.listButton, c); |
// Add button |
this.addButton.setPreferredSize(new Dimension(24, 16)); |
this.addButton.setPreferredSize(new Dimension(iconSize + 8, iconSize)); |
this.addButton.setIcon(getAddIcon()); |
IListButton.initButton(this.addButton); |
this.addButton.setToolTipText(EditFrame.getCreateMessage(this.element)); |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/pen_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/pen_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/plus_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/plus_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/loupe_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/loupe_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/error_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/error_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/request/ListSQLRequest.java |
---|
57,8 → 57,6 |
public ListSQLRequest(final SQLRowValues graph, final Where where) { |
super(graph, where); |
if (!this.getPrimaryTable().isOrdered()) |
throw new IllegalArgumentException(this.getPrimaryTable() + " is not ordered."); |
} |
protected ListSQLRequest(ListSQLRequest req, final boolean freeze) { |
/trunk/OpenConcerto/src/org/openconcerto/sql/request/BaseFillSQLRequest.java |
---|
17,7 → 17,9 |
import org.openconcerto.sql.TM; |
import org.openconcerto.sql.model.FieldRef; |
import org.openconcerto.sql.model.IFieldPath; |
import org.openconcerto.sql.model.OrderComparator; |
import org.openconcerto.sql.model.SQLField; |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.model.SQLRowValues.CreateMode; |
import org.openconcerto.sql.model.SQLRowValuesListFetcher; |
46,6 → 48,7 |
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.List; |
352,7 → 355,38 |
return this.getDefaultOrder(); |
} |
public final boolean isTableOrder() { |
return this.getPrimaryTable().isOrdered() && this.getOrder().equals(getTableOrder()); |
} |
/** |
* Order the passed rows the same as {@link #getFetcher()}. |
* |
* @param r1 the first row. |
* @param r2 the second row. |
* @return a negative integer, zero, or a positive integer as the first argument is less than, |
* equal to, or greater than the second. |
*/ |
public final int order(final SQLRowValues r1, final SQLRowValues r2) { |
if (r1 == r2) |
return 0; |
// same behaviour as SQLSelect |
final Comparator<SQLRowAccessor> comp = OrderComparator.getFallbackToPKInstance(); |
for (final Path p : getOrder()) { |
final SQLRowValues o1 = r1.followPath(p); |
final SQLRowValues o2 = r2.followPath(p); |
final int res = comp.compare(o1, o2); |
if (res != 0) |
return res; |
} |
return 0; |
} |
protected List<Path> getDefaultOrder() { |
return getTableOrder(); |
} |
protected final List<Path> getTableOrder() { |
return Collections.singletonList(Path.get(getPrimaryTable())); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/element/GlobalMapper.java |
---|
43,7 → 43,6 |
l = new ArrayList<String>(3); |
objectsToIds.put(obj, l); |
l.add(id); |
objectsToIds.put(obj, l); |
} else if (!l.contains(obj)) { |
l.add(id); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/element/UISQLComponent.java |
---|
203,10 → 203,19 |
this.setLayout(new GridLayout(1, 1)); |
this.add(this.tabbedPane); |
} |
this.currentPanel = new JPanel(); |
final JPanel newPanel = new JPanel(); |
// from Guillaume : tabs shouldn't be opaque in Windows L&F |
this.currentPanel.setOpaque(false); |
this.tabbedPane.addTab(tabTitle, this.currentPanel); |
newPanel.setOpaque(false); |
this.tabbedPane.addTab(tabTitle, newPanel); |
this.setLayouterOn(newPanel, w, d); |
} |
protected final void setLayouterOn(final JPanel cont) { |
this.setLayouterOn(cont, this.width, this.def); |
} |
protected final void setLayouterOn(final JPanel cont, int w, int d) { |
this.currentPanel = cont; |
this.setLayouter(w, d); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLTable.java |
---|
515,7 → 515,7 |
// must be called in setState() after fields have been set (for isRowable()) |
private int fetchUndefID() { |
int res; |
final int res; |
final SQLField pk; |
synchronized (this) { |
pk = isRowable() ? this.getKey() : null; |
523,14 → 523,8 |
if (pk != null) { |
final Tuple2<Boolean, Number> currentValue = getUndefID(this.getSchema(), this.getName()); |
if (!currentValue.get0()) { |
try { |
// no row |
res = this.findMinID(pk); |
} catch (Exception e) { |
// we ***** don't care |
e.printStackTrace(); |
res = SQLRow.NONEXISTANT_ID; |
} |
} else { |
// a row |
final Number id = currentValue.get1(); |
982,6 → 976,10 |
@Immutable |
static public final class VirtualFields { |
// must be set first, as they are used by others (e.g. create()) |
static public final VirtualFields NONE = new VirtualFields(EnumSet.noneOf(VirtualFieldPartition.class)); |
static public final VirtualFields ALL = new VirtualFields(EnumSet.allOf(VirtualFieldPartition.class)); |
static public final VirtualFields ORDER = new VirtualFields(VirtualFieldPartition.ORDER); |
static public final VirtualFields ARCHIVE = new VirtualFields(VirtualFieldPartition.ARCHIVE); |
static public final VirtualFields METADATA = new VirtualFields(VirtualFieldPartition.METADATA); |
1004,9 → 1002,16 |
* {@link #PRIMARY_KEY} with {@link #FOREIGN_KEYS}. |
*/ |
static public final VirtualFields KEYS = PRIMARY_KEY.union(FOREIGN_KEYS); |
static public final VirtualFields NONE = new VirtualFields(EnumSet.noneOf(VirtualFieldPartition.class)); |
static public final VirtualFields ALL = new VirtualFields(EnumSet.allOf(VirtualFieldPartition.class)); |
static private VirtualFields create(final EnumSet<VirtualFieldPartition> set) { |
if (set.isEmpty()) |
return NONE; |
else if (set.equals(ALL.set)) |
return ALL; |
else |
return new VirtualFields(set); |
} |
private final EnumSet<VirtualFieldPartition> set; |
// use constants above |
1021,25 → 1026,45 |
this.set = set; |
} |
public final boolean contains(VirtualFields other) { |
return this == other || this == ALL || this != NONE && this.set.containsAll(other.set); |
} |
public final VirtualFields union(VirtualFields... other) { |
// optimizations |
if (this == ALL || other.length == 0 || other.length == 1 && this.contains(other[0])) |
return this; |
if (other.length == 1 && other[0].contains(this)) |
return other[0]; |
final EnumSet<VirtualFieldPartition> set = this.set.clone(); |
for (final VirtualFields o : other) |
set.addAll(o.set); |
return new VirtualFields(set); |
return create(set); |
} |
public final VirtualFields intersection(VirtualFields... other) { |
// optimizations |
if (this == NONE || other.length == 0 || other.length == 1 && other[0].contains(this)) |
return this; |
if (other.length == 1 && this.contains(other[0])) |
return other[0]; |
final EnumSet<VirtualFieldPartition> set = this.set.clone(); |
for (final VirtualFields o : other) |
set.retainAll(o.set); |
return new VirtualFields(set); |
return create(set); |
} |
public final VirtualFields difference(VirtualFields... other) { |
// optimizations |
if (this == NONE || other.length == 0 || other.length == 1 && Collections.disjoint(this.set, other[0].set)) |
return this; |
final EnumSet<VirtualFieldPartition> set = this.set.clone(); |
for (final VirtualFields o : other) |
set.removeAll(o.set); |
return new VirtualFields(set); |
return create(set); |
} |
public final VirtualFields complement() { |
1068,7 → 1093,12 |
final VirtualFields other = (VirtualFields) obj; |
return this.set.equals(other.set); |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName() + " " + this.set; |
} |
} |
/** |
* A partition of the fields (except that some can be empty). Being a partition allow to use |
2177,13 → 2207,17 |
try { |
triggerClass = Class.forName(className); |
} catch (ClassNotFoundException e) { |
throw new SQLException("Class not found for " + t, e); |
// throw new SQLException("Class not found for " + t, e); |
e.printStackTrace(); |
continue; |
} |
PartialUniqueTrigger n; |
try { |
n = (PartialUniqueTrigger) triggerClass.newInstance(); |
} catch (Exception e) { |
throw new SQLException("Couldn't instantiate class for " + t, e); |
// throw new SQLException("Couldn't instantiate class for " + t, e); |
e.printStackTrace(); |
continue; |
} |
final String indexName = ChangeTable.getIndexName(t.getName(), thisSystem); |
final Index idx = createUniqueIndex(indexName, n.getColumns(), n.getWhere()); |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowValuesListFetcher.java |
---|
26,6 → 26,7 |
import org.openconcerto.utils.ListMap; |
import org.openconcerto.utils.RTInterruptedException; |
import org.openconcerto.utils.RecursionType; |
import org.openconcerto.utils.SetMap; |
import org.openconcerto.utils.Tuple2; |
import org.openconcerto.utils.cc.ITransformer; |
import org.openconcerto.utils.cc.LinkedIdentitySet; |
246,6 → 247,9 |
// graftPlace -> {referent path -> fetcher}, unmodifiable |
@GuardedBy("this") |
private Map<Path, Map<Path, SQLRowValuesListFetcher>> grafts; |
// {pathToAdd, existingPath}, unmodifiable |
@GuardedBy("this") |
private Map<Path, Path> postFetchLinks; |
/** |
* Construct a new instance with the passed graph of SQLRowValues. |
349,6 → 353,7 |
this.frozen = null; |
this.freezeRows = false; |
this.grafts = Collections.emptyMap(); |
this.postFetchLinks = Collections.emptyMap(); |
} |
} |
381,6 → 386,7 |
e.setValue(Collections.unmodifiableMap(innerMutable)); |
} |
this.grafts = Collections.unmodifiableMap(outerMutable); |
this.postFetchLinks = f.postFetchLinks; |
} |
} |
} |
629,6 → 635,69 |
return this.descendantsOrdered; |
} |
public final void addPostFetchLink(final Path toAdd, final Path existingDestination) { |
this.addPostFetchLink(toAdd, existingDestination, false); |
} |
/** |
* Add a link to be added at the end of fetch(). This is needed when the graph to be fetched |
* isn't a tree. |
* |
* @param toAdd the last step of this parameter will be added at the end of {@link #fetch()}, |
* e.g. /SOURCE/ --[ID_MOST_SERIOUS_OBS]--> /OBSERVATION/. |
* @param existingDestination where the destination rows of <code>toAdd</code> are, e.g. |
* /SOURCE/ <--[ID_SOURCE]-- /SOURCE_OBSERVATION/ --[ID_OBSERVATION]--> /OBSERVATION/. |
* @param ignoreIfMissing what to do if a passed path isn't in this, <code>true</code> to do |
* nothing, <code>false</code> to throw an exception. |
* @return <code>true</code> if the link was added. |
*/ |
public synchronized final boolean addPostFetchLink(final Path toAdd, final Path existingDestination, final boolean ignoreIfMissing) { |
checkFrozen(); |
if (toAdd.getLast() != existingDestination.getLast()) |
throw new IllegalArgumentException("Different destination tables"); |
if (!toAdd.isSingleField()) |
throw new IllegalArgumentException("Path to add isn't composed of single fields"); |
final Step lastStep = toAdd.getStep(-1); |
if (lastStep.getDirection() != Direction.FOREIGN) |
throw new IllegalArgumentException("Last step isn't foreign : " + lastStep); |
if (!getFetchers(toAdd).isEmpty()) |
throw new IllegalArgumentException("Path to add already fetched"); |
final Path pathToFK = toAdd.minusLast(); |
final ListMap<Path, SQLRowValuesListFetcher> fkFetchers = getFetchers(pathToFK); |
if (fkFetchers.isEmpty()) { |
if (ignoreIfMissing) |
return false; |
else |
throw new IllegalArgumentException("Path to add should only have the last step missing"); |
} |
final String lastFieldName = lastStep.getSingleField().getName(); |
for (final Entry<Path, List<SQLRowValuesListFetcher>> e : fkFetchers.entrySet()) { |
final int pathLength = e.getKey().length(); |
for (final SQLRowValuesListFetcher fkFetcher : e.getValue()) { |
if (!fkFetcher.getGraph().followPath(pathToFK.subPath(pathLength)).contains(lastFieldName)) { |
if (ignoreIfMissing) |
return false; |
else |
throw new IllegalArgumentException("Foreign key " + lastFieldName + " isn't fetched"); |
} |
} |
} |
if (getFetchers(existingDestination).isEmpty()) { |
if (ignoreIfMissing) |
return false; |
else |
throw new IllegalArgumentException("Destination won't be fetched : " + existingDestination); |
} |
final Map<Path, Path> copy = new HashMap<>(this.postFetchLinks); |
copy.put(toAdd, existingDestination); |
this.postFetchLinks = Collections.unmodifiableMap(copy); |
return true; |
} |
public synchronized Map<Path, Path> getPostFetchLinks() { |
return this.postFetchLinks; |
} |
public final SQLRowValuesListFetcher graft(final SQLRowValuesListFetcher other) { |
return this.graft(other, Path.get(getGraph().getTable())); |
} |
1239,11 → 1308,13 |
} |
final SQLSelect req; |
final Map<Path, Map<Path, SQLRowValuesListFetcher>> grafts; |
final Map<Path, Path> postLinks; |
final boolean freezeRows; |
// the only other internal state used is this.descendantPath which is final immutable |
synchronized (this) { |
req = this.getReq(w, selTransf); |
grafts = this.getGrafts(); |
postLinks = this.postFetchLinks; |
freezeRows = unmodifiableRows == null ? this.areReturnedRowsUnmodifiable() : unmodifiableRows.booleanValue(); |
} |
// getName() would take 5% of ResultSetHandler.handle() |
1288,9 → 1359,10 |
final boolean mergeReferents = this.fetchReferents(); |
final boolean mergeGrafts = grafts.size() > 0; |
final boolean addPostLinks = !postLinks.isEmpty(); |
// if it is possible let the handler do the freeze, avoid another loop and further is |
// multi-threaded |
final boolean handlerCanFreeze = !mergeReferents && !mergeGrafts; |
final boolean handlerCanFreeze = !mergeReferents && !mergeGrafts && !addPostLinks; |
// if we wanted to use the cache, we'd need to copy the returned list and its items (i.e. |
// deepCopy()), since we modify them afterwards. Or perhaps include the code after this line |
1328,6 → 1400,58 |
mainRes.pop(); |
} |
} |
if (addPostLinks) { |
// group by destinationPath to index only once for all links to add |
// SetMap<Tuple2<commonPath, destinationPath>, toAddPath> |
final SetMap<Tuple2<Path, Path>, Path> byCommonPath = new SetMap<>(); |
for (final Entry<Path, Path> e : postLinks.entrySet()) { |
final Path toAdd = e.getKey(); |
final Path existingPath = e.getValue(); |
final Path commonPath = toAdd.getCommonPath(existingPath); |
byCommonPath.add(Tuple2.create(commonPath, existingPath.subPath(commonPath.length())), toAdd.subPath(commonPath.length())); |
} |
/** |
* <pre> |
* LOCAL <-- SRC <-- JOIN --> OBSERVATION |
* \--ID_OLDEST_OBS--/ |
* \--ID_MOST_SERIOUS_OBS--/ |
* </pre> |
*/ |
for (final Entry<Tuple2<Path, Path>, Set<Path>> e : byCommonPath.entrySet()) { |
// LOCAL <-- SRC |
final Path commonPath = e.getKey().get0(); |
// SRC <-- JOIN --> OBSERVATION |
final Path throughTargetRows = e.getKey().get1(); |
// SRC -- ID_OLDEST_OBS --> OBSERVATION |
// SRC -- ID_MOST_SERIOUS_OBS --> OBSERVATION |
final Set<Path> pathsToAdd = e.getValue(); |
for (final SQLRowValues v : merged) { |
for (final SQLRowValues commonRow : v.getDistantRows(commonPath)) { |
// index target rows |
final Map<Number, SQLRowValues> byIDs = new HashMap<>(); |
for (final SQLRowValues target : commonRow.getDistantRows(throughTargetRows)) { |
byIDs.put(target.getIDNumber(), target); |
} |
// add links |
for (final Path toAdd : pathsToAdd) { |
final String fkName = toAdd.getStep(-1).getSingleField().getName(); |
// SRC |
final Path throughRowToUpdate = toAdd.minusLast(); |
for (final SQLRowValues toUpdate : commonRow.getDistantRows(throughRowToUpdate)) { |
final Number foreignID = toUpdate.getNonEmptyForeignIDNumber(fkName); |
if (foreignID != null) { |
final SQLRowValues target = byIDs.get(foreignID); |
if (target == null) |
throw new IllegalStateException("Missing row for " + foreignID + " at " + throughTargetRows); |
toUpdate.put(fkName, target); |
} |
} |
} |
} |
} |
} |
} |
if (freezeRows && !handlerCanFreeze) { |
for (final SQLRowValues r : merged) { |
r.getGraph().freeze(); |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowAccessor.java |
---|
261,6 → 261,10 |
*/ |
public abstract Set<String> getFields(); |
public boolean contains(final String fieldName) { |
return this.getFields().contains(fieldName); |
} |
public abstract Object getObject(String fieldName); |
/** |
283,8 → 287,14 |
// MAYBE change paramter to enum MissingMode = THROW_EXCEPTION, ADD, RETURN_NULL |
public final Object getObject(String fieldName, final boolean mustBePresent) throws IllegalArgumentException { |
if (mustBePresent && !this.getFields().contains(fieldName)) |
throw new IllegalArgumentException("Field " + fieldName + " not present in this : " + this.getFields() + " table " + this.getTable().getName()); |
if (mustBePresent && !this.contains(fieldName)) { |
final String msg; |
if (this.getTable().contains(fieldName)) |
msg = "Field " + fieldName + " not present in this : " + this.getFields() + " but exists in " + this.getTable(); |
else |
msg = "Field " + fieldName + " neither present in this : " + this.getFields() + " nor " + this.getTable(); |
throw new IllegalArgumentException(msg); |
} |
return this.getObject(fieldName); |
} |
314,6 → 324,7 |
* @return the values of the passed fields. |
*/ |
public final Map<String, Object> getValues(final Collection<String> fields, final boolean includeMissingKeys) { |
this.initValues(); |
final Map<String, Object> res = new LinkedHashMap<String, Object>(); |
final Set<String> thisFields = this.getFields(); |
for (final String f : fields) { |
323,6 → 334,9 |
return res; |
} |
protected void initValues() { |
} |
/** |
* Retourne le champ nommé <code>field</code> de cette ligne. Cette méthode formate la valeur en |
* fonction de son type, par exemple une date sera localisée. |
465,7 → 479,8 |
* <code>null</code> : |
* <ol> |
* <li><code>field</code> is defined and has the value <code>null</code></li> |
* <li><code>field</code> is defined and has an SQLRowValues value without an ID</li> |
* <li><code>field</code> is defined and has an SQLRowValues value {@link #hasID() without an |
* ID} (i.e. field not defined or <code>null</code>)</li> |
* </ol> |
* In the second case, <code>field</code> is *not* {@link #isForeignEmpty(String) empty}, an ID |
* is just missing. |
489,14 → 504,19 |
* {@link #isForeignEmpty(String) empty}, otherwise the foreign ID for the passed field. |
* @throws IllegalArgumentException if fieldName is not a foreign field or if the field isn't |
* specified. |
* @throws IllegalStateException if fieldName is not empty but lacks an ID (i.e. has a |
* SQLRowValues without an ID) as by definition a <code>null</code> result means empty. |
* @see #getNonEmptyForeign(String) |
*/ |
public final Number getNonEmptyForeignIDNumber(String fieldName) { |
if (this.isForeignEmpty(fieldName)) { |
return null; |
} else { |
final Number res = this.getForeignIDNumber(fieldName); |
assert res != null; |
return res; |
final Value<Number> res = this.getForeignIDNumberValue(fieldName); |
if (!res.hasValue()) |
throw new IllegalStateException("Foreign row has no ID"); |
assert res.getValue() != null; |
return res.getValue(); |
} |
} |
527,7 → 547,7 |
} |
private void fetchIfNeeded(String fieldName) { |
if (getAccessDBIfNeeded() && (this instanceof SQLRow) && !getFields().contains(fieldName)) { |
if (getAccessDBIfNeeded() && (this instanceof SQLRow) && !contains(fieldName)) { |
assert false : "Missing " + fieldName + " in " + this; |
Log.get().log(Level.WARNING, "Missing " + fieldName + " in " + this, new IllegalStateException()); |
((SQLRow) this).fetchValues(); |
540,6 → 560,10 |
* @param fieldName name of the foreign field. |
* @return <code>true</code> if {@link #getForeignIDNumber(String)} is the |
* {@link SQLTable#getUndefinedIDNumber()}. |
* @throws IllegalArgumentException if fieldName is not a foreign field or if the field isn't |
* specified. |
* @throws IllegalStateException if <code>fieldName</code> is <code>null</code> but the foreign |
* table has an undefined ID. |
*/ |
public final boolean isForeignEmpty(String fieldName) { |
final Value<Number> fID = this.getForeignIDNumberValue(fieldName); |
550,6 → 574,12 |
// keep getForeignTable at the 1st line since it does the check |
final SQLTable foreignTable = this.getForeignTable(fieldName); |
final Number undefID = foreignTable.getUndefinedIDNumber(); |
if (undefID != null && fID.getValue() == null) { |
// since a foreign row with ID=null !hasID() and thus getForeignIDNumberValue() is |
// none and this method returns false above |
assert this.getObject(fieldName) == null; |
throw new IllegalStateException("Null isn't a valid foreign key value when pointing to a table with undefined ID : " + undefID); |
} |
return NumberUtils.areNumericallyEqual(fID.getValue(), undefID); |
} |
} |
599,17 → 629,6 |
return this.getTable().hashCode() + this.getID(); |
} |
public SQLRowValues getMergedRowValuesFromDatabase() { |
SQLRowValues result = this.asRowValues(); |
if (this.hasID()) { |
SQLRow r = result.getTable().getRow(getID()); |
for (String f : r.getFields()) { |
if (!result.getFields().contains(f)) { |
result.put(f, r.getObject(f)); |
// return the all current field values |
public abstract String mapToString(); |
} |
} |
} |
return result; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLSchema.java |
---|
53,7 → 53,7 |
public static final String NOAUTO_CREATE_METADATA = "org.openconcerto.sql.noautoCreateMetadata"; |
public static final String FWK_TABLENAME_PREFIX = "FWK_"; |
static final String METADATA_TABLENAME = FWK_TABLENAME_PREFIX + "SCHEMA_METADATA"; |
public static final String METADATA_TABLENAME = FWK_TABLENAME_PREFIX + "SCHEMA_METADATA"; |
private static final String VERSION_MDKEY = "VERSION"; |
private static final String VERSION_XMLATTR = "schemaVersion"; |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/OrderComparator.java |
---|
13,6 → 13,8 |
package org.openconcerto.sql.model; |
import org.openconcerto.utils.CompareUtils; |
import java.util.Comparator; |
/** |
22,10 → 24,28 |
*/ |
public class OrderComparator implements Comparator<SQLRowAccessor> { |
public static final OrderComparator INSTANCE = new OrderComparator(); |
/** |
* Order rows by {@link SQLTable#getOrderField()}. |
*/ |
public static final OrderComparator INSTANCE = new OrderComparator(false); |
private static final OrderComparator INSTANCE_FALLBACK_TO_PK = new OrderComparator(true); |
/** |
* Order rows by {@link SQLTable#getOrderField()}, or if the table is not |
* {@link SQLTable#isOrdered() ordered} by {@link SQLTable#getKey()}. |
* |
* @return the comparator. |
*/ |
public static final Comparator<SQLRowAccessor> getFallbackToPKInstance() { |
return INSTANCE_FALLBACK_TO_PK; |
} |
private final boolean fallbackToPK; |
// singleton |
private OrderComparator() { |
private OrderComparator(boolean fallbackToPK) { |
super(); |
this.fallbackToPK = fallbackToPK; |
} |
@Override |
34,9 → 54,21 |
// MAYBE NULLS FIRST/LAST |
if (r1 == r2) |
return 0; |
if (!r1.getTable().equals(r2.getTable())) |
final SQLTable t = r1.getTable(); |
if (!t.equals(r2.getTable())) |
throw new IllegalArgumentException(r1 + " and " + r2 + " are not of the same table"); |
if (t.isOrdered()) { |
return r1.getOrder().compareTo(r2.getOrder()); |
} else if (this.fallbackToPK) { |
if (!t.isRowable()) |
throw new IllegalArgumentException(t + " neither ordered nor rowable"); |
else if (r1.hasID() && r2.hasID()) |
return CompareUtils.compareInt(r1.getID(), r2.getID()); |
else |
throw new IllegalArgumentException("Missing ID"); |
} else { |
throw new IllegalArgumentException(t + " not ordered"); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowValuesCluster.java |
---|
123,6 → 123,10 |
return this.getHead().getTable().getDBSystemRoot(); |
} |
public final int getLinksCount() { |
return this.links.size(); |
} |
/** |
* All the rowValues in this cluster. |
* |
325,6 → 329,43 |
} |
public final Map<SQLRowValues, SQLRowValues> deepCopy(final boolean freeze) { |
return this.copy(null, false, freeze); |
} |
/** |
* Copy a subset of this graph. For each link to copy, if the destination was copied then the |
* new row will point to it, otherwise the new row will point to the original row. For example, |
* if |
* |
* <pre> |
* start is CONTAINER <-- *ITEM [F1, F2]* --> PRIVATE |
* and graph is ITEM [F2, ID_PRIVATE] |
* then after this method : |
* CONTAINER <-- ITEM [F1, F2] --> PRIVATE |
* \-- ITEM [F2] --> PRIVATE |
* </pre> |
* |
* @param start where to start copying. |
* @param graph which rows and which fields to copy, not <code>null</code>. |
* @return the new rows, indexed by the original rows in this instance. |
*/ |
public final Map<SQLRowValues, SQLRowValues> copy(final SQLRowValues start, final SQLRowValues graph) { |
return this.copy(computeToRetain(start, graph, true), true, false); |
} |
/** |
* Copy rows of this graph. |
* |
* @param subset which rows and which fields to copy, <code>null</code> to copy all rows. |
* @param allowSameGraph used when copied rows point to rows which weren't copied, |
* <code>true</code> to point to the original rows (and thus linking the new rows into |
* the existing graph), <code>false</code> to flatten the link (like |
* {@link ForeignCopyMode#COPY_ID_OR_RM}). |
* @param freeze <code>true</code> if the copied rows should be frozen. |
* @return the new rows, indexed by the original rows in this instance. |
*/ |
private final Map<SQLRowValues, SQLRowValues> copy(final SetMap<SQLRowValues, String> subset, final boolean allowSameGraph, final boolean freeze) { |
assert !allowSameGraph || !freeze; |
// copy all rowValues of this graph |
final Map<SQLRowValues, SQLRowValues> noLinkCopy = new IdentityHashMap<SQLRowValues, SQLRowValues>(); |
// don't copy foreigns, but we want to preserve the order of all fields. This works because |
332,6 → 373,7 |
final ForeignCopyMode copyMode = ForeignCopyMode.COPY_NULL; |
for (final SQLRowValues n : this.getItems()) { |
final SQLRowValues copy; |
if (subset == null || subset.containsKey(n)) { |
// might as well use the minimum memory if the values won't change |
if (freeze) { |
copy = new SQLRowValues(n.getTable(), n.size(), n.getForeignsSize(), n.getReferents().size()); |
338,18 → 380,43 |
copy.setAll(n.getAllValues(copyMode)); |
} else { |
copy = new SQLRowValues(n, copyMode); |
if (subset != null) { |
copy.retainAll(subset.get(n)); |
} |
} |
noLinkCopy.put(n, copy); |
} |
} |
// and link them together in order |
for (final Link l : this.links) { |
final List<Link> iterableLinks = subset == null ? this.links : new ArrayList<Link>(this.links); |
for (final Link l : iterableLinks) { |
if (l.getField() != null) { |
noLinkCopy.get(l.getSrc()).put(l.getField().getName(), noLinkCopy.get(l.getDest())); |
final SQLRowValues sourceCopy = noLinkCopy.get(l.getSrc()); |
if (subset == null || (sourceCopy != null && sourceCopy.contains(l.getField().getName()))) { |
assert l.getDest() != null; |
final SQLRowValues destCopy = noLinkCopy.get(l.getDest()); |
final Object dest; |
if (destCopy != null) |
dest = destCopy; |
else if (allowSameGraph) |
dest = l.getDest(); |
else if (l.getDest().hasID()) |
dest = l.getDest().getIDNumber(); |
else |
dest = null; |
if (dest != null) { |
sourceCopy.put(l.getField().getName(), dest); |
} else { |
assert noLinkCopy.containsKey(l.getSrc()); |
// ForeignCopyMode.COPY_ID_OR_RM like pruneWithoutCopy() (avoids |
// leaving nulls) |
sourceCopy.remove(l.getField().getName()); |
} |
} |
} else { |
assert subset != null || noLinkCopy.containsKey(l.getSrc()); |
} |
} |
final SQLRowValues res = noLinkCopy.values().iterator().next(); |
// only force graph creation if needed |
356,6 → 423,7 |
if (freeze) |
res.getGraph().freeze(); |
assert res.isFrozen() == freeze; |
assert allowSameGraph || res.getGraph() != this; |
return noLinkCopy; |
} |
896,10 → 964,12 |
return pruneMap(start, graph, keepUnionOfFields).get(start); |
} |
// private since result isn't trimmed, the values are still all there, not all in the pruned |
// graph |
private final Map<SQLRowValues, SQLRowValues> pruneMap(final SQLRowValues start, final SQLRowValues graph, final boolean keepUnionOfFields) { |
public final Map<SQLRowValues, SQLRowValues> pruneMap(final SQLRowValues start, final SQLRowValues graph, final boolean keepUnionOfFields) { |
this.containsCheck(start); |
return this.copy(computeToRetain(start, graph, keepUnionOfFields), false, false); |
} |
static SetMap<SQLRowValues, String> computeToRetain(final SQLRowValues start, final SQLRowValues graph, final boolean keepUnionOfFields) { |
if (!start.getTable().equals(graph.getTable())) |
throw new IllegalArgumentException(start + " is not from the same table as " + graph); |
// there's no way to tell apart 2 referents |
906,9 → 976,6 |
if (!graph.getGraph().hasOneRowPerPath()) |
throw new IllegalArgumentException("More than one row for " + graph.printGraph()); |
final Map<SQLRowValues, SQLRowValues> map = start.getGraph().deepCopy(false); |
final SQLRowValues res = map.get(start); |
final SetMap<SQLRowValues, String> toRetain = new SetMap<SQLRowValues, String>(new IdentityHashMap<SQLRowValues, Set<String>>(), Mode.NULL_FORBIDDEN); |
// BREADTH_FIRST to stop as soon as this no longer have rows in the graph |
// CycleAllowed since we need to go through every path (e.g. what is a cycle in graph might |
921,7 → 988,7 |
public Object transformChecked(State<Object> input) { |
final SQLRowValues r = input.getCurrent(); |
// since we allowed cycles in graph, allow it here |
final Collection<SQLRowValues> rows = res.followPath(input.getPath(), CreateMode.CREATE_NONE, false, true); |
final Collection<SQLRowValues> rows = start.followPath(input.getPath(), CreateMode.CREATE_NONE, false, true); |
// since we're using BREADTH_FIRST, the next path will be longer so no need to |
// continue if there's already no row |
if (rows.isEmpty()) |
935,7 → 1002,18 |
return null; |
} |
}, walkOptions); |
return toRetain; |
} |
public final SQLRowValues pruneWithoutCopy(final SQLRowValues start, final SQLRowValues graph) { |
return this.pruneWithoutCopy(start, graph, true); |
} |
public final SQLRowValues pruneWithoutCopy(final SQLRowValues start, final SQLRowValues graph, final boolean keepUnionOfFields) { |
this.containsCheck(start); |
final SetMap<SQLRowValues, String> toRetain = computeToRetain(start, graph, keepUnionOfFields); |
assert toRetain.containsKey(start); |
// remove extra fields and flatten if necessary |
for (final Entry<SQLRowValues, Set<String>> e : toRetain.entrySet()) { |
final SQLRowValues r = e.getKey(); |
952,7 → 1030,7 |
} |
} |
// now, remove referents that aren't in the graph |
for (final SQLRowValues r : new ArrayList<SQLRowValues>(res.getGraph().getItems())) { |
for (final SQLRowValues r : new ArrayList<SQLRowValues>(start.getGraph().getItems())) { |
if (!toRetain.containsKey(r)) { |
// only remove links at the border and even then, only remove links to the result : |
// avoid creating a myriad of graphs |
966,44 → 1044,53 |
r.removeAll(toFlatten); |
} |
} |
assert res.getGraph().getItems().equals(toRetain.keySet()); |
return map; |
assert start.getGraph().getItems().equals(toRetain.keySet()); |
// NOTE this instance no longer the graph of start if referents were removed |
return start; |
} |
// TODO handle referents (and decide how to handle multiple paths to the same node) |
final void grow(final SQLRowValues start, final SQLRowValues toGrow, final boolean checkFields) { |
final void grow(final SQLRowValues start, final SQLRowValues toGrow, final boolean checkFields, final boolean growUndefined) { |
this.containsCheck(start); |
if (!start.getTable().equals(toGrow.getTable())) |
throw new IllegalArgumentException(start + " is not from the same table as " + toGrow); |
this.walk(start, null, new ITransformer<State<Object>, Object>() { |
this.walk(start, toGrow, new ITransformer<State<SQLRowValues>, SQLRowValues>() { |
@Override |
public Object transformChecked(State<Object> input) { |
public SQLRowValues transformChecked(State<SQLRowValues> input) { |
final SQLRowValues existing = toGrow.followPath(input.getPath()); |
// don't add undefined row if there's none or if don't want |
if (existing == null && input.getAcc().isForeignEmpty(input.getFrom().getName()) && (input.getPath().getLast().getUndefinedIDNumber() == null || !growUndefined)) |
throw new StopRecurseException().setCompletely(false); |
if (existing == null || (checkFields && !existing.getFields().containsAll(input.getCurrent().getFields()))) { |
final SQLRowValues leaf = toGrow.assurePath(input.getPath()); |
if (leaf.hasID()) { |
final SQLRowValuesListFetcher fetcher = new SQLRowValuesListFetcher(input.getCurrent()); |
// don't exclude undef otherwise cannot grow eg |
// LOCAL.ID_FAMILLE_2 = 1 |
if (growUndefined) { |
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() { |
@Override |
public SQLSelect transformChecked(SQLSelect input) { |
// don't exclude undef otherwise cannot grow eg |
// LOCAL.ID_FAMILLE_2 = 1 |
input.setExcludeUndefined(false); |
return input; |
} |
}); |
} |
final SQLRowValues fetched = fetcher.fetchOne(leaf.getIDNumber()); |
if (fetched == null) |
throw new IllegalArgumentException("no row for " + fetcher); |
leaf.load(fetched, null); |
} else |
// we already loaded all further rows |
throw new StopRecurseException().setCompletely(false); |
} else { |
throw new IllegalArgumentException("cannot expand, missing ID in " + leaf + " at " + input.getPath()); |
} |
return null; |
} else { |
return existing; |
} |
}, RecursionType.BREADTH_FIRST); |
} |
}, RecursionType.BREADTH_FIRST, Direction.FOREIGN); |
} |
public final String contains(final SQLRowValues start, SQLRowValues graph) { |
return this.contains(start, graph, true); |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLBackgroundTableCacheItem.java |
---|
17,25 → 17,33 |
import java.util.Collections; |
import java.util.List; |
public class SQLBackgroundTableCacheItem implements SQLTableModifiedListener { |
public class SQLBackgroundTableCacheItem { |
private SQLTable table; |
private int timeout; |
private List<SQLRow> rows = new ArrayList<SQLRow>(); |
private long lastReload;// time in millis |
private boolean enableReloadIfTableModified = true; |
public SQLBackgroundTableCacheItem(final SQLTable t, final int second) { |
this.table = t; |
this.timeout = second; |
this.table.addTableModifiedListener(new SQLTableModifiedListener() { |
} |
@Override |
public void tableModified(SQLTableEvent evt) { |
this.lastReload = 0; |
if (enableReloadIfTableModified) { |
lastReload = 0; |
} |
reloadFromDbIfNeeded(); |
} |
}); |
} |
public void setEnableReloadIfTableModified(boolean enableReloadIfTableModified) { |
this.enableReloadIfTableModified = enableReloadIfTableModified; |
} |
@SuppressWarnings("unchecked") |
public synchronized void reloadFromDbIfNeeded() { |
final long delta = System.currentTimeMillis() - this.lastReload; |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRequestLog.java |
---|
14,6 → 14,7 |
package org.openconcerto.sql.model; |
import org.openconcerto.sql.Log; |
import org.openconcerto.ui.FontUtils; |
import org.openconcerto.utils.ExceptionUtils; |
import java.awt.BorderLayout; |
237,7 → 238,8 |
JFrame f = new JFrame("SQL monitoring"); |
final SQLRequestLogModel model = new SQLRequestLogModel(); |
final JTable table = new JTable(model); |
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()); |
table.setRowHeight(FontUtils.getPreferredRowHeight(table)); |
final TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel()); |
table.setRowSorter(sorter); |
table.getTableHeader().setReorderingAllowed(false); |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRow.java |
---|
280,9 → 280,14 |
return this.fetched; |
} |
private Map<String, Object> getValues() { |
@Override |
protected void initValues() { |
if (!this.isFilled()) |
this.fetchValues(); |
} |
private Map<String, Object> getValues() { |
this.initValues(); |
return this.values; |
} |
326,6 → 331,12 |
return this.fetched ? Collections.unmodifiableSet(this.getValues().keySet()) : Collections.<String> emptySet(); |
} |
// avoid Collections.unmodifiableSet() allocation |
@Override |
public boolean contains(String fieldName) { |
return this.fetched ? this.getValues().containsKey(fieldName) : false; |
} |
private String getQuery() { |
return "SELECT * FROM " + this.getTable().getSQLName().quote() + " WHERE " + this.getWhere().getClause(); |
} |
994,6 → 1005,12 |
return this.getTable().getName() + "[" + this.ID + "]"; |
} |
@Override |
public String mapToString() { |
final String result = this.fullToString(false) + " : "; |
return result + (this.values != null ? this.values : (this.isFilled() ? "not in DB" : "not filled")); |
} |
/** |
* Renvoie tous les champs de cette ligne, clef comprises. En général on ne veut pas les valeurs |
* des clefs, voir getAllValues(). |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLRowValues.java |
---|
330,6 → 330,10 |
return this.getGraph().deepCopy(this, false); |
} |
public final SQLRowValues copy(final SQLRowValues graph) { |
return this.getGraph().copy(this, graph).get(this); |
} |
/** |
* Get a frozen version of this. If not already {@link #isFrozen() frozen}, copy this rowValues |
* and all others connected to it and {@link SQLRowValuesCluster#freeze()} the copy. I.e. if the |
433,10 → 437,24 |
} |
public final SQLRowValues prune(SQLRowValues graph) { |
return this.getGraph().prune(this, graph); |
return this.prune(graph, true); |
} |
/** |
* Prune this graph. |
* |
* @param graph the rows and fields to keep. |
* @param copy <code>true</code> if a pruned copy should be returned, <code>false</code> to |
* modify this instance in-place. |
* @return a graph no bigger than the passed parameter. |
* @see SQLRowValuesCluster#prune(SQLRowValues, SQLRowValues, boolean) |
* @see SQLRowValuesCluster#pruneWithoutCopy(SQLRowValues, SQLRowValues, boolean) |
*/ |
public final SQLRowValues prune(SQLRowValues graph, final boolean copy) { |
return copy ? this.getGraph().prune(this, graph) : this.getGraph().pruneWithoutCopy(this, graph); |
} |
/** |
* Fetch if necessary and store in this the foreign row. |
* |
* @param fk a foreign key, eg "ID_FAMILLE_2". |
469,7 → 487,11 |
* @throws IllegalArgumentException if this couldn't be grown. |
*/ |
public final SQLRowValues grow(SQLRowValues graph, final boolean checkFields) { |
graph.getGraph().grow(graph, this, checkFields); |
return this.grow(graph, checkFields, false); |
} |
public final SQLRowValues grow(SQLRowValues graph, final boolean checkFields, final boolean growUndefined) { |
graph.getGraph().grow(graph, this, checkFields, growUndefined); |
return this; |
} |
768,7 → 790,13 |
return Collections.unmodifiableSet(this.values.keySet()); |
} |
// avoid Collections.unmodifiableSet() allocation |
@Override |
public boolean contains(String fieldName) { |
return this.values.containsKey(fieldName); |
} |
@Override |
public final SQLRow asRow() { |
if (!this.hasID()) |
throw new IllegalStateException(this + " has no ID"); |
1823,7 → 1851,7 |
} else { |
// check that the foreign key is complete |
for (final String ff : foreignLink.getCols()) { |
if (!this.getFields().contains(ff)) |
if (!this.contains(ff)) |
return new Object[] { ff, null }; |
} |
foreignLinks.keySet().removeAll(foreignLink.getCols()); |
1998,6 → 2026,11 |
*/ |
@Override |
public String toString() { |
return mapToString(); |
} |
@Override |
public String mapToString() { |
String result = this.getClass().getSimpleName() + " on " + this.getTable() + " : {"; |
result += CollectionUtils.join(this.values.entrySet(), ", ", new ITransformer<Entry<String, ?>, String>() { |
public String transformChecked(final Entry<String, ?> e) { |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/graph/Path.java |
---|
465,4 → 465,15 |
return this.getLast() == other.getLast(); |
return thisL >= otherL && this.subPath(thisL - otherL, thisL).equals(other); |
} |
public final Path getCommonPath(final Path other) { |
if (other.getFirst() != this.getFirst()) |
throw new IllegalArgumentException("Not the same starting point"); |
final int equalsCount = CollectionUtils.equalsFromStart(this.steps, other.steps); |
// avoid allocation |
if (equalsCount == other.length()) |
return other; |
else |
return this.subPath(0, equalsCount); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/users/User.java |
---|
28,7 → 28,7 |
this.name = r.getString("NOM").trim(); |
this.firstName = r.getString("PRENOM").trim(); |
this.nickName = r.getString("SURNOM").trim(); |
if (r.getFields().contains("DISABLED")) { |
if (r.contains("DISABLED")) { |
this.active = !r.getBoolean("DISABLED"); |
} else { |
this.active = null; |
/trunk/OpenConcerto/src/org/openconcerto/sql/users/UserCommonSQLElement.java |
---|
93,7 → 93,7 |
this.familyNameFirst = false; |
} |
public UserCommonSQLElement(DBRoot root, final boolean familyNameFirst) { |
public UserCommonSQLElement(final DBRoot root, final boolean familyNameFirst) { |
super(root.findTable("USER_COMMON")); |
this.familyNameFirst = familyNameFirst; |
} |
119,7 → 119,7 |
} |
@Override |
protected synchronized void _initTableSource(SQLTableModelSource res) { |
protected synchronized void _initTableSource(final SQLTableModelSource res) { |
super._initTableSource(res); |
// current user in bold |
for (final SQLTableModelColumn col : res.getColumns()) { |
126,7 → 126,7 |
if (col.getValueClass().equals(String.class)) { |
col.setRenderer(new DefaultTableCellRenderer() { |
@Override |
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) { |
final JLabel res = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); |
final boolean isCurrentUser = ITableModel.getLine(table.getModel(), row).getRow().getID() == UserManager.getUserID(); |
final int targetStyle = isCurrentUser ? Font.BOLD : Font.PLAIN; |
154,7 → 154,7 |
} |
@Override |
protected void _initComboRequest(ComboSQLRequest req) { |
protected void _initComboRequest(final ComboSQLRequest req) { |
super._initComboRequest(req); |
req.setFieldSeparator(" "); |
} |
189,7 → 189,7 |
this.accessSocieteElem = t == null ? null : getDirectory().getElement(t); |
} |
protected UserSQLComponent(SQLElement element) { |
protected UserSQLComponent(final SQLElement element) { |
super(element); |
} |
333,7 → 333,7 |
} |
if (getTable().contains("OUT")) { |
c.gridx++; |
JCheckBox boxOut = new JCheckBox(getLabelFor("OUT")); |
final JCheckBox boxOut = new JCheckBox(getLabelFor("OUT")); |
c.gridwidth = 1; |
c.weightx = 1; |
c.gridwidth = GridBagConstraints.REMAINDER; |
342,7 → 342,7 |
} else { |
if (getTable().contains("DISABLED")) { |
c.gridx++; |
JCheckBox boxDisabled = new JCheckBox(getLabelFor("DISABLED")); |
final JCheckBox boxDisabled = new JCheckBox(getLabelFor("DISABLED")); |
c.gridwidth = 1; |
c.weightx = 1; |
c.gridwidth = GridBagConstraints.REMAINDER; |
353,11 → 353,11 |
c.gridy++; |
if (getTable().contains("TEL")) { |
c.gridx = 0; |
JLabel labelTel = new JLabel(getLabelFor("TEL")); |
final JLabel labelTel = new JLabel(getLabelFor("TEL")); |
c.gridwidth = 1; |
c.weightx = 0; |
this.add(labelTel, c); |
JTextField fieldTel = new JTextField(20); |
final JTextField fieldTel = new JTextField(20); |
c.gridx++; |
c.weightx = 1; |
this.add(fieldTel, c); |
365,7 → 365,7 |
} |
if (getTable().contains("CALENDAR_USER")) { |
c.gridx = 2; |
JCheckBox boxCalUser = new JCheckBox(getLabelFor("CALENDAR_USER")); |
final JCheckBox boxCalUser = new JCheckBox(getLabelFor("CALENDAR_USER")); |
c.weightx = 1; |
c.gridwidth = GridBagConstraints.REMAINDER; |
this.add(boxCalUser, c); |
372,12 → 372,12 |
this.addView(boxCalUser, "CALENDAR_USER"); |
} |
boolean gestionHoraire = false; |
final boolean gestionHoraire = false; |
if (Configuration.getInstance().getAppName().startsWith("OpenConcerto") && gestionHoraire) { |
c.gridwidth = 1; |
JPanel panelHoraires = new JPanel(new GridBagLayout()); |
GridBagConstraints cH = new DefaultGridBagConstraints(); |
final JPanel panelHoraires = new JPanel(new GridBagLayout()); |
final GridBagConstraints cH = new DefaultGridBagConstraints(); |
createHalfDay(panelHoraires, cH, "Matin :", "MATIN", 8, 12); |
createHalfDay(panelHoraires, cH, "Après midi :", "MIDI", 13, 17); |
398,8 → 398,8 |
this.add(new JLabelBold("Accés aux sociétés"), c); |
c.gridy++; |
noCompanyLimitCheckBox = new JCheckBox("ne pas limiter l'accès à certaines sociétés"); |
this.add(noCompanyLimitCheckBox, c); |
this.noCompanyLimitCheckBox = new JCheckBox("ne pas limiter l'accès à certaines sociétés"); |
this.add(this.noCompanyLimitCheckBox, c); |
c.gridy++; |
c.weighty = 1; |
411,22 → 411,22 |
this.table = new QuickAssignPanel(companyElement, "ID", model); |
this.add(this.table, c); |
noCompanyLimitCheckBox.addItemListener(new ItemListener() { |
this.noCompanyLimitCheckBox.addItemListener(new ItemListener() { |
@Override |
public void itemStateChanged(ItemEvent e) { |
table.setEnabled(e.getStateChange() == ItemEvent.DESELECTED); |
public void itemStateChanged(final ItemEvent e) { |
UserSQLComponent.this.table.setEnabled(e.getStateChange() == ItemEvent.DESELECTED); |
} |
}); |
getView("ADMIN").addValueListener(new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
public void propertyChange(final PropertyChangeEvent evt) { |
final boolean selected = evt.getNewValue() == Boolean.TRUE; |
noCompanyLimitCheckBox.setEnabled(!selected); |
UserSQLComponent.this.noCompanyLimitCheckBox.setEnabled(!selected); |
if (selected) |
noCompanyLimitCheckBox.setSelected(true); |
UserSQLComponent.this.noCompanyLimitCheckBox.setSelected(true); |
} |
}); |
noCompanyLimitCheckBox.setSelected(true); |
this.noCompanyLimitCheckBox.setSelected(true); |
} |
this.addRequiredSQLObject(textLogin, "LOGIN"); |
443,7 → 443,7 |
this.getPassField().getDocument().addDocumentListener(new SimpleDocumentListener() { |
@Override |
public void update(DocumentEvent e) { |
public void update(final DocumentEvent e) { |
updateEncrypted(); |
fireValidChange(); |
} |
450,7 → 450,7 |
}); |
this.getPassFieldConfirm().getDocument().addDocumentListener(new SimpleDocumentListener() { |
@Override |
public void update(DocumentEvent e) { |
public void update(final DocumentEvent e) { |
fireValidChange(); |
} |
}); |
463,7 → 463,7 |
// après midi arrivée 13:30 |
// __________ départ 17:53 |
private void createHalfDay(JPanel panelHoraires, GridBagConstraints cH, String label, String field, int startHour, int endHour) { |
private void createHalfDay(final JPanel panelHoraires, final GridBagConstraints cH, final String label, final String field, final int startHour, final int endHour) { |
panelHoraires.add(new JLabel(label), cH); |
cH.gridx++; |
createTime(panelHoraires, cH, "arrivée", field + "_A", startHour); |
475,7 → 475,7 |
} |
// départ 17:53 |
private void createTime(JPanel panelHoraires, GridBagConstraints cH, String label, String field, int hour) { |
private void createTime(final JPanel panelHoraires, final GridBagConstraints cH, final String label, final String field, final int hour) { |
panelHoraires.add(new JLabel(label), cH); |
cH.gridx++; |
487,9 → 487,9 |
} |
// 17 h or 53 min |
private ISpinner createSpinner(JPanel panelHoraires, GridBagConstraints cH, final boolean hour, int value) { |
ISpinnerIntegerModel modelHourMA = new ISpinnerIntegerModel(0, hour ? 23 : 59, value); |
ISpinner spinHourMA = new ISpinner(modelHourMA); |
private ISpinner createSpinner(final JPanel panelHoraires, final GridBagConstraints cH, final boolean hour, final int value) { |
final ISpinnerIntegerModel modelHourMA = new ISpinnerIntegerModel(0, hour ? 23 : 59, value); |
final ISpinner spinHourMA = new ISpinner(modelHourMA); |
panelHoraires.add(spinHourMA.getComp(), cH); |
cH.gridx++; |
panelHoraires.add(new JLabel(hour ? "h" : "min"), cH); |
520,8 → 520,8 |
// so that this.encryptedPass (which will be updated by updateEncrypted() and thus |
// have a bogus value) will be changed to its database value and thus the user can |
// update any field without changing the password. |
if (table != null) { |
table.getModel().clearRows(); |
if (this.table != null) { |
this.table.getModel().clearRows(); |
} |
if (row != null) { |
final String bogusPass = "bogusPass!"; |
530,23 → 530,23 |
// Allowed companies |
if (this.accessSocieteElem != null) { |
final SQLTable tableCompanyAccess = this.accessSocieteElem.getTable(); |
SQLRowValues graph = new SQLRowValues(tableCompanyAccess); |
final SQLRowValues graph = new SQLRowValues(tableCompanyAccess); |
graph.put("ID", null); |
graph.putRowValues("ID_SOCIETE_COMMON").put("NOM", null); |
SQLRowValuesListFetcher f = new SQLRowValuesListFetcher(graph); |
final SQLRowValuesListFetcher f = new SQLRowValuesListFetcher(graph); |
f.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() { |
@Override |
public SQLSelect transformChecked(SQLSelect input) { |
public SQLSelect transformChecked(final SQLSelect input) { |
input.setWhere(new Where(tableCompanyAccess.getField("ID_USER_COMMON"), "=", row.getID())); |
return input; |
} |
}); |
List<SQLRowValues> companies = f.fetch(); |
final List<SQLRowValues> companies = f.fetch(); |
for (SQLRowValues r : companies) { |
table.getModel().addRow(r.getForeign("ID_SOCIETE_COMMON").asRowValues()); |
for (final SQLRowValues r : companies) { |
this.table.getModel().addRow(r.getForeign("ID_SOCIETE_COMMON").asRowValues()); |
} |
noCompanyLimitCheckBox.setSelected(companies.isEmpty()); |
this.noCompanyLimitCheckBox.setSelected(companies.isEmpty()); |
} |
} |
super.select(row); |
561,17 → 561,17 |
return id; |
} |
private void insertCompanyAccessForUser(int id) { |
private void insertCompanyAccessForUser(final int id) { |
final SQLTable tableCompanyAccess = this.getDirectory().getElement("ACCES_SOCIETE").getTable(); |
int stop = table.getModel().getRowCount(); |
final int stop = this.table.getModel().getRowCount(); |
for (int i = 0; i < stop; i++) { |
SQLRowValues rCompany = table.getModel().getRowValuesAt(i); |
SQLRowValues rAccess = new SQLRowValues(tableCompanyAccess); |
final SQLRowValues rCompany = this.table.getModel().getRowValuesAt(i); |
final SQLRowValues rAccess = new SQLRowValues(tableCompanyAccess); |
rAccess.put("ID_USER_COMMON", id); |
rAccess.put("ID_SOCIETE_COMMON", rCompany.getID()); |
try { |
rAccess.commit(); |
} catch (SQLException e) { |
} catch (final SQLException e) { |
ExceptionHandler.handle("Unable to store company access", e); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/changer/convert/MergeRows.java |
---|
107,7 → 107,7 |
} |
protected boolean isEqualValue(final SQLRowAccessor r1, final SQLRowAccessor r2, final String f, final boolean nonEmpty) { |
if (!r1.getFields().contains(f) || !r2.getFields().contains(f)) |
if (!r1.contains(f) || !r2.contains(f)) |
throw new IllegalStateException("Missing " + f); |
final Object normalized1 = normalize(f, r1.getObject(f)); |
final Object normalized2 = normalize(f, r2.getObject(f)); |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/EditFrame.java |
---|
14,6 → 14,7 |
package org.openconcerto.sql.view; |
import static org.openconcerto.sql.TM.getTM; |
import org.openconcerto.sql.element.BaseSQLComponent; |
import org.openconcerto.sql.element.SQLComponent; |
import org.openconcerto.sql.element.SQLElement; |
197,8 → 198,8 |
} |
/** |
* Redimensionne la frame pour qu'elle soit de taille maximum sans déborder de l'écran. <img |
* src="doc-files/resizeFrame.png"/> |
* Redimensionne la frame pour qu'elle soit de taille maximum sans déborder de l'écran. |
* <img src="doc-files/resizeFrame.png"/> |
*/ |
protected void viewResized() { |
if (!this.frameResize) { |
274,4 → 275,9 |
public boolean isDocTransversable() { |
return true; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName() + " " + this.getTitle() + " : " + super.toString(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/save.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/IListPanel.java |
---|
31,7 → 31,10 |
import org.openconcerto.sql.users.rights.UserRightsManager; |
import org.openconcerto.sql.view.list.IListe; |
import org.openconcerto.sql.view.list.IListeAction; |
import org.openconcerto.sql.view.list.IListeAction.IListeEvent; |
import org.openconcerto.sql.view.list.ITableModel; |
import org.openconcerto.sql.view.list.RowAction; |
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction; |
import org.openconcerto.sql.view.search.SearchListComponent; |
import org.openconcerto.ui.ContinuousButtonModel; |
import org.openconcerto.ui.FrameUtil; |
38,6 → 41,7 |
import org.openconcerto.ui.SwingThreadUtils; |
import org.openconcerto.ui.component.JRadioButtons.JStringRadioButtons; |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.FileUtils; |
import org.openconcerto.utils.StringUtils; |
import org.openconcerto.utils.Tuple2; |
import org.openconcerto.utils.Tuple2.List2; |
57,9 → 61,6 |
import java.awt.event.ActionListener; |
import java.awt.event.HierarchyEvent; |
import java.awt.event.HierarchyListener; |
import java.awt.event.InputEvent; |
import java.awt.event.MouseAdapter; |
import java.awt.event.MouseEvent; |
import java.beans.PropertyChangeEvent; |
import java.beans.PropertyChangeListener; |
import java.io.File; |
73,6 → 74,7 |
import java.util.Set; |
import java.util.prefs.Preferences; |
import javax.swing.AbstractAction; |
import javax.swing.BorderFactory; |
import javax.swing.Icon; |
import javax.swing.ImageIcon; |
119,6 → 121,36 |
return new File(structFile, c.getSimpleName() + File.separator + IListFrame.getConfigFileName(code)); |
} |
public static enum FrameMode { |
NO_FRAME, READ_ONLY_FRAME, READ_WRITE_FRAME; |
} |
public static final String TWO_X_SUFFIX = "_2x"; |
private static final String FLECHE_HAUT_PNG = "fleche_haut.png"; |
private static final String FLECHE_BAS_PNG = "fleche_bas.png"; |
private static final Icon UP_ARROW = getIcon(FLECHE_HAUT_PNG, false); |
private static final Icon UP_ARROW_2X = getIcon(FLECHE_HAUT_PNG, true); |
private static final Icon DOWN_ARROW = getIcon(FLECHE_BAS_PNG, false); |
private static final Icon DOWN_ARROW_2X = getIcon(FLECHE_BAS_PNG, true); |
static final String getResourceName(final String rsrcName, final boolean twoX) { |
if (!twoX) |
return rsrcName; |
final String extension = FileUtils.getExtension(rsrcName, true); |
if (extension == null) |
return rsrcName + TWO_X_SUFFIX; |
else |
return FileUtils.removeSuffix(rsrcName, extension) + TWO_X_SUFFIX + extension; |
} |
static final Icon getIcon(final String fileName, final boolean twoX) { |
return getIcon(IListPanel.class, fileName, twoX); |
} |
public static final Icon getIcon(final Class<?> clazz, final String fileName, final boolean twoX) { |
return new ImageIcon(clazz.getResource(getResourceName(fileName, twoX))); |
} |
private final IListe liste; |
protected final SQLElement element; |
135,9 → 167,6 |
private JButton buttonPlus; |
private JButton buttonMoins; |
protected final JPanel searchPanel = new JPanel(new GridBagLayout()); |
private static final Icon UP_ARROW = new ImageIcon(IListPanel.class.getResource("fleche_haut.png")); |
private static final Icon DOWN_ARROW = new ImageIcon(IListPanel.class.getResource("fleche_bas.png")); |
private static final JButton createBtn(Icon i) { |
final JButton res = new JButton(i); |
res.setMargin(new Insets(1, 1, 1, 1)); |
149,9 → 178,11 |
return res; |
} |
private final RowAction displayRowAction; |
protected EditFrame createFrame; |
private boolean selectRowOnAdd = true; |
private boolean showReadOnlyFrameOnDoubleClick = true; |
// NO_FRAME since at creation the action isn't added to our IListe |
private FrameMode showFrameOnDoubleClick = FrameMode.NO_FRAME; |
private boolean deaf = Boolean.getBoolean("org.openconcerto.sql.listPanel.deafEditPanel"); |
protected SearchListComponent searchComponent; |
209,6 → 240,32 |
} |
}); |
this.displayRowAction = new PredicateRowAction(new AbstractAction(TM.tr("display")) { |
private EditFrame listeningFrame = null; |
private final EditFrame createFrame(final boolean listening) { |
final EditFrame res = new EditFrame(getElement(), IListPanel.this.showFrameOnDoubleClick == FrameMode.READ_ONLY_FRAME ? EditPanel.READONLY : EditPanel.MODIFICATION); |
if (listening) |
getListe().addIListener(res); |
res.selectionId(getListe().getSelectedId()); |
return res; |
} |
@Override |
public void actionPerformed(ActionEvent e) { |
final EditFrame frame; |
if ((e.getModifiers() & ActionEvent.ALT_MASK) != 0) { |
if (this.listeningFrame == null) |
this.listeningFrame = createFrame(true); |
frame = this.listeningFrame; |
} else { |
frame = createFrame(false); |
} |
FrameUtil.show(frame); |
} |
}, false).setPredicate(IListeEvent.getSingleSelectionPredicate()); |
this.init(); |
} |
235,34 → 292,16 |
IListPanel.this.searchComponent.reset((ITableModel) evt.getNewValue()); |
} |
}); |
this.liste.getJTable().addMouseListener(new MouseAdapter() { |
// don't need to display in a separate frame, if it's already displayed in this panel |
final FrameMode m; |
if (this.modifyIsImmediate()) |
m = FrameMode.NO_FRAME; |
else if (Boolean.getBoolean("org.openconcerto.sql.listPanel.rwOnDoubleClick")) |
m = FrameMode.READ_WRITE_FRAME; |
else |
m = FrameMode.READ_ONLY_FRAME; |
this.setShowFrameOnDoubleClickMode(m); |
private EditFrame listeningFrame = null; |
private final EditFrame createFrame(final boolean listening) { |
Boolean rw = Boolean.getBoolean("org.openconcerto.sql.listPanel.rwOnDoubleClick"); |
final EditFrame res = new EditFrame(getElement(), !rw ? EditPanel.READONLY : EditPanel.MODIFICATION); |
if (listening) |
getListe().addIListener(res); |
res.selectionId(getListe().getSelectedId()); |
return res; |
} |
@Override |
public void mouseClicked(MouseEvent e) { |
if (IListPanel.this.showReadOnlyFrameOnDoubleClick && e.getClickCount() == 2) { |
final EditFrame frame; |
if ((e.getModifiersEx() & InputEvent.ALT_DOWN_MASK) != 0) { |
if (this.listeningFrame == null) |
this.listeningFrame = createFrame(true); |
frame = this.listeningFrame; |
} else { |
frame = createFrame(false); |
} |
FrameUtil.show(frame); |
} |
} |
}); |
// selectID() alone won't init us if NONEXISTANT_ID is already the selected id |
this.btnMngr.updateBtns(); |
this.getListe().selectID(SQLRow.NONEXISTANT_ID); |
303,15 → 342,19 |
} |
protected void createUI() { |
// int sca |
final boolean twoX = this.getFont().getSize() > 16; |
final int buttonSize = twoX ? 36 : 20; |
this.setOpaque(false); |
this.buttonActualiser = new JButton(new ImageIcon(IListPanel.class.getResource("reload.png"))); |
this.buttonActualiser = new JButton(getIcon("reload.png", twoX)); |
this.buttonActualiser.setBorderPainted(false); |
this.buttonActualiser.setFocusPainted(false); |
this.buttonActualiser.setOpaque(false); |
this.buttonActualiser.setContentAreaFilled(false); |
this.buttonActualiser.setMinimumSize(new Dimension(20, 20)); |
this.buttonActualiser.setPreferredSize(new Dimension(20, 20)); |
this.buttonActualiser.setMaximumSize(new Dimension(20, 20)); |
this.buttonActualiser.setMinimumSize(new Dimension(buttonSize, buttonSize)); |
this.buttonActualiser.setPreferredSize(new Dimension(buttonSize, buttonSize)); |
this.buttonActualiser.setMaximumSize(new Dimension(buttonSize, buttonSize)); |
this.searchComponent = new SearchListComponent(this.liste.getModel()); |
this.searchComponent.setFormats(this.liste.getSearchFormats()); |
329,17 → 372,18 |
this.btnMngr.addBtn(this.buttonClone, "noRightToClone", TableAllRights.ADD_ROW_TABLE, true, false); |
this.btnMngr.setOKToolTip(this.buttonClone, TM.tr("listPanel.cloneToolTip")); |
this.saveBtn = new JButton(new ImageIcon(IListPanel.class.getResource("save.png"))); |
this.saveBtn = new JButton(getIcon("save.png", twoX)); |
this.saveBtn.setFocusPainted(false); |
this.saveBtn.setOpaque(false); |
this.saveBtn.setContentAreaFilled(false); |
this.saveBtn.setBorderPainted(false); |
this.saveBtn.setMinimumSize(new Dimension(20, 20)); |
this.saveBtn.setPreferredSize(new Dimension(20, 20)); |
this.saveBtn.setMaximumSize(new Dimension(20, 20)); |
this.buttonMoins = createBtn(UP_ARROW); |
this.buttonPlus = createBtn(DOWN_ARROW); |
this.saveBtn.setMinimumSize(new Dimension(buttonSize, buttonSize)); |
this.saveBtn.setPreferredSize(new Dimension(buttonSize, buttonSize)); |
this.saveBtn.setMaximumSize(new Dimension(buttonSize, buttonSize)); |
this.buttonMoins = createBtn(twoX ? UP_ARROW_2X : UP_ARROW); |
this.buttonPlus = createBtn(twoX ? DOWN_ARROW_2X : DOWN_ARROW); |
// needSelection = false since we handle it with the transformer |
this.btnMngr.addBtn(this.buttonMoins, "noRightToReorder", TableAllRights.MODIFY_ROW_TABLE, false); |
this.btnMngr.addBtn(this.buttonPlus, "noRightToReorder", TableAllRights.MODIFY_ROW_TABLE, false); |
346,7 → 390,7 |
final ITransformer<JButton, String> transf = new ITransformer<JButton, String>() { |
@Override |
public String transformChecked(JButton input) { |
final boolean ok = getListe().hasSelection() && !getListe().isSorted(); |
final boolean ok = getListe().hasSelection() && !getListe().isSorted() && getListe().getSource().getReq().isTableOrder(); |
// keep them enabled when armed otherwise they will be disabled when used |
// since they refresh the list which in turn does a clearSelection() |
return input.getModel().isArmed() || ok ? null : TM.tr("listPanel.noSelectionOrSort"); |
792,10 → 836,21 |
this.getListe().getJTable().setDragEnabled(b); |
} |
@Deprecated |
public void setShowReadOnlyFrameOnDoubleClick(boolean showReadOnlyFrameOnDoubleClick) { |
this.showReadOnlyFrameOnDoubleClick = showReadOnlyFrameOnDoubleClick; |
this.setShowFrameOnDoubleClickMode(showReadOnlyFrameOnDoubleClick ? FrameMode.READ_ONLY_FRAME : FrameMode.NO_FRAME); |
} |
public void setShowFrameOnDoubleClickMode(FrameMode m) { |
if (this.showFrameOnDoubleClick != m) { |
this.showFrameOnDoubleClick = m; |
if (this.showFrameOnDoubleClick != FrameMode.NO_FRAME) |
this.liste.setDefaultRowAction(this.displayRowAction); |
else |
this.liste.removeIListeAction(this.displayRowAction); |
} |
} |
public void setAddVisible(boolean b) { |
this.buttonAjouter.setVisible(b); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/reload.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/IListButton.java |
---|
11,12 → 11,6 |
* When distributing the software, include this License Header Notice in each file. |
*/ |
/* |
* Created on 17 janv. 2005 |
* |
* TODO To change the template for this generated file go to Window - Preferences - Java - Code |
* Style - Code Templates |
*/ |
package org.openconcerto.sql.view; |
import java.awt.Dimension; |
24,17 → 18,10 |
import javax.swing.Action; |
import javax.swing.BorderFactory; |
import javax.swing.Icon; |
import javax.swing.ImageIcon; |
import javax.swing.JButton; |
/** |
* @author ilm |
* |
* TODO To change the template for this generated type comment go to Window - Preferences - |
* Java - Code Style - Code Templates |
*/ |
public class IListButton extends JButton { |
private static ImageIcon icon = null; |
public final class IListButton extends JButton { |
private static Icon icon = null; |
/** |
* |
79,10 → 66,11 |
private final void init() { |
if (icon == null) { |
icon = new ImageIcon(getClass().getResource("liste.png")); |
icon = IListPanel.getIcon("liste.png", getFont().getSize() > 16); |
} |
setIcon(icon); |
setPreferredSize(new Dimension(24, 16)); |
setMinimumSize(new Dimension(icon.getIconWidth() + 8, icon.getIconHeight())); |
setPreferredSize(new Dimension(icon.getIconWidth() + 8, icon.getIconHeight())); |
initButton(this); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/fleche_haut_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/fleche_haut_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/fleche_bas_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/fleche_bas_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/ListSQLLine.java |
---|
22,6 → 22,7 |
import org.openconcerto.sql.model.graph.Path; |
import org.openconcerto.sql.view.list.search.SearchQueue; |
import org.openconcerto.utils.CollectionUtils; |
import org.openconcerto.utils.NumberUtils; |
import java.util.ArrayList; |
import java.util.Collection; |
127,6 → 128,30 |
return this.src.compare(this, o); |
} |
static final int compareLikeRequest(final ListSQLLine l1, final ListSQLLine l2) { |
if (l1 == l2) |
return 0; |
if (l1.getState() != l2.getState()) |
throw new IllegalArgumentException("Different states"); |
final Number order1, order2; |
final SQLTableModelLinesSource src = l1.getSrc(); |
// avoid comparing in the middle of a reordering |
synchronized (src.getModel().getUpdateQ().getFullList()) { |
order1 = l1.getOrder(); |
order2 = l2.getOrder(); |
} |
if (order1 != null) { |
if (order2 == null) |
throw new IllegalStateException("Order mismatch :\n" + order1 + " for " + l1 + " not coherent with\n" + order2 + " for " + l2); |
return NumberUtils.compare(order1, order2); |
} else { |
if (order2 != null) |
throw new IllegalStateException("Order mismatch :\n" + order1 + " for " + l1 + " not coherent with\n" + order2 + " for " + l2); |
return l1.getState().getReq().order(l1.getRow(), l2.getRow()); |
} |
} |
public int getID() { |
return this.id; |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/SQLTableModelLinesSource.java |
---|
24,6 → 24,7 |
import java.beans.PropertyChangeListener; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Comparator; |
import java.util.List; |
import java.util.concurrent.Future; |
31,6 → 32,7 |
public abstract class SQLTableModelLinesSource { |
private final ITableModel model; |
private final PropertyChangeListener reqListener; |
private final List<PropertyChangeListener> listeners; |
private IPredicate<SQLRowValues> filter; |
41,9 → 43,20 |
protected SQLTableModelLinesSource(final ITableModel model) { |
this.model = model; |
this.reqListener = new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
fireChanged(evt); |
} |
}; |
} |
void live() { |
this.getParent().getReq().addWhereListener(this.reqListener); |
} |
void die() { |
this.getParent().getReq().rmWhereListener(this.reqListener); |
} |
public final ITableModel getModel() { |
67,8 → 80,26 |
*/ |
public abstract Value<ListSQLLine> get(final int id); |
public abstract int compare(ListSQLLine l1, ListSQLLine l2); |
/** |
* Implementations should only use state of the parameters, so that this method can be |
* thread-safe (it is called both by the {@link UpdateQueue} and by the EDT in |
* {@link ITableModel}). This implementation order lines like the source {@link ListSQLRequest |
* request}. |
* |
* @param l1 the first line. |
* @param l2 the second line. |
* @return a negative integer, zero, or a positive integer as this object is less than, equal |
* to, or greater than the specified object. |
* @see Comparator#compare(Object, Object) |
*/ |
public int compare(ListSQLLine l1, ListSQLLine l2) { |
return ListSQLLine.compareLikeRequest(l1, l2); |
} |
public boolean isCellEditable(ListSQLLine line, int colIndex, SQLTableModelColumn col) { |
return true; |
} |
public abstract Future<?> moveBy(final List<? extends SQLRowAccessor> rows, final int inc); |
// take IDs : |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/SQLTableModelLinesSourceOffline.java |
---|
24,15 → 24,14 |
import org.openconcerto.sql.model.graph.Path; |
import org.openconcerto.sql.utils.SQLUtils; |
import org.openconcerto.utils.CompareUtils; |
import org.openconcerto.utils.NumberUtils; |
import org.openconcerto.utils.SetMap; |
import org.openconcerto.utils.Value; |
import org.openconcerto.utils.cc.IClosure; |
import org.openconcerto.utils.cc.ITransformerExn; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Collections; |
import java.util.Comparator; |
import java.util.HashMap; |
import java.util.HashSet; |
import java.util.LinkedHashMap; |
45,7 → 44,6 |
import java.util.concurrent.CopyOnWriteArrayList; |
import java.util.concurrent.Future; |
import java.util.concurrent.FutureTask; |
import java.util.concurrent.atomic.AtomicReference; |
import net.jcip.annotations.NotThreadSafe; |
59,7 → 57,7 |
// row container with equals() using reference equality |
@NotThreadSafe |
static private final class Row { |
static public final class Row { |
private final Integer id; |
private SQLRowValues vals; |
77,7 → 75,7 |
return this.vals; |
} |
public final void setRow(SQLRowValues newVals) { |
final void setRow(SQLRowValues newVals) { |
if (!newVals.isFrozen()) |
throw new IllegalArgumentException("Not frozen : " + newVals); |
this.vals = newVals; |
138,10 → 136,15 |
return this.parent; |
} |
private synchronized boolean checkUpdateThread() { |
private boolean isUpdateThread() { |
return this.getModel().getUpdateQ().currentlyInQueue(); |
} |
private void checkUpdateThread() { |
if (!this.isUpdateThread()) |
throw new IllegalStateException("Not in the update thread"); |
} |
private final Row getRow(Integer id) { |
return this.getRow(id, false); |
} |
157,6 → 160,16 |
return res; |
} |
public final Row getRowNow(Integer id, final boolean required) { |
checkUpdateThread(); |
return this.getRow(id, required); |
} |
public final List<Row> getRowsNow() { |
checkUpdateThread(); |
return Collections.unmodifiableList(this.lines); |
} |
protected final int getSize() { |
return this.lines.size(); |
} |
181,7 → 194,7 |
} |
private final boolean setDBOrder(final boolean dbOrder) { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
if (this.dbOrder != dbOrder) { |
this.dbOrder = dbOrder; |
return true; |
206,38 → 219,6 |
return res; |
} |
/** |
* Compare 2 lines. Only use state of the parameters, so this method is thread-safe. |
* |
* @param l1 the first line. |
* @param l2 the second line. |
* @return a negative integer, zero, or a positive integer as this object is less than, equal |
* to, or greater than the specified object. |
* @see Comparator#compare(Object, Object) |
*/ |
@Override |
public int compare(ListSQLLine l1, ListSQLLine l2) { |
if (l1 == l2) |
return 0; |
final Number order1, order2; |
final SQLTableModelLinesSource src = l1.getSrc(); |
// avoid comparing in the middle of a reordering |
synchronized (src.getModel().getUpdateQ().getFullList()) { |
order1 = l1.getOrder(); |
order2 = l2.getOrder(); |
} |
if (order1 != null) { |
if (order2 == null) |
throw new IllegalStateException("Order mismatch :\n" + order1 + " for " + l1 + " not coherent with\n" + order2 + " for " + l2); |
return NumberUtils.compare(order1, order2); |
} else { |
if (order2 != null) |
throw new IllegalStateException("Order mismatch :\n" + order1 + " for " + l1 + " not coherent with\n" + order2 + " for " + l2); |
return OrderComparator.INSTANCE.compare(l1.getRow(), l2.getRow()); |
} |
} |
protected final List<SQLRowValues> fetch() { |
return this.getUpdateQueueReq().getValues(); |
} |
251,7 → 232,7 |
*/ |
@Override |
public List<ListSQLLine> getAll() { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
final List<SQLRowValues> dbRows = this.fetch(); |
if (this.lines.isEmpty()) { |
312,32 → 293,57 |
*/ |
@Override |
public Value<ListSQLLine> get(final int id) { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
return updateRow(id, this.getUpdateQueueReq().getValues(id)); |
} |
// *** Modify virtual rows *** |
private final <T> Future<T> execInUpdateQ(final OfflineCallable<T> call) { |
return this.getModel().getUpdateQ().execute(new FutureTask<T>(call)); |
} |
public final Future<Number> add(final SQLRowValues vals) { |
// since SQLRowValues isn't thread-safe, use AtomicReference to safely pass it to another |
// thread |
final AtomicReference<SQLRowValues> copy = new AtomicReference<SQLRowValues>(vals.deepCopy()); |
return this.getModel().getUpdateQ().execute(new FutureTask<Number>(new OfflineCallable<Number>() { |
// copy to avoid back-door and allow grow() |
final SQLRowValues copy = vals.deepCopy(); |
return this.execInUpdateQ(new OfflineCallable<Number>() { |
@Override |
public Number call() throws Exception { |
return _add(copy.get(), true, true).getID(); |
return addNow(copy, true); |
} |
})); |
}); |
} |
/** |
* Add a new row. This method can only be called from the update thread, e.g. from |
* {@link #useRow(Number, ITransformerExn)}. |
* |
* @param vals the values, its {@link SQLRowValues#getID() ID} will be ignored. |
* @return the ID for the new row. |
* @see #add(SQLRowValues) |
*/ |
public final Integer addNow(final SQLRowValues vals) { |
return addNow(vals, false); |
} |
private final Integer addNow(final SQLRowValues vals, final boolean safe) { |
if (!safe) |
checkUpdateThread(); |
final SQLRowValues copy = safe ? vals : vals.deepCopy(); |
// otherwise could replace an existing row (use replaceRow() for that) |
// existing DB rows can only be added by fetch() |
copy.clearPrimaryKeys(); |
return this._add(copy, true, true).getID(); |
} |
protected Row _add(final SQLRowValues vals, final boolean grow, final boolean fireAdd) { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
// make sure every needed path is there |
if (grow) |
vals.grow(getUpdateQueueReq().getGraphToFetch(), false); |
// ATTN only works because vals was just fetched or just copied |
vals.getGraph().freeze(); |
final boolean fromDB = vals.hasID(); |
final boolean fromDB = vals.hasID() && vals.getID() >= SQLRow.MIN_VALID_ID; |
final List<Integer> order; |
final Row r; |
r = new Row(fromDB ? vals.getID() : this.freeID--, vals); |
366,16 → 372,21 |
} |
public final Future<SQLRowValues> remove(final Number id) { |
return this.getModel().getUpdateQ().execute(new FutureTask<SQLRowValues>(new OfflineCallable<SQLRowValues>() { |
return this.execInUpdateQ(new OfflineCallable<SQLRowValues>() { |
@Override |
public SQLRowValues call() throws Exception { |
final Row r = getRow(id.intValue()); |
return r == null ? null : rm(r).vals; |
return rm(r); |
} |
})); |
}); |
} |
private Row rm(final Row r) { |
public final SQLRowValues removeNow(final Row r) { |
this.checkUpdateThread(); |
return rm(r); |
} |
private SQLRowValues rm(final Row r) { |
if (r != null) { |
this._rm(r); |
// add to a list of id to archive if it's in the DB |
382,12 → 393,14 |
if (r.vals.hasID()) |
this.deleted.add(r.vals.getIDNumber()); |
this.getModel().getUpdateQ().replaceLine(r.getID().intValue(), null); |
return r.vals; |
} else { |
return null; |
} |
return r; |
} |
private void _rm(final Row l) { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
if (l != null) { |
this.lines.remove(l); |
this.id2line.remove(l.id); |
400,13 → 413,10 |
checkCanModif(path); |
if (!vals.isFrozen()) |
throw new IllegalArgumentException("Not frozen"); |
// since SQLRowValues isn't thread-safe, use AtomicReference to safely pass it to another |
// thread |
final AtomicReference<SQLRowValues> copy = new AtomicReference<SQLRowValues>(vals); |
this.getModel().getUpdateQ().put(new OfflineRunnable() { |
this.execInUpdateQ(new OfflineRunnable() { |
@Override |
public void run() { |
getModel().getUpdateQ().updateLine(l, path, copy.get().getID(), copy.get()); |
getModel().getUpdateQ().updateLine(l, path, vals.getID(), vals); |
recordOriginal(l); |
} |
}); |
447,22 → 457,26 |
}, false); |
} |
public Future<?> updateRow(final Number id, final IClosure<SQLRowValues> valsClosure) { |
public Future<SQLRowValues> updateRow(final Number id, final IClosure<SQLRowValues> valsClosure) { |
return this.updateRow(id, valsClosure, true); |
} |
private Future<?> updateRow(final Number id, final IClosure<SQLRowValues> valsClosure, final boolean mdCanChange) { |
return this.getModel().getUpdateQ().put(new OfflineRunnable() { |
private Future<SQLRowValues> updateRow(final Number id, final IClosure<SQLRowValues> valsClosure, final boolean mdCanChange) { |
return this.execInUpdateQ(new OfflineCallable<SQLRowValues>() { |
@Override |
public void run() { |
_updateRow(id, valsClosure, mdCanChange); |
public SQLRowValues call() throws Exception { |
return _updateRow(getRow(id.intValue(), true), valsClosure, mdCanChange).vals; |
} |
}); |
} |
protected Row _updateRow(final Number id, final IClosure<SQLRowValues> valsClosure, final boolean mdCanChange) { |
assert checkUpdateThread(); |
final Row r = getRow(id.intValue(), true); |
public final SQLRowValues updateRowNow(final Row r, final IClosure<SQLRowValues> valsClosure) { |
checkUpdateThread(); |
return _updateRow(r, valsClosure, true).vals; |
} |
protected Row _updateRow(final Row r, final IClosure<SQLRowValues> valsClosure, final boolean mdCanChange) { |
assert isUpdateThread(); |
final SQLRowValues newVals = r.getRow().deepCopy(); |
valsClosure.executeChecked(newVals); |
// make sure PK and metadata don't change |
500,6 → 514,32 |
r.setRow(newVals); |
} |
public final <T> Future<T> useRow(final Number id, final ITransformerExn<SQLRowValues, T, ?> valsTransf) { |
return this.execInUpdateQ(new OfflineCallable<T>() { |
@Override |
public T call() throws Exception { |
final SQLRowValues vals = getRow(id.intValue(), true).vals; |
assert vals.isFrozen(); |
return valsTransf.transformChecked(vals); |
} |
}); |
} |
/** |
* Execute the passed transformer in the update queue, allow to call any method ending in "Now". |
* |
* @param rowsTransf what to do. |
* @return a future with the value returned by <code>rowsTransf</code>. |
*/ |
public final <T> Future<T> useRows(final ITransformerExn<SQLTableModelLinesSourceOffline, T, ?> rowsTransf) { |
return this.execInUpdateQ(new OfflineCallable<T>() { |
@Override |
public T call() throws Exception { |
return rowsTransf.transformChecked(SQLTableModelLinesSourceOffline.this); |
} |
}); |
} |
// *** Order *** |
@Override |
510,7 → 550,7 |
// since SQLRowValues isn't thread-safe, use Concurrent Collection to safely pass it to |
// another thread |
final List<SQLRowAccessor> copy = new CopyOnWriteArrayList<SQLRowAccessor>(list); |
return this.getModel().getUpdateQ().put(new OfflineRunnable() { |
return this.execInUpdateQ(new OfflineRunnable() { |
@Override |
public void run() { |
_moveBy(copy, inc); |
519,7 → 559,7 |
} |
protected void _moveBy(final List<? extends SQLRowAccessor> list, final int inc) { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
final int count = this.lines.size(); |
final boolean after = inc > 0; |
556,7 → 596,7 |
@Override |
public Future<?> moveTo(final List<? extends Number> ids, final int index) { |
return this.getModel().getUpdateQ().put(new OfflineRunnable() { |
return this.execInUpdateQ(new OfflineRunnable() { |
@Override |
public void run() { |
_moveTo(ids, index); |
565,7 → 605,7 |
} |
protected void _moveTo(final List<?> ids, final int index) { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
final int count = this.lines.size(); |
final List<Integer> order; |
607,6 → 647,21 |
// *** Roll back or Commit *** |
public final Future<Boolean> hasModifications() { |
return this.execInUpdateQ(new OfflineCallable<Boolean>() { |
@Override |
public Boolean call() throws Exception { |
return hasModificationsNow(); |
} |
}); |
} |
public final boolean hasModificationsNow() { |
checkUpdateThread(); |
// ATTN this.dbOrder doesn't check just for order but also for added rows |
return !this.dbVals.isEmpty() || !this.deleted.isEmpty() || !this.dbOrder; |
} |
/** |
* Lose any changes and refetch from the database. |
* |
613,7 → 668,7 |
* @return the future. |
*/ |
public final Future<?> reset() { |
return this.getModel().getUpdateQ().put(new OfflineRunnable() { |
return this.execInUpdateQ(new OfflineRunnable() { |
@Override |
public void run() { |
_reset(); |
622,7 → 677,7 |
} |
protected void _reset() { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
this.lines.clear(); |
this.id2line.clear(); |
641,17 → 696,22 |
* @return the future. |
*/ |
public final Future<?> commit() { |
return this.getModel().getUpdateQ().execute(new FutureTask<Object>(new OfflineCallable<Object>() { |
return this.execInUpdateQ(new OfflineCallable<Object>() { |
@Override |
public Object call() throws Exception { |
_commit(); |
return null; |
} |
})); |
}); |
} |
public final void commitNow() throws SQLException { |
checkUpdateThread(); |
this._commit(); |
} |
protected final void _commit() throws SQLException { |
assert checkUpdateThread(); |
assert isUpdateThread(); |
// don't listen to every commit and then to re-order, just updateAll() at the end |
this.getModel().getUpdateQ().rmTableListener(); |
700,6 → 760,7 |
} |
this.dbVals.clear(); |
if (getParent().getPrimaryTable().isOrdered()) { |
final List<SQLRow> wantedOrder = new ArrayList<SQLRow>(newRows.values()); |
final List<SQLRow> dbOrder = new ArrayList<SQLRow>(newRows.values()); |
Collections.sort(dbOrder, OrderComparator.INSTANCE); |
708,3 → 769,4 |
} |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/IListeAction.java |
---|
230,6 → 230,7 |
} |
final JMenuItem getRootMenuItem(final Action defaultAction) { |
// Cannot compare actions since menu items are not required to have an action |
String actionCommand = (String) defaultAction.getValue(Action.ACTION_COMMAND_KEY); |
if (actionCommand == null) |
actionCommand = (String) defaultAction.getValue(Action.NAME); |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/RowValuesTable.java |
---|
474,4 → 474,9 |
} |
this.sqlName = sqlName; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName() + " of " + this.model.getSQLElement() + " : " + super.toString(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/SQLTextComboTableCellEditor.java |
---|
132,7 → 132,7 |
this.comboBox.addModelListener("wantedID", new PropertyChangeListener() { |
@Override |
public void propertyChange(final PropertyChangeEvent evt) { |
SQLTextComboTableCellEditor.this.val = SQLTextComboTableCellEditor.this.comboBox.getWantedID(); |
SQLTextComboTableCellEditor.this.val = comboBox.getWantedID(); |
} |
}); |
// Filtre sur une valeur specifique |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/RowAction.java |
---|
173,7 → 173,7 |
@Override |
public Action getDefaultAction(IListeEvent evt) { |
return null; |
return this.enabledFor(evt) ? this.getAction() : null; |
} |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/SQLTableModelLinesSourceOnline.java |
---|
17,14 → 17,10 |
import org.openconcerto.sql.model.SQLRowAccessor; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.model.graph.Path; |
import org.openconcerto.sql.request.ListSQLRequest; |
import org.openconcerto.utils.SleepingQueue.LethalFutureTask; |
import org.openconcerto.utils.SleepingQueue.RunningState; |
import org.openconcerto.utils.Value; |
import java.beans.PropertyChangeEvent; |
import java.beans.PropertyChangeListener; |
import java.math.BigDecimal; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.List; |
41,19 → 37,11 |
public class SQLTableModelLinesSourceOnline extends SQLTableModelLinesSource { |
private final SQLTableModelSourceOnline parent; |
private final PropertyChangeListener listener; |
private MoveQueue moveQ; |
public SQLTableModelLinesSourceOnline(SQLTableModelSourceOnline parent, final ITableModel model) { |
super(model); |
this.parent = parent; |
this.listener = new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
fireChanged(evt); |
} |
}; |
this.getParent().getReq().addWhereListener(this.listener); |
this.moveQ = null; |
} |
68,8 → 56,6 |
@Override |
protected void die() { |
this.getParent().getReq().rmWhereListener(this.listener); |
if (this.moveQ != null) { |
final RunningState threadState = this.moveQ.getRunningState(); |
if (threadState == RunningState.RUNNING) { |
105,16 → 91,7 |
return Value.getSome(createLine(this.getUpdateQueueReq().getValues(id))); |
} |
private BigDecimal getOrder(SQLRowAccessor r) { |
return (BigDecimal) r.getObject(r.getTable().getOrderField().getName()); |
} |
@Override |
public int compare(ListSQLLine l1, ListSQLLine l2) { |
return getOrder(l1.getRow()).compareTo(getOrder(l2.getRow())); |
} |
@Override |
public Future<?> moveBy(List<? extends SQLRowAccessor> rows, int inc) { |
return this.getMoveQ().move(rows, inc); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/ITableModel.java |
---|
104,11 → 104,19 |
ITableModel.defaultCellsEditable = defaultEditable; |
} |
public static final boolean isDefaultCellsEditable() { |
return ITableModel.defaultCellsEditable; |
} |
public static void setDefaultOrderEditable(boolean defaultEditable) { |
assert SwingUtilities.isEventDispatchThread(); |
ITableModel.defaultOrderEditable = defaultEditable; |
} |
public static final boolean isDefaultOrderEditable() { |
return ITableModel.defaultOrderEditable; |
} |
/** |
* Return the line of a JTable at the passed index, handling {@link TableSorter}. |
* |
171,8 → 179,8 |
this.updating = false; |
this.filledOnce = false; |
this.setCellsEditable(defaultCellsEditable); |
this.setOrderEditable(defaultOrderEditable); |
this.setCellsEditable(isDefaultCellsEditable()); |
this.setOrderEditable(isDefaultOrderEditable()); |
this.debug = false; |
// don't use CopyUtils.copy() since this prevent the use of anonymous inner class |
445,13 → 453,12 |
this.setOrderEditable(b); |
} |
public final boolean isEditable() { |
return this.areCellsEditable() || this.isOrderEditable(); |
} |
public final void setCellsEditable(boolean b) { |
if (this.cellsEditable != b) { |
this.cellsEditable = b; |
this.supp.firePropertyChange("cellsEditable", !this.cellsEditable, this.cellsEditable); |
} |
} |
public final boolean areCellsEditable() { |
return this.cellsEditable; |
458,8 → 465,11 |
} |
public final void setOrderEditable(boolean b) { |
if (this.orderEditable != b) { |
this.orderEditable = b; |
this.supp.firePropertyChange("orderEditable", !this.orderEditable, this.orderEditable); |
} |
} |
public final boolean isOrderEditable() { |
return this.orderEditable; |
471,11 → 481,14 |
return false; |
final SQLTableModelColumn col = this.getReq().getColumn(columnIndex); |
// hasRight is expensive so put it last |
return col.isEditable() && !isReadOnly(rowIndex) && hasRight(col); |
return col.isEditable() && !isReadOnly(rowIndex, columnIndex, col) && hasRight(col); |
} |
private boolean isReadOnly(int rowIndex) { |
final SQLRowValues r = getRow(rowIndex).getRow(); |
private boolean isReadOnly(final int rowIndex, final int columnIndex, final SQLTableModelColumn col) { |
final ListSQLLine line = getRow(rowIndex); |
if (!line.getSrc().isCellEditable(line, columnIndex, col)) |
return true; |
final SQLRowValues r = line.getRow(); |
return r.getTable().contains(SQLComponent.READ_ONLY_FIELD) && SQLComponent.isReadOnly(r); |
} |
578,7 → 591,7 |
// *** move |
protected final boolean canOrder() { |
return this.isOrderEditable() && TableAllRights.hasRight(UserRightsManager.getCurrentUserRights(), TableAllRights.MODIFY_ROW_TABLE, getTable()); |
return this.isOrderEditable() && this.getReq().getReq().isTableOrder() && TableAllRights.hasRight(UserRightsManager.getCurrentUserRights(), TableAllRights.MODIFY_ROW_TABLE, getTable()); |
} |
private final void handleCannotOrder(final boolean ignoreForbidden) { |
874,6 → 887,7 |
throw new IllegalStateException("dead tableModel: " + this); |
if (state == RunningState.NEW) { |
print("starting"); |
this.getLinesSource().live(); |
this.updateQ.start(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/IListe.java |
---|
310,6 → 310,9 |
private int retainCount = 0; |
private boolean cellModificationAllowed = ITableModel.isDefaultCellsEditable(); |
private boolean orderModificationAllowed = ITableModel.isDefaultOrderEditable(); |
public IListe(final SQLTableModelSource req) { |
this(req, null); |
} |
445,7 → 448,7 |
// Better look |
this.jTable.setShowHorizontalLines(false); |
this.jTable.setGridColor(new Color(230, 230, 230)); |
this.jTable.setRowHeight(this.jTable.getRowHeight() + 4); |
this.jTable.setRowHeight(FontUtils.getPreferredRowHeight(this.jTable)); |
this.popup = new JPopupMenu(); |
TablePopupMouseListener.add(this.jTable, new ITransformer<MouseEvent, JPopupMenu>() { |
548,11 → 551,12 |
// donc on ne peut faire aucune action pendant les maj |
this.btnPanel = new JPanel(new FlowLayout(FlowLayout.LEADING)); |
this.addModelListener(new PropertyChangeListener() { |
this.addListenerOnModel(new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
// let the header buttons know that the rows have changed |
if ("updating".equals(evt.getPropertyName()) && Boolean.FALSE.equals(evt.getNewValue())) |
final boolean doneUpdating = "updating".equals(evt.getPropertyName()) && Boolean.FALSE.equals(evt.getNewValue()); |
if (doneUpdating || "cellsEditable".equals(evt.getPropertyName())) |
updateButtons(); |
} |
}); |
668,13 → 672,19 |
for (final IListeAction a : this.rowActions.keySet()) { |
final PopupBuilder popupContent = a.getPopupContent(evt); |
if (defaultAction != null && a == this.defaultRowAction) { |
// Cannot compare actions since menu items are not required to have an action |
// If popup actions are ["Dial 03", "Dial 06"] then getDefaultAction() cannot always |
// return the same instance "if land line is default then Dial 03 else Dial 06" |
// otherwise we can't find its matching menu item in the popup |
/** |
* If popup actions are ["Dial 03", "Dial 06"] then getDefaultAction() must not |
* always return the same instance "if land line is default then Dial 03 else Dial |
* 06" otherwise we can't find its matching menu item in the popup. IOW the check |
* should be done in getDefaultAction(), which should then return one of the popup |
* actions. |
* <p> |
* Also, the IListeAction can just choose not to return the default action in its |
* menu. |
*/ |
final JMenuItem defaultMI = popupContent.getRootMenuItem(defaultAction); |
if (defaultMI == null) |
Log.get().warning("Default action not found at the root level of popup for " + this); |
Log.get().info("Default action not found at the root level of popup for " + this); |
else |
defaultMI.setFont(defaultMI.getFont().deriveFont(Font.BOLD)); |
} |
884,7 → 894,7 |
// TODO speed up like IListPanel buttons |
// works because "JTable.autoStartsEdit" is false |
// otherwise mets un + a la fin de la cellule courante |
if (this.getSource().getPrimaryTable().isOrdered()) { |
if (this.getSource().getReq().isTableOrder()) { |
this.jTable.addKeyListener(new KeyAdapter() { |
public void keyTyped(KeyEvent e) { |
if (e.getKeyChar() == '+') { |
1130,12 → 1140,14 |
// protect our internal values |
private <R> R getRow(int index, final Class<R> clazz) { |
final SQLRowValues internalRow = this.getLine(index).getRow(); |
final SQLRowAccessor toCast; |
final ListSQLLine line = this.getLine(index); |
final Object toCast; |
if (clazz == SQLRowValues.class) { |
toCast = internalRow.toImmutable(); |
toCast = line.getRow().toImmutable(); |
} else if (clazz == SQLRow.class) { |
toCast = internalRow.asRow(); |
toCast = line.getRow().asRow(); |
} else if (clazz == ListSQLLine.class) { |
toCast = line; |
} else { |
throw new IllegalArgumentException("Not implemented : " + clazz); |
} |
1175,7 → 1187,11 |
return iterateSelectedRows(SQLRowValues.class); |
} |
private final <R extends SQLRowAccessor> List<R> iterateSelectedRows(final Class<R> clazz) { |
public final List<ListSQLLine> getSelectedLines() { |
return iterateSelectedRows(ListSQLLine.class); |
} |
private final <R> List<R> iterateSelectedRows(final Class<R> clazz) { |
final ListSelectionModel selectionModel = this.getJTable().getSelectionModel(); |
if (selectionModel.isSelectionEmpty()) |
return Collections.emptyList(); |
1340,10 → 1356,6 |
this.getModel().setSleeping(!this.isShowing()); |
} |
public void setSQLEditable(boolean b) { |
this.getModel().setEditable(b); |
} |
/** |
* The {@link ITableModel} of this list. |
* |
1372,6 → 1384,7 |
} |
this.sorter.setTableModel(t); |
if (t != null) { |
updateModelEditable(); |
// no need to listen to source columns since our ITableModel does, then it |
// fireTableStructureChanged() and our JTable createDefaultColumnsFromModel() so |
// columnAdded() and thus updateCols() are called. Note: we might want to listen to |
1498,6 → 1511,38 |
return this.jTable; |
} |
private void updateModelEditable() { |
final ITableModel m = this.getModel(); |
if (m != null) { |
m.setCellsEditable(this.isCellModificationAllowed() && !getSource().getElem().isPrivate()); |
m.setOrderEditable(this.isOrderModificationAllowed() && (!getSource().getElem().isPrivate())); |
} |
} |
public void setModificationAllowed(boolean b) { |
this.setCellModificationAllowed(b); |
this.setOrderModificationAllowed(b); |
} |
public void setCellModificationAllowed(boolean b) { |
this.cellModificationAllowed = b; |
updateModelEditable(); |
} |
public boolean isCellModificationAllowed() { |
return this.cellModificationAllowed; |
} |
public void setOrderModificationAllowed(boolean b) { |
this.orderModificationAllowed = b; |
updateModelEditable(); |
} |
public boolean isOrderModificationAllowed() { |
return this.orderModificationAllowed; |
} |
@Override |
public void grabFocus() { |
this.jTable.grabFocus(); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/liste_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/liste_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/save_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/save_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/reload_2x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/reload_2x.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/OpenConcerto/src/org/openconcerto/sql/PropsConfiguration.java |
---|
788,6 → 788,10 |
} |
} |
public final Set<String> getPropertyNames() { |
return this.props.stringPropertyNames(); |
} |
/** |
* For each property starting with {@link #LOG}, set the level of the specified logger to the |
* property's value. Eg if there's "log.level.=FINE", the root logger will be set to log FINE |
/trunk/OpenConcerto/src/product.properties |
---|
1,5 → 1,5 |
NAME=OpenConcerto |
VERSION=1.5.3 |
VERSION=1.5.4 |
ORGANIZATION_NAME=OpenConcerto |
ORGANIZATION_ID=org.openconcerto |