OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 182 → Rev 181

/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/pdfbox2d.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/fontbox-2.0.22.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/pdfbox-2.0.22.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/flatlaf-1.2.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/mysql-connector-java-5.1.45-bin.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/poi-5.0.0.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/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.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/poi-4.1.0.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/poi-4.1.0.jar
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/lib/flatlaf-0.41.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/flatlaf-0.41.jar
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/lib/fontbox-2.0.19.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/fontbox-2.0.19.jar
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/lib/pdfbox-2.0.19.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/pdfbox-2.0.19.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/lib/mysql-connector-java-5.1.40-bin.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/mysql-connector-java-5.1.40-bin.jar
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/Configuration/Template/Labels/test.graphicspl
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Labels/icon.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/DepotCheque.odsp
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/SituationCompte.xml
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/EtatStockInventaire.odsp
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/VenteFactureTicket.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/ReportingClient.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/DepotCheque.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/EtatStockInventaire.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/SituationCompte.odsp
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/VenteFactureTicket.xml
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/ReportingClient.xml
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/SituationCompte.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/DepotCheque.xml
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/EtatStockInventaire.xml
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/VenteFactureTicket.odsp
File deleted
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/ReleveChequeEmis.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Avoir.xml
26,7 → 26,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
 
/trunk/OpenConcerto/Configuration/Template/Default/LivrePaye.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/AvoirF.xml
27,7 → 27,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/Configuration/Template/Default/FichePayeSimplifiee.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/BonLivraison.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/FicheRelance.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/EtatChargesPaye.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/FactureFournisseur.xml
25,7 → 25,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET " />
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN " />
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/Configuration/Template/Default/DemandePrix.xml
25,7 → 25,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/Configuration/Template/Default/FicheClient.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/FactureFournisseur.odsp
1,6 → 1,6
<odsp>
<spliteveryrow>
<sheet number="0">58</sheet>
<sheet number="0">57</sheet>
</spliteveryrow>
<offset x="40" y ="20"/>
<resize percent="85"/>
/trunk/OpenConcerto/Configuration/Template/Default/Avoir.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/AvoirF.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/EtatVentes.xml
124,28 → 124,4
</element>
</table3>
<element4 location="A4" type="Value" ValueName="DATE">
</element4>
<table4 firstLine="7" endLine="52" endPageLine="54" lastColumn="F" base="Societe" table="SAISIE_VENTE_FACTURE_ELEMENT">
<element location="A" type="fill">
<field base="Societe" name="CODE" />
</element>
 
<element location="B" type="fill">
<field base="Societe" name="NOM" />
</element>
 
<element location="D" type="fill">
<field base="Societe" name="QTE" />
</element>
 
<element location="E" type="fill">
<field base="Societe" name="QTE_REEL" />
</element>
<element location="F" type="fill">
<field base="Societe" name="QTE_MIN" />
</element>
</table4>
</contentDocument>
/trunk/OpenConcerto/Configuration/Template/Default/CommandeClient.xml
24,7 → 24,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
62,7 → 62,7
<field name="NOM" />
</element>
 
<element location="H10" type="fill">
<element location="I10" type="fill">
<field name="ID_CLIENT">
<field name="FORME_JURIDIQUE" />
<field name="NOM" />
69,7 → 69,7
</field>
</element>
 
<element location="H11" type="address.customer.full">
<element location="I11" type="address.customer.full">
 
</element>
 
/trunk/OpenConcerto/Configuration/Template/Default/FactureFournisseur.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/DemandePrix.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/CommandeClient.odsp
1,6 → 1,6
<odsp>
<spliteveryrow>
<sheet number="0">66</sheet>
<sheet number="0">65</sheet>
</spliteveryrow>
<offset x="40" y ="20"/>
<resize percent="85"/>
/trunk/OpenConcerto/Configuration/Template/Default/BonReception.xml
25,7 → 25,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/Configuration/Template/Default/ListeDebiteur.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/JournauxAnalytique.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/ReleveCheque.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Operations Report.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/ReportingTaxeComplementaire.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/DIPE.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/EtatVentes.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/CommandeClient.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/FichePayeSimplifiee.odsp
1,7 → 1,6
<odsp>
<spliteveryrow>
<sheet number="0">65</sheet>
<sheet number="0">61</sheet>
</spliteveryrow>
<resize percent="92"/>
<offset x="23" y ="0"/>
<offset x="20" y ="20"/>
</odsp>
/trunk/OpenConcerto/Configuration/Template/Default/EtatStocks.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Balance.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/ExportArticle.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/BonReception.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/VentilationAnalytique.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/ListeFacture.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Courrier.odt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Commande.xml
25,7 → 25,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/Configuration/Template/Default/ReportingVentes.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/ReportingEcoContribution.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/JournauxMois.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/VenteFacture.xml
25,7 → 25,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/Configuration/Template/Default/VenteFactureSituation.xml
24,7 → 24,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/Configuration/Template/Default/BonReception.odsp
1,6 → 1,6
<odsp>
<spliteveryrow>
<sheet number="0">58</sheet>
<sheet number="0">57</sheet>
</spliteveryrow>
<offset x="40" y ="20"/>
<resize percent="85"/>
/trunk/OpenConcerto/Configuration/Template/Default/DemandePrix.odsp
2,4 → 2,8
<spliteveryrow>
<sheet number="0">58</sheet>
</spliteveryrow>
<offset x="40" y ="20"/>
<resize percent="85"/>
 
 
</odsp>
/trunk/OpenConcerto/Configuration/Template/Default/FicheArticle.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Commande.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Devis.xml
23,7 → 23,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
62,7 → 62,7
<field name="OBJET" />
</element>
 
<element location="H10" type="fill">
<element location="I10" type="fill">
<field name="ID_CLIENT">
<field name="FORME_JURIDIQUE" />
<field name="NOM" />
69,7 → 69,7
</field>
</element>
 
<element location="H11" type="address.customer.full">
<element location="I11" type="address.customer.full">
</element>
 
<element location="L63" type="fill">
/trunk/OpenConcerto/Configuration/Template/Default/VenteFacture.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Relance1.odt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/VenteFactureSituation.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Relance2.odt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Relance3.odt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/GrandLivre.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/FichePaye.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/RepartitionAnalytique.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Commande.odsp
1,6 → 1,6
<odsp>
<spliteveryrow>
<sheet number="0">58</sheet>
<sheet number="0">57</sheet>
</spliteveryrow>
<offset x="40" y ="20"/>
<resize percent="85"/>
/trunk/OpenConcerto/Configuration/Template/Default/BalanceAgee.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Devis.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/Journaux.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/FichePayeSimplifiee.xml
47,7 → 47,7
<field name="AU" prefix=" au " type="date" datePattern="dd/MM/yy" />
</element>
 
<element location="D58" type="fill">
<element location="D54" type="fill">
<field name="DU" type="datePaye" />
</element>
 
89,7 → 89,7
</element>
<element location="F12" type="fill">
<field name="ID_CUMULS_CONGES">
<field name="ACQUIS" type="cumulConges" />
<field name="ACQUIS" />
</field>
</element>
<element location="B6" type="replace" replacePattern="_">
122,159 → 122,79
</element>
 
 
<element location="H54" type="fill">
<field name="NET_AVANT_PAS" />
<element location="I54" type="fill">
<field name="NET_A_PAYER" />
</element>
 
<element location="I55" type="fill">
<field name="REDUCTION_GVT" />
</element>
 
<element location="E57" type="fill">
<field name="NET_IMP" />
</element>
<element location="F57" type="fill">
<field name="ID_PAS">
<field name="TAUX_PAS" />
</field>
</element>
<element location="I57" type="fill">
<field name="TOTAL_PAS" />
</element>
 
 
 
 
<element location="I58" type="fill">
<field name="NET_A_PAYER" />
</element>
 
<element location="D62" type="fill">
<element location="D58" type="fill">
<field name="SAL_BRUT" />
</element>
<element location="E62" type="fill">
<element location="E58" type="fill">
<field name="COT_SAL" />
</element>
<element location="F62" type="fill">
<element location="F58" type="fill">
<field name="COT_PAT" />
</element>
 
<element location="G62" type="fill">
<element location="G58" type="fill">
<field name="AVANTAGE_NATURE" />
</element>
 
<element location="H62" type="fill">
<element location="H58" type="fill">
<field name="NET_IMP" />
</element>
 
<element location="I62" type="fill">
<element location="I58" type="fill">
<field name="ALLEGEMENT_COTISATION" />
</element>
 
<element location="D63" type="fill">
<element location="D59" type="fill">
<field name="SAL_BRUT" type="cumulPaye" />
</element>
<element location="E63" type="fill">
<element location="E59" type="fill">
<field name="COT_SAL" type="cumulPaye" />
</element>
<element location="F63" type="fill">
<element location="F59" type="fill">
<field name="COT_PAT" type="cumulPaye" />
</element>
<element location="G63" type="fill">
<element location="G59" type="fill">
<field name="AVANTAGE_NATURE" type="cumulPaye" />
</element>
 
<element location="H63" type="fill">
<element location="H59" type="fill">
<field name="NET_IMP" type="cumulPaye" />
</element>
 
<element location="I63" type="fill">
<element location="I59" type="fill">
<field name="ALLEGEMENT_COTISATION" type="cumulPaye" />
</element>
 
<element location="J16" type="fill">
<field name="ID_SALARIE">
<field name="CODE" />
</field>
</element>
<element location="J18" type="fill">
<field name="ID_SALARIE">
<field name="ID_INFOS_SALARIE_PAYE">
<field name="DATE_ARRIVE">
</field>
</field>
</field>
</element>
<element location="J21" type="fichepaye.smic" />
<element location="J23" type="fichepaye.plafond" />
 
<element location="J28" type="fill">
<field name="ID_VARIABLE_SALARIE">
<field name="HEURE_TRAV" />
</field>
</element>
 
<element location="J30" type="fichepaye.heure.sup.total">
</element>
<element location="J32" type="fichepaye.heure.total">
</element>
 
<element location="J35" type="fill">
<field name="ID_VARIABLE_SALARIE">
<field name="HEURE_TRAV_CUMUL_VAL" />
</field>
</element>
<element location="J37" type="fichepaye.heure.sup.cumul.total">
</element>
 
<element location="J39" type="fichepaye.heure.cumul.total">
</element>
 
 
<table endPageLine="65" 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" />
</element>
<element location="D" type="fill">
<element location="E" type="fill">
<field name="NB_BASE" />
</element>
<element location="E" type="fill">
<field name="TAUX_SAL">
<exclude value="0.00" />
<exclude value="0.00%" />
<exclude value="0.000000" />
</field>
</element>
<element location="F" type="fill">
<field name="MONTANT_SAL_AJ">
<exclude value="0.00" />
<exclude value="0.00%" />
<exclude value="0.000000" />
</field>
<field name="TAUX_SAL" />
</element>
<element location="G" type="fill">
<field name="MONTANT_SAL_DED">
<exclude value="0.00" />
<exclude value="0.00%" />
<exclude value="0.000000" />
</field>
<field name="MONTANT_SAL_AJ" />
</element>
<element location="H" type="fill">
<field name="TAUX_PAT">
<exclude value="0.00" />
<exclude value="0.00%" />
<exclude value="0.000000" />
</field>
<field name="MONTANT_SAL_DED" />
</element>
<element location="I" type="fill">
<field name="MONTANT_PAT">
<exclude value="0.00" />
<exclude value="0.00%" />
<exclude value="0.000000" />
</field>
<!-- <element location="I" type="fill">
<field name="TAUX_PAT" type="Devise" />
</element> -->
<element location="J" type="fill">
<field name="MONTANT_PAT" />
</element>
 
 
/trunk/OpenConcerto/Configuration/Template/Default/BonLivraison.xml
24,7 → 24,7
</element>
 
<element location="B6" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIRET "/>
<field base="Common" table="SOCIETE_COMMON" name="NUM_SIRET" prefix="N° de SIREN "/>
</element>
 
<element location="B7" type="replace" replacePattern="_">
/trunk/OpenConcerto/src/org/openconcerto/utils/reentrantEventsIn-order.seq.violet.html
File deleted
\ No newline at end of file
/trunk/OpenConcerto/src/org/openconcerto/utils/system/Powershell.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/system/package-info.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/IntHashSet.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/doml/PushBackReader.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/doml/Element.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/doml/DOMLStreamReader.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/doml/Document.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/jsonrpc/JSONRPCClient.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/Outlook.powershell
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/reentrantEventsNaive.seq.violet.html
File deleted
\ No newline at end of file
/trunk/OpenConcerto/src/org/openconcerto/utils/Action.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/ExceptionUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
16,9 → 16,6
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.util.Objects;
import java.util.function.BiPredicate;
 
/**
* Utilitaires pour les exceptions.
95,27 → 92,4
Log.get().warning("Error while writing " + cause);
return res.toString();
}
 
static public void requireEquals(final BigDecimal a, final BigDecimal b, final String msg) {
require((bd1, bd2) -> bd1.compareTo(bd2) == 0, a, b, msg);
}
 
static public void requireEquals(final Object a, final Object b, final String msg) {
require(Objects::equals, a, b, msg);
}
 
static public <T> void require(final BiPredicate<T, T> pred, final T a, final T b, final String msg) {
if (!pred.test(a, b))
throw new IllegalArgumentException(msg + ", expected " + a + " but got " + b);
}
 
static public void requireSame(final Object a, final Object b, final String msg) {
if (a != b)
throw new IllegalArgumentException(msg + ", expected same reference to " + a + " but got " + b);
}
 
static public void requireEquals(final int a, final int b, final String msg) {
if (a != b)
throw new IllegalArgumentException(msg + ", expected " + a + " but got " + b);
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/StringUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
21,7 → 21,6
import java.nio.charset.Charset;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
360,39 → 359,6
return res;
}
 
static private final Pattern singleQuote = Pattern.compile("'", Pattern.LITERAL);
static public final Pattern SINGLE_QUOTED_PATTERN = Pattern.compile("'(('')|[^'])*'");
static private final Pattern twoSingleQuote = Pattern.compile("''", Pattern.LITERAL);
 
/**
* Quote a string with single quotes ( e.g. for {@link SimpleDateFormat}).
*
* @param s an arbitrary string, eg "salut\ l'ami".
* @return the quoted form, eg "'salut\ l''ami'".
*/
static public final String singleQuote(String s) {
if (s.isEmpty())
return "''";
else
return "'" + singleQuote.matcher(s).replaceAll("''") + "'";
}
 
static public final String unSingleQuote(String s) {
if (!SINGLE_QUOTED_PATTERN.matcher(s).matches())
throw new IllegalArgumentException("Invalid quoted string " + s);
return unSingleQuoteUnsafe(s);
}
 
private static String unSingleQuoteUnsafe(String s) {
return twoSingleQuote.matcher(s.substring(1, s.length() - 1)).replaceAll("'");
}
 
static public final String unSingleQuote(Matcher m) {
if (m.pattern() != SINGLE_QUOTED_PATTERN)
throw new IllegalArgumentException("Matcher not from SINGLE_QUOTED_PATTERN : " + m);
return unSingleQuoteUnsafe(m.group());
}
 
static private final Pattern quotePatrn = Pattern.compile("\"", Pattern.LITERAL);
static private final Pattern slashPatrn = Pattern.compile("(\\\\+)");
 
774,13 → 740,10
}
 
/**
* Convert a byte array to its hexa representation (uppercase)
*
* @param bytes to converts
* @param size of the byte array to use
* @return the hexa representation
* convert a byte array to its hexa representation
*/
public static String bytesToHexString(byte[] bytes, int length) {
public static String bytesToHexString(byte[] bytes) {
final int length = bytes.length;
char[] hexChars = new char[length * 2];
for (int j = 0; j < length; j++) {
int v = bytes[j] & 0xFF;
790,25 → 753,7
return new String(hexChars);
}
 
public static String charToHex(char c) {
int v = c & 0xFF;
char[] hexChars = new char[2];
hexChars[0] = hexArray[v >>> 4];
hexChars[1] = hexArray[v & 0x0F];
return new String(hexChars);
}
 
/**
* Convert a byte array to its hexa representation (uppercase)
*
* @param bytes to converts
* @return the hexa representation
*/
public static String bytesToHexString(byte[] bytes) {
return bytesToHexString(bytes, bytes.length);
}
 
/**
* Whether the parameter is empty.
*
* @param s the string to test.
823,11 → 768,22
}
 
/**
* Return the first parameter that is non-empty.
*
* @param s1 the string to test.
* @param s2 the alternate value.
* @return <code>s1</code> if not <code>null</code> and not {@link String#isEmpty() empty},
* <code>s2</code> otherwise.
*/
public static String coalesce(String s1, String s2) {
return isEmpty(s1) ? s2 : s1;
}
 
/**
* Return the first value that is non-empty.
*
* @param values values to test for emptiness.
* @return the first value that is neither <code>null</code> nor {@link String#isEmpty() empty},
* <code>null</code> if none.
* @return the first value that is neither <code>null</code> nor {@link String#isEmpty() empty}.
*/
public static String coalesce(String... values) {
return coalesce(false, values);
834,10 → 790,9
}
 
public static String coalesce(final boolean trim, String... values) {
for (final String s : values) {
for (final String s : values)
if (!isEmpty(s, trim))
return s;
}
return null;
}
 
/trunk/OpenConcerto/src/org/openconcerto/utils/SystemUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
17,7 → 17,6
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.regex.Pattern;
 
public class SystemUtils {
124,18 → 123,4
return true;
}
}
 
static public final <T extends Enum<T>> T getEnumFromProperty(final String propName, final Class<T> clazz, final T def) {
final String prop = System.getProperty(propName);
if (prop == null)
return def;
return Enum.valueOf(clazz, propName);
}
 
static public final <T> T getProperty(final String propName, final Function<String, T> func, final T def) {
final String prop = System.getProperty(propName);
if (prop == null)
return def;
return func.apply(prop);
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/text/TypesFormats.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/text/DateTimeSkeleton.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/text/DateTimeComponents.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/text/DateTimeFormat.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/text/DateTimeFormatBuilder.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/text/DateProp.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/text/DateTimeFormatComponent.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/text/BooleanFormat.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
18,13 → 18,9
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.Arrays;
import java.util.Locale;
import java.util.ResourceBundle;
 
import net.jcip.annotations.Immutable;
 
@Immutable
public class BooleanFormat extends Format {
static private final boolean[] BOOLEAN_VALUES = new boolean[] { false, true };
static private final BooleanFormat NUMBER_INSTANCE = new BooleanFormat("0", "1");
43,18 → 39,10
return new BooleanFormat(getFormattedBooleans(l, true));
}
 
static public BooleanFormat createTrueFalse(final Locale l) {
return new BooleanFormat(getFormattedBooleans(l, false));
}
 
static public final BooleanFormat getNumberInstance() {
return NUMBER_INSTANCE;
}
 
static public final BooleanFormat[] getAll(final Locale l) {
return new BooleanFormat[] { createTrueFalse(l), createYesNo(l), getNumberInstance() };
}
 
private final String[] formattedValues;
 
public BooleanFormat() {
65,7 → 53,6
this(new String[] { falseValue, trueValue });
}
 
// not public because parameter isn't copied
private BooleanFormat(final String[] formattedValues) {
this.formattedValues = formattedValues;
}
101,29 → 88,4
pos.setErrorIndex(pos.getIndex());
return null;
}
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(this.formattedValues);
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final BooleanFormat other = (BooleanFormat) obj;
return Arrays.equals(this.formattedValues, other.formattedValues);
}
 
@Override
public String toString() {
return this.getClass().getSimpleName() + " with " + Arrays.asList(this.formattedValues);
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/ListMap.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
36,8 → 36,6
}
 
static public <K, V> ListMapItf<K, V> unmodifiableMap(ListMapItf<K, V> map) {
if (map.isEmpty())
return empty();
return new Unmodifiable<K, V>(map);
}
 
/trunk/OpenConcerto/src/org/openconcerto/utils/checks/MutableValueObject.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
21,8 → 21,6
* Set the value as if this object was newly created. Ie if this object had a way of computing
* its initial value, reuse it (eg setValue(currentTime)).
*/
public default void resetValue() {
this.setValue(null);
}
public void resetValue();
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/ProductInfo.java
30,12 → 30,9
public static final String PROPERTIES_NAME = "/product.properties";
public static final String ORGANIZATION_NAME = "ORGANIZATION_NAME";
public static final String ORGANIZATION_ID = "ORGANIZATION_ID";
// e.g. LibreOffice
public static final String NAME = "NAME";
public static final String ID = "ID";
public static final String VERSION = "VERSION";
// Allow multiple end-user applications (e.g. icons) to share a product name, e.g. Writer
public static final String LAUNCHER = "LAUNCHER";
 
private static ProductInfo INSTANCE;
 
159,18 → 156,6
return orgID == null ? null : orgID + '.' + this.getID();
}
 
public final String getLauncher() {
return this.getProperty(LAUNCHER);
}
 
public final String getFullLauncherID() {
final String launcher = this.getLauncher();
final String fullID = this.getFullID();
if (launcher == null || fullID == null)
return fullID;
return fullID + '-' + sanitizeDomainPart(launcher);
}
 
public final String getVersion() {
return this.getProperty(VERSION);
}
177,14 → 162,10
 
public final void store(final Path p) throws IOException {
try (final OutputStream out = Files.newOutputStream(p)) {
store(out);
this.getProps().store(out, this.getClass().getName());
}
}
 
public final void store(final OutputStream out) throws IOException {
this.getProps().store(out, this.getClass().getName());
}
 
@Override
public String toString() {
return this.getClass().getSimpleName() + " for " + getName() + " " + getVersion();
/trunk/OpenConcerto/src/org/openconcerto/utils/OutlookEmail.vbs
New file
0,0 → 1,71
' http://msdn.microsoft.com/en-us/library/aa210946(office.11).aspx
 
' Enable error handling
On Error Resume Next
 
if Wscript.Arguments.count = 0 or Wscript.Arguments.Named.count > 3 then
Wscript.Echo "Usage: " & WScript.ScriptName & " /to:addr /subject:Re [ /body:""Hi, dear friend"" | /unicodeStdIn:[0|1] ] attachment..." & vbNewLine &_
vbTab & "Named parameters should be percent-encoded since certain characters like double quote cannot be passed." &_
" If unicodeStdIn is defined the body will be read from stdin (avoiding arguments size limitation), 1 will parse the stream as UTF16, " &_
"0 will parse as the platform default. If calling from cmd.exe you might need to change the codepage, e.g. chcp 1252 (from 850)"
Wscript.Quit 1
end if
 
toAddr = getNamedArg("to")
subject = getNamedArg("subject")
' Cannot always call StdIn.ReadAll since it blocks
If Wscript.Arguments.Named.Exists("unicodeStdIn") then
isUnicode = CBool(Wscript.Arguments.Named.item("unicodeStdIn"))
Set fso = CreateObject ("Scripting.FileSystemObject")
Set ins = fso.GetStandardStream (StdIn, isUnicode)
' ReadAll fails if already at the end of file
if ins.AtEndOfStream then
piped = ""
else
piped = ins.ReadAll
end if
else
body = getNamedArg("body")
End If
 
quitIfErr()
 
'Create a mail object and send the mail
Dim objMail
Dim objclient
 
Set objMail = CreateObject("Outlook.application")
quitIfErr()
Set objclient = objMail.createitem(olMailItem)
quitIfErr()
 
With objclient
.Subject = subject
.To = toAddr
'.CC = "cc@email.com"
.Body = body & piped
For each attachmentPath in Wscript.Arguments.Unnamed
.Attachments.Add attachmentPath
Next
.Display
End With
quitIfErr()
 
Function getNamedArg(n)
getNamedArg = Unescape(Wscript.Arguments.Named.item(n))
End Function
 
Function getNoExn(i)
if Wscript.Arguments.Unnamed.count > i then
getNoExn = Wscript.Arguments.Unnamed.item(i)
else
getNoExn = ""
end if
End Function
 
Function quitIfErr()
If Err.number <> 0 Then
Wscript.Echo "Error # " & CStr(Err.Number) & " " & Err.Description & " Source: " & Err.Source
Wscript.Quit Err.Number
End If
End Function
/trunk/OpenConcerto/src/org/openconcerto/utils/cache/ICacheSupport.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
13,12 → 13,12
package org.openconcerto.utils.cache;
 
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.IScheduledFutureTask;
 
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
178,7 → 178,7
}
 
final synchronized Map<D, CacheWatcher<? super D>> watch(Set<? extends D> data, final CacheItem<?, ?, D> item) {
final Map<D, CacheWatcher<? super D>> res = CollectionUtils.newLinkedHashMap(data.size());
final Map<D, CacheWatcher<? super D>> res = new LinkedHashMap<D, CacheWatcher<? super D>>(data.size(), 1.0f);
for (final D d : data) {
final CacheWatcher<? super D> watcher = this.watch(d, item);
if (watcher != null)
/trunk/OpenConcerto/src/org/openconcerto/utils/cache/ICache.java
32,8 → 32,6
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
 
import net.jcip.annotations.GuardedBy;
 
/**
* To keep results computed from some data. The results will be automatically invalidated after some
* period of time or when the data is modified.
54,9 → 52,7
private final ICacheSupport<D> supp;
// linked to fifo, ATTN the values in this map can be invalid since clear() is called without
// the lock on CacheValue
@GuardedBy("this")
private final LinkedHashMap<K, CacheItem<K, V, D>> cache;
@GuardedBy("this")
private final Map<K, CacheItem<K, V, D>> running;
private final int delay;
private final int size;
228,21 → 224,17
removeRunning(getRunningValFromRes(res));
}
 
private final synchronized boolean removeRunning(final CacheItem<K, V, D> val) {
private final synchronized void removeRunning(final CacheItem<K, V, D> val) {
if (val == null)
return false;
return;
final K key = val.getKey();
final boolean removed;
if (this.running.get(key) == val) {
if (this.running.get(key) == val)
this.removeRunning(key);
removed = true;
} else {
else
// either val wasn't created in this cache or another value was already put in this
// cache
removed = val.setRemovalType(RemovalType.EXPLICIT);
}
val.setRemovalType(RemovalType.EXPLICIT);
assert val.getRemovalType() != null;
return removed;
}
 
private final synchronized void removeRunning(K key) {
435,10 → 427,10
final boolean clear(final CacheItem<K, V, D> val) {
if (val.getRemovalType() == null)
throw new IllegalStateException("Not yet removed : " + val);
final boolean removedFromRunning, toBeRemoved;
final boolean toBeRemoved;
synchronized (this) {
log("clear", val);
removedFromRunning = this.removeRunning(val);
this.removeRunning(val);
toBeRemoved = this.cache.get(val.getKey()) == val;
if (toBeRemoved) {
this.cache.remove(val.getKey());
445,28 → 437,18
}
}
// NOTE these events are often fired with our monitor since this method is called with it
if (removedFromRunning || toBeRemoved) {
this.propSupp.firePropertyChange(new Event<K, V, D>(this, ITEMS_CHANGED, null, null));
this.propSupp.firePropertyChange(this.createItemEvent(ITEM_REMOVED, val, null));
}
return toBeRemoved;
}
 
public final synchronized void clear() {
for (final CacheItem<K, V, D> val : new ArrayList<CacheItem<K, V, D>>(this.cache.values())) {
// We have our monitor so if val is still in us but setRemovalType() was already called,
// then it means another thread is waiting on our monitor in clear(CacheItem). In that
// case, just call it now so that this is empty at the end of this method.
if (!val.setRemovalType(RemovalType.EXPLICIT)) {
final boolean removed = this.clear(val);
assert removed;
}
}
assert this.size() == 0 : this + " expected to be empty but contains : " + this.cache.keySet();
 
for (final CacheItem<K, V, D> val : new ArrayList<CacheItem<K, V, D>>(this.cache.values()))
val.setRemovalType(RemovalType.EXPLICIT);
assert this.size() == 0;
for (final CacheItem<K, V, D> val : new ArrayList<CacheItem<K, V, D>>(this.running.values()))
val.setRemovalType(RemovalType.EXPLICIT);
assert this.running.size() == 0 : this + " expected to have no running but contains : " + this.running.keySet();
assert this.running.size() == 0;
}
 
private final void log(String msg, Object subject) {
/trunk/OpenConcerto/src/org/openconcerto/utils/EmailClient.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
20,23 → 20,21
import org.openconcerto.utils.DesktopEnvironment.XFCE;
import org.openconcerto.utils.OSFamily.Unix;
import org.openconcerto.utils.io.PercentEncoder;
import org.openconcerto.utils.system.Powershell;
 
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.lang.ProcessBuilder.Redirect;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
 
public abstract class EmailClient {
 
346,34 → 344,26
public static final EmailClient Outlook = new EmailClient(EmailClientType.Outlook) {
@Override
protected boolean composeNative(String to, String subject, String body, File... attachments) throws IOException, InterruptedException {
return composePowershell(to, subject, body, attachments);
final DesktopEnvironment de = DesktopEnvironment.getDE();
final File vbs = FileUtils.getFile(EmailClient.class.getResource("OutlookEmail.vbs"));
final List<String> l = new ArrayList<String>(6);
l.add("cscript");
l.add(de.quoteParamForExec(vbs.getAbsolutePath()));
if (to != null)
l.add(createVBParam("to", to));
if (subject != null)
l.add(createVBParam("subject", subject));
// at least set a parameter otherwise the usage get displayed
l.add(createVBParam("unicodeStdIn", "1"));
for (File attachment : attachments) {
l.add(de.quoteParamForExec(attachment.getAbsolutePath()));
}
 
// only tested with powershell 5.1
protected boolean composePowershell(String to, String subject, String body, File... attachments) throws IOException, InterruptedException {
final Powershell pwsh = Powershell.getInstance();
 
// Don't create temporary file :
// https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.1
String template = new String(StreamUtils.read(EmailClient.class.getResourceAsStream("Outlook.powershell")), StandardCharsets.UTF_8);
template = template.replace("@to@", pwsh.quote(to == null ? "" : to));
template = template.replace("@subject@", pwsh.quote(subject == null ? "" : subject));
template = template.replace("@attachments@", pwsh.quoteArray(Arrays.asList(attachments).stream().map(File::getAbsolutePath).collect(Collectors.toList())));
 
final ProcessBuilder pb = new ProcessBuilder();
pb.command().add("powershell");
// Apparently piping (i.e. "-Command -") only supports ASCII (and would require
// embedding the body in the script).
pb.command().add("-EncodedCommand");
pb.command().add(pwsh.getEncodedCommand(template));
 
pb.inheritIO();
pb.redirectInput(Redirect.PIPE);
final Process process = pb.start();
try (final OutputStream in = process.getOutputStream()) {
in.write(body.getBytes(StandardCharsets.UTF_8));
}
 
final Process process = new ProcessBuilder(l).start();
// VBScript only knows ASCII and UTF-16
final Writer writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), StringUtils.UTF16));
writer.write(body);
writer.close();
final int returnCode = process.waitFor();
if (returnCode != 0)
throw new IllegalStateException("Non zero return code: " + returnCode);
/trunk/OpenConcerto/src/org/openconcerto/utils/io/MailAccount.java
15,7 → 15,6
 
import org.openconcerto.utils.ExceptionUtils;
 
import java.util.Objects;
import java.util.Properties;
 
import javax.mail.Address;
24,8 → 23,6
import javax.mail.PasswordAuthentication;
import javax.mail.SendFailedException;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
 
/**
* A mail account.
110,20 → 107,6
return sb.toString();
}
 
public static final MailAccount create(final String fromAddr, String smtpServer, String smtpLogin, String smtpPassword) throws AddressException {
Objects.requireNonNull(fromAddr, "Missing 'From:' address");
final InternetAddress fromInetAddr = new InternetAddress(fromAddr, true);
if (smtpServer == null) {
smtpServer = "smtp." + fromInetAddr.getAddress().substring(fromInetAddr.getAddress().indexOf('@') + 1);
}
if (smtpLogin == null) {
smtpLogin = fromInetAddr.getAddress().substring(0, fromInetAddr.getAddress().indexOf('@'));
}
final MailAccount res = new MailAccount(fromInetAddr.getPersonal(), fromInetAddr.getAddress(), smtpServer);
res.setAuth(new PasswordAuthentication(smtpLogin, smtpPassword));
return res;
}
 
// nullable
private final String name;
private final String address;
199,8 → 182,7
 
public final void send(final Message msg) throws MessagingException {
final PasswordAuthentication auth = this.getAuth();
final Properties props = msg.getSession().getProperties();
props.setProperty("mail." + getSMTPProtocol() + ".auth", auth == null ? "false" : "true");
msg.getSession().getProperties().setProperty("mail." + getSMTPProtocol() + ".auth", auth == null ? "false" : "true");
try (final Transport mailTransport = msg.getSession().getTransport()) {
if (auth == null)
mailTransport.connect();
207,8 → 189,6
else
mailTransport.connect(auth.getUserName(), auth.getPassword());
mailTransport.sendMessage(msg, msg.getAllRecipients());
} catch (MessagingException e) {
throw new MessagingException("Couldn't send as " + auth.getUserName() + " using\n" + props, e);
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/utils/io/JSONConverter.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
73,11 → 73,7
} else if (param instanceof Calendar) {
result = formatCalendar(((Calendar) param));
} else if (param instanceof Class<?>) {
if (param == String.class) {
result = "string";
} else {
result = ((Class<?>) param).getName();
}
} else if (param instanceof Iterable) {
final Iterable<?> tmp = (Iterable<?>) param;
final JSONArray jsonArray = new JSONArray();
86,11 → 82,14
}
result = jsonArray;
} else if (param instanceof Color) {
String hexString = Integer.toHexString(((Color) param).getRGB());
if (hexString.length() > 6) {
hexString = hexString.substring(2, hexString.length());
if (param != null) {
final Color paramColor = (Color) param;
final JSONObject jsonColor = new JSONObject();
jsonColor.put("r", paramColor.getRed());
jsonColor.put("g", paramColor.getGreen());
jsonColor.put("b", paramColor.getBlue());
result = jsonColor;
}
result = "#" + hexString;
} else if (param instanceof BigDecimal) {
result = ((BigDecimal) param).doubleValue();
} else {
133,7 → 132,11
throw new IllegalArgumentException("object (" + o.getClass().getName() + ") is not assignable for '" + type + "', the format is not valid", e);
}
} else if (type.equals(Color.class)) {
result = type.cast(Color.decode(o.toString()));
final JSONObject jsonColor = (JSONObject) o;
final int r = JSONConverter.getParameterFromJSON(jsonColor, "r", Integer.class);
final int g = JSONConverter.getParameterFromJSON(jsonColor, "g", Integer.class);
final int b = JSONConverter.getParameterFromJSON(jsonColor, "b", Integer.class);
result = type.cast(new Color(r, g, b));
} else {
result = type.cast(o);
}
/trunk/OpenConcerto/src/org/openconcerto/utils/BaseDirs.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
35,18 → 35,6
super(info, subdir);
}
 
private String getHomePath() {
// ATTN on FreeBSD man 8 service : "service command sets HOME to /" thus one should
// probably not use this class (perhaps Portable).
return StringUtils.coalesce(System.getenv("HOME"), System.getProperty("user.home"));
}
 
private String getInHomePath(final String subPath) {
final String homePath = getHomePath();
// If no home, use current working directory
return homePath == null ? subPath : homePath + '/' + subPath;
}
 
@Override
protected File _getAppDataFolder() {
/*
54,7 → 42,7
* should be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to
* $HOME/.local/share should be used.
*/
return new File(StringUtils.coalesce(System.getenv("XDG_DATA_HOME"), getInHomePath(".local/share")), this.getAppID());
return new File(StringUtils.coalesce(System.getenv("XDG_DATA_HOME"), System.getenv("HOME") + "/.local/share"), this.getAppID());
}
 
@Override
64,7 → 52,7
* configuration files should be stored. If $XDG_CONFIG_HOME is either not set or empty,
* a default equal to $HOME/.config should be used.
*/
return new File(StringUtils.coalesce(System.getenv("XDG_CONFIG_HOME"), getInHomePath(".config")), this.getAppID());
return new File(StringUtils.coalesce(System.getenv("XDG_CONFIG_HOME"), System.getenv("HOME") + "/.config"), this.getAppID());
}
 
@Override
74,7 → 62,7
* non-essential data files should be stored. If $XDG_CACHE_HOME is either not set or
* empty, a default equal to $HOME/.cache should be used.
*/
return new File(StringUtils.coalesce(System.getenv("XDG_CACHE_HOME"), getInHomePath(".cache")), this.getAppID());
return new File(StringUtils.coalesce(System.getenv("XDG_CACHE_HOME"), System.getenv("HOME") + "/.cache"), this.getAppID());
}
}
 
223,8 → 211,7
return res != null ? res : this.getAppID();
}
 
static public final File getFolderToWrite(final File dir) throws IOException {
// MAYBE test for symlink
protected File getFolderToWrite(final File dir) throws IOException {
if (dir.isDirectory() && dir.canWrite())
return dir;
if (dir.exists())
259,7 → 246,7
}
 
protected File _getPreferencesFolder() {
return this._getAppDataFolder();
return this.getAppDataFolder();
}
 
// where to write configuration
284,23 → 271,6
return getFolderToWrite(this.getCacheFolder());
}
 
protected File _getStateFolder() {
return this._getCacheFolder();
}
 
// where to write data that is non-essential but cannot be recreated
// - logfiles
// - state of application windows on exit
// - recently opened files
// See STATE directory in https://wiki.debian.org/XDGBaseDirectorySpecification
public final File getStateFolder() {
return getSubDir(_getStateFolder());
}
 
public final File getStateFolderToWrite() throws IOException {
return getFolderToWrite(this.getStateFolder());
}
 
@Override
public String toString() {
return BaseDirs.class.getSimpleName() + " " + this.getClass().getSimpleName();
/trunk/OpenConcerto/src/org/openconcerto/utils/DesktopEnvironment.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
160,12 → 160,62
}
 
static public final class Windows extends DEisOS {
static private boolean needsQuoting(String s) {
final int len = s.length();
if (len == 0) // empty string have to be quoted
return true;
for (int i = 0; i < len; i++) {
switch (s.charAt(i)) {
case ' ':
case '\t':
case '\\':
case '"':
return true;
}
}
return false;
}
 
// on Windows program themselves are required to parse the command line, thus a lot of them
// do it differently, see http://www.autohotkey.net/~deleyd/parameters/parameters.htm
 
static private final Pattern quotePatrn = Pattern.compile("([\\\\]*)\"");
static private final Pattern endSlashPatrn = Pattern.compile("([\\\\]*)\\z");
 
// see http://bugs.sun.com/view_bug.do?bug_id=6468220
// e.g. find.exe, choice.exe
public String quoteParamForMsftC(String s) {
if (!needsQuoting(s))
return s;
if (s.length() > 0) {
// replace '(\*)"' by '$1$1\"', e.g. '\quote " \"' by '\quote \" \\\"'
// $1 needed so that the backslash we add isn't escaped itself by a preceding
// backslash
s = quotePatrn.matcher(s).replaceAll("$1$1\\\\\"");
// replace '(\*)\z' by '$1$1', e.g. 'foo\' by 'foo\\'
// needed to not escape closing quote
s = endSlashPatrn.matcher(s).replaceAll("$1$1");
}
return '"' + s + '"';
}
 
// e.g. bash.exe
public String quoteParamForGCC(String s) {
return StringUtils.doubleQuote(s);
}
 
public String quoteParamForScript(final String s) {
if (s.indexOf('"') >= 0)
throw new IllegalArgumentException("Can not pass a double quote as part of a parameter");
return '"' + s + '"';
}
 
@Override
public String quoteParamForExec(final String s) {
return quoteParamForMsftC(s);
}
}
 
static public final class Mac extends DEisOS {
 
// From CarbonCore/Folders.h
348,8 → 398,8
}
 
// on some systems arguments are not passed correctly by ProcessBuilder
public final String quoteParamForExec(String s) {
return Platform.getInstance().getProcessArg(s);
public String quoteParamForExec(String s) {
return s;
}
 
@Override
/trunk/OpenConcerto/src/org/openconcerto/utils/FileUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
277,7 → 277,6
* @return the relative path, eg "../x/y.txt".
* @throws IOException if an error occurs while canonicalizing the files.
* @throws IllegalArgumentException if fromDir exists and is not directory.
* @see {@link Path#relativize(Path)}
*/
public static final String relative(File fromDir, File to) throws IOException {
if (fromDir.exists() && !fromDir.isDirectory())
/trunk/OpenConcerto/src/org/openconcerto/utils/CompareUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
282,7 → 282,7
}
};
 
static public final <T> boolean equals(List<? extends T> l1, List<? extends T> l2, Equalizer<? super T> comp) {
static public final <T> boolean equals(List<T> l1, List<T> l2, Equalizer<? super T> comp) {
return compare(l1, l2, comp, null) == null;
}
 
297,7 → 297,7
* @return <code>null</code> if the two lists are equal, otherwise a String explaining the
* difference.
*/
static public final <T> String compare(List<? extends T> l1, List<? extends T> l2, Equalizer<? super T> comp, final ITransformer<? super T, String> toString) {
static public final <T> String compare(List<T> l1, List<T> l2, Equalizer<? super T> comp, final ITransformer<? super T, String> toString) {
final int size = l1.size();
if (size != l2.size())
return "unequal size";
/trunk/OpenConcerto/src/org/openconcerto/utils/sync/SimpleSyncClient.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
27,7 → 27,6
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
53,15 → 52,15
 
public final class SimpleSyncClient extends HTTPClient {
 
protected static final long getLong(final Object o) {
static protected final long getLong(final Object o) {
return ((Number) o).longValue();
}
 
protected static final Instant getInstant(final Object o) {
static protected final Instant getInstant(final Object o) {
return Instant.ofEpochMilli(getLong(o));
}
 
public static abstract class BaseAttrs implements Serializable {
static protected abstract class BaseAttrs {
private final String path;
private final String name;
private final Instant lastModified;
91,8 → 90,8
}
}
 
public static final class DirAttrs extends BaseAttrs {
protected static DirAttrs fromJSON(final String path, final JSONArray array) {
static public final class DirAttrs extends BaseAttrs {
static protected DirAttrs fromJSON(final String path, final JSONArray array) {
return new DirAttrs(path, (String) array.get(0), getInstant(array.get(1)));
}
 
101,9 → 100,9
}
}
 
public static final class FileAttrs extends BaseAttrs {
static public final class FileAttrs extends BaseAttrs {
 
protected static FileAttrs fromJSON(final String path, final JSONArray array) {
static protected FileAttrs fromJSON(final String path, final JSONArray array) {
return new FileAttrs(path, (String) array.get(0), getInstant(array.get(2)), getLong(array.get(1)), (String) array.get(3));
}
 
159,7 → 158,7
}
}
 
public static final class DirContent {
static public final class DirContent {
private final String path;
private final JSONObject json;
 
220,11 → 219,11
}
 
@FunctionalInterface
public static interface FileConsumer {
static public interface FileConsumer {
public void accept(FileAttrs attrs, InputStream fileStream) throws IOException;
}
 
private static final Set<Integer> GETFILE_OK_CODES = CollectionUtils.createSet(200, 404);
static private final Set<Integer> GETFILE_OK_CODES = CollectionUtils.createSet(200, 404);
 
public Response getFile(final String path, final String fileName, final FileConsumer fileConsumer) throws IOException {
if (path == null) {
247,26 → 246,6
return res;
}
 
public Integer getCounter(final String key) throws IOException {
if (key == null) {
throw new IllegalArgumentException("null key");
}
final HttpsURLConnection con = openConnection("/getCounter");
send(con, NetUtils.urlEncode("key", key), false);
final Response res = checkResponseCode(con, GETFILE_OK_CODES);
if (res.getCode() == 200) {
byte[] bytes = new byte[20];
try (final InputStream in = getInputStream(con)) {
int r = in.read(bytes);
String str = new String(bytes, 0, r);
return Integer.parseInt(str);
}
 
}
return null;
 
}
 
// ATTN contrary to other methods, the result isn't if the request was OK : it ignores
// throwsException() and always throws. The return value is true if the file existed and was
// saved.
302,7 → 281,7
}
 
public final Response renameFile(final String path, final String fileName, final String newFileName) throws IOException {
return this.renameFile(path, fileName, path, newFileName);
return this.renameFile(path, fileName, null, newFileName);
}
 
public final Response renameFile(final String path, final String fileName, final String newPath, final String newFileName) throws IOException {
352,15 → 331,4
 
return checkResponseCode(send(con, ba.toByteArray(), true));
}
 
public Response createDir(String path, String fileName) throws IOException {
if (path == null) {
throw new IllegalArgumentException("null path");
}
if (fileName == null) {
throw new IllegalArgumentException("null fileName");
}
final HttpsURLConnection con = openConnection("/mkdir");
return checkResponseCode(send(con, NetUtils.urlEncode("rn", fileName, "rp", path), false));
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/sync/SyncClient.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
18,7 → 18,6
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
530,16 → 529,7
wr.close();
 
// Get the response ASAP in order to not block the server while computing locally hash256
 
// Copy the entire data first because DataInputStream will fail on partial buffer (mainly
// readUTF)
InputStream ins = conn.getInputStream();
final ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamUtils.copy(ins, out);
ins.close();
 
DataInputStream in = new DataInputStream(new ByteArrayInputStream(out.toByteArray()));
 
DataInputStream in = new DataInputStream(new BufferedInputStream(conn.getInputStream()));
int fileCount = in.readInt();
this.byteReceived += 4;
ArrayList<FileProperty> list = new ArrayList<FileProperty>();
885,6 → 875,4
public void setVerifyHost(boolean verify) {
this.verifyHost = verify;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/i18n/translation/messages_es.properties
File deleted
\ No newline at end of file
/trunk/OpenConcerto/src/org/openconcerto/utils/i18n/translation/messages_en.properties
6,7 → 6,6
linkOpenError=Error while opening {0}
 
memory=memory
memory.used=memory used
megabytes={0} MB
processors={0, plural, one { # processor } other { # processors } }
os=Operating system
13,8 → 12,6
javaVersion=Version <b>{0}</b> of {1}
javaHome=installation directory
no.laf=No look and feel
properties.all=All properties
env.all=Whole environment
 
user=User
home.dir=home directory
29,18 → 26,4
 
cut=Cut
copy=Copy
paste=Paste
 
# search
all=All
toReverse=Reverse
 
contains=Contains
contains.exactly=Contains exactly
isLessThan=Is less than
isLessThanOrEqualTo=Is less than or equal to
isEqualTo=Is equal to
isExactlyEqualTo=Is exactly equal to
isGreaterThan=Is greater than
isGreaterThanOrEqualTo=Is greater than or equal to
isEmpty=Is empty
paste=Paste
/trunk/OpenConcerto/src/org/openconcerto/utils/i18n/translation/messages_sp.properties
New file
0,0 → 1,8
true_key=verdadero
false_key=falso
yes_key=sí
no_key=no
 
cut=Cortar
copy=Copiar
paste=Pegar
/trunk/OpenConcerto/src/org/openconcerto/utils/i18n/translation/messages_fr.properties
6,7 → 6,6
linkOpenError=Impossible d''ouvrir {0}
 
memory=mémoire
memory.used=mémoire utilisée
megabytes={0} Mo
processors={0, plural, one { # processeur } other { # processeurs } }
os=Système d''exploitation
13,8 → 12,6
javaVersion=Version <b>{0}</b> de {1}
javaHome=dossier d'installation
no.laf=Aucun thème
properties.all=Toutes les propriétés
env.all=Tout l'environnement
 
user=Utilisateur
home.dir=dossier utilisateur
30,20 → 27,3
cut=Couper
copy=Copier
paste=Coller
 
# search
all=Tout
toReverse=inverser
 
contains=Contient
contains.exactly=Contient exactement
startsWith=Commence par
endsWith=Finit par
isLessThan=Est inférieur à
isLessThanOrEqualTo=Est inférieur ou égal à
isEqualTo=Est égal à
isExactlyEqualTo=Est exactement égal à
isGreaterThan=Est supérieur à
isGreaterThanOrEqualTo=Est supérieur ou égal à
isEmpty=Est vide
matchRegexp=Correspond à l'expression régulière
/trunk/OpenConcerto/src/org/openconcerto/utils/i18n/translation/messages_pl.properties
27,17 → 27,3
cut=Wytnij
copy=Kopi\u0119
paste=Wklej
 
# search
all=All
toReverse=Reverse
 
contains=Contains
contains.exactly=Contains exactly
isLessThan=Is less than
isLessThanOrEqualTo=Is less than or equal to
isEqualTo=Is equal to
isExactlyEqualTo=Is exactly equal to
isGreaterThan=Is greater than
isGreaterThanOrEqualTo=Is greater than or equal to
isEmpty=Is empty
/trunk/OpenConcerto/src/org/openconcerto/utils/SystemInfo.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
47,8 → 47,6
}
 
public static final String CLASS_PROTOCOL = "class";
public static final String PROPS_PROTOCOL = "props";
public static final String ENV_PROTOCOL = "env";
 
static public NavigableMap<Info, String> get(final boolean html, final Locale locale) {
final TM tm = TM.getInstance(locale);
69,22 → 67,12
e1.printStackTrace();
}
final Runtime rt = Runtime.getRuntime();
final long totalMemory = rt.totalMemory();
final String stats = "<i>" + tm.translate("memory.used") + " :</i> " + formatBytes(tm, totalMemory - rt.freeMemory()) + " / " + formatBytes(tm, totalMemory) + " ; "
final String stats = "<i>" + tm.translate("memory") + " :</i> " + formatBytes(tm, rt.freeMemory()) + " / " + formatBytes(tm, rt.totalMemory()) + " ; "
+ tm.translate("processors", rt.availableProcessors());
final String lafDesc = lookAndFeel == null ? tm.translate("no.laf") : getLink(lookAndFeel.getName(), lafURI, html) + ", " + lookAndFeel.getDescription();
URI propsURI = null;
URI envURI = null;
try {
propsURI = new URI(PROPS_PROTOCOL, "/", null);
envURI = new URI(ENV_PROTOCOL, "/", null);
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
final String propsDesc = envURI == null ? "" : lineBreak + getLink(tm.translate("properties.all"), propsURI, html) + ", " + getLink(tm.translate("env.all"), envURI, html);
 
final String p = tm.translate("javaVersion", version, getLink(getProperty("java.vendor"), vendorURI, html)) + " ; "
+ getLink(tm.translate("javaHome"), new File(getProperty("java.home")).toURI(), html) + lineBreak + stats + lineBreak + lafDesc + propsDesc;
+ getLink(tm.translate("javaHome"), new File(getProperty("java.home")).toURI(), html) + lineBreak + stats + lineBreak + lafDesc;
 
res.put(Info.JAVA, p);
 
/trunk/OpenConcerto/src/org/openconcerto/utils/FormatGroup.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
27,7 → 27,7
*/
public class FormatGroup extends Format {
 
private final List<Format> formats;
private final List<? extends Format> formats;
private int formatIndex;
 
public FormatGroup(Format... formats) {
44,11 → 44,11
public FormatGroup(final List<? extends Format> formats) {
if (formats.size() == 0)
throw new IllegalArgumentException("formats must not be empty");
this.formats = CollectionUtils.toImmutableList(formats);
this.formats = formats;
this.formatIndex = 0;
}
 
public final List<Format> getFormats() {
public final List<? extends Format> getFormats() {
return this.formats;
}
 
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/IExnRunnable.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/CopyOnWriteList.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/ListIdentitySet.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/ArrayIdentitySet.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/CustomEquals.java
31,15 → 31,6
*/
public class CustomEquals {
 
static public final <T> boolean nullSafeEquals(final T o1, final T o2, final BiPredicate<? super T, ? super T> equal) {
if (o1 == null)
return o2 == null;
else if (o2 == null)
return false;
else
return equal.test(o1, o2);
}
 
static private final HashingStrategy<Object> DEFAULT = new HashingStrategy<Object>() {
@Override
public boolean equals(Object object1, Object object2) {
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/IncludeExclude.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
50,40 → 50,13
 
@SafeVarargs
public static <T> IncludeExclude<T> getNormalized(final T... includes) {
return getNormalizedInclude(Arrays.asList(includes));
return getNormalized(Arrays.asList(includes));
}
 
@Deprecated
public static <T> IncludeExclude<T> getNormalized(final Collection<? extends T> includes) {
return getNormalizedInclude(includes);
}
 
/**
* Return the normalized version including only the passed values. E.g. if <code>includes</code>
* is empty or <code>null</code>, this won't allocate any memory and {@link #getEmpty()} or
* {@link #getFull()} will be returned.
*
* @param <T> type of items
* @param includes which values to include.
* @return the normalized version.
*/
public static <T> IncludeExclude<T> getNormalizedInclude(final Collection<? extends T> includes) {
return getNormalized(includes, Collections.<T> emptySet());
}
 
/**
* Return the normalized version excluding only the passed values. E.g. if <code>excludes</code>
* is empty or <code>null</code>, this won't allocate any memory and {@link #getFull()} or
* {@link #getEmpty()} will be returned.
*
* @param <T> type of items
* @param excludes which values to exclude.
* @return the normalized version.
*/
public static <T> IncludeExclude<T> getNormalizedExclude(final Collection<? extends T> excludes) {
return getNormalized(null, excludes);
}
 
public static <T> IncludeExclude<T> getNormalized(final Collection<? extends T> includes, final Collection<? extends T> excludes) {
return new IncludeExclude<T>(includes, excludes).normal;
}
101,7 → 74,6
*
* @param includes which objects to include, <code>null</code> meaning all.
* @param excludes which objects to exclude, <code>null</code> meaning all.
* @see #isIncluded(Object)
*/
public IncludeExclude(final Collection<? extends T> includes, final Collection<? extends T> excludes) {
this(includes, excludes, false);
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/IdentityHashSet.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
29,8 → 29,6
*/
public final class IdentityHashSet<E> extends AbstractSet<E> implements IdentitySet<E>, Cloneable {
 
static private final Object VALUE = new Object();
 
private final IdentityHashMap<E, Object> map;
 
public IdentityHashSet() {
48,8 → 46,13
 
@Override
public boolean add(E e) {
return this.map.put(e, VALUE) != VALUE;
if (this.contains(e))
return false;
else {
this.map.put(e, null);
return true;
}
}
 
@Override
public boolean addAll(Collection<? extends E> c) {
79,7 → 82,7
 
@Override
public boolean contains(Object o) {
return this.map.containsKey(o);
return this.map.keySet().contains(o);
}
 
@Override
89,7 → 92,7
 
@Override
public boolean remove(Object o) {
return this.map.remove(o) == VALUE;
return this.map.keySet().remove(o);
}
 
@Override
112,14 → 115,6
return this.map.keySet().toArray(a);
}
 
// use System.identityHashCode()
@Override
public int hashCode() {
return this.map.keySet().hashCode();
}
 
// equals() uses containsAll which is correct
 
/**
* Returns a shallow copy of this <tt>HashSet</tt> instance: the elements themselves are not
* cloned.
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/CopyOnWriteMap.java
96,28 → 96,28
}
 
@Override
public int size() {
return this.getImmutable().size();
public synchronized int size() {
return this.immutable.size();
}
 
@Override
public boolean isEmpty() {
return this.getImmutable().isEmpty();
public synchronized boolean isEmpty() {
return this.immutable.isEmpty();
}
 
@Override
public boolean containsKey(final Object key) {
return this.getImmutable().containsKey(key);
public synchronized boolean containsKey(final Object key) {
return this.immutable.containsKey(key);
}
 
@Override
public boolean containsValue(final Object value) {
return this.getImmutable().containsValue(value);
public synchronized boolean containsValue(final Object value) {
return this.immutable.containsValue(value);
}
 
@Override
public V get(final Object key) {
return this.getImmutable().get(key);
public synchronized V get(final Object key) {
return this.immutable.get(key);
}
 
@Override
177,12 → 177,12
// equals
 
@Override
public boolean equals(final Object o) {
return this.getImmutable().equals(o);
public synchronized boolean equals(final Object o) {
return this.immutable.equals(o);
}
 
@Override
public int hashCode() {
return this.getImmutable().hashCode();
public synchronized int hashCode() {
return this.immutable.hashCode();
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/LinkedIdentitySet.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
13,8 → 13,12
package org.openconcerto.utils.cc;
 
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
 
/**
* An IdentitySet maintaining insertion order.
22,25 → 26,119
* @param <E> the type of elements maintained by this set
* @see IdentityHashSet
*/
public final class LinkedIdentitySet<E> extends ListIdentitySet<E> implements Cloneable {
public final class LinkedIdentitySet<E> extends AbstractSet<E> implements IdentitySet<E>, Cloneable {
 
private final LinkedList<E> list;
 
public LinkedIdentitySet() {
super();
this.list = new LinkedList<E>();
}
 
public LinkedIdentitySet(int expectedSize) {
super(expectedSize);
public LinkedIdentitySet(Collection<? extends E> c) {
this.list = new LinkedList<E>();
this.addAll(c);
}
 
public LinkedIdentitySet(Collection<? extends E> c) {
super(c);
public final List<E> getList() {
return Collections.unmodifiableList(this.list);
}
 
@Override
protected LinkedList<E> newList(int expectedSize) {
return new LinkedList<>();
public boolean add(E e) {
if (this.contains(e))
return false;
else {
this.list.add(e);
return true;
}
}
 
@Override
public boolean addAll(Collection<? extends E> c) {
// let the super which calls add() since we don't want to build a map to use Map.addAll()
return super.addAll(c);
}
 
@Override
public void clear() {
this.list.clear();
}
 
@Override
public int size() {
return this.list.size();
}
 
@Override
public boolean isEmpty() {
return this.list.isEmpty();
}
 
@Override
public Iterator<E> iterator() {
return this.list.iterator();
}
 
@Override
public boolean contains(Object o) {
Iterator<E> e = iterator();
while (e.hasNext())
if (o == e.next())
return true;
return false;
}
 
@Override
public boolean containsAll(Collection<?> c) {
// let the super which calls contains()
return super.containsAll(c);
}
 
@Override
public boolean remove(Object o) {
Iterator<E> e = iterator();
while (e.hasNext()) {
if (o == e.next()) {
e.remove();
return true;
}
}
return false;
}
 
/*
* (From IdentityHashMap) Must revert from AbstractSet's impl to AbstractCollection's, as the
* former contains an optimization that results in incorrect behavior when c is a smaller
* "normal" (non-identity-based) Set.
*/
@Override
public boolean removeAll(Collection<?> c) {
boolean modified = false;
for (Iterator<E> i = iterator(); i.hasNext();) {
if (c.contains(i.next())) {
i.remove();
modified = true;
}
}
return modified;
}
 
@Override
public boolean retainAll(Collection<?> c) {
// let the super which calls remove()
return super.retainAll(c);
}
 
@Override
public Object[] toArray() {
return this.list.toArray();
}
 
@Override
public <T> T[] toArray(T[] a) {
return this.list.toArray(a);
}
 
/**
* Returns a shallow copy of this <tt>HashSet</tt> instance: the elements themselves are not
* cloned.
47,7 → 145,6
*
* @return a shallow copy of this set
*/
@Override
public Object clone() {
return new LinkedIdentitySet<E>(this);
}
/trunk/OpenConcerto/src/org/openconcerto/utils/cc/Cookies.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
21,7 → 21,6
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
 
import com.google.gson.reflect.TypeToken;
 
188,21 → 187,6
return res;
}
public final <T> Collection<T> computeCollectionIfAbsent(Object k, Class<T> clazz, Function<Object, ? extends Collection<T>> mappingFunction) {
Collection<T> res;
synchronized (this) {
res = this.getCollection(k, clazz);
// same algorithm as java.util.Map
if (res == null) {
res = mappingFunction.apply(k);
if (res != null)
this.putCollection(k, res, clazz);
}
}
return res;
}
 
 
public final <T> List<T> getList(Object k, Class<T> clazz) {
return (List<T>) this.getCollection(k, clazz);
}
218,20 → 202,6
return res;
}
 
public final <K, V> Map<K, V> computeMapIfAbsent(Object k, Class<K> keyClass, Class<V> valueClass, Function<Object, ? extends Map<K, V>> mappingFunction) {
Map<K, V> res;
synchronized (this) {
res = this.getMap(k, keyClass, valueClass);
// same algorithm as java.util.Map
if (res == null) {
res = mappingFunction.apply(k);
if (res != null)
this.putMap(k, res, keyClass, valueClass);
}
}
return res;
}
 
public final <T> T getGeneric(Object k, TypeToken<T> clazz) {
final Object object = checkType(k, clazz, "putGeneric()");
@SuppressWarnings("unchecked")
239,20 → 209,6
return res;
}
 
public final <T> T computeIfAbsent(Object k, TypeToken<T> clazz, Function<Object, ? extends T> mappingFunction) {
T res;
synchronized (this) {
res = this.getGeneric(k, clazz);
// same algorithm as java.util.Map
if (res == null) {
res = mappingFunction.apply(k);
if (res != null)
this.putGeneric(k, res, clazz);
}
}
return res;
}
 
@Override
public synchronized String toString() {
return this.getClass().getSimpleName() + " of " + this.map.keySet();
/trunk/OpenConcerto/src/org/openconcerto/utils/ReentrantEventDispatcher.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
21,12 → 21,6
 
/**
* Allow to maintain the dispatching of events in order when a listener itself fires an event.
* <p>
* If each notification simply goes through a list of listeners, the events are delivered out of
* order : <img src="doc-files/reentrantEventsNaive.png" />
* <p>
* This class adds new notifications at the end of a list, but resume notifying from the start of
* the list. <img src="doc-files/reentrantEventsIn-order.png" />
*
* @author sylvain
*
36,30 → 30,12
*/
public final class ReentrantEventDispatcher<L, E, X extends Exception> {
 
public final class DispatchingState {
private final Iterator<L> iter;
private final BiConsumerExn<L, E, X> callback;
private final E evt;
 
private DispatchingState(final Iterator<L> iter, BiConsumerExn<L, E, X> callback, final E evt) {
this.iter = Objects.requireNonNull(iter, "Missing iterator");
this.callback = Objects.requireNonNull(callback, "Missing callback");
this.evt = evt;
private final class DispatchingState extends Tuple3<Iterator<L>, BiConsumerExn<L, E, X>, E> {
public DispatchingState(final Iterator<L> iter, BiConsumerExn<L, E, X> callback, final E evt) {
super(Objects.requireNonNull(iter, "Missing iterator"), Objects.requireNonNull(callback, "Missing callback"), evt);
}
 
private final Iterator<L> getIterator() {
return this.iter;
}
 
private final BiConsumerExn<L, E, X> getCallback() {
return this.callback;
}
 
public final E getEvt() {
return this.evt;
}
}
 
private final ThreadLocal<LinkedList<DispatchingState>> events = new ThreadLocal<LinkedList<DispatchingState>>() {
@Override
protected LinkedList<DispatchingState> initialValue() {
79,22 → 55,14
}
 
public final void fire(final Iterator<L> iter, final E evt) throws X {
this.fire(this.createDispatchingState(iter, evt));
this.fire(iter, this.callback, evt);
}
 
public final void fire(final Iterator<L> iter, final BiConsumerExn<L, E, X> callback, final E evt) throws X {
this.fire(this.createDispatchingState(iter, callback, evt));
this.fire(new DispatchingState(iter, callback, evt));
}
 
public final DispatchingState createDispatchingState(final Iterator<L> iter, final E evt) {
return this.createDispatchingState(iter, this.callback, evt);
}
 
public final DispatchingState createDispatchingState(final Iterator<L> iter, final BiConsumerExn<L, E, X> callback, final E evt) {
return new DispatchingState(iter, callback, evt);
}
 
public final void fire(final DispatchingState newTuple) throws X {
private final void fire(final DispatchingState newTuple) throws X {
final LinkedList<DispatchingState> linkedList = this.events.get();
// add new event
linkedList.addLast(newTuple);
101,34 → 69,16
// process all pending events
DispatchingState currentTuple;
while ((currentTuple = linkedList.peekFirst()) != null) {
final Iterator<L> currentIter = currentTuple.getIterator();
final BiConsumerExn<L, E, X> currentCallback = currentTuple.getCallback();
final E currentEvt = currentTuple.getEvt();
final Iterator<L> currentIter = currentTuple.get0();
final BiConsumerExn<L, E, X> currentCallback = currentTuple.get1();
final E currentEvt = currentTuple.get2();
while (currentIter.hasNext()) {
final L l = currentIter.next();
currentCallback.accept(l, currentEvt);
}
/*
* It isn't because one callback failed that the event itself didn't happen or should be
* reverted : we should still notify the other callbacks. So don't use a finally block
* to remove currentTuple. But if the event should indeed be reverted (e.g. the callback
* was a check), #remove(DispatchingState) should be called.
*/
// not removeFirst() since the item might have been already removed
linkedList.pollFirst();
}
}
 
/**
* Remove a dispatching state. Useful because if there's an exception while notifying the
* listeners, then the next {@link #fire(DispatchingState)} in the same thread will by default
* resume notifying the listeners. That behaviour is not valid for a reverted DB transaction.
*
* @param dispatchingState what to remove.
* @return {@code true} if the item was actually removed.
* @see #createDispatchingState(Iterator, Object)
*/
public final boolean remove(DispatchingState dispatchingState) {
return this.events.get().remove(dispatchingState);
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/TimeUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
15,9 → 15,6
 
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
427,30 → 424,4
}
return finerAmount == finer.convert(coarserAmount, coarser);
}
 
public static LocalDateTime toLocalDateTime(Calendar calendar) {
if (calendar == null)
return null;
return LocalDateTime.ofInstant(calendar.toInstant(), getTZ(calendar));
}
 
private static ZoneId getTZ(Calendar calendar) {
final TimeZone tz = calendar.getTimeZone();
return tz == null ? ZoneId.systemDefault() : tz.toZoneId();
}
 
public static final Calendar toCalendar(final LocalDateTime dt) {
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(dt.atZone(getTZ(cal)).toInstant().toEpochMilli());
return cal;
}
 
public static LocalDate toLocalDate(Calendar calendar) {
if (calendar == null)
return null;
if (calendar instanceof GregorianCalendar)
return LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH));
else
return toLocalDateTime(calendar).toLocalDate();
}
}
/trunk/OpenConcerto/src/org/openconcerto/utils/model/ListComboBoxModel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
27,8 → 27,6
*/
public class ListComboBoxModel<T> extends DefaultIMutableListModel<T> implements MutableComboBoxModel<T> {
private boolean truncated;
 
public ListComboBoxModel() {
this(Collections.<T> emptyList());
}
46,12 → 44,4
this.removeForJRE(obj);
}
 
public void setTruncated(boolean truncated) {
this.truncated = truncated;
}
 
public boolean isTruncated() {
return this.truncated;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/TinyMap.java
13,223 → 13,187
package org.openconcerto.utils;
 
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
 
public class TinyMap<K, V> extends AbstractMap<K, V> {
private static final Function<Entry<?, ?>, Object> KEY_GETTER = Entry::getKey;
private static final Function<Entry<?, ?>, Object> VALUE_GETTER = Entry::getValue;
public class TinyMap<K, V> implements Map<K, V> {
private final ArrayList<K> keys;
private final ArrayList<V> values;
 
private final ArrayList<Entry<K, V>> entries;
private transient Set<Map.Entry<K, V>> entrySet;
/**
* The number of times this HashMap has been structurally modified Structural modifications are
* those that change the number of mappings in the HashMap or otherwise modify its internal
* structure (e.g., rehash). This field is used to make iterators on Collection-views of the
* HashMap fail-fast. (See ConcurrentModificationException).
*/
transient int modCount = 0;
 
public TinyMap() {
this(10);
}
 
public TinyMap(final int initialCapacity) {
this.entries = new ArrayList<>(initialCapacity);
public TinyMap(int initialCapacity) {
keys = new ArrayList<K>(initialCapacity);
values = new ArrayList<V>(initialCapacity);
}
 
public TinyMap(final Map<? extends K, ? extends V> m) {
this.entries = new ArrayList<>(m.size());
// don't call putAll() to avoid indexOfKey()
for (final Entry<? extends K, ? extends V> e : m.entrySet()) {
this.entries.add(new SimpleEntry<>(e));
}
++this.modCount;
}
 
@Override
public int size() {
return this.entries.size();
return keys.size();
}
 
@Override
public boolean isEmpty() {
return this.entries.isEmpty();
return keys.isEmpty();
}
 
@Override
public boolean containsKey(final Object key) {
return indexOfKey(key) >= 0;
public boolean containsKey(Object key) {
return keys.contains(key);
}
 
@Override
public boolean containsValue(final Object value) {
return this.indexOf(value, VALUE_GETTER) >= 0;
public boolean containsValue(Object value) {
return values.contains(value);
}
 
private int indexOfKey(final Object key) {
return this.indexOf(key, KEY_GETTER);
@Override
public V get(Object key) {
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
if (this.keys.get(i).equals(key)) {
return this.values.get(i);
}
 
private final int indexOf(final Object o, final Function<Entry<?, ?>, Object> getter) {
final int stop = this.entries.size();
for (int i = 0; i < stop; i++) {
final Entry<K, V> e = this.entries.get(i);
if (Objects.equals(o, getter.apply(e)))
return i;
}
return -1;
return null;
}
 
@Override
public V get(final Object key) {
final int i = indexOfKey(key);
if (i < 0)
public V put(K key, V value) {
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
if (this.keys.get(i).equals(key)) {
final V old = this.values.get(i);
this.values.set(i, value);
return old;
}
}
this.keys.add(key);
this.values.add(value);
return null;
return this.entries.get(i).getValue();
}
 
@Override
public V put(final K key, final V value) {
final int i = this.indexOfKey(key);
final V res;
if (i < 0) {
this.entries.add(new SimpleEntry<>(key, value));
++this.modCount;
res = null;
} else {
res = this.entries.get(i).setValue(value);
public V remove(Object key) {
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
if (this.keys.get(i).equals(key)) {
this.keys.remove(i);
return this.values.remove(i);
}
return res;
}
 
@Override
public V remove(final Object key) {
return this.remove(indexOfKey(key));
}
 
private V remove(final int i) {
if (i < 0)
return null;
final Entry<K, V> res = this.entries.remove(i);
++this.modCount;
return res.getValue();
}
 
@Override
public boolean remove(final Object key, final Object value) {
final int i = indexOfKey(key);
if (i < 0)
return false;
final boolean eqVal = Objects.equals(this.entries.get(i).getValue(), value);
if (eqVal) {
this.remove(i);
public void putAll(Map<? extends K, ? extends V> m) {
final Set<? extends K> keySet = m.keySet();
for (Iterator<? extends K> iterator = keySet.iterator(); iterator.hasNext();) {
K key = (K) iterator.next();
put(key, m.get(key));
}
return eqVal;
}
 
@Override
public void clear() {
this.entries.clear();
++this.modCount;
this.keys.clear();
this.values.clear();
}
 
// Views
 
@Override
public Set<Map.Entry<K, V>> entrySet() {
Set<Map.Entry<K, V>> es;
return (es = this.entrySet) == null ? (this.entrySet = new EntrySet()) : es;
}
 
final class EntrySet extends AbstractSet<Map.Entry<K, V>> {
public Set<K> keySet() {
return new HashSet<K>(this.keys) {
@Override
public final int size() {
return TinyMap.this.size();
public boolean remove(Object o) {
TinyMap.this.remove(o);
return super.remove(o);
}
 
@Override
public final void clear() {
TinyMap.this.clear();
public void clear() {
clear();
super.clear();
}
};
}
 
@Override
public final Iterator<Map.Entry<K, V>> iterator() {
return new Iterator<Map.Entry<K, V>>() {
public Collection<V> values() {
 
private int expectedModCount = TinyMap.this.modCount;
/**
* The index last returned, i.e. initial value just before first item.
*
* <pre>
* a b c
* -1 0 1 2
* </pre>
*/
private int currentPos = -1;
private Entry<K, V> lastReturned = null;
 
return new ArrayList<V>(this.values()) {
@Override
public boolean hasNext() {
final int nextIndex = this.currentPos + 1;
return nextIndex < size();
public V remove(int index) {
keys.remove(index);
values.remove(index);
return super.remove(index);
}
 
@Override
public Entry<K, V> next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
this.currentPos++;
final Entry<K, V> res = TinyMap.this.entries.get(this.currentPos);
this.lastReturned = res;
return res;
public boolean remove(Object o) {
int index = values.indexOf(o);
if (index >= 0) {
keys.remove(index);
values.remove(index);
}
return super.remove(o);
}
 
@Override
public void remove() {
checkForComodification();
if (this.lastReturned == null)
throw new IllegalStateException();
TinyMap.this.remove(this.currentPos);
this.currentPos--;
// per doc : cannot be called twice
this.lastReturned = null;
this.expectedModCount = TinyMap.this.modCount;
public void clear() {
clear();
super.clear();
}
};
}
 
final void checkForComodification() {
if (TinyMap.this.modCount != this.expectedModCount)
throw new ConcurrentModificationException();
@Override
public Set<Entry<K, V>> entrySet() {
final Set<Entry<K, V>> set = new HashSet<Map.Entry<K, V>>() {
@Override
public boolean remove(Object o) {
Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
int index = values.indexOf(entry.getValue());
if (index >= 0) {
keys.remove(index);
values.remove(index);
}
};
return super.remove(o);
}
 
@Override
public final boolean contains(final Object o) {
if (!(o instanceof Map.Entry))
return false;
final Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
return TinyMap.this.entries.contains(e);
public boolean removeAll(Collection<?> c) {
for (Iterator iterator = c.iterator(); iterator.hasNext();) {
Entry<K, V> entry = (Entry<K, V>) iterator.next();
int index = values.indexOf(entry.getValue());
if (index >= 0) {
keys.remove(index);
values.remove(index);
}
}
return super.removeAll(c);
}
 
@Override
public final boolean remove(final Object o) {
if (o instanceof Map.Entry) {
final Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
final Object key = e.getKey();
final Object value = e.getValue();
return TinyMap.this.remove(key, value);
public void clear() {
clear();
super.clear();
}
return false;
 
};
final int size = this.keys.size();
for (int i = 0; i < size; i++) {
set.add(new SimpleImmutableEntry<K, V>(this.keys.get(i), this.values.get(i)));
}
return set;
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/utils/Platform.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
18,7 → 18,6
import org.openconcerto.utils.cc.ITransformer;
 
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
26,7 → 25,6
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
42,8 → 40,6
*/
public abstract class Platform {
 
public static final String PROCESS_ALLOW_AMBIGUOUS_COMMANDS = "jdk.lang.Process.allowAmbiguousCommands";
 
private static final int PING_TIMEOUT = 250;
 
public static final Platform getInstance() {
59,19 → 55,6
}
}
 
public static class CannotPassArgumentException extends RuntimeException {
private final String arg;
 
private CannotPassArgumentException(String arg, String message) {
super("Cannot pass " + arg + message);
this.arg = arg;
}
 
public final String getArg() {
return this.arg;
}
}
 
public abstract boolean supportsPID();
 
public abstract boolean isRunning(final int pid) throws IOException;
78,14 → 61,6
 
public abstract String getPath(final File f);
 
public String getPath(final Path p) {
return this.getPath(p.toFile());
}
 
public String getProcessArg(final String arg) {
return arg;
}
 
public final String getPID() throws IOException {
// TODO remove reflection and getPreJava9PID() once on java 11
try {
178,19 → 153,7
// Keep errors out of cmdSubstitution() (e.g. "ping: sendto: Message too long" when
// setDontFragment(true))
final Process proc = evalPB(command).redirectErrorStream(false).start();
 
// some programs won't write anything until they read everything
proc.getOutputStream().close();
final ByteArrayOutputStream out = new ByteArrayOutputStream(5 * 1024);
final ByteArrayOutputStream err = new ByteArrayOutputStream(2 * 1024);
try (final ProcessStreams streams = new ProcessStreams(proc)) {
streams.start(out, err);
streams.awaitTermination();
} catch (Exception e) {
throw new IllegalStateException("Couldn't capture output of ping", e);
}
 
final String output = out.toString();
final String output = cmdSubstitution(proc);
try {
this.waitForSuccess(proc, "ping");
final List<String> countAndLastLine = StringUtils.splitIntoLines(output);
201,7 → 164,7
final BigDecimal averageRTT = replied == 0 ? null : parsePingAverageRT(countAndLastLine.get(1).trim());
return new PingResult(totalCount, replied, requiredCount, averageRTT);
} catch (Exception e) {
throw new IllegalStateException("Couldn't use output :<<<\n" + output + "\n<<<\nerr:<<<\n" + err.toString() + "\n<<<", e);
throw new IllegalStateException("Couldn't use output :<<<\n" + output + "\n<<<", e);
}
}
 
267,17 → 230,11
return this.exitStatus(p) == 0;
}
 
@Override
public String getPath(final File f) {
return f.getPath();
}
 
@Override
public String getPath(final Path f) {
return f.toString();
}
 
@Override
protected String getBash() {
return "bash";
}
424,129 → 381,9
}
};
 
// return 171 for "1.8.0_171"
// return 11 for "11.0.11"
public static final int getUpdateVersion(final char sep) {
final String vers = System.getProperty("java.version");
final int lastIndexOf = vers.lastIndexOf(sep);
// e.g. "13"
if (lastIndexOf < 0)
return 0;
return Integer.parseInt(vers.substring(lastIndexOf + 1));
}
private static final class CygwinPlatform extends Platform {
 
public static abstract class WindowsPlatform extends Platform {
// on Windows program themselves are required to parse the command line, thus a lot of them
// do it differently, see "How Command Line Parameters Are Parsed"
// https://daviddeley.com/autohotkey/parameters/parameters.htm
 
static private final Pattern quotePatrn = Pattern.compile("([\\\\]*)\"");
static private final Pattern endSlashPatrn = Pattern.compile("([\\\\]+)\\z");
 
static private boolean needsQuoting(String s) {
final int len = s.length();
if (len == 0) // empty string have to be quoted
return true;
for (int i = 0; i < len; i++) {
switch (s.charAt(i)) {
case ' ':
case '\t':
case '"':
return true;
}
}
return false;
}
 
// see http://bugs.sun.com/view_bug.do?bug_id=6468220
// e.g. find.exe, choice.exe
public String quoteParamForMsftC(String s) {
if (!needsQuoting(s))
return s;
if (s.length() > 0) {
// replace '(\*)"' by '$1$1\"', e.g. '\quote " \"' by '\quote \" \\\"'
// $1 needed so that the backslash we add isn't escaped itself by a preceding
// backslash
s = quotePatrn.matcher(s).replaceAll("$1$1\\\\\"");
// replace '(\*)\z' by '$1$1', e.g. 'foo\' by 'foo\\'
// needed to not escape closing quote
s = endSlashPatrn.matcher(s).replaceAll("$1$1");
}
return '"' + s + '"';
}
 
@Override
public String getProcessArg(String arg) {
return this.getProcessArg(arg, false);
}
 
public final String getScriptProcessArg(String arg) {
return this.getProcessArg(arg, true);
}
 
private String getProcessArg(String arg, final boolean script) {
// Perhaps should have one method for .exe and one for .cmd/.bat (ProcessImpl checks
// with isShellFile() and isExe()).
 
if (script && arg.indexOf('"') >= 0)
throw new CannotPassArgumentException(arg, ", it contains a double quote which is always removed by wscript!SplitCommandLine()");
 
/*
* If has VERIFICATION_WIN32_SAFE && !allowAmbiguousCommands, then ProcessImpl behaves
* almost correctly : the argument we pass arrives as-is to the process (so the caller
* shouldn't quote, ProcessImpl will fail with "Malformed argument has embedded quote"
* if a character was escaped). Otherwise ProcessImpl does nothing if arg begins and
* ends with double quotes (it's the caller responsibility to correctly quote).
*/
final boolean doubleQuote;
// 1.8 or 11
final String specVers = System.getProperty("java.specification.version");
// 8 or 11
final int jreFamilyVersion = Integer.parseInt(specVers.startsWith("1.") ? specVers.substring(2) : specVers);
final String javaVendor = System.getProperty("java.vendor");
// VERIFICATION_WIN32_SAFE thanks to https://nvd.nist.gov/vuln/detail/CVE-2019-2958
// For Oracle and OpenJDK :
// https://www.oracle.com/java/technologies/javase/8u231-relnotes.html#JDK-8221858
// https://github.com/openjdk/jdk/commit/5a98b8cfb0cd4c5ce84746e9fa5e42a86d1b2d24#diff-71e1dde85b2937bbf08d0bfd9e8a2e3553c578a3f58907ba6f4f30ec350db184
// For AdoptOpenJDK :
// https://github.com/AdoptOpenJDK/openjdk-jdk11u/commit/0074850a15405a676a492d09e4955d4053966bbc#diff-71e1dde85b2937bbf08d0bfd9e8a2e3553c578a3f58907ba6f4f30ec350db184
if (jreFamilyVersion >= 14 || (javaVendor.equals("AdoptOpenJDK") && (jreFamilyVersion == 11 && getUpdateVersion('.') >= 5 || jreFamilyVersion == 13 && getUpdateVersion('.') >= 1))
|| (jreFamilyVersion == 8 && getUpdateVersion('_') >= 231)) {
// copied from ProcessImpl
final SecurityManager security = System.getSecurityManager();
final String value = System.getProperty(PROCESS_ALLOW_AMBIGUOUS_COMMANDS, (security == null ? "true" : "false"));
final boolean allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
if ((script || allowAmbiguousCommands) && arg.endsWith("\\")) {
// with script, we always do our own quoting since ProcessBuilder will double
// back slashes.
if (script || needsQuoting(arg)) {
throw new CannotPassArgumentException(arg,
", if we'd double quote, then the string would end with 2 back slashes and 1 double quote, but ProcessImpl.unQuote() : 'not properly quoted, treat as unquoted'. So it would get quoted a second time. Try setting '"
+ PROCESS_ALLOW_AMBIGUOUS_COMMANDS + "' to 'false'.");
} else {
doubleQuote = false;
}
} else if (!allowAmbiguousCommands && arg.length() >= 2 && arg.charAt(0) == '"' && arg.charAt(arg.length() - 1) == '"') {
throw new CannotPassArgumentException(arg,
"\nif we pass it as-is then ProcessImpl will consider the string already quoted and needsEscaping() will return false, thus the quotes will be removed by CommandLineToArgvW()"
+ "\nif we quote it then ProcessImpl.needsEscaping() will throw 'Malformed argument has embedded quote'");
} else {
doubleQuote = allowAmbiguousCommands;
}
} else {
doubleQuote = true;
}
 
if (script)
return '"' + arg + '"';
else
return doubleQuote ? quoteParamForMsftC(arg) : arg;
}
}
 
private static final class CygwinPlatform extends WindowsPlatform {
 
@Override
public boolean supportsPID() {
return false;
}
/trunk/OpenConcerto/src/org/openconcerto/utils/TableSorter.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
468,13 → 468,8
} else if (o2 == null) {
comparison = 1;
} else {
final Comparator comparator = getComparator(column);
try {
comparison = comparator.compare(o1, o2);
} catch (Exception e) {
throw new IllegalStateException("Couldn't compare column " + column + " using " + comparator + " for objects " + o1 + " and " + o2, e);
comparison = getComparator(column).compare(o1, o2);
}
}
if (comparison != 0) {
return directive.direction == DESCENDING ? -comparison : comparison;
}
650,11 → 645,6
 
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (column < 0) {
Log.get().severe("out of bound renderer, column :" + column);
return new JLabel("");
}
 
Component c = tableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (c instanceof JLabel) {
JLabel l = (JLabel) c;
/trunk/OpenConcerto/src/org/openconcerto/utils/ProcessStreams.java
21,14 → 21,10
import java.io.PrintStream;
import java.lang.ProcessBuilder.Redirect;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
 
/**
36,41 → 32,55
*
* @author Sylvain
*/
public class ProcessStreams implements AutoCloseable {
public class ProcessStreams {
 
// Don't set too low, this is a maximum, it would only fail on slow computers.
private static final int MAX_SHUTTING_DOWN_DELAY = 500;
static public enum Action {
/**
* Redirect process streams to ours.
*
* @deprecated use {@link ProcessStreams#redirect(ProcessBuilder)} (or
* {@link Redirect#INHERIT} directly) as it makes sure that
* {@link Process#waitFor()} only returns once all streams are flushed.
*/
REDIRECT,
/**
* Consume streams.
*/
CONSUME,
/**
* Close process streams. NOTE : some programs might fail (e.g. route on FreeBSD), in those
* cases use {@link #CONSUME}.
*/
CLOSE,
/**
* Do nothing, which is dangerous as the process will hang until its output is read.
*/
DO_NOTHING
}
 
// Added to Java 9
public static final Redirect DISCARD = Redirect.to(StreamUtils.NULL_FILE);
 
static public final ProcessBuilder redirect(final ProcessBuilder pb) {
// ATTN don't use redirectErrorStream(true) as this would merge the error and output of pb
// into the VM output.
return pb.redirectError(Redirect.INHERIT).redirectOutput(Redirect.INHERIT);
return pb.redirectErrorStream(true).redirectOutput(Redirect.INHERIT);
}
 
/**
* Consume all streams. Needed since some programs might fail (e.g. route on FreeBSD) if the
* streams are just closed.
*
* @param proc the process.
* @return the passed process.
*/
static public final Process consume(final Process proc) {
try (final ProcessStreams streams = new ProcessStreams(proc)) {
streams.start(StreamUtils.NULL_OS, StreamUtils.NULL_OS);
streams.awaitTermination();
} catch (Exception e) {
throw new IllegalStateException("Couldn't consume output of " + proc, e);
static public final Process handle(final Process p, final Action action) throws IOException {
if (action == Action.CLOSE) {
p.getInputStream().close();
p.getErrorStream().close();
} else if (action == Action.REDIRECT) {
new ProcessStreams(p, System.out, System.err);
} else if (action == Action.CONSUME) {
new ProcessStreams(p, StreamUtils.NULL_OS, StreamUtils.NULL_OS);
}
return proc;
return p;
}
 
private final ExecutorService exec = Executors.newFixedThreadPool(2);
private final Process process;
private Future<?> out;
private Future<?> err;
private final CountDownLatch latch;
private final Future<?> out;
private final Future<?> err;
 
/**
* Create a new instance and start reading from the passed process. If a passed
82,35 → 92,23
* @param out where to write the {@link Process#getInputStream() standard output}.
* @param err where to write the {@link Process#getErrorStream() standard error}.
*/
public ProcessStreams(final Process p) {
this.process = p;
}
 
public final ProcessStreams start(final OutputStream out, final OutputStream err) {
if (this.out != null)
throw new IllegalStateException("Already started");
this.out = writeToAsync(this.process::getInputStream, out);
this.err = writeToAsync(this.process::getErrorStream, err);
assert this.out != null && this.err != null;
public ProcessStreams(final Process p, final OutputStream out, final OutputStream err) {
this.latch = new CountDownLatch(2);
this.out = writeToAsync(p::getInputStream, out);
this.err = writeToAsync(p::getErrorStream, err);
this.exec.submit(new Runnable() {
@Override
public void run() {
try {
// OK even if the future is cancelled before having started
try {
ProcessStreams.this.out.get();
} catch (Exception e) {
}
try {
ProcessStreams.this.err.get();
} catch (Exception e) {
}
ProcessStreams.this.latch.await();
} catch (final InterruptedException e) {
// ne rien faire
e.printStackTrace();
} finally {
ProcessStreams.this.exec.shutdown();
}
}
});
return this;
}
 
protected final void stopOut() {
123,42 → 121,16
 
private final void stop(final Future<?> f) {
if (f == null)
throw new IllegalStateException("Not started");
// ATTN Process returns InputStream which are not interruptible.
f.cancel(true);
return;
// TODO
// ATTN don't interrupt, hangs in readLine()
f.cancel(false);
}
 
// From AutoCloseable : close() shouldn't throw InterruptedException
@Override
public void close() {
this.exec.shutdownNow();
}
 
public final void awaitTermination() throws InterruptedException, ExecutionException {
this.out.get();
this.err.get();
if (!this.exec.awaitTermination(MAX_SHUTTING_DOWN_DELAY, TimeUnit.MILLISECONDS))
throw new IllegalStateException("Executor still not terminated after " + MAX_SHUTTING_DOWN_DELAY);
}
 
public final void awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
try {
this.out.get(timeout, unit);
} catch (CancellationException e) {
// OK
}
try {
this.err.get(timeout, unit);
} catch (CancellationException e) {
// OK
}
if (!this.exec.awaitTermination(MAX_SHUTTING_DOWN_DELAY, TimeUnit.MILLISECONDS))
throw new TimeoutException("Executor still not terminated after " + MAX_SHUTTING_DOWN_DELAY);
}
 
private final Future<?> writeToAsync(final Supplier<InputStream> insSupplier, final Object outs) {
if (outs == null) {
return CompletableFuture.completedFuture(null);
this.latch.countDown();
return null;
}
return this.exec.submit(new Callable<Object>() {
@Override
170,6 → 142,8
else
StreamUtils.copy(ins, (OutputStream) outs);
return null;
} finally {
ProcessStreams.this.latch.countDown();
}
}
});
/trunk/OpenConcerto/src/org/openconcerto/utils/BloomFilter.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
41,7 → 41,7
public BloomFilter(int bitArraySize, int expectedElements) {
this.bitArraySize = bitArraySize;
this.expectedElements = expectedElements;
this.k = (int) Math.ceil(((double) bitArraySize / expectedElements) * Math.log(2.0));
this.k = (int) Math.ceil((bitArraySize / expectedElements) * Math.log(2.0));
bitSet = new BitSet(bitArraySize);
}
 
148,7 → 148,7
}
 
public static void main(String[] args) {
BloomFilter<String> set = new BloomFilter<>(100, 5);
BloomFilter<String> set = new BloomFilter<String>(100, 5);
 
// Add some things to the bloom filter
set.add("dog");
/trunk/OpenConcerto/src/org/openconcerto/utils/prog/ExtractFromBEncoding.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/utils/ExceptionHandler.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
128,26 → 128,21
clipboard.setContents(data, data);
}
 
static public Future<Boolean> handle(Component comp, String msg, Throwable originalExn) {
return handle(comp, msg, null, originalExn);
}
 
/**
* Display the passed message. Note: this method doesn't block.
*
* @param comp the modal parent of the error window.
* @param msg the message to display.
* @param title the title, can be <code>null</code>.
* @param originalExn the cause, can be <code>null</code>.
* @return a future completed when the error is handled (e.g. the user clicked on the dialog),
* <code>false</code> if the error couldn't be displayed to the user.
*/
static public Future<Boolean> handle(Component comp, String msg, String title, Throwable originalExn) {
static public Future<Boolean> handle(Component comp, String msg, Throwable originalExn) {
final Future<Boolean> res;
if (tHandler != null && tHandler.handle(msg, originalExn)) {
res = TRUE_FUTURE;
} else {
res = new ExceptionHandler(comp, msg, title, originalExn, false).display();
res = new ExceptionHandler(comp, msg, originalExn, false).display();
}
assert res != null;
return res;
170,7 → 165,7
* @return an exception.
*/
static public RuntimeException die(String msg, Throwable originalExn) {
final ExceptionHandler res = new ExceptionHandler(null, msg, null, originalExn);
final ExceptionHandler res = new ExceptionHandler(null, msg, originalExn);
res.display();
return res;
}
185,7 → 180,6
 
// the comp on which to display the popup, may be null
private final Component comp;
private final String title;
private final boolean quit;
protected static AtomicInteger openedWindows = new AtomicInteger(0);
private static boolean forceUI;
247,10 → 241,7
return Boolean.FALSE;
}
 
protected final void showMsg(String msg, final boolean quit) {
if (msg == null) {
msg = "";
}
protected final void showMsg(final String msg, final boolean quit) {
final JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
final GridBagConstraints c = new GridBagConstraints();
415,9 → 406,9
final Window window = this.comp == null ? null : SwingUtilities.getWindowAncestor(this.comp);
final JDialog f;
if (window instanceof Frame) {
f = new JDialog((Frame) window, this.getTitle(), true);
f = new JDialog((Frame) window, "Erreur", true);
} else {
f = new JDialog((Dialog) window, this.getTitle(), true);
f = new JDialog((Dialog) window, "Erreur", true);
}
f.setContentPane(p);
f.pack();
460,11 → 451,10
*
* @param comp the component upon which to display the popup.
* @param msg le message d'erreur à afficher.
* @param title the title, can be <code>null</code>.
* @param cause la cause de l'exception (peut être <code>null</code>).
*/
private ExceptionHandler(Component comp, String msg, String title, Throwable cause) {
this(comp, msg, title, cause, true);
private ExceptionHandler(Component comp, String msg, Throwable cause) {
this(comp, msg, cause, true);
}
 
/**
472,23 → 462,15
*
* @param comp the component upon which to display the popup.
* @param msg the error message to display.
* @param title the title, can be <code>null</code>.
* @param cause the cause of the exception (maybe <code>null</code>).
* @param quit if the VM must exit.
*/
private ExceptionHandler(Component comp, String msg, String title, Throwable cause, boolean quit) {
private ExceptionHandler(Component comp, String msg, Throwable cause, boolean quit) {
super(msg, cause);
this.comp = comp;
this.title = title;
this.quit = quit;
}
 
public String getTitle() {
if (this.title != null)
return this.title;
return this.quit ? "Erreur fatale" : "Erreur";
}
 
private void submitError(String error) {
final Charset cs = StringUtils.UTF8;
try {
/trunk/OpenConcerto/src/org/openconcerto/utils/NetUtils.java
32,7 → 32,6
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
 
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
185,11 → 184,10
return content;
}
 
/**
* Encode for POST message application/x-www-form-urlencoded
*/
static public final String urlEncode(final String... kv) {
return urlEncode(false, kv);
}
 
static public final String urlEncode(final boolean spaceAsPlus, final String... kv) {
final int size = kv.length;
if (size % 2 != 0)
throw new IllegalArgumentException("Odd number of items : " + size);
197,22 → 195,13
for (int i = 0; i < size; i += 2) {
map.put(kv[i], kv[i + 1]);
}
return urlEncode(map, spaceAsPlus);
return urlEncode(map);
}
 
/**
* Encode pairs in application/x-www-form-urlencoded format. Although both the
* <a href="https://url.spec.whatwg.org/#urlencoded-serializing">URL standard</a> and the
* <a href="https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1">HTML standard</a>
* specifies <code>spaceAsPlus</code> some applications expect the opposite (e.g. POST with
* jetty).
*
* @param map the values to encode.
* @param spaceAsPlus <code>true</code> to use '+' for a space, <code>false</code> to use '%20'.
* @return the encoded string.
* @see #percentEncode(String, String, boolean)
* Encode for POST message application/x-www-form-urlencoded
*/
static public final String urlEncode(final Map<String, ?> map, final boolean spaceAsPlus) {
static public final String urlEncode(final Map<String, ?> map) {
if (map.isEmpty())
return "";
final String charset = StandardCharsets.UTF_8.name();
222,9 → 211,9
// Avoid null and "null" confusion.
if (value != null) {
try {
sb.append(percentEncode(e.getKey(), charset, spaceAsPlus));
sb.append(URLEncoder.encode(e.getKey(), charset).replace("+", "%20"));
sb.append('=');
sb.append(percentEncode(String.valueOf(value), charset, spaceAsPlus));
sb.append(URLEncoder.encode(String.valueOf(value), charset).replace("+", "%20"));
sb.append('&');
} catch (UnsupportedEncodingException exn) {
throw new IllegalStateException("UTF-8 should be standard", exn);
236,31 → 225,6
return sb.toString();
}
 
static private final Pattern SPACE_PATTERN = Pattern.compile("+", Pattern.LITERAL);
 
/**
* Percent encode a string.
*
* @param s the string to encode.
* @param charset the charset to use.
* @param spaceAsPlus <code>true</code> to use '+' for a space (as per
* <a href="https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1">HTML</a> and
* <a href=
* "https://url.spec.whatwg.org/#urlencoded-serializing">application/x-www-form-urlencoded</a>
* of URL Standard), <code>false</code> to use '%20' (as per
* <a href="https://url.spec.whatwg.org/#path-state">Path part</a> of URL Standard).
* @return the encoded string.
* @throws UnsupportedEncodingException if charset is unknown.
* @see <a href="https://url.spec.whatwg.org/#string-percent-encode-after-encoding">URL
* standard</a>
*/
static public final String percentEncode(final String s, final String charset, final boolean spaceAsPlus) throws UnsupportedEncodingException {
final String withPlus = URLEncoder.encode(s, charset);
if (spaceAsPlus)
return withPlus;
return SPACE_PATTERN.matcher(withPlus).replaceAll("%20");
}
 
// Create a trust manager that does not validate certificate chains
static private final TrustManager[] TRUSTALL_MANAGERS = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
/trunk/OpenConcerto/src/org/openconcerto/utils/CollectionUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
13,7 → 13,6
package org.openconcerto.utils;
 
import org.openconcerto.utils.cc.CustomEquals;
import org.openconcerto.utils.cc.IClosure;
import org.openconcerto.utils.cc.IPredicate;
import org.openconcerto.utils.cc.ITransformer;
48,10 → 47,7
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
/**
* Une classe regroupant des méthodes utilitaires pour les collections.
407,53 → 403,13
}
 
static public final boolean identityContains(final Collection<?> coll, final Object item) {
final int size = coll.size();
if (size > 0) {
if (coll instanceof RandomAccess && coll instanceof List) {
final List<?> list = (List<?>) coll;
for (int i = 0; i < size; i++) {
final Object v = list.get(i);
if (item == v)
return true;
}
} else {
for (final Object v : coll) {
if (item == v)
return true;
}
}
}
return false;
}
 
static public final boolean identityRemove(final Collection<?> coll, final Object item) {
final int size = coll.size();
if (size > 0) {
if (coll instanceof RandomAccess && coll instanceof List) {
final List<?> list = (List<?>) coll;
for (int i = 0; i < size; i++) {
final Object v = list.get(i);
if (item == v) {
list.remove(i);
return true;
}
}
} else {
for (Iterator<?> i = coll.iterator(); i.hasNext();) {
if (item == i.next()) {
i.remove();
return true;
}
}
}
}
return false;
}
 
static public final <T> int identityIndexOf(final List<T> coll, final T item) {
return CustomEquals.indexOf(coll, item, CustomEquals.getIdentity());
}
 
static public final boolean identityEquals(final List<?> coll1, final List<?> coll2) {
if (coll1 == coll2)
return true;
507,19 → 463,11
return null;
}
 
final List<E> result;
if (list instanceof RandomAccess) {
final int size = list.size();
result = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
final List<E> result = new ArrayList<E>(size);
for (int i = 0; i < list.size(); i++) {
result.add(c.cast(list.get(i)));
}
} else {
result = new LinkedList<>();
for (final Object o : list) {
result.add(c.cast(o));
}
}
return result;
}
 
536,15 → 484,11
* a <code>E</code> or a value which the type is not a <code>F</code>.
*/
public static <E, F> Map<E, F> castMap(final Map<?, ?> map, Class<E> cKey, Class<F> cValue) throws ClassCastException {
return castMap(map, cKey, cValue, HashMap::new);
}
 
public static <E, F> Map<E, F> castMap(final Map<?, ?> map, Class<E> cKey, Class<F> cValue, final Supplier<Map<E, F>> ctor) throws ClassCastException {
if (map == null) {
return null;
}
 
final Map<E, F> result = ctor.get();
final Map<E, F> result = new HashMap<E, F>();
for (final Entry<?, ?> mapEntry : map.entrySet()) {
final E key;
try {
563,14 → 507,6
return result;
}
 
public static <T> Stream<T> subclassFilter(final Collection<? super T> coll, final Class<T> subclass) {
return coll.stream().filter(subclass::isInstance).map(subclass::cast);
}
 
public static <T> List<T> subclassFilterToList(final Collection<? super T> coll, final Class<T> subclass) {
return subclassFilter(coll, subclass).collect(Collectors.toList());
}
 
/**
* The number of equals item between a and b, starting from the end.
*
1012,42 → 948,13
}
}
 
@SafeVarargs
public static final <T> List<T> toImmutableList(final T... items) {
final int length = items.length;
if (length == 0)
return Collections.emptyList();
else if (length == 1)
return Collections.singletonList(items[0]);
return Collections.unmodifiableList(Arrays.asList(Arrays.copyOf(items, length)));
}
 
public static final <T> List<T> toImmutableList(final Collection<? extends T> coll) {
return toImmutableList(coll, ArrayList::new);
}
 
public static final <T, C extends Collection<? extends T>> List<T> toImmutableList(final C coll, final Function<? super C, ? extends List<T>> createColl) {
return toImmutableList(coll, createColl, true);
}
 
/**
* Create a new immutable list.
*
* @param <T> type of items
* @param <C> type of collection
* @param coll the collection holding the items.
* @param createColl how to copy the collection into a new list.
* @param std <code>true</code> if the created <code>createColl</code> use
* {@link Object#equals(Object)}, in that case {@link Collections#singletonList(Object)}
* can be returned.
* @return an immutable list with the same items as <code>coll</code>.
*/
public static final <T, C extends Collection<? extends T>> List<T> toImmutableList(final C coll, final Function<? super C, ? extends List<T>> createColl, final boolean std) {
final int size = coll.size();
if (size == 0)
if (coll.isEmpty())
return Collections.emptyList();
else if (std && size == 1)
return Collections.singletonList(coll.iterator().next());
return Collections.unmodifiableList(createColl.apply(coll));
}
 
1059,7 → 966,7
// but not at runtime.
return toImmutableSet((SortedSet<T>) coll, TreeSet::new);
} else if (coll instanceof IdentitySet) {
return toImmutableSet((IdentitySet<? extends T>) coll, LinkedIdentitySet::new, false);
return toImmutableSet((IdentitySet<? extends T>) coll, LinkedIdentitySet::new);
} else {
// In doubt, keep order
// ATTN LinkedHashSet extends HashSet
1068,28 → 975,8
}
 
public static final <T, C extends Collection<? extends T>> Set<T> toImmutableSet(final C coll, final Function<? super C, ? extends Set<T>> createColl) {
return toImmutableSet(coll, createColl, true);
 
}
 
/**
* Create a new immutable set.
*
* @param <T> type of items
* @param <C> type of collection
* @param coll the collection holding the items.
* @param createColl how to copy the collection into a new list.
* @param std <code>true</code> if the created <code>createColl</code> use
* {@link Object#equals(Object)}, in that case {@link Collections#singleton(Object)} can
* be returned.
* @return an immutable set with the same items as <code>coll</code>.
*/
public static final <T, C extends Collection<? extends T>> Set<T> toImmutableSet(final C coll, final Function<? super C, ? extends Set<T>> createColl, final boolean std) {
final int size = coll.size();
if (size == 0)
if (coll.isEmpty())
return Collections.emptySet();
else if (std && size == 1)
return Collections.singleton(coll.iterator().next());
final Set<T> res = createColl.apply(coll);
return Collections.unmodifiableSet(res);
}
1108,7 → 995,7
// ATTN see eclipse bug below about wrong constructor
return toImmutableMap((SortedMap<K, ? extends V>) map, TreeMap::new);
} else if (map instanceof IdentityHashMap) {
return toImmutableMap((IdentityHashMap<? extends K, ? extends V>) map, IdentityHashMap::new, false);
return toImmutableMap((IdentityHashMap<? extends K, ? extends V>) map, IdentityHashMap::new);
} else {
// In doubt, keep order
// ATTN LinkedHashMap extends HashMap
1116,10 → 1003,6
}
}
 
public static final <K, V, InMap extends Map<? extends K, ? extends V>> Map<K, V> toImmutableMap(final InMap map, final Function<? super InMap, ? extends Map<K, V>> copyFunction) {
return toImmutableMap(map, copyFunction, true);
}
 
/**
* Return an immutable map with the same entries as the passed one. NOTE: <code>copyMap</code>
* <strong>must</strong> copy the entries so that a modification of <code>map</code> doesn't
1133,20 → 1016,11
* {@link TreeMap#TreeMap(Map)} is (correctly) executed at runtime.
* @param map the map.
* @param copyFunction how to copy the passed map.
* @param std <code>true</code> if the created <code>createColl</code> use
* {@link Object#equals(Object)}, in that case
* {@link Collections#singletonMap(Object, Object)} can be returned.
* @return an immutable map.
*/
public static final <K, V, InMap extends Map<? extends K, ? extends V>> Map<K, V> toImmutableMap(final InMap map, final Function<? super InMap, ? extends Map<K, V>> copyFunction,
final boolean std) {
final int size = map.size();
if (size == 0) {
public static final <K, V, InMap extends Map<? extends K, ? extends V>> Map<K, V> toImmutableMap(final InMap map, final Function<? super InMap, ? extends Map<K, V>> copyFunction) {
if (map.isEmpty())
return Collections.emptyMap();
} else if (std && size == 1) {
final Entry<? extends K, ? extends V> e = map.entrySet().iterator().next();
return Collections.singletonMap(e.getKey(), e.getValue());
}
return Collections.unmodifiableMap(copyFunction.apply(map));
}
 
1181,77 → 1055,7
return res;
}
 
// same as HashMap and HashSet
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
 
public static interface MapConstructor<K, V, M extends Map<K, V>> {
M create(int initialCapacity, float loadFactor);
}
 
public static final int getCapacity(final int plannedSize, final float loadFactor) {
return Math.max((int) Math.ceil(plannedSize / loadFactor), 4);
}
 
public static final <K, V> LinkedHashMap<K, V> newLinkedHashMap(final int plannedSize) {
return newMap(plannedSize, DEFAULT_LOAD_FACTOR, (MapConstructor<K, V, LinkedHashMap<K, V>>) LinkedHashMap::new);
}
 
public static final <K, V> HashMap<K, V> newHashMap(final int plannedSize) {
return newHashMap(plannedSize, DEFAULT_LOAD_FACTOR);
}
 
/**
* Create a new map with no rehash operations until at least a certain size.
*
* @param <K> the type of keys maintained by the new map
* @param <V> the type of mapped values
* @param plannedSize the number of entries expected to be added to the returned map.
* @param loadFactor the load factor of the returned map, not advised to be <code>1.0f</code>
* because it increases the chances of hash collisions.
* @return a new map that won't rehash until at least <code>plannedSize</code> items.
*/
public static final <K, V> HashMap<K, V> newHashMap(final int plannedSize, final float loadFactor) {
return newMap(plannedSize, loadFactor, (MapConstructor<K, V, HashMap<K, V>>) HashMap::new);
}
 
/**
* Create a new map with no rehash operations until at least a certain size.
*
* @param <K> the type of keys maintained by the new map
* @param <V> the type of mapped values
* @param <M> the type of the new map
* @param plannedSize the number of entries expected to be added to the returned map
* @param loadFactor the load factor, passed to <code>ctor</code>.
* @param ctor how to create the new map, will be passed the computed initial capacity and
* <code>loadFactor</code>, e.g. {@link LinkedHashMap#LinkedHashMap(int, float)
* LinkedHashMap::new}.
* @return a new map that won't rehash until at least <code>plannedSize</code> items.
*/
public static final <K, V, M extends Map<K, V>> M newMap(final int plannedSize, final float loadFactor, final MapConstructor<K, V, M> ctor) {
return ctor.create(getCapacity(plannedSize, loadFactor), loadFactor);
}
 
public static interface SetConstructor<V, S extends Set<V>> {
S create(int initialCapacity, float loadFactor);
}
 
public static final <V> LinkedHashSet<V> newLinkedHashSet(final int plannedSize) {
return newSet(plannedSize, DEFAULT_LOAD_FACTOR, (SetConstructor<V, LinkedHashSet<V>>) LinkedHashSet::new);
}
 
public static final <V> HashSet<V> newHashSet(final int plannedSize) {
return newHashSet(plannedSize, DEFAULT_LOAD_FACTOR);
}
 
public static final <V> HashSet<V> newHashSet(final int plannedSize, final float loadFactor) {
return newSet(plannedSize, loadFactor, (SetConstructor<V, HashSet<V>>) HashSet::new);
}
 
public static final <V, S extends Set<V>> S newSet(final int plannedSize, final float loadFactor, final SetConstructor<V, S> ctor) {
return ctor.create(getCapacity(plannedSize, loadFactor), loadFactor);
}
 
/**
* Creates a map with null values.
*
* @param <K> type of key.
/trunk/OpenConcerto/src/org/openconcerto/utils/SetMap.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
36,8 → 36,6
}
 
static public <K, V> SetMapItf<K, V> unmodifiableMap(SetMapItf<K, V> map) {
if (map.isEmpty())
return empty();
return new Unmodifiable<K, V>(map);
}
 
/trunk/OpenConcerto/src/org/openconcerto/utils/change/ListChangeRecorder.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
21,7 → 21,7
 
/**
* A class that wraps a list, to detect every change made to it. The changes are available with
* {@link #getRecipe()}. Thread-safe if the delegate is itself thread-safe and not keeping history.
* {@link #getRecipe()}.
*
* @author Sylvain
*
32,11 → 32,11
private final List<E> delegate;
private final ListChangeRecipe<E> recipe;
 
public ListChangeRecorder(final List<E> delegate) {
public ListChangeRecorder(List<E> delegate) {
this(delegate, false);
}
 
public ListChangeRecorder(final List<E> delegate, final boolean keepHistory) {
public ListChangeRecorder(List<E> delegate, final boolean keepHistory) {
super();
this.delegate = delegate;
this.recipe = new ListChangeRecipe<E>(keepHistory);
52,58 → 52,47
 
// ** read only
 
@Override
public E get(final int index) {
public E get(int index) {
return this.delegate.get(index);
}
 
@Override
public int size() {
return this.delegate.size();
}
 
@Override
public Object[] toArray() {
return this.delegate.toArray();
}
 
@Override
public <T> T[] toArray(final T[] a) {
public <T> T[] toArray(T[] a) {
return this.delegate.toArray(a);
}
 
@Override
public boolean contains(final Object o) {
public boolean contains(Object o) {
return this.delegate.contains(o);
}
 
@Override
public boolean containsAll(final Collection<?> c) {
public boolean containsAll(Collection<?> c) {
return this.delegate.containsAll(c);
}
 
@Override
public boolean equals(final Object o) {
public boolean equals(Object o) {
return this.delegate.equals(o);
}
 
@Override
public int hashCode() {
return this.delegate.hashCode();
}
 
@Override
public int indexOf(final Object o) {
public int indexOf(Object o) {
return this.delegate.indexOf(o);
}
 
@Override
public boolean isEmpty() {
return this.delegate.isEmpty();
}
 
@Override
public int lastIndexOf(final Object o) {
public int lastIndexOf(Object o) {
return this.delegate.lastIndexOf(o);
}
 
110,8 → 99,7
// ** write, always change the delegate before notifying the recipe
// otherwise the listeners will be told of the changes before they even happened
 
@Override
public synchronized boolean add(final E e) {
public boolean add(E e) {
final boolean res = this.delegate.add(e);
// -1 since this just grew by one
this.recipe.add(this.size() - 1, Collections.singleton(e));
118,14 → 106,12
return res;
}
 
@Override
public synchronized void add(final int index, final E e) {
public void add(int index, E e) {
this.delegate.add(index, e);
this.recipe.add(index, Collections.singleton(e));
}
 
@Override
public synchronized boolean addAll(final Collection<? extends E> c) {
public boolean addAll(Collection<? extends E> c) {
final int size = this.size();
final boolean res = this.delegate.addAll(c);
this.recipe.add(size, c);
132,29 → 118,25
return res;
}
 
@Override
public synchronized boolean addAll(final int index, final Collection<? extends E> c) {
public boolean addAll(int index, Collection<? extends E> c) {
final boolean res = this.delegate.addAll(index, c);
this.recipe.add(index, c);
return res;
}
 
@Override
public synchronized void clear() {
public void clear() {
final List<E> copy = (List<E>) ListChangeIndex.copy(this);
this.delegate.clear();
this.recipe.remove(0, copy.size() - 1, copy);
}
 
@Override
public synchronized E set(final int index, final E element) {
public E set(int index, E element) {
final E res = this.delegate.set(index, element);
this.recipe.set(index, res, element);
return res;
}
 
@Override
public synchronized E remove(final int index) {
public E remove(int index) {
final E res = this.delegate.remove(index);
this.recipe.remove(index, index, Collections.singletonList(res));
return res;
162,8 → 144,7
 
// objects
 
@Override
public synchronized boolean remove(final Object o) {
public boolean remove(Object o) {
final int index = this.indexOf(o);
if (index < 0)
return false;
173,19 → 154,17
}
}
 
@Override
public boolean removeAll(final Collection<?> c) {
public boolean removeAll(Collection<?> c) {
return this.changeAll(c, true);
}
 
@Override
public boolean retainAll(final Collection<?> c) {
public boolean retainAll(Collection<?> c) {
return this.changeAll(c, false);
}
 
private synchronized boolean changeAll(final Collection<?> c, final boolean remove) {
private boolean changeAll(Collection<?> c, boolean remove) {
boolean modified = false;
final Iterator<?> e = iterator();
Iterator<?> e = iterator();
while (e.hasNext()) {
if (c.contains(e.next()) == remove) {
e.remove();
/trunk/OpenConcerto/src/org/openconcerto/utils/change/ListChangeIndex.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
23,12 → 23,12
 
public abstract class ListChangeIndex<T> implements ListChange<T> {
 
protected final static <T> Collection<T> copy(final Collection<T> col) {
protected final static <T> Collection<T> copy(Collection<T> col) {
Collection<T> res;
try {
// tries to keep the same class
res = CopyUtils.copy(col);
} catch (final RuntimeException e) {
} catch (RuntimeException e) {
// but this doesn't always work (see sublist())
// so just use a plain ArrayList
res = new ArrayList<T>(col);
39,7 → 39,7
private final int index0;
private final int index1;
 
public ListChangeIndex(final int index0, final int index1) {
public ListChangeIndex(int index0, int index1) {
super();
this.index0 = index0;
this.index1 = index1;
61,7 → 61,7
 
private final List<T> removed;
 
public Rm(final int index0, final int index1, final List<T> removed) {
public Rm(int index0, int index1, final List<T> removed) {
super(index0, index1);
// ok to cast : either it copies it : List<T>, either it uses an arrayList which
// implements List<T>
68,18 → 68,15
this.removed = (List<T>) copy(removed);
}
 
@Override
public <U> void apply(final List<U> l, final ITransformer<T, U> transf) {
public <U> void apply(List<U> l, ITransformer<T, U> transf) {
// sublist exclusive
l.subList(this.getIndex0(), this.getIndex1() + 1).clear();
}
 
@Override
public List<? extends T> getItemsAdded() {
return Collections.emptyList();
}
 
@Override
public List<T> getItemsRemoved() {
return this.removed;
}
94,13 → 91,12
 
private final Collection<? extends T> added;
 
public Add(final int index0, final Collection<? extends T> added) {
public Add(int index0, Collection<? extends T> added) {
super(index0, index0);
this.added = copy(added);
}
 
@Override
public <U> void apply(final List<U> l, final ITransformer<T, U> transf) {
public <U> void apply(List<U> l, ITransformer<T, U> transf) {
final List<U> toAdd = new ArrayList<U>();
for (final T t : this.added) {
toAdd.add(transf.transformChecked(t));
108,12 → 104,10
l.addAll(this.getIndex0(), toAdd);
}
 
@Override
public Collection<? extends T> getItemsAdded() {
return this.added;
}
 
@Override
public List<? extends T> getItemsRemoved() {
return Collections.emptyList();
}
129,23 → 123,20
private final T removed;
private final T added;
 
public Set(final int index, final T removed, final T added) {
public Set(int index, T removed, T added) {
super(index, index);
this.removed = removed;
this.added = added;
}
 
@Override
public <U> void apply(final List<U> l, final ITransformer<T, U> transf) {
public <U> void apply(List<U> l, ITransformer<T, U> transf) {
l.set(this.getIndex0(), transf.transformChecked(this.added));
}
 
@Override
public List<? extends T> getItemsAdded() {
return Collections.singletonList(this.added);
}
 
@Override
public List<? extends T> getItemsRemoved() {
return Collections.singletonList(this.removed);
}
/trunk/OpenConcerto/src/org/openconcerto/utils/change/ListChangeRecipe.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
22,10 → 22,7
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
 
import net.jcip.annotations.GuardedBy;
 
/**
* Allow to propagate ListChange to listeners and bound lists. Can also store all changes that it
* was notified and replay them with {@link #apply(List, ITransformer)}.
42,12 → 39,10
// don't use PropertyChangeSupport since it isn't type safe and we're only interested in the
// last change (and not the whole property, i.e. the whole list)
private final List<IClosure<? super ListChangeIndex<T>>> listeners;
@GuardedBy("this")
private final Map<List<?>, Pair<?>> boundLists;
 
/**
* Create a new instance. Recording is only necessary for {@link #apply(List, ITransformer)}.
* Thread-safe only if not recording.
*
* @param record <code>true</code> if all changes should be kept (this will leak memory until
* {@link #clear()} is called).
55,7 → 50,7
public ListChangeRecipe(final boolean record) {
super();
this.changes = record ? new ArrayList<ListChangeIndex<T>>() : null;
this.listeners = new CopyOnWriteArrayList<>();
this.listeners = new ArrayList<IClosure<? super ListChangeIndex<T>>>();
// need IdentityHashMap since List.equals() depend on its items
// which will change
this.boundLists = new IdentityHashMap<List<?>, Pair<?>>();
65,11 → 60,6
return this.changes != null;
}
 
/**
* The list of changes since the last {@link #clear()}. Not thread-safe.
*
* @return the list of changes
*/
public final List<ListChangeIndex<T>> getChanges() {
if (!this.recordChanges())
throw new IllegalStateException("This instance wasn't created to record changes");
76,15 → 66,15
return this.changes;
}
 
public void addListener(final IClosure<? super ListChangeIndex<T>> l) {
public void addListener(IClosure<? super ListChangeIndex<T>> l) {
this.listeners.add(l);
}
 
public void rmListener(final IClosure<? super ListChangeIndex<T>> l) {
public void rmListener(IClosure<? super ListChangeIndex<T>> l) {
this.listeners.remove(l);
}
 
public void bind(final List<T> l) {
public void bind(List<T> l) {
this.bind(l, Transformer.<T> nopTransformer());
}
 
95,19 → 85,18
* @param l the list to keep in sync.
* @param transf the transformer.
*/
public synchronized <U> void bind(final List<U> l, final ITransformer<T, U> transf) {
public <U> void bind(List<U> l, ITransformer<T, U> transf) {
this.boundLists.put(l, new Pair<U>(l, transf));
}
 
public synchronized <U> void unbind(final List<U> l) {
public <U> void unbind(List<U> l) {
this.boundLists.remove(l);
}
 
private final void add(final ListChangeIndex<T> change) {
private final void add(ListChangeIndex<T> change) {
if (this.recordChanges())
this.changes.add(change);
// must change bounded lists first, otherwise listeners couldn't access them
synchronized (this) {
for (final Pair<?> p : this.boundLists.values()) {
p.apply(change);
}
114,17 → 103,16
for (final IClosure<? super ListChangeIndex<T>> l : this.listeners)
l.executeChecked(change);
}
}
 
public void add(final int index0, final Collection<? extends T> c) {
public void add(int index0, Collection<? extends T> c) {
this.add(new ListChangeIndex.Add<T>(index0, c));
}
 
public void remove(final int index0, final int index1, final List<T> removed) {
public void remove(int index0, int index1, List<T> removed) {
this.add(new ListChangeIndex.Rm<T>(index0, index1, removed));
}
 
public void set(final int index0, final T old, final T newItem) {
public void set(int index0, T old, T newItem) {
this.add(new ListChangeIndex.Set<T>(index0, old, newItem));
}
 
146,7 → 134,7
* changes}.
*/
@Override
public <U> void apply(final List<U> l, final ITransformer<T, U> transf) throws IllegalStateException {
public <U> void apply(List<U> l, ITransformer<T, U> transf) throws IllegalStateException {
for (final ListChange<T> change : this.getChanges()) {
change.apply(l, transf);
}
157,13 → 145,13
private final List<U> l;
private final ITransformer<T, U> transf;
 
public Pair(final List<U> l, final ITransformer<T, U> transf) {
public Pair(List<U> l, ITransformer<T, U> transf) {
super();
this.l = l;
this.transf = transf;
}
 
void apply(final ListChange<T> change) {
void apply(ListChange<T> change) {
change.apply(this.l, this.transf);
}
}
/trunk/OpenConcerto/src/org/openconcerto/laf/IButtonUI.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
/trunk/OpenConcerto/src/org/openconcerto/laf/IScrollBarUI.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
/trunk/OpenConcerto/src/org/openconcerto/laf/ILookAndFeel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
/trunk/OpenConcerto/src/org/openconcerto/laf/IComboBoxUI.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
/trunk/OpenConcerto/src/org/openconcerto/task/config/ComptaOptions.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/task/config/Customer.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/gs1/ISO646.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/gs1/GS1AIElements.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/gs1/GS1ApplicationIdentifier.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/gs1/GS1ParseException.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/gs1/GS1Util.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/compta/ImportRImport.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
65,7 → 65,6
line = bReader.readLine();
while (line != null && !line.contains("#Section")) {
final List<String> parts = StringUtils.fastSplit(line, '\t');
if (parts.size() > 6) {
final String journalCode = unquote(parts.get(1).trim());
final Date ecritureDate = parseDate(unquote(parts.get(2).trim()));
final String compteNum = unquote(parts.get(3).trim());
91,7 → 90,7
p = new Piece(pieceRef);
mouvement = new Mouvement();
p.add(mouvement);
this.mapPiece.put(pieceRef, p);
 
} else {
mouvement = p.getMouvements().get(0);
}
108,11 → 107,8
if ("AN".equals(journalCode)) {
ecriture.setaNouveau(true);
}
mouvement.add(ecriture);
 
mouvement.add(ecriture);
} else {
System.err.println("Ignoring : " + line);
}
// Next
line = bReader.readLine();
}
180,10 → 176,6
return this.error;
}
 
public List<Piece> getPieces() {
return new ArrayList<Piece>(this.mapPiece.values());
}
 
public void importTo(SQLElementDirectory directory, DBRoot rootSociete, User user) throws SQLException {
Exercice e = new Exercice();
e.insert(directory, rootSociete, user, new ArrayList<Piece>(this.mapPiece.values()));
192,15 → 184,7
public static void main(String[] args) throws IOException {
ImportRImport i = new ImportRImport();
i.loadFrom(new File("Y:\\Projets\\OpenConcerto\\ExportCiel\\RImport.txt"));
System.err.println("ImportRImport.main() " + i.getPieces().size() + " pieces");
System.err.println("ImportRImport.main()" + i.getError());
for (Piece p : i.getPieces()) {
System.err.println(p.getNom() + " " + p.getMouvements().size() + " mouvements");
for (Mouvement m : p.getMouvements()) {
System.err.println(m.asString());
}
}
 
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/compta/ExportFEC.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
44,7 → 44,7
 
public static final char ZONE_SEPARATOR = '\t';
public static final char RECORD_SEPARATOR = '\n';
private static final char REPLACEMENT = ' ';
public static final List<String> COLS = Arrays.asList("JournalCode", "JournalLib", "EcritureNum", "EcritureDate", "CompteNum", "CompteLib", "CompAuxNum", "CompAuxLib", "PieceRef", "PieceDate",
"EcritureLib", "Debit", "Credit", "EcritureLet", "DateLet", "ValidDate", "Montantdevise", "Idevise");
 
99,7 → 99,7
}
 
private final void addAmountField(final List<String> line, final Number cents) {
final String formattedAmount = this.format.format(BigDecimal.valueOf(cents.longValue()).movePointLeft(2));
final String formattedAmount = format.format(BigDecimal.valueOf(cents.longValue()).movePointLeft(2));
line.add(formattedAmount);
}
 
107,42 → 107,10
if (s == null) {
throw new NullPointerException("Valeur manquante pour remplir la ligne : " + line);
}
final String escapedString = strongEscape(s).trim();
line.add(escapedString);
final String escapedString = StringUtils.toAsciiString(s).trim();
line.add(escapedString.replace(ZONE_SEPARATOR, REPLACEMENT).replace(RECORD_SEPARATOR, REPLACEMENT));
}
 
private final String strongEscape(String str) {
if (str == null) {
return "";
}
final int length = str.length();
final StringBuilder b = new StringBuilder(length);
for (int i = 0; i < length; i++) {
final char c = str.charAt(i);
final char newChar;
if (c > 31 && c < 126 && c != ';') {
// ';' is escaped to avoid issue with Excel
newChar = c;
} else if (c == 'é' || c == 'è' || c == 'ê') {
newChar = 'e';
} else if (c == 'â' || c == 'à') {
newChar = 'a';
} else if (c == 'î') {
newChar = 'i';
} else if (c == 'ù' || c == 'û') {
newChar = 'u';
} else if (c == 'ô') {
newChar = 'o';
} else if (c == 'ç') {
newChar = 'c';
} else {
newChar = ' ';
}
b.append(newChar);
}
return b.toString();
}
 
@Override
protected void export(OutputStream out) throws IOException {
final Writer bufOut = new OutputStreamWriter(out, StringUtils.ISO8859_15);
218,7 → 186,7
line.add(ecritureDateValid);
} else {
line.add("");
if (this.cloture) {
if (cloture) {
bufOut.close();
JOptionPane.showMessageDialog(new JFrame(), "Une écriture n'est pas validée (pas de date):\n" + line, "Erreur FEC", JOptionPane.ERROR_MESSAGE);
return;
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/ITreeSelection.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
36,8 → 36,6
import org.openconcerto.utils.checks.ValidState;
 
import java.awt.event.ActionEvent;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeListener;
71,12 → 69,11
private DefaultTreeModel model;
 
// Map <Id, Node>
private final Map<Integer, ITreeSelectionNode> mapNode = new HashMap<Integer, ITreeSelectionNode>();
private Map<Integer, ITreeSelectionNode> mapNode = new HashMap<Integer, ITreeSelectionNode>();
 
protected static final int EMPTY_ID = SQLRow.MIN_VALID_ID - 1;
private final EmptyChangeSupport helper;
private final PropertyChangeSupport supp;
private final SQLTableListener listener;
 
public ITreeSelection() {
this(null);
106,59 → 103,22
}
});
 
this.listener = new SQLTableListener() {
public void rowModified(SQLTable table, int id) {
final ITreeSelectionNode node = ITreeSelection.this.mapNode.get(Integer.valueOf(id));
if (node != null) {
modifyNode(table.getRow(id), node);
}
}
 
public void rowAdded(SQLTable table, int id) {
final SQLRow row = table.getRow(id);
int idPere = row.getInt("ID_" + element.getTable().getName() + "_PERE");
addNewNode(null, row, idPere, new HashSet<>());
}
 
public void rowDeleted(SQLTable table, int id) {
final ITreeSelectionNode node = ITreeSelection.this.mapNode.get(Integer.valueOf(id));
for (int i = 0; i < node.getChildCount(); i++) {
removeNode(table.getRow(id), node);
}
}
};
 
}
 
private void initTree() {
if (this.element == null) {
this.rootNode = new ITreeSelectionNode(null);
} else {
SQLRowValues row = UndefinedRowValuesCache.getInstance().getDefaultRowValues(this.element.getTable());
SQLRowValues row = UndefinedRowValuesCache.getInstance().getDefaultRowValues(element.getTable());
this.rootNode = new ITreeSelectionNode(row);
}
this.model = new DefaultTreeModel(this.rootNode);
this.setModel(this.model);
loadTree();
setTableListener();
this.addMouseListener(this);
this.element.getTable().addTableListener(this.listener);
this.addHierarchyListener(new HierarchyListener() {
 
@Override
public void hierarchyChanged(HierarchyEvent e) {
// check for Hierarchy event
if (e.getChangeFlags() == HierarchyEvent.DISPLAYABILITY_CHANGED) {
// do the required action upon close
if (!isDisplayable()) {
ITreeSelection.this.element.getTable().removeTableListener(ITreeSelection.this.listener);
}
 
}
 
}
});
}
 
public void mouseClicked(MouseEvent e) {
}
 
223,10 → 183,10
* Ajouter une feuille
*/
public void addElement(int idRoot) {
EditFrame frameAdd = new EditFrame(this.element, EditFrame.CREATION);
SQLRowValues rowVals = new SQLRowValues(this.element.getTable());
EditFrame frameAdd = new EditFrame(element, EditFrame.CREATION);
SQLRowValues rowVals = new SQLRowValues(element.getTable());
if (idRoot > 1) {
rowVals.put("ID_" + this.element.getTable().getName() + "_PERE", idRoot);
rowVals.put("ID_" + element.getTable().getName() + "_PERE", idRoot);
frameAdd.getSQLComponent().select(rowVals);
}
FrameUtil.showPacked(frameAdd);
239,7 → 199,7
public void removeElement(int id) {
if (id > 1) {
try {
this.element.archive(id);
element.archive(id);
} catch (SQLException e1) {
e1.printStackTrace();
}
251,7 → 211,7
*/
public void modifyElement(int id) {
if (id > 1) {
EditFrame frameModFamille = new EditFrame(this.element, EditFrame.MODIFICATION);
EditFrame frameModFamille = new EditFrame(element, EditFrame.MODIFICATION);
frameModFamille.selectionId(id, 1);
FrameUtil.showPacked(frameModFamille);
}
342,7 → 302,7
new SwingWorker<List<SQLRow>, Object>() {
@Override
protected List<SQLRow> doInBackground() throws Exception {
final SQLTable table = ITreeSelection.this.element.getTable();
final SQLTable table = element.getTable();
final SQLSelect sel = new SQLSelect();
sel.addSelectStar(table);
return SQLRowListRSH.execute(sel);
361,7 → 321,7
}
for (int i = 0; i < l.size(); i++) {
SQLRow row = l.get(i);
addNewNode(familles, row, row.getInt("ID_" + ITreeSelection.this.element.getTable().getName() + "_PERE"), new HashSet<>());
addNewNode(familles, row, row.getInt("ID_" + element.getTable().getName() + "_PERE"), new HashSet<>());
}
expandRow(0);
}
388,7 → 348,7
if (idPere != row.getID()) {
if (!addedIDs.contains(idPere)) {
addedIDs.add(idPere);
addNewNode(familles, rowPere, rowPere.getInt("ID_" + this.element.getTable().getName() + "_PERE"), addedIDs);
addNewNode(familles, rowPere, rowPere.getInt("ID_" + element.getTable().getName() + "_PERE"), addedIDs);
}
}
nodePere = this.mapNode.get(Integer.valueOf(idPere));
400,7 → 360,7
addNode(newNode, nodePere);
} else {
if (idPere == 1) {
addNode(newNode, this.rootNode);
addNode(newNode, rootNode);
}
}
}
421,7 → 381,7
break;
}
}
this.model.insertNodeInto(nodeToAdd, nodeParent, n);
model.insertNodeInto(nodeToAdd, nodeParent, n);
}
 
/**
431,10 → 391,10
*/
private void modifyNode(SQLRow row, ITreeSelectionNode node) {
if (row.isArchived() && node.getParent() != null) {
this.model.removeNodeFromParent(node);
model.removeNodeFromParent(node);
} else {
node.setRow(row);
this.model.nodeChanged(node);
model.nodeChanged(node);
}
}
 
449,7 → 409,7
for (int i = 0; i < childCount; i++) {
final ITreeSelectionNode v = (ITreeSelectionNode) nodeParent.getChildAt(i);
if (v.getId() == row.getID()) {
this.model.removeNodeFromParent(v);
model.removeNodeFromParent(v);
}
}
}
459,7 → 419,27
*
*/
private void setTableListener() {
final SQLTableListener listener = new SQLTableListener() {
public void rowModified(SQLTable table, int id) {
final ITreeSelectionNode node = mapNode.get(Integer.valueOf(id));
if (node != null) {
modifyNode(table.getRow(id), node);
}
}
 
this.element.getTable().addTableListener(this.listener);
public void rowAdded(SQLTable table, int id) {
final SQLRow row = table.getRow(id);
int idPere = row.getInt("ID_" + element.getTable().getName() + "_PERE");
addNewNode(null, row, idPere, new HashSet<>());
}
 
public void rowDeleted(SQLTable table, int id) {
final ITreeSelectionNode node = mapNode.get(Integer.valueOf(id));
for (int i = 0; i < node.getChildCount(); i++) {
removeNode(table.getRow(id), node);
}
}
};
this.element.getTable().addTableListener(listener);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/UserExitPanel.java
37,6 → 37,8
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
 
188,15 → 190,50
Gestion.pgFrameStart.setVisible(false);
}
new Thread() {
private PostgreSQLFrame pgFrame = null;
 
@Override
public void run() {
try {
Configuration.getInstance().destroy();
Runtime runtime = Runtime.getRuntime();
 
File f = new File(".\\PostgreSQL\\bin\\");
if (f.exists()) {
final Process p = runtime.exec(new String[] { "cmd.exe", "/C", "stopPostGres.bat" }, null, f);
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
 
try {
pgFrame = new PostgreSQLFrame("Arrêt en cours");
pgFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
System.err.println("Execute end postgres");
ProcessStreams.handle(p, ProcessStreams.Action.REDIRECT);
p.waitFor();
 
}
ComptaPropsConfiguration.getInstanceCompta().tearDownLogging(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
 
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (pgFrame != null) {
pgFrame.dispose();
}
}
});
startTimeOut();
// System.exit(0);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/model/MouseSheetXmlListeListener.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
14,48 → 14,33
package org.openconcerto.erp.model;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.ui.PreviewFrame;
import org.openconcerto.erp.core.customerrelationship.mail.EmailTemplate;
import org.openconcerto.erp.core.customerrelationship.mail.ValueListener;
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.action.ListEvent;
import org.openconcerto.ui.EmailComposer;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.Action;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.ListMap;
import org.openconcerto.utils.i18n.Grammar;
import org.openconcerto.utils.i18n.TranslationManager;
 
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
 
import javax.swing.AbstractAction;
import javax.swing.JFileChooser;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
 
71,15 → 56,13
private boolean previewHeader = false;
private boolean showHeader = false;
private boolean generateHeader = false;
private SQLElement element;
 
public MouseSheetXmlListeListener(SQLElement element, Class<? extends AbstractSheetXml> clazz) {
this(element, clazz, true, true, true, true);
public MouseSheetXmlListeListener(Class<? extends AbstractSheetXml> clazz) {
this(clazz, true, true, true, true);
 
}
 
public MouseSheetXmlListeListener(SQLElement element, Class<? extends AbstractSheetXml> clazz, boolean show, boolean preview, boolean print, boolean generate) {
this.element = element;
public MouseSheetXmlListeListener(Class<? extends AbstractSheetXml> clazz, boolean show, boolean preview, boolean print, boolean generate) {
this.clazz = clazz;
this.printIsVisible = print;
this.previewIsVisible = preview;
132,7 → 115,7
this.showHeader = showHeader;
}
 
public void sendMail(EmailTemplate template, final AbstractSheetXml sheet, final boolean readOnly) {
protected void sendMail(EmailTemplate template, final AbstractSheetXml sheet, final boolean readOnly) {
List<AbstractSheetXml> l = new ArrayList<>(1);
l.add(sheet);
sendMail(template, l, readOnly);
306,7 → 289,7
}, this.previewHeader, "document.modify") {
 
@Override
public boolean enabledFor(ListEvent evt) {
public boolean enabledFor(IListeEvent evt) {
// On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
// du temps
return evt.getSelectedRow() != null && (evt.getTotalRowCount() >= 1);
324,10 → 307,10
try {
final AbstractSheetXml sheet = createAbstractSheet(IListe.get(ev).fetchSelectedRow());
final SQLTable table = IListe.get(ev).getSource().getPrimaryTable();
final Action emailAction = new Action(TranslationManager.getInstance().getTranslationForAction("document.pdf.send.email")) {
sheet.showPreviewDocument(TranslationManager.getInstance().getTranslationForAction("email"), new Runnable() {
 
@Override
public void run(Object source) {
public void run() {
EmailTemplate.askTemplate(IListe.get(ev), table.getDBRoot(), new ValueListener() {
 
@Override
337,23 → 320,7
});
 
}
};
final Action modifyAction = new Action(
TranslationManager.getInstance().getTranslationForAction("modify") + " " + element.getName().getVariant(Grammar.DEFINITE_ARTICLE_SINGULAR)) {
 
@Override
public void run(Object source) {
if (source instanceof PreviewFrame) {
((PreviewFrame) source).dispose();
}
final SQLComponent component = element.createDefaultComponent();
final EditFrame f = new EditFrame(component, EditMode.MODIFICATION);
f.selectionId(IListe.get(ev).getSelectedId());
FrameUtil.show(f);
 
}
};
sheet.showPreviewDocument(Arrays.asList(emailAction, modifyAction));
});
} catch (Exception e) {
ExceptionHandler.handle("Impossible d'ouvrir le fichier", e);
}
362,7 → 329,7
}, this.previewHeader, "document.preview") {
 
@Override
public boolean enabledFor(ListEvent evt) {
public boolean enabledFor(IListeEvent evt) {
// On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
// du temps
return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
392,7 → 359,7
}, this.showHeader, "document.modify") {
 
@Override
public boolean enabledFor(ListEvent evt) {
public boolean enabledFor(IListeEvent evt) {
// On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
// du temps
return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
401,62 → 368,6
 
}
 
l.add(new RowAction(new AbstractAction() {
public void actionPerformed(ActionEvent ev) {
try {
File file = createAbstractSheet(IListe.get(ev).fetchSelectedRow()).getOrCreatePDFDocumentFile(true);
 
JFileChooser fileChooser = new JFileChooser();
fileChooser.setSelectedFile(file);
fileChooser.setDialogTitle(TranslationManager.getInstance().getTranslationForAction("document.saveToPDF"));
 
int userSelection = fileChooser.showSaveDialog(IListe.get(ev));
 
if (userSelection == JFileChooser.APPROVE_OPTION) {
File fileToSave = fileChooser.getSelectedFile();
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(file);
os = new FileOutputStream(fileToSave);
byte[] buffer = new byte[4096];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
 
try {
if (is != null)
is.close();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
if (os != null)
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
 
} catch (Exception e) {
ExceptionHandler.handle("Impossible d'ouvrir le fichier", e);
}
}
}, false, "document.saveToPDF") {
 
@Override
public boolean enabledFor(ListEvent evt) {
// On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
// du temps
return evt.getSelectedRow() != null && evt.getSelectedRowAccessors().size() == 1;
}
});
 
if (this.printIsVisible) {
 
// Impression rapide : imprime le ou les documents sélectionnés (les génère si besoin)
464,8 → 375,8
l.add(new RowAction(new PrintDocumentAction(this), false, "document.print") {
 
@Override
public boolean enabledFor(ListEvent evt) {
return evt.getSelectedRow() != null && evt.getTotalRowCount() > 0;
public boolean enabledFor(IListeEvent evt) {
return evt.getSelectedRow() != null && evt.getSelectedRows().size() > 0;
}
});
 
483,9 → 394,8
if (this.generateIsVisible) {
l.add(new RowAction(new AbstractAction() {
public void actionPerformed(ActionEvent ev) {
List<SQLRowValues> l = IListe.get(ev).getSelectedRows();
 
List<SQLRowAccessor> l = IListe.get(ev).getSelectedRowAccessors();
 
if (l.size() == 1) {
createDocument(ev);
} else {
495,8 → 405,8
}, this.generateHeader, "document.create") {
 
@Override
public boolean enabledFor(ListEvent selection) {
return selection != null && selection.getTotalRowCount() > 0;
public boolean enabledFor(List<SQLRowValues> selection) {
return selection != null && !selection.isEmpty();
}
 
});
513,7 → 423,7
}, false, "document.send.email") {
 
@Override
public boolean enabledFor(ListEvent evt) {
public boolean enabledFor(IListeEvent evt) {
// On ne teste pas l'existence du fichier génété car les IOs peuvent prendre du
// temps
return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
530,7 → 440,7
}, false, "document.pdf.send.email") {
 
@Override
public boolean enabledFor(ListEvent evt) {
public boolean enabledFor(IListeEvent evt) {
// On ne teste pas l'existence du fichier génété car les IOs peuvent prendre du
// temps
return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
546,7 → 456,7
for (SQLRowAccessor sqlRowAccessor : selection) {
final AbstractSheetXml sheet = createAbstractSheet(sqlRowAccessor.getTable().getRow(sqlRowAccessor.getID()));
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(false, false, true, Collections.emptyList());
sheet.showPrintAndExportAsynchronous(false, false, true);
}
}
}
557,7 → 467,7
int a = JOptionPane.showConfirmDialog(null, "Voulez vous remplacer le document existant?", "Génération de documents", JOptionPane.YES_NO_OPTION);
if (a == JOptionPane.YES_OPTION) {
sheet.createDocumentAsynchronous();
sheet.showPrintAndExportAsynchronous(true, false, true, Collections.emptyList());
sheet.showPrintAndExportAsynchronous(true, false, true);
return;
}
}
564,7 → 474,7
 
try {
sheet.getOrCreateDocumentFile();
sheet.showPrintAndExportAsynchronous(true, false, false, Collections.emptyList());
sheet.showPrintAndExportAsynchronous(true, false, false);
} catch (Exception exn) {
exn.printStackTrace();
}
582,7 → 492,7
final AbstractSheetXml sheet = createAbstractSheet(IListe.get(ev).fetchSelectedRow().asRow());
try {
sheet.getOrCreateDocumentFile();
sheet.showPrintAndExportAsynchronous(true, false, true, Collections.emptyList());
sheet.showPrintAndExportAsynchronous(true, false, true);
} catch (Exception exn) {
ExceptionHandler.handle("Une erreur est survenue lors de la création du document.", exn);
}
590,23 → 500,22
}, false, false, "document.create") {
 
@Override
public boolean enabledFor(ListEvent selection) {
return selection != null && selection.getTotalRowCount() == 1;
public boolean enabledFor(List<SQLRowValues> selection) {
return selection != null && selection.size() == 1;
}
 
@Override
public javax.swing.Action getDefaultAction(final ListEvent evt) {
public Action getDefaultAction(final IListeEvent evt) {
return this.getAction();
}
};
}
 
protected void sendMail(ActionEvent ev, boolean pdf) {
final List<SQLRowAccessor> selectedRows = IListe.get(ev).getSelectedRowAccessors();
 
private void sendMail(ActionEvent ev, boolean pdf) {
final List<SQLRowValues> selectedRows = IListe.get(ev).getSelectedRows();
final SQLTable table = IListe.get(ev).getSource().getPrimaryTable();
final List<SQLRow> rows = new ArrayList<>();
for (SQLRowAccessor r : selectedRows) {
for (SQLRowValues r : selectedRows) {
rows.add(table.getRow(r.getID()));
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/model/EditionFichePayeModel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
28,7 → 28,6
 
import java.sql.Date;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
341,7 → 340,7
FichePayeSheetXML sheet = new FichePayeSheetXML(rowFiche);
sheet.createDocumentAsynchronous();
Boolean bPrint = (Boolean) m.get("IMPRESSION");
sheet.showPrintAndExportAsynchronous(false, bPrint.booleanValue(), true, Collections.emptyList());
sheet.showPrintAndExportAsynchronous(false, bPrint.booleanValue(), true);
} catch (Exception e) {
ExceptionHandler.handle("Erreur lors de la création du document!", e);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/rights/DepotStockViewRightEditor.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/SoundGenerator.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/correct/CorrectMouvement.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
48,7 → 48,7
final SQLSelect selUnbalanced = new SQLSelect();
selUnbalanced.addSelect(ecritureMvtFF);
selUnbalanced.addGroupBy(ecritureMvtFF);
selUnbalanced.setHaving(Where.quote(selUnbalanced.getSyntax(), ecritureT.getBase().quote("SUM(%n) != SUM(%n)", ecritureT.getField("DEBIT"), ecritureT.getField("CREDIT"))));
selUnbalanced.setHaving(Where.quote(ecritureT.getBase().quote("SUM(%n) != SUM(%n)", ecritureT.getField("DEBIT"), ecritureT.getField("CREDIT"))));
return selUnbalanced;
}
 
112,7 → 112,7
Where joinEcritureW = null;
for (final String uniqField : uniqueFields) {
final SQLTable t = uniqField.equals("ID_MOUVEMENT") ? saisieKmT : saisieKmElemT;
joinEcritureW = Where.quote(getSyntax(), "e." + SQLBase.quoteIdentifier(uniqField) + "= %f", t.getField(uniqField)).and(joinEcritureW);
joinEcritureW = Where.quote("e." + SQLBase.quoteIdentifier(uniqField) + "= %f", t.getField(uniqField)).and(joinEcritureW);
}
final Where dontOverwrite = new Where(saisieKmElemT.getField("ID_ECRITURE"), Where.NULL_IS_DATA_EQ, ecritureT.getUndefinedIDNumber());
final Where dontUpdateUndef = new Where(saisieKmElemT.getKey(), Where.NULL_IS_DATA_NEQ, saisieKmElemT.getUndefinedIDNumber());
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/DataImporter.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
243,7 → 243,7
if (cellValue == null) {
rowData.add("");
} else {
switch (cellValue.getCellType()) {
switch (cellValue.getCellTypeEnum()) {
case BOOLEAN:
rowData.add(Boolean.valueOf(cellValue.getBooleanValue()));
break;
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/UIPreferencePanel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
279,11 → 279,6
final String look = properties.getProperty(UI_LOOK);
final String nimbusClassName = getNimbusClassName();
if (look != null && look.equals("flat")) {
UIManager.put("Table.showHorizontalLines", true);
UIManager.put("Table.showVerticalLines", true);
UIManager.put("ScrollBar.showButtons", true);
UIManager.put("TabbedPane.selectedBackground", Color.white);
UIManager.put("TabbedPane.showTabSeparators", true);
FlatLightLaf.install();
} else if (look != null && look.equals("system")) {
useSystemLF();
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/TemplateNXProps.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
17,6 → 17,7
import org.openconcerto.erp.core.customerrelationship.customer.report.FicheClientXmlSheet;
import org.openconcerto.erp.core.edm.AttachmentSQLElement;
import org.openconcerto.erp.core.finance.accounting.report.BalanceSheet;
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;
150,6 → 151,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(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/GestionArticleGlobalPreferencePanel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
25,7 → 25,6
import org.openconcerto.utils.PrefType;
 
public class GestionArticleGlobalPreferencePanel extends JavaPrefPreferencePanel {
public static String ACTIVER_DECLINAISON = "GestionDeclinaison";
public static String STOCK_FACT = "StockOnOrder";
public static String UNITE_VENTE = "UniteVenteActive";
public static String USE_CREATED_ARTICLE = "UseCreatedArticle";
41,10 → 40,6
public static String STOCK_MULTI_DEPOT = "MultiDepot";
public static String CAN_EXPAND_NOMENCLATURE_VT = "CanExpandNomenclature";
public static String CAN_EXPAND_NOMENCLATURE_HA = "CanExpandNomenclaturePurchase";
public static String SHOW_LIST_COMPTE = "ShowListProductCompte";
public static String SHOW_LIST_TAXE = "ShowListProductTaxe";
public static String SHOW_LIST_FAMILLE = "ShowListProductFamille";
public static String SHOW_LIST_FOURNISSEUR = "ShowListProductFournisseur";
 
public GestionArticleGlobalPreferencePanel() {
super("Gestion des articles", null);
87,10 → 82,6
view.setDefaultValue(Boolean.TRUE);
this.addView(view);
 
PrefView<Boolean> viewGestionDeclinaison = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Activer la gestion des déclinaisons", ACTIVER_DECLINAISON);
viewGestionDeclinaison.setDefaultValue(Boolean.FALSE);
this.addView(viewGestionDeclinaison);
 
PrefView<Boolean> viewMultiStock = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Activer la gestion multidépôt", STOCK_MULTI_DEPOT);
viewMultiStock.setDefaultValue(Boolean.FALSE);
this.addView(viewMultiStock);
119,18 → 110,5
view5.setDefaultValue(Boolean.FALSE);
this.addView(view5);
 
PrefView<Boolean> viewCompte = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Afficher les comptes comptables des articles dans les listes", SHOW_LIST_COMPTE);
viewCompte.setDefaultValue(Boolean.FALSE);
this.addView(viewCompte);
PrefView<Boolean> viewTaxe = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Afficher la TVA des articles dans les listes", SHOW_LIST_TAXE);
viewTaxe.setDefaultValue(Boolean.FALSE);
this.addView(viewTaxe);
PrefView<Boolean> viewFamille = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Afficher les familles des articles dans les listes", SHOW_LIST_FAMILLE);
viewFamille.setDefaultValue(Boolean.FALSE);
this.addView(viewFamille);
PrefView<Boolean> viewFournisseur = new PrefView<Boolean>(PrefType.BOOLEAN_TYPE, "Afficher les fournisseurs des articles dans les listes", SHOW_LIST_FOURNISSEUR);
viewFournisseur.setDefaultValue(Boolean.FALSE);
this.addView(viewFournisseur);
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/GenerationDocumentComptaPreferencePanel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
14,6 → 14,7
package org.openconcerto.erp.preferences;
 
import org.openconcerto.erp.core.finance.accounting.report.BalanceSheet;
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheetXML;
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheetXML;
import org.openconcerto.utils.Tuple2;
 
21,8 → 22,10
 
public GenerationDocumentComptaPreferencePanel() {
super();
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();
}
 
public String getTitleName() {
/trunk/OpenConcerto/src/org/openconcerto/erp/config/NewsChecker.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ComptaPropsConfiguration.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
83,7 → 83,6
import org.openconcerto.erp.core.humanresources.employe.element.ObjectifSQLElement;
import org.openconcerto.erp.core.humanresources.employe.element.SituationFamilialeSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.AcompteSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.ArretChomageIntemperieSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.AyantDroitContratPrevSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.AyantDroitSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.AyantDroitTypeSQLElement;
93,7 → 92,6
import org.openconcerto.erp.core.humanresources.payroll.element.ClassementConventionnelSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.CodeAmenagementPartielSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.CodeBaseAssujettieSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.CodeCaisseCongesPayesSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.CodeCaisseTypeRubriqueSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.CodeCaractActiviteSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.CodeContratTravailSQLElement;
133,7 → 131,6
import org.openconcerto.erp.core.humanresources.payroll.element.ModeReglementPayeSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.MotifArretTravailSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.MotifFinContratSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.MotifNonAssujettisTASQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.MotifRepriseArretTravailSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.PasSQLElement;
import org.openconcerto.erp.core.humanresources.payroll.element.PeriodeValiditeSQLElement;
174,14 → 171,11
import org.openconcerto.erp.core.sales.pos.element.TicketCaisseSQLElement;
import org.openconcerto.erp.core.sales.pos.io.BarcodeReader;
import org.openconcerto.erp.core.sales.price.element.DeviseSQLElement;
import org.openconcerto.erp.core.sales.price.element.TarifPromotionSQLElement;
import org.openconcerto.erp.core.sales.price.element.TarifSQLElement;
import org.openconcerto.erp.core.sales.product.element.ArticleCatComptableSQLElement;
import org.openconcerto.erp.core.sales.product.element.ArticleCodeClientSQLElement;
import org.openconcerto.erp.core.sales.product.element.ArticleDeclinaisonSQLElement;
import org.openconcerto.erp.core.sales.product.element.ArticleDesignationSQLElement;
import org.openconcerto.erp.core.sales.product.element.ArticleFournisseurSecondaireSQLElement;
import org.openconcerto.erp.core.sales.product.element.ArticleTarifPromotionSQLElement;
import org.openconcerto.erp.core.sales.product.element.ArticleTarifSQLElement;
import org.openconcerto.erp.core.sales.product.element.CoutRevientSQLElement;
import org.openconcerto.erp.core.sales.product.element.CustomerProductFamilyQtyPriceSQLElement;
189,7 → 183,6
import org.openconcerto.erp.core.sales.product.element.EcoContributionSQLElement;
import org.openconcerto.erp.core.sales.product.element.FamilleArticleSQLElement;
import org.openconcerto.erp.core.sales.product.element.FamilleEcoContributionSQLElement;
import org.openconcerto.erp.core.sales.product.element.LotSQLElement;
import org.openconcerto.erp.core.sales.product.element.MetriqueSQLElement;
import org.openconcerto.erp.core.sales.product.element.ModeVenteArticleSQLElement;
import org.openconcerto.erp.core.sales.product.element.ProductItemSQLElement;
198,7 → 191,6
import org.openconcerto.erp.core.sales.product.element.ReliquatSQLElement;
import org.openconcerto.erp.core.sales.product.element.ReliquatSQLElement.ReliquatBRSQLElement;
import org.openconcerto.erp.core.sales.product.element.SupplierPriceListSQLElement;
import org.openconcerto.erp.core.sales.product.element.TaxeCatComptableSQLElement;
import org.openconcerto.erp.core.sales.product.element.UniteVenteArticleSQLElement;
import org.openconcerto.erp.core.sales.quote.element.DevisItemSQLElement;
import org.openconcerto.erp.core.sales.quote.element.DevisLogMailSQLElement;
262,9 → 254,7
import org.openconcerto.erp.generationDoc.provider.PrixUVProvider;
import org.openconcerto.erp.generationDoc.provider.PrixUnitaireProvider;
import org.openconcerto.erp.generationDoc.provider.PrixUnitaireRemiseProvider;
import org.openconcerto.erp.generationDoc.provider.QteLineDocProvider;
import org.openconcerto.erp.generationDoc.provider.QteTotalDocProvider;
import org.openconcerto.erp.generationDoc.provider.QteTotalLineDocProvider;
import org.openconcerto.erp.generationDoc.provider.QteTotalProvider;
import org.openconcerto.erp.generationDoc.provider.RecapFactureProvider;
import org.openconcerto.erp.generationDoc.provider.RefClientValueProvider;
302,7 → 292,6
import org.openconcerto.erp.injector.DevisBlSQLInjector;
import org.openconcerto.erp.injector.DevisCommandeFournisseurSQLInjector;
import org.openconcerto.erp.injector.DevisCommandeSQLInjector;
import org.openconcerto.erp.injector.DevisEltCmdEltSQLInjector;
import org.openconcerto.erp.injector.DevisEltFactureEltSQLInjector;
import org.openconcerto.erp.injector.DevisFactureSQLInjector;
import org.openconcerto.erp.injector.DmdAchatDmdPrixEltSQLInjector;
368,7 → 357,6
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.Set;
 
import javax.imageio.ImageIO;
import javax.swing.JFrame;
450,8 → 438,7
// b/ dans le jar
try {
final Properties props;
// webstart should be self-contained, e.g. if a user launches from the web it
// shoudln't
// webstart should be self-contained, e.g. if a user launches from the web it shoudln't
// read an old preference file but should always read its own configuration.
if (confFile != null && confFile.exists() && !inWebStart) {
props = create(new FileInputStream(confFile), defaults);
487,7 → 474,6
private File portableDir = null;
private Currency currency = null;
private final ModuleManager moduleMngr = new ModuleManager();
private boolean isExperimental;
 
public ComptaPropsConfiguration(Properties props, final ProductInfo productInfo) {
super(props, productInfo);
502,7 → 488,6
this.isMain = main;
this.inWebstart = inWebstart;
this.isPortable = Boolean.parseBoolean(this.getProperty("portable", "false"));
this.isExperimental = Boolean.parseBoolean(this.getProperty("experimental", "false"));
String pDir = this.getProperty("portableDir", null);
if (isPortable) {
if (pDir == null) {
592,11 → 577,10
}
this.setProperty("server.ip", getProperty("server.ip").replace(DATA_DIR_VAR, getDataDir().getPath()));
final SQLSystem system = getSystem();
this.isServerless = system == SQLSystem.H2 && system.getHostnameAndPath(getServerIp()).get0() == null;
this.isServerless = system == SQLSystem.H2 && system.getHostname(getServerIp()) == null;
}
if (this.isMain) {
// ATTN this works because this is executed last (i.e. if you put this in a
// superclass
// ATTN this works because this is executed last (i.e. if you put this in a superclass
// this won't work since e.g. app.name won't have its correct value)
try {
this.setupLogging("logs");
606,10 → 590,6
registerAccountingProvider();
registerCellValueProvider();
}
 
// Early so that other apps may add jars before setUpSocieteDataBaseConnexion()
// Perhaps add a folder relative to VMLauncher.getJPackageAppDir()
this.getModuleManager().setFolders(new File(Gestion.MODULES_DIR_NAME), new File(this.getBaseDirs().getAppDataFolder(), Gestion.MODULES_DIR_NAME));
}
 
public final TM getERP_TM() {
642,8 → 622,6
AdresseVilleNomClientValueProvider.register();
AdresseFullClientValueProvider.register();
QteTotalProvider.register();
QteLineDocProvider.register();
QteTotalLineDocProvider.register();
QteTotalDocProvider.register();
StockLocationProvider.register();
RefClientValueProvider.register();
679,10 → 657,6
return getProperty("token");
}
 
public boolean isExperimental() {
return isExperimental;
}
 
public final boolean isServerless() {
return this.isServerless;
}
748,8 → 722,7
return;
try {
// H2 create the database on connection
// don't create if root explicitly excluded (e.g. map no roots just to quickly
// test
// don't create if root explicitly excluded (e.g. map no roots just to quickly test
// connection)
if (sysRoot.shouldMap(getRootName()) && !sysRoot.contains(getRootName())) {
Log.get().warning("Creating DB");
776,10 → 749,8
@Override
protected DBSystemRoot createSystemRoot() {
final DBSystemRoot res = super.createSystemRoot();
// Don't create a separate server for createDB() as on normal databases just
// setting up a
// data source can take 2 seconds (e.g. validateConnectionFactory()). And this
// is for every
// Don't create a separate server for createDB() as on normal databases just setting up a
// data source can take 2 seconds (e.g. validateConnectionFactory()). And this is for every
// boot.
this.createDB(res);
return res;
806,8 → 777,6
dir.addSQLElement(CodeBaseAssujettieSQLElement.class, root);
dir.addSQLElement(ContratModaliteTempsSQLElement.class, root);
dir.addSQLElement(CodeCaisseTypeRubriqueSQLElement.class, root);
dir.addSQLElement(CodeCaisseCongesPayesSQLElement.class, root);
dir.addSQLElement(MotifNonAssujettisTASQLElement.class, root);
dir.addSQLElement(CodeTypeRubriqueBrutSQLElement.class, root);
dir.addSQLElement(MotifArretTravailSQLElement.class, root);
dir.addSQLElement(ContratDispositifPolitiqueSQLElement.class, root);
847,8 → 816,6
dir.addSQLElement(CodeCotisationIndividuelleSQLElement.class, root);
dir.addSQLElement(CodeCotisationEtablissementSQLElement.class, root);
dir.addSQLElement(CodePenibiliteSQLElement.class, root);
dir.addSQLElement(CodeIdccSQLElement.class, root);
 
dir.addSQLElement(new ImpressionRubriqueSQLElement(root));
 
dir.addSQLElement(new VariablePayeSQLElement(root));
864,15 → 831,8
}
// Check 1.6 updated
if (!this.getRootSociete().contains("ETAT_STOCK")) {
throw new DBStructureItemNotFound("Base de données non à jour (<1.6)");
throw new DBStructureItemNotFound("Base de données non à jour");
}
// Check 1.7 updated
if (!this.getRootSociete().contains("AGENCE")) {
throw new DBStructureItemNotFound("Base de données non à jour (< 1.7.0)");
}
if (!this.getRootSociete().getTable("NUMEROTATION_AUTO").contains("ARTICLE_FORMAT")) {
throw new DBStructureItemNotFound("Base de données non à jour (< 1.7.1)");
}
SQLElementDirectory dir = this.getDirectory();
 
dir.addSQLElement(AttachmentSQLElement.class);
889,7 → 849,6
dir.addSQLElement(ProductItemSQLElement.class);
dir.addSQLElement(CategorieComptableSQLElement.class);
dir.addSQLElement(ArticleCatComptableSQLElement.class);
dir.addSQLElement(TaxeCatComptableSQLElement.class);
dir.addSQLElement(ArticleFournisseurSecondaireSQLElement.class);
dir.addSQLElement(SupplierPriceListSQLElement.class);
dir.addSQLElement(FraisDocumentSQLElement.class);
927,14 → 886,7
dir.addSQLElement(new AcompteSQLElement());
 
dir.addSQLElement(new AxeAnalytiqueSQLElement());
Set<SQLTable> tablesInRoot = dir.getElement(ReferenceArticleSQLElement.class).getTable().getDBRoot().getTables();
for (SQLTable table : tablesInRoot) {
if (table.getName().startsWith("ARTICLE_DECLINAISON_")) {
dir.addSQLElement(new ArticleDeclinaisonSQLElement(table.getName()));
}
}
 
dir.addSQLElement(LotSQLElement.class);
dir.addSQLElement(new BonDeLivraisonItemSQLElement());
dir.addSQLElement(new BonDeLivraisonSQLElement());
dir.addSQLElement(new TransferShipmentSQLElement());
1020,6 → 972,8
 
dir.addSQLElement(new FournisseurSQLElement());
 
dir.addSQLElement(new CodeIdccSQLElement());
 
dir.addSQLElement(new InfosSalariePayeSQLElement());
 
dir.addSQLElement(new JournalSQLElement());
1067,9 → 1021,10
dir.addSQLElement(SituationFamilialeSQLElement.class);
dir.addSQLElement(new StockSQLElement());
dir.addSQLElement(new StyleSQLElement());
 
dir.addSQLElement(new SalarieSQLElement());
 
dir.addSQLElement(TarifSQLElement.class);
dir.addSQLElement(TarifPromotionSQLElement.class);
dir.addSQLElement(ArticleTarifPromotionSQLElement.class);
dir.addSQLElement(new TaxeSQLElement());
dir.addSQLElement(TaxeComplementaireSQLElement.class);
dir.addSQLElement(TicketCaisseSQLElement.class);
1081,17 → 1036,8
dir.addSQLElement(new TypeReglementSQLElement());
dir.addSQLElement(new SDDMessageSQLElement(this));
dir.addSQLElement(new SEPAMandateSQLElement(this));
dir.addSQLElement(TarifSQLElement.class);
dir.addSQLElement(TarifPromotionSQLElement.class);
dir.addSQLElement(ArticleTarifPromotionSQLElement.class);
dir.addSQLElement(new TaxeSQLElement());
dir.addSQLElement(TaxeComplementaireSQLElement.class);
dir.addSQLElement(TicketCaisseSQLElement.class);
dir.addSQLElement(ClôtureCaisseSQLElement.class);
dir.addSQLElement(CaisseJournalSQLElement.class);
 
dir.addSQLElement(new VariableSalarieSQLElement());
dir.addSQLElement(SalarieSQLElement.class);
dir.addSQLElement(UniteVenteArticleSQLElement.class);
 
dir.addSQLElement(CalendarItemSQLElement.class);
1099,8 → 1045,6
dir.addSQLElement(DeviseHistoriqueSQLElement.class);
dir.addSQLElement(EmailTemplateSQLElement.class);
 
dir.addSQLElement(ArretChomageIntemperieSQLElement.class);
 
if (getRootSociete().contains("FWK_LIST_PREFS")) {
dir.addSQLElement(new FWKListPrefs(getRootSociete()));
}
1165,7 → 1109,6
new FactureCommandeSQLInjector(rootSociete);
new DevisFactureSQLInjector(rootSociete);
new DevisCommandeSQLInjector(rootSociete);
new DevisEltCmdEltSQLInjector(rootSociete);
new DevisCommandeFournisseurSQLInjector(rootSociete);
new DevisBlEltSQLInjector(rootSociete);
new DevisBlSQLInjector(rootSociete);
1248,15 → 1191,8
 
List<String> listFieldDevisElt = new ArrayList<String>();
listFieldDevisElt.add("NUMERO");
listFieldDevisElt.add("OBJET");
listFieldDevisElt.add("DATE");
listFieldDevisElt.add("ID_CLIENT");
if (root.getTable("DEVIS").contains("DATE_LIVRAISON")) {
listFieldDevisElt.add("DATE_LIVRAISON");
}
if (root.getTable("DEVIS").contains("TRANSFORMATION")) {
listFieldDevisElt.add("TRANSFORMATION");
}
 
listFieldDevisElt.add("ID_ETAT_DEVIS");
showAs.showField("DEVIS_ELEMENT.ID_DEVIS", listFieldDevisElt);
1307,14 → 1243,21
 
List<String> listFieldFactureElt = new ArrayList<String>();
listFieldFactureElt.add("NUMERO");
listFieldFactureElt.add("NOM");
listFieldFactureElt.add("DATE");
listFieldFactureElt.add("ID_COMMERCIAL");
listFieldFactureElt.add("ID_CLIENT");
showAs.showField("SAISIE_VENTE_FACTURE_ELEMENT.ID_SAISIE_VENTE_FACTURE", listFieldFactureElt);
 
showAs.show("SALARIE", SQLRow.toList("CODE,NOM,PRENOM"));
 
showAs.show("SITUATION_FAMILIALE", "NOM");
 
if (root.getTable("STOCK").contains("ID_ARTICLE")) {
List<String> listFieldArtElt = new ArrayList<String>();
listFieldArtElt.add("CODE");
listFieldArtElt.add("NOM");
listFieldArtElt.add("ID_FAMILLE_ARTICLE");
showAs.showField("STOCK.ID_ARTICLE", listFieldArtElt);
}
showAs.show("STYLE", "NOM");
 
showAs.show("TAXE", "TAUX");
1365,6 → 1308,7
// Prefetch undefined
rootSociete.getTables().iterator().next().getUndefinedID();
 
this.getModuleManager().addFactories(Gestion.MODULES_DIR);
this.getModuleManager().setup(this.getRootSociete(), this);
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/config/MenuManager.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
24,14 → 24,10
public class MenuManager {
private static MenuManager instance = null;
 
public static final void setInstance(final MenuAndActions baseMA) {
setInstance(new MenuManager(baseMA));
public static synchronized final void setInstance(final MenuAndActions baseMA) {
instance = new MenuManager(baseMA);
}
 
public static synchronized final void setInstance(final MenuManager mm) {
instance = mm;
}
 
public static synchronized final MenuManager getInstance() {
if (instance == null)
throw new IllegalStateException("Not inited");
/trunk/OpenConcerto/src/org/openconcerto/erp/config/MainFrame.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
33,7 → 33,6
 
import java.awt.Color;
import java.awt.Container;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
44,9 → 43,6
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
79,10 → 75,6
public static final String FILE_MENU = "menu.file";
public static final String HELP_MENU = "menu.help";
 
public static final String PREFS_MENU_ITEM = "preferences";
public static final String QUIT_MENU_ITEM = "quit";
public static final String ABOUT_MENU_ITEM = "information";
 
static private final List<Runnable> runnables = new ArrayList<Runnable>();
@GuardedBy("MainFrame")
static private MainFrame instance = null;
193,6 → 185,8
final File confFile = new File(conf.getConfDir(), "Configuration" + File.separator + "Frame" + File.separator + "mainFrame" + confSuffix + ".xml");
new WindowStateManager(this, confFile).loadState();
 
registerForMacOSXEvents();
 
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
217,10 → 211,10
if (im != null) {
image.setImage(im);
}
 
new NewsUpdater(this.image);
}
 
// create the UI menu from the MenuAndActions and hide items handled by java.awt.Desktop
// create the UI menu from the menu manager
public final void initMenuBar() {
final MenuManager mm = MenuManager.getInstance();
final PropertyChangeListener listener = new PropertyChangeListener() {
388,59 → 382,10
MenuUtils.removeMenuItem(item);
}
 
public void registerDesktopEvents(final MenuAndActions menuAndActions) {
// First try standard >=9 way, otherwise fall back to com.apple.eawt.Application
if (!this.registerAWTDesktopEvents(menuAndActions))
this.registerForMacOSXEvents(menuAndActions);
}
 
private boolean registerAWTDesktopEvents(final MenuAndActions menuAndActions) {
if (!Desktop.isDesktopSupported())
return false;
final Desktop desktop = Desktop.getDesktop();
final boolean quitHandled = registerAWTDesktopEvent(desktop, "QuitHandler", "APP_QUIT_HANDLER", menuAndActions, QUIT_MENU_ITEM);
final boolean aboutHandled = registerAWTDesktopEvent(desktop, "AboutHandler", "APP_ABOUT", menuAndActions, ABOUT_MENU_ITEM);
final boolean prefsHandled = registerAWTDesktopEvent(desktop, "PreferencesHandler", "APP_PREFERENCES", menuAndActions, PREFS_MENU_ITEM);
return quitHandled && aboutHandled && prefsHandled;
}
 
private boolean registerAWTDesktopEvent(final Desktop desktop, final String handlerClassName, final String desktopActionName, final MenuAndActions menuAndActions, final String menuActionName) {
final Desktop.Action appPrefsAction;
try {
appPrefsAction = Desktop.Action.valueOf(desktopActionName);
} catch (Exception e) {
// JRE <9, fallback to the old way
return false;
}
if (!desktop.isSupported(appPrefsAction)) {
// JRE >= 9, but not supported
return false;
}
try {
final Class<?> prefHandlerClass = Class.forName("java.awt.desktop." + handlerClassName);
final Object prefHandler = Proxy.newProxyInstance(prefHandlerClass.getClassLoader(), new Class<?>[] { prefHandlerClass }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
menuAndActions.getAction(menuActionName).actionPerformed(null);
return null;
}
});
desktop.getClass().getMethod("set" + handlerClassName, prefHandlerClass).invoke(desktop, prefHandler);
menuAndActions.setMenuItemVisible(menuActionName, false);
return true;
} catch (Exception e) {
// Unknown error, still try to fallback to the old way
e.printStackTrace();
return false;
}
}
 
// Generic registration with the Mac OS X application menu
// Checks the platform, then attempts to register with the Apple EAWT
// See OSXAdapter.java to see how this is done without directly referencing any Apple APIs
// Remove once depending on Java 11.
@Deprecated
public void registerForMacOSXEvents(final MenuAndActions menuAndActions) {
public void registerForMacOSXEvents() {
if (Gestion.MAC_OS_X) {
try {
// Generate and register the OSXAdapter, passing it a hash of all the methods we
448,9 → 393,6
OSXAdapter.setQuitHandler(this, getClass().getDeclaredMethod("quit", new Class[0]));
OSXAdapter.setAboutHandler(this, getClass().getDeclaredMethod("about", new Class[0]));
OSXAdapter.setPreferencesHandler(this, getClass().getDeclaredMethod("preferences", new Class[0]));
menuAndActions.setMenuItemVisible(QUIT_MENU_ITEM, false);
menuAndActions.setMenuItemVisible(ABOUT_MENU_ITEM, false);
menuAndActions.setMenuItemVisible(PREFS_MENU_ITEM, false);
// no OSXAdapter.setFileHandler() for now
} catch (Exception e) {
System.err.println("Error while loading the OSXAdapter:");
460,14 → 402,12
}
 
// used by OSXAdapter
@Deprecated
public final void preferences() {
MenuManager.getInstance().getActionForId(PREFS_MENU_ITEM).actionPerformed(null);
MenuManager.getInstance().getActionForId("preferences").actionPerformed(null);
}
 
@Deprecated
public final void about() {
MenuManager.getInstance().getActionForId(ABOUT_MENU_ITEM).actionPerformed(null);
MenuManager.getInstance().getActionForId("information").actionPerformed(null);
}
 
public boolean quit() {
/trunk/OpenConcerto/src/org/openconcerto/erp/config/NewsUpdater.java
New file
0,0 → 1,83
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.config;
 
import org.openconcerto.utils.JImage;
 
import java.awt.MediaTracker;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Random;
 
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
 
public class NewsUpdater {
 
public NewsUpdater(final JImage image) {
final Thread tDownloader = new Thread(new Runnable() {
 
@Override
public void run() {
final String id = ComptaPropsConfiguration.getInstance().getAppID();
 
final String imageUrl = "http://www.ilm-informatique.fr/news/" + id + ".png";
 
try {
final URL location = new URL(imageUrl);
final File tempFile = File.createTempFile("newsupdater_image", ".png");
FileOutputStream out = new FileOutputStream(tempFile);
URLConnection conn = location.openConnection();
InputStream in = conn.getInputStream();
byte[] buffer = new byte[1024];
int numRead;
 
while ((numRead = in.read(buffer)) != -1) {
out.write(buffer, 0, numRead);
 
}
out.close();
in.close();
final ImageIcon im = new ImageIcon(tempFile.getAbsolutePath());
 
if (im.getImageLoadStatus() == MediaTracker.COMPLETE) {
SwingUtilities.invokeLater(new Runnable() {
 
@Override
public void run() {
image.invalidate();
image.setImage(im.getImage());
image.revalidate();
image.repaint();
 
}
});
 
}
} catch (Exception exception) {
System.err.println("Unable to get:" + imageUrl);
}
}
}, "News updater");
tDownloader.setPriority(Thread.MIN_PRIORITY);
Random r = new Random();
if (r.nextInt(3) == 0) {
tDownloader.start();
}
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/DefaultMenuConfiguration.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
40,7 → 40,6
import org.openconcerto.erp.core.finance.accounting.action.GestionPlanComptableEAction;
import org.openconcerto.erp.core.finance.accounting.action.ImportEcritureAction;
import org.openconcerto.erp.core.finance.accounting.action.ImportEcritureFECAction;
import org.openconcerto.erp.core.finance.accounting.action.ImportEcritureRImportAction;
import org.openconcerto.erp.core.finance.accounting.action.ImpressionJournauxAnalytiqueAction;
import org.openconcerto.erp.core.finance.accounting.action.ImpressionLivrePayeAction;
import org.openconcerto.erp.core.finance.accounting.action.ImpressionRepartitionAnalytiqueAction;
81,6 → 80,7
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesContratsPrevoyanceAction;
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesSalariesAction;
import org.openconcerto.erp.core.humanresources.employe.action.ListeDesSecretairesAction;
import org.openconcerto.erp.core.humanresources.employe.action.N4DSAction;
import org.openconcerto.erp.core.humanresources.payroll.action.ClotureMensuellePayeAction;
import org.openconcerto.erp.core.humanresources.payroll.action.EditionFichePayeAction;
import org.openconcerto.erp.core.humanresources.payroll.action.ListeDesInfosSalariePayeAction;
124,7 → 124,6
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;
import org.openconcerto.erp.core.sales.order.element.CommandeClientSQLElement;
import org.openconcerto.erp.core.sales.pos.action.ListeDesCaissesTicketAction;
import org.openconcerto.erp.core.sales.product.action.FamilleArticleAction;
import org.openconcerto.erp.core.sales.product.action.ListeDesArticlesAction;
261,8 → 260,10
if (UserRightsManager.getCurrentUserRights().haveRight(BackupPanel.RIGHT_CODE))
group.addItem("backup");
group.addItem("modules");
group.addItem(MainFrame.PREFS_MENU_ITEM);
group.addItem(MainFrame.QUIT_MENU_ITEM);
if (!Gestion.MAC_OS_X) {
group.addItem("preferences");
group.addItem("quit");
}
return group;
}
 
309,7 → 310,7
 
public Group createHelpMenuGroup() {
final Group group = new Group(MainFrame.HELP_MENU);
group.addItem(MainFrame.ABOUT_MENU_ITEM);
group.addItem("information");
group.addItem("tips");
return group;
}
440,7 → 441,7
group.addItem("accounting.costs.report");
group.addItem("accounting.balance.report");
// group.addItem("accounting.2050Report");
// group.addItem("employe.social.report");
group.addItem("employe.social.report");
return group;
}
 
462,9 → 463,6
final Group gIO = new Group("menu.accounting.io", LayoutHints.DEFAULT_NOLABEL_SEPARATED_GROUP_HINTS);
gIO.addItem("accounting.import");
gIO.addItem("accounting.import.fec");
if (this.configuration.isExperimental()) {
gIO.addItem("accounting.import.rimport");
}
gIO.addItem("accounting.export");
group.add(gIO);
 
518,7 → 516,6
}
 
gCustomer.addItem("customer.credit.list");
gCustomer.addItem("sales.quote.element.list");
gCustomer.addItem("customer.invoice.details.list");
 
final Group gSupplier = new Group("menu.list.supplier", LayoutHints.DEFAULT_NOLABEL_SEPARATED_GROUP_HINTS);
558,9 → 555,6
 
public Group createTestMenuGroup() {
final Group group = new Group("menu.test");
group.addItem("test.checkReplannedCmd");
group.addItem("test.checkReplannedMultiCmd");
 
group.addItem("test.lettrage.fact");
group.addItem("test.lettrage.compt");
group.addItem("test.lettrage.achat");
587,13 → 581,13
FrameUtil.show(this.frame);
}
}, "modules");
mManager.putAction(new PreferencesAction(getConfiguration().getModuleManager()), MainFrame.PREFS_MENU_ITEM);
mManager.putAction(new PreferencesAction(getConfiguration().getModuleManager()), "preferences");
mManager.putAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
MainFrame.getInstance().quit();
}
}, MainFrame.QUIT_MENU_ITEM);
}, "quit");
}
 
public void registerCreationMenuActions(final MenuAndActions mManager) {
674,7 → 668,6
 
mManager.putAction(new ListeDesAvoirsClientsAction(conf), "customer.credit.list");
mManager.putAction(new ListeDesFactureItemsAction(conf), "customer.invoice.details.list");
mManager.putAction(new ListeDesElementsDevisAction(conf), "sales.quote.element.list");
 
mManager.putAction(new ListeDesFournisseursAction(), "supplier.list");
mManager.putAction(new ListeDesContactsFournisseursAction(), "supplier.contact.list");
720,7 → 713,6
mManager.putAction(new ImportEcritureAction(), "accounting.import");
mManager.putAction(new ExportRelationExpertAction(), "accounting.export");
mManager.putAction(new ImportEcritureFECAction(), "accounting.import.fec");
mManager.putAction(new ImportEcritureRImportAction(), "accounting.import.rimport");
}
 
public void registerStatsDocumentsActions(final MenuAndActions mManager) {
727,7 → 719,7
// mManager.putAction("accounting.vat.report", new DeclarationTVAAction());
mManager.putAction(new EtatChargeAction(), "accounting.costs.report");
mManager.putAction(new CompteResultatBilanAction(), "accounting.balance.report");
// mManager.putAction(new N4DSAction(), "employe.social.report");
mManager.putAction(new N4DSAction(), "employe.social.report");
// mManager.putAction("accounting.2050Report", new CompteResultatBilan2050Action());
}
 
889,7 → 881,7
}
 
public void registerHelpMenuActions(final MenuAndActions mManager) {
mManager.putAction(new AboutAction(getConfiguration()), MainFrame.ABOUT_MENU_ITEM);
mManager.putAction(new AboutAction(getConfiguration()), "information");
mManager.putAction(new AstuceAction(), "tips");
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/config/translation_fr.xml
161,11 → 161,6
<menu id="menu.supplier.invoice.list" label="Factures" />
<menu id="menu.supplier.credit.list" label="Avoirs" />
 
<!-- Standard labels -->
<item id="button.cancel" label="Annuler" />
<item id="button.close" label="Fermer" />
<item id="button.add" label="Ajouter" />
<item id="button.save.modification" label="Enregistrer les modifications" />
 
 
<!-- Quote -->
184,7 → 179,9
<action id="sales.quote.clone" label="Créer à partir de" />
<action id="sales.quote.create.customer.order" label="Transfert vers commande client" />
<action id="sales.quote.create.customer.delivery" label="Transfert vers bon de livraison" />
<action id="sales.quote.accept.create.customer.order" label="Accepté et Transfert en commande client" />
 
<action id="sales.quote.accept.create.customer.order"
label="Marquer comme accepté et Transfert en commande client" />
<!-- Customer -->
<action id="customerrelationship.customer.label.print" label="Imprimer l'étiquette client" />
<action id="customerrelationship.customer.info.create" label="Créer la fiche client" />
214,7 → 211,6
<action id="sales.shipment.create.invoice" label="Transfert en facture" />
 
<!-- Document -->
<action id="modify" label="Modifier" />
<action id="document.quickprint" label="Impression rapide" />
<action id="document.print" label="Imprimer..." />
<action id="document.print.all" label="Imprimer les documents" />
223,8 → 219,6
<action id="document.create" label="Générer le document" />
<action id="document.pdf.send.email" label="Envoyer le document PDF par email" />
<action id="document.send.email" label="Envoyer le document par email" />
<action id="document.saveToPDF" label="Enregistrer le PDF sous ..." />
<action id="ticket.document.generate" label="Générer une facture" />
 
<!-- Supplier order -->
<action id="supplychain.order.create.purchase" label="Transfert vers saisie achat" />
236,7 → 230,6
<action id="sales.order.create.deliverynote" label="Transfert vers bon de livraison" />
<action id="sales.order.create.invoice" label="Transfert vers facture" />
<action id="sales.order.create.supplier.order" label="Transfert vers commande fournisseur" />
<action id="sales.order.reliquat.show" label="Voir les reliquats" />
<item id="sales.order.state.waiting" label="A préparer" />
<item id="sales.order.state.running" label="En préparation" />
<item id="sales.order.state.noStock" label="Rupture de stock" />
245,15 → 238,7
<item id="sales.order.state.block" label="Bloquée" />
<item id="sales.order.state.cancelled" label="Annulée" />
 
 
 
<item id="sales.order.state.kd.waiting" label="En attente" />
<item id="sales.order.state.kd.rapportrecu" label="Facturable(Rapport reçu)" />
<item id="sales.order.state.kd.facture" label="Facturé" />
<item id="sales.order.state.kd.cancelled" label="Annulée" />
 
<!-- Customer -->
<item id="customerrelationship.customer" label="Clients" />
<item id="delivery.address.same.main.address" label="Adresse identique à l'adresse du siège" />
<item id="invoice.address.same.main.address" label="Adresse identique à l'adresse du siège" />
<item id="customerrelationship.customer.address" label="Adresses" />
337,51 → 322,4
<item id="csg.imp" label="CSG/CRDS non déductible à l'impôt sur le revenu" />
<item id="allegement" label="Allégement de cotisation" />
<action id="email" label="Email" />
 
<!-- Affaire -->
<action id="controle.project.seeAttribution" label="Voir la fiche d'attribution" />
<action id="controle.project.invoice" label="Facturer" />
<action id="controle.project.history" label="Historique" />
<action id="controle.project.seeAdminLabel" label="Voir l'étiquette administrative" />
<action id="controle.project.generateAdminLabel" label="Générer l'étiquette administrative" />
<action id="controle.project.seeTechLabel" label="Voir l'étiquette technique" />
<action id="controle.project.generateTechLabel" label="Générer l'étiquette technique" />
 
<!-- Avoir fournisseur -->
<item id="supplychain.credit.note.amounts" label="Montant" />
<item id="supplychain.credit.note.accounting" label="Comptabilité" />
<item id="supplychain.credit.note.information" label="Informations Complémentaires" />
 
<!-- Finances -->
<item id="finance.accounting.userentry.table" label="Comptabilité" />
<item id="finance.accounting.userentry.create.account" label=" " />
<item id="finance.accounting.userentry.create.lineauto" label=" " />
<item id="finance.accounting.userentry.total.credit" label="Crédit" />
<item id="finance.accounting.userentry.total.debit" label="Débit" />
<item id="finance.accounting.userentry.total" label="Totaux" />
<item id="finance.accounting.userentry.warning" label=" " />
 
<!-- Commercial -->
<item id="humanresources.employe.salesman.tab1" label="Informations" />
<item id="humanresources.employe.salesman.tab2" label="Objectifs" />
<item id="humanresources.employe.salesman.initial" label="Initiales" />
 
<!-- Fournisseur -->
<item id="supplychain.supplier" label="Fournisseurs" />
<item id="supplychain.supplier.tab1" label="Adresses" />
<item id="supplychain.supplier.tab2" label="Contacts" />
<item id="supplychain.supplier.tab3" label="Mode de règlement" />
<item id="supplychain.supplier.tab4" label="Banque et comptes" />
<item id="supplychain.supplier.tab5" label="Comptes associés" />
<item id="supplychain.supplier.contacts" label="Contacts fournisseur" />
 
<!-- Societe Common -->
<item id="common.SOCIETE_COMMON.grp1" label="Informations générales" />
<item id="common.SOCIETE_COMMON.grp2" label="Adresse" />
<item id="common.SOCIETE_COMMON.grp3" label="Contact" />
<item id="common.SOCIETE_COMMON.grp4" label="Dates exercice" />
<item id="common.SOCIETE_COMMON.grp5" label="Plan comptable de l'entreprise" />
<item id="common.SOCIETE_COMMON.accounting.plan" label="Choix du plan comptable" />
 
 
</translation>
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mappingCompta_fr.xml
1,5 → 1,6
<?xml version="1.0" encoding="UTF-8" ?>
<ROOT>
 
<element refid="sales.customer.product.qty.price" nameClass="masculine" name="tarif client">
<FIELD name="QUANTITE" label="Quantité" />
<FIELD name="ID_ARTICLE" label="Article" />
11,21 → 12,9
<FIELD name="MONTANT" label="Montant" />
<FIELD name="ID_MOUVEMENT" label="Mouvement" />
</element>
<element refid="humanresources.payroll.suspension.contract" nameClass="masculine"
name="Arrêt chômage, intempérie">
<FIELD name="ID_INFOS_SALARIE_PAYE" label="Salarié" />
<FIELD name="ID_CODE_AMENAGEMENT_PARTIEL" label="Code d'aménagement" />
<FIELD name="ID_CODE_SUSPENSION" label="Code de suspension" />
<FIELD name="DATE_DEBUT_SUSPENSION" label="Début de suspension" />
<FIELD name="DATE_FIN_SUSPENSION" label="Fin de suspension" />
</element>
 
 
 
<element refid="customerrelationship.customer.category" nameClass="feminine" name="catégorie de client">
<FIELD name="name" label="Nom" />
</element>
 
<element refid="sales.customer.product.qty.price" nameClass="masculine" name="tarif client">
<FIELD name="QUANTITE" label="Quantité" />
<FIELD name="ID_ARTICLE" label="Article" />
125,25 → 114,11
<FIELD name="SITUATION_ADMIN" label="Situation administrative" />
<FIELD name="NOTA" label="Nota" />
</element>
 
<element refid="sales.product.ARTICLE_DECLINAISON_TAILLE.name" nameClass="feminine" name="déclinaison taille">
<FIELD name="NOM" label="Taille" />
</element>
 
<element refid="sales.product.ARTICLE_DECLINAISON_COULEUR.name" nameClass="feminine" name="déclinaison couleur">
<FIELD name="NOM" label="Couleur" />
</element>
 
<element refid="sales.product.ref" nameClass="masculine" name="article">
<FIELD name="OPTION" label="Option" />
<FIELD name="HAUTEUR" label="Hauteur" />
<FIELD name="LARGEUR" label="Largeur" />
<FIELD name="LONGUEUR" label="Longueur" />
<FIELD name="POIDS_COLIS_NET" label="Poids colis" />
<FIELD name="OPTION" label="Option" />
<FIELD name="ID_ARTICLE_VIRTUEL_PERE" label="Article référent" />
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="MARGE_WITH_COUT_REVIENT" label="Inclure le coût de revient dans le calcul du prix de vente" />
<FIELD name="ID_COUT_REVIENT" label="%CR" />
<FIELD name="QTE_UNITAIRE" label="Quantité unitaire par défaut" />
207,13 → 182,6
<FIELD name="ID_COMPTE_PCE_VENTE" label="Compte spécifique de vente" />
<FIELD name="ID_COMPTE_PCE_ACHAT" label="Compte spécifique d'achat" />
</element>
<element refid="sales.product.taxe.compta" nameClass="feminine" name="liaison taxe catégorie comptable"
namePlural="liaisons taxe catégorie comptable">
<FIELD name="ID_TAXE" label="TVA" />
<FIELD name="ID_CATEGORIE_COMPTABLE" label="Catégorie comptable" />
<FIELD name="ID_COMPTE_PCE_VENTE" label="Compte spécifique de vente" />
<FIELD name="ID_COMPTE_PCE_ACHAT" label="Compte spécifique d'achat" />
</element>
<element refid="sales.product.customcode" nameClass="masculine" name="code article client"
namePlural="codes articles clients">
<FIELD name="ID_ARTICLE" label="Article" />
243,19 → 211,6
<FIELD name="PRIX_FINAL_TTC" label="Prix client final ttc" />
<FIELD name="PV_HT" label="Prix vente HT" />
<FIELD name="PV_TTC" label="Prix vente TTC" />
<FIELD name="POURCENT_REMISE" label="% Remise" />
<FIELD name="PRIX_METRIQUE_VT_1" label="P.V. UV HT" />
</element>
<element refid="sales.product.promo" nameClass="masculine" name="tarif promotionnel d'article"
namePlural="tarifs promotionnels d'article">
<FIELD name="ID_TARIF_PROMOTION" label="Tarif promotionnel" />
<FIELD name="ID_TAXE" label="Taxe" />
<FIELD name="QTE" label="Qté" />
<FIELD name="ID_DEVISE" label="Devise" />
<FIELD name="PRIX_REVENTE_HT" label="Prix de revente ht" />
<FIELD name="PRIX_FINAL_TTC" label="Prix client final ttc" />
<FIELD name="PV_HT" label="Prix vente HT" />
<FIELD name="PV_TTC" label="Prix vente TTC" />
 
<FIELD name="PRIX_METRIQUE_VT_1" label="P.V. UV HT" />
</element>
355,8 → 310,6
<FIELD name="ID_TAXE_PORT" label="Taxe sur port" />
</element>
<element refid="sales.credit.item" nameClass="masculine" name="élément d'avoir" namePlural="éléments d'avoir">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" />
<FIELD name="ID_ECO_CONTRIBUTION" label="Code Eco-Contrib." />
<FIELD name="ECO_CONTRIBUTION" label="Dont Eco-Contrib." />
487,7 → 440,6
</element>
<element refid="supplychain.receipt.note" nameClass="masculine" name="bon de réception"
namePlural="bons de réception">
<FIELD name="ID_MODELE" label="Modèle" />
<FIELD name="DATE" label="Date" />
<FIELD name="ID_FOURNISSEUR" label="Fournisseur" />
<FIELD name="NUMERO" label="Numéro du bon" titlelabel="Numéro BR" />
507,8 → 459,6
</element>
<element refid="supplychain.receipt.item" nameClass="masculine" name="élément de bon"
namePlural="éléments de bon">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="NB_COLIS" label="Nb Colis" />
<FIELD name="POIDS_COLIS_NET" label="Pds Colis" />
<FIELD name="T_POIDS_COLIS_NET" label="Pds Colis Total" />
589,8 → 539,6
</element>
<element refid="sales.shipment.item" nameClass="masculine" name="élément de bon de livraison"
namePlural="éléments de bon de livraison">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" />
<FIELD name="ID_ECO_CONTRIBUTION" label="Code Eco-Contrib." />
<FIELD name="ECO_CONTRIBUTION" label="Dont Eco-Contrib." />
732,7 → 680,7
</element>
<!-- Mapping pour client partagé KD/Preventec -->
<element refid="controle.customer" nameClass="masculine" name="client">
<FIELD name="ALERTE" label="Alerte" />
 
<FIELD name="ID_SEPA_MANDATE_DEFAULT" label="Mandat par défaut" />
<FIELD name="ID_FRAIS_DOCUMENT" label="Frais de création de documents" />
<FIELD name="CODE_FOURNISSEUR" label="Code interne fournisseur" />
815,15 → 763,6
<FIELD name="BLOQUE_LIVRAISON" label="Bloquer les livraisons" />
<FIELD name="OBSOLETE" label="Obsolète" />
 
<FIELD name="USE_CLIENT_FORMAT" label="Utiliser la numérotation du client (GARI)" />
<FIELD name="NOMENCLATURE_RAPPORT" label="Nomenclature des rapports" />
<FIELD name="SEND_FAX" label="Envoyer une copie des rapports par fax " />
<FIELD name="SEND_POST_MAIL" label="Envoyer une copie des rapports par courrier " />
<FIELD name="MAIL_SUPPL_OBL_GARI" label="Email dest. suppl. GARI requis" />
 
 
 
 
</element>
<!-- Mapping pour client standard OpenConcerto -->
<element refid="customerrelationship.customer" nameClass="masculine" name="client">
909,7 → 848,7
<FIELD name="GROUPE" label="Groupe" />
<FIELD name="BLOQUE_LIVRAISON" label="Bloquer les livraisons" />
<FIELD name="OBSOLETE" label="Obsolète" />
<FIELD name="ALERTE" label="Message d'alerte" />
 
</element>
<element refid="customerrelationship.customer.department" nameClass="masculine" name="service client"
namePlural="services client">
1090,20 → 1029,9
<FIELD name="NB_AYANT_DROIT_AUTRE" label="Nombre d'ayants-droit autres (ascendants, collatéraux...)" />
<FIELD name="NB_ENFANT_AYANT_DROIT" label="Nombre d'enfants ayants-droit" />
</element>
<element refid="humanresources.payroll.suspention.contract" nameClass="masculine"
name="arrêt chômage ou intempéries" namePlural="arrêts chômages ou intempéries">
<FIELD name="ID_INFOS_SALARIE_PAYE" label="Contrat salarié" />
<FIELD name="ID_CODE_AMENAGEMENT_PARTIEL" label="Aménagement temps partiel (S21.G00.40.078)" />
<FIELD name="ID_CODE_SUSPENSION" label="Motif de suspension (S21.G00.65.001)" />
<FIELD name="DATE_FIN_SUSPENSION" label="Fin de supension (S21.G00.65.003)" />
<FIELD name="DATE_DEBUT_SUSPENSION" label="Début de supension (S21.G00.65.002)" />
</element>
 
<element refid="humanresources.payroll.contract.employe" nameClass="masculine" name="contrat salarié"
namePlural="contrats salariés">
<FIELD name="ID_DIPLOME_PREPARE" label="Diplôme préparé (S21.G00.30.025)" />
<FIELD name="ID_CODE_CAISSE_CONGES_PAYES" label="Caisse de congés payés (S21.G00.40.022)" />
<FIELD name="TAUX_FRAIS_PROFESSIONNELS" label="Taux frais professionnels (S21.G00.40.023)" />
<FIELD name="ID_CODE_AMENAGEMENT_PARTIEL" label="Aménagement temps partiel (S21.G00.40.078)" />
<FIELD name="ID_CODE_SUSPENSION" label="Motif de suspension (S21.G00.65.001)" />
<FIELD name="DATE_FIN_SUSPENSION" label="Fin de supension (S21.G00.65.003)" />
1175,8 → 1103,6
</element>
<element refid="supplychain.order.item" nameClass="masculine" name="élément de commande"
namePlural="éléments de commande">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="NB_COLIS" label="Nb Colis" />
<FIELD name="POIDS_COLIS_NET" label="Pds Colis" />
<FIELD name="T_POIDS_COLIS_NET" label="Pds Colis Total" />
1227,10 → 1153,6
<FIELD name="ID_MODE_VENTE_ARTICLE" label="Mode de vente" />
</element>
<element refid="sales.order" nameClass="feminine" name="commande client" namePlural="commandes clients">
<FIELD name="FACTURATION_INTERNE" label="Facturation interne" />
<FIELD name="T_ACOMPTE" label="Acompte" />
<FIELD name="ID_COMMANDE_CLIENT_PRECEDENT" label="Commande précedente" />
 
<FIELD name="ID_TAXE_FRAIS_DOCUMENT" label="TVA sur frais documents" />
<FIELD name="FRAIS_DOCUMENT_HT" label="Frais de document HT" />
<FIELD name="DATE_LIVRAISON_PREV" label="Livraison prévue le" />
1267,8 → 1189,6
<FIELD name="DATE_LIVRAISON_REELLE" label="Date livraison réelle" />
</element>
<element refid="sales.order.item" nameClass="masculine" name="article commandé" namePlural="articles commandés">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" />
<FIELD name="ID_ECO_CONTRIBUTION" label="Code Eco-Contrib." />
<FIELD name="ECO_CONTRIBUTION" label="Dont Eco-Contrib." />
1447,8 → 1367,6
</element>
<element refid="supplychain.order.demande.item" nameClass="masculine" name="élement de demande de prix"
namePlural="élements de demandes de prix">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" />
<FIELD name="ID_ECO_CONTRIBUTION" label="Code Eco-Contrib." />
<FIELD name="ECO_CONTRIBUTION" label="Dont Eco-Contrib." />
1522,9 → 1440,6
<FIELD name="REGION_ADMIN" label="Région administrative" />
</element>
<element refid="sales.quote" nameClass="masculine" name="devis">
 
<FIELD name="TRANSFORMATION" label="Taux de transformation estimé" />
<FIELD name="DATE_LIVRAISON" label="Livraison prévue le" />
<FIELD name="ID_TAXE_FRAIS_DOCUMENT" label="TVA sur frais documents" />
<FIELD name="FRAIS_DOCUMENT_HT" label="Frais de document HT" />
<FIELD name="ID_TAXE_PORT" label="TVA sur Port" />
1593,8 → 1508,6
<FIELD name="T_ECO_CONTRIBUTION" label="Dont Eco-Contrib." />
</element>
<element refid="sales.quote.item" nameClass="masculine" name="élément de devis" namePlural="éléments de devis">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" />
<FIELD name="ID_ECO_CONTRIBUTION" label="Code Eco-Contrib." />
<FIELD name="ECO_CONTRIBUTION" label="Dont Eco-Contrib." />
1874,8 → 1787,6
<FIELD name="POIDS_COLIS_NET" label="Pds Colis" />
<FIELD name="T_POIDS_COLIS_NET" label="Pds Colis Total" />
<FIELD name="ID_COMPTE_PCE" label="Compte charge spécifique" />
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" />
<FIELD name="ID_ECO_CONTRIBUTION" label="Code Eco-Contrib." />
<FIELD name="ECO_CONTRIBUTION" label="Dont Eco-Contrib." />
1938,7 → 1849,6
<FIELD name="NET_IMP" label="Salaire net imposable" />
<FIELD name="NET_A_PAYER" label="Salaire net à payer" />
<FIELD name="CSG" label="Base CSG" />
<FIELD name="PERTE_TPT" label="Perte TPT" />
<FIELD name="ID_CUMULS_PAYE" label="Cumuls" />
<FIELD name="ACOMPTE" label="Acompte" />
<FIELD name="ID_MOIS" label="Mois" />
2058,7 → 1968,6
<FIELD name="TEL" label="Téléphone" />
<FIELD name="FAX" label="Fax" />
<FIELD name="ID_MODE_REGLEMENT" label="Mode de règlement par défaut" />
<FIELD name="CONDITIONS_PORT" label="Conditions frais de port" />
</element>
<element refid="finance.accounting.FRAIS_DOCUMENT">
<FIELD name="CODE" label="Code" />
2067,7 → 1976,11
<FIELD name="MONTANT_HT" label="Montant HT" />
<FIELD name="MONTANT_TTC" label="Montant TTC" />
</element>
 
<element refid="humanresources.payroll.conventions.code" nameClass="masculine" name="code de convention"
namePlural="codes de conventions">
<FIELD name="CODE" label="Code" />
<FIELD name="NOM" label="Libellé" />
</element>
<element refid="humanresources.payroll.info" nameClass="feminine" name="fiche d'informations salarié-paye"
namePlural="fiches d'informations salariés-payes">
<FIELD name="ID_IDCC" label="Convention collective (*)" titlelabel="Convention collective" />
2169,8 → 2082,6
namePlural="numérotations automatiques">
<FIELD name="AFFAIRE_FORMAT" label="Format" />
<FIELD name="AFFAIRE_START" label="Prochain numéro" />
<FIELD name="ARTICLE_FORMAT" label="Format" />
<FIELD name="ARTICLE_START" label="Prochain numéro" />
<FIELD name="AVOIR_FORMAT" label="Format" />
<FIELD name="AVOIR_START" label="Prochain numéro" />
<FIELD name="AVOIR_F_FORMAT" label="Format" />
2533,7 → 2444,6
<FIELD name="TYPE_INTERVENTION" label="Type d'intervention" />
<FIELD name="ID_REFERENCE_CLIENT" label="Référence client" />
<FIELD name="ID_VERIFICATEUR" label="Vérificateur" />
<FIELD name="ID_VERIFICATEUR_SOUS_TRAITANCE" label="Sous-traitée par" />
<FIELD name="ID_MODELE" label="Modèle" />
<FIELD name="CONTROLE_TECHNIQUE" label="Facture CTC" />
<FIELD name="COMPTE_SERVICE_AUTO" label="Gestion automatique du compte de service" />
2542,8 → 2452,6
<FIELD name="ID_SDD_MESSAGE" label="Ordre de prélèvement SEPA" titlelabel="Prélèv. SEPA" />
</element>
<element refid="sales.invoice.item" nameClass="masculine" name="article facturé" namePlural="articles facturés">
<FIELD name="ID_ARTICLE_DECLINAISON_TAILLE" label="Taille" />
<FIELD name="ID_ARTICLE_DECLINAISON_COULEUR" label="Couleur" />
<FIELD name="ID_DEPOT_STOCK" label="Dépôt Stock" />
<FIELD name="ID_COMPTE_PCE" label="Compte vente spécifique" />
<FIELD name="ID_ECO_CONTRIBUTION" label="Code Eco-Contrib." />
2689,14 → 2597,7
<FIELD name="ID_TAXE" label="TVA" />
<FIELD name="ID_DEVISE" label="Devise" />
</element>
<element refid="sales.price.promo.list" nameClass="masculine" name="tarif promotionnel">
<FIELD name="NOM" label="Tarif" />
<FIELD name="ID_TAXE" label="TVA" />
<FIELD name="ID_DEVISE" label="Devise" />
<FIELD name="START" label="Du" />
<FIELD name="END" label="Au" />
</element>
<element refid="sales.product.qty.price" nameClass="masculine" name="tarif par quantité">
<element refid="sales.product.qty.price">
<FIELD name="QUANTITE" label="Qté (A partir de)" />
<FIELD name="POURCENT_REMISE" label="% de remise" />
<FIELD name="PRIX_METRIQUE_VT_1" label="Prix de vente HT remisé" />
/trunk/OpenConcerto/src/org/openconcerto/erp/config/Gestion.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
100,7 → 100,7
 
public class Gestion {
 
static final String MODULES_DIR_NAME = "Modules";
public static final File MODULES_DIR = new File("Modules");
 
/**
* When this system property is set to <code>true</code>, Gestion will hide most of its normal
316,7 → 316,6
ex2.printStackTrace();
}
System.out.println("Application working directory folder : " + conf.getWD().getAbsolutePath());
System.out.println("Modules folders : " + conf.getModuleManager().getFolders().toString());
if (inWebStart()) {
// needed since our classes aren't loaded by the same loader as the library classes
Helper.setURLStreamHandlerFactory();
340,9 → 339,6
SQLRequestLog.setEnabled(true);
}
 
// columns order/visibility per company
IListFrame.setConfDirFunction((elem) -> conf.getConfDir(elem.getTable().getDBRoot()));
 
if (Boolean.valueOf(conf.getProperty("minimal", "false"))) {
System.setProperty(MINIMAL_PROP, Boolean.TRUE.toString());
}
588,7 → 584,6
 
// needed so that we can uninstall modules
System.setProperty(SQLBase.ALLOW_OBJECT_REMOVAL, "true");
NewsChecker.check(pTOS, conf.getConfDir(), conf.getServer().getSQLSystem().equals(SQLSystem.H2));
}
 
private static void saveProperties(File fTOS, Properties pTOS) {
797,7 → 792,6
return realIp;
}
 
// TODO : n'est plus utilisé
public static PostgreSQLFrame pgFrameStart = null;
 
private static JDialog frameExit = null;
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mapping_fr.xml
7,13 → 7,9
<FIELD name="ID_CLIENT" label="Client" />
<FIELD name="POURCENT_REMISE" label="% remise" />
</element>
<element refid="humanresources.payroll.conventions.code" nameClass="masculine" name="code de convention"
namePlural="codes de conventions">
<FIELD name="CODE" label="Code" />
<FIELD name="NOM" label="Libellé" />
</element>
 
 
 
<element refid="common.address" nameClass="feminine" name="adresse">
<FIELD name="RAISON_SOCIALE" label="Raison sociale" />
<FIELD name="RUE" label="Rue" />
266,13 → 262,8
<FIELD name="CAPITAL" label="Capital" />
<FIELD name="NUMERO_URSSAF" label="Identifiant personnel URSSAF" />
<FIELD name="ID_DEVISE" label="Devise" />
<FIELD name="ID_IDCC" label="Convention collective applicable" />
<FIELD name="ORG_PROTECTION_SOCIAL_ID" label="Siret URSSAF" />
<FIELD name="SEPA_CREDITOR_ID" label="Identifiant Créancier SEPA" />
<FIELD name="ID_MOTIF_NON_ASSUJETIS_TA" label="Motif non assuj. TA (S21.G00.44.004)" />
<FIELD name="ASSUJETTISSEMENT_TA" label="Assujettisement TA (S21.G00.44.001)" />
<FIELD name="ASSUJETTISSEMENT_CFP" label="Assujettisement CFP (S21.G00.44.001)" />
<FIELD name="ASSUJETTISSEMENT_CFP_CDD" label="Assujettisement CFP CDD (S21.G00.44.001)" />
</element>
<element refid="document.template-type" nameClass="masculine" name="type de modèle"
namePlural="types de modèles">
/trunk/OpenConcerto/src/org/openconcerto/erp/config/update/Updater_1_5.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
29,7 → 29,6
import org.openconcerto.erp.core.supplychain.stock.element.DepotStockSQLElement;
import org.openconcerto.erp.core.supplychain.stock.element.StockItem;
import org.openconcerto.sql.changer.convert.AddMDFields;
import org.openconcerto.sql.changer.convert.SetFKDefault;
import org.openconcerto.sql.model.AliasedTable;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLField;
42,7 → 41,6
import org.openconcerto.sql.model.SQLSyntax;
import org.openconcerto.sql.model.SQLSystem;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLUpdate;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.request.UpdateBuilder;
142,14 → 140,6
tClient.fetchFields();
}
 
if (!tClient.contains("ALERTE")) {
final AlterTable alterClient = new AlterTable(tClient);
alterClient.addVarCharColumn("ALERTE", 4096);
tClient.getBase().getDataSource().execute(alterClient.asString());
tClient.getSchema().updateVersion();
tClient.fetchFields();
}
 
final SQLTable tCompteClient = root.getTable("COMPTE_CLIENT_TRANSACTION");
if (!tCompteClient.contains("ID_MOUVEMENT")) {
final AlterTable alterClient = new AlterTable(tCompteClient);
827,7 → 817,7
 
String field = sqlField.getName();
if (!field.equalsIgnoreCase("ID_USER_COMMON_CREATE") && !field.equalsIgnoreCase("ID_USER_COMMON_MODIFY") && !field.equalsIgnoreCase("MODIFICATION_DATE")
&& !field.equalsIgnoreCase("CREATION_DATE") && !field.equalsIgnoreCase("HEURE_TRAV") && !tableVarSal.contains(field + "_DEFAULT_VAL")) {
&& !field.equalsIgnoreCase("CREATION_DATE") && !field.equalsIgnoreCase("HEURE_TRAV")) {
alterB.addColumn(field + "_DEFAULT_VAL", "real DEFAULT 0");
}
}
869,14 → 859,6
root.getSchema().updateVersion();
}
 
if (!tableFpaye.contains("PERTE_TPT")) {
final AlterTable alterB = new AlterTable(tableFpaye);
alterB.addDecimalColumn("PERTE_TPT", 16, 2, BigDecimal.ZERO, false);
root.getBase().getDataSource().execute(alterB.asString());
root.refetchTable("FICHE_PAYE");
root.getSchema().updateVersion();
}
 
SQLTable tableCpaye = root.findTable("CUMULS_PAYE");
if (!tableCpaye.contains("TAXE_CM_SAL_C")) {
final AlterTable alterB = new AlterTable(tableCpaye);
952,14 → 934,6
tableArticle.getSchema().updateVersion();
tableArticle.fetchFields();
}
if (!tableArticle.contains("OPTION")) {
final AlterTable alterArticle = new AlterTable(tableArticle);
alterArticle.addBooleanColumn("OPTION", Boolean.FALSE, false);
tableArticle.getBase().getDataSource().execute(alterArticle.asString());
tableArticle.getSchema().updateVersion();
tableArticle.fetchFields();
}
 
SQLTable tableFournisseur = root.getTable("FOURNISSEUR");
if (!tableFournisseur.contains("NUMERO_TVA")) {
final AlterTable alter = new AlterTable(tableFournisseur);
969,13 → 943,6
tableFournisseur.getSchema().updateVersion();
tableFournisseur.fetchFields();
}
if (!tableFournisseur.contains("CONDITIONS_PORT")) {
final AlterTable alter = new AlterTable(tableFournisseur);
alter.addVarCharColumn("CONDITIONS_PORT", 128);
tableFournisseur.getBase().getDataSource().execute(alter.asString());
tableFournisseur.getSchema().updateVersion();
tableFournisseur.fetchFields();
}
 
// POS
final SQLTable caisseT = root.getTable("CAISSE");
1091,31 → 1058,6
root.getSchema().updateVersion();
}
 
SQLTable tableCommandeAcompte = root.getTable("COMMANDE_CLIENT");
if (!tableCommandeAcompte.contains("T_ACOMPTE")) {
final AlterTable alterB = new AlterTable(tableCommandeAcompte);
alterB.addLongColumn("T_ACOMPTE", 0L, false);
root.getBase().getDataSource().execute(alterB.asString());
root.refetchTable("COMMANDE_CLIENT");
root.getSchema().updateVersion();
 
SQLTable tableEncaisse = root.getTable("ENCAISSER_MONTANT");
final AlterTable alterC = new AlterTable(tableEncaisse);
alterC.addForeignColumn("ID_COMMANDE_CLIENT", tableDevisAcompte);
root.getBase().getDataSource().execute(alterC.asString());
root.refetchTable("ENCAISSER_MONTANT");
root.getSchema().updateVersion();
}
 
if (!tableDevisAcompte.contains("DATE_LIVRAISON")) {
final AlterTable alterB = new AlterTable(tableDevisAcompte);
alterB.addColumn("DATE_LIVRAISON", "date");
alterB.addVarCharColumn("TRANSFORMATION", 200);
root.getBase().getDataSource().execute(alterB.asString());
root.refetchTable("DEVIS");
root.getSchema().updateVersion();
}
 
// Paye Simplifiée
if (!tableFpaye.contains("ALLEGEMENT_COTISATION")) {
final AlterTable alterB = new AlterTable(tableFpaye);
1712,7 → 1654,6
}
 
// Gestion multidepot
final SQLTable userT = root.findTable("USER_COMMON");
{
// Ajout table depot
if (!root.contains("DEPOT_STOCK")) {
1720,7 → 1661,7
createTable.addVarCharColumn("CODE", 25);
createTable.addVarCharColumn("NOM", 256);
createTable.addVarCharColumn("UI_LOCK", 256);
createTable.addForeignColumn("ID_USER_UI_LOCK", userT);
createTable.addForeignColumn("ID_USER_UI_LOCK", root.findTable("USER_COMMON"));
// sqlRowValues.put("UI_LOCK", "ro");
// sqlRowValues.put("ID_USER_UI_LOCK", 2);
 
1926,7 → 1867,7
 
String field = sqlField.getName();
if (!field.equalsIgnoreCase("ID_USER_COMMON_CREATE") && !field.equalsIgnoreCase("ID_USER_COMMON_MODIFY") && !field.equalsIgnoreCase("MODIFICATION_DATE")
&& !field.equalsIgnoreCase("CREATION_DATE") && !field.endsWith("_DEFAULT_VAL") && !tableVarSal.contains(field + "_CUMUL_VAL")) {
&& !field.equalsIgnoreCase("CREATION_DATE") && !field.endsWith("_DEFAULT_VAL")) {
alterB.addColumn(field + "_CUMUL_VAL", "real DEFAULT 0");
}
}
1944,14 → 1885,6
root.getSchema().updateVersion();
}
 
if (!tableBL.contains("VERROU_FACTURATION")) {
final AlterTable alterB = new AlterTable(tableBL);
alterB.addBooleanColumn("VERROU_FACTURATION", Boolean.FALSE, false);
root.getBase().getDataSource().execute(alterB.asString());
root.refetchTable("BON_DE_LIVRAISON");
root.getSchema().updateVersion();
}
 
// fix stock
{
SQLTable tableStock = root.getTable("STOCK");
2008,17 → 1941,15
}
}
 
// Remove useless since 1.7.1
// SQLSelect selArt = new SQLSelect();
// selArt.addSelectStar(tableArt);
// Where w = new Where(tableArt.getField("ID_STOCK"), "=", 1);
// selArt.setWhere(w);
// List<SQLRow> badStock = SQLRowListRSH.execute(selArt);
// for (SQLRow sqlRow : badStock) {
// initStock(sqlRow);
// }
 
SQLSelect selArt = new SQLSelect();
selArt.addSelectStar(tableArt);
Where w = new Where(tableArt.getField("ID_STOCK"), "=", 1);
selArt.setWhere(w);
List<SQLRow> badStock = SQLRowListRSH.execute(selArt);
for (SQLRow sqlRow : badStock) {
initStock(sqlRow);
}
}
 
// Tarification client par quantite
if (root.getTable("TARIF_ARTICLE_CLIENT") == null) {
2165,7 → 2096,7
final SQLTable tableSalarie = root.getTable("SALARIE");
if (!tableSalarie.contains("ID_USER_COMMON")) {
final AlterTable alter = new AlterTable(tableSalarie);
alter.addForeignColumn("ID_USER_COMMON", userT);
alter.addForeignColumn("ID_USER_COMMON", root.findTable("USER_COMMON"));
exec(alter);
root.refetchTable(tableSalarie.getName());
root.getSchema().updateVersion();
2489,258 → 2420,8
tableVF.fetchFields();
}
 
SQLTable tableNumAuto = root.getTable("NUMEROTATION_AUTO");
if (!tableNumAuto.contains("ARTICLE_FORMAT")) {
 
final AlterTable alterNumero = new AlterTable(tableNumAuto);
alterNumero.addVarCharColumn("ARTICLE_FORMAT", 128);
alterNumero.addIntegerColumn("ARTICLE_START", 1);
root.getBase().getDataSource().execute(alterNumero.asString());
root.refetchTable("NUMEROTATION_AUTO");
root.getSchema().updateVersion();
}
 
if (!tableArticle.contains("VIRTUEL")) {
 
final SQLCreateTable createTableDeclinaisonCouleur = new SQLCreateTable(root, "ARTICLE_DECLINAISON_COULEUR");
createTableDeclinaisonCouleur.addVarCharColumn("NOM", 256);
root.getBase().getDataSource().execute(createTableDeclinaisonCouleur.asString());
InstallationPanel.insertUndef(createTableDeclinaisonCouleur);
root.refetchTable("ARTICLE_DECLINAISON_COULEUR");
root.getSchema().updateVersion();
 
final SQLCreateTable createTableDeclinaisonTaille = new SQLCreateTable(root, "ARTICLE_DECLINAISON_TAILLE");
createTableDeclinaisonTaille.addVarCharColumn("NOM", 256);
root.getBase().getDataSource().execute(createTableDeclinaisonTaille.asString());
InstallationPanel.insertUndef(createTableDeclinaisonTaille);
root.refetchTable("ARTICLE_DECLINAISON_TAILLE");
root.getSchema().updateVersion();
 
final AlterTable alter = new AlterTable(tableArticle);
alter.addBooleanColumn("VIRTUEL", false, false);
alter.addForeignColumn("ID_ARTICLE_VIRTUEL_PERE", tableArticle);
alter.addForeignColumn("ID_ARTICLE_DECLINAISON_TAILLE", root.getTable("ARTICLE_DECLINAISON_TAILLE"));
alter.addForeignColumn("ID_ARTICLE_DECLINAISON_COULEUR", root.getTable("ARTICLE_DECLINAISON_COULEUR"));
tableArticle.getBase().getDataSource().execute(alter.asString());
tableArticle.getSchema().updateVersion();
tableArticle.fetchFields();
}
 
for (String string : achatItems) {
boolean alter = false;
SQLTable tableItems = root.getTable(string);
final AlterTable t = new AlterTable(tableItems);
 
if (!tableItems.getFieldsName().contains("ID_ARTICLE_DECLINAISON_TAILLE")) {
t.addForeignColumn("ID_ARTICLE_DECLINAISON_TAILLE", root.getTable("ARTICLE_DECLINAISON_TAILLE"));
alter = true;
}
if (!tableItems.getFieldsName().contains("ID_ARTICLE_DECLINAISON_COULEUR")) {
t.addForeignColumn("ID_ARTICLE_DECLINAISON_COULEUR", root.getTable("ARTICLE_DECLINAISON_COULEUR"));
alter = true;
}
 
if (alter) {
tableItems.getBase().getDataSource().execute(t.asString());
tableItems.getSchema().updateVersion();
tableItems.fetchFields();
}
}
 
for (String tableName : tableElementWithTable) {
final SQLTable tableToDecl = root.getTable(tableName);
boolean alter = false;
 
final AlterTable alterDecl = new AlterTable(tableToDecl);
if (!tableToDecl.getFieldsName().contains("ID_ARTICLE_DECLINAISON_TAILLE")) {
alterDecl.addForeignColumn("ID_ARTICLE_DECLINAISON_TAILLE", root.getTable("ARTICLE_DECLINAISON_TAILLE"));
alter = true;
}
if (!tableToDecl.getFieldsName().contains("ID_ARTICLE_DECLINAISON_COULEUR")) {
alterDecl.addForeignColumn("ID_ARTICLE_DECLINAISON_COULEUR", root.getTable("ARTICLE_DECLINAISON_COULEUR"));
alter = true;
}
 
if (alter) {
tableToDecl.getBase().getDataSource().execute(alterDecl.asString());
tableToDecl.getSchema().updateVersion();
tableToDecl.fetchFields();
}
}
 
// Création de la table Tarif promotion
if (!root.contains("TARIF_PROMOTION")) {
 
SQLCreateTable createTarif = new SQLCreateTable(root, "TARIF_PROMOTION");
createTarif.addVarCharColumn("NOM", 256);
createTarif.addColumn("START", "date");
createTarif.addColumn("END", "date");
root.getBase().getDataSource().execute(createTarif.asString());
InstallationPanel.insertUndef(createTarif);
tableDevis.getSchema().updateVersion();
root.refetchTable(createTarif.getName());
}
 
// Création de la table article Tarif promotion
if (!root.contains("ARTICLE_TARIF_PROMOTION")) {
 
SQLCreateTable createTarif = new SQLCreateTable(root, "ARTICLE_TARIF_PROMOTION");
createTarif.addForeignColumn("ID_DEVISE", root.findTable("DEVISE", true));
createTarif.addForeignColumn("ID_TAXE", root.findTable("TAXE", true));
createTarif.addForeignColumn("ID_TARIF_PROMOTION", root.findTable("TARIF_PROMOTION", true));
createTarif.addForeignColumn("ID_ARTICLE", root.findTable("ARTICLE", true));
createTarif.addIntegerColumn("QTE", 1);
createTarif.addDecimalColumn("PV_HT", 16, 6, BigDecimal.ZERO, false);
createTarif.addDecimalColumn("PV_TTC", 16, 6, BigDecimal.ZERO, false);
createTarif.addDecimalColumn("PRIX_METRIQUE_VT_1", 16, 6, BigDecimal.ZERO, false);
createTarif.addDecimalColumn("PRIX_METRIQUE_VT_2", 16, 6, BigDecimal.ZERO, false);
createTarif.addDecimalColumn("PRIX_METRIQUE_VT_3", 16, 6, BigDecimal.ZERO, false);
root.getBase().getDataSource().execute(createTarif.asString());
InstallationPanel.insertUndef(createTarif);
tableDevis.getSchema().updateVersion();
root.refetchTable(createTarif.getName());
}
 
if (!root.contains("TAXE_CATEGORIE_COMPTABLE")) {
 
final SQLCreateTable createTableTaxeCat = new SQLCreateTable(root, "TAXE_CATEGORIE_COMPTABLE");
createTableTaxeCat.addForeignColumn("ID_CATEGORIE_COMPTABLE", root.getTable("CATEGORIE_COMPTABLE"));
createTableTaxeCat.addForeignColumn("ID_TAXE", root.getTable("TAXE"));
createTableTaxeCat.addForeignColumn("ID_COMPTE_PCE_VENTE", root.getTable("COMPTE_PCE"));
createTableTaxeCat.addForeignColumn("ID_COMPTE_PCE_ACHAT", root.getTable("COMPTE_PCE"));
 
try {
root.getBase().getDataSource().execute(createTableTaxeCat.asString());
InstallationPanel.insertUndef(createTableTaxeCat);
root.refetchTable("TAXE_CATEGORIE_COMPTABLE");
root.getSchema().updateVersion();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table " + "TAXE_CATEGORIE_COMPTABLE", ex);
}
 
}
 
if (!root.contains("LOT_RECEPTION")) {
SQLCreateTable createLotReception = new SQLCreateTable(root, "LOT_RECEPTION");
createLotReception.addDateAndTimeColumn("DATE_RECEPTION");
createLotReception.addVarCharColumn("FOURNISSEUR", 256);
createLotReception.addVarCharColumn("ARTICLE", 256);
createLotReception.addForeignColumn("ID_ARTICLE", root.findTable("ARTICLE", true));
createLotReception.addForeignColumn("ID_DEPOT_STOCK", root.findTable("DEPOT_STOCK", true));
createLotReception.addDecimalColumn("QUANTITE", 16, 6, BigDecimal.ONE, false);
createLotReception.addVarCharColumn("NUMERO_LOT", 256);
createLotReception.addVarCharColumn("NUMERO_SERIE", 256);
createLotReception.addDateAndTimeColumn("DLC");
createLotReception.addDateAndTimeColumn("DLUO");
createLotReception.addForeignColumn("ID_BON_RECEPTION_ELEMENT", root.findTable("BON_RECEPTION_ELEMENT", true));
root.getBase().getDataSource().execute(createLotReception.asString());
InstallationPanel.insertUndef(createLotReception);
 
SQLCreateTable createLotLivraison = new SQLCreateTable(root, "LOT_LIVRAISON");
createLotLivraison.addDateAndTimeColumn("DATE_LIVRAISON");
createLotLivraison.addVarCharColumn("CLIENT", 256);
createLotLivraison.addVarCharColumn("ARTICLE", 256);
createLotLivraison.addForeignColumn("ID_ARTICLE", root.findTable("ARTICLE", true));
createLotLivraison.addForeignColumn("ID_DEPOT_STOCK", root.findTable("DEPOT_STOCK", true));
createLotLivraison.addDecimalColumn("QUANTITE", 16, 6, BigDecimal.ONE, false);
createLotLivraison.addVarCharColumn("NUMERO_LOT", 256);
createLotLivraison.addVarCharColumn("NUMERO_SERIE", 256);
createLotLivraison.addDateAndTimeColumn("DLC");
createLotLivraison.addDateAndTimeColumn("DLUO");
createLotLivraison.addForeignColumn("ID_BON_DE_LIVRAISON_ELEMENT", root.findTable("BON_DE_LIVRAISON_ELEMENT", true));
root.getBase().getDataSource().execute(createLotLivraison.asString());
InstallationPanel.insertUndef(createLotLivraison);
}
 
if (!root.contains("LOT")) {
SQLCreateTable createLot = new SQLCreateTable(root, "LOT");
createLot.addForeignColumn("ID_STOCK", root.findTable("STOCK", true));
createLot.addDecimalColumn("QUANTITE", 16, 6, BigDecimal.ONE, false);
createLot.addVarCharColumn("NUMERO_LOT", 256);
createLot.addVarCharColumn("NUMERO_SERIE", 256);
createLot.addDateAndTimeColumn("DLC");
createLot.addDateAndTimeColumn("DLUO");
root.getBase().getDataSource().execute(createLot.asString());
InstallationPanel.insertUndef(createLot);
 
SQLCreateTable createTransfertStock = new SQLCreateTable(root, "TRANSFERT_STOCK");
createTransfertStock.addDateAndTimeColumn("DATE");
createTransfertStock.addForeignColumn("ID_ARTICLE", root.findTable("ARTICLE", true));
createTransfertStock.addForeignColumn("ID_DEPOT_STOCK_SOURCE", root.findTable("DEPOT_STOCK", true));
createTransfertStock.addForeignColumn("ID_DEPOT_STOCK_DEST", root.findTable("DEPOT_STOCK", true));
createTransfertStock.addDecimalColumn("QUANTITE", 16, 6, BigDecimal.ONE, false);
createTransfertStock.addVarCharColumn("NUMEROS_SERIE", 50000);
createTransfertStock.addVarCharColumn("NUMEROS_LOT", 50000);
createTransfertStock.addVarCharColumn("CONTEXTE", 256);
 
root.getBase().getDataSource().execute(createTransfertStock.asString());
InstallationPanel.insertUndef(createTransfertStock);
 
final AlterTable alterArticle = new AlterTable(tableArticle);
alterArticle.addBooleanColumn("NUMERO_LOT_REQUIS", false, false);
alterArticle.addBooleanColumn("NUMERO_SERIE_REQUIS", false, false);
alterArticle.addBooleanColumn("DLC_REQUIS", false, false);
alterArticle.addBooleanColumn("DLUO_REQUIS", false, false);
tableArticle.getBase().getDataSource().execute(alterArticle.asString());
tableArticle.getSchema().updateVersion();
tableArticle.fetchFields();
 
final AlterTable alterBonReceptionElement = new AlterTable(root.getTable("BON_RECEPTION_ELEMENT"));
alterBonReceptionElement.addForeignColumn("ID_LOT", createLot);
tableArticle.getBase().getDataSource().execute(alterBonReceptionElement.asString());
 
final AlterTable alterBonLivraisonElement = new AlterTable(root.getTable("BON_DE_LIVRAISON"));
alterBonLivraisonElement.addForeignColumn("ID_LOT", createLot);
tableArticle.getBase().getDataSource().execute(alterBonLivraisonElement.asString());
tableArticle.getSchema().updateVersion();
root.refetch();
}
 
SQLTable tableBR = root.getTable("BON_RECEPTION");
SQLTable tableModele = root.getTable("MODELE");
if (!tableBR.contains("ID_MODELE")) {
AlterTable a = new AlterTable(tableBR);
a.addForeignColumn("ID_MODELE", tableModele);
root.getBase().getDataSource().execute(a.asString());
tableBR.getSchema().updateVersion();
root.refetchTable(tableBR.getName());
}
 
SQLTable typeModele = tableModele.getForeignTable("ID_TYPE_MODELE");
SQLSelect sel = new SQLSelect();
sel.addSelect(typeModele.getKey());
sel.setWhere(new Where(typeModele.getField("TABLE"), "=", "BON_RECEPTION"));
List<SQLRow> l = SQLRowListRSH.execute(sel);
if (l.isEmpty()) {
SQLRowValues rowVals = new SQLRowValues(typeModele);
rowVals.put("TABLE", "BON_RECEPTION");
rowVals.put("NOM", "Bon de réception");
rowVals.put("DEFAULT_MODELE", "BonReception");
rowVals.commit();
}
// Fix undefined
new SetFKDefault(root.getDBSystemRoot()).changeAll(root);
List<SQLUpdate> ups = new ArrayList<>();
if (userT.getUndefinedIDNumber() != null) {
for (SQLField userF : root.getDBSystemRoot().getGraph().getReferentKeys(userT)) {
if (userF.getTable().getDBRoot() == root) {
SQLUpdate up = new SQLUpdate(Where.isNull(userF));
up.add(userF, userT.getUndefinedIDNumber());
ups.add(up);
}
}
}
if (!ups.isEmpty()) {
SQLUpdate.executeMultipleWithBatch(root.getDBSystemRoot(), ups);
System.err.println("Updater_1_5.update() fixed " + ups.size() + " error(s) on FK to USER_COMMON");
} else {
System.err.println("Updater_1_5.update() no error on FK to USER_COMMON");
}
}
 
public static void initStock(SQLRow rowArticle, int idDepot) {
 
SQLSelect selStock = new SQLSelect();
/trunk/OpenConcerto/src/org/openconcerto/erp/config/MinimalMenuConfiguration.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
42,7 → 42,9
 
final Group fileMenu = new Group(MainFrame.FILE_MENU);
fileMenu.addItem("backup");
fileMenu.addItem(MainFrame.QUIT_MENU_ITEM);
if (!Gestion.MAC_OS_X) {
fileMenu.addItem("quit");
}
res.add(fileMenu);
 
if (rights.haveRight(LockAdminUserRight.LOCK_MENU_ADMIN)) {
52,7 → 54,7
}
 
final Group helpMenu = new Group(MainFrame.HELP_MENU);
helpMenu.addItem(MainFrame.ABOUT_MENU_ITEM);
helpMenu.addItem("information");
 
res.add(helpMenu);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/InProgressFrame.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
15,12 → 15,7
 
import org.openconcerto.ui.ReloadPanel;
 
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.SplashScreen;
 
import javax.swing.JDialog;
import javax.swing.JLabel;
32,25 → 27,6
}
 
public void show(String title) {
try {
final SplashScreen splash = SplashScreen.getSplashScreen();
if (splash != null) {
Graphics2D g = splash.createGraphics();
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g.setColor(Color.WHITE);
g.fillRect(0, (int) splash.getSize().getHeight() - 24, (int) splash.getSize().getWidth(), 24);
g.setFont(g.getFont().deriveFont(Font.BOLD).deriveFont(11f));
g.setColor(Color.DARK_GRAY);
g.drawString(title, 20, ((int) splash.getSize().getHeight()) - 8);
 
splash.update();
return;
}
} catch (Throwable e) {
// OpenJDK bug on linux
e.printStackTrace();
}
 
setTitle("Veuillez patienter");
JPanel p = new JPanel();
p.setLayout(new FlowLayout(FlowLayout.LEADING, 5, 5));
/trunk/OpenConcerto/src/org/openconcerto/erp/config/MenuAndActions.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
130,7 → 130,7
 
// check and modify group
final Group groupDesc = this.getGroup().followPath(path, true);
final Item child = groupDesc.getDescFromID(actionID);
final Item child = groupDesc.getChildFromID(actionID);
if (!canReplace && child != null) {
throw new IllegalStateException("ID exists : " + child);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/InstallationPanel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
19,11 → 19,9
import org.openconcerto.erp.core.sales.quote.element.EtatDevisSQLElement;
import org.openconcerto.erp.modules.ModuleManager;
import org.openconcerto.erp.modules.ModuleReference;
import org.openconcerto.erp.rights.DepotStockViewRightEditor;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.changer.convert.AddFK;
import org.openconcerto.sql.changer.convert.AddMDFields;
import org.openconcerto.sql.changer.convert.ChangeIDToInt;
import org.openconcerto.sql.changer.convert.MergeTable;
import org.openconcerto.sql.changer.correct.CorrectOrder;
import org.openconcerto.sql.changer.correct.FixSerial;
import org.openconcerto.sql.element.GroupSQLComponent;
143,6 → 141,20
System.setProperty(SQLSchema.NOAUTO_CREATE_METADATA, "false");
final ComptaPropsConfiguration conf = ComptaPropsConfiguration.create(true);
 
final DBSystemRoot systemRoot = conf.getSystemRoot();
if (systemRoot.getChild(conf.getRootNameValue().getValue()) == null) {
conf.destroy();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
up.setEnabled(true);
bar.setValue(bar.getMaximum());
JOptionPane.showMessageDialog(InstallationPanel.this, "Votre base de données n'est pas initialisée");
}
});
return;
}
 
updateDatabase(conf);
 
conf.destroy();
3556,7 → 3568,7
patchFieldElt1Dot3(table, root);
}
 
private void updateSocieteSchema(final DBRoot root) throws IOException, Exception {
private void updateSocieteSchema(final Configuration conf, final DBRoot root) throws IOException, Exception {
final DBSystemRoot sysRoot = root.getDBSystemRoot();
final SQLDataSource ds = sysRoot.getDataSource();
System.out.println("InstallationPanel.InstallationPanel() UPDATE COMMERCIAL " + root);
3660,7 → 3672,7
final List<ChangeTable<?>> changes = new ArrayList<ChangeTable<?>>();
 
final ModuleManager instance = new ModuleManager();
instance.setRoot(root);
instance.setup(root, conf);
final Collection<ModuleReference> refs = instance.getModulesInstalledRemotely();
final Set<String> allUsedTable = new HashSet<String>();
for (ModuleReference ref : refs) {
3669,6 → 3681,10
}
System.out.println("Tables created by modules:" + allUsedTable);
 
final Set<String> notMigrated = instance.migrateOldTransientDirs();
if (!notMigrated.isEmpty())
System.out.println("Couldn't migrate old backed up/failed modules: " + notMigrated);
 
final List<String> alterRequests = ChangeTable.cat(changes, root.getName());
try {
for (final String req : alterRequests) {
3742,19 → 3758,6
rowValsUserRight.commit();
}
 
if (!codes.contains(DepotStockViewRightEditor.ID_RIGHT)) {
SQLRowValues rowVals = new SQLRowValues(table);
rowVals.put("CODE", DepotStockViewRightEditor.ID_RIGHT);
rowVals.put("NOM", "Voir le stock d'un dépôt");
String desc = "Autorise un utilisateur à visualiser le stock d'un dépôt.";
rowVals.put("DESCRIPTION", desc);
SQLRow row = rowVals.commit();
SQLRowValues rowValsUserRight = new SQLRowValues(table.getTable("USER_RIGHT"));
rowValsUserRight.put("ID_RIGHT", row.getID());
rowValsUserRight.put("HAVE_RIGHT", Boolean.TRUE);
rowValsUserRight.commit();
}
 
if (!codes.contains("MENU_ACCESS")) {
SQLRowValues rowVals = new SQLRowValues(table);
rowVals.put("CODE", "MENU_ACCESS");
3815,7 → 3818,6
rowValsUserRight.put("HAVE_RIGHT", Boolean.TRUE);
rowValsUserRight.commit();
}
 
// if (!codes.contains("MODIF_PRODUCT_KIT")) {
// SQLRowValues rowVals = new SQLRowValues(table);
// rowVals.put("CODE", "MODIF_PRODUCT_KIT");
4208,23 → 4210,25
public void updateDatabase(final ComptaPropsConfiguration conf) {
 
try {
final SQLDataSource ds = conf.getSystemRoot().getDataSource();
System.err.println("SystemRoot:" + conf.getSystemRoot());
System.err.println("Root:" + conf.getRoot());
final DBSystemRoot systemRoot = conf.getSystemRoot();
System.err.println("SystemRoot:" + systemRoot);
final DBRoot rootCommon = conf.getRoot();
System.err.println("Root:" + rootCommon);
 
final SQLDataSource ds = systemRoot.getDataSource();
// FixUnbounded varchar
fixUnboundedVarchar(conf.getRoot());
fixUnboundedVarchar(rootCommon);
 
// FIXME DROP CONSTRAINT UNIQUE ORDRE ON
// CONTACT_FOURNISSEUR
 
checkCompteDefault(conf.getRoot());
checkCompteDefault(rootCommon);
 
updateSocieteTable(conf.getRoot());
updateVille(conf.getRoot().getTable("ADRESSE"));
updateSocieteTable(rootCommon);
updateVille(rootCommon.getTable("ADRESSE"));
 
// Champ user 1.4.1
final SQLTable tableUser = conf.getRoot().getTable("USER_COMMON");
final SQLTable tableUser = rootCommon.getTable("USER_COMMON");
if (tableUser != null) {
final AlterTable alter = new AlterTable(tableUser);
boolean alterUser = false;
4239,56 → 4243,46
 
if (alterUser) {
final String req = alter.asString();
conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
conf.getRoot().refetchTable(tableUser.getName());
conf.getRoot().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableUser.getName());
rootCommon.getSchema().updateVersion();
}
}
 
// Champ Paye
final SQLTable tableCaisse = conf.getRoot().getTable("CAISSE_COTISATION");
final SQLTable tableCaisse = rootCommon.getTable("CAISSE_COTISATION");
if (!tableCaisse.contains("NUMERO_COMPTE_PCE")) {
final AlterTable alter = new AlterTable(tableCaisse);
alter.addVarCharColumn("NUMERO_COMPTE_PCE", 128);
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().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableCaisse.getName());
rootCommon.getSchema().updateVersion();
}
 
final SQLTable tableRC = conf.getRoot().getTable("RUBRIQUE_COTISATION");
final SQLTable tableRC = rootCommon.getTable("RUBRIQUE_COTISATION");
if (!tableRC.contains("PART_CSG_SANS_ABATTEMENT")) {
final AlterTable alter = new AlterTable(tableRC);
alter.addBooleanColumn("PART_CSG_SANS_ABATTEMENT", Boolean.FALSE, false);
final String req = alter.asString();
conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
conf.getRoot().refetchTable(tableRC.getName());
conf.getRoot().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableRC.getName());
rootCommon.getSchema().updateVersion();
}
 
// if (!tableRC.contains("DATE_DEBUT_REGUL")) {
// final AlterTable alter = new AlterTable(tableRC);
// alter.addColumn("DATE_DEBUT_REGUL", "date");
// alter.addColumn("DATE_FIN_REGUL", "date");
// final String req = alter.asString();
// conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
// conf.getRoot().refetchTable(tableRC.getName());
// conf.getRoot().getSchema().updateVersion();
// }
 
// Paye simplifiee
List<SQLRow> rowRubriqueReduGvt = new ArrayList<>();
{
 
final SQLTable tableRCom = conf.getRoot().getTable("RUBRIQUE_COMM");
final SQLTable tableRCom = rootCommon.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();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableRCom.getName());
rootCommon.getSchema().updateVersion();
 
SQLRowValues rowValsCommChom = new SQLRowValues(tableRCom);
rowValsCommChom.put("TAUX_SAL", "1.45;");
4327,13 → 4321,13
rowRubriqueReduGvt.add(rowValsCommCSG.commit());
 
SQLSelect sel = new SQLSelect();
sel.addSelect(conf.getRoot().getTable("PROFIL_PAYE").getKey());
sel.addSelect(rootCommon.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"));
SQLRowValues rowValsRubGvt = new SQLRowValues(rootCommon.getTable("PROFIL_PAYE_ELEMENT"));
rowValsRubGvt.put("ID_PROFIL_PAYE", rowProfil.getID());
rowValsRubGvt.put("POSITION", pos);
rowValsRubGvt.put("IDSOURCE", rowRub.getID());
4345,14 → 4339,14
}
}
 
final SQLTable tableRB = conf.getRoot().getTable("RUBRIQUE_BRUT");
final SQLTable tableRB = rootCommon.getTable("RUBRIQUE_BRUT");
if (!tableRB.contains("AVANTAGE_NATURE")) {
final AlterTable alter = new AlterTable(tableRB);
alter.addBooleanColumn("AVANTAGE_NATURE", Boolean.FALSE, false);
final String req = alter.asString();
conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
conf.getRoot().refetchTable(tableRB.getName());
conf.getRoot().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableRB.getName());
rootCommon.getSchema().updateVersion();
}
 
if (!tableRC.contains("LIGNE_PAYE_SIMPLIFIEE")) {
4361,9 → 4355,9
alter.addBooleanColumn("ALLEGEMENT_COTISATION", Boolean.FALSE, false);
alter.addVarCharColumn("LIGNE_PAYE_SIMPLIFIEE", 256);
final String req = alter.asString();
conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
conf.getRoot().refetchTable(tableRC.getName());
conf.getRoot().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableRC.getName());
rootCommon.getSchema().updateVersion();
Map<String, String> liaison = new HashMap<String, String>();
liaison.put("COTCSA", LignePayeSimplifiee.SANTE_SECURITE.getId());
liaison.put("COTMALADIE", LignePayeSimplifiee.SANTE_SECURITE.getId());
4412,9 → 4406,9
liaison.put("COT_PENIBLE", LignePayeSimplifiee.AUTRES_CONTRIBUTIONS.getId());
 
SQLSelect sel = new SQLSelect();
sel.addSelect(conf.getRoot().findTable("RUBRIQUE_COTISATION").getField("CODE"));
sel.addSelect(conf.getRoot().findTable("RUBRIQUE_COTISATION").getField("NOM"));
sel.addSelect(conf.getRoot().findTable("RUBRIQUE_COTISATION").getKey());
sel.addSelect(rootCommon.findTable("RUBRIQUE_COTISATION").getField("CODE"));
sel.addSelect(rootCommon.findTable("RUBRIQUE_COTISATION").getField("NOM"));
sel.addSelect(rootCommon.findTable("RUBRIQUE_COTISATION").getKey());
List<SQLRow> rubCotis = SQLRowListRSH.execute(sel);
 
for (SQLRow sqlRow : rubCotis) {
4429,15 → 4423,15
}
}
 
final SQLTable tableRnet = conf.getRoot().getTable("RUBRIQUE_NET");
final SQLTable tableRnet = rootCommon.getTable("RUBRIQUE_NET");
 
if (!tableRnet.contains("NUMERO_COMPTE_PCE_CHARGES")) {
final AlterTable alter = new AlterTable(tableRnet);
alter.addVarCharColumn("NUMERO_COMPTE_PCE_CHARGES", 128);
final String req = alter.asString();
conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
conf.getRoot().refetchTable(tableRnet.getName());
conf.getRoot().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableRnet.getName());
rootCommon.getSchema().updateVersion();
}
 
if (!tableRC.contains("PART_PAT_IMPOSABLE")) {
4444,9 → 4438,9
final AlterTable alter = new AlterTable(tableRC);
alter.addBooleanColumn("PART_PAT_IMPOSABLE", Boolean.FALSE, false);
final String req = alter.asString();
conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
conf.getRoot().refetchTable(tableRC.getName());
conf.getRoot().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableRC.getName());
rootCommon.getSchema().updateVersion();
}
 
if (!tableRC.contains("REDUCTION_FILLON")) {
4453,21 → 4447,21
final AlterTable alter = new AlterTable(tableRC);
alter.addBooleanColumn("REDUCTION_FILLON", Boolean.FALSE, false);
final String req = alter.asString();
conf.getRoot().getDBSystemRoot().getDataSource().execute(req);
conf.getRoot().refetchTable(tableRC.getName());
conf.getRoot().getSchema().updateVersion();
rootCommon.getDBSystemRoot().getDataSource().execute(req);
rootCommon.refetchTable(tableRC.getName());
rootCommon.getSchema().updateVersion();
}
 
// Vérification des droits existants
checkRights(conf.getRoot());
checkRights(rootCommon);
 
if (!conf.getRoot().contains("DEVISE")) {
if (!rootCommon.contains("DEVISE")) {
System.out.println("InstallationPanel.InstallationPanel() ADD DEVISE");
try {
SQLUtils.executeAtomic(ds, new SQLUtils.SQLFactory<Object>() {
@Override
public Object create() throws SQLException {
final SQLCreateTable createDevise = new SQLCreateTable(conf.getRoot(), "DEVISE");
final SQLCreateTable createDevise = new SQLCreateTable(rootCommon, "DEVISE");
createDevise.addVarCharColumn("CODE", 128);
createDevise.addVarCharColumn("NOM", 128);
createDevise.addVarCharColumn("LIBELLE", 128);
4476,7 → 4470,7
createDevise.addDecimalColumn("TAUX_COMMERCIAL", 16, 8, BigDecimal.ONE, false);
ds.execute(createDevise.asString());
insertUndef(createDevise);
conf.getRoot().getSchema().updateVersion();
rootCommon.getSchema().updateVersion();
return null;
}
});
4483,8 → 4477,8
} catch (Exception ex) {
throw new IllegalStateException("Erreur lors de la création de la table DEVISE", ex);
}
} else if (!conf.getRoot().getTable("DEVISE").contains("TAUX_COMMERCIAL")) {
final SQLTable tDevise = conf.getRoot().getTable("DEVISE");
} else if (!rootCommon.getTable("DEVISE").contains("TAUX_COMMERCIAL")) {
final SQLTable tDevise = rootCommon.getTable("DEVISE");
final AlterTable alterDevise = new AlterTable(tDevise);
alterDevise.addDecimalColumn("TAUX_COMMERCIAL", 16, 8, BigDecimal.ONE, false);
ds.execute(alterDevise.asString());
4491,7 → 4485,7
tDevise.getSchema().updateVersion();
}
 
if (!conf.getRoot().contains("TYPE_MODELE")) {
if (!rootCommon.contains("TYPE_MODELE")) {
System.out.println("InstallationPanel.InstallationPanel() ADD TYPE_MODELE");
try {
SQLUtils.executeAtomic(ds, new SQLUtils.SQLFactory<Object>() {
4498,7 → 4492,7
 
@Override
public Object create() throws SQLException {
final SQLCreateTable createTypeModele = new SQLCreateTable(conf.getRoot(), "TYPE_MODELE");
final SQLCreateTable createTypeModele = new SQLCreateTable(rootCommon, "TYPE_MODELE");
createTypeModele.addVarCharColumn("NOM", 128);
createTypeModele.addVarCharColumn("TABLE", 128);
createTypeModele.addVarCharColumn("DEFAULT_MODELE", 128);
4506,9 → 4500,9
 
insertUndef(createTypeModele);
 
conf.getRoot().getSchema().updateVersion();
rootCommon.getSchema().updateVersion();
 
conf.getRoot().refetch();
rootCommon.refetch();
 
return null;
}
4518,7 → 4512,7
// ('FR', 'Français', 1.000), ('EN',
// 'Anglais', 2.000)
final List<String> values = new ArrayList<String>();
final SQLBase base = conf.getRoot().getBase();
final SQLBase base = rootCommon.getBase();
 
for (int i = 0; i < type.length; i += 3) {
final int order = values.size() + 1;
4525,8 → 4519,8
values.add("(" + base.quoteString(type[i]) + ", " + base.quoteString(type[i + 1]) + ", " + base.quoteString(type[i + 2]) + ", " + order + ")");
}
final String valuesStr = CollectionUtils.join(values, ", ");
final String insertVals = "INSERT INTO " + conf.getRoot().getTable("TYPE_MODELE").getSQLName().quote() + "(" + SQLBase.quoteIdentifier("NOM") + ", "
+ SQLBase.quoteIdentifier("TABLE") + ", " + SQLBase.quoteIdentifier("DEFAULT_MODELE") + ", " + SQLBase.quoteIdentifier(SQLSyntax.ORDER_NAME) + ") VALUES" + valuesStr;
final String insertVals = "INSERT INTO " + rootCommon.getTable("TYPE_MODELE").getSQLName().quote() + "(" + SQLBase.quoteIdentifier("NOM") + ", " + SQLBase.quoteIdentifier("TABLE")
+ ", " + SQLBase.quoteIdentifier("DEFAULT_MODELE") + ", " + SQLBase.quoteIdentifier(SQLSyntax.ORDER_NAME) + ") VALUES" + valuesStr;
 
ds.execute(insertVals);
} catch (Exception ex) {
4534,64 → 4528,25
}
}
 
SQLTable.setUndefID(conf.getRoot().getSchema(), "DEVISE", 1);
SQLTable.setUndefID(conf.getRoot().getSchema(), "TYPE_MODELE", 1);
SQLTable.setUndefID(rootCommon.getSchema(), "DEVISE", 1);
SQLTable.setUndefID(rootCommon.getSchema(), "TYPE_MODELE", 1);
 
// DSN
final DSNInstallationUtils dsnUtils = new DSNInstallationUtils();
dsnUtils.updateDSNCommonTable(conf.getRoot());
SQLRow rowRubNetPAS = createPasCommon(conf.getRoot());
dsnUtils.updateDSNCommonTable(rootCommon);
SQLRow rowRubNetPAS = createPasCommon(rootCommon);
// ECo contribution
final EcoContributionInstallationUtils ecoUtils = new EcoContributionInstallationUtils();
ecoUtils.updateEcoCommonTable(conf.getRoot());
ecoUtils.updateEcoCommonTable(rootCommon);
 
 
// we need to upgrade all roots
// ///////////////////////////
conf.getSystemRoot().mapAllRoots();
conf.getSystemRoot().refetch();
systemRoot.mapAllRoots();
systemRoot.refetch();
 
// Merge IDCC
final SQLTable societeCommon = conf.getRoot().getTable("SOCIETE_COMMON");
if (!societeCommon.contains("ID_IDCC")) {
SQLCreateTable createIDCCCommon = new SQLCreateTable(conf.getRoot(), "IDCC");
createIDCCCommon.addVarCharColumn("CODE", 45, false, "''", true);
createIDCCCommon.addVarCharColumn("NOM", 2048, false, "''", true);
AddMDFields.addFields(createIDCCCommon, conf.getRoot().getTable("USER_COMMON"));
final Set<String> childrenNames = systemRoot.getChildrenNames();
 
societeCommon.getDBRoot().createTable(createIDCCCommon);
societeCommon.getDBRoot().refetchTable("IDCC");
 
AlterTable alter = new AlterTable(societeCommon);
alter.addForeignColumn("ID_IDCC", conf.getRoot().getTable("IDCC"));
societeCommon.getDBRoot().getDBSystemRoot().getDataSource().execute(alter.asString());
societeCommon.getDBRoot().refetchTable("SOCIETE_COMMON");
 
}
final Set<String> childrenNames = conf.getSystemRoot().getChildrenNames();
MergeTable mergeIDCC = new MergeTable(conf.getRoot().getDBSystemRoot());
mergeIDCC.setDestTable(conf.getRoot().getTable("IDCC"));
 
final List<String> mdFields = Arrays.asList("ID_USER_COMMON_CREATE", "ID_USER_COMMON_MODIFY", "CREATION_DATE", "MODIFICATION_DATE");
for (final String childName : childrenNames) {
final DBRoot root = conf.getSystemRoot().getRoot(childName);
if (!root.getName().contains("Common") && root.contains("IDCC")) {
final SQLTable table = root.getTable("IDCC");
AlterTable alter = new AlterTable(table);
alter.alterColumnNullable("ARCHIVE", false);
// Drop MD Fields to be sure having same column properties
for (String field : mdFields) {
alter.dropColumn(field);
}
root.getDBSystemRoot().getDataSource().execute(alter.asString());
root.refetchTable("IDCC");
new AddMDFields(root.getDBSystemRoot()).change(table);
 
mergeIDCC.change(table);
}
}
// final Set<String> childrenNames = conf.getSystemRoot().getChildrenNames();
 
SwingUtilities.invokeLater(new Runnable() {
 
@Override
4613,9 → 4568,9
}
});
i++;
final DBRoot root = conf.getSystemRoot().getRoot(childName);
final DBRoot root = systemRoot.getRoot(childName);
try {
conf.getSystemRoot().getDataSource().execute("CREATE LANGUAGE plpgsql;");
systemRoot.getDataSource().execute("CREATE LANGUAGE plpgsql;");
} catch (Exception e) {
System.err.println("Warning: cannot add language plpgsql" + e.getMessage());
}
4646,7 → 4601,7
fixUnboundedNumeric(root);
fixCompletion(root);
try {
updateSocieteSchema(root);
updateSocieteSchema(conf, root);
} catch (Exception e) {
throw new SQLException(e);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/config/DSNInstallationUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
56,7 → 56,7
private void insertValues(List<Tuple2<String, String>> values, SQLTable table) throws SQLException {
SQLSelect sel = new SQLSelect();
sel.addSelect(table.getField("CODE"));
List<String> codes = (List<String>) table.getDBSystemRoot().getDataSource().executeCol(sel.asString());
List<String> codes = (List<String>) table.getDBSystemRoot().getDataSource().executeA(sel.asString());
for (Tuple2<String, String> tuple2 : values) {
if (!codes.contains(tuple2.get0())) {
SQLRowValues rowVals = new SQLRowValues(table);
86,14 → 86,6
root.getSchema().updateVersion();
}
 
if (!societeCommonT.contains("ORG_PROTECTION_SOCIAL_ID")) {
AlterTable t = new AlterTable(societeCommonT);
t.addVarCharColumn("ORG_PROTECTION_SOCIAL_ID", 256);
root.getBase().getDataSource().execute(t.asString());
root.refetchTable("SOCIETE_COMMON");
root.getSchema().updateVersion();
}
 
SQLTable tableRubCot = root.getTable("RUBRIQUE_COTISATION");
if (!tableRubCot.contains("ASSIETTE_PLAFONNEE")) {
AlterTable tableRub = new AlterTable(tableRubCot);
195,6 → 187,7
}
}
 
 
if (!root.contains("TYPE_PREAVIS")) {
final SQLCreateTable createTableMotif = new SQLCreateTable(root, "TYPE_PREAVIS");
createTableMotif.addVarCharColumn("CODE", 25);
1044,7 → 1037,6
v.add(Tuple2.create("102", "Cotisation Allocation Familiale - taux réduit"));
v.add(Tuple2.create("103", "Contribution actions gratuites"));
v.add(Tuple2.create("226", "Assiette du Versement Transport"));
 
v.add(Tuple2.create("901", "Cotisation épargne retraite"));
 
insertValues(v, table);
1359,39 → 1351,8
final SQLTable tableCotInd = root.getTable("CODE_COTISATION_INDIVIDUELLE");
List<Tuple2<String, String>> vCodeIndiv = new ArrayList<>();
vCodeIndiv.add(Tuple2.create("104", " Pénibilité Cotisation de base"));
vCodeIndiv.add(Tuple2.create("105", " Montant de cotisation Régime Unifié Agirc Arrco, y compris Apec"));
vCodeIndiv.add(Tuple2.create("106", " Réduction générale des cotisations patronales de retraite complémentaire"));
vCodeIndiv.add(Tuple2.create("107", " Forfait marin"));
vCodeIndiv.add(Tuple2.create("108", " Demi rôle marin"));
vCodeIndiv.add(Tuple2.create("109", " Exonération de cotisations salariales de retraite complémentaire au titre de l'emploi d'un apprenti"));
vCodeIndiv.add(Tuple2.create("110", " Exonération de cotisations patronales de retraite complémentaire applicable dans les DOM (LODEOM) SMIC 130% à 220%"));
vCodeIndiv.add(Tuple2.create("111", " Exonération de cotisations de retraite complémentaire applicable aux entreprises et associations d'aide à domicile"));
vCodeIndiv.add(Tuple2.create("112", " Exonération de cotisations patronales de retraite complémentaire applicable dans les DOM (LODEOM) SMIC 170% à 270%"));
vCodeIndiv.add(Tuple2.create("113", " Exonération de cotisations patronales de retraite complémentaire applicable dans les DOM (LODEOM) SMIC 170% à 350%"));
vCodeIndiv.add(Tuple2.create("114", " Montant de réduction des heures supplémentaires/complémentaires"));
vCodeIndiv.add(Tuple2.create("115", " Cotisation Assurance Maladie pour le Régime Local Alsace Moselle"));
vCodeIndiv.add(Tuple2.create("116", " Cotisation absente de la norme en cas de régularisation prud'homale"));
vCodeIndiv.add(Tuple2.create("128", " Contribution à la formation professionnelle (CFP)"));
vCodeIndiv.add(Tuple2.create("129", " Contribution dédiée au financement du Compte Professionnel de Formation pour les titulaires de CDD (CPFCDD)"));
vCodeIndiv.add(Tuple2.create("130", " Part principale de la taxe d'apprentissage"));
vCodeIndiv.add(Tuple2.create("131", " Cotisation régime unifié Agirc Arrco"));
vCodeIndiv.add(Tuple2.create("132", " Cotisation Apec"));
vCodeIndiv.add(Tuple2.create("133", " Contribution maladie spécifique Mayotte"));
vCodeIndiv.add(Tuple2.create("902", " Contribution à la formation professionnelle des Artisans assimilés salariés"));
vCodeIndiv.add(Tuple2.create("903", " Cotisation AFNCA"));
vCodeIndiv.add(Tuple2.create("904", " Cotisation ANEFA"));
vCodeIndiv.add(Tuple2.create("905", " Cotisation ASCPA"));
vCodeIndiv.add(Tuple2.create("906", " Cotisation PROVEA"));
vCodeIndiv.add(Tuple2.create("907", " Complément de cotisation Assurance Maladie"));
vCodeIndiv.add(Tuple2.create("908", " Taxe forfaitaire CDDU Assurance Chômage"));
vCodeIndiv.add(Tuple2.create("909", " Cotisation au titre du financement des régimes de retraites supplémentaires à prestation définies"));
vCodeIndiv.add(Tuple2.create("910", " Exonération de cotisations patronales pour les entreprises affectées par la crise sanitaire"));
vCodeIndiv.add(Tuple2.create("911", " Réduction de cotisations patronales pour les entreprises du secteur de la vigne affectées par la crise sanitaire"));
vCodeIndiv.add(Tuple2.create("912", " Exonération du forfait social à 10%"));
vCodeIndiv.add(Tuple2.create("913", " Potentielle nouvelle cotisation C"));
vCodeIndiv.add(Tuple2.create("914", " Potentielle nouvelle cotisation A"));
vCodeIndiv.add(Tuple2.create("915", " Potentielle nouvelle cotisation B"));
 
vCodeIndiv.add(Tuple2.create("105", "Montant de cotisation Régime Unifié Agirc-Arrco y compris Apec"));
vCodeIndiv.add(Tuple2.create("106", "Réduction générale des cotisations patronales Agirc-Arrco"));
insertValues(vCodeIndiv, tableCotInd);
 
final SQLTable tableCTP = root.getTable("CODE_CAISSE_TYPE_RUBRIQUE");
1399,40 → 1360,6
vCTP.add(Tuple2.create("003", "Réduction cotisations salariale heures supplémentaires"));
vCTP.add(Tuple2.create("510", "Prime exceptionnelle de pouvoir d’achat"));
vCTP.add(Tuple2.create("060", "RR Chômage CSG-CRDS taux plein"));
vCTP.add(Tuple2.create("917", "MOBILITE ADD JOURNALISTE TX MINO 20%"));
vCTP.add(Tuple2.create("920", "EMPL AGRIC (1500 TONNES CANNE) RMI OM"));
vCTP.add(Tuple2.create("921", "MOBILITE ARTISTES TX MINORE 30%"));
vCTP.add(Tuple2.create("922", "ENTR.DE PRODUCTION D ELECTRICITE"));
vCTP.add(Tuple2.create("922", "ENTR.DE PRODUCTION D ELECTRICITE"));
vCTP.add(Tuple2.create("926", "AT SEULEMENT - GESTION TOTALE"));
vCTP.add(Tuple2.create("927", "MOBILITE ADD ARTISTES TX MINO 30%"));
vCTP.add(Tuple2.create("936", "CNIEG PRESTATION COMPL. INVALIDITE"));
vCTP.add(Tuple2.create("937", "COTISATIONS AGS CAS GENERAL U2"));
vCTP.add(Tuple2.create("938", "CONTRATS AIDES ATELIER INSERTION"));
vCTP.add(Tuple2.create("939", "ATELIER INSERTION MAYOTTE"));
vCTP.add(Tuple2.create("939", "ATELIER INSERTION MAYOTTE"));
vCTP.add(Tuple2.create("940", "CNIEG DROITS SPE. PASSES NON REGULES"));
vCTP.add(Tuple2.create("948", "CONTRAT EMPLOI SOLIDARITE"));
vCTP.add(Tuple2.create("950", "CONTRAT EMPLOI SOLIDARITE CAS PART"));
vCTP.add(Tuple2.create("951", "CONTRATS EMPLOI SOLIDARITE CAS PART"));
vCTP.add(Tuple2.create("952", "CONTRAT EMPLOI CONSOLIDE CAS GENERAL"));
vCTP.add(Tuple2.create("954", "CONTRAT EMPLOI CONSOLIDE CAS PART"));
vCTP.add(Tuple2.create("955", "CNIEG PETIT POOL"));
vCTP.add(Tuple2.create("959", "CFP ENTREPRISE < 11 SALARIES"));
vCTP.add(Tuple2.create("967", "CONTR.ROYALTIES ART.ET MANNEQUINS"));
vCTP.add(Tuple2.create("969", "COT.MAL.ROYALTIES ART.ETRANGER"));
vCTP.add(Tuple2.create("971", "CFP ENTREPRISE >= 11 SALARIES"));
vCTP.add(Tuple2.create("983", "CFP INTERMITTENTS DU SPECTACLE"));
vCTP.add(Tuple2.create("985", "PENALITE PENIBILITE"));
vCTP.add(Tuple2.create("987", "CONTRIBUTION CPF CDD "));
vCTP.add(Tuple2.create("992", "TA PRINCIPALE HORS ALSACE MOSELLE"));
vCTP.add(Tuple2.create("993", "TA ALSACE MOSELLE"));
vCTP.add(Tuple2.create("994", "TA DEDUCTION CFA ET OFFRE NOUVELLE"));
vCTP.add(Tuple2.create("995", "TA - SOLDE VERSEMENT LIBERATOIRE"));
vCTP.add(Tuple2.create("995", "TA - SOLDE VERSEMENT LIBERATOIRE"));
vCTP.add(Tuple2.create("996", "TA - DEDUCTION AU SOLDE CFA"));
vCTP.add(Tuple2.create("997", "TA - DEDUCTION SOLDE CREANCE ALTERN"));
vCTP.add(Tuple2.create("998", "CSA CONTRIBUTION ANNUELLE"));
insertValues(vCTP, tableCTP);
 
final SQLTable tableTypeBrut = root.getTable("CODE_TYPE_RUBRIQUE_BRUT");
1442,94 → 1369,11
vbrutType.add(Tuple3.create("018", "Heures supplémentaires structurelles", DsnTypeCodeBrut.REMUNERATION.getName()));
vbrutType.add(Tuple3.create("019", "Heures d'activité partielle", DsnTypeCodeBrut.REMUNERATION.getName()));
vbrutType.add(Tuple3.create("020", "Heures affectées à un travail d’aide à domicile de publics fragiles", DsnTypeCodeBrut.REMUNERATION.getName()));
 
vbrutType.add(Tuple3.create("021", "[FP] Taux de rémunération de la situation administrative", DsnTypeCodeBrut.REMUNERATION.getName()));
vbrutType.add(Tuple3.create("022", "Potentiel nouveau type de rémunération B", DsnTypeCodeBrut.REMUNERATION.getName()));
vbrutType.add(Tuple3.create("023", "Potentiel nouveau type de rémunération C", DsnTypeCodeBrut.REMUNERATION.getName()));
vbrutType.add(Tuple3.create("025", "Heures correspondant à du chômage intempéries", DsnTypeCodeBrut.REMUNERATION.getName()));
vbrutType.add(Tuple3.create("026", "Heures supplémentaires exonérées", DsnTypeCodeBrut.REMUNERATION.getName()));
vbrutType.add(Tuple3.create("027", "Potentiel nouveau type de rémunération A", DsnTypeCodeBrut.REMUNERATION.getName()));
 
DsnBrutCode dsnBurCode = new DsnBrutCode();
dsnBurCode.updateTable(vbrutType, tableTypeBrut);
 
// P21
final SQLTable tableArret = root.getTable("MOTIF_ARRET_TRAVAIL");
List<Tuple2<String, String>> vArret = new ArrayList<Tuple2<String, String>>();
vArret.add(Tuple2.create("09", "adoption"));
vArret.add(Tuple2.create("15", "temps partiel thérapeutique (risque maladie)"));
vArret.add(Tuple2.create("16", "temps partiel thérapeutique (risque accident de travail)"));
vArret.add(Tuple2.create("17", "temps partiel thérapeutique (risque accident de trajet)"));
vArret.add(Tuple2.create("18", "temps partiel thérapeutique (risque maladie professionnelle)"));
insertValues(vArret, tableArret);
 
if (!root.contains("CODE_CAISSE_CONGES_PAYES")) {
final SQLCreateTable createTableCode = new SQLCreateTable(root, "CODE_CAISSE_CONGES_PAYES");
createTableCode.addVarCharColumn("CODE", 25);
createTableCode.addVarCharColumn("NOM", 512);
 
try {
root.getBase().getDataSource().execute(createTableCode.asString());
insertUndef(createTableCode);
root.refetchTable("CODE_CAISSE_CONGES_PAYES");
root.getSchema().updateVersion();
 
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table " + "CODE_CAISSE_CONGES_PAYES", ex);
}
}
 
if (!root.contains("MOTIF_NON_ASSUJETIS_TA")) {
final SQLCreateTable createTableCode = new SQLCreateTable(root, "MOTIF_NON_ASSUJETIS_TA");
createTableCode.addVarCharColumn("CODE", 25);
createTableCode.addVarCharColumn("NOM", 512);
 
try {
root.getBase().getDataSource().execute(createTableCode.asString());
insertUndef(createTableCode);
root.refetchTable("MOTIF_NON_ASSUJETIS_TA");
root.getSchema().updateVersion();
 
final SQLTable tableMotif = root.getTable("MOTIF_NON_ASSUJETIS_TA");
List<Tuple2<String, String>> vMotif = new ArrayList<Tuple2<String, String>>();
vMotif.add(Tuple2.create("001", "Non assujetti par choix du régime fiscal (option IR en catégorie BNC)"));
vMotif.add(Tuple2.create("002", "Collectivités publiques"));
vMotif.add(Tuple2.create("003", "Etablissements publics de recherche et les établissements publics d'enseignement supérieurs"));
vMotif.add(Tuple2.create("004", "Personnes morales créées pour la gestion d'un pôle de recherche et d'enseignement supérieur ou d'un réseau thématique de recherche avancée"));
vMotif.add(Tuple2.create("005", "Fondations reconnues d'utilité public du secteur de la recherche"));
vMotif.add(Tuple2.create("006", "Sociétés et personnes morales ayant pour objet exclusif l'enseignement"));
vMotif.add(Tuple2.create("007", "Associations sans but lucratif"));
vMotif.add(Tuple2.create("008", "Syndicats professionnels"));
vMotif.add(Tuple2.create("009", "Entreprises sans établissement en France (ESEF)"));
vMotif.add(Tuple2.create("010", "Sociétés civiles de moyens (SCM) non commerciale"));
vMotif.add(Tuple2.create("011", "Personnes physiques ou morales assujetties aux BNC ou BA"));
vMotif.add(Tuple2.create("012", "Les coopératives agricoles"));
vMotif.add(Tuple2.create("013", "Les coopératives artisanales, transport (y compris fluvial et maritime) et leurs unions"));
vMotif.add(Tuple2.create("014", "Les groupements d'employeurs dont agricoles"));
vMotif.add(Tuple2.create("015", "Les sociétés civiles agricoles"));
vMotif.add(Tuple2.create("016", "Les mutuelles et organismes mutualistes"));
vMotif.add(Tuple2.create("017",
"Les organismes HLM, SA de crédit immobilier (I et au II de l'article L. 422-4 du code de la construction et de l'habitation ) et unions d'économie sociale"));
vMotif.add(Tuple2.create("018", "Les sociétés coopératives de construction désignées à l'article L. 432-2 du code de la construction et de l'habitation."));
vMotif.add(Tuple2.create("019", "Organismes chargés de l'organisation en France d'une compétition sportive internationale en France (Article L6131-1 du code du travail)"));
 
insertValues(vMotif, tableMotif);
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table " + "MOTIF_NON_ASSUJETIS_TA", ex);
}
}
if (!societeCommonT.contains("ASSUJETTISSEMENT_TA")) {
AlterTable alterSoc = new AlterTable(societeCommonT);
alterSoc.addBooleanColumn("ASSUJETTISSEMENT_TA", Boolean.TRUE, false);
alterSoc.addBooleanColumn("ASSUJETTISSEMENT_CFP", Boolean.TRUE, false);
alterSoc.addBooleanColumn("ASSUJETTISSEMENT_CFP_CDD", Boolean.TRUE, false);
alterSoc.addForeignColumn("ID_MOTIF_NON_ASSUJETIS_TA", root.findTable("MOTIF_NON_ASSUJETIS_TA"));
 
root.getBase().getDataSource().execute(alterSoc.asString());
root.getSchema().updateVersion();
}
}
 
public void updateDSN(final DBRoot root) throws SQLException {
final SQLTable tableCodeStatutCat = root.getTable("CODE_STATUT_CATEGORIEL");
SQLRow rowNonCadre = tableCodeStatutCat.getRow(4);
2038,35 → 1882,6
throw new IllegalStateException("Erreur lors de la création de la table " + "CODE_PENIBILITE_CONTRAT_SALARIE", ex);
}
}
 
if (!root.contains("ARRET_CHOMAGE_INTEMPERIE")) {
 
final SQLCreateTable createTableSal = new SQLCreateTable(root, "ARRET_CHOMAGE_INTEMPERIE");
final SQLTable tableInfosSalarie = root.getTable("INFOS_SALARIE_PAYE");
createTableSal.addForeignColumn("ID_INFOS_SALARIE_PAYE", tableInfosSalarie);
createTableSal.addForeignColumn("ID_CODE_AMENAGEMENT_PARTIEL", root.findTable("CODE_AMENAGEMENT_PARTIEL"));
createTableSal.addForeignColumn("ID_CODE_SUSPENSION", root.findTable("CODE_SUSPENSION"));
createTableSal.addColumn("DATE_DEBUT_SUSPENSION", "date");
createTableSal.addColumn("DATE_FIN_SUSPENSION", "date");
 
try {
root.getBase().getDataSource().execute(createTableSal.asString());
insertUndef(createTableSal);
root.refetchTable("ARRET_CHOMAGE_INTEMPERIE");
root.getSchema().updateVersion();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de la création de la table " + "ARRET_CHOMAGE_INTEMPERIE", ex);
}
}
 
if (!tableContrat.contains("ID_CODE_CAISSE_CONGES_PAYES")) {
AlterTable alterContrat = new AlterTable(tableContrat);
alterContrat.addForeignColumn("ID_CODE_CAISSE_CONGES_PAYES", root.findTable("CODE_CAISSE_CONGES_PAYES"));
alterContrat.addDecimalColumn("TAUX_FRAIS_PROFESSIONNELS", 16, 4, null, true);
root.getBase().getDataSource().execute(alterContrat.asString());
root.getSchema().updateVersion();
}
 
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleManager.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
54,7 → 54,6
import org.openconcerto.sql.utils.SQLUtils.SQLFactory;
import org.openconcerto.sql.view.list.IListeAction;
import org.openconcerto.ui.SwingThreadUtils;
import org.openconcerto.utils.BaseDirs;
import org.openconcerto.utils.CollectionMap2.Mode;
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.ExceptionHandler;
226,8 → 225,6
 
// final (thus safely published) and thread-safe
private final FactoriesByID factories;
@GuardedBy("this")
private List<File> folders = Collections.emptyList();
// to avoid starting twice the same module
// we synchronize the whole install/start and stop/uninstall
@GuardedBy("this")
319,41 → 316,6
 
// *** factories (thread-safe)
 
public final void setFolders(final File... dirs) {
this.setFolders(Arrays.asList(dirs));
}
 
// The system directories should be before the user directories.
// This order is important for getFolderToWrite() and allow the user modules to replace the
// system ones.
public final void setFolders(final List<File> dirs) {
final List<File> absolutes = new ArrayList<>(dirs.size());
for (final File dir : dirs) {
final File abs = dir.getAbsoluteFile();
this.addFactories(abs);
absolutes.add(abs);
}
synchronized (this) {
this.folders = Collections.unmodifiableList(absolutes);
}
}
 
public synchronized final List<File> getFolders() {
return this.folders;
}
 
public static final File getFolderToWrite(final List<File> dirs) {
// Try to install in system directory first, then fall back to user directory.
for (final File dir : dirs) {
try {
return BaseDirs.getFolderToWrite(dir);
} catch (IOException e) {
// try next one
}
}
return null;
}
 
public final int addFactories(final File dir) {
if (!dir.exists()) {
L.warning("Module factory directory not found: " + dir.getAbsolutePath());
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/AvailableModulesPanel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
32,7 → 32,6
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import javax.swing.AbstractAction;
228,16 → 227,21
JOptionPane.showMessageDialog(panel, "Impossible d'installer le module. Le fichier n'est pas un module.");
return;
}
final List<File> dirs = panel.getModuleManager().getFolders();
final File dir = ModuleManager.getFolderToWrite(dirs);
if (dir == null) {
if (dirs.isEmpty()) {
JOptionPane.showMessageDialog(panel, "Aucun dossier configuré");
final File dir = Gestion.MODULES_DIR;
// TODO test symlink in Java 7
if (!dir.isDirectory()) {
if (dir.exists()) {
JOptionPane.showMessageDialog(panel, "Le fichier existe mais n'est pas un dossier : " + dir.getAbsolutePath());
return;
} else {
JOptionPane.showMessageDialog(panel, "Impossible de créer le dossier des modules : " + dirs);
}
try {
FileUtils.mkdir_p(dir);
} catch (IOException e) {
JOptionPane.showMessageDialog(panel, "Impossible de créer le dossier des modules : " + dir.getAbsolutePath());
return;
}
}
}
File out = null;
if (dir.canWrite()) {
try {
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleLauncher.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
16,12 → 16,10
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.modules.ModulePackager.ModuleFiles;
import org.openconcerto.utils.BaseDirs;
import org.openconcerto.utils.FileUtils;
 
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
 
/**
* Package a module from a project and launch it. The system property {@link #MODULE_DIR_PROP} must
52,6 → 50,10
 
// always update dist/ to avoid out of date problems
final File jar = ModulePackager.createDist(moduleFiles);
// to avoid out of date modules from OpenConcerto (e.g. when launching this module, the jars
// of MODULES_DIR are used for dependencies)
FileUtils.mkdir_p(Gestion.MODULES_DIR);
FileUtils.copyFile(jar, new File(Gestion.MODULES_DIR, jar.getName()));
 
final PropsModuleFactory factory;
if (launchFromPackage) {
66,14 → 68,7
}
 
Gestion.main(args);
 
final ModuleManager moduleManager = ComptaPropsConfiguration.getInstanceCompta().getModuleManager();
// to avoid out of date modules from OpenConcerto (e.g. when launching this module, the jars
// of MODULES_DIR are used for dependencies)
final File modulesDir = BaseDirs.getFolderToWrite(moduleManager.getFolders().get(0));
Files.copy(jar.toPath(), modulesDir.toPath().resolve(jar.getName()), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
 
// add after main() otherwise we could be overwritten by an older jar
moduleManager.addFactoryAndStart(factory, false);
ComptaPropsConfiguration.getInstanceCompta().getModuleManager().addFactoryAndStart(factory, false);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/action/AboutAction.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
15,6 → 15,7
 
import org.openconcerto.erp.config.Benchmark;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.sql.ui.InfoPanel;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
29,6 → 30,7
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
 
import javax.swing.AbstractAction;
import javax.swing.Action;
113,14 → 115,18
p.add(new JLabel(dbPath), c);
}
c.gridy++;
try {
c.gridx = 0;
c.weightx = 0;
c.anchor = GridBagConstraints.EAST;
p.add(new JLabelBold("Dossiers des modules : "), c);
p.add(new JLabelBold("Dossier des modules : "), c);
c.gridx++;
c.weightx = 1;
c.anchor = GridBagConstraints.WEST;
p.add(new JLabel(this.conf.getModuleManager().getFolders().toString()), c);
p.add(new JLabel(Gestion.MODULES_DIR.getCanonicalPath()), c);
} catch (IOException e) {
e.printStackTrace();
}
 
return p;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/action/NouvelleConnexionAction.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
31,7 → 31,6
import org.openconcerto.erp.modules.ModuleManager;
import org.openconcerto.erp.panel.ComptaTipsFrame;
import org.openconcerto.erp.preferences.GestionClientPreferencePanel;
import org.openconcerto.erp.rights.DepotStockViewRightEditor;
import org.openconcerto.erp.rights.GroupUIComboRightEditor;
import org.openconcerto.erp.rights.MenuComboRightEditor;
import org.openconcerto.erp.utils.NXDatabaseAccessor;
198,11 → 197,9
MenuComboRightEditor.register();
GroupUIComboRightEditor.register();
SQLTableRightEditor.register();
DepotStockViewRightEditor.register();
// even for quick login, check the license before displaying the main
// frame
 
 
MutableListComboPopupListener.setLockOverridable(rights.isSuperUser());
 
StatusPanel.getInstance().fireStatusChanged();
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/DevisEltCmdEltSQLInjector.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/CommandeFactureClientSQLInjector.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
32,9 → 32,6
if (tableCommande.contains("ID_TAXE_PORT")) {
map(tableCommande.getField("ID_TAXE_PORT"), tableFacture.getField("ID_TAXE_PORT"));
}
if (tableCommande.contains("T_ACOMPTE")) {
map(tableCommande.getField("T_ACOMPTE"), tableFacture.getField("T_ACOMPTE"));
}
if (tableCommande.contains("PORT_HT")) {
map(tableCommande.getField("PORT_HT"), tableFacture.getField("PORT_HT"));
}
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/CommandeBlSQLInjector.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
72,10 → 72,7
if (getSource().getTable().contains("ID_CATEGORIE_COMPTABLE") && getDestination().getTable().contains("ID_CATEGORIE_COMPTABLE")) {
map(getSource().getField("ID_CATEGORIE_COMPTABLE"), getDestination().getField("ID_CATEGORIE_COMPTABLE"));
}
if (getSource().contains("ID_COMMERCIAL") && getDestination().contains("ID_COMMERCIAL")) {
map(getSource().getField("ID_COMMERCIAL"), getDestination().getField("ID_COMMERCIAL"));
}
}
 
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/CommandeFactureEltSQLInjector.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
20,9 → 20,7
public CommandeFactureEltSQLInjector(final DBRoot root) {
super(root, "COMMANDE_CLIENT_ELEMENT", "SAISIE_VENTE_FACTURE_ELEMENT", false);
createDefaultMap();
if (getSource().contains("QTE_LIVREE") && getDestination().contains("QTE_LIVREE")) {
remove(getSource().getField("QTE_LIVREE"), getDestination().getField("QTE_LIVREE"));
}
if (getDestination().contains("ID_COMMANDE_CLIENT_ELEMENT")) {
map(getSource().getKey(), getDestination().getField("ID_COMMANDE_CLIENT_ELEMENT"));
}
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/BonReceptionFactureFournisseurSQLInjector.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
45,13 → 45,6
@Override
protected void merge(SQLRowAccessor srcRow, SQLRowValues rowVals) {
super.merge(srcRow, rowVals);
SQLRowAccessor rowFournisseur = srcRow.getNonEmptyForeign("ID_FOURNISSEUR");
if (rowFournisseur != null) {
SQLRowAccessor rowCompte = rowFournisseur.getNonEmptyForeign("ID_COMPTE_PCE_CHARGE");
if (rowCompte != null) {
rowVals.put("ID_COMPTE_PCE", rowCompte.getID());
}
}
 
// Merge elements
final SQLTable tableElementSource = getSource().getTable("BON_RECEPTION_ELEMENT");
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/PDFAttachment.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationXML.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
257,21 → 257,16
lastColumn = sheet.resolveHint(oLastColTmp.toString() + 1).x + 1;
}
 
int firstLine = Integer.parseInt(tableau.getAttributeValue("firstLine"));
int endLine = Integer.parseInt(tableau.getAttributeValue("endLine"));
Object printRangeObj = sheet.getPrintRanges();
Map<String, Map<Integer, String>> mapStyle = searchStyle(sheet, lastColumn, endPageLine);
 
final Map<String, Map<Integer, String>> mapStyle;
 
if (tableau.getAttributeValue("table").equalsIgnoreCase("TVA")) {
mapStyle = null;
fillTaxeDocumentMap(tableau, sheet, false);
fillTaxeDocumentMap(tableau, sheet, mapStyle, false);
return;
} else {
mapStyle = searchStyle(sheet, firstLine, lastColumn, endLine);
}
 
int nbPage = fillTable(tableau, row, sheet, mapStyle, true, rowLanguage);
int firstLine = Integer.parseInt(tableau.getAttributeValue("firstLine"));
int endLine = Integer.parseInt(tableau.getAttributeValue("endLine"));
Object printRangeObj = sheet.getPrintRanges();
 
System.err.println("Nombre de page == " + nbPage);
if (nbPage == 1) {
286,9 → 281,10
range[i] = string.subSequence(string.indexOf('.') + 1, string.length()).toString();
}
 
int rowEnd = -1;
if (range.length > 1) {
int rowEnd = sheet.resolveHint(range[1]).y + 1;
int rowEndNew = rowEnd * nbPage;
rowEnd = sheet.resolveHint(range[1]).y + 1;
int rowEndNew = rowEnd * (nbPage);
String sNew = s.replaceAll(String.valueOf(rowEnd), String.valueOf(rowEndNew));
sheet.setPrintRanges(sNew);
System.err.println(" ****** Replace print ranges; Old:" + rowEnd + "--" + s + " New:" + rowEndNew + "--" + sNew);
756,7 → 752,7
return nbCellule;
}
 
private void fillTaxeDocumentMap(Element tableau, Sheet sheet, boolean test) {
private void fillTaxeDocumentMap(Element tableau, Sheet sheet, Map<String, Map<Integer, String>> mapStyle, boolean test) {
 
int line = Integer.parseInt(tableau.getAttributeValue("firstLine"));
List<Element> listElts = tableau.getChildren("element");
896,13 → 892,7
 
// on divise en 2 cellules si il y a des retours à la ligne
if (controleMultiline && value != null && value.toString().indexOf('\n') >= 0) {
String[] values;
if (cell.getRowsSpanned() < 2) {
// TODO : mettre une option pour splitter ou pas
values = value.toString().split("\n");
} else {
values = new String[] { value.toString() };
}
String[] values = value.toString().split("\n");
 
Point p = sheet.resolveHint(location);
int y = 0;
1040,7 → 1030,7
/**
* parcourt l'ensemble de la feuille pour trouver les style définit
*/
private Map<String, Map<Integer, String>> searchStyle(Sheet sheet, int rowDeb, int colEnd, int rowEnd) {
private Map<String, Map<Integer, String>> searchStyle(Sheet sheet, int colEnd, int rowEnd) {
 
if (cacheStyle.get(sheet) != null) {
return cacheStyle.get(sheet);
1053,10 → 1043,8
System.err.println("End column search : " + columnCount);
 
int rowCount = (rowEnd > 0) ? rowEnd : sheet.getRowCount();
int start = (rowDeb - 1 > 0) ? rowDeb - 1 : 0;
 
System.err.println("End row search : " + rowCount);
for (int i = start; i < rowCount; i++) {
for (int i = 0; i < rowCount; i++) {
int x = 0;
Map<Integer, String> mapCellStyle = new HashMap<>();
String style = "";
1131,13 → 1119,12
 
Object oLastColTmp = tableau.getAttributeValue("lastColumn");
int lastColumn = -1;
int endPageLine = Integer.parseInt(tableau.getAttributeValue("endPageLine"));
if (oLastColTmp != null) {
lastColumn = sheet.resolveHint(oLastColTmp.toString() + 1).x + 1;
}
int firstLine = Integer.parseInt(tableau.getAttributeValue("firstLine"));
int endLine = Integer.parseInt(tableau.getAttributeValue("endLine"));
 
Map<String, Map<Integer, String>> mapStyle = searchStyle(sheet, firstLine, lastColumn, endLine);
Map<String, Map<Integer, String>> mapStyle = searchStyle(sheet, lastColumn, endPageLine);
 
int nbPage = fillTable(tableau, row, sheet, mapStyle, true, rowLanguage);
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLTableElement.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
83,20 → 83,47
}
 
public List<? extends SQLRowAccessor> getRows() {
String foreignTableName = this.tableau.getAttributeValue("table");
SQLTable tableElt = Configuration.getInstance().getRoot().findTable(this.tableau.getAttributeValue("table"));
 
SQLTable tableElt = null;
if (!this.row.isEmpty()) {
SQLTable tableRow = this.row.get(0).getTable();
if (tableRow.getDBRoot().contains(foreignTableName)) {
tableElt = tableRow.getDBRoot().getTable(foreignTableName);
} else {
tableElt = Configuration.getInstance().getRoot().findTable(foreignTableName);
}
}
 
if (tableElt != null) {
 
// // #if gestionnx
// Set<SQLField> fields =
// tablePourcentService.getForeignKeys(tableElt);
//
// if (((ComptaPropsConfiguration)
// Configuration.getInstance()).customerIsPreventec() && fields !=
// null && fields.size() > 0) {
// SQLSelect sel = new
// SQLSelect(Configuration.getInstance().getBase());
//
// sel.addSelectStar(tableElt);
// Set<SQLField> fieldsElt =
// tableElt.getForeignKeys(this.row.getTable());
// Where w = new Where(fieldsElt.iterator().next(), "=",
// this.row.getTable().getKey());
// w = w.and(new Where(fields.iterator().next(), "=",
// tableElt.getKey()));
// w = w.and(new Where(this.row.getTable().getKey(), "=",
// this.row.getID()));
// sel.setWhere(w);
// sel.addFieldOrder(tablePourcentService.getField("ID_VERIFICATEUR"));
// sel.addFieldOrder(fields.iterator().next());
// List<SQLRow> l = (List<SQLRow>)
// Configuration.getInstance().getBase().getDataSource().execute(sel.asString(),
// SQLRowListRSH.createFromSelect(sel, tableElt));
//
// // Suppression des doublons
// List<SQLRow> list = new ArrayList<SQLRow>();
// for (SQLRow sqlRow : l) {
// if (!list.contains(sqlRow)) {
// list.add(sqlRow);
// }
// }
// return list;
// }
// // #endif
 
return cache.getReferentRows(this.row, tableElt, this.tableau.getAttributeValue("groupBy"), this.tableau.getAttributeValue("orderBy"),
Boolean.valueOf(this.tableau.getAttributeValue("expandNomenclature")), this.tableau.getAttributeValue("foreignField"),
Boolean.valueOf(this.tableau.getAttributeValue("excludeZeroQty")));
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationListeColumnXML.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
152,8 → 152,49
}
Map<String, Map<Integer, String>> mapStyle = searchStyle(sheet, lastColumn, endPageLine);
// int nbPage = fillTable(tableau, liste, sheet, mapStyle, true, style);
// int firstLine = Integer.valueOf(tableau.getAttributeValue("firstLine"));
// int endLine = Integer.valueOf(tableau.getAttributeValue("endLine"));
// Object printRangeObj = sheet.getPrintRanges();
//
// System.err.println("Nombre de page == " + nbPage);
// if (nbPage == 1) {
// fillTable(tableau, liste, sheet, mapStyle, false, style);
// } else {
//
// if (printRangeObj != null) {
// String s = printRangeObj.toString();
// String[] range = s.split(":");
//
// for (int i = 0; i < range.length; i++) {
// String string = range[i];
// range[i] = string.subSequence(string.indexOf('.') + 1, string.length()).toString();
// }
//
// int rowEnd = -1;
// if (range.length > 1) {
// rowEnd = sheet.resolveHint(range[1]).y + 1;
// int rowEndNew = rowEnd * (nbPage + 1);
// String sNew = s.replaceAll(String.valueOf(rowEnd), String.valueOf(rowEndNew));
// sheet.setPrintRanges(sNew);
// System.err.println(" ****** Replace print ranges; Old:" + rowEnd + "--" + s + " New:" +
// rowEndNew + "--" + sNew);
// }
// }
//
// // le nombre d'éléments ne tient pas dans le tableau du modéle
// sheet.duplicateFirstRows(endLine, 1);
//
// int lineToAdd = endPageLine - endLine;
// sheet.insertDuplicatedRows(firstLine, lineToAdd);
//
// // On duplique la premiere page si on a besoin de plus de deux pages
// System.err.println("nbPage == " + nbPage);
// if (nbPage > 2) {
// sheet.duplicateFirstRows(endPageLine, nbPage - 2);
// }
fillTable(tableau, liste, sheet, mapStyle, false, style);
// }
}
 
/**
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLElement.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
129,10 → 129,6
if (rmBreakLines) {
res = (res == null ? res : res.toString().replaceAll("\n", ","));
}
final String brk = this.elt.getAttributeValue("replaceWithBreakLine");
if (brk != null && brk.trim().length() > 0) {
res = (res == null ? res : res.toString().replaceAll(brk, "\n"));
}
return res;
}
 
149,24 → 145,8
 
protected String getStringProposition(SQLRowAccessor rowProp) {
 
if (rowProp.getTable().getName().equalsIgnoreCase("AFFAIRE")) {
final SQLRowAccessor nonEmptyForeignProp = rowProp.getNonEmptyForeign("ID_PROPOSITION");
String result = "";
if (rowProp.getString("NUMERO_PROPOSITION").trim().length() > 0) {
return "Notre proposition " + rowProp.getString("NUMERO_PROPOSITION");
}
if (nonEmptyForeignProp != null && !nonEmptyForeignProp.isUndefined()) {
if (result.length() == 0) {
result = "Notre proposition " + nonEmptyForeignProp.getString("NUMERO_PROPOSITION");
}
result += " du " + format.format(rowProp.getObject("DATE"));
}
return result;
} else {
 
return "Notre proposition " + rowProp.getString("NUMERO") + " du " + format.format(rowProp.getObject("DATE"));
}
}
 
 
public Double getTotalHTTable(SQLRowAccessor rowFact) {
235,8 → 215,4
public boolean isImage() {
return this.elt.getAttributeValue("type").equalsIgnoreCase("image");
}
 
public SQLElement getSQLElement() {
return this.sqlElt;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/QteLineDocProvider.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/QteTotalLineDocProvider.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/QteTotalProvider.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
31,7 → 31,7
 
BigDecimal pv = row.getBigDecimal("PV_HT");
 
if (pv != null && pv.compareTo(BigDecimal.ZERO) == 0) {
if (pv.compareTo(BigDecimal.ZERO) == 0) {
return null;
} else {
return result;
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/PaiementRemainedProvider.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
65,7 → 65,6
long total = totalEch;
if (t == Type.DONE) {
total = r.getLong("T_TTC") - total;
//TODO deduire T avoir
}
return new BigDecimal(total).movePointLeft(2);
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/FormatedGlobalQtyTotalProvider.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
27,7 → 27,7
private final boolean shortName, alwaysShowOnZeroQty, pieceName;
 
public static enum Type {
NORMAL, SHIPMENT, REMAIND
NORMAL, SHIPMENT
}
 
public final Type type;
46,34 → 46,16
public Object getValue(SpreadSheetCellValueContext context) {
final SQLRowAccessor row = context.getRow();
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (!this.alwaysShowOnZeroQty && pv != null && pv.compareTo(BigDecimal.ZERO) == 0) {
if (!this.alwaysShowOnZeroQty && pv.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
 
final String field;
if (this.type == Type.NORMAL) {
field = "QTE";
} else if (row.getTable().contains("QTE_LIVREE")) {
field = "QTE_LIVREE";
} else if (row.getTable().contains("QTE_ORIGINE")) {
field = "QTE_ORIGINE";
} else {
return null;
}
final String field = this.type == Type.NORMAL ? "QTE" : "QTE_LIVREE";
if (row.getObject(field) == null) {
return null;
}
 
int qte = row.getInt(field);
if (this.type == Type.REMAIND) {
if (row.getObject("QTE") != null) {
if (field.equalsIgnoreCase("QTE_ORIGINE")) {
qte = qte - row.getInt("QTE");
} else {
qte = row.getInt("QTE") - qte;
}
}
}
final int qte = row.getInt(field);
 
if (!this.pieceName && row.getInt("ID_UNITE_VENTE") == UniteVenteArticleSQLElement.A_LA_PIECE) {
return String.valueOf(qte);
99,15 → 81,10
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.deliver.short", new FormatedGlobalQtyTotalProvider(Type.SHIPMENT, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.deliver", new FormatedGlobalQtyTotalProvider(Type.SHIPMENT, false));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.deliver.short.with.quantity", new FormatedGlobalQtyTotalProvider(Type.SHIPMENT, true, true, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.remainder.short", new FormatedGlobalQtyTotalProvider(Type.REMAIND, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.remainder", new FormatedGlobalQtyTotalProvider(Type.REMAIND, false));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.remainder.short.with.quantity", new FormatedGlobalQtyTotalProvider(Type.REMAIND, true, true, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.alwaysnamed.short.with.quantity", new FormatedGlobalQtyTotalProvider(Type.NORMAL, true, true, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.alwaysnamed.short", new FormatedGlobalQtyTotalProvider(Type.NORMAL, true, false, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.alwaysnamed", new FormatedGlobalQtyTotalProvider(Type.NORMAL, false, false, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.alwaysnamed.deliver.short", new FormatedGlobalQtyTotalProvider(Type.SHIPMENT, true, false, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.alwaysnamed.deliver", new FormatedGlobalQtyTotalProvider(Type.SHIPMENT, false, false, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.alwaysnamed.remainder.short", new FormatedGlobalQtyTotalProvider(Type.REMAIND, true, false, true));
SpreadSheetCellValueProviderManager.put("supplychain.element.qtyunit.alwaysnamed.remainder", new FormatedGlobalQtyTotalProvider(Type.REMAIND, false, false, true));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/PrixUVProvider.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
33,7 → 33,7
public Object getValue(SpreadSheetCellValueContext context) {
final SQLRowAccessor row = context.getRow();
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (pv == null || pv.compareTo(BigDecimal.ZERO) == 0) {
if (pv.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
String result = decimalFormat.format(pv);
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/AdresseFullClientValueProvider.java
21,12 → 21,10
 
private final int type;
private final boolean withName;
private final boolean noCountry;
 
public AdresseFullClientValueProvider(int type, boolean withName, boolean noCountry) {
public AdresseFullClientValueProvider(int type, boolean withName) {
this.type = type;
this.withName = withName;
this.noCountry = noCountry;
}
 
@Override
34,32 → 32,25
final SQLRowAccessor r = getAdresse(context.getRow(), this.type);
String result = "";
if (this.withName) {
result = context.getRow().getForeign("ID_CLIENT").getString("NOM") + "\n\n";
result = context.getRow().getForeign("ID_CLIENT").getString("NOM") + "\n";
}
result = getFormattedAddress(r, result, !this.noCountry);
result = getFormattedAddress(r, result);
 
return result;
}
 
public static String getFormattedAddress(final SQLRowAccessor rAddress, String prefix) {
return getFormattedAddress(rAddress, prefix, true);
}
 
public static String getFormattedAddress(final SQLRowAccessor rAddress, String prefix, boolean withCountry) {
String result = prefix;
boolean notEmptyLib = getStringTrimmed(rAddress, "LIBELLE").length() > 0;
if (notEmptyLib) {
if (getStringTrimmed(rAddress, "LIBELLE").length() > 0) {
result = getStringTrimmed(rAddress, "LIBELLE") + "\n";
}
boolean notEmptyDest = getStringTrimmed(rAddress, "DEST").length() > 0;
if (notEmptyDest) {
if (getStringTrimmed(rAddress, "DEST").length() > 0) {
result = getStringTrimmed(rAddress, "DEST") + "\n";
}
boolean notEmptyRue = getStringTrimmed(rAddress, "RUE").length() > 0;
if (notEmptyRue) {
if (getStringTrimmed(rAddress, "RUE").length() > 0) {
result += getStringTrimmed(rAddress, "RUE") + "\n";
}
result += notEmptyDest && notEmptyLib && notEmptyLib ? ("\n" + getStringTrimmed(rAddress, "CODE_POSTAL")) : getStringTrimmed(rAddress, "CODE_POSTAL");
result += "\n" + getStringTrimmed(rAddress, "CODE_POSTAL");
result += " ";
if (rAddress.getTable().contains("DISTRICT")) {
result += getStringTrimmed(rAddress, "DISTRICT") + " ";
73,23 → 64,17
}
}
if (rAddress.getTable().contains("PROVINCE")) {
String province = getStringTrimmed(rAddress, "PROVINCE");
boolean department = rAddress.getTable().contains("DEPARTEMENT");
if (province.length() > 0 || (department && getStringTrimmed(rAddress, "DEPARTEMENT").length() > 0)) {
result += "\n";
}
if (province.length() > 0) {
 
if (getStringTrimmed(rAddress, "PROVINCE").length() > 0) {
result += getStringTrimmed(rAddress, ("PROVINCE")) + " ";
}
 
if (department && getStringTrimmed(rAddress, "DEPARTEMENT").length() > 0) {
 
if (rAddress.getTable().contains("DEPARTEMENT")) {
result += getStringTrimmed(rAddress, "DEPARTEMENT");
}
}
 
if (withCountry && getStringTrimmed(rAddress, "PAYS").length() > 0) {
if (getStringTrimmed(rAddress, "PAYS").length() > 0) {
result += "\n" + getStringTrimmed(rAddress, "PAYS");
}
return result;
103,17 → 88,11
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("address.customer.full", new AdresseFullClientValueProvider(ADRESSE_PRINCIPALE, false, false));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.full", new AdresseFullClientValueProvider(ADRESSE_FACTURATION, false, false));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.full", new AdresseFullClientValueProvider(ADRESSE_LIVRAISON, false, false));
SpreadSheetCellValueProviderManager.put("address.customer.full.nocountry", new AdresseFullClientValueProvider(ADRESSE_PRINCIPALE, false, true));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.full.nocountry", new AdresseFullClientValueProvider(ADRESSE_FACTURATION, false, true));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.full.nocountry", new AdresseFullClientValueProvider(ADRESSE_LIVRAISON, false, true));
SpreadSheetCellValueProviderManager.put("address.customer.full.withname", new AdresseFullClientValueProvider(ADRESSE_PRINCIPALE, true, false));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.full.withname", new AdresseFullClientValueProvider(ADRESSE_FACTURATION, true, false));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.full.withname", new AdresseFullClientValueProvider(ADRESSE_LIVRAISON, true, false));
SpreadSheetCellValueProviderManager.put("address.customer.full.withname.nocountry", new AdresseFullClientValueProvider(ADRESSE_PRINCIPALE, true, true));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.full.withname.nocountry", new AdresseFullClientValueProvider(ADRESSE_FACTURATION, true, true));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.full.withname.nocountry", new AdresseFullClientValueProvider(ADRESSE_LIVRAISON, true, true));
SpreadSheetCellValueProviderManager.put("address.customer.full", new AdresseFullClientValueProvider(ADRESSE_PRINCIPALE, false));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.full", new AdresseFullClientValueProvider(ADRESSE_FACTURATION, false));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.full", new AdresseFullClientValueProvider(ADRESSE_LIVRAISON, false));
SpreadSheetCellValueProviderManager.put("address.customer.full.withname", new AdresseFullClientValueProvider(ADRESSE_PRINCIPALE, true));
SpreadSheetCellValueProviderManager.put("address.customer.invoice.full.withname", new AdresseFullClientValueProvider(ADRESSE_FACTURATION, true));
SpreadSheetCellValueProviderManager.put("address.customer.shipment.full.withname", new AdresseFullClientValueProvider(ADRESSE_LIVRAISON, true));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/PrixUnitaireProvider.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
29,7 → 29,7
public Object getValue(SpreadSheetCellValueContext context) {
final SQLRowAccessor row = context.getRow();
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (pv == null || pv.compareTo(BigDecimal.ZERO) == 0) {
if (pv.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/MergedGlobalQtyTotalProvider.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
34,9 → 34,8
 
public Object getValue(SpreadSheetCellValueContext context) {
final SQLRowAccessor row = context.getRow();
// FIXME pb si on est dans achat avec le check PV_HT
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (pv != null && pv.compareTo(BigDecimal.ZERO) == 0) {
if (pv.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/provider/PrixUnitaireRemiseProvider.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
13,7 → 13,6
package org.openconcerto.erp.generationDoc.provider;
 
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueContext;
import org.openconcerto.erp.generationDoc.SpreadSheetCellValueProviderManager;
import org.openconcerto.sql.model.SQLRowAccessor;
26,8 → 25,6
 
public static int UNITAIRE_REMISE = 0;
public static int TOTAL_NON_ACOMPTE = 1;
public static int UNITAIRE_REMISE_TTC = 2;
public static int UNITAIRE_TTC = 3;
public final int type;
 
public PrixUnitaireRemiseProvider(int t) {
37,10 → 34,8
@Override
public Object getValue(SpreadSheetCellValueContext context) {
SQLRowAccessor row = context.getRow();
if (this.type == UNITAIRE_REMISE || this.type == UNITAIRE_REMISE_TTC) {
return getPrixUnitaire(row, true);
} else if (this.type == UNITAIRE_TTC) {
return getPrixUnitaire(row, false);
if (this.type == UNITAIRE_REMISE) {
return getPrixUnitaire(row);
} else {
return getPrixTotalOrigin(row);
}
48,11 → 43,8
 
public Object getPrixTotalOrigin(SQLRowAccessor row) {
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (pv == null) {
return null;
}
BigDecimal remise = (BigDecimal) row.getObject("POURCENT_REMISE");
if (pv == null || remise == null) {
if (remise == null) {
remise = BigDecimal.ZERO;
}
BigDecimal acompte = BigDecimal.ONE;
62,13 → 54,10
return result.multiply(row.getBigDecimal("QTE_UNITAIRE")).multiply(new BigDecimal(row.getInt("QTE"))).setScale(2, RoundingMode.HALF_UP);
}
 
public Object getPrixUnitaire(SQLRowAccessor row, boolean withRemise) {
public Object getPrixUnitaire(SQLRowAccessor row) {
final BigDecimal pv = row.getBigDecimal("PV_HT");
if (pv == null) {
return null;
}
BigDecimal remise = (BigDecimal) row.getObject("POURCENT_REMISE");
if (remise == null || !withRemise) {
if (remise == null) {
remise = BigDecimal.ZERO;
}
BigDecimal acompte = BigDecimal.ONE;
77,19 → 66,11
}
BigDecimal result = BigDecimal.ONE.subtract(remise.movePointLeft(2)).multiply(pv, DecimalUtils.HIGH_PRECISION).multiply(acompte, DecimalUtils.HIGH_PRECISION);
 
if (this.type == UNITAIRE_REMISE_TTC) {
float t = TaxeCache.getCache().getTauxFromId(row.getForeignID("ID_TAXE"));
result = result.multiply(new BigDecimal(t).movePointLeft(2).add(BigDecimal.ONE));
return result.setScale(2, RoundingMode.HALF_UP);
}
 
final BigDecimal setScale = result.setScale(2, RoundingMode.HALF_UP);
return setScale;
}
 
public static void register() {
SpreadSheetCellValueProviderManager.put("PrixUnitaireTTC", new PrixUnitaireRemiseProvider(UNITAIRE_TTC));
SpreadSheetCellValueProviderManager.put("PrixUnitaireRemise", new PrixUnitaireRemiseProvider(UNITAIRE_REMISE));
SpreadSheetCellValueProviderManager.put("PrixUnitaireRemiseTTC", new PrixUnitaireRemiseProvider(UNITAIRE_REMISE_TTC));
SpreadSheetCellValueProviderManager.put("PrixTotalSansAcompte", new PrixUnitaireRemiseProvider(TOTAL_NON_ACOMPTE));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationListeXML.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
182,12 → 182,13
range[i] = string.subSequence(string.indexOf('.') + 1, string.length()).toString();
}
 
int rowEnd = -1;
if (range.length > 1) {
int rowEnd = sheet.resolveHint(range[1]).y + 1;
int rowEndNew = rowEnd * nbPage;
rowEnd = sheet.resolveHint(range[1]).y + 1;
int rowEndNew = rowEnd * (nbPage + 1);
String sNew = s.replaceAll(String.valueOf(rowEnd), String.valueOf(rowEndNew));
sheet.setPrintRanges(sNew);
System.err.println("OOgenerationListXML ****** Replace print ranges; Old:" + rowEnd + "--" + s + " New:" + rowEndNew + "--" + sNew);
System.err.println(" ****** Replace print ranges; Old:" + rowEnd + "--" + s + " New:" + rowEndNew + "--" + sNew);
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLCache.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
134,18 → 134,10
} else {
for (SQLRowAccessor rowAccess : row) {
if (rowAccess != null && !rowAccess.isUndefined()) {
final Object[] array = tableForeign.getForeignKeys(rowAccess.getTable()).toArray();
final SQLField field1;
if (array == null || array.length == 0) {
field1 = tableForeign.getField("ID_" + tableForeign.getName().replaceAll("_ELEMENT", ""));
} else {
 
field1 = (SQLField) array[0];
}
if (w == null) {
w = new Where(field1, "=", rowAccess.getID());
w = new Where((SQLField) tableForeign.getForeignKeys(rowAccess.getTable()).toArray()[0], "=", rowAccess.getID());
} else {
w = w.or(new Where(field1, "=", rowAccess.getID()));
w = w.or(new Where((SQLField) tableForeign.getForeignKeys(rowAccess.getTable()).toArray()[0], "=", rowAccess.getID()));
}
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SpreadSheetGeneratorCompta.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
71,10 → 71,7
System.err.println("Set Column Count to :: " + (colEnd + 1));
sheet.setColumnCount(colEnd + 1);
}
if (this.nbPage < 1) {
throw new IllegalArgumentException("invalid page count : " + this.nbPage);
}
sheet.duplicateFirstRows(this.nbRowsPerPage, this.nbPage - 1);
sheet.duplicateFirstRows(this.nbRowsPerPage, this.nbPage);
 
Object printRangeObj = sheet.getPrintRanges();
if (printRangeObj != null) {
85,12 → 82,13
range2[i] = string.subSequence(string.indexOf('.') + 1, string.length()).toString();
}
 
int end = -1;
if (range2.length > 1) {
int end = sheet.resolveHint(range2[1]).y + 1;
int rowEndNew = end * this.nbPage;
end = sheet.resolveHint(range2[1]).y + 1;
long rowEndNew = end * (this.nbPage + 1);
String sNew = s.replaceAll(String.valueOf(end), String.valueOf(rowEndNew));
sheet.setPrintRanges(sNew);
System.err.println("SpreadSheetGenerator ****** Replace print ranges; Old:" + end + "--" + s + " New:" + rowEndNew + "--" + sNew);
System.err.println(" ****** Replace print ranges; Old:" + end + "--" + s + " New:" + rowEndNew + "--" + sNew);
}
} else {
sheet.removePrintRanges();
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetXml.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
15,12 → 15,9
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.ui.PreviewFrame;
import org.openconcerto.erp.core.customerrelationship.mail.EmailTemplate;
import org.openconcerto.erp.core.customerrelationship.mail.ValueListener;
import org.openconcerto.erp.core.sales.invoice.report.VenteFactureXmlSheet;
import org.openconcerto.erp.core.sales.quote.report.PaypalStamper;
import org.openconcerto.erp.generationDoc.element.TypeModeleSQLElement;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
import org.openconcerto.erp.preferences.PayPalPreferencePanel;
import org.openconcerto.erp.storage.CloudStorageEngine;
import org.openconcerto.erp.storage.StorageEngine;
28,21 → 25,13
import org.openconcerto.openoffice.OOUtils;
import org.jopendocument.link.Component;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.Action;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.i18n.Grammar;
import org.openconcerto.utils.i18n.TranslationManager;
 
import java.awt.GraphicsEnvironment;
import java.awt.print.PrinterJob;
60,9 → 49,7
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
153,19 → 140,15
return this.elt;
}
 
public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF) {
return showPrintAndExportAsynchronous(showDocument, printDocument, exportToPDF, Collections.emptyList());
}
 
/**
* Show, print and export the document to PDF. This method is asynchronous, but is executed in a
* single threaded queue shared with createDocument
*/
public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF, List<Action> actions) {
public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF) {
final Callable<SheetXml> c = new Callable<SheetXml>() {
@Override
public SheetXml call() throws Exception {
showPrintAndExport(showDocument, printDocument, exportToPDF, actions);
showPrintAndExport(showDocument, printDocument, exportToPDF);
return SheetXml.this;
}
};
173,55 → 156,6
 
}
 
public Future<SheetXml> showPrintAndExportAsynchronous(final boolean showDocument, final boolean printDocument, final boolean exportToPDF, final SQLElement element, SQLRow row) {
final Callable<SheetXml> c = new Callable<SheetXml>() {
 
@Override
public SheetXml call() throws Exception {
final List<Action> actions = new ArrayList<>();
if (SheetXml.this instanceof AbstractSheetXml) {
final SQLTable table = element.getTable();
final Action emailAction = new Action(TranslationManager.getInstance().getTranslationForAction("document.pdf.send.email")) {
 
@Override
public void run(Object source) {
EmailTemplate.askTemplate(null, table.getDBRoot(), new ValueListener() {
 
@Override
public void valueSelected(Object value) {
final MouseSheetXmlListeListener l = new MouseSheetXmlListeListener(element, ((AbstractSheetXml) SheetXml.this).getClass());
l.sendMail((EmailTemplate) value, (AbstractSheetXml) SheetXml.this, true);
}
});
 
}
};
actions.add(emailAction);
}
final Action modifyAction = new Action(TranslationManager.getInstance().getTranslationForAction("modify") + " " + element.getName().getVariant(Grammar.DEFINITE_ARTICLE_SINGULAR)) {
 
@Override
public void run(Object source) {
if (source instanceof PreviewFrame) {
((PreviewFrame) source).dispose();
}
 
final SQLComponent component = element.createDefaultComponent();
final EditFrame f = new EditFrame(component, EditMode.MODIFICATION);
f.selectionId(row.getID());
FrameUtil.show(f);
 
}
};
actions.add(modifyAction);
showPrintAndExport(showDocument, printDocument, exportToPDF, actions);
return SheetXml.this;
}
};
return runnableQueue.submit(c);
 
}
 
public static Future<?> submitInQueue(final Runnable r) {
 
return runnableQueue.submit(r);
228,21 → 162,13
}
 
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF) {
showPrintAndExport(showDocument, printDocument, exportToPDF, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"), false, Collections.emptyList());
showPrintAndExport(showDocument, printDocument, exportToPDF, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"), false);
}
 
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, List<Action> actions) {
showPrintAndExport(showDocument, printDocument, exportToPDF, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"), false, actions);
}
 
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, boolean useODSViewer, boolean exportPDFSynch) {
showPrintAndExport(showDocument, printDocument, exportToPDF, useODSViewer, exportPDFSynch, Collections.emptyList());
}
 
/**
* Show, print and export the document to PDF. This method is synchronous
*/
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, boolean useODSViewer, boolean exportPDFSynch, List<Action> actions) {
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, boolean useODSViewer, boolean exportPDFSynch) {
 
final File generatedFile = getGeneratedFile();
final File pdfFile = getGeneratedPDFFile();
274,7 → 200,7
final OpenDocument doc = new OpenDocument(generatedFile);
 
if (showDocument) {
showPreviewDocument(actions);
showPreviewDocument();
}
if (printDocument) {
// Print !
336,17 → 262,88
throw new IllegalArgumentException("null PDF file");
}
try {
if (VenteFactureXmlSheet.TEMPLATE_ID.equals(getDefaultTemplateId())) {
final SQLPreferences prefs = SQLPreferences.getMemCached(getElement().getTable().getDBRoot());
if (prefs.getBoolean(PayPalPreferencePanel.PAYPAL_INVOICE, false)) {
try {
final File inFile = File.createTempFile("oc_", pdfFile.getName());
SheetUtils.convert2PDF(doc, inFile);
PaypalStamper s = new PaypalStamper();
int x = prefs.getInt(PayPalPreferencePanel.PAYPAL_INVOICE_X, 0);
int y = prefs.getInt(PayPalPreferencePanel.PAYPAL_INVOICE_Y, 0);
 
// Reference
String ref = getSQLRow().getString("NUMERO");
// Montant : ex : 10.55
long cents = getSQLRow().getLong("NET_A_PAYER");
String amount = cents / 100 + "." + cents % 100;
// Devise
// TODO : autres devises
String currency = "EUR";
// POST
final URL url = new URL("https://cloud.openconcerto.org/payment");
final URLConnection con = url.openConnection();
final HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setDefaultUseCaches(false);
 
String hyperlink = null;
// x-www-form-urlencoded
final Map<String, String> arguments = new HashMap<>();
arguments.put("pI", prefs.get(PayPalPreferencePanel.PAYPAL_CLIENTID, ""));
arguments.put("pS", prefs.get(PayPalPreferencePanel.PAYPAL_SECRET, ""));
arguments.put("ref", ref);
arguments.put("amount", amount);
arguments.put("currency", currency);
arguments.put("type", "paypal");
final StringJoiner sj = new StringJoiner("&");
for (Map.Entry<String, String> entry : arguments.entrySet()) {
sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8"));
}
final String postData = sj.toString();
System.err.println("SheetXml.createPDF() " + postData);
byte[] out = postData.getBytes(StandardCharsets.UTF_8);
int length = out.length;
http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.connect();
try (OutputStream os = http.getOutputStream()) {
os.write(out);
}
if (http.getResponseCode() != 401) {
 
InputStream is = http.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
 
int numCharsRead;
char[] charArray = new char[1024];
StringBuilder sb = new StringBuilder();
while ((numCharsRead = isr.read(charArray)) > 0) {
sb.append(charArray, 0, numCharsRead);
}
//
hyperlink = sb.toString();
}
s.addLink(inFile, pdfFile, x, y, hyperlink);
} catch (Exception e) {
e.printStackTrace();
SheetUtils.convert2PDF(doc, pdfFile);
} catch (Exception e) {
}
 
} else {
SheetUtils.convert2PDF(doc, pdfFile);
}
} else {
SheetUtils.convert2PDF(doc, pdfFile);
}
 
} catch (Throwable e) {
ExceptionHandler.handle("Impossible de créer le PDF " + pdfFile.getAbsolutePath(), e);
}
if (!pdfFile.canRead()) {
ExceptionHandler.handle("Le fichier PDF " + pdfFile.getAbsolutePath() + " ne peut être lu.");
}
storeWithStorageEngines(generatedFile, pdfFile, storagePath);
}
 
protected void storeWithStorageEngines(final File generatedFile, final File pdfFile, String storagePath) {
List<StorageEngine> engines = StorageEngines.getInstance().getActiveEngines();
for (StorageEngine storageEngine : engines) {
if (storageEngine.isConfigured() && storageEngine.allowAutoStorage()) {
493,12 → 490,12
File f = getGeneratedPDFFile();
if (!f.exists()) {
getOrCreateDocumentFile();
showPrintAndExport(false, false, true, useODSViewer, true, Collections.emptyList());
showPrintAndExport(false, false, true, useODSViewer, true);
return f;
} else {
File fODS = getOrCreateDocumentFile();
if (fODS.lastModified() > f.lastModified()) {
showPrintAndExport(false, false, true, useODSViewer, true, Collections.emptyList());
showPrintAndExport(false, false, true, useODSViewer, true);
}
return f;
}
550,13 → 547,13
}
 
public void showPreviewDocument() throws Exception {
showPreviewDocument(Collections.emptyList());
showPreviewDocument(null, null);
}
 
public void showPreviewDocument(List<Action> actions) throws Exception {
public void showPreviewDocument(String actionName, Runnable r) throws Exception {
File f = null;
f = getOrCreateDocumentFile();
PreviewFrame.show(f, actions);
PreviewFrame.show(f, actionName, r);
}
 
public void printDocument() {
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetUtils.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
19,22 → 19,15
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.FileUtils;
 
import java.awt.Color;
import java.awt.Desktop;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
41,13 → 34,9
 
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix;
import org.jopendocument.model.OpenDocument;
150,12 → 139,7
}
 
public static void convert2PDF(final OpenDocument doc, final File pdfFileToCreate) throws Exception {
convert2PDF(doc, pdfFileToCreate, Collections.emptyList());
}
 
public static void convert2PDF(final OpenDocument doc, final File pdfFileToCreate, final List<PDFAttachment> attachments) throws Exception {
assert (!SwingUtilities.isEventDispatchThread());
System.out.println("SheetUtils convert2PDF " + doc.getLoadedFile().getAbsolutePath() + " -> " + pdfFileToCreate.getAbsolutePath());
try {
PDDocument document = new PDDocument();
PDDocumentInformation info = new PDDocumentInformation();
165,29 → 149,8
info.setModificationDate(Calendar.getInstance());
document.setDocumentInformation(info);
 
// Attachments
final PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode();
final Map<String, PDComplexFileSpecification> efMap = new HashMap<>();
for (final PDFAttachment att : attachments) {
// first create the file specification, which holds the embedded file
final PDComplexFileSpecification fs = new PDComplexFileSpecification();
fs.setFile(att.getFileName());
final InputStream is = new ByteArrayInputStream(att.getBytes());
final PDEmbeddedFile ef = new PDEmbeddedFile(document, is);
// set some of the attributes of the embedded file
ef.setSubtype(att.getMimetype());
ef.setSize(att.getBytes().length);
ef.setCreationDate(new GregorianCalendar());
fs.setEmbeddedFile(ef);
efMap.put(att.getName(), fs);
}
FileOutputStream fileOutputStream = new FileOutputStream(pdfFileToCreate);
 
efTree.setNames(efMap);
// attachments are stored as part of the "names" dictionary in the document catalog
final PDDocumentNameDictionary names = new PDDocumentNameDictionary(document.getDocumentCatalog());
names.setEmbeddedFiles(efTree);
document.getDocumentCatalog().setNames(names);
 
PdfBoxGraphics2DFontTextDrawer fontTextDrawer = new PdfBoxGraphics2DFontTextDrawerDefaultFonts();
final File dir = new File("Fonts");
if (dir.exists()) {
206,24 → 169,23
// Configure the renderer
ODTRenderer renderer = new ODTRenderer(doc);
renderer.setIgnoreMargins(false);
renderer.setResizeFactor(100);
renderer.setPaintMaxResolution(true);
PDRectangle pageSize = PDRectangle.A4;
 
// Scale the renderer to fit width or height
final double widthFactor = renderer.getPrintWidth() / pageSize.getWidth();
final double heightFactor = renderer.getPrintHeight() / pageSize.getHeight();
final int resizeFactor = (int) Math.ceil(Math.max(widthFactor, heightFactor));
renderer.setResizeFactor(resizeFactor);
renderer.setResizeFactor(Math.max(widthFactor, heightFactor));
 
// Print pages
for (int i = 0; i < renderer.getPrintedPagesNumber(); i++) {
final PDPage page = new PDPage(pageSize);
PDPage page = new PDPage(pageSize);
document.addPage(page);
PdfBoxGraphics2D g2 = new PdfBoxGraphics2D(document, pageSize.getWidth(), pageSize.getHeight());
g2.setFontTextDrawer(fontTextDrawer);
 
// centrage horizontal, alignement vertical en haut
final double hMargin = (pageSize.getWidth() - renderer.getPageWidthInPixel()) / 2.0;
g2.translate(hMargin, 0);
g2.translate((PageSize.A4.getWidth() - renderer.getPrintWidthInPixel()) / 2.0, 0);
 
// Render
renderer.setCurrentPage(i);
237,9 → 199,8
contentStream.transform(matrix);
contentStream.drawForm(xform);
contentStream.close();
 
}
document.save(pdfFileToCreate);
document.save(fileOutputStream);
// Close the PDF document
document.close();
 
265,12 → 226,4
final File f = new File(file.getParent(), name);
return f;
}
 
public static void main(String[] args) throws Exception {
// final OpenDocument doc = new OpenDocument(new File("Documents/Facture_FACT128.ods"));
final OpenDocument doc = new OpenDocument(new File("../ODSViewer/documents/bug_marges_pdf/Devis.ods"));
final File file = new File("out.pdf");
convert2PDF(doc, file);
Desktop.getDesktop().open(file);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/OptionDocProcessor.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/ReleveChequeEmisSheet.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
83,6 → 83,5
 
// Total
this.mCell.put("L45", new Double(GestionDevise.currencyToString(montantTotal, false)));
this.nbPage = 1;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/AvoirClientXmlSheet.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
38,7 → 38,6
super(row);
this.printer = PrinterNXProps.getInstance().getStringProperty("BonPrinter");
this.elt = Configuration.getInstance().getDirectory().getElement("AVOIR_CLIENT");
this.setPostProcess(new OptionDocProcessor());
}
 
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/EtatVentesXmlSheet.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
30,7 → 30,6
import org.openconcerto.sql.model.SQLSelectJoin;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.utils.ListMap;
import org.openconcerto.utils.Tuple2;
 
import java.math.BigDecimal;
147,19 → 146,13
// Stock
SQLRowValues rowValsArtStock = new SQLRowValues(foreignTableArticle);
rowValsArtStock.putNulls("ID", "CODE", "NOM");
SQLRowValues rowValsStock = new SQLRowValues(tableFactureElement.getTable("STOCK"));
rowValsStock.putNulls("QTE_REEL", "QTE_TH", "QTE_MIN", "QTE_RECEPT_ATTENTE", "QTE_LIV_ATTENTE").put("ID_ARTICLE", rowValsArtStock);
rowValsArtStock.putRowValues("ID_STOCK").putNulls("QTE_REEL", "QTE_TH", "QTE_MIN", "QTE_RECEPT_ATTENTE", "QTE_LIV_ATTENTE");
SQLRowValuesListFetcher fetcherStock = SQLRowValuesListFetcher.create(rowValsArtStock);
List<SQLRowValues> resultStock = fetcherStock.fetch();
 
ListMap<Integer, SQLRowValues> mapStock = new ListMap<>();
Map<Integer, SQLRowValues> mapStock = new HashMap<>();
for (SQLRowValues sqlRowValues : resultStock) {
final Set<SQLRowValues> referentRows = sqlRowValues.getReferentRows(tableFactureElement.getTable("STOCK").getField("ID_ARTICLE"));
for (SQLRowValues sqlRowValues2 : referentRows) {
 
mapStock.add(sqlRowValues.getID(), sqlRowValues2);
mapStock.put(sqlRowValues.getID(), sqlRowValues);
}
}
 
// Requete Pour obtenir les quantités pour chaque type de réglement
SQLSelect sel = new SQLSelect();
331,28 → 324,17
mValuesStock.put("NOM", nom);
mValuesStock.put("QTE", a.qte);
if (mapStock.containsKey(articleID)) {
List<SQLRowValues> rowValsArt = mapStock.get(articleID);
BigDecimal totalTh = BigDecimal.ZERO;
BigDecimal totalReel = BigDecimal.ZERO;
BigDecimal min = BigDecimal.ZERO;
BigDecimal attentR = BigDecimal.ZERO;
BigDecimal attenteL = BigDecimal.ZERO;
for (SQLRowValues rowStock : rowValsArt) {
totalTh = totalTh.add(new BigDecimal(rowStock.getFloat("QTE_TH")));
totalReel = totalReel.add(new BigDecimal(rowStock.getFloat("QTE_REEL")));
min = min.add(new BigDecimal(rowStock.getFloat("QTE_MIN")));
attentR = attentR.add(new BigDecimal(rowStock.getFloat("QTE_RECEPT_ATTENTE")));
attenteL = attenteL.add(new BigDecimal(rowStock.getFloat("QTE_LIV_ATTENTE")));
SQLRowValues rowValsArt = mapStock.get(articleID);
if (rowValsArt.getObject("ID_STOCK") != null && !rowValsArt.isForeignEmpty("ID_STOCK")) {
SQLRowAccessor rowValsStock = rowValsArt.getForeign("ID_STOCK");
mValuesStock.put("QTE_TH", rowValsStock.getObject("QTE_TH"));
mValuesStock.put("QTE_REEL", rowValsStock.getObject("QTE_REEL"));
mValuesStock.put("QTE_MIN", rowValsStock.getObject("QTE_MIN"));
mValuesStock.put("QTE_RECEPT_ATTENTE", rowValsStock.getObject("QTE_RECEPT_ATTENTE"));
mValuesStock.put("QTE_LIV_ATTENTE", rowValsStock.getObject("QTE_LIV_ATTENTE"));
}
 
mValuesStock.put("QTE_TH", totalTh);
mValuesStock.put("QTE_REEL", totalReel);
mValuesStock.put("QTE_MIN", min);
mValuesStock.put("QTE_RECEPT_ATTENTE", attentR);
mValuesStock.put("QTE_LIV_ATTENTE", attenteL);
styleStock.put(listValuesStock.size(), "Normal");
listValuesStock.add(mValuesStock);
 
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLField.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
60,10 → 60,7
this.row = row;
if ((this.row == null || !this.row.getTable().getSchema().getName().equalsIgnoreCase("Common")) && base != null && base.equalsIgnoreCase("COMMON")) {
this.row = ((ComptaPropsConfiguration) Configuration.getInstance()).getRowSociete();
if (!this.row.getString("DATABASE_NAME").equalsIgnoreCase(row.getTable().getDBRoot().getName())) {
this.row = this.row.getTable().getRow(Integer.valueOf(row.getTable().getDBRoot().getName().replaceAll("OpenConcerto", "")));
}
}
if (this.row == null) {
this.row = sqlElt.getTable().getRow(id);
}
533,7 → 530,7
 
private Object getTraduction() {
if (this.rowLanguage == null || this.rowLanguage.isUndefined()) {
return this.row.getObject(this.elt.getAttributeValue("name"));
return null;
}
int id = ReferenceArticleSQLElement.getIdForCNM(row.asRowValues(), false);
SQLTable table = Configuration.getInstance().getBase().getTable("ARTICLE_DESIGNATION");
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieVenteFacture.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
17,7 → 17,6
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.JournalSQLElement;
import org.openconcerto.erp.generationDoc.SheetXml;
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.generationEcritures.provider.AccountingRecordsProvider;
import org.openconcerto.erp.generationEcritures.provider.AccountingRecordsProviderManager;
import org.openconcerto.erp.model.PrixTTC;
141,20 → 140,13
SQLTable tableEchantillon = null;
BigDecimal portHT = BigDecimal.valueOf(saisieRow.getLong("PORT_HT")).movePointLeft(2);
BigDecimal fraisDocHT = BigDecimal.valueOf(saisieRow.getLong("FRAIS_DOCUMENT_HT")).movePointLeft(2);
SQLRow taxeDoc = saisieRow.getNonEmptyForeign("ID_TAXE_FRAIS_DOCUMENT") == null ? TaxeCache.getCache().getFirstTaxe()
: TaxeCache.getCache().getRowFromId(saisieRow.getForeignID("ID_TAXE_FRAIS_DOCUMENT")).asRow();
 
TotalCalculator calc;
SQLRow taxePort = saisieRow.getNonEmptyForeign("ID_TAXE_PORT") == null ? TaxeCache.getCache().getFirstTaxe()
: TaxeCache.getCache().getRowFromId(saisieRow.getForeignID("ID_TAXE_PORT")).asRow();
 
if (clientRow.getTable().contains("ID_COMPTE_PCE_PRODUIT") && !clientRow.isForeignEmpty("ID_COMPTE_PCE_PRODUIT")) {
 
calc = getValuesFromElement(false, false, "T_PV_HT", saisieRow, saisieVFTable.getTable("SAISIE_VENTE_FACTURE_ELEMENT"), portHT, taxePort, fraisDocHT, taxeDoc, tableEchantillon,
clientRow.getForeign("ID_COMPTE_PCE_PRODUIT"));
calc = getValuesFromElement(false, false, "T_PV_HT", saisieRow, saisieVFTable.getTable("SAISIE_VENTE_FACTURE_ELEMENT"), portHT, saisieRow.getForeign("ID_TAXE_PORT"), fraisDocHT,
saisieRow.getForeign("ID_TAXE_FRAIS_DOCUMENT"), tableEchantillon, clientRow.getForeign("ID_COMPTE_PCE_PRODUIT"));
} else {
 
calc = getValuesFromElement(saisieRow, saisieVFTable.getTable("SAISIE_VENTE_FACTURE_ELEMENT"), portHT, taxePort, fraisDocHT, taxeDoc, tableEchantillon);
calc = getValuesFromElement(saisieRow, saisieVFTable.getTable("SAISIE_VENTE_FACTURE_ELEMENT"), portHT, saisieRow.getForeign("ID_TAXE_PORT"), fraisDocHT,
saisieRow.getForeign("ID_TAXE_FRAIS_DOCUMENT"), tableEchantillon);
}
 
// On génére les ecritures si la facture n'est pas un acompte
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/Mouvement.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
101,25 → 101,6
 
}
 
public String asString() {
StringBuilder s = new StringBuilder();
BigDecimal d = BigDecimal.ZERO;
BigDecimal c = BigDecimal.ZERO;
s.append("Mouvement N°");
s.append(this.numero);
s.append("\n");
for (Ecriture e : this.ecritures) {
 
s.append("D : " + e.getDebit());
s.append("\tC : " + e.getCredit());
 
d = d.add(e.getDebit());
c = c.add(e.getCredit());
s.append("\tS : " + (d.subtract(c)) + "\n");
}
return s.toString();
}
 
public boolean isEmpty() {
return this.ecritures.isEmpty();
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieAchat.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
49,7 → 49,7
 
// iniatilisation des valeurs de la map
this.date = (Date) saisieRow.getObject("DATE");
this.nom = " Fourn. : " + rowFournisseur.getString("NOM") + " " + saisieRow.getObject("NOM").toString() + " Facture : " + this.saisieRow.getObject("NUMERO_FACTURE").toString();
this.nom = "Achat : " + rowFournisseur.getString("NOM") + " Facture : " + this.saisieRow.getObject("NUMERO_FACTURE").toString() + " " + saisieRow.getObject("NOM").toString();
this.putValue("DATE", this.date);
AccountingRecordsProvider provider = AccountingRecordsProviderManager.get(ID);
provider.putLabel(saisieRow, this.mEcritures);
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtReglementAchat.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
80,7 → 80,7
// this.nom = saisieRow.getObject("NOM").toString();
 
// si paiement comptant
if (typeRegRow.getID() != TypeReglementSQLElement.INDEFINI && (modeRegRow.getInt("AJOURS") == 0) && (modeRegRow.getInt("LENJOUR") == 0)) {
if ((modeRegRow.getInt("AJOURS") == 0) && (modeRegRow.getInt("LENJOUR") == 0)) {
 
System.out.println("Règlement Comptant");
// test Cheque
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/ItemAutoCompletionManager.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AjoutDeclinaisonTableModel.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AjoutDeclinaisonButton.java
File deleted
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/TotalCalculator.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
21,10 → 21,7
import org.openconcerto.sql.model.SQLBackgroundTableCacheItem;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.utils.DecimalUtils;
import org.openconcerto.utils.Tuple2;
34,7 → 31,6
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
528,7 → 524,7
 
SQLRowAccessor cpt = (this.achat ? this.rowDefaultCptAchat : this.rowDefaultCptProduit);
final SQLBackgroundTableCacheItem cacheForTableCompte = SQLBackgroundTableCache.getInstance().getCacheForTable(cpt.getTable());
boolean compteCategorieTaxeSpecifique = false;
 
if (!this.achat) {
// Total Service
if (this.bServiceActive != null && this.bServiceActive && service != null && service.booleanValue()) {
544,25 → 540,7
}
 
}
 
// Récupération du compte par défaut dans les liaisons taxe catégorie comptable (ex
// utilisé pour la caisse Altena)
if (tva != null && !tva.isUndefined() && this.rowCatComptable != null && !this.rowCatComptable.isUndefined()) {
final SQLTable tableTaxeCat = this.rowCatComptable.getTable().getTable("TAXE_CATEGORIE_COMPTABLE");
SQLRowValues rowVals = new SQLRowValues(tableTaxeCat);
rowVals.putNulls(tableTaxeCat.getFieldsName());
final List<SQLRowValues> fetchTaxeCat = SQLRowValuesListFetcher.create(rowVals)
.fetch(new Where(tableTaxeCat.getField("ID_CATEGORIE_COMPTABLE"), "=", this.rowCatComptable.getID()).and(new Where(tableTaxeCat.getField("ID_TAXE"), "=", tva.getID())));
if (!fetchTaxeCat.isEmpty()) {
 
final Number foreignID = fetchTaxeCat.get(0).getNonEmptyForeignIDNumber("ID_COMPTE_PCE_VENTE");
if (foreignID != null) {
cpt = cacheForTableCompte.getRowFromId(foreignID.intValue());
compteCategorieTaxeSpecifique = true;
}
}
}
}
 
// Compte PCE défini directement sur la ligne
boolean compteSpec = false;
572,9 → 550,9
}
if (article != null && !article.isUndefined()) {
if (!compteSpec) {
SQLRowAccessor cptCatComptable = compteCategorieTaxeSpecifique ? cpt : null;
SQLRowAccessor cptCatComptable = null;
// TODO Optimiser les requetes
if (!compteCategorieTaxeSpecifique && this.rowCatComptable != null && !this.rowCatComptable.isUndefined()) {
if (this.rowCatComptable != null && !this.rowCatComptable.isUndefined()) {
String suffix = (this.achat ? "_ACHAT" : "_VENTE");
if (!this.rowCatComptable.isForeignEmpty("ID_COMPTE_PCE" + suffix)) {
cptCatComptable = cacheForTableCompte.getRowFromId(this.rowCatComptable.getForeignID("ID_COMPTE_PCE" + suffix));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractArticleItemTable.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
74,7 → 74,7
protected SQLRowAccessor rowCatComptable;
private RowValuesTableModel model;
protected SQLRowValues defaultRowVals;
protected List<JButton> buttons = new ArrayList<>();
protected List<JButton> buttons = null;
protected RowValuesTableControlPanel control = null;
private SQLRowAccessor tarif = null;
 
144,7 → 144,6
 
c.weightx = 1;
 
this.buttons.add(1, new AjoutDeclinaisonButton(this));
control = new RowValuesTableControlPanel(this.table, this.buttons);
control.setOpaque(false);
this.add(control, c);
284,11 → 283,10
// On récupére les articles qui composent la table
// final List<SQLRow> listElts =
// eltSource.getTable().getRow(id).getReferentRows(eltArticleTable.getTable());
final SQLRowValues rowArticle = new SQLRowValues(tableArticle);
final Set<SQLField> fields = tableArticle.getFields();
 
SQLRow rowCmd = null;
for (final SQLRowAccessor rowElt : resultNonAssigned) {
final SQLRowValues rowArticle = new SQLRowValues(tableArticle);
// final SQLRow foreignRow = rowElt.getForeignRow("ID_ARTICLE");
// if (foreignRow == null || foreignRow.isUndefined()) {
final Set<String> fieldsName = rowElt.getTable().getFieldsName();
301,21 → 299,6
rowArticle.put(name, rowElt.getObject(name));
}
}
if (rowElt.getTable().getName().equals("COMMANDE_ELEMENT")) {
if (rowCmd == null) {
rowCmd = rowElt.getTable().getForeignTable("ID_COMMANDE").getRow(id);
}
rowArticle.put("ID_FOURNISSEUR", rowCmd.getForeignIDNumber("ID_FOURNISSEUR"));
 
SQLRowValues rowValsTarifF = new SQLRowValues(rowCmd.getTable().getTable("ARTICLE_TARIF_FOURNISSEUR"));
rowValsTarifF.put("ID_FOURNISSEUR", rowCmd.getForeignIDNumber("ID_FOURNISSEUR"));
rowValsTarifF.put("ID_ARTICLE", rowArticle);
rowValsTarifF.put("PRIX_ACHAT", rowArticle.getObject("PRIX_METRIQUE_HA_1"));
rowValsTarifF.put("PRIX_ACHAT_DEVISE_F", rowArticle.getObject("PRIX_METRIQUE_HA_1"));
rowValsTarifF.put("QTE", 1);
rowValsTarifF.put("DATE_PRIX", rowCmd.getDate("DATE").getTime());
}
 
// crée les articles si il n'existe pas
 
int idArt = -1;
489,10 → 472,6
VIEW_ONLY, EXPAND, FLAT
};
 
public AutoCompletionManager getCodeCompletionManager() {
return null;
}
 
public void expandNomenclature(int index, AutoCompletionManager m, final EXPAND_TYPE type) {
SQLRowValues rowValsLineFather = this.model.getRowValuesAt(index);
if (!rowValsLineFather.isForeignEmpty("ID_ARTICLE")) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractAchatArticleItemTable.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
52,7 → 52,6
import org.openconcerto.sql.view.list.ValidStateChecker;
import org.openconcerto.ui.preferences.DefaultProps;
import org.openconcerto.utils.DecimalUtils;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.Tuple3;
import org.openconcerto.utils.i18n.TranslationManager;
 
104,11 → 103,6
}
 
@Override
public AutoCompletionManager getCodeCompletionManager() {
return this.m;
}
 
@Override
protected void setModel(RowValuesTableModel model) {
super.setModel(model);
model.addTableModelListener(new TableModelListener() {
132,7 → 126,6
final boolean showDmdAchat = prefs.getBoolean(GestionArticleGlobalPreferencePanel.ACTIVE_DEMANDE_ACHAT, false);
final boolean showDevise = prefs.getBoolean(AbstractVenteArticleItemTable.ARTICLE_SHOW_DEVISE, false);
this.supplierCode = prefs.getBoolean(GestionArticleGlobalPreferencePanel.SUPPLIER_PRODUCT_CODE, false);
final boolean withDeclinaison = prefs.getBoolean(GestionArticleGlobalPreferencePanel.ACTIVER_DECLINAISON, false);
 
final List<SQLTableElement> list = new Vector<SQLTableElement>();
final SQLTableElement eNiveau = new SQLTableElement(e.getTable().getField("NIVEAU")) {
184,24 → 177,23
SQLTableElement tableElementDepot = new SQLTableElement(e.getTable().getField("ID_DEPOT_STOCK"), true, true, true);
list.add(tableElementDepot);
 
Set<String> fieldsName = e.getTable().getFieldsName();
if (fieldsName.contains("ID_FAMILLE_ARTICLE")) {
if (e.getTable().getFieldsName().contains("ID_FAMILLE_ARTICLE")) {
final SQLTableElement tableFamille = new SQLTableElement(e.getTable().getField("ID_FAMILLE_ARTICLE"));
list.add(tableFamille);
}
 
if (fieldsName.contains("ID_ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("ID_ECO_CONTRIBUTION")) {
this.tableElementEcoID = new SQLTableElement(e.getTable().getField("ID_ECO_CONTRIBUTION"));
list.add(this.tableElementEcoID);
}
 
if (fieldsName.contains("INCOTERM")) {
if (e.getTable().getFieldsName().contains("INCOTERM")) {
final SQLTableElement tableElementInco = new SQLTableElement(e.getTable().getField("INCOTERM"));
tableElementInco.setEditable(false);
list.add(tableElementInco);
}
 
if (fieldsName.contains("PREBILAN")) {
if (e.getTable().getFieldsName().contains("PREBILAN")) {
final SQLTableElement tableElementPre = new SQLTableElement(e.getTable().getField("PREBILAN"), BigDecimal.class);
tableElementPre.setRenderer(new DeviseTableCellRenderer());
list.add(tableElementPre);
209,7 → 201,7
 
// Code article
final SQLTableElement tableElementCode = new SQLTableElement(e.getTable().getField("CODE"), String.class,
new ITextArticleWithCompletionCellEditor(e.getTable().getTable("ARTICLE"), e.getTable().getTable("ARTICLE_FOURNISSEUR"), withDeclinaison)) {
new ITextArticleWithCompletionCellEditor(e.getTable().getTable("ARTICLE"), e.getTable().getTable("ARTICLE_FOURNISSEUR"))) {
@Override
public boolean isCellEditable(SQLRowValues vals, int rowIndex, int columnIndex) {
boolean b = super.isCellEditable(vals, rowIndex, columnIndex);
229,33 → 221,14
};
list.add(tableElementNom);
 
List<String> fieldDecl = new ArrayList<>();
 
if (withDeclinaison) {
 
for (String string : fieldsName) {
if (string.startsWith("ID_ARTICLE_DECLINAISON")) {
final SQLTableElement tableElementDeclinaison = new SQLTableElement(e.getTable().getField(string));
tableElementDeclinaison.setEditable(false);
fieldDecl.add(string);
list.add(tableElementDeclinaison);
}
}
}
if (fieldsName.contains("DESCRIPTIF")) {
if (e.getTable().getFieldsName().contains("DESCRIPTIF")) {
final SQLTableElement tableElementDesc = new SQLTableElement(e.getTable().getField("DESCRIPTIF"));
list.add(tableElementDesc);
}
if (fieldsName.contains("COLORIS")) {
if (e.getTable().getFieldsName().contains("COLORIS")) {
final SQLTableElement tableElementColoris = new SQLTableElement(e.getTable().getField("COLORIS"));
list.add(tableElementColoris);
}
 
if (fieldsName.contains("ID_FABRICANT")) {
SQLTableElement fab = new SQLTableElement(e.getTable().getField("ID_FABRICANT"));
list.add(fab);
}
 
// Valeur des métriques
final SQLTableElement tableElement_ValeurMetrique2 = new SQLTableElement(e.getTable().getField("VALEUR_METRIQUE_2"), Float.class);
list.add(tableElement_ValeurMetrique2);
269,7 → 242,7
tableElement_PrixMetrique1_AchatHT.setRenderer(new CurrencyWithSymbolRenderer());
list.add(tableElement_PrixMetrique1_AchatHT);
 
if (fieldsName.contains("ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("ECO_CONTRIBUTION")) {
this.tableElementEco = new SQLTableElement(e.getTable().getField("ECO_CONTRIBUTION"));
list.add(this.tableElementEco);
}
358,7 → 331,7
list.add(tableBrElt);
}
 
if (fieldsName.contains("QTE_ORIGINE")) {
if (e.getTable().getFieldsName().contains("QTE_ORIGINE")) {
final SQLTableElement tableQteO = new SQLTableElement(e.getTable().getField("QTE_ORIGINE"));
tableQteO.setEditable(false);
list.add(tableQteO);
370,7 → 343,7
return Integer.valueOf(0);
}
};
if (fieldsName.contains("QTE_ORIGINE")) {
if (e.getTable().getFieldsName().contains("QTE_ORIGINE")) {
qteElement.setRenderer(new DeliveredQtyRowValuesRenderer(false));
}
list.add(qteElement);
497,7 → 470,7
list.add(tableElementRemise);
}
 
if (fieldsName.contains("T_ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("T_ECO_CONTRIBUTION")) {
this.tableElementEcoTotal = new SQLTableElement(e.getTable().getField("T_ECO_CONTRIBUTION"));
list.add(this.tableElementEcoTotal);
}
616,10 → 589,10
dmd.fill("ID_FAMILLE_ARTICLE", "ID_FAMILLE_ARTICLE");
}
List<String> completionFields = new ArrayList<String>();
if (fieldsName.contains("INCOTERM")) {
if (e.getTable().getFieldsName().contains("INCOTERM")) {
completionFields.add("INCOTERM");
}
if (fieldsName.contains("ID_ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("ID_ECO_CONTRIBUTION")) {
completionFields.add("ID_ECO_CONTRIBUTION");
}
completionFields.add("ID_UNITE_VENTE");
641,15 → 614,14
completionFields.add("SERVICE");
completionFields.add("ID_DEVISE");
completionFields.add("PA_DEVISE");
completionFields.addAll(fieldDecl);
if (fieldsName.contains("COLORIS")) {
if (e.getTable().getFieldsName().contains("COLORIS")) {
completionFields.add("COLORIS");
}
 
if (fieldsName.contains("DESCRIPTIF")) {
if (e.getTable().getFieldsName().contains("DESCRIPTIF")) {
completionFields.add("DESCRIPTIF");
}
if (fieldsName.contains("ID_FAMILLE_ARTICLE")) {
if (e.getTable().getFieldsName().contains("ID_FAMILLE_ARTICLE")) {
completionFields.add("ID_FAMILLE_ARTICLE");
}
final SQLTable sqlTableArticle = e.getTable().getTable("ARTICLE");
664,11 → 636,7
protected Object getValueFrom(SQLRow row, String field, SQLRowAccessor rowDest) {
Object res = tarifCompletion(row, field);
if (res == null) {
if (field.equalsIgnoreCase("ID_CODE_FOURNISSEUR")) {
return null;
} else {
return super.getValueFrom(row, field, rowDest);
}
} else {
return res;
}
827,7 → 795,7
if (source != null && source.getField().getName().equals("PA_DEVISE")) {
return row.getObject("PA_DEVISE");
} else {
if (row.contains("ID_DEVISE") && !row.isForeignEmpty("ID_DEVISE")) {
if (!row.isForeignEmpty("ID_DEVISE") && row.getForeign("ID_DEVISE") != null) {
String devCode = row.getForeign("ID_DEVISE").getString("CODE");
BigDecimal bigDecimal = (BigDecimal) row.getObject("PRIX_METRIQUE_HA_1");
 
980,7 → 948,7
return row.getObject("PRIX_METRIQUE_HA_1");
} else {
if (source != null && source.getField().getName().equals("PA_DEVISE")) {
if (row.contains("ID_DEVISE") && !row.isForeignEmpty("ID_DEVISE")) {
if (!row.isForeignEmpty("ID_DEVISE") && row.getForeign("ID_DEVISE") != null) {
String devCode = row.getForeign("ID_DEVISE").getString("CODE");
BigDecimal bigDecimal = (BigDecimal) row.getObject("PA_DEVISE");
 
1092,7 → 1060,6
JButton buttonStock = new JButton("Consulter le stock");
buttonStock.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
SQLRowValues rowValsSel = table.getSelectedRowValues();
if (rowValsSel != null) {
SQLRowAccessor foreignArt = rowValsSel.getForeign("ID_ARTICLE");
1105,10 → 1072,8
}
}
}
} catch (Exception e) {
ExceptionHandler.handle("Erreur d'accès au stock", e);
 
}
}
});
 
this.buttons.add(buttonStock);
1164,6 → 1129,7
if (row != null && !row.isUndefined() && (field.equalsIgnoreCase("ID_CODE_FOURNISSEUR")) && this.rowFournisseur != null && !this.rowFournisseur.isUndefined()) {
final SQLTable foreignTableCodeF = getSQLElement().getTable().getForeignTable("ID_CODE_FOURNISSEUR");
List<SQLRow> resultCode = row.getReferentRows(foreignTableCodeF);
int idCode = foreignTableCodeF.getUndefinedID();
for (SQLRow sqlRow : resultCode) {
if (sqlRow.getForeignID("ID_FOURNISSEUR") == this.rowFournisseur.getID()) {
return sqlRow.getID();
1170,11 → 1136,11
}
 
}
return foreignTableCodeF.getUndefinedIDNumber();
return idCode;
}
if (field.equalsIgnoreCase("ID_CODE_FOURNISSEUR")) {
final SQLTable foreignTableCodeF = getSQLElement().getTable().getForeignTable("ID_CODE_FOURNISSEUR");
return foreignTableCodeF.getUndefinedIDNumber();
return foreignTableCodeF.getUndefinedID();
}
 
if (row != null && !row.isUndefined() && (field.equalsIgnoreCase("PRIX_METRIQUE_HA_1") || field.equalsIgnoreCase("PA_HT")) && tTarifFournisseur != null) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/IListTotalPanel.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
16,7 → 16,7
import org.openconcerto.erp.core.finance.accounting.model.Currency;
import org.openconcerto.erp.core.finance.accounting.model.CurrencyConverter;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.ITableModel;
import org.openconcerto.sql.view.list.ListSQLLine;
222,7 → 222,7
 
for (ListSQLLine line : listLines) {
 
final SQLRowAccessor rowAt = line.getRowAccessor();
final SQLRowValues rowAt = line.getRow();
final List<SQLTableModelColumn> columns = line.getColumns().getColumns();
 
for (final Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
288,11 → 288,6
}
}
} else if (type != Type.MOYENNE_MARGE && type != Type.COUNT) {
 
// FIXME Test si la colonne existe sinon exception dans liste des articles quand
// on passe de la vue normal à virtuel
if (columns.indexOf(field.get0()) != -1) {
 
BigDecimal n = mapTotal.get(field.get0());
 
final Object value = getValueAt(line, field.get0(), columns);
321,7 → 316,6
}
}
}
}
 
for (Tuple2<? extends SQLTableModelColumn, Type> field : listField) {
if (field.get1() == Type.MOYENNE_MARGE) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/DeviseNumericCellEditor.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
47,10 → 47,6
protected final DecimalFormat decimalFormat = new DecimalFormat("0.00#######");
 
public DeviseNumericCellEditor(SQLField field) {
this(field.getType().getDecimalDigits());
}
 
public DeviseNumericCellEditor(int precision) {
final DecimalFormatSymbols symbol = DecimalFormatSymbols.getInstance();
symbol.setDecimalSeparator('.');
decimalFormat.setDecimalFormatSymbols(symbol);
58,7 → 54,7
// Mimic JTable.GenericEditor behavior
this.textField.setBorder(new LineBorder(Color.black));
this.textField.setHorizontalAlignment(JTextField.RIGHT);
this.precision = precision;
this.precision = field.getType().getDecimalDigits();
// On ne peut saisir qu'un chiffre à 2 décimales
textField.addKeyListener(new KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent keyEvent) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/NumericTextField.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
191,7 → 191,7
@Override
public BigDecimal getValue() {
if (this.getText().trim().length() == 0) {
return BigDecimal.ZERO;
return null;
} else {
try {
return new BigDecimal(this.getText().trim());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/PreviewFrame.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
14,8 → 14,9
package org.openconcerto.erp.core.common.ui;
 
import org.openconcerto.erp.generationDoc.A4;
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.erp.generationDoc.DefaultNXDocumentPrinter;
import org.openconcerto.utils.Action;
import org.openconcerto.erp.generationDoc.ODTPrinterNX;
import org.openconcerto.utils.ExceptionHandler;
 
import java.awt.Dimension;
23,11 → 24,13
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.Paper;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
 
import javax.print.PrintService;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.Size2DSyntax;
35,12 → 38,15
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSizeName;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
 
import org.jopendocument.model.OpenDocument;
import org.jopendocument.panel.ODSViewerPanel;
import org.jopendocument.print.DefaultXMLDocumentPrinter;
import org.jopendocument.print.ODTPrinterXML;
 
public class PreviewFrame extends JFrame {
 
47,7 → 53,6
private PreviewFrame(OpenDocument doc, String title) {
super(title);
final ODSViewerPanel viewerPanel = new ODSViewerPanel(doc, createDocumentPrinter());
viewerPanel.showSaveAsButton(false);
this.setContentPane(viewerPanel);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
54,20 → 59,20
 
public PreviewFrame(String title, String url, String odspXml) {
final ODSViewerPanel contentPane = new ODSViewerPanel(url, odspXml, createDocumentPrinter(), true);
contentPane.showSaveAsButton(false);
 
this.setContentPane(contentPane);
this.setTitle(title);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
 
public void addTool(Action a) {
JButton b = new JButton(a.getName());
public void addTool(String n, Runnable r) {
JButton b = new JButton(n);
((ODSViewerPanel) this.getContentPane()).addTool(b);
b.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
a.run(PreviewFrame.this);
r.run();
}
});
}
144,16 → 149,16
}
 
public static void show(File file) {
show(file, Collections.emptyList());
show(file, null, null);
}
 
public static void show(File file, List<Action> actions) {
public static void show(File file, String actionName, Runnable r) {
final OpenDocument doc = new OpenDocument(file);
final String title = file.getName();
if (SwingUtilities.isEventDispatchThread()) {
PreviewFrame previewFrame = new PreviewFrame(doc, title);
for (Action a : actions) {
previewFrame.addTool(a);
if (r != null) {
previewFrame.addTool(actionName, r);
}
previewFrame.pack();
previewFrame.setVisible(true);
162,8 → 167,8
@Override
public void run() {
PreviewFrame previewFrame = new PreviewFrame(doc, title);
for (Action a : actions) {
previewFrame.addTool(a);
if (r != null) {
previewFrame.addTool(actionName, r);
}
previewFrame.pack();
previewFrame.setVisible(true);
<
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractVenteArticleItemTable.java
1,7 → 1,7
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
* 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
27,7 → 27,6
import org.openconcerto.erp.core.sales.product.ui.CurrencyWithSymbolRenderer;
import org.openconcerto.erp.core.sales.product.ui.QteMultipleRowValuesRenderer;
import org.openconcerto.erp.core.sales.product.ui.QteUnitRowValuesRenderer;
import org.openconcerto.erp.core.sales.product.ui.QteUnitairePieceRowValuesRenderer;
import org.openconcerto.erp.core.supplychain.stock.element.DepotStockSQLElement;
import org.openconcerto.erp.core.supplychain.stock.element.StockSQLElement;
import org.openconcerto.erp.importer.ArrayTableModel;
44,7 → 43,6
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.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.UndefinedRowValuesCache;
67,7 → 65,6
import org.openconcerto.ui.preferences.DefaultProps;
import org.openconcerto.utils.CompareUtils;
import org.openconcerto.utils.DecimalUtils;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.StringUtils;
import org.openconcerto.utils.Tuple3;
import org.openconcerto.utils.cc.ITransformer;
91,9 → 88,7
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
268,7 → 263,6
 
private SQLTable tableArticleTarif = Configuration.getInstance().getBase().getTable("ARTICLE_TARIF");
private SQLTable tableArticle = Configuration.getInstance().getBase().getTable("ARTICLE");
protected AutoCompletionManager codeCompletionManager;
 
protected void init() {
 
279,7 → 273,6
final boolean createAuto = prefs.getBoolean(GestionArticleGlobalPreferencePanel.CREATE_ARTICLE_AUTO, true);
final boolean showEco = prefs.getBoolean(AbstractVenteArticleItemTable.SHOW_ECO_CONTRIBUTION_COLUMNS, false);
final boolean showDevise = prefs.getBoolean(AbstractVenteArticleItemTable.ARTICLE_SHOW_DEVISE, false);
final boolean withDeclinaison = prefs.getBoolean(GestionArticleGlobalPreferencePanel.ACTIVER_DECLINAISON, false);
 
final UserRights rights = UserRightsManager.getCurrentUserRights();
final boolean editVTPrice = rights.haveRight(EDIT_PRIX_VENTE_CODE);
316,8 → 309,7
SQLTableElement tableElementArticle = new SQLTableElement(e.getTable().getField("ID_ARTICLE"), true, true, true);
list.add(tableElementArticle);
 
Set<String> fieldsName = e.getTable().getFieldsName();
if (fieldsName.contains("ID_ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("ID_ECO_CONTRIBUTION")) {
this.tableElementEcoID = new SQLTableElement(e.getTable().getField("ID_ECO_CONTRIBUTION"));
list.add(this.tableElementEcoID);
}
324,7 → 316,7
 
// Code article
final SQLTableElement tableElementCode = new SQLTableElement(e.getTable().getField("CODE"), String.class,
new ITextArticleWithCompletionCellEditor(e.getTable().getTable("ARTICLE"), e.getTable().getTable("ARTICLE_FOURNISSEUR"), withDeclinaison));
new ITextArticleWithCompletionCellEditor(e.getTable().getTable("ARTICLE"), e.getTable().getTable("ARTICLE_FOURNISSEUR")));
list.add(tableElementCode);
 
// Désignation de l'article
331,31 → 323,17
final SQLTableElement tableElementNom = new SQLTableElement(e.getTable().getField("NOM"));
list.add(tableElementNom);
 
List<String> fieldDecl = new ArrayList<>();
 
if (withDeclinaison) {
 
for (String string : fieldsName) {
if (string.startsWith("ID_ARTICLE_DECLINAISON")) {
final SQLTableElement tableElementDeclinaison = new SQLTableElement(e.getTable().getField(string));
tableElementDeclinaison.setEditable(false);
fieldDecl.add(string);
list.add(tableElementDeclinaison);
}
}
}
 
if (fieldsName.contains("COLORIS")) {
if (e.getTable().getFieldsName().contains("COLORIS")) {
final SQLTableElement tableElementColoris = new SQLTableElement(e.getTable().getField("COLORIS"));
list.add(tableElementColoris);
}
 
if (fieldsName.contains("DESCRIPTIF")) {
if (e.getTable().getFieldsName().contains("DESCRIPTIF")) {
final SQLTableElement tableElementDesc = new SQLTableElement(e.getTable().getField("DESCRIPTIF"));
list.add(tableElementDesc);
}
 
if (fieldsName.contains("DELAI")) {
if (e.getTable().getFieldsName().contains("DELAI")) {
final SQLTableElement tableElementDelai = new SQLTableElement(e.getTable().getField("DELAI"));
list.add(tableElementDelai);
}
368,51 → 346,6
list.add(tableElementPays);
}
 
SQLTableElement qteU = new SQLTableElement(e.getTable().getField("QTE_UNITAIRE"), BigDecimal.class) {
@Override
public boolean isCellEditable(SQLRowValues vals, int rowIndex, int columnIndex) {
 
SQLRowAccessor row = vals.getForeign("ID_UNITE_VENTE");
if (row != null && !row.isUndefined() && row.getBoolean("A_LA_PIECE")) {
return false;
} else if (activeCalculM2 && row != null && !row.isUndefined() && row.getID() == UniteVenteArticleSQLElement.M2) {
return false;
} else {
return super.isCellEditable(vals, rowIndex, columnIndex);
}
}
 
@Override
public TableCellRenderer getTableCellRenderer() {
return new QteUnitairePieceRowValuesRenderer();
}
 
protected Object getDefaultNullValue() {
return BigDecimal.ZERO;
}
};
list.add(qteU);
 
SQLTableElement uniteVente = new SQLTableElement(e.getTable().getField("ID_UNITE_VENTE"));
list.add(uniteVente);
 
// Quantité
this.qte = new SQLTableElement(e.getTable().getField("QTE"), Integer.class, new QteCellEditor()) {
protected Object getDefaultNullValue() {
return Integer.valueOf(0);
}
 
public TableCellRenderer getTableCellRenderer() {
if (getSQLElement().getTable().getFieldsName().contains("QTE_ACHAT")) {
return new QteMultipleRowValuesRenderer();
} else {
return super.getTableCellRenderer();
}
}
};
this.qte.setPreferredSize(20);
list.add(this.qte);
 
// Valeur des métriques
final SQLTableElement tableElement_ValeurMetrique2 = new SQLTableElement(e.getTable().getField("VALEUR_METRIQUE_2"), Float.class) {
@Override
476,7 → 409,7
 
// Prébilan
 
if (fieldsName.contains("PREBILAN")) {
if (e.getTable().getFieldsName().contains("PREBILAN")) {
prebilan = new SQLTableElement(e.getTable().getField("PREBILAN"), BigDecimal.class) {
protected Object getDefaultNullValue() {
return BigDecimal.ZERO;
544,7 → 477,7
tableElement_PrixMetrique1_VenteHT.setRenderer(new CurrencyWithSymbolRenderer());
list.add(tableElement_PrixMetrique1_VenteHT);
 
if (fieldsName.contains("ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("ECO_CONTRIBUTION")) {
this.tableElementEco = new SQLTableElement(e.getTable().getField("ECO_CONTRIBUTION"));
list.add(this.tableElementEco);
}
572,6 → 505,51
SQLTableElement eltHauteur = new SQLTableElement(e.getTable().getField("HAUTEUR"));
list.add(eltHauteur);
 
SQLTableElement qteU = new SQLTableElement(e.getTable().getField("QTE_UNITAIRE"), BigDecimal.class) {
@Override
public boolean isCellEditable(SQLRowValues vals, int rowIndex, int columnIndex) {
 
SQLRowAccessor row = vals.getForeign("ID_UNITE_VENTE");
if (row != null && !row.isUndefined() && row.getBoolean("A_LA_PIECE")) {
return false;
} else if (activeCalculM2 && row != null && !row.isUndefined() && row.getID() == UniteVenteArticleSQLElement.M2) {
return false;
} else {
return super.isCellEditable(vals, rowIndex, columnIndex);
}
}
 
@Override
public TableCellRenderer getTableCellRenderer() {
return new QteUnitRowValuesRenderer();
}
 
protected Object getDefaultNullValue() {
return BigDecimal.ZERO;
}
};
list.add(qteU);
 
SQLTableElement uniteVente = new SQLTableElement(e.getTable().getField("ID_UNITE_VENTE"));
list.add(uniteVente);
 
// Quantité
this.qte = new SQLTableElement(e.getTable().getField("QTE"), Integer.class, new QteCellEditor()) {
protected Object getDefaultNullValue() {
return Integer.valueOf(0);
}
 
public TableCellRenderer getTableCellRenderer() {
if (getSQLElement().getTable().getFieldsName().contains("QTE_ACHAT")) {
return new QteMultipleRowValuesRenderer();
} else {
return super.getTableCellRenderer();
}
}
};
this.qte.setPreferredSize(20);
list.add(this.qte);
 
if (e.getTable().contains("RETOUR_STOCK")) {
list.add(new SQLTableElement(e.getTable().getField("RETOUR_STOCK")));
}
753,7 → 731,7
this.totalHT.setEditable(false);
this.totalHA = new SQLTableElement(e.getTable().getField("T_PA_HT"), BigDecimal.class);
 
if (fieldsName.contains("MONTANT_FACTURABLE")) {
if (e.getTable().getFieldsName().contains("MONTANT_FACTURABLE")) {
// SQLTableElement tableElementAcompte = new
// SQLTableElement(e.getTable().getField("POURCENT_ACOMPTE"));
// list.add(tableElementAcompte);
792,7 → 770,7
 
final SQLField fieldRemise = e.getTable().getField("POURCENT_REMISE");
 
if (fieldsName.contains("MONTANT_REMISE")) {
if (e.getTable().getFieldsName().contains("MONTANT_REMISE")) {
tableElementRemise = new SQLTableElement(e.getTable().getField("POURCENT_REMISE"), Acompte.class, new AcompteCellEditor("POURCENT_REMISE", "MONTANT_REMISE")) {
@Override
public void setValueFrom(SQLRowValues row, Object value) {
829,7 → 807,7
}
list.add(tableElementRemise);
SQLTableElement tableElementRG = null;
if (fieldsName.contains("POURCENT_RG")) {
if (e.getTable().getFieldsName().contains("POURCENT_RG")) {
tableElementRG = new SQLTableElement(e.getTable().getField("POURCENT_RG"));
list.add(tableElementRG);
}
855,7 → 833,7
}
 
// Marge HT
if (fieldsName.contains("MARGE_HT")) {
if (e.getTable().getFieldsName().contains("MARGE_HT")) {
 
final SQLTableElement marge = new SQLTableElement(e.getTable().getField("MARGE_HT"), BigDecimal.class) {
protected Object getDefaultNullValue() {
894,7 → 872,7
 
}
 
if (fieldsName.contains("MARGE_PREBILAN_HT")) {
if (e.getTable().getFieldsName().contains("MARGE_PREBILAN_HT")) {
 
final SQLTableElement marge = new SQLTableElement(e.getTable().getField("MARGE_PREBILAN_HT"), BigDecimal.class) {
protected Object getDefaultNullValue() {
926,7 → 904,7
 
}
 
if (fieldsName.contains("T_ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("T_ECO_CONTRIBUTION")) {
this.tableElementEcoTotal = new SQLTableElement(e.getTable().getField("T_ECO_CONTRIBUTION"));
list.add(this.tableElementEcoTotal);
}
979,8 → 957,6
ToolTipManager.sharedInstance().unregisterComponent(this.table);
ToolTipManager.sharedInstance().unregisterComponent(this.table.getTableHeader());
if (getSQLElement().getTable().getName().equals("COMMANDE_CLIENT_ELEMENT")) {
this.table.getClearCloneTableElement().add("ID_MISSION");
this.table.getClearCloneTableElement().add("ID_DEVIS_ELEMENT");
this.table.getClearCloneTableElement().add("QTE_LIVREE");
this.table.getClearCloneTableElement().add("LIVRE");
this.table.getClearCloneTableElement().add("LIVRE_FORCED");
1031,7 → 1007,7
// Autocompletion
final SQLTable sqlTableArticle = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete().getTable("ARTICLE");
List<String> completionField = new ArrayList<String>();
if (fieldsName.contains("ID_ECO_CONTRIBUTION")) {
if (e.getTable().getFieldsName().contains("ID_ECO_CONTRIBUTION")) {
completionField.add("ID_ECO_CONTRIBUTION");
}
 
1042,7 → 1018,6
completionField.add("POURCENT_REMISE");
completionField.add("ID_UNITE_VENTE");
completionField.add("QTE_UNITAIRE");
completionField.add("QTE");
completionField.add("PA_HT");
completionField.add("PV_HT");
completionField.add("ID_TAXE");
1062,7 → 1037,6
completionField.add("LONGUEUR");
completionField.add("LARGEUR");
completionField.add("HAUTEUR");
completionField.addAll(fieldDecl);
if (getSQLElement().getTable().getFieldsName().contains("DESCRIPTIF")) {
completionField.add("DESCRIPTIF");
}
1081,12 → 1055,25
completionField.add("TARE");
}
 
this.codeCompletionManager = new ItemAutoCompletionManager(this, tableElementCode, sqlTableArticle.getField("CODE"), this.table, this.table.getRowValuesTableModel());
final AutoCompletionManager m = new AutoCompletionManager(tableElementCode, sqlTableArticle.getField("CODE"), this.table, this.table.getRowValuesTableModel()) {
 
this.codeCompletionManager.fill("NOM", "NOM");
this.codeCompletionManager.fill("ID", "ID_ARTICLE");
@Override
protected Object getValueFrom(SQLRow row, String field, SQLRowAccessor rowDest) {
Object res = tarifCompletion(row, field, rowDest, true);
if (res == null) {
res = super.getValueFrom(row, field, rowDest);
}
if (field.equals("POURCENT_REMISE")) {
return getRemiseClient(row);
}
return res;
}
 
};
m.fill("NOM", "NOM");
m.fill("ID", "ID_ARTICLE");
for (String string : completionField) {
this.codeCompletionManager.fill(string, string);
m.fill(string, string);
}
 
ITransformer<SQLSelect, SQLSelect> selTrans = new ITransformer<SQLSelect, SQLSelect>() {
1111,12 → 1098,12
}
};
 
this.codeCompletionManager.setSelectTransformer(selTrans);
m.setSelectTransformer(selTrans);
 
this.table.setDropTarget(new DropTarget() {
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
dropInTable(dtde, AbstractVenteArticleItemTable.this.codeCompletionManager);
dropInTable(dtde, m);
// super.drop(dtde);
}
});
1147,7 → 1134,7
 
@Override
public void actionPerformed(ActionEvent arg0) {
expandNomenclature(rowindex, codeCompletionManager, EXPAND_TYPE.EXPAND);
expandNomenclature(rowindex, m, EXPAND_TYPE.EXPAND);
}
});
popup.add(new AbstractAction(TranslationManager.getInstance().getTranslationForItem("product.bom.expose")) {
1154,7 → 1141,7
 
@Override
public void actionPerformed(ActionEvent arg0) {
expandNomenclature(rowindex, codeCompletionManager, EXPAND_TYPE.VIEW_ONLY);
expandNomenclature(rowindex, m, EXPAND_TYPE.VIEW_ONLY);
}
});
 
1167,7 → 1154,20
}
});
}
final AutoCompletionManager m2 = new ItemAutoCompletionManager(this, tableElementNom, sqlTableArticle.getField("NOM"), this.table, this.table.getRowValuesTableModel());
final AutoCompletionManager m2 = new AutoCompletionManager(tableElementNom, sqlTableArticle.getField("NOM"), this.table, this.table.getRowValuesTableModel()) {
@Override
protected Object getValueFrom(SQLRow row, String field, SQLRowAccessor rowDest) {
Object res = tarifCompletion(row, field, rowDest, true);
if (res == null) {
res = super.getValueFrom(row, field, rowDest);
}
if (field.equals("POURCENT_REMISE")) {
return getRemiseClient(row);
}
return res;
}
 
};
m2.fill("CODE", "CODE");
m2.fill("ID", "ID_ARTICLE");
for (String string : completionField) {