Update upstream source from tag 'upstream/2.8.4+dfsg'
Update to upstream version '2.8.4+dfsg'
with Debian dir 8fb9f8368bb2d94e45ee33225380506f471e2f5d
Jochen Sprickerhof
5 years ago
2 | 2 | <classpathentry kind="src" path="src"/> |
3 | 3 | <classpathentry kind="src" output="test-bin" path="test"/> |
4 | 4 | <classpathentry including="*.java" kind="src" output="updates" path="updates"/> |
5 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | |
5 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> | |
6 | 6 | <classpathentry exported="true" kind="src" path="/jameica"/> |
7 | 7 | <classpathentry kind="lib" path="lib/super-csv-2.4.0.jar"/> |
8 | 8 | <classpathentry kind="lib" path="lib/swtchart/org.swtchart_0.10.0.v20160212.jar"/> |
10 | 10 | <classpathentry kind="lib" path="lib/itextpdf-5.3.3.jar"/> |
11 | 11 | <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> |
12 | 12 | <classpathentry exported="true" kind="lib" path="lib/obantoo-bin-2.1.12.jar"/> |
13 | <classpathentry exported="true" kind="lib" path="lib/hbci4j-core-3.0.18-SNAPSHOT.jar"/> | |
13 | <classpathentry exported="true" kind="lib" path="lib/hbci4j-core-3.0.21-SNAPSHOT.jar" sourcepath="/hbci4j-core/src/main/java"/> | |
14 | 14 | <classpathentry kind="output" path="bin"/> |
15 | 15 | </classpath> |
6 | 6 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled |
7 | 7 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled |
8 | 8 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate |
9 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 | |
9 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 | |
10 | 10 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve |
11 | org.eclipse.jdt.core.compiler.compliance=1.6 | |
11 | org.eclipse.jdt.core.compiler.compliance=1.7 | |
12 | 12 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate |
13 | 13 | org.eclipse.jdt.core.compiler.debug.localVariable=generate |
14 | 14 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate |
109 | 109 | org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore |
110 | 110 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning |
111 | 111 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning |
112 | org.eclipse.jdt.core.compiler.source=1.6 | |
112 | org.eclipse.jdt.core.compiler.release=disabled | |
113 | org.eclipse.jdt.core.compiler.source=1.7 | |
113 | 114 | org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled |
114 | 115 | org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,LOW,LOW |
115 | 116 | org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,BUGZILLA,TICKET |
129 | 130 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 |
130 | 131 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 |
131 | 132 | org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 |
133 | org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 | |
132 | 134 | org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 |
133 | 135 | org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 |
134 | 136 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 |
166 | 168 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line |
167 | 169 | org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line |
168 | 170 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line |
171 | org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false | |
172 | org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false | |
169 | 173 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false |
170 | 174 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false |
175 | org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false | |
171 | 176 | org.eclipse.jdt.core.formatter.comment.format_block_comments=true |
172 | 177 | org.eclipse.jdt.core.formatter.comment.format_header=false |
173 | 178 | org.eclipse.jdt.core.formatter.comment.format_html=true |
178 | 183 | org.eclipse.jdt.core.formatter.comment.indent_root_tags=true |
179 | 184 | org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert |
180 | 185 | org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert |
181 | org.eclipse.jdt.core.formatter.comment.line_length=80 | |
186 | org.eclipse.jdt.core.formatter.comment.line_length=160 | |
182 | 187 | org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true |
183 | 188 | org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true |
184 | 189 | org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false |
390 | 395 | org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false |
391 | 396 | org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false |
392 | 397 | org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false |
393 | org.eclipse.jdt.core.formatter.lineSplit=80 | |
398 | org.eclipse.jdt.core.formatter.lineSplit=160 | |
394 | 399 | org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false |
395 | 400 | org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false |
396 | 401 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 |
1 | 1 | eclipse.preferences.version=1 |
2 | 2 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true |
3 | 3 | formatter_profile=_meins |
4 | formatter_settings_version=12 | |
5 | org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/> | |
4 | formatter_settings_version=14 | |
6 | 5 | sp_cleanup.add_default_serial_version_id=true |
7 | 6 | sp_cleanup.add_generated_serial_version_id=false |
8 | 7 | sp_cleanup.add_missing_annotations=true |
0 | 0 | #Build Number for ANT. Do not edit! |
1 | #Tue Jun 05 11:12:48 CEST 2018 | |
2 | build.number=364 | |
1 | #Wed Jun 27 18:39:48 CEST 2018 | |
2 | build.number=367 |
0 | 2018-09-26 Version 2.8.4 | |
1 | ||
2 | * NEW: 0700 Beim Empfang neuer UPD gleich die BPD mit aktualisieren | |
3 | * NEW: 0699 Neue HBCI4Java-Version mit Server-Adressen für IsBank - https://github.com/hbci4j/hbci4java/commit/649179cd52cc57bc540ce224cc8ef6ebaf0a806e | |
4 | * NEW: 0698 Scrollbalken in Einstellungsdialog für elektr. Kontoauszug für kleine Displays anzeigen, Fenstergröße speichern | |
5 | * NEW: 0697 BUGZILLA 1495 - automatisches Entfernen nicht unterstüzter Zeichen beim Einfügen des Verwendungszweck per Zwischenablage | |
6 | * NEW: 0696 Neue HBCI4Java-Version mit aktualisierter Server-Adresse der Sparda-Bank Berlin - https://github.com/hbci4j/hbci4java/commit/c91f6ed2c5b6b5ddc8d29c4ec6cb66428af6f15e | |
7 | * NEW: 0695 Support für dedizierte EndToEnd-ID in Umsätzen | |
8 | * BUG: 0694 NPE beim Parsen von CAMT-Dateien - https://github.com/hbci4j/hbci4java/commit/b2b607ad8b72012978badab5f8cc39a8f8dfccaa | |
9 | * CHG: 0693 Nachtrag zu Bugzilla 1864 - Kontofilter in der Liste der Konten auf der Startseite ausblenden, dort ist der Platz dafuer zu knapp | |
10 | * NEW: 0692 BUGZILLA 1864 - Filterkriterien in der Liste der Konten (u.a. deaktivierte Konten ausblenden) | |
11 | * NEW: 0691 Suchbegriff "flicker" in die Liste der TAN-Verfahren aufgenommen, für die chipTAN USB in Frage kommt | |
12 | * NEW: 0690 Sonderbehandlung fuer Fehlerfall https://homebanking-hilfe.de/forum/topic.php?p=139423#real139423 (Fehler beim Update der H2-Datenbank durch fehlerhaften H2-Treiber) | |
13 | * NEW: 0689 BUGZILLA 1861 - Unterstützung für benutzerspezifische CSV-Import-Profile | |
14 | * NEW: 0688 Neue obantoo-Version mit aktualisierter BLZ-Datei gültig ab 03.09.2018 | |
15 | * NEW: 0687 Nur jene Synchronizisierungsoptionen anzeigen, die das Backend unterstützt | |
16 | * NEW: 0686 Manueller Import von Umsätzen im CAMT-Format | |
17 | * BUG: 0685 BUGZILLA 1860 - Kein Scrollbalken bei Anzeige einer überlangen Banknachricht | |
18 | * NEW: 0684 BUGZILLA 1621 - Support für Umsatz-Abruf im CAMT-Format | |
19 | * BUG: 0683 Neuer PIN/TAN-Bankzugang liess sich nicht mehr anlegen, da die ChipTAN-USB-Checkbox zu dem Zeitpunkt nicht korrekt berücksichtigt wurde | |
20 | * NEW: 0682 Neue HBCI4Java-Version mit CAMT-Bugfix - https://github.com/hbci4j/hbci4java/commit/3dc9ebf080810acc2636aef0c9413e0d40672dbb | |
21 | * NEW: 0681 Neue HBCI4Java-Version mit Unterstützung für CAMT - https://github.com/hbci4j/hbci4java/commit/ecca11320308b1fa1dc40bb37e6571d629064471 | |
22 | * BUG: 0680 BUGZILLA 1858 - Hibiscus sucht auch bei deaktivierter chipTAN-USB-Option weiter nach Kartenlesern | |
23 | * NEW: 0679 Support für HKKAZ/HKKAN in Segment-Version 7 - https://github.com/hbci4j/hbci4java/commit/e3372a339bd5b9f0c2cea80155199f475dd46ed4 | |
24 | * DEL: 0678 Option "Dauerhafte Internetverbindung, Aufforderung zum Verbinden nicht erforderlich" aus den Einstellungen entfernt, braucht keiner mehr | |
25 | * NEW: 0677 Option "Alle Daten des Verwendungszwecks anzeigen" auch in Liste der Umsätze konfigurierbar (per Config-Button oben rechts) | |
26 | * NEW: 0676 In der Auswertung "Umsätze nach Kategorien -> Im Verlauf" können durch Rechtsklick in die Grafik auch andere Intervalle (Jahr, Monat, Woche) ausgewählt werden. | |
27 | * BUG: 0675 In Kontoliste in der Spalte "verfügbarer Saldo" das Währungskennzeichen des konkreten Kontos verwenden und nicht des ersten gefundenen | |
28 | * NEW: 0674 Wenn eine Bank im Verwendungszweck zwar das "SVWZ"-Tag liefert, es aber keinen Wert enthält, wird ebenfalls ein Fallback auf die Anzeige des kompletten Verwendungszweck gemacht | |
29 | * NEW: 0673 Beim MT940-Export in Feld :25: das Währungskennzeichen weglassen und die Auszugsnummer in Feld ":28C:" mit dem Pseudowert "1" ausgeben - SAP benötigt das für den Import | |
30 | * NEW: 0672 Fehler beim Ermitteln der Kartenleser-Features tolerieren (der tanJACK USB scheint das nicht zu unterstützen) - https://github.com/hbci4j/hbci4java/commit/22b702505bc9aef54bdb7b6663c948ce4b0b91cf | |
31 | * BUG: 0671 Export-Optionen "Saldo ausblenden" und "Summenzeile anzeigen" funktionierten nur, wenn die Checkboxen beim Export betätigt wurden - https://homebanking-hilfe.de/forum/topic.php?p=138415 | |
32 | ||
0 | 33 | 2018-06-27 Version 2.8.3 |
1 | 34 | |
2 | 35 | * NEW: 0670 chipTAN USB auch dann anbieten, wenn zwar chipTAN optisch ausgewählt aber ein Kartenleser gefunden wurde |
Binary diff not shown
0 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
1 | <!-- Created with Inkscape (http://www.inkscape.org/) --> | |
2 | ||
3 | <svg | |
4 | xmlns:dc="http://purl.org/dc/elements/1.1/" | |
5 | xmlns:cc="http://creativecommons.org/ns#" | |
6 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
7 | xmlns:svg="http://www.w3.org/2000/svg" | |
8 | xmlns="http://www.w3.org/2000/svg" | |
9 | xmlns:xlink="http://www.w3.org/1999/xlink" | |
10 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |
11 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |
12 | width="210mm" | |
13 | height="297mm" | |
14 | viewBox="0 0 210 297" | |
15 | version="1.1" | |
16 | id="svg8" | |
17 | inkscape:version="0.92.3 (2405546, 2018-03-11)" | |
18 | sodipodi:docname="camtsetup.svg" | |
19 | inkscape:export-filename="/work/willuhn/git/hibiscus/src/img/300/camtsetup.png" | |
20 | inkscape:export-xdpi="84.57" | |
21 | inkscape:export-ydpi="84.57"> | |
22 | <defs | |
23 | id="defs2"><marker | |
24 | inkscape:stockid="Arrow1Mend" | |
25 | orient="auto" | |
26 | refY="0.0" | |
27 | refX="0.0" | |
28 | id="Arrow1Mend" | |
29 | style="overflow:visible;" | |
30 | inkscape:isstock="true"> | |
31 | <path | |
32 | id="path1469" | |
33 | d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " | |
34 | style="fill-rule:evenodd;stroke:#6f6f6f;stroke-width:1pt;stroke-opacity:1;fill:#6f6f6f;fill-opacity:1" | |
35 | transform="scale(0.4) rotate(180) translate(10,0)" /> | |
36 | </marker> | |
37 | <marker | |
38 | inkscape:stockid="Arrow1Lstart" | |
39 | orient="auto" | |
40 | refY="0.0" | |
41 | refX="0.0" | |
42 | id="Arrow1Lstart" | |
43 | style="overflow:visible" | |
44 | inkscape:isstock="true"> | |
45 | <path | |
46 | id="path1460" | |
47 | d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " | |
48 | style="fill-rule:evenodd;stroke:#6f6f6f;stroke-width:1pt;stroke-opacity:1;fill:#6f6f6f;fill-opacity:1" | |
49 | transform="scale(0.8) translate(12.5,0)" /> | |
50 | </marker> | |
51 | <marker | |
52 | inkscape:stockid="Arrow2Send" | |
53 | orient="auto" | |
54 | refY="0.0" | |
55 | refX="0.0" | |
56 | id="Arrow2Send" | |
57 | style="overflow:visible;" | |
58 | inkscape:isstock="true"> | |
59 | <path | |
60 | id="path1493" | |
61 | style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#6f6f6f;stroke-opacity:1;fill:#6f6f6f;fill-opacity:1" | |
62 | d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " | |
63 | transform="scale(0.3) rotate(180) translate(-2.3,0)" /> | |
64 | </marker> | |
65 | <marker | |
66 | inkscape:stockid="Arrow2Mend" | |
67 | orient="auto" | |
68 | refY="0.0" | |
69 | refX="0.0" | |
70 | id="Arrow2Mend" | |
71 | style="overflow:visible;" | |
72 | inkscape:isstock="true"> | |
73 | <path | |
74 | id="path1487" | |
75 | style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#6f6f6f;stroke-opacity:1;fill:#6f6f6f;fill-opacity:1" | |
76 | d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " | |
77 | transform="scale(0.6) rotate(180) translate(0,0)" /> | |
78 | </marker> | |
79 | <marker | |
80 | inkscape:stockid="Arrow2Lend" | |
81 | orient="auto" | |
82 | refY="0.0" | |
83 | refX="0.0" | |
84 | id="Arrow2Lend" | |
85 | style="overflow:visible;" | |
86 | inkscape:isstock="true"> | |
87 | <path | |
88 | id="path1481" | |
89 | style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#6f6f6f;stroke-opacity:1;fill:#6f6f6f;fill-opacity:1" | |
90 | d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " | |
91 | transform="scale(1.1) rotate(180) translate(1,0)" /> | |
92 | </marker> | |
93 | <marker | |
94 | inkscape:stockid="Arrow1Lend" | |
95 | orient="auto" | |
96 | refY="0.0" | |
97 | refX="0.0" | |
98 | id="Arrow1Lend" | |
99 | style="overflow:visible;" | |
100 | inkscape:isstock="true"> | |
101 | <path | |
102 | id="path1463" | |
103 | d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " | |
104 | style="fill-rule:evenodd;stroke:#6f6f6f;stroke-width:1pt;stroke-opacity:1;fill:#6f6f6f;fill-opacity:1" | |
105 | transform="scale(0.8) rotate(180) translate(12.5,0)" /> | |
106 | </marker> | |
107 | <linearGradient | |
108 | inkscape:collect="always" | |
109 | id="linearGradient1421"> | |
110 | <stop | |
111 | style="stop-color:#bdbdbd;stop-opacity:1" | |
112 | offset="0" | |
113 | id="stop1417" /> | |
114 | <stop | |
115 | id="stop1425" | |
116 | offset="0.40976068" | |
117 | style="stop-color:#fafafa;stop-opacity:0.83137256" /> | |
118 | <stop | |
119 | style="stop-color:#fefefe;stop-opacity:0.74509805" | |
120 | offset="0.46878463" | |
121 | id="stop1427" /> | |
122 | <stop | |
123 | style="stop-color:#a0a0a0;stop-opacity:0.66274512" | |
124 | offset="1" | |
125 | id="stop1419" /> | |
126 | </linearGradient> | |
127 | <filter | |
128 | inkscape:collect="always" | |
129 | style="color-interpolation-filters:sRGB" | |
130 | id="filter1029" | |
131 | x="-0.18230396" | |
132 | width="1.3646079" | |
133 | y="-0.22848846" | |
134 | height="1.4569769"> | |
135 | <feGaussianBlur | |
136 | inkscape:collect="always" | |
137 | stdDeviation="1.3494205" | |
138 | id="feGaussianBlur1031" /> | |
139 | </filter> | |
140 | <filter | |
141 | inkscape:collect="always" | |
142 | style="color-interpolation-filters:sRGB" | |
143 | id="filter1121" | |
144 | x="-0.11554185" | |
145 | width="1.2310837" | |
146 | y="-0.082112184" | |
147 | height="1.1642244"> | |
148 | <feGaussianBlur | |
149 | inkscape:collect="always" | |
150 | stdDeviation="2.0961503" | |
151 | id="feGaussianBlur1123" /> | |
152 | </filter> | |
153 | ||
154 | ||
155 | ||
156 | ||
157 | ||
158 | ||
159 | ||
160 | ||
161 | ||
162 | ||
163 | ||
164 | ||
165 | ||
166 | ||
167 | ||
168 | ||
169 | ||
170 | ||
171 | ||
172 | ||
173 | ||
174 | ||
175 | ||
176 | ||
177 | ||
178 | ||
179 | ||
180 | ||
181 | ||
182 | ||
183 | ||
184 | ||
185 | <linearGradient | |
186 | inkscape:collect="always" | |
187 | xlink:href="#linearGradient1421" | |
188 | id="linearGradient1423" | |
189 | x1="161.86833" | |
190 | y1="63.457966" | |
191 | x2="201.7448" | |
192 | y2="63.457966" | |
193 | gradientUnits="userSpaceOnUse" /> | |
194 | <filter | |
195 | inkscape:collect="always" | |
196 | style="color-interpolation-filters:sRGB" | |
197 | id="filter2723" | |
198 | x="-0.25683135" | |
199 | width="1.5136627" | |
200 | y="-0.2960247" | |
201 | height="1.5920494"> | |
202 | <feGaussianBlur | |
203 | inkscape:collect="always" | |
204 | stdDeviation="1.3345558" | |
205 | id="feGaussianBlur2725" /> | |
206 | </filter> | |
207 | <filter | |
208 | inkscape:collect="always" | |
209 | style="color-interpolation-filters:sRGB" | |
210 | id="filter2727" | |
211 | x="-0.27834261" | |
212 | width="1.5566852" | |
213 | y="-0.0898687" | |
214 | height="1.1797374"> | |
215 | <feGaussianBlur | |
216 | inkscape:collect="always" | |
217 | stdDeviation="1.3345558" | |
218 | id="feGaussianBlur2729" /> | |
219 | </filter> | |
220 | </defs> | |
221 | <sodipodi:namedview | |
222 | id="base" | |
223 | pagecolor="#ffffff" | |
224 | bordercolor="#666666" | |
225 | borderopacity="1.0" | |
226 | inkscape:pageopacity="0.0" | |
227 | inkscape:pageshadow="2" | |
228 | inkscape:zoom="1.979899" | |
229 | inkscape:cx="549.26181" | |
230 | inkscape:cy="401.53886" | |
231 | inkscape:document-units="mm" | |
232 | inkscape:current-layer="layer1" | |
233 | showgrid="false" | |
234 | inkscape:snap-global="false" /> | |
235 | <metadata | |
236 | id="metadata5"> | |
237 | <rdf:RDF> | |
238 | <cc:Work | |
239 | rdf:about=""> | |
240 | <dc:format>image/svg+xml</dc:format> | |
241 | <dc:type | |
242 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |
243 | <dc:title></dc:title> | |
244 | </cc:Work> | |
245 | </rdf:RDF> | |
246 | </metadata> | |
247 | <g | |
248 | inkscape:label="Layer 1" | |
249 | inkscape:groupmode="layer" | |
250 | id="layer1"> | |
251 | <path | |
252 | sodipodi:nodetypes="sccssssss" | |
253 | inkscape:connector-curvature="0" | |
254 | id="path1043" | |
255 | d="m 110.38811,173.8337 h 23.06949 l 17.98406,14.22678 v 44.20244 c 0,1.57208 -1.10922,2.8377 -2.48704,2.8377 h -38.56651 c -1.37782,0 -2.48704,-1.26562 -2.48704,-2.8377 V 176.6714 c 0,-1.57209 1.10922,-2.8377 2.48704,-2.8377 z" | |
256 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.553;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#060606;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.4313364;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;filter:url(#filter1121);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> | |
257 | <path | |
258 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#3d76a4;stroke-width:5.73099995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | |
259 | d="m 106.89183,169.77046 h 23.06949 l 17.98407,14.22678 v 44.20244 c 0,1.57208 -1.10922,2.8377 -2.48704,2.8377 h -38.56652 c -1.37782,0 -2.48704,-1.26562 -2.48704,-2.8377 v -55.59152 c 0,-1.57209 1.10922,-2.8377 2.48704,-2.8377 z" | |
260 | id="rect819" | |
261 | inkscape:connector-curvature="0" | |
262 | sodipodi:nodetypes="sccssssss" /> | |
263 | <text | |
264 | xml:space="preserve" | |
265 | style="font-style:normal;font-weight:normal;font-size:12.34722233px;line-height:17.22174644px;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#3d76a4;fill-opacity:1;stroke:none;stroke-width:1.32474971px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | |
266 | x="126.15907" | |
267 | y="228.31453" | |
268 | id="text817"><tspan | |
269 | sodipodi:role="line" | |
270 | x="126.15907" | |
271 | y="228.31453" | |
272 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Sans;-inkscape-font-specification:'Sans Bold';text-align:center;text-anchor:middle;fill:#3d76a4;fill-opacity:1;stroke-width:1.32474971px" | |
273 | id="tspan1041">CAMT</tspan></text> | |
274 | <path | |
275 | style="opacity:0.38399999;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36500001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter1029)" | |
276 | d="m 130.60573,171.09885 c 2.01587,6.00037 0.96068,11.10305 1.27566,14.31585 1.73239,-0.29923 16.22149,-0.45673 17.15069,-0.0473 z" | |
277 | id="path851" | |
278 | inkscape:connector-curvature="0" | |
279 | sodipodi:nodetypes="cccc" /> | |
280 | <path | |
281 | sodipodi:nodetypes="cccc" | |
282 | inkscape:connector-curvature="0" | |
283 | id="path849" | |
284 | d="m 129.50409,168.58259 c 4.0475,3.82701 3.46478,10.29985 3.02381,13.27641 6.78782,-0.53546 13.6229,0.20474 16.58371,2.69309 z" | |
285 | style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36500001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |
286 | <path | |
287 | style="fill:none;fill-rule:evenodd;stroke:#3d76a4;stroke-width:2.66499996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | |
288 | d="m 129.50409,168.58259 c 4.0475,3.82701 3.46478,10.29985 3.02381,13.27641 6.78782,-0.53546 13.6229,0.20474 16.58371,2.69309" | |
289 | id="path847" | |
290 | inkscape:connector-curvature="0" | |
291 | sodipodi:nodetypes="ccc" /> | |
292 | <path | |
293 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.553;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#060606;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.4313364;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;filter:url(#filter1121);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | |
294 | d="m 78.827098,93.135783 h 23.069492 l 17.98406,14.226777 V 151.565 c 0,1.57208 -1.10922,2.8377 -2.48704,2.8377 H 78.827098 c -1.37782,0 -2.48704,-1.26562 -2.48704,-2.8377 V 95.973483 c 0,-1.57209 1.10922,-2.8377 2.48704,-2.8377 z" | |
295 | id="path1125" | |
296 | inkscape:connector-curvature="0" | |
297 | sodipodi:nodetypes="sccssssss" /> | |
298 | <path | |
299 | sodipodi:nodetypes="sccssssss" | |
300 | inkscape:connector-curvature="0" | |
301 | id="path1127" | |
302 | d="m 75.330818,89.072543 h 23.06949 l 17.984072,14.226777 v 44.20244 c 0,1.57208 -1.10922,2.8377 -2.48704,2.8377 H 75.330818 c -1.37782,0 -2.48704,-1.26562 -2.48704,-2.8377 V 91.910243 c 0,-1.57209 1.10922,-2.8377 2.48704,-2.8377 z" | |
303 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#666666;stroke-width:5.73099995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> | |
304 | <text | |
305 | id="text1133" | |
306 | y="147.84215" | |
307 | x="94.35128" | |
308 | style="font-style:normal;font-weight:normal;font-size:12.34722233px;line-height:13.82831383px;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1.06371641px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;" | |
309 | xml:space="preserve"><tspan | |
310 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Sans;-inkscape-font-specification:'Sans Bold';text-align:center;text-anchor:middle;fill:#666666;fill-opacity:1;stroke-width:1.06371641px;" | |
311 | y="147.84215" | |
312 | x="94.35128" | |
313 | sodipodi:role="line" | |
314 | id="tspan1433">MT940</tspan></text> | |
315 | <path | |
316 | sodipodi:nodetypes="cccc" | |
317 | inkscape:connector-curvature="0" | |
318 | id="path1135" | |
319 | d="m 99.044718,90.400933 c 2.015872,6.00037 0.960682,11.103047 1.275662,14.315847 1.73239,-0.29923 16.22149,-0.45673 17.15069,-0.0473 z" | |
320 | style="opacity:0.38399999;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36500001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter1029)" /> | |
321 | <path | |
322 | style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36500001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | |
323 | d="m 97.943078,87.884673 c 4.047502,3.82701 3.464782,10.29985 3.023812,13.276407 6.78782,-0.53546 13.6229,0.20474 16.58371,2.69309 z" | |
324 | id="path1137" | |
325 | inkscape:connector-curvature="0" | |
326 | sodipodi:nodetypes="cccc" /> | |
327 | <path | |
328 | sodipodi:nodetypes="ccc" | |
329 | inkscape:connector-curvature="0" | |
330 | id="path1139" | |
331 | d="m 97.943078,87.884673 c 4.047502,3.82701 3.464782,10.29985 3.023812,13.276407 6.78782,-0.53546 13.6229,0.20474 16.58371,2.69309" | |
332 | style="fill:none;fill-rule:evenodd;stroke:#666666;stroke-width:2.66499996;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |
333 | <g | |
334 | id="g1446" | |
335 | transform="matrix(0.3091787,0,0,0.3091787,35.176442,93.214905)"> | |
336 | <path | |
337 | sodipodi:nodetypes="cccccc" | |
338 | inkscape:connector-curvature="0" | |
339 | id="rect1404" | |
340 | d="m 151.47395,53.29985 h 67.94122 l 6.89807,5.811382 v 68.744418 h -74.83929 z" | |
341 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.66499996;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> | |
342 | <rect | |
343 | y="93.176338" | |
344 | x="162.15178" | |
345 | height="33.923363" | |
346 | width="53.294643" | |
347 | id="rect1407" | |
348 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.48955512;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> | |
349 | <rect | |
350 | y="53.29985" | |
351 | x="161.30135" | |
352 | height="25.985863" | |
353 | width="40.443455" | |
354 | id="rect1415" | |
355 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient1423);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.16499996;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> | |
356 | <path | |
357 | sodipodi:nodetypes="ccsssssssscccccccccccccssssccccsssscccc" | |
358 | inkscape:connector-curvature="0" | |
359 | style="fill:#000000;fill-opacity:0.98387098;stroke-width:0.15967564" | |
360 | d="m 227.45195,58.428605 -7.3069,-6.739932 c -0.29939,-0.299392 -0.70561,-0.46769 -1.12907,-0.46769 h -67.74065 c -0.88189,0 -1.59676,0.714868 -1.59676,1.596756 v 75.047551 c 0,0.88173 0.71487,1.59676 1.59676,1.59676 h 75.04755 c 0.88189,0 1.59676,-0.71503 1.59676,-1.59676 V 59.557671 c 0,-0.42346 -0.1683,-0.829515 -0.46769,-1.129066 z m -64.99933,-4.014109 h 38.32216 V 78.365843 H 162.45262 Z M 163.251,126.26854 V 94.6788 h 51.09621 v 31.58974 z m 61.47513,0 h -7.18541 V 92.73665 c 0,-0.88189 -0.71487,-1.596755 -1.59676,-1.596755 h -54.28972 c -0.88188,0 -1.59675,0.714865 -1.59675,1.596755 v 33.53189 h -7.18541 V 54.414496 h 6.38703 V 79.9626 c 0,0.881889 0.71487,1.596756 1.59676,1.596756 h 41.51566 c 0.88189,0 1.59676,-0.714867 1.59676,-1.596756 V 54.414496 h 14.38632 l 6.37152,5.804711 z" | |
361 | id="path1259" /> | |
362 | <rect | |
363 | x="219.23196" | |
364 | y="121.34135" | |
365 | style="fill:#231f20;stroke-width:0.15967564" | |
366 | width="3.1935129" | |
367 | height="3.1935129" | |
368 | id="rect1261" /> | |
369 | <path | |
370 | inkscape:connector-curvature="0" | |
371 | id="path1409" | |
372 | d="m 166.40401,102.24777 h 44.41221" | |
373 | style="fill:none;fill-rule:evenodd;stroke:#a9a9a9;stroke-width:2.19798326;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |
374 | <path | |
375 | style="fill:none;fill-rule:evenodd;stroke:#a9a9a9;stroke-width:2.19798326;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | |
376 | d="m 166.40401,109.99628 h 44.41221" | |
377 | id="path1411" | |
378 | inkscape:connector-curvature="0" /> | |
379 | <path | |
380 | inkscape:connector-curvature="0" | |
381 | id="path1413" | |
382 | d="m 166.40401,117.5558 h 44.41221" | |
383 | style="fill:none;fill-rule:evenodd;stroke:#a9a9a9;stroke-width:2.19798326;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | |
384 | <rect | |
385 | y="53.205357" | |
386 | x="186.53125" | |
387 | height="20.221727" | |
388 | width="8.4099703" | |
389 | id="rect1429" | |
390 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.97849462;fill-rule:evenodd;stroke:none;stroke-width:2.16499996;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> | |
391 | </g> | |
392 | <text | |
393 | id="text1456" | |
394 | y="209.45544" | |
395 | x="125.61912" | |
396 | style="font-style:normal;font-weight:normal;font-size:16.7424984px;line-height:23.35221863px;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#5e5e5e;fill-opacity:1;stroke:none;stroke-width:1.79632437px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;" | |
397 | xml:space="preserve"><tspan | |
398 | id="tspan1454" | |
399 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Sans;-inkscape-font-specification:'Sans Bold';text-align:center;text-anchor:middle;fill:#5e5e5e;fill-opacity:1;stroke-width:1.79632437px;" | |
400 | y="209.45544" | |
401 | x="125.61912" | |
402 | sodipodi:role="line"></></tspan></text> | |
403 | <path | |
404 | sodipodi:nodetypes="cc" | |
405 | inkscape:connector-curvature="0" | |
406 | id="path2585" | |
407 | d="m 84.769881,163.26256 c -5.988006,24.47914 -2.874726,29.48428 8.522642,35.64015" | |
408 | style="opacity:0.68199989;fill:none;fill-rule:evenodd;stroke:#6f6f6f;stroke-width:2.59508085;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter2727)" /> | |
409 | <path | |
410 | inkscape:transform-center-x="0.73614057" | |
411 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.68199989;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#6f6f6f;fill-opacity:1;fill-rule:evenodd;stroke:#6f6f6f;stroke-width:1.66467774;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;filter:url(#filter2723);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | |
412 | inkscape:transform-center-y="-0.97010407" | |
413 | d="M 96.854902,201.57525 84.38394,198.445 l 5.524401,-7.68957 z" | |
414 | id="path2587" | |
415 | inkscape:connector-curvature="0" | |
416 | sodipodi:nodetypes="cccc" /> | |
417 | <path | |
418 | style="fill:none;fill-rule:evenodd;stroke:#509c6b;stroke-width:2.59508085;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | |
419 | d="m 83.534743,161.20662 c -5.988006,24.47914 -2.874726,29.48428 8.522642,35.64015" | |
420 | id="path1458" | |
421 | inkscape:connector-curvature="0" | |
422 | sodipodi:nodetypes="cc" /> | |
423 | <path | |
424 | sodipodi:nodetypes="cccc" | |
425 | inkscape:connector-curvature="0" | |
426 | id="path2583" | |
427 | d="m 95.619764,199.51931 -12.470962,-3.13025 5.524401,-7.68957 z" | |
428 | inkscape:transform-center-y="-0.97010407" | |
429 | style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#509c6b;fill-opacity:1;fill-rule:evenodd;stroke:#509c6b;stroke-width:1.66467774;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | |
430 | inkscape:transform-center-x="0.73614057" /> | |
431 | </g> | |
432 | </svg> |
2 | 2 | <plugin xmlns="http://www.willuhn.de/schema/jameica-plugin" |
3 | 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
4 | 4 | xsi:schemaLocation="http://www.willuhn.de/schema/jameica-plugin http://www.willuhn.de/schema/jameica-plugin-1.2.xsd" |
5 | name="hibiscus" version="2.8.3" class="de.willuhn.jameica.hbci.HBCI"> | |
5 | name="hibiscus" version="2.8.4" class="de.willuhn.jameica.hbci.HBCI"> | |
6 | 6 | |
7 | 7 | <description>HBCI-Onlinebanking-Plugin für Jameica</description> |
8 | <url>https://www.willuhn.de/products/hibiscus/releases/2.8/hibiscus-2.8.3.zip</url> | |
8 | <url>https://www.willuhn.de/products/hibiscus/releases/2.8/hibiscus-2.8.4.zip</url> | |
9 | 9 | <homepage>http://www.willuhn.de/products/hibiscus</homepage> |
10 | 10 | <license>GPL - http://www.gnu.org/copyleft/gpl.html</license> |
11 | 11 | <icon>hibiscus-large.png</icon> |
54 | 54 | |
55 | 55 | <navigation> |
56 | 56 | <item id="hibiscus.navi" name="Hibiscus" icon-close="folder.png" icon-open="folder-open.png"> |
57 | <item id="hibiscus.navi.passports" name="Bank-Zugänge" icon-close="user-info.png" action="de.willuhn.jameica.hbci.gui.action.PassportList" /> | |
57 | <item id="hibiscus.navi.passports" name="Bank-Zugänge" icon-close="system-users.png" action="de.willuhn.jameica.hbci.gui.action.PassportList" /> | |
58 | 58 | <item id="hibiscus.navi.accounts" name="Konten" icon-close="system-file-manager.png" action="de.willuhn.jameica.hbci.gui.action.KontoList" /> |
59 | 59 | <item id="hibiscus.navi.umsatz" name="Umsätze" icon-close="emblem-documents.png" action="de.willuhn.jameica.hbci.gui.action.KontoauszugList" /> |
60 | 60 | <item id="hibiscus.navi.kontoauszug" name="Elektr. Kontoauszüge" icon-close="application-pdf.png" action="de.willuhn.jameica.hbci.gui.action.KontoauszugPdfList" /> |
176 | 176 | empfaenger_blz varchar(15), |
177 | 177 | empfaenger_name varchar(255), |
178 | 178 | betrag double NOT NULL, |
179 | zweck varchar(35), | |
179 | zweck varchar(255), | |
180 | 180 | zweck2 varchar(35), |
181 | 181 | zweck3 varchar(1000), |
182 | 182 | datum date NOT NULL, |
191 | 191 | flags int(1) NULL, |
192 | 192 | gvcode varchar(3) NULL, |
193 | 193 | addkey varchar(3) NULL, |
194 | txid varchar(100), | |
195 | purposecode varchar(10), | |
196 | endtoendid varchar(100), | |
194 | 197 | UNIQUE (id), |
195 | 198 | PRIMARY KEY (id) |
196 | 199 | ); |
442 | 445 | CREATE INDEX idx_umsatz_valuta ON umsatz(valuta); |
443 | 446 | CREATE INDEX idx_umsatz_flags ON umsatz(flags); |
444 | 447 | |
445 | INSERT INTO version (name,version) values ('db',62); | |
448 | INSERT INTO version (name,version) values ('db',64); | |
446 | 449 | |
447 | 450 | COMMIT; |
285 | 285 | , empfaenger_blz VARCHAR(15) |
286 | 286 | , empfaenger_name VARCHAR(255) |
287 | 287 | , betrag DOUBLE NOT NULL |
288 | , zweck VARCHAR(35) | |
288 | , zweck VARCHAR(255) | |
289 | 289 | , zweck2 VARCHAR(35) |
290 | 290 | , zweck3 TEXT |
291 | 291 | , datum DATE NOT NULL |
300 | 300 | , flags int(1) |
301 | 301 | , gvcode varchar(3) |
302 | 302 | , addkey varchar(3) |
303 | , txid varchar(100) | |
304 | , purposecode varchar(10) | |
305 | , endtoendid varchar(100) | |
303 | 306 | , UNIQUE (id) |
304 | 307 | , PRIMARY KEY (id) |
305 | 308 | ) ENGINE=InnoDB; |
469 | 472 | ALTER TABLE ueberweisung ADD INDEX (termin); |
470 | 473 | ALTER TABLE lastschrift ADD INDEX (termin); |
471 | 474 | |
472 | INSERT INTO version (name,version) values ('db',62); | |
475 | INSERT INTO version (name,version) values ('db',64); |
156 | 156 | empfaenger_blz varchar(15), |
157 | 157 | empfaenger_name varchar(255), |
158 | 158 | betrag float NOT NULL, |
159 | zweck varchar(35), | |
159 | zweck varchar(255), | |
160 | 160 | zweck2 varchar(35), |
161 | 161 | zweck3 varchar(1000), |
162 | 162 | datum date NOT NULL, |
170 | 170 | umsatztyp_id integer NULL, |
171 | 171 | flags integer NULL, |
172 | 172 | gvcode varchar(3) NULL, |
173 | addkey varchar(3) NULL | |
173 | addkey varchar(3) NULL, | |
174 | txid varchar(100), | |
175 | purposecode varchar(10), | |
176 | endtoendid varchar(100) | |
174 | 177 | ); |
175 | 178 | |
176 | 179 | CREATE TABLE umsatztyp ( |
388 | 391 | CREATE INDEX idx_umsatz_valuta ON umsatz(valuta); |
389 | 392 | CREATE INDEX idx_umsatz_flags ON umsatz(flags); |
390 | 393 | |
391 | INSERT INTO version (name,version) values ('db',62); | |
394 | INSERT INTO version (name,version) values ('db',63); |
45 | 45 | */ |
46 | 46 | protected void updateUPD(HBCIPassport passport) |
47 | 47 | { |
48 | BPDUtil.updateCache(passport,Prefix.UPD); | |
48 | if (BPDUtil.updateCache(passport,Prefix.UPD)) | |
49 | { | |
50 | // Wenn wir neue UPD haben, aktualisieren wir gleich auch nochmal die BPD | |
51 | // Denn wenn wir die UPD haben, sind auch die Konten vorhanden. Und damit | |
52 | // koennen wir die BPD ebenfalls korrekt fuer alle verfuegbaren Kundenkennungen speichern | |
53 | BPDUtil.expireCache(passport,Prefix.BPD); | |
54 | BPDUtil.updateCache(passport,Prefix.BPD); | |
55 | } | |
49 | 56 | } |
50 | 57 | |
51 | 58 | /** |
134 | 134 | public final static int HBCI_TRANSFER_BZU_LENGTH = settings.getInt("hbci.transfer.bzu.length",13); |
135 | 135 | |
136 | 136 | /** |
137 | * Maximale Text-Laenge einer Verwendungszweck-Zeile fuer Auslandsueberweisungen. | |
138 | */ | |
139 | public final static int HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH = settings.getInt("hbci.foreigntransfer.usage.maxlength",140); | |
137 | * Maximale Text-Laenge einer Verwendungszweck-Zeile bei SEPA-Auftraegen. | |
138 | */ | |
139 | public final static int HBCI_SEPATRANSFER_USAGE_MAXLENGTH = settings.getInt("hbci.foreigntransfer.usage.maxlength",140); | |
140 | 140 | |
141 | 141 | /** |
142 | 142 | * Maximale Anzahl von Verwendungszwecken. |
95 | 95 | * Template fuer den Dateinamen. |
96 | 96 | */ |
97 | 97 | KONTOAUSZUG_TEMPLATE_NAME("kontoauszug.template.name","Vorlage für Dateinamen","${jahr}-${nummer}"), |
98 | ||
99 | /** | |
100 | * Legt fest, ob CAMT fuer den Umsatz-Abruf verwendet werden soll. | |
101 | */ | |
102 | UMSATZ_CAMT("umsatz.camt","CAMT-Format für Umsatz-Abruf verwenden",null); | |
98 | 103 | |
99 | 104 | ; |
100 | 105 |
11 | 11 | import de.willuhn.jameica.gui.Action; |
12 | 12 | import de.willuhn.jameica.hbci.HBCI; |
13 | 13 | import de.willuhn.jameica.hbci.gui.dialogs.ExportDialog; |
14 | import de.willuhn.jameica.hbci.server.EinnahmeAusgabe; | |
14 | import de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum; | |
15 | 15 | import de.willuhn.jameica.messaging.StatusBarMessage; |
16 | 16 | import de.willuhn.jameica.system.Application; |
17 | 17 | import de.willuhn.jameica.system.OperationCanceledException; |
32 | 32 | */ |
33 | 33 | public void handleAction(Object context) throws ApplicationException |
34 | 34 | { |
35 | if (context == null || !(context instanceof EinnahmeAusgabe[])) | |
35 | if (context == null || !(context instanceof EinnahmeAusgabeZeitraum[])) | |
36 | 36 | throw new ApplicationException(i18n.tr("Bitte wählen Sie die zu exportierenden Daten aus")); |
37 | 37 | |
38 | 38 | try |
39 | 39 | { |
40 | ExportDialog d = new ExportDialog((EinnahmeAusgabe[]) context,EinnahmeAusgabe.class); | |
40 | ExportDialog d = new ExportDialog((EinnahmeAusgabeZeitraum[])context,EinnahmeAusgabeZeitraum.class); | |
41 | 41 | d.open(); |
42 | 42 | } |
43 | 43 | catch (OperationCanceledException oce) |
55 | 55 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Fehler bei der Erstellung der Liste"),StatusBarMessage.TYPE_ERROR)); |
56 | 56 | } |
57 | 57 | } |
58 | ||
59 | 58 | } |
60 | ||
61 | /******************************************************************************* | |
62 | * $Log: EinnahmeAusgabeExport.java,v $ | |
63 | * Revision 1.5 2011/05/11 10:20:28 willuhn | |
64 | * @N OCE fangen | |
65 | * | |
66 | * Revision 1.4 2010-08-24 17:38:04 willuhn | |
67 | * @N BUGZILLA 896 | |
68 | * | |
69 | * Revision 1.3 2009/04/05 21:16:22 willuhn | |
70 | * @B BUGZILLA 716 | |
71 | ******************************************************************************/ |
11 | 11 | import de.willuhn.jameica.gui.Action; |
12 | 12 | import de.willuhn.jameica.gui.GUI; |
13 | 13 | import de.willuhn.jameica.hbci.HBCI; |
14 | import de.willuhn.jameica.hbci.PassportRegistry; | |
14 | 15 | import de.willuhn.jameica.hbci.gui.views.KontoList; |
15 | 16 | import de.willuhn.jameica.hbci.passport.Passport; |
17 | import de.willuhn.jameica.hbci.rmi.Konto; | |
16 | 18 | import de.willuhn.jameica.system.Application; |
17 | 19 | import de.willuhn.jameica.system.OperationCanceledException; |
18 | 20 | import de.willuhn.logging.Logger; |
32 | 34 | */ |
33 | 35 | public void handleAction(Object context) throws ApplicationException |
34 | 36 | { |
35 | if (context == null || !(context instanceof Passport)) | |
36 | throw new ApplicationException(i18n.tr("Kein Sicherheitsmedium ausgewählt oder keines verfügbar")); | |
37 | if (context == null) | |
38 | throw new ApplicationException(i18n.tr("Bitte wählen Sie ein Konto oder einen Bankzugang aus")); | |
37 | 39 | |
38 | final Passport p = (Passport) context; | |
40 | Passport passport = null; | |
41 | ||
42 | if (context instanceof Konto) | |
43 | { | |
44 | try | |
45 | { | |
46 | Konto k = (Konto) context; | |
47 | passport = PassportRegistry.findByClass(k.getPassportClass()); | |
48 | } | |
49 | catch (ApplicationException ae) | |
50 | { | |
51 | throw ae; | |
52 | } | |
53 | catch (Exception e) | |
54 | { | |
55 | Logger.error("error while reading passport from select box",e); | |
56 | throw new ApplicationException(i18n.tr("Fehler beim Auslesen der Konto-Informationen")); | |
57 | } | |
58 | } | |
59 | else if (context instanceof Passport) | |
60 | { | |
61 | passport = (Passport) context; | |
62 | } | |
63 | ||
64 | final Passport p = passport; | |
39 | 65 | |
40 | 66 | GUI.startSync(new Runnable() |
41 | 67 | { |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2004 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.gui.action; | |
11 | ||
12 | import de.willuhn.jameica.gui.Action; | |
13 | import de.willuhn.jameica.hbci.HBCI; | |
14 | import de.willuhn.jameica.hbci.gui.dialogs.KontoauszugSettingsDialog; | |
15 | import de.willuhn.jameica.system.Application; | |
16 | import de.willuhn.jameica.system.OperationCanceledException; | |
17 | import de.willuhn.util.ApplicationException; | |
18 | import de.willuhn.util.I18N; | |
19 | ||
20 | /** | |
21 | * Action fuer die Einstellungen des Kontoauszugsabrufes. | |
22 | */ | |
23 | public class KontoauszugSettings implements Action | |
24 | { | |
25 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
26 | ||
27 | /** | |
28 | * @see de.willuhn.jameica.gui.Action#handleAction(java.lang.Object) | |
29 | */ | |
30 | @Override | |
31 | public void handleAction(Object context) throws ApplicationException | |
32 | { | |
33 | try | |
34 | { | |
35 | KontoauszugSettingsDialog d = new KontoauszugSettingsDialog(); | |
36 | d.open(); | |
37 | } | |
38 | catch (ApplicationException ae) | |
39 | { | |
40 | throw ae; | |
41 | } | |
42 | catch (OperationCanceledException oce) | |
43 | { | |
44 | throw oce; | |
45 | } | |
46 | catch (Exception e) | |
47 | { | |
48 | throw new ApplicationException(i18n.tr("Fehler beim Speichern der Einstellungen"),e); | |
49 | } | |
50 | } | |
51 | ||
52 | } | |
53 | ||
54 |
27 | 27 | */ |
28 | 28 | public class UmsatzDetailEdit implements Action |
29 | 29 | { |
30 | ||
31 | private boolean createReverse=false; | |
32 | private Konto toBookTo=null; | |
30 | private boolean createReverse = false; | |
31 | private Konto toBookTo = null; | |
33 | 32 | |
34 | 33 | /** |
35 | 34 | * setzt ein flag, dass die Gegenbuchung des Kontext-Objects erstellt werden soll |
36 | 35 | * @param toBookTo Offline-Konto, auf das die Gegenbuchung erstellt werden soll |
37 | 36 | * @return das (modifizierte) Objekt selbst |
38 | 37 | * */ |
39 | public UmsatzDetailEdit asReverse(Konto toBookTo){ | |
40 | this.createReverse=true; | |
41 | this.toBookTo=toBookTo; | |
38 | public UmsatzDetailEdit asReverse(Konto toBookTo) | |
39 | { | |
40 | this.createReverse = true; | |
41 | this.toBookTo = toBookTo; | |
42 | 42 | return this; |
43 | 43 | } |
44 | 44 | |
71 | 71 | throw new ApplicationException(i18n.tr("Fehler beim Anlegen des Umsatzes: {0}",re.getMessage())); |
72 | 72 | } |
73 | 73 | } |
74 | else if (!(context instanceof Umsatz)){ | |
74 | else if (!(context instanceof Umsatz)) | |
75 | { | |
75 | 76 | return; |
76 | }else if(createReverse){ | |
77 | } | |
78 | else if (createReverse) | |
79 | { | |
77 | 80 | try |
78 | 81 | { |
79 | 82 | Umsatz orig=(Umsatz)context; |
86 | 89 | u.setGegenkontoNummer(konto.getKontonummer()); |
87 | 90 | u.setUmsatzTyp(null); |
88 | 91 | context = u; |
89 | } catch (RemoteException e) | |
92 | } | |
93 | catch (RemoteException e) | |
90 | 94 | { |
91 | 95 | throw new ApplicationException(e); |
92 | 96 | } |
136 | 136 | } |
137 | 137 | |
138 | 138 | ButtonArea buttons = new ButtonArea(); |
139 | buttons.addButton(i18n.tr("Bank-Zugang einrichten"),new PassportDetail(),null,true,"user-info.png"); | |
139 | buttons.addButton(i18n.tr("Bank-Zugang einrichten"),new PassportDetail(),null,true,"system-users.png"); | |
140 | 140 | buttons.addButton(i18n.tr("Konten-Übersicht"),new KontoList(),null,false,"wallet-open.png"); |
141 | 141 | buttons.paint(comp); |
142 | 142 | } |
19 | 19 | import de.willuhn.jameica.hbci.Settings; |
20 | 20 | import de.willuhn.jameica.hbci.gui.action.KontoNew; |
21 | 21 | import de.willuhn.jameica.hbci.gui.parts.KontoList; |
22 | import de.willuhn.jameica.hbci.server.KontoUtil; | |
22 | 23 | import de.willuhn.jameica.system.Application; |
23 | 24 | import de.willuhn.util.I18N; |
24 | 25 | |
66 | 67 | */ |
67 | 68 | public void paint(Composite parent) throws RemoteException |
68 | 69 | { |
69 | KontoList l = new KontoList(new KontoNew()); | |
70 | KontoList l = new KontoList(KontoUtil.getKonten(null),new KontoNew()); | |
71 | l.setShowFilter(false); | |
70 | 72 | l.paint(parent); |
71 | 73 | } |
72 | 74 | |
79 | 81 | } |
80 | 82 | |
81 | 83 | } |
82 | ||
83 | ||
84 | /********************************************************************* | |
85 | * $Log: Konten.java,v $ | |
86 | * Revision 1.9 2010/08/12 17:12:32 willuhn | |
87 | * @N Saldo-Chart komplett ueberarbeitet (Daten wurden vorher mehrmals geladen, Summen-Funktion, Anzeige mehrerer Konten, Durchschnitt ueber mehrere Konten, Bugfixing, echte "Homogenisierung" der Salden via SaldoFinder) | |
88 | * | |
89 | * Revision 1.8 2010-07-29 21:43:22 willuhn | |
90 | * @N BUGZILLA 886 | |
91 | * | |
92 | * Revision 1.7 2010/06/17 12:16:52 willuhn | |
93 | * @N BUGZILLA 530 | |
94 | * | |
95 | * Revision 1.6 2008/01/04 16:39:31 willuhn | |
96 | * @N Weitere Hoehen-Angaben von Komponenten | |
97 | * | |
98 | * Revision 1.5 2007/12/18 17:10:22 willuhn | |
99 | * @N Neues ExpandPart | |
100 | * @N Boxen auf der Startseite koennen jetzt zusammengeklappt werden | |
101 | * | |
102 | * Revision 1.4 2007/08/29 10:04:42 willuhn | |
103 | * @N Bug 476 | |
104 | * | |
105 | * Revision 1.3 2006/06/29 23:10:33 willuhn | |
106 | * @R Box-System aus Hibiscus in Jameica-Source verschoben | |
107 | * @C keine eigene Startseite mehr, jetzt alles ueber Jameica-Boxsystem geregelt | |
108 | * | |
109 | * Revision 1.2 2006/03/27 21:34:16 willuhn | |
110 | * *** empty log message *** | |
111 | * | |
112 | * Revision 1.1 2006/03/20 00:35:54 willuhn | |
113 | * @N new box "Konten-Übersicht" | |
114 | * | |
115 | **********************************************************************/⏎ |
74 | 74 | * Liefert das eigentliche SWT-Chart-Objekt. |
75 | 75 | * @return das eigentliche SWT-Chart-Objekt. |
76 | 76 | */ |
77 | protected org.swtchart.Chart getChart() | |
77 | public org.swtchart.Chart getChart() | |
78 | 78 | { |
79 | 79 | return this.chart; |
80 | 80 | } |
+3
-3
31 | 31 | import de.willuhn.jameica.hbci.gui.input.BICInput; |
32 | 32 | import de.willuhn.jameica.hbci.gui.input.IBANInput; |
33 | 33 | import de.willuhn.jameica.hbci.gui.input.PurposeCodeInput; |
34 | import de.willuhn.jameica.hbci.gui.input.ZweckInput; | |
34 | 35 | import de.willuhn.jameica.hbci.rmi.Address; |
35 | 36 | import de.willuhn.jameica.hbci.rmi.HibiscusAddress; |
36 | 37 | import de.willuhn.jameica.hbci.rmi.SepaSammelTransfer; |
52 | 53 | |
53 | 54 | // Eingabe-Felder |
54 | 55 | private Input betrag = null; |
55 | private TextInput zweck = null; | |
56 | private ZweckInput zweck = null; | |
56 | 57 | |
57 | 58 | private AddressInput empfName = null; |
58 | 59 | private TextInput empfkto = null; |
186 | 187 | |
187 | 188 | SepaSammelTransferBuchung s = this.getBuchung(); |
188 | 189 | |
189 | zweck = new TextInput(s.getZweck(),HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
190 | zweck.setValidChars(HBCIProperties.HBCI_SEPA_VALIDCHARS); | |
190 | zweck = new ZweckInput(s.getZweck()); | |
191 | 191 | zweck.setEnabled(!s.getSammelTransfer().ausgefuehrt()); |
192 | 192 | return zweck; |
193 | 193 | } |
41 | 41 | import de.willuhn.jameica.hbci.gui.input.PurposeCodeInput; |
42 | 42 | import de.willuhn.jameica.hbci.gui.input.ReminderIntervalInput; |
43 | 43 | import de.willuhn.jameica.hbci.gui.input.TerminInput; |
44 | import de.willuhn.jameica.hbci.gui.input.ZweckInput; | |
44 | 45 | import de.willuhn.jameica.hbci.gui.parts.AuslandsUeberweisungList; |
45 | 46 | import de.willuhn.jameica.hbci.reminder.ReminderUtil; |
46 | 47 | import de.willuhn.jameica.hbci.rmi.Address; |
72 | 73 | // Eingabe-Felder |
73 | 74 | private KontoInput kontoAuswahl = null; |
74 | 75 | private Input betrag = null; |
75 | private TextInput zweck = null; | |
76 | private ZweckInput zweck = null; | |
76 | 77 | |
77 | 78 | private AddressInput empfName = null; |
78 | 79 | private TextInput empfkto = null; |
270 | 271 | { |
271 | 272 | if (zweck != null) |
272 | 273 | return zweck; |
273 | zweck = new TextInput(getTransfer().getZweck(),HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
274 | zweck.setValidChars(HBCIProperties.HBCI_SEPA_VALIDCHARS); | |
274 | zweck = new ZweckInput(getTransfer().getZweck()); | |
275 | 275 | zweck.setEnabled(!getTransfer().ausgefuehrt()); |
276 | 276 | return zweck; |
277 | 277 | } |
10 | 10 | |
11 | 11 | import java.rmi.RemoteException; |
12 | 12 | import java.util.ArrayList; |
13 | import java.util.Calendar; | |
13 | 14 | import java.util.Date; |
14 | 15 | import java.util.List; |
15 | 16 | |
16 | import org.eclipse.swt.widgets.TableItem; | |
17 | import org.eclipse.swt.widgets.TreeItem; | |
17 | 18 | |
18 | 19 | import de.willuhn.datasource.rmi.DBIterator; |
19 | 20 | import de.willuhn.jameica.gui.AbstractControl; |
20 | 21 | import de.willuhn.jameica.gui.AbstractView; |
21 | 22 | import de.willuhn.jameica.gui.GUI; |
22 | 23 | import de.willuhn.jameica.gui.formatter.CurrencyFormatter; |
23 | import de.willuhn.jameica.gui.formatter.TableFormatter; | |
24 | import de.willuhn.jameica.gui.formatter.TreeFormatter; | |
24 | 25 | import de.willuhn.jameica.gui.input.DateInput; |
25 | 26 | import de.willuhn.jameica.gui.input.Input; |
26 | import de.willuhn.jameica.gui.parts.TablePart; | |
27 | import de.willuhn.jameica.gui.input.SelectInput; | |
28 | import de.willuhn.jameica.gui.parts.TreePart; | |
27 | 29 | import de.willuhn.jameica.gui.util.Color; |
28 | 30 | import de.willuhn.jameica.gui.util.Font; |
29 | 31 | import de.willuhn.jameica.hbci.HBCI; |
36 | 38 | import de.willuhn.jameica.hbci.gui.input.RangeInput; |
37 | 39 | import de.willuhn.jameica.hbci.rmi.Konto; |
38 | 40 | import de.willuhn.jameica.hbci.server.EinnahmeAusgabe; |
41 | import de.willuhn.jameica.hbci.server.EinnahmeAusgabeTreeNode; | |
39 | 42 | import de.willuhn.jameica.messaging.StatusBarMessage; |
40 | 43 | import de.willuhn.jameica.system.Application; |
41 | 44 | import de.willuhn.jameica.util.DateUtil; |
49 | 52 | { |
50 | 53 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
51 | 54 | |
52 | private KontoInput kontoAuswahl = null; | |
53 | private DateInput start = null; | |
54 | private DateInput end = null; | |
55 | private RangeInput range = null; | |
56 | ||
57 | private TablePart table = null; | |
55 | private KontoInput kontoAuswahl = null; | |
56 | private DateInput start = null; | |
57 | private DateInput end = null; | |
58 | private RangeInput range = null; | |
59 | private SelectInput interval = null; | |
60 | ||
61 | private TreePart tree = null; | |
62 | ||
63 | /** | |
64 | * Gruppierung der Einnahmen/Ausgaben nach Zeitraum. | |
65 | */ | |
66 | private enum Interval | |
67 | { | |
68 | ALL(-1, -1, i18n.tr("Gesamtzeitraum")), | |
69 | YEAR(Calendar.DAY_OF_YEAR, Calendar.YEAR,i18n.tr("Jahr")), | |
70 | MONTH(Calendar.DAY_OF_MONTH, Calendar.MONDAY, i18n.tr("Monat")), | |
71 | ||
72 | ; | |
73 | ||
74 | private String name; | |
75 | private int type; | |
76 | private int size; | |
77 | ||
78 | /** | |
79 | * ct. | |
80 | * @param type | |
81 | * @param size | |
82 | * @param name | |
83 | */ | |
84 | private Interval(int type, int size, String name) | |
85 | { | |
86 | this.name = name; | |
87 | this.type = type; | |
88 | this.size = size; | |
89 | } | |
90 | ||
91 | /** | |
92 | * @see java.lang.Enum#toString() | |
93 | */ | |
94 | @Override | |
95 | public String toString() | |
96 | { | |
97 | return this.name; | |
98 | } | |
99 | } | |
58 | 100 | |
59 | 101 | /** |
60 | 102 | * ct. |
128 | 170 | } |
129 | 171 | |
130 | 172 | /** |
173 | * Liefert ein Auswahl-Feld für die zeitliche Gruppierung. | |
174 | * @return Auswahl-Feld | |
175 | * */ | |
176 | public SelectInput getInterval() | |
177 | { | |
178 | if(this.interval !=null) | |
179 | return this.interval; | |
180 | ||
181 | this.interval = new SelectInput(Interval.values(), null); | |
182 | this.interval.setName(i18n.tr("Gruppierung nach")); | |
183 | return this.interval; | |
184 | } | |
185 | ||
186 | /** | |
131 | 187 | * Liefert eine Tabelle mit den Einnahmen/Ausgaben und Salden |
132 | 188 | * @return Tabelle mit den Einnahmen/Ausgaben und Salden |
133 | 189 | * @throws RemoteException |
134 | 190 | */ |
135 | public TablePart getTable() throws RemoteException | |
136 | { | |
137 | if (this.table != null) | |
138 | return this.table; | |
139 | ||
140 | table = new TablePart(getWerte(), null); | |
141 | table.addColumn(i18n.tr("Konto"), "text"); | |
142 | table.addColumn(i18n.tr("Anfangssaldo"), "anfangssaldo",new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
143 | table.addColumn(i18n.tr("Einnahmen"), "einnahmen", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
144 | table.addColumn(i18n.tr("Ausgaben"), "ausgaben", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
145 | table.addColumn(i18n.tr("Endsaldo"), "endsaldo", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
146 | table.addColumn(i18n.tr("Plus/Minus"), "plusminus", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
147 | table.addColumn(i18n.tr("Differenz"), "differenz", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
148 | ||
149 | table.setFormatter(new TableFormatter() | |
191 | public TreePart getTree() throws RemoteException | |
192 | { | |
193 | if (this.tree != null) | |
194 | return this.tree; | |
195 | ||
196 | tree = new TreePart(getWerte(), null); | |
197 | tree.addColumn(i18n.tr("Konto"), "text"); | |
198 | tree.addColumn(i18n.tr("Anfangssaldo"), "anfangssaldo",new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
199 | tree.addColumn(i18n.tr("Einnahmen"), "einnahmen", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
200 | tree.addColumn(i18n.tr("Ausgaben"), "ausgaben", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
201 | tree.addColumn(i18n.tr("Endsaldo"), "endsaldo", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
202 | tree.addColumn(i18n.tr("Plus/Minus"), "plusminus", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
203 | tree.addColumn(i18n.tr("Differenz"), "differenz", new CurrencyFormatter(HBCIProperties.CURRENCY_DEFAULT_DE, HBCI.DECIMALFORMAT)); | |
204 | ||
205 | tree.setFormatter(new TreeFormatter() | |
150 | 206 | { |
151 | 207 | /** |
152 | 208 | * @see de.willuhn.jameica.gui.formatter.TableFormatter#format(org.eclipse.swt.widgets.TableItem) |
153 | 209 | */ |
154 | public void format(TableItem item) | |
210 | public void format(TreeItem item) | |
155 | 211 | { |
156 | if (item == null) | |
212 | if (item == null || item.getData() instanceof EinnahmeAusgabeTreeNode) | |
157 | 213 | return; |
158 | 214 | |
159 | 215 | EinnahmeAusgabe ea = (EinnahmeAusgabe) item.getData(); |
179 | 235 | } |
180 | 236 | }); |
181 | 237 | |
182 | table.setRememberColWidths(true); | |
183 | table.setSummary(false); | |
184 | return table; | |
185 | } | |
186 | ||
187 | /** | |
188 | * Ermittelt die Liste der Zeilen fuer die Tabelle. | |
238 | tree.setRememberColWidths(true); | |
239 | return tree; | |
240 | } | |
241 | ||
242 | /** | |
243 | * Ermittelt die Liste der Knoten für den Baum. Wenn keine Aufschlüsselung gewünscht ist, | |
244 | * werden die Zeilen ohne Elternknoten angezeigt. | |
189 | 245 | * @return Liste mit den Werten. |
190 | 246 | * @throws RemoteException |
191 | 247 | */ |
192 | private List<EinnahmeAusgabe> getWerte() throws RemoteException | |
193 | { | |
194 | List<EinnahmeAusgabe> list = new ArrayList<EinnahmeAusgabe>(); | |
195 | ||
248 | private List<Object> getWerte() throws RemoteException | |
249 | { | |
196 | 250 | Date start = (Date) this.getStart().getValue(); |
197 | 251 | Date end = (Date) this.getEnd().getValue(); |
198 | Object o = getKontoAuswahl().getValue(); | |
252 | ||
253 | Interval interval = (Interval) getInterval().getValue(); | |
254 | List<Object> result=new ArrayList<Object>(); | |
255 | ||
256 | // Sonderfall "alle". Es findet keine zeitliche Gruppierung statt | |
257 | if(Interval.ALL.equals(interval)) | |
258 | { | |
259 | result.addAll(this.getWerte(start, end)); | |
260 | return result; | |
261 | } | |
262 | ||
263 | EinnahmeAusgabeTreeNode node; | |
264 | Calendar calendar = Calendar.getInstance(); | |
265 | calendar.setTime(DateUtil.startOfDay(start)); | |
266 | while (calendar.getTime().before(end)) | |
267 | { | |
268 | calendar.set(interval.type, 1); | |
269 | Date nodeFrom = calendar.getTime(); | |
270 | ||
271 | // ermittle den Zeipunkt unmittelbar vor dem nächsten Zeitraumstart | |
272 | calendar.add(interval.size,1); | |
273 | calendar.setTimeInMillis(calendar.getTime().getTime()-1); | |
274 | Date nodeTo = DateUtil.startOfDay(calendar.getTime()); | |
275 | ||
276 | List<EinnahmeAusgabe> werte = this.getWerte(nodeFrom, nodeTo); | |
277 | node = new EinnahmeAusgabeTreeNode(nodeFrom, nodeTo, werte); | |
278 | result.add(node); | |
279 | ||
280 | // ermittle den Start des nächsten Zeitraums | |
281 | calendar.setTime(nodeFrom); | |
282 | calendar.add(interval.size, 1); | |
283 | } | |
284 | return result; | |
285 | } | |
286 | ||
287 | /** | |
288 | * Liefert die Werte fuer den angegebenen Zeitraum. | |
289 | * @param start Startdatum. | |
290 | * @param end Enddatum. | |
291 | * @return die Liste der Werte. | |
292 | * @throws RemoteException | |
293 | */ | |
294 | private List<EinnahmeAusgabe> getWerte(Date start, Date end) throws RemoteException | |
295 | { | |
296 | List<EinnahmeAusgabe> list = new ArrayList<EinnahmeAusgabe>(); | |
297 | ||
298 | Object o = getKontoAuswahl().getValue(); | |
199 | 299 | |
200 | 300 | // Uhrzeit zuruecksetzen, falls vorhanden |
201 | 301 | if (start != null) start = DateUtil.startOfDay(start); |
239 | 339 | summen.setAusgaben(summeAusgaben); |
240 | 340 | summen.setEinnahmen(summeEinnahmen); |
241 | 341 | summen.setEndsaldo(summeEndsaldo); |
242 | summen.setEnddatum((Date) this.getStart().getValue()); | |
243 | summen.setStartdatum((Date) this.getEnd().getValue()); | |
342 | summen.setEnddatum(start); | |
343 | summen.setStartdatum(end); | |
244 | 344 | list.add(summen); |
245 | 345 | |
246 | 346 | return list; |
253 | 353 | { |
254 | 354 | try |
255 | 355 | { |
256 | TablePart table = this.getTable(); | |
257 | table.removeAll(); | |
356 | TreePart tree = this.getTree(); | |
357 | tree.removeAll(); | |
258 | 358 | |
259 | 359 | Date tStart = (Date) getStart().getValue(); |
260 | 360 | Date tEnd = (Date) getEnd().getValue(); |
263 | 363 | GUI.getView().setErrorText(i18n.tr("Das Anfangsdatum muss vor dem Enddatum liegen")); |
264 | 364 | return; |
265 | 365 | } |
266 | ||
267 | List<EinnahmeAusgabe> list = this.getWerte(); | |
268 | for (EinnahmeAusgabe ea:list) | |
269 | table.addItem(ea); | |
366 | if (tStart == null || tEnd == null) | |
367 | { | |
368 | // bei einem offenen Intervall ist keine Aufschlüsselung möglich | |
369 | getInterval().setValue(Interval.ALL); | |
370 | } | |
371 | ||
372 | tree.setList(this.getWerte()); | |
270 | 373 | } |
271 | 374 | catch (RemoteException re) |
272 | 375 | { |
414 | 414 | Address a = getAddress(); |
415 | 415 | if (a instanceof HibiscusAddress) |
416 | 416 | s = ((HibiscusAddress)a).getBank(); |
417 | this.bank = new TextInput(s, HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
417 | this.bank = new TextInput(s, HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
418 | 418 | this.bank.setEnabled(isHibiscusAdresse()); |
419 | 419 | } |
420 | 420 | return this.bank; |
40 | 40 | import de.willuhn.jameica.hbci.HBCIProperties; |
41 | 41 | import de.willuhn.jameica.hbci.Settings; |
42 | 42 | import de.willuhn.jameica.hbci.gui.action.KontoDelete; |
43 | import de.willuhn.jameica.hbci.gui.action.KontoFetchFromPassport; | |
44 | 43 | import de.willuhn.jameica.hbci.gui.action.KontoNew; |
45 | 44 | import de.willuhn.jameica.hbci.gui.action.UmsatzDetail; |
46 | import de.willuhn.jameica.hbci.gui.dialogs.PassportAuswahlDialog; | |
47 | 45 | import de.willuhn.jameica.hbci.gui.dialogs.SynchronizeOptionsDialog; |
48 | 46 | import de.willuhn.jameica.hbci.gui.input.BICInput; |
49 | 47 | import de.willuhn.jameica.hbci.gui.input.BLZInput; |
671 | 669 | if (kontoList != null) |
672 | 670 | return kontoList; |
673 | 671 | |
674 | kontoList = new de.willuhn.jameica.hbci.gui.parts.KontoList(new KontoNew()); | |
672 | kontoList = new de.willuhn.jameica.hbci.gui.parts.KontoList(null,new KontoNew()); | |
675 | 673 | // BUGZILLA 81 http://www.willuhn.de/bugzilla/show_bug.cgi?id=81 |
676 | 674 | kontoList.addColumn(i18n.tr("Umsätze"),"numumsaetze"); |
677 | 675 | return kontoList; |
827 | 825 | getKonto().setFlags(flags ^ Konto.FLAG_OFFLINE); |
828 | 826 | } |
829 | 827 | |
830 | /** | |
831 | * Liest alle ueber das Sicherheitsmedium verfuegbaren Konten | |
832 | * aus und speichert sie (insofern Konten mit identischer kto-Nummer/BLZ nicht schon existieren). | |
833 | */ | |
834 | public synchronized void handleReadFromPassport() | |
835 | { | |
836 | ||
837 | try | |
838 | { | |
839 | // Checken, ob wir ein Konto ausgewaehlt haben | |
840 | Object selection = getKontoListe().getSelection(); | |
841 | Konto k = null; | |
842 | if (selection != null && (selection instanceof Konto)) | |
843 | k = (Konto) selection; | |
844 | PassportAuswahlDialog d = new PassportAuswahlDialog(k,PassportAuswahlDialog.POSITION_CENTER); | |
845 | Passport p = (Passport) d.open(); | |
846 | ||
847 | new KontoFetchFromPassport().handleAction(p); | |
848 | } | |
849 | catch (OperationCanceledException oce) | |
850 | { | |
851 | Logger.info("operation cancelled"); | |
852 | } | |
853 | catch (ApplicationException ae) | |
854 | { | |
855 | GUI.getStatusBar().setErrorText(ae.getMessage()); | |
856 | } | |
857 | catch (Exception e) | |
858 | { | |
859 | Logger.error("error while reading passport from select box",e); | |
860 | GUI.getStatusBar().setErrorText(i18n.tr("Fehler beim Auslesen der Konto-Informationen")); | |
861 | } | |
862 | } | |
863 | ||
864 | 828 | /** |
865 | 829 | * Laedt die Tabelle mit den Umsaetzen neu. |
866 | 830 | */ |
39 | 39 | import de.willuhn.jameica.hbci.gui.input.IBANInput; |
40 | 40 | import de.willuhn.jameica.hbci.gui.input.KontoInput; |
41 | 41 | import de.willuhn.jameica.hbci.gui.input.PurposeCodeInput; |
42 | import de.willuhn.jameica.hbci.gui.input.ZweckInput; | |
42 | 43 | import de.willuhn.jameica.hbci.gui.parts.SepaDauerauftragList; |
43 | 44 | import de.willuhn.jameica.hbci.rmi.Address; |
44 | 45 | import de.willuhn.jameica.hbci.rmi.HibiscusAddress; |
73 | 74 | |
74 | 75 | private KontoInput kontoAuswahl = null; |
75 | 76 | private DecimalInput betrag = null; |
76 | private TextInput zweck = null; | |
77 | private ZweckInput zweck = null; | |
77 | 78 | private AddressInput empfName = null; |
78 | 79 | private TextInput empfkto = null; |
79 | 80 | private TextInput bic = null; |
442 | 443 | * @return Eingabe-Feld. |
443 | 444 | * @throws RemoteException |
444 | 445 | */ |
445 | public TextInput getZweck() throws RemoteException | |
446 | public ZweckInput getZweck() throws RemoteException | |
446 | 447 | { |
447 | 448 | if (zweck != null) |
448 | 449 | return zweck; |
449 | 450 | |
450 | 451 | SepaDauerauftrag t = getTransfer(); |
451 | zweck = new TextInput(getTransfer().getZweck(),HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
452 | zweck.setValidChars(HBCIProperties.HBCI_SEPA_VALIDCHARS); | |
452 | zweck = new ZweckInput(getTransfer().getZweck()); | |
453 | 453 | zweck.setMandatory(true); |
454 | 454 | if (t.isActive()) |
455 | 455 | zweck.setEnabled(getBPD().getBoolean("usageeditable",true)); |
42 | 42 | import de.willuhn.jameica.hbci.gui.input.KontoInput; |
43 | 43 | import de.willuhn.jameica.hbci.gui.input.ReminderIntervalInput; |
44 | 44 | import de.willuhn.jameica.hbci.gui.input.TerminInput; |
45 | import de.willuhn.jameica.hbci.gui.input.ZweckInput; | |
45 | 46 | import de.willuhn.jameica.hbci.gui.parts.SepaLastschriftList; |
46 | 47 | import de.willuhn.jameica.hbci.reminder.ReminderUtil; |
47 | 48 | import de.willuhn.jameica.hbci.rmi.Address; |
76 | 77 | // Eingabe-Felder |
77 | 78 | private KontoInput kontoAuswahl = null; |
78 | 79 | private Input betrag = null; |
79 | private TextInput zweck = null; | |
80 | private ZweckInput zweck = null; | |
80 | 81 | |
81 | 82 | private AddressInput empfName = null; |
82 | 83 | private TextInput empfkto = null; |
391 | 392 | { |
392 | 393 | if (zweck != null) |
393 | 394 | return zweck; |
394 | zweck = new TextInput(getTransfer().getZweck(),HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
395 | zweck.setValidChars(HBCIProperties.HBCI_SEPA_VALIDCHARS); | |
395 | zweck = new ZweckInput(getTransfer().getZweck()); | |
396 | 396 | zweck.setEnabled(!getTransfer().ausgefuehrt()); |
397 | 397 | return zweck; |
398 | 398 | } |
43 | 43 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
44 | 44 | |
45 | 45 | // Eingabe-Felder |
46 | private CheckboxInput onlineMode = null; | |
47 | 46 | private CheckboxInput cachePin = null; |
48 | 47 | private CheckboxInput storePin = null; |
49 | 48 | private CheckboxInput decimalGrouping = null; |
76 | 75 | umsatzTypTree = new UmsatzTypTree(new UmsatzTypNew()); |
77 | 76 | return umsatzTypTree; |
78 | 77 | } |
79 | ||
80 | /** | |
81 | * Checkbox zur Auswahl des Online-Mode. | |
82 | * @return Checkbox. | |
83 | */ | |
84 | public CheckboxInput getOnlineMode() | |
85 | { | |
86 | if (onlineMode == null) | |
87 | onlineMode = new CheckboxInput(Settings.getOnlineMode()); | |
88 | return onlineMode; | |
89 | } | |
90 | 78 | |
91 | 79 | /** |
92 | 80 | * Checkbox zur Auswahl von Dezimal-Trennzeichen in Betraegen. |
257 | 245 | Settings.setBuchungHabenForeground(hf.getRGB()); |
258 | 246 | Settings.setBuchungSollForeground(sf.getRGB()); |
259 | 247 | |
260 | Settings.setOnlineMode(((Boolean)getOnlineMode().getValue()).booleanValue()); | |
261 | 248 | Settings.setDecimalGrouping(((Boolean)getDecimalGrouping().getValue()).booleanValue()); |
262 | 249 | Settings.setKontoCheck(((Boolean)getKontoCheck().getValue()).booleanValue()); |
263 | 250 | Settings.setKontoCheckExcludeAddressbook(((Boolean)getKontoCheckExcludeAddressbook().getValue()).booleanValue()); |
15 | 15 | import org.eclipse.swt.widgets.Event; |
16 | 16 | import org.eclipse.swt.widgets.Listener; |
17 | 17 | |
18 | import de.willuhn.datasource.BeanUtil; | |
19 | 18 | import de.willuhn.jameica.gui.AbstractControl; |
20 | 19 | import de.willuhn.jameica.gui.AbstractView; |
21 | 20 | import de.willuhn.jameica.gui.input.CheckboxInput; |
75 | 74 | private Input primanota = null; |
76 | 75 | private Input art = null; |
77 | 76 | private Input customerRef = null; |
77 | private TextInput endToEndId = null; | |
78 | 78 | private TextInput gvcode = null; |
79 | 79 | |
80 | 80 | private Input kommentar = null; |
366 | 366 | } |
367 | 367 | return this.customerRef; |
368 | 368 | } |
369 | ||
369 | ||
370 | /** | |
371 | * Liefert ein Eingabe-Feld mit der EndToEnd-ID. | |
372 | * @return Eingabe-Feld. | |
373 | * @throws RemoteException | |
374 | */ | |
375 | public Input getEndToEndId() throws RemoteException | |
376 | { | |
377 | if (this.endToEndId == null) | |
378 | { | |
379 | String eref = StringUtils.trimToNull(getUmsatz().getEndToEndId()); | |
380 | ||
381 | // Fuer die Abwaertskompatibilitaet | |
382 | if (eref == null) | |
383 | eref = VerwendungszweckUtil.getTag(getUmsatz(),Tag.EREF); | |
384 | ||
385 | this.endToEndId = new TextInput(eref,HBCIProperties.HBCI_SEPA_ENDTOENDID_MAXLENGTH); | |
386 | this.endToEndId.setValidChars(HBCIProperties.HBCI_SEPA_VALIDCHARS); | |
387 | this.endToEndId.setName(i18n.tr("End-to-End ID")); | |
388 | this.endToEndId.setEnabled(false); | |
389 | ||
390 | } | |
391 | return this.endToEndId; | |
392 | } | |
393 | ||
370 | 394 | /** |
371 | 395 | * Liefert ein Eingabe-Feld fuer den GV-Code. |
372 | 396 | * @return Eingabe-Feld. |
455 | 479 | if (showAll) |
456 | 480 | return VerwendungszweckUtil.toString(u); |
457 | 481 | |
458 | return (String) BeanUtil.get(u,Tag.SVWZ.name()); | |
482 | return (String) u.getAttribute(Tag.SVWZ.name()); | |
459 | 483 | } |
460 | 484 | catch (RemoteException re) |
461 | 485 | { |
263 | 263 | input.setEnabled(true); |
264 | 264 | return input; |
265 | 265 | } |
266 | ||
267 | /** | |
268 | * @see de.willuhn.jameica.hbci.gui.controller.UmsatzDetailControl#getEndToEndId() | |
269 | */ | |
270 | @Override | |
271 | public Input getEndToEndId() throws RemoteException | |
272 | { | |
273 | Input input = super.getEndToEndId(); | |
274 | if (!input.isEnabled()) | |
275 | input.setEnabled(true); | |
276 | return input; | |
277 | } | |
266 | 278 | |
267 | 279 | /** |
268 | 280 | * @see de.willuhn.jameica.hbci.gui.controller.UmsatzDetailControl#getGvCode() |
357 | 369 | |
358 | 370 | u.setCustomerRef((String)getCustomerRef().getValue()); |
359 | 371 | u.setPrimanota((String)getPrimanota().getValue()); |
372 | u.setEndToEndId((String)getEndToEndId().getValue()); | |
360 | 373 | |
361 | 374 | Date valuta = (Date) getValuta().getValue(); |
362 | 375 | Date datum = (Date) getDatum().getValue(); |
9 | 9 | |
10 | 10 | package de.willuhn.jameica.hbci.gui.dialogs; |
11 | 11 | |
12 | import java.beans.ExceptionListener; | |
13 | import java.beans.XMLDecoder; | |
14 | import java.beans.XMLEncoder; | |
15 | import java.io.BufferedInputStream; | |
16 | import java.io.BufferedOutputStream; | |
17 | 12 | import java.io.ByteArrayInputStream; |
18 | import java.io.File; | |
19 | import java.io.FileInputStream; | |
20 | import java.io.FileOutputStream; | |
21 | 13 | import java.io.IOException; |
22 | 14 | import java.io.InputStreamReader; |
15 | import java.nio.charset.Charset; | |
16 | import java.nio.charset.UnsupportedCharsetException; | |
23 | 17 | import java.util.ArrayList; |
24 | 18 | import java.util.List; |
25 | 19 | |
27 | 21 | import org.eclipse.swt.layout.GridData; |
28 | 22 | import org.eclipse.swt.layout.GridLayout; |
29 | 23 | import org.eclipse.swt.widgets.Composite; |
24 | import org.eclipse.swt.widgets.Event; | |
25 | import org.eclipse.swt.widgets.Listener; | |
30 | 26 | import org.supercsv.io.CsvListReader; |
31 | 27 | import org.supercsv.io.ICsvListReader; |
32 | 28 | import org.supercsv.prefs.CsvPreference; |
38 | 34 | import de.willuhn.jameica.gui.input.SelectInput; |
39 | 35 | import de.willuhn.jameica.gui.input.SpinnerInput; |
40 | 36 | import de.willuhn.jameica.gui.input.TextInput; |
37 | import de.willuhn.jameica.gui.internal.buttons.Cancel; | |
41 | 38 | import de.willuhn.jameica.gui.parts.ButtonArea; |
42 | 39 | import de.willuhn.jameica.gui.util.Color; |
43 | 40 | import de.willuhn.jameica.gui.util.Container; |
48 | 45 | import de.willuhn.jameica.hbci.io.csv.Column; |
49 | 46 | import de.willuhn.jameica.hbci.io.csv.Format; |
50 | 47 | import de.willuhn.jameica.hbci.io.csv.Profile; |
48 | import de.willuhn.jameica.hbci.io.csv.ProfileUtil; | |
51 | 49 | import de.willuhn.jameica.system.Application; |
52 | 50 | import de.willuhn.jameica.system.OperationCanceledException; |
53 | 51 | import de.willuhn.logging.Logger; |
62 | 60 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
63 | 61 | private final static String[] CHARSETS = new String[]{"UTF-8","ISO-8859-15","ISO-8859-1"}; |
64 | 62 | |
63 | private SelectInput profiles = null; | |
64 | private Profile result = null; | |
65 | 65 | private Format format = null; |
66 | private Profile profile = null; | |
67 | 66 | private byte[] data = null; |
68 | 67 | |
69 | 68 | private TextInput sepChar = null; |
93 | 92 | this.data = data; |
94 | 93 | |
95 | 94 | this.setTitle(i18n.tr("Zuordnung der Spalten")); |
96 | this.setSize(680,500); | |
95 | this.setSize(680,700); | |
97 | 96 | |
98 | 97 | } |
99 | 98 | |
104 | 103 | { |
105 | 104 | // BUGZILLA 281 |
106 | 105 | Container options = new SimpleContainer(parent); |
106 | options.addInput(this.getProfiles()); | |
107 | ||
108 | ButtonArea b = new ButtonArea(); | |
109 | b.addButton(i18n.tr("CSV-Datei neu laden"), new Action() | |
110 | { | |
111 | public void handleAction(Object context) throws ApplicationException | |
112 | { | |
113 | reload(); | |
114 | } | |
115 | },null,false,"view-refresh.png"); | |
116 | b.addButton(i18n.tr("Profil speichern..."), new Action() { | |
117 | ||
118 | @Override | |
119 | public void handleAction(Object context) throws ApplicationException | |
120 | { | |
121 | // Wir erzeugen erstmal ein neues Profil | |
122 | // Der User entscheidet dann im CSVProfileStoreDialog, ob er ueberschreibt oder nicht | |
123 | Profile p = new Profile(); | |
124 | p.setColumns(getColumns()); | |
125 | p.setName(getProfile().getName()); | |
126 | p.setSystem(false); | |
127 | p.setFileEncoding((String)getFileEncoding().getValue()); | |
128 | p.setQuotingChar((String)getQuoteChar().getValue()); | |
129 | p.setSeparatorChar((String)getSeparatorChar().getValue()); | |
130 | p.setSkipLines(((Integer)getSkipLines().getValue()).intValue()); | |
131 | ||
132 | Profile pNew = ProfileUtil.add(format,p); | |
133 | if (pNew != null) | |
134 | { | |
135 | // Liste in der Auswahlbox neu laden und das neue Profil selektieren | |
136 | getProfiles().setList(ProfileUtil.read(format)); | |
137 | getProfiles().setPreselected(pNew); | |
138 | } | |
139 | } | |
140 | },null,false,"document-save.png"); | |
141 | b.addButton(i18n.tr("Profil löschen..."), new Action() { | |
142 | ||
143 | @Override | |
144 | public void handleAction(Object context) throws ApplicationException | |
145 | { | |
146 | try | |
147 | { | |
148 | if (!Application.getCallback().askUser(i18n.tr("Soll das Profil wirklich gelöscht werden?"),false)) | |
149 | return; | |
150 | } | |
151 | catch (ApplicationException ae) | |
152 | { | |
153 | throw ae; | |
154 | } | |
155 | catch (OperationCanceledException oce) | |
156 | { | |
157 | throw oce; | |
158 | } | |
159 | catch (Exception e) | |
160 | { | |
161 | Logger.error("unable to delete profile",e); | |
162 | getError().setValue(i18n.tr("Fehler beim Löschen: {0}",e.getMessage())); | |
163 | return; | |
164 | } | |
165 | if (ProfileUtil.delete(format,getProfile())) | |
166 | { | |
167 | // Liste aktualisieren | |
168 | getProfiles().setList(ProfileUtil.read(format)); | |
169 | ||
170 | // Nach dem Loeschen die Auswahl zurueck auf das Default-Profil setzen | |
171 | getProfiles().setValue(getProfiles().getList().get(0)); | |
172 | } | |
173 | ||
174 | // Einstellungen des ausgewaehlten Profils uebernehmen | |
175 | update(); | |
176 | ||
177 | // Datei damit neu laden | |
178 | reload(); | |
179 | } | |
180 | },null,false,"user-trash-full.png"); | |
181 | options.addButtonArea(b); | |
182 | ||
183 | options.addText("",false); | |
107 | 184 | options.addHeadline(i18n.tr("Optionen")); |
108 | 185 | options.addInput(this.getFileEncoding()); |
109 | 186 | options.addInput(this.getSeparatorChar()); |
110 | 187 | options.addInput(this.getQuoteChar()); |
111 | 188 | options.addInput(this.getSkipLines()); |
112 | 189 | |
190 | options.addText("",false); | |
113 | 191 | // BUGZILLA 412 |
114 | 192 | options.addHeadline(i18n.tr("Zuordnung der Spalten")); |
115 | 193 | options.addText(i18n.tr("In der linken Spalte sehen Sie die erste Zeile Ihrer CSV-Datei.\n" + |
123 | 201 | SimpleContainer c = new SimpleContainer(parent); |
124 | 202 | c.addInput(this.getError()); |
125 | 203 | |
126 | ButtonArea b = new ButtonArea(); | |
127 | b.addButton(i18n.tr("Übernehmen"), new Action() | |
204 | ButtonArea b2 = new ButtonArea(); | |
205 | b2.addButton(i18n.tr("Import starten"), new Action() | |
128 | 206 | { |
129 | 207 | public void handleAction(Object context) throws ApplicationException |
130 | 208 | { |
131 | Profile p = getProfile(); | |
132 | p.setFileEncoding((String)getFileEncoding().getValue()); | |
133 | p.setQuotingChar((String)getQuoteChar().getValue()); | |
134 | p.setSeparatorChar((String)getSeparatorChar().getValue()); | |
135 | p.setSkipLines(((Integer)getSkipLines().getValue()).intValue()); | |
136 | ||
137 | // Spalten noch zuordnen | |
138 | List<Column> columns = new ArrayList<Column>(); | |
139 | for (int i=0;i<selects.size();++i) | |
140 | { | |
141 | SelectInput input = selects.get(i); | |
142 | Column c = (Column) input.getValue(); | |
143 | if (c == null) | |
144 | continue; // Spalte nicht zugeordnet | |
145 | ||
146 | // Spalten konnen mehrfach zugeordnet werden. | |
147 | // Daher verwenden wir einen Clone. Andernfalls wuerden | |
148 | // wir nur die letzte Zuordnung speichern | |
149 | try | |
150 | { | |
151 | c = (Column) c.clone(); | |
152 | } | |
153 | catch (CloneNotSupportedException e) {/*dann halt nicht */} | |
154 | ||
155 | // Spaltennummer speichern | |
156 | c.setColumn(i); | |
157 | columns.add(c); | |
158 | } | |
159 | p.setColumns(columns); | |
160 | ||
161 | storeProfile(p); | |
209 | result = getProfile(); | |
210 | result.setFileEncoding((String)getFileEncoding().getValue()); | |
211 | result.setQuotingChar((String)getQuoteChar().getValue()); | |
212 | result.setSeparatorChar((String)getSeparatorChar().getValue()); | |
213 | result.setSkipLines(((Integer)getSkipLines().getValue()).intValue()); | |
214 | result.setColumns(getColumns()); | |
162 | 215 | close(); |
163 | 216 | } |
164 | 217 | },null,false,"ok.png"); |
165 | b.addButton(i18n.tr("Datei neu laden"), new Action() | |
166 | { | |
167 | public void handleAction(Object context) throws ApplicationException | |
168 | { | |
169 | Profile p = getProfile(); | |
170 | p.setFileEncoding((String)getFileEncoding().getValue()); | |
171 | p.setQuotingChar((String)getQuoteChar().getValue()); | |
172 | p.setSeparatorChar((String)getSeparatorChar().getValue()); | |
173 | p.setSkipLines(((Integer)getSkipLines().getValue()).intValue()); | |
174 | reload(); | |
175 | } | |
176 | },null,false,"view-refresh.png"); | |
177 | b.addButton(i18n.tr("Abbrechen"), new Action() | |
178 | { | |
179 | public void handleAction(Object context) throws ApplicationException | |
180 | { | |
181 | throw new OperationCanceledException(); | |
182 | } | |
183 | },null,false,"process-stop.png"); | |
184 | ||
185 | c.addButtonArea(b); | |
218 | b2.addButton(new Cancel()); | |
219 | c.addButtonArea(b2); | |
220 | } | |
221 | ||
222 | /** | |
223 | * Liefert die aktuelle Spalten-Zuordnung. | |
224 | * @return die aktuelle Spalten-Zuordnung. | |
225 | */ | |
226 | private List<Column> getColumns() | |
227 | { | |
228 | // Spalten noch zuordnen | |
229 | List<Column> columns = new ArrayList<Column>(); | |
230 | for (int i=0;i<selects.size();++i) | |
231 | { | |
232 | SelectInput input = selects.get(i); | |
233 | Column c = (Column) input.getValue(); | |
234 | if (c == null) | |
235 | continue; // Spalte nicht zugeordnet | |
236 | ||
237 | // Spalten konnen mehrfach zugeordnet werden. | |
238 | // Daher verwenden wir einen Clone. Andernfalls wuerden | |
239 | // wir nur die letzte Zuordnung speichern | |
240 | try | |
241 | { | |
242 | c = (Column) c.clone(); | |
243 | } | |
244 | catch (CloneNotSupportedException e) {/*dann halt nicht */} | |
245 | ||
246 | // Spaltennummer speichern | |
247 | c.setColumn(i); | |
248 | columns.add(c); | |
249 | } | |
250 | return columns; | |
186 | 251 | } |
187 | 252 | |
188 | 253 | /** |
199 | 264 | |
200 | 265 | this.selects.clear(); |
201 | 266 | |
202 | Profile p = this.getProfile(); | |
267 | Profile p = getProfile(); | |
203 | 268 | List<List<String>> lines = new ArrayList<List<String>>(); // Liste mit Zeilen mit Listen von Spalten %-) |
204 | 269 | int cols = 0; |
205 | 270 | |
206 | 271 | //////////////////////////////////////////////////////////////////////////// |
207 | 272 | // CSV-Datei einlesen |
208 | 273 | CsvPreference prefs = p.createCsvPreference(); |
209 | csv = new CsvListReader(new InputStreamReader(new ByteArrayInputStream(this.data),p.getFileEncoding()),prefs); | |
274 | ||
275 | Charset charset = null; | |
276 | ||
277 | try | |
278 | { | |
279 | charset = Charset.forName(p.getFileEncoding()); | |
280 | } | |
281 | catch (UnsupportedCharsetException e) | |
282 | { | |
283 | getError().setValue(i18n.tr("Encoding {0} ignoriert, wird nicht unterstützt",p.getFileEncoding())); | |
284 | } | |
285 | csv = new CsvListReader(new InputStreamReader(new ByteArrayInputStream(this.data),charset != null ? charset : Charset.defaultCharset()),prefs); | |
210 | 286 | List<String> line = null; |
211 | 287 | while ((line = csv.read()) != null) |
212 | 288 | { |
219 | 295 | lines.add(l); |
220 | 296 | |
221 | 297 | // Wir verwenden als Basis die Zeile mit den meisten Spalten |
222 | if (l.size() > cols) | |
223 | cols = l.size(); | |
298 | cols = Math.max(l.size(),cols); | |
224 | 299 | } |
225 | 300 | |
226 | 301 | if (cols == 0) |
244 | 319 | // |
245 | 320 | //////////////////////////////////////////////////////////////////////////// |
246 | 321 | |
247 | List<Column> columns = p.getColumns(); | |
322 | List<Column> all = format.getDefaultProfile().getColumns(); // Als Auswahlmoeglichkeit immer die aus dem Default | |
323 | List<Column> columns = p.getColumns(); // Die, die im Template tatsaechlich zugeordnet sind. | |
248 | 324 | List<String> current = lines.get(p.getSkipLines()); // Die erste anzuzeigende Zeile |
249 | 325 | |
250 | 326 | ScrolledContainer container = new ScrolledContainer(this.parent); |
259 | 335 | value = value.substring(0,30) + "..."; |
260 | 336 | } catch (Exception e) {} // Spalte gibts in der Zeile nicht |
261 | 337 | |
262 | final SelectInput s = new SelectInput(columns,getColumn(columns,i)); | |
338 | final SelectInput s = new SelectInput(all,getColumn(columns,i)); | |
263 | 339 | s.setName((i+1) + ". " + (value != null ? value : "<" + i18n.tr("leer") + ">")); |
264 | 340 | s.setPleaseChoose("<" + i18n.tr("Nicht zugeordnet") + ">"); |
265 | 341 | selects.add(s); |
297 | 373 | } |
298 | 374 | return null; |
299 | 375 | } |
300 | ||
301 | ||
302 | /** | |
303 | * Prueft, ob ein serialisiertes, vom User abgespeichertes Profil existiert | |
304 | * und laedt dieses. Andernfalls wird das Default-Profil des Formats verwendet. | |
305 | * @return das Profil. Nie NULL sondern hoechstens das Default-Profil. | |
306 | */ | |
307 | private Profile getProfile() | |
308 | { | |
309 | if (this.profile != null) | |
310 | return this.profile; | |
311 | ||
312 | Profile defaultProfile = this.format.getDefaultProfile(); | |
313 | ||
314 | // 1. Wir nehmen erstmal das Default-Profil | |
315 | this.profile = defaultProfile; | |
316 | ||
317 | // 2. Mal schauen, ob wir ein gespeichertes Profil fuer das Format haben | |
318 | File dir = new File(Application.getPluginLoader().getPlugin(HBCI.class).getResources().getWorkPath(),"csv"); | |
319 | if (!dir.exists()) | |
320 | { | |
321 | // Wir erstellen das Verzeichnis - dann muss es der User nicht selbst anlegen | |
322 | Logger.info("creating " + dir); | |
323 | dir.mkdirs(); | |
324 | return this.profile; // Wenn das Verzeichnis noch nicht existierte, gibts auch kein Benutzer-Profil | |
325 | } | |
326 | ||
327 | File file = new File(dir,this.format.getClass().getName() + ".xml"); | |
328 | if (!file.exists() || !file.canRead()) | |
329 | return this.profile; // XML-Datei gibts nicht oder nicht lesbar - also Default-Profil | |
330 | ||
331 | Logger.info("reading csv profile " + file); | |
332 | XMLDecoder decoder = null; | |
333 | try | |
334 | { | |
335 | decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream(file))); | |
336 | decoder.setExceptionListener(new ExceptionListener() | |
337 | { | |
338 | public void exceptionThrown(Exception e) | |
339 | { | |
340 | throw new RuntimeException(e); | |
341 | } | |
342 | }); | |
343 | Profile p = (Profile) decoder.readObject(); | |
344 | ||
345 | // Versionsnummer pruefen | |
346 | if (defaultProfile.getVersion() > p.getVersion()) | |
347 | { | |
348 | Logger.info("default profile has changed, new version number " + defaultProfile.getVersion() + ". skipping serialized profile"); | |
349 | return this.profile; | |
350 | } | |
351 | ||
352 | ||
353 | this.profile = p; | |
354 | ||
355 | // Der User hat beim letzten Mal eventuell nicht alle Spalten zugeordnet. | |
356 | // Die wuerden jetzt hier in dem Objekt fehlen. Daher nehmen wir | |
357 | // noch die Spalten aus dem Default-Profil und haengen die fehlenden noch an. | |
358 | List<Column> currentColumns = this.profile.getColumns(); | |
359 | List<Column> defaultColumns = defaultProfile.getColumns(); | |
360 | for (Column cd:defaultColumns) | |
361 | { | |
362 | String n1 = cd.getProperty(); | |
363 | if (n1 == null) | |
364 | continue; // Sollte es eigentlich nicht geben | |
365 | ||
366 | cd.setColumn(-1); // gilt als nicht zugeordnet | |
367 | ||
368 | // Checken, ob im serialisierten Profil enthalten | |
369 | boolean found = false; | |
370 | for (Column cc:currentColumns) | |
371 | { | |
372 | String n2 = cc.getProperty(); | |
373 | if (n2 == null) | |
374 | continue; | |
375 | if (n1.equals(n2)) | |
376 | { | |
377 | found = true; | |
378 | break; | |
379 | } | |
380 | } | |
381 | ||
382 | // Wenn wir die Spalte im serialisierten Profil nicht gefunden | |
383 | // haben, haengen wir sie als nicht zugeordnet hinten dran | |
384 | if (!found) | |
385 | currentColumns.add(cd); | |
386 | } | |
387 | } | |
388 | catch (Exception e) | |
389 | { | |
390 | Logger.error("unable to read profile " + file,e); | |
391 | } | |
392 | finally | |
393 | { | |
394 | if (decoder != null) { | |
395 | try { | |
396 | decoder.close(); | |
397 | } | |
398 | catch (Exception e) { /* useless */} | |
399 | } | |
400 | } | |
401 | ||
402 | return this.profile; | |
403 | } | |
404 | ||
405 | ||
406 | /** | |
407 | * Serialisiert das Profil. | |
408 | * @param profile das zu serialisierende Profil. | |
409 | */ | |
410 | private void storeProfile(Profile profile) | |
411 | { | |
412 | // 2. Mal schauen, ob wir ein gespeichertes Profil fuer das Format haben | |
413 | File dir = new File(Application.getPluginLoader().getPlugin(HBCI.class).getResources().getWorkPath(),"csv"); | |
414 | File file = new File(dir,this.format.getClass().getName() + ".xml"); | |
415 | ||
416 | Logger.info("writing csv profile " + file); | |
417 | XMLEncoder encoder = null; | |
418 | try | |
419 | { | |
420 | encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(file))); | |
421 | encoder.setExceptionListener(new ExceptionListener() | |
422 | { | |
423 | public void exceptionThrown(Exception e) | |
424 | { | |
425 | throw new RuntimeException(e); | |
426 | } | |
427 | }); | |
428 | encoder.writeObject(profile); | |
429 | } | |
430 | catch (Exception e) | |
431 | { | |
432 | Logger.error("unable to store profile " + file,e); | |
433 | } | |
434 | finally | |
435 | { | |
436 | if (encoder != null) { | |
437 | try { | |
438 | encoder.close(); | |
439 | } | |
440 | catch (Exception e) { /* useless */} | |
441 | } | |
442 | } | |
443 | } | |
444 | ||
376 | ||
445 | 377 | /** |
446 | 378 | * Liefert das angepasste Mapping zurueck. |
447 | 379 | * @see de.willuhn.jameica.gui.dialogs.AbstractDialog#getData() |
448 | 380 | */ |
449 | 381 | protected Object getData() throws Exception |
450 | 382 | { |
451 | return this.getProfile(); | |
383 | return this.result; | |
452 | 384 | } |
453 | 385 | |
454 | 386 | |
458 | 390 | */ |
459 | 391 | private TextInput getSeparatorChar() |
460 | 392 | { |
461 | if (this.sepChar == null) | |
462 | { | |
463 | this.sepChar = new TextInput(this.getProfile().getSeparatorChar(),1); | |
464 | this.sepChar.setName(i18n.tr("Trennzeichen")); | |
465 | this.sepChar.setComment(i18n.tr("Zeichen, mit dem die Spalten getrennt sind")); | |
466 | this.sepChar.setMandatory(true); | |
467 | } | |
393 | if (this.sepChar != null) | |
394 | return this.sepChar; | |
395 | ||
396 | this.sepChar = new TextInput(getProfile().getSeparatorChar(),1); | |
397 | this.sepChar.setName(i18n.tr("Trennzeichen")); | |
398 | this.sepChar.setComment(i18n.tr("Zeichen, mit dem die Spalten getrennt sind")); | |
399 | this.sepChar.setMandatory(true); | |
468 | 400 | return this.sepChar; |
469 | 401 | } |
470 | 402 | |
474 | 406 | */ |
475 | 407 | private LabelInput getError() |
476 | 408 | { |
477 | if (this.error == null) | |
478 | { | |
479 | this.error = new LabelInput(""); | |
480 | this.error.setName(""); | |
481 | this.error.setColor(Color.ERROR); | |
482 | } | |
409 | if (this.error != null) | |
410 | return this.error; | |
411 | ||
412 | this.error = new LabelInput(""); | |
413 | this.error.setName(""); | |
414 | this.error.setColor(Color.ERROR); | |
483 | 415 | return this.error; |
484 | 416 | } |
485 | 417 | |
489 | 421 | */ |
490 | 422 | private TextInput getQuoteChar() |
491 | 423 | { |
492 | if (this.quoteChar == null) | |
493 | { | |
494 | this.quoteChar = new TextInput(this.getProfile().getQuotingChar(),1); | |
495 | this.quoteChar.setName(i18n.tr("Anführungszeichen")); | |
496 | this.quoteChar.setComment(i18n.tr("Zeichen, mit dem die Spalten umschlossen sind")); | |
497 | this.quoteChar.setMandatory(false); | |
498 | } | |
424 | if (this.quoteChar != null) | |
425 | return this.quoteChar; | |
426 | ||
427 | this.quoteChar = new TextInput(this.getProfile().getQuotingChar(),1); | |
428 | this.quoteChar.setName(i18n.tr("Anführungszeichen")); | |
429 | this.quoteChar.setComment(i18n.tr("Zeichen, mit dem die Spalten umschlossen sind")); | |
430 | this.quoteChar.setMandatory(false); | |
499 | 431 | return this.quoteChar; |
500 | 432 | } |
501 | 433 | |
505 | 437 | */ |
506 | 438 | private SelectInput getFileEncoding() |
507 | 439 | { |
508 | if (this.encoding == null) | |
509 | { | |
510 | this.encoding = new SelectInput(CHARSETS,this.getProfile().getFileEncoding()); | |
511 | this.encoding.setName(i18n.tr("Zeichensatz")); | |
512 | this.encoding.setComment(i18n.tr("Zeichensatz der CSV-Datei")); | |
513 | this.encoding.setMandatory(true); | |
514 | this.encoding.setEditable(true); | |
515 | } | |
440 | if (this.encoding != null) | |
441 | return this.encoding; | |
442 | ||
443 | this.encoding = new SelectInput(CHARSETS,this.getProfile().getFileEncoding()); | |
444 | this.encoding.setName(i18n.tr("Zeichensatz")); | |
445 | this.encoding.setComment(i18n.tr("Zeichensatz der CSV-Datei")); | |
446 | this.encoding.setMandatory(true); | |
447 | this.encoding.setEditable(true); | |
516 | 448 | return this.encoding; |
517 | 449 | } |
518 | 450 | |
523 | 455 | */ |
524 | 456 | private SpinnerInput getSkipLines() |
525 | 457 | { |
526 | if (this.skipLines == null) | |
527 | { | |
528 | this.skipLines = new SpinnerInput(0,10,this.getProfile().getSkipLines()); | |
529 | this.skipLines.setName(i18n.tr("Zeilen überspringen")); | |
530 | this.skipLines.setComment(i18n.tr("Zu überspringende Zeilen am Datei-Anfang")); | |
531 | this.skipLines.setMandatory(false); | |
532 | } | |
458 | if (this.skipLines != null) | |
459 | return this.skipLines; | |
460 | ||
461 | this.skipLines = new SpinnerInput(0,10,this.getProfile().getSkipLines()); | |
462 | this.skipLines.setName(i18n.tr("Zeilen überspringen")); | |
463 | this.skipLines.setComment(i18n.tr("Zu überspringende Zeilen am Datei-Anfang")); | |
464 | this.skipLines.setMandatory(false); | |
533 | 465 | return this.skipLines; |
534 | 466 | } |
467 | ||
468 | /** | |
469 | * Liefert das aktuelle Profil. | |
470 | * @return das aktuelle Profil. | |
471 | */ | |
472 | private Profile getProfile() | |
473 | { | |
474 | return (Profile) this.getProfiles().getValue(); | |
475 | } | |
476 | ||
477 | /** | |
478 | * Liefert eine Auswahlbox mit den verfuegbaren Profilen. | |
479 | * @return eine Auswahlbox mit den verfuegbaren Profilen. | |
480 | * @throws ApplicationException | |
481 | */ | |
482 | private SelectInput getProfiles() | |
483 | { | |
484 | if (this.profiles != null) | |
485 | return this.profiles; | |
486 | ||
487 | this.profiles = new SelectInput(ProfileUtil.read(this.format),null); | |
488 | this.profiles.setAttribute("name"); | |
489 | this.profiles.setName(i18n.tr("Profil")); | |
490 | this.profiles.addListener(new Listener() { | |
491 | @Override | |
492 | public void handleEvent(Event event) | |
493 | { | |
494 | if (event != null && event.type == SWT.Selection) | |
495 | { | |
496 | update(); | |
497 | reload(); | |
498 | } | |
499 | } | |
500 | }); | |
501 | return this.profiles; | |
502 | } | |
503 | ||
504 | /** | |
505 | * Aktualisiert die Auswahl- und Eingabefelder nach Wechsel des Profils. | |
506 | */ | |
507 | private void update() | |
508 | { | |
509 | Profile p = getProfile(); | |
510 | Logger.info("chaning profile to: " + p); | |
511 | ||
512 | // Einstellungen in die Eingabefelder uebernehmen | |
513 | this.getFileEncoding().setValue(p.getFileEncoding()); | |
514 | this.getQuoteChar().setValue(p.getQuotingChar()); | |
515 | this.getSeparatorChar().setValue(p.getSeparatorChar()); | |
516 | this.getSkipLines().setValue(Integer.valueOf(p.getSkipLines())); | |
517 | ||
518 | // Datei mit den neuen Einstellungen laden | |
519 | reload(); | |
520 | } | |
535 | 521 | } |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2004 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | package de.willuhn.jameica.hbci.gui.dialogs; | |
10 | ||
11 | import java.util.List; | |
12 | ||
13 | import org.apache.commons.lang.StringUtils; | |
14 | import org.eclipse.swt.SWT; | |
15 | import org.eclipse.swt.events.KeyAdapter; | |
16 | import org.eclipse.swt.events.KeyEvent; | |
17 | import org.eclipse.swt.widgets.Composite; | |
18 | ||
19 | import de.willuhn.jameica.gui.Action; | |
20 | import de.willuhn.jameica.gui.dialogs.AbstractDialog; | |
21 | import de.willuhn.jameica.gui.input.Input; | |
22 | import de.willuhn.jameica.gui.input.LabelInput; | |
23 | import de.willuhn.jameica.gui.input.TextInput; | |
24 | import de.willuhn.jameica.gui.internal.buttons.Cancel; | |
25 | import de.willuhn.jameica.gui.parts.Button; | |
26 | import de.willuhn.jameica.gui.parts.ButtonArea; | |
27 | import de.willuhn.jameica.gui.util.Color; | |
28 | import de.willuhn.jameica.gui.util.Container; | |
29 | import de.willuhn.jameica.gui.util.SWTUtil; | |
30 | import de.willuhn.jameica.gui.util.SimpleContainer; | |
31 | import de.willuhn.jameica.hbci.HBCI; | |
32 | import de.willuhn.jameica.hbci.io.csv.Format; | |
33 | import de.willuhn.jameica.hbci.io.csv.Profile; | |
34 | import de.willuhn.jameica.hbci.io.csv.ProfileUtil; | |
35 | import de.willuhn.jameica.system.Application; | |
36 | import de.willuhn.util.ApplicationException; | |
37 | import de.willuhn.util.I18N; | |
38 | ||
39 | /** | |
40 | * Dialog zum Speichern eines CSV-Profils. | |
41 | */ | |
42 | public class CSVProfileStoreDialog extends AbstractDialog | |
43 | { | |
44 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
45 | private final static int WINDOW_WIDTH = 500; | |
46 | ||
47 | private Format format = null; | |
48 | private Profile profile = null; | |
49 | private Button apply = null; | |
50 | private TextInput name = null; | |
51 | private LabelInput hint = null; | |
52 | ||
53 | private List<Profile> profiles = null; | |
54 | ||
55 | /** | |
56 | * Erzeugt einen neuen Text-Dialog. | |
57 | * @param format das Format. | |
58 | * @param profile das Profil. | |
59 | * @see AbstractDialog#POSITION_MOUSE | |
60 | * @see AbstractDialog#POSITION_CENTER | |
61 | */ | |
62 | public CSVProfileStoreDialog(Format format, Profile profile) | |
63 | { | |
64 | super(CSVProfileStoreDialog.POSITION_CENTER); | |
65 | this.setSize(WINDOW_WIDTH,SWT.DEFAULT); | |
66 | this.setTitle(i18n.tr("Name des Profils")); | |
67 | this.setSideImage(SWTUtil.getImage("dialog-question-large.png")); | |
68 | ||
69 | this.profile = profile; | |
70 | ||
71 | // Wir machen neue Profile generell zu Nicht-System-Profilen | |
72 | this.profile.setSystem(false); | |
73 | ||
74 | this.format = format; | |
75 | this.profiles = ProfileUtil.read(format); | |
76 | } | |
77 | ||
78 | /** | |
79 | * Liefert das Eingabefeld fuer den Namen. | |
80 | * @return das Eingabefeld fuer den Namen. | |
81 | */ | |
82 | private TextInput getName() | |
83 | { | |
84 | if (this.name != null) | |
85 | return this.name; | |
86 | ||
87 | this.name = new TextInput(this.suggestName()); | |
88 | this.name.setName(""); | |
89 | this.name.setMandatory(true); | |
90 | return this.name; | |
91 | } | |
92 | ||
93 | /** | |
94 | * Liefert einen Namensvorschlag fuer das Profil. | |
95 | * @return Namensvorschlag fuer das Profil. | |
96 | */ | |
97 | private String suggestName() | |
98 | { | |
99 | // Wir versuchen einen Namensvorschlag für das Profil zu ermitteln | |
100 | // Hierzu checken wir, ob es mit einer Zahl endet. Wenn ja, erhoehen | |
101 | // wir sie um 1. Wenn nicht, haengen wir "2" hinten dran. | |
102 | String template = this.profile.getName(); | |
103 | int space = template.lastIndexOf(" "); | |
104 | ||
105 | // Checken, ob wir schon eine Nummer im Namen haben | |
106 | if (space > 0) | |
107 | { | |
108 | String s1 = StringUtils.trimToNull(template.substring(0,space)); | |
109 | String s2 = StringUtils.trimToNull(template.substring(space)); | |
110 | if (s1 != null && s2 != null && s2.matches("[0-9]{1,4}")) | |
111 | template = s1; | |
112 | } | |
113 | ||
114 | // Erste freie Nummer suchen | |
115 | for (int i=2;i<100;++i) | |
116 | { | |
117 | boolean found = false; | |
118 | String name = template + " " + i; | |
119 | for (Profile p:this.profiles) | |
120 | { | |
121 | if (name.equals(p.getName())) | |
122 | { | |
123 | found = true; | |
124 | break; | |
125 | } | |
126 | } | |
127 | ||
128 | // wir haben einen passenden Namen gefunden | |
129 | if (!found) | |
130 | return name; | |
131 | } | |
132 | ||
133 | // Ne, dann muss der User selbst einen neuen Namen vergeben | |
134 | return template; | |
135 | } | |
136 | ||
137 | /** | |
138 | * Zeigt einen Hinweis-Text an. | |
139 | * @return Hinweis-Text. | |
140 | */ | |
141 | private LabelInput getHint() | |
142 | { | |
143 | if (this.hint != null) | |
144 | return this.hint; | |
145 | ||
146 | this.hint = new LabelInput(""); | |
147 | this.hint.setName(""); | |
148 | this.hint.setColor(Color.ERROR); | |
149 | return this.hint; | |
150 | } | |
151 | ||
152 | /** | |
153 | * Liefert den Apply-Button. | |
154 | * @return der Apply-Button. | |
155 | */ | |
156 | private Button getApply() | |
157 | { | |
158 | if (this.apply != null) | |
159 | return this.apply; | |
160 | ||
161 | this.apply = new Button(i18n.tr("Übernehmen"),new Action() { | |
162 | public void handleAction(Object context) throws ApplicationException | |
163 | { | |
164 | // Name uebernehmen | |
165 | profile.setName((String) getName().getValue()); | |
166 | ||
167 | // Wir koennen das Profil zur Liste hinzufuegen. | |
168 | // Checken, ob eines ueberschrieben werden soll. | |
169 | boolean found = false; | |
170 | for (Profile p:profiles) | |
171 | { | |
172 | if (p.isSystem()) | |
173 | continue; | |
174 | ||
175 | if (p.getName().equals(profile.getName())) | |
176 | { | |
177 | profiles.set(profiles.indexOf(p),profile); | |
178 | found = true; | |
179 | break; | |
180 | } | |
181 | } | |
182 | ||
183 | if (!found) | |
184 | profiles.add(profile); | |
185 | ||
186 | ProfileUtil.store(format,profiles); | |
187 | close(); | |
188 | } | |
189 | },null,true,"ok.png"); | |
190 | ||
191 | return this.apply; | |
192 | } | |
193 | ||
194 | /** | |
195 | * @see de.willuhn.jameica.gui.dialogs.AbstractDialog#paint(org.eclipse.swt.widgets.Composite) | |
196 | */ | |
197 | protected void paint(Composite parent) throws Exception | |
198 | { | |
199 | Container c = new SimpleContainer(parent); | |
200 | c.addText(i18n.tr("Bitte geben Sie einen Namen für das Profil an.\n\n" + | |
201 | "Verwenden Sie einen noch nicht benutzten Namen, um ein neues Profil hinzuzufügen. " + | |
202 | "Vergeben Sie alternativ einen bereits verwendeten Namen, um dieses Profil zu überschreiben."),true); | |
203 | ||
204 | final Input name = this.getName(); | |
205 | c.addInput(name); | |
206 | ||
207 | name.getControl().addKeyListener(new KeyAdapter() { | |
208 | /** | |
209 | * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent) | |
210 | */ | |
211 | @Override | |
212 | public void keyReleased(KeyEvent e) | |
213 | { | |
214 | updateUI(); | |
215 | } | |
216 | }); | |
217 | ||
218 | c.addInput(getHint()); | |
219 | ||
220 | ButtonArea buttons = new ButtonArea(); | |
221 | buttons.addButton(this.getApply()); | |
222 | buttons.addButton(new Cancel()); | |
223 | ||
224 | c.addButtonArea(buttons); | |
225 | getShell().setMinimumSize(getShell().computeSize(WINDOW_WIDTH,SWT.DEFAULT)); | |
226 | ||
227 | // UI initialisieren | |
228 | updateUI(); | |
229 | } | |
230 | ||
231 | /** | |
232 | * Aktualisiert die UI nach Zeicheneingabe | |
233 | */ | |
234 | private void updateUI() | |
235 | { | |
236 | // Apply-Button deaktivieren, wenn nichts drin steht. | |
237 | final String text = StringUtils.trimToNull((String) name.getValue()); | |
238 | getApply().setEnabled(text != null); | |
239 | ||
240 | // Hier brauchen wir nichts weiter checken | |
241 | if (text == null) | |
242 | return; | |
243 | ||
244 | getHint().setValue(""); | |
245 | ||
246 | boolean found = false; | |
247 | boolean system = false; | |
248 | ||
249 | // Jetzt noch checken, ob wir ein existierendes Profil ueberschreiben und einen Warnhinweis anzeigen | |
250 | // Ausserdem einen Hinweis, wenn der User versucht, das System-Profil zu ueberschreiben | |
251 | for (Profile p:this.profiles) | |
252 | { | |
253 | if (p.getName().equals(text)) | |
254 | { | |
255 | found = true; | |
256 | system = p.isSystem(); | |
257 | } | |
258 | } | |
259 | ||
260 | if (!found) | |
261 | { | |
262 | getHint().setColor(Color.SUCCESS); | |
263 | getHint().setValue(i18n.tr("Ein neues Profil wird angelegt.")); | |
264 | } | |
265 | ||
266 | if (found && !system) | |
267 | { | |
268 | getHint().setColor(Color.LINK); | |
269 | getHint().setValue(i18n.tr("Existierendes Profil wird überschrieben.")); | |
270 | } | |
271 | ||
272 | if (system) | |
273 | { | |
274 | getHint().setColor(Color.ERROR); | |
275 | getHint().setValue(i18n.tr("Das Default-Profil darf nicht überschrieben werden.")); | |
276 | getApply().setEnabled(false); | |
277 | } | |
278 | } | |
279 | ||
280 | /** | |
281 | * @see de.willuhn.jameica.gui.dialogs.AbstractDialog#getData() | |
282 | */ | |
283 | protected Object getData() throws Exception | |
284 | { | |
285 | return this.profile; | |
286 | } | |
287 | } |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2004 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.gui.dialogs; | |
11 | ||
12 | import java.util.Arrays; | |
13 | import java.util.List; | |
14 | ||
15 | import org.eclipse.swt.SWT; | |
16 | import org.eclipse.swt.widgets.Composite; | |
17 | ||
18 | import de.willuhn.jameica.gui.Action; | |
19 | import de.willuhn.jameica.gui.dialogs.AbstractDialog; | |
20 | import de.willuhn.jameica.gui.input.CheckboxInput; | |
21 | import de.willuhn.jameica.gui.parts.Button; | |
22 | import de.willuhn.jameica.gui.parts.ButtonArea; | |
23 | import de.willuhn.jameica.gui.util.Container; | |
24 | import de.willuhn.jameica.gui.util.SWTUtil; | |
25 | import de.willuhn.jameica.gui.util.SimpleContainer; | |
26 | import de.willuhn.jameica.hbci.HBCI; | |
27 | import de.willuhn.jameica.hbci.MetaKey; | |
28 | import de.willuhn.jameica.hbci.gui.filter.KontoFilter; | |
29 | import de.willuhn.jameica.hbci.rmi.Konto; | |
30 | import de.willuhn.jameica.hbci.server.KontoUtil; | |
31 | import de.willuhn.jameica.messaging.StatusBarMessage; | |
32 | import de.willuhn.jameica.system.Application; | |
33 | import de.willuhn.logging.Logger; | |
34 | import de.willuhn.util.ApplicationException; | |
35 | import de.willuhn.util.I18N; | |
36 | ||
37 | /** | |
38 | * Dialog, mit dem der Abruf der Umsaetze initial auf CAMT umgestellt werden kann. | |
39 | * Der Dialog liefert true oder false zurueck. | |
40 | */ | |
41 | public class CamtSetupDialog extends AbstractDialog | |
42 | { | |
43 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
44 | ||
45 | private final static int WINDOW_WIDTH = 780; | |
46 | ||
47 | private Konto konto = null; | |
48 | private CheckboxInput switchAll = null; | |
49 | private Boolean value = null; | |
50 | ||
51 | /** | |
52 | * ct. | |
53 | * @param k das Konto. | |
54 | */ | |
55 | public CamtSetupDialog(Konto k) | |
56 | { | |
57 | super(POSITION_CENTER); | |
58 | ||
59 | this.konto = k; | |
60 | this.setTitle(i18n.tr("Umsätze im SEPA CAMT-Format abrufen")); | |
61 | this.setSize(WINDOW_WIDTH,SWT.DEFAULT); | |
62 | this.setSideImage(SWTUtil.getImage("camtsetup.png")); | |
63 | ||
64 | } | |
65 | ||
66 | /** | |
67 | * @see de.willuhn.jameica.gui.dialogs.AbstractDialog#paint(org.eclipse.swt.widgets.Composite) | |
68 | */ | |
69 | @Override | |
70 | protected void paint(Composite parent) throws Exception | |
71 | { | |
72 | final Container c = new SimpleContainer(parent); | |
73 | String text = "Hibiscus unterstützt beim Abruf der Konto-Umsätze jetzt auch das neue moderne XML-basierte CAMT-Format, welches " + | |
74 | "für den SEPA-Zahlungsverkehr besser geeignet ist als das bisherige MT940-Format.\n\n" + | |
75 | "Das Konto \"{0}\" kann jetzt auf CAMT umgestellt werden. Sie können diese Umstellung später in den Synchronisierungsoptionen " + | |
76 | "des Kontos jederzeit wieder rückgängig machen."; | |
77 | c.addText(i18n.tr(text,this.konto.getLongName()),true); | |
78 | ||
79 | c.addHeadline(i18n.tr("Hinweis")); | |
80 | text = "Da sich die Datenformate von CAMT und MT940 grundlegend unterscheiden, kann es nach der Umstellung dazu kommen, dass " + | |
81 | "Umsatzbuchungen ggf. doppelt angezeigt werden. Sie können diese Duplikate einfach löschen. In der Regel sollte das jedoch " + | |
82 | "nur am Tag der Umstellung selbst auftreten."; | |
83 | c.addText(text,true); | |
84 | ||
85 | c.addInput(this.getSwitchAll()); | |
86 | ||
87 | ButtonArea buttons = new ButtonArea(); | |
88 | ||
89 | final Button yes = new Button(i18n.tr("Ja, auf CAMT umstellen"),new Action() { | |
90 | ||
91 | @Override | |
92 | public void handleAction(Object context) throws ApplicationException | |
93 | { | |
94 | apply(true); | |
95 | } | |
96 | },null,true,"ok.png"); | |
97 | buttons.addButton(yes); | |
98 | ||
99 | final Button no = new Button(i18n.tr("Nein, nicht umstellen"),new Action() { | |
100 | ||
101 | @Override | |
102 | public void handleAction(Object context) throws ApplicationException | |
103 | { | |
104 | apply(false); | |
105 | } | |
106 | },null,true,"window-close.png"); | |
107 | buttons.addButton(no); | |
108 | ||
109 | final Button later = new Button(i18n.tr("Beim nächsten Mal erinnern"),new Action() { | |
110 | ||
111 | @Override | |
112 | public void handleAction(Object context) throws ApplicationException | |
113 | { | |
114 | close(); | |
115 | } | |
116 | },null,true,"preferences-system-time.png"); | |
117 | buttons.addButton(later); | |
118 | ||
119 | c.addButtonArea(buttons); | |
120 | ||
121 | getShell().setMinimumSize(getShell().computeSize(WINDOW_WIDTH,SWT.DEFAULT)); | |
122 | } | |
123 | ||
124 | /** | |
125 | * Liefert eine Checkbox, mit der eingestellt werden kann, ob die Umstellung fuer alle Konten erfolgen soll. | |
126 | * @return Checkbox. | |
127 | */ | |
128 | private CheckboxInput getSwitchAll() | |
129 | { | |
130 | if (this.switchAll != null) | |
131 | return this.switchAll; | |
132 | ||
133 | this.switchAll = new CheckboxInput(false); | |
134 | this.switchAll.setName(i18n.tr("Auch auf alle anderen Konten anwenden")); | |
135 | return this.switchAll; | |
136 | } | |
137 | ||
138 | /** | |
139 | * Uebernimmt die Einstellungen und schliesst den Dialog. | |
140 | * @param enabled true, wenn CAMT aktiviert werden soll. | |
141 | */ | |
142 | private void apply(boolean enabled) | |
143 | { | |
144 | try | |
145 | { | |
146 | this.value = enabled; | |
147 | final String s = Boolean.toString(enabled); | |
148 | final Boolean all = (Boolean) this.getSwitchAll().getValue(); | |
149 | ||
150 | List<Konto> konten = all.booleanValue() ? KontoUtil.getKonten(KontoFilter.ONLINE) : Arrays.asList(this.konto); | |
151 | for (Konto k:konten) | |
152 | { | |
153 | MetaKey.UMSATZ_CAMT.set(k,s); | |
154 | } | |
155 | } | |
156 | catch (Exception e) | |
157 | { | |
158 | Logger.error("unable to save changes",e); | |
159 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Übernehmen der Einstellungen fehlgeschlagen: {0}",e.getMessage()),StatusBarMessage.TYPE_ERROR)); | |
160 | } | |
161 | finally | |
162 | { | |
163 | close(); | |
164 | } | |
165 | } | |
166 | ||
167 | /** | |
168 | * @see de.willuhn.jameica.gui.dialogs.AbstractDialog#getData() | |
169 | */ | |
170 | @Override | |
171 | protected Object getData() throws Exception | |
172 | { | |
173 | return this.value; | |
174 | } | |
175 | } | |
176 |
14 | 14 | |
15 | 15 | import org.apache.commons.lang.StringUtils; |
16 | 16 | import org.eclipse.swt.SWT; |
17 | import org.eclipse.swt.events.DisposeEvent; | |
18 | import org.eclipse.swt.events.DisposeListener; | |
19 | import org.eclipse.swt.graphics.Point; | |
17 | 20 | import org.eclipse.swt.widgets.Composite; |
18 | 21 | import org.eclipse.swt.widgets.Event; |
19 | 22 | import org.eclipse.swt.widgets.Listener; |
23 | import org.eclipse.swt.widgets.Shell; | |
20 | 24 | import org.kapott.hbci.GV_Result.GVRKontoauszug.Format; |
21 | 25 | |
22 | 26 | import de.willuhn.jameica.gui.Action; |
31 | 35 | import de.willuhn.jameica.gui.parts.ButtonArea; |
32 | 36 | import de.willuhn.jameica.gui.util.Color; |
33 | 37 | import de.willuhn.jameica.gui.util.Container; |
38 | import de.willuhn.jameica.gui.util.ScrolledContainer; | |
34 | 39 | import de.willuhn.jameica.gui.util.SimpleContainer; |
35 | 40 | import de.willuhn.jameica.hbci.HBCI; |
36 | 41 | import de.willuhn.jameica.hbci.MetaKey; |
46 | 51 | import de.willuhn.jameica.hbci.server.KontoauszugPdfUtil; |
47 | 52 | import de.willuhn.jameica.messaging.StatusBarMessage; |
48 | 53 | import de.willuhn.jameica.system.Application; |
54 | import de.willuhn.jameica.system.Settings; | |
49 | 55 | import de.willuhn.logging.Logger; |
50 | 56 | import de.willuhn.util.ApplicationException; |
51 | 57 | import de.willuhn.util.I18N; |
56 | 62 | public class KontoauszugPdfSettingsDialog extends AbstractDialog |
57 | 63 | { |
58 | 64 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
59 | ||
60 | private final static int WINDOW_WIDTH = 600; | |
65 | private final static Settings settings = new Settings(KontoauszugPdfSettingsDialog.class); | |
66 | ||
67 | private final static int WINDOW_WIDTH = 700; | |
68 | private final static int WINDOW_HEIGHT = 500; | |
61 | 69 | |
62 | 70 | private Konto konto = null; |
63 | 71 | |
92 | 100 | super(POSITION_CENTER); |
93 | 101 | this.konto = konto; |
94 | 102 | this.setTitle(i18n.tr("Einstellungen für den elektronischen Kontoauszug")); |
95 | setSize(WINDOW_WIDTH,SWT.DEFAULT); | |
103 | setSize(settings.getInt("window.width",WINDOW_WIDTH),settings.getInt("window.height",WINDOW_HEIGHT)); | |
96 | 104 | } |
97 | 105 | |
98 | 106 | /** |
101 | 109 | @Override |
102 | 110 | protected void paint(Composite parent) throws Exception |
103 | 111 | { |
104 | Container c = new SimpleContainer(parent); | |
112 | Container scroll = new ScrolledContainer(parent,1) | |
113 | { | |
114 | /** | |
115 | * @see de.willuhn.jameica.gui.util.ScrolledContainer#update() | |
116 | */ | |
117 | @Override | |
118 | public void update() | |
119 | { | |
120 | Composite comp = this.getComposite(); | |
121 | if (comp == null || comp.isDisposed()) | |
122 | return; | |
123 | comp.setSize(comp.computeSize(settings.getInt("window.width",WINDOW_WIDTH), SWT.DEFAULT)); | |
124 | comp.layout(); | |
125 | } | |
126 | }; | |
127 | Container c = new SimpleContainer(scroll.getComposite()); | |
105 | 128 | |
106 | 129 | c.addText(i18n.tr("Wählen Sie das Konto aus, für das Sie den Abruf der elektronischen Kontoauszüge konfigurieren möchten.\nFür weitere Informationen klicken Sie auf die Schaltfläche \"Hilfe\".") + "\n",true); |
107 | 130 | c.addInput(this.getKontoAuswahl()); |
134 | 157 | c.addInput(this.getFolder()); |
135 | 158 | c.addInput(this.getName()); |
136 | 159 | |
137 | Container c2 = new SimpleContainer(parent); | |
160 | Container c2 = new SimpleContainer(scroll.getComposite()); | |
138 | 161 | c2.addInput(this.getExampleText()); |
139 | 162 | c2.addInput(this.getExample()); |
163 | c2.addInput(new LabelInput("")); // Unten noch etwas Platzhalter | |
140 | 164 | |
141 | 165 | Container c3 = new SimpleContainer(parent); |
142 | 166 | ButtonArea buttons = new ButtonArea(); |
151 | 175 | },null,false,"window-close.png"); |
152 | 176 | c3.addButtonArea(buttons); |
153 | 177 | |
154 | getShell().setMinimumSize(getShell().computeSize(WINDOW_WIDTH,SWT.DEFAULT)); | |
155 | ||
178 | // Unabhaengig von dem, was der User als Groesse eingestellt hat, bleibt das die Minimalgroesse. | |
179 | getShell().setMinimumSize(WINDOW_WIDTH,WINDOW_HEIGHT); | |
180 | ||
181 | getShell().addDisposeListener(new DisposeListener() { | |
182 | ||
183 | @Override | |
184 | public void widgetDisposed(DisposeEvent e) | |
185 | { | |
186 | Shell shell = getShell(); | |
187 | if (shell == null || shell.isDisposed()) | |
188 | return; | |
189 | ||
190 | Point size = shell.getSize(); | |
191 | Logger.debug("saving window size: " + size.x + "x" + size.y); | |
192 | settings.setAttribute("window.width",size.x); | |
193 | settings.setAttribute("window.height",size.y); | |
194 | } | |
195 | }); | |
156 | 196 | } |
157 | 197 | |
158 | 198 | /** |
298 | 338 | return this.nextFetch; |
299 | 339 | |
300 | 340 | this.nextFetch = new LabelInput(""); |
301 | this.nextFetch.setName(i18n.tr("Nächste Abruf")); | |
341 | this.nextFetch.setName(i18n.tr("Nächster Abruf")); | |
302 | 342 | this.nextFetch.setComment(""); |
303 | 343 | return this.nextFetch; |
304 | 344 | } |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2004 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.gui.dialogs; | |
11 | ||
12 | import org.eclipse.swt.SWT; | |
13 | import org.eclipse.swt.widgets.Composite; | |
14 | ||
15 | import de.willuhn.jameica.gui.Action; | |
16 | import de.willuhn.jameica.gui.dialogs.AbstractDialog; | |
17 | import de.willuhn.jameica.gui.input.CheckboxInput; | |
18 | import de.willuhn.jameica.gui.internal.buttons.Cancel; | |
19 | import de.willuhn.jameica.gui.parts.Button; | |
20 | import de.willuhn.jameica.gui.parts.ButtonArea; | |
21 | import de.willuhn.jameica.gui.util.Container; | |
22 | import de.willuhn.jameica.gui.util.SimpleContainer; | |
23 | import de.willuhn.jameica.hbci.HBCI; | |
24 | import de.willuhn.jameica.system.Application; | |
25 | import de.willuhn.jameica.system.Settings; | |
26 | import de.willuhn.util.ApplicationException; | |
27 | import de.willuhn.util.I18N; | |
28 | ||
29 | /** | |
30 | * Dialog zum Konfigurieren der Anzeigeeinstellungen fuer die Umsaetze. | |
31 | */ | |
32 | public class KontoauszugSettingsDialog extends AbstractDialog | |
33 | { | |
34 | private final static Settings settings = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getSettings(); | |
35 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
36 | ||
37 | private final static int WINDOW_WIDTH = 500; | |
38 | ||
39 | private CheckboxInput displayAll = null; | |
40 | ||
41 | /** | |
42 | * ct. | |
43 | */ | |
44 | public KontoauszugSettingsDialog() | |
45 | { | |
46 | super(POSITION_CENTER); | |
47 | this.setTitle(i18n.tr("Anzeige-Einstellungen")); | |
48 | setSize(WINDOW_WIDTH,SWT.DEFAULT); | |
49 | } | |
50 | ||
51 | /** | |
52 | * @see de.willuhn.jameica.gui.dialogs.AbstractDialog#paint(org.eclipse.swt.widgets.Composite) | |
53 | */ | |
54 | @Override | |
55 | protected void paint(Composite parent) throws Exception | |
56 | { | |
57 | final Container c = new SimpleContainer(parent); | |
58 | c.addInput(this.getDisplayAll()); | |
59 | ||
60 | final Button apply = new Button(i18n.tr("Übernehmen"),new Action() { | |
61 | ||
62 | @Override | |
63 | public void handleAction(Object context) throws ApplicationException | |
64 | { | |
65 | settings.setAttribute("usage.list.all",((Boolean) getDisplayAll().getValue()).booleanValue()); | |
66 | close(); | |
67 | } | |
68 | },null,true,"ok.png"); | |
69 | ||
70 | ButtonArea buttons = new ButtonArea(); | |
71 | buttons.addButton(apply); | |
72 | buttons.addButton(new Cancel()); | |
73 | c.addButtonArea(buttons); | |
74 | ||
75 | getShell().setMinimumSize(getShell().computeSize(WINDOW_WIDTH,SWT.DEFAULT)); | |
76 | } | |
77 | ||
78 | /** | |
79 | * @see de.willuhn.jameica.gui.dialogs.AbstractDialog#getData() | |
80 | */ | |
81 | @Override | |
82 | protected Object getData() throws Exception | |
83 | { | |
84 | return null; | |
85 | } | |
86 | ||
87 | /** | |
88 | * Liefert die Checkbox, mit der eingestellt werden kann, ob alle Daten des Verwendungszwecks angezeigt werden sollen. | |
89 | * @return Checkbox. | |
90 | */ | |
91 | private CheckboxInput getDisplayAll() | |
92 | { | |
93 | if (this.displayAll != null) | |
94 | return this.displayAll; | |
95 | ||
96 | this.displayAll = new CheckboxInput(settings.getBoolean("usage.list.all",false)); | |
97 | this.displayAll.setName(i18n.tr("Alle Daten des Verwendungszwecks anzeigen")); | |
98 | return this.displayAll; | |
99 | } | |
100 | ||
101 | } | |
102 | ||
103 |
15 | 15 | import org.eclipse.swt.widgets.Composite; |
16 | 16 | import org.eclipse.swt.widgets.Event; |
17 | 17 | import org.eclipse.swt.widgets.Listener; |
18 | import org.kapott.hbci.sepa.PainVersion; | |
19 | import org.kapott.hbci.sepa.PainVersion.Type; | |
18 | import org.kapott.hbci.sepa.SepaVersion; | |
19 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
20 | 20 | |
21 | 21 | import de.willuhn.jameica.gui.Action; |
22 | 22 | import de.willuhn.jameica.gui.dialogs.AbstractDialog; |
43 | 43 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
44 | 44 | |
45 | 45 | private Type type = null; |
46 | private PainVersion painVersion = null; | |
46 | private SepaVersion painVersion = null; | |
47 | 47 | private Button ok = null; |
48 | 48 | |
49 | 49 | /** |
77 | 77 | { |
78 | 78 | public void handleAction(Object context) throws ApplicationException |
79 | 79 | { |
80 | painVersion = (PainVersion) version.getValue(); | |
80 | painVersion = (SepaVersion) version.getValue(); | |
81 | 81 | if (painVersion == null) |
82 | 82 | { |
83 | 83 | msg.setValue(i18n.tr("Bitte wählen Sie eine SEPA XML-Version aus.")); |
106 | 106 | */ |
107 | 107 | private SelectInput getPainVersionInput() |
108 | 108 | { |
109 | List<PainVersion> list = PainVersion.getKnownVersions(type); | |
110 | final SelectInput select = new SelectInput(list,PainVersion.findGreatest(list)); | |
109 | List<SepaVersion> list = SepaVersion.getKnownVersions(type); | |
110 | final SelectInput select = new SelectInput(list,SepaVersion.findGreatest(list)); | |
111 | 111 | select.setAttribute("file"); |
112 | 112 | select.setName(i18n.tr("Schema-Version der SEPA XML-Datei")); |
113 | 113 | select.addListener(new Listener() { |
21 | 21 | import org.eclipse.swt.widgets.Event; |
22 | 22 | import org.eclipse.swt.widgets.FileDialog; |
23 | 23 | import org.eclipse.swt.widgets.Listener; |
24 | import org.kapott.hbci.sepa.PainVersion; | |
25 | import org.kapott.hbci.sepa.PainVersion.Type; | |
24 | import org.kapott.hbci.sepa.SepaVersion; | |
25 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
26 | 26 | |
27 | 27 | import de.willuhn.jameica.gui.Action; |
28 | 28 | import de.willuhn.jameica.gui.dialogs.AbstractDialog; |
53 | 53 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
54 | 54 | |
55 | 55 | private Type type = null; |
56 | private PainVersion painVersion = null; | |
56 | private SepaVersion painVersion = null; | |
57 | 57 | private File file = null; |
58 | 58 | private Button ok = null; |
59 | 59 | |
100 | 100 | { |
101 | 101 | public void handleAction(Object context) throws ApplicationException |
102 | 102 | { |
103 | painVersion = (PainVersion) version.getValue(); | |
103 | painVersion = (SepaVersion) version.getValue(); | |
104 | 104 | if (painVersion == null) |
105 | 105 | { |
106 | 106 | msg.setValue(i18n.tr("Bitte wählen Sie eine Schema-Version aus.")); |
155 | 155 | */ |
156 | 156 | private SelectInput getPainVersionInput() |
157 | 157 | { |
158 | List<PainVersion> list = PainVersion.getKnownVersions(type); | |
159 | final SelectInput select = new SelectInput(list,PainVersion.findGreatest(list)); | |
158 | List<SepaVersion> list = SepaVersion.getKnownVersions(type); | |
159 | final SelectInput select = new SelectInput(list,SepaVersion.findGreatest(list)); | |
160 | 160 | select.setAttribute("file"); |
161 | 161 | select.setName(i18n.tr("Schema-Version der SEPA-Datei")); |
162 | 162 | select.addListener(new Listener() { |
238 | 238 | * Liefert die ausgewaehlte PAIN-Version. |
239 | 239 | * @return die ausgewaehlte PAIN-Version. |
240 | 240 | */ |
241 | public PainVersion getPainVersion() | |
241 | public SepaVersion getPainVersion() | |
242 | 242 | { |
243 | 243 | return this.painVersion; |
244 | 244 | } |
11 | 11 | |
12 | 12 | import java.rmi.RemoteException; |
13 | 13 | import java.util.ArrayList; |
14 | import java.util.HashMap; | |
14 | 15 | import java.util.List; |
16 | import java.util.Map; | |
17 | import java.util.Map.Entry; | |
15 | 18 | |
16 | 19 | import org.eclipse.swt.SWT; |
17 | 20 | import org.eclipse.swt.widgets.Composite; |
31 | 34 | import de.willuhn.jameica.gui.util.Container; |
32 | 35 | import de.willuhn.jameica.gui.util.SimpleContainer; |
33 | 36 | import de.willuhn.jameica.hbci.HBCI; |
37 | import de.willuhn.jameica.hbci.MetaKey; | |
34 | 38 | import de.willuhn.jameica.hbci.SynchronizeOptions; |
35 | 39 | import de.willuhn.jameica.hbci.rmi.Konto; |
40 | import de.willuhn.jameica.hbci.server.BPDUtil; | |
41 | import de.willuhn.jameica.hbci.server.BPDUtil.Query; | |
42 | import de.willuhn.jameica.hbci.server.BPDUtil.Support; | |
43 | import de.willuhn.jameica.hbci.server.KontoUtil; | |
36 | 44 | import de.willuhn.jameica.hbci.server.KontoauszugPdfUtil; |
37 | 45 | import de.willuhn.jameica.hbci.synchronize.SynchronizeBackend; |
38 | 46 | import de.willuhn.jameica.hbci.synchronize.SynchronizeEngine; |
39 | 47 | import de.willuhn.jameica.hbci.synchronize.jobs.SynchronizeJobKontoauszug; |
48 | import de.willuhn.jameica.hbci.synchronize.jobs.SynchronizeJobKontoauszugPdf; | |
49 | import de.willuhn.jameica.hbci.synchronize.jobs.SynchronizeJobSepaDauerauftragList; | |
50 | import de.willuhn.jameica.hbci.synchronize.jobs.SynchronizeJobSepaLastschrift; | |
51 | import de.willuhn.jameica.hbci.synchronize.jobs.SynchronizeJobSepaUeberweisung; | |
40 | 52 | import de.willuhn.jameica.messaging.StatusBarMessage; |
41 | 53 | import de.willuhn.jameica.services.BeanService; |
42 | 54 | import de.willuhn.jameica.system.Application; |
51 | 63 | { |
52 | 64 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
53 | 65 | |
54 | private final static int WINDOW_WIDTH = 400; | |
66 | private final static int WINDOW_WIDTH = 500; | |
55 | 67 | |
56 | 68 | private Konto konto = null; |
57 | 69 | private boolean offline = false; |
65 | 77 | private CheckboxInput syncSepaLast = null; |
66 | 78 | private CheckboxInput syncSepaDauer = null; |
67 | 79 | private CheckboxInput syncMessages = null; |
80 | private CheckboxInput useCamt = null; | |
68 | 81 | private LabelInput error = null; |
69 | 82 | private Button apply = null; |
70 | 83 | |
71 | private List<Input> properties = new ArrayList<Input>(); | |
84 | private Map<SynchronizeBackend,List<Input>> properties = new HashMap<SynchronizeBackend,List<Input>>(); | |
72 | 85 | |
73 | 86 | /** |
74 | 87 | * ct. |
98 | 111 | List<String> names = backend.getPropertyNames(konto); |
99 | 112 | if (names != null && names.size() > 0) |
100 | 113 | { |
114 | List<Input> props = new ArrayList<Input>(); | |
115 | this.properties.put(backend,props); | |
101 | 116 | for (String name:names) |
102 | 117 | { |
103 | this.createCustomProperty(name); | |
118 | props.add(this.createCustomProperty(name)); | |
104 | 119 | } |
105 | 120 | } |
106 | 121 | } |
114 | 129 | /** |
115 | 130 | * Erzeugt ein Custom-Property-Input fuer den angegebenen Property-Namen. |
116 | 131 | * @param name der Name des Custom-Property. |
132 | * @return das erzeugte Eingabefeld. | |
117 | 133 | * @throws RemoteException |
118 | 134 | */ |
119 | private void createCustomProperty(String name) throws RemoteException | |
135 | private Input createCustomProperty(String name) throws RemoteException | |
120 | 136 | { |
121 | 137 | Input t = null; |
122 | 138 | if (name.endsWith("(true/false)")) |
137 | 153 | t = new TextInput(konto.getMeta(name,null)); |
138 | 154 | t.setName(name); |
139 | 155 | } |
140 | this.properties.add(t); | |
156 | return t; | |
141 | 157 | } |
142 | 158 | |
143 | 159 | /** |
146 | 162 | protected void paint(Composite parent) throws Exception |
147 | 163 | { |
148 | 164 | Container group = new SimpleContainer(parent); |
165 | ||
166 | group.addHeadline(this.konto.getLongName()); | |
149 | 167 | |
150 | 168 | group.addText(i18n.tr("Bitte wählen Sie aus, welche Geschäftsvorfälle bei der " + |
151 | 169 | "Synchronisierung des Kontos ausgeführt werden sollen."),true); |
152 | 170 | |
153 | group.addHeadline(this.konto.getLongName()); | |
154 | ||
155 | 171 | this.apply = new Button(i18n.tr("Übernehmen"),new Action() { |
156 | 172 | public void handleAction(Object context) throws ApplicationException |
157 | 173 | { |
160 | 176 | { |
161 | 177 | options.setSyncSaldo(((Boolean)getSyncSaldo().getValue()).booleanValue()); |
162 | 178 | options.setSyncKontoauszuege(((Boolean)getSyncUmsatz().getValue()).booleanValue()); |
179 | ||
180 | Support support = BPDUtil.getSupport(konto,Query.UmsatzCamt); | |
181 | if (support != null && support.isSupported()) | |
182 | { | |
183 | try | |
184 | { | |
185 | Boolean value = (Boolean) getUseCamt().getValue(); | |
186 | MetaKey.UMSATZ_CAMT.set(konto,value.toString()); | |
187 | } | |
188 | catch (RemoteException re) | |
189 | { | |
190 | Logger.error("unable to save changes",re); | |
191 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Übernehmen der Einstellungen fehlgeschlagen: {0}",re.getMessage()),StatusBarMessage.TYPE_ERROR)); | |
192 | } | |
193 | } | |
163 | 194 | } |
164 | 195 | |
165 | 196 | if (offline) |
177 | 208 | |
178 | 209 | try |
179 | 210 | { |
180 | for (Input prop:properties) | |
211 | for (List<Input> l:properties.values()) | |
181 | 212 | { |
182 | Object value = prop.getValue(); | |
183 | konto.setMeta(prop.getName(),value != null ? value.toString() : null); | |
213 | for (Input prop:l) | |
214 | { | |
215 | Object value = prop.getValue(); | |
216 | konto.setMeta(prop.getName(),value != null ? value.toString() : null); | |
217 | } | |
184 | 218 | } |
185 | 219 | } |
186 | 220 | catch (Exception e) |
192 | 226 | } |
193 | 227 | },null,true,"ok.png"); |
194 | 228 | |
195 | Input i1 = this.getSyncSaldo(); | |
196 | Input i2 = this.getSyncUmsatz(); | |
197 | Input i3 = this.getSyncOffline(); | |
198 | Input i4 = this.getSyncAueb(); | |
199 | Input i5 = this.getSyncSepaLast(); | |
200 | Input i6 = this.getSyncSepaDauer(); | |
201 | Input i7 = this.getSyncMessages(); | |
202 | Input i8 = this.getSyncKontoauszug(); | |
203 | ||
229 | Input i1 = this.getSyncSaldo(); | |
230 | Input i2 = this.getSyncUmsatz(); | |
231 | Input i3 = this.getSyncOffline(); | |
232 | Input i4 = this.getSyncAueb(); | |
233 | Input i5 = this.getSyncSepaLast(); | |
234 | Input i6 = this.getSyncSepaDauer(); | |
235 | Input i7 = this.getSyncMessages(); | |
236 | Input i8 = this.getSyncKontoauszug(); | |
237 | ||
238 | Input camt = null; | |
239 | ||
204 | 240 | if (!offline || syncAvail) |
205 | 241 | { |
242 | // Wir stellen die Option nur zur Verfuegung, wenn das Konto es prinzipiell unterstuetzt | |
243 | Support support = BPDUtil.getSupport(this.konto,Query.UmsatzCamt); | |
244 | ||
245 | // Wichtig: Das Input muss erzeugt werden, bevor getSyncUmsatz gezeichnet wird. Sonst wird der Listener nicht mehr registriert | |
246 | if (!offline && support != null && support.isSupported()) | |
247 | camt = this.getUseCamt(); | |
248 | ||
206 | 249 | group.addInput(i1); |
207 | 250 | group.addInput(i2); |
208 | 251 | } |
213 | 256 | } |
214 | 257 | else |
215 | 258 | { |
216 | group.addInput(i8); | |
217 | group.addInput(i4); | |
218 | group.addInput(i5); | |
219 | group.addInput(i6); | |
259 | BeanService service = Application.getBootLoader().getBootable(BeanService.class); | |
260 | SynchronizeEngine engine = service.get(SynchronizeEngine.class); | |
261 | ||
262 | if (engine.supports(SynchronizeJobKontoauszugPdf.class,this.konto)) group.addInput(i8); | |
263 | if (engine.supports(SynchronizeJobSepaUeberweisung.class,this.konto)) group.addInput(i4); | |
264 | if (engine.supports(SynchronizeJobSepaLastschrift.class,this.konto)) group.addInput(i5); | |
265 | if (engine.supports(SynchronizeJobSepaDauerauftragList.class,this.konto)) group.addInput(i6); | |
266 | ||
267 | // Abrufen der Nachrichten lassen wir immer zu. | |
220 | 268 | group.addInput(i7); |
221 | 269 | } |
222 | ||
270 | ||
271 | if (camt != null && (!offline || syncAvail)) | |
272 | { | |
273 | group.addHeadline(i18n.tr("Erweiterte Einstellungen: FinTS")); | |
274 | group.addInput(camt); | |
275 | } | |
276 | ||
223 | 277 | if (this.properties.size() > 0) |
224 | 278 | { |
225 | group.addHeadline(i18n.tr("Erweiterte Einstellungen")); | |
226 | for (Input prop:this.properties) | |
227 | { | |
228 | group.addInput(prop); | |
279 | for (Entry<SynchronizeBackend,List<Input>> e:this.properties.entrySet()) | |
280 | { | |
281 | group.addHeadline(i18n.tr("Erweiterte Einstellungen: {0}",e.getKey().getName())); | |
282 | for (Input prop:e.getValue()) | |
283 | { | |
284 | group.addInput(prop); | |
285 | } | |
229 | 286 | } |
230 | 287 | } |
231 | 288 | |
272 | 329 | this.syncUmsatz.addListener(new OfflineListener()); |
273 | 330 | } |
274 | 331 | return this.syncUmsatz; |
332 | } | |
333 | ||
334 | /** | |
335 | * Liefert eine Checkbox fuer die Aktivierung/Deaktivierung des CAMT-Formats. | |
336 | * @return Checkbox. | |
337 | */ | |
338 | private CheckboxInput getUseCamt() | |
339 | { | |
340 | if (this.useCamt == null) | |
341 | { | |
342 | this.useCamt = new CheckboxInput(KontoUtil.useCamt(this.konto,false)); | |
343 | this.useCamt.setName(i18n.tr("Umsätze im neuen SEPA CAMT-Format abrufen")); | |
344 | ||
345 | final CheckboxInput syncUms = this.getSyncUmsatz(); | |
346 | ||
347 | final Listener l = new Listener() { | |
348 | ||
349 | @Override | |
350 | public void handleEvent(Event event) | |
351 | { | |
352 | // Option nur freischalten, wenn Umsatz-Abruf aktiviert ist | |
353 | useCamt.setEnabled((Boolean)syncUms.getValue()); | |
354 | } | |
355 | }; | |
356 | ||
357 | syncUms.addListener(l); | |
358 | l.handleEvent(null); | |
359 | } | |
360 | ||
361 | return this.useCamt; | |
275 | 362 | } |
276 | 363 | |
277 | 364 | /** |
52 | 52 | Class type = e.getType(); |
53 | 53 | if (!type.isAssignableFrom(Umsatz.class)) |
54 | 54 | return; |
55 | ||
56 | boolean initial = ExportDialog.SETTINGS.getBoolean(KEY_SUMROW_ADD,false); | |
57 | Exporter.SESSION.put(KEY_SUMROW_ADD,initial); | |
55 | 58 | |
56 | // Erstmal per Default nicht ausblenden | |
57 | Exporter.SESSION.put(KEY_SUMROW_ADD,false); | |
58 | ||
59 | final CheckboxInput check = new CheckboxInput(ExportDialog.SETTINGS.getBoolean(KEY_SUMROW_ADD,false)); | |
59 | final CheckboxInput check = new CheckboxInput(initial); | |
60 | 60 | check.setName(i18n.tr("Summe-Zeile am Ende der Datei anfügen")); |
61 | 61 | check.addListener(new Listener() { |
62 | 62 | public void handleEvent(Event event) |
54 | 54 | return; |
55 | 55 | |
56 | 56 | // Erstmal per Default nicht ausblenden |
57 | Exporter.SESSION.put(KEY_SALDO_HIDE,false); | |
57 | boolean initial = ExportDialog.SETTINGS.getBoolean(KEY_SALDO_HIDE,false); | |
58 | Exporter.SESSION.put(KEY_SALDO_HIDE,initial); | |
58 | 59 | |
59 | final CheckboxInput check = new CheckboxInput(ExportDialog.SETTINGS.getBoolean(KEY_SALDO_HIDE,false)); | |
60 | final CheckboxInput check = new CheckboxInput(initial); | |
60 | 61 | check.setName(i18n.tr("Spalte \"Saldo\" in Export ausblenden")); |
61 | 62 | check.addListener(new Listener() { |
62 | 63 | public void handleEvent(Event event) |
10 | 10 | package de.willuhn.jameica.hbci.gui.filter; |
11 | 11 | |
12 | 12 | import java.rmi.RemoteException; |
13 | ||
14 | import org.apache.commons.lang.StringUtils; | |
13 | 15 | |
14 | 16 | import de.willuhn.jameica.hbci.HBCIProperties; |
15 | 17 | import de.willuhn.jameica.hbci.rmi.Konto; |
149 | 151 | SynchronizeEngine engine = service.get(SynchronizeEngine.class); |
150 | 152 | return engine.supports(SynchronizeJobKontoauszug.class,konto); |
151 | 153 | } |
152 | }; | |
154 | }; | |
155 | ||
156 | /** | |
157 | * Liefert einen Kontofilter zur Suche nach Konten mit bestimmten Kriterien. | |
158 | * @param text Suchbegriff. | |
159 | * @param ignoreFlags optionale Flags. Kann NULL bleiben, wenn keine Flags als Filter dienen sollen. Konten mit diesen Flags werden ignoriert. | |
160 | * @param accountType optionale Angabe der Kontoart. | |
161 | * @return der Kontofilter. | |
162 | */ | |
163 | public final static KontoFilter SEARCH(final String text, final Integer ignoreFlags, final Integer accountType) | |
164 | { | |
165 | return new KontoFilter() { | |
166 | @Override | |
167 | public boolean accept(Konto konto) throws RemoteException | |
168 | { | |
169 | if (konto == null) | |
170 | return false; | |
171 | ||
172 | if (ignoreFlags != null) | |
173 | { | |
174 | int f = ignoreFlags.intValue(); | |
175 | ||
176 | for (int flag:new int[]{Konto.FLAG_DISABLED,Konto.FLAG_OFFLINE}) | |
177 | { | |
178 | // Ist das Flag in der Suche enthalten? | |
179 | if ((f & flag) == flag) | |
180 | { | |
181 | // Dann darf es im Konto nicht enthalten sein | |
182 | if (konto.hasFlag(flag)) | |
183 | return false; | |
184 | } | |
185 | } | |
186 | } | |
187 | ||
188 | if (accountType != null && (konto.getAccountType() == null || !konto.getAccountType().equals(accountType))) | |
189 | return false; | |
190 | ||
191 | String s = StringUtils.trimToNull(text); | |
192 | if (s == null) | |
193 | return true; | |
194 | s = s.toLowerCase(); | |
195 | ||
196 | String s1 = StringUtils.trimToEmpty(konto.getBezeichnung()).toLowerCase(); | |
197 | String s2 = StringUtils.trimToEmpty(konto.getBic()).toLowerCase(); | |
198 | String s3 = StringUtils.trimToEmpty(konto.getBLZ()).toLowerCase(); | |
199 | String s4 = StringUtils.trimToEmpty(konto.getIban()).toLowerCase(); | |
200 | String s5 = StringUtils.trimToEmpty(konto.getKategorie()).toLowerCase(); | |
201 | String s6 = StringUtils.trimToEmpty(konto.getKommentar()).toLowerCase(); | |
202 | String s7 = StringUtils.trimToEmpty(konto.getKontonummer()).toLowerCase(); | |
203 | String s8 = StringUtils.trimToEmpty(konto.getKundennummer()).toLowerCase(); | |
204 | String s9 = StringUtils.trimToEmpty(konto.getName()).toLowerCase(); | |
205 | ||
206 | return s1.contains(s) || | |
207 | s2.contains(s) || | |
208 | s3.contains(s) || | |
209 | s4.contains(s) || | |
210 | s5.contains(s) || | |
211 | s6.contains(s) || | |
212 | s7.contains(s) || | |
213 | s8.contains(s) || | |
214 | s9.contains(s); | |
215 | } | |
216 | }; | |
217 | } | |
153 | 218 | |
154 | 219 | /** |
155 | 220 | * Erzeugt einen Konto-Filter basierend auf {@link KontoFilter#FOREIGN}, welcher jedoch nur jene Konten |
9 | 9 | |
10 | 10 | package de.willuhn.jameica.hbci.gui.input; |
11 | 11 | |
12 | import java.util.Date; | |
13 | ||
12 | 14 | import org.eclipse.swt.widgets.Event; |
13 | 15 | import org.eclipse.swt.widgets.Listener; |
14 | 16 | |
17 | import de.willuhn.jameica.gui.GUI; | |
15 | 18 | import de.willuhn.jameica.gui.input.Input; |
16 | 19 | import de.willuhn.jameica.gui.input.SelectInput; |
20 | import de.willuhn.jameica.gui.parts.NotificationPanel; | |
17 | 21 | import de.willuhn.jameica.hbci.HBCI; |
18 | 22 | import de.willuhn.jameica.hbci.server.Range; |
23 | import de.willuhn.jameica.messaging.StatusBarMessage; | |
19 | 24 | import de.willuhn.jameica.system.Application; |
20 | 25 | import de.willuhn.jameica.system.Settings; |
21 | 26 | import de.willuhn.util.I18N; |
81 | 86 | |
82 | 87 | setValue(null); |
83 | 88 | settings.setAttribute(param,(String)null); |
89 | checkRange(); | |
84 | 90 | } |
85 | 91 | }; |
86 | 92 | |
102 | 108 | } |
103 | 109 | }); |
104 | 110 | } |
105 | ||
111 | ||
112 | /** | |
113 | * Prueft den vom User eingegebenen Zeitraum auf Plausibilitaet. | |
114 | */ | |
115 | private void checkRange() | |
116 | { | |
117 | if (this.from == null || this.to ==null) | |
118 | return; | |
119 | ||
120 | Object oFrom = this.from.getValue(); | |
121 | Object oTo = this.to.getValue(); | |
122 | ||
123 | if (!(oFrom instanceof Date) || !(oTo instanceof Date)) | |
124 | return; | |
125 | ||
126 | Date dFrom = (Date) oFrom; | |
127 | Date dTo = (Date) oTo; | |
128 | ||
129 | if (dTo.before(dFrom)) | |
130 | { | |
131 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Bitte prüfen Sie den Zeitraum. Das Bis-Datum sollte nicht vor dem Von-Datum liegen."), StatusBarMessage.TYPE_INFO)); | |
132 | return; | |
133 | } | |
134 | ||
135 | // Hier weitere Checks bei Bedarf | |
136 | ||
137 | ||
138 | // Ansonsten Fehlermeldung loeschen | |
139 | NotificationPanel panel = GUI.getView().getNotificationPanel(); | |
140 | if (panel != null) | |
141 | panel.reset(); | |
142 | ||
143 | } | |
144 | ||
106 | 145 | /** |
107 | 146 | * Wendet den Range auf die Von- und Bis-Felder an. |
108 | 147 | * @param range der Range. Kann null sein. |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2018 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.gui.input; | |
11 | ||
12 | import org.eclipse.swt.SWT; | |
13 | import org.eclipse.swt.widgets.Control; | |
14 | import org.eclipse.swt.widgets.Event; | |
15 | import org.eclipse.swt.widgets.Listener; | |
16 | ||
17 | import de.willuhn.jameica.gui.input.TextInput; | |
18 | import de.willuhn.jameica.hbci.HBCI; | |
19 | import de.willuhn.jameica.hbci.HBCIProperties; | |
20 | import de.willuhn.jameica.messaging.StatusBarMessage; | |
21 | import de.willuhn.jameica.system.Application; | |
22 | import de.willuhn.util.I18N; | |
23 | ||
24 | /** | |
25 | * Vorkonfiguriertes Eingabefeld fuer den Verwendungszweck. | |
26 | */ | |
27 | public class ZweckInput extends TextInput | |
28 | { | |
29 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
30 | private final static String VALID = HBCIProperties.HBCI_SEPA_VALIDCHARS; | |
31 | ||
32 | private Control control = null; | |
33 | ||
34 | /** | |
35 | * ct. | |
36 | * @param value der Verwendungszweck. | |
37 | */ | |
38 | public ZweckInput(String value) | |
39 | { | |
40 | super(value,HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
41 | this.setValidChars(VALID); | |
42 | this.setName(i18n.tr("Verwendungszweck")); | |
43 | } | |
44 | ||
45 | /** | |
46 | * Ueberschrieben, um die in SEPA-Verwendungszwecken erlaubten Zeichen automatisch zu entfernen. | |
47 | * Dann kann der User per Zwischenablage auch unerlaubte Zeichen einfuegen. Hibiscus schneidet die | |
48 | * dann automatisch raus. | |
49 | * @see de.willuhn.jameica.gui.input.TextInput#getControl() | |
50 | */ | |
51 | @Override | |
52 | public Control getControl() | |
53 | { | |
54 | if (this.control != null) | |
55 | return this.control; | |
56 | ||
57 | this.control = super.getControl(); | |
58 | ||
59 | // BUGZILLA 1495 - nicht erlaubte Zeichen automatisch rausschneiden | |
60 | this.control.addListener(SWT.Verify, new Listener() | |
61 | { | |
62 | public void handleEvent(Event e) | |
63 | { | |
64 | if (e.text == null || e.text.length() == 0) | |
65 | return; | |
66 | ||
67 | String backup = e.text; | |
68 | e.text = HBCIProperties.clean(e.text,VALID); | |
69 | ||
70 | int diff = backup.length() - e.text.length(); | |
71 | if (diff > 0) | |
72 | { | |
73 | String msg = diff > 1 ? i18n.tr("Es wurden {0} nicht unterstützte Zeichen entfernt",Integer.toString(diff)) : i18n.tr("Es wurde ein nicht unterstütztes Zeichen entfernt"); | |
74 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(msg,StatusBarMessage.TYPE_INFO)); | |
75 | } | |
76 | } | |
77 | }); | |
78 | ||
79 | return this.control; | |
80 | ||
81 | } | |
82 | ||
83 | } |
12 | 12 | |
13 | 13 | import de.willuhn.jameica.gui.Action; |
14 | 14 | import de.willuhn.jameica.gui.extension.Extendable; |
15 | import de.willuhn.jameica.gui.extension.ExtensionRegistry; | |
15 | 16 | import de.willuhn.jameica.gui.parts.CheckedContextMenuItem; |
16 | 17 | import de.willuhn.jameica.gui.parts.CheckedSingleContextMenuItem; |
17 | 18 | import de.willuhn.jameica.gui.parts.ContextMenu; |
47 | 48 | public class KontoList extends ContextMenu implements Extendable |
48 | 49 | { |
49 | 50 | |
50 | private I18N i18n; | |
51 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
51 | 52 | |
52 | 53 | /** |
53 | 54 | * Erzeugt ein Kontext-Menu fuer eine Liste von Konten. |
54 | 55 | */ |
55 | 56 | public KontoList() |
56 | 57 | { |
57 | i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
58 | ||
59 | 58 | addItem(new CheckedSingleContextMenuItem(i18n.tr("Öffnen"), new KontoNew(),"document-open.png")); |
60 | 59 | addItem(new ContextMenuItem(i18n.tr("Neues Konto..."), new KNeu(),"list-add.png")); |
61 | 60 | addItem(new CheckedSingleContextMenuItem(i18n.tr("Löschen..."), new KontoDelete(),"user-trash-full.png")); |
75 | 74 | addItem(new ContextMenuItem(i18n.tr("Umsätze importieren..."),new UmsatzImport(),"document-open.png")); |
76 | 75 | addItem(ContextMenuItem.SEPARATOR); |
77 | 76 | addMenu(new ExtendedMenu()); |
77 | ||
78 | // Wir geben das Context-Menu jetzt noch zur Erweiterung frei. | |
79 | ExtensionRegistry.extend(this); | |
78 | 80 | } |
79 | 81 | |
80 | 82 | /** |
32 | 32 | import de.willuhn.jameica.gui.formatter.TableFormatter; |
33 | 33 | import de.willuhn.jameica.gui.input.SelectInput; |
34 | 34 | import de.willuhn.jameica.gui.input.TextInput; |
35 | import de.willuhn.jameica.gui.parts.ButtonArea; | |
35 | 36 | import de.willuhn.jameica.gui.parts.TablePart; |
36 | 37 | import de.willuhn.jameica.gui.util.Color; |
37 | 38 | import de.willuhn.jameica.gui.util.DelayedListener; |
38 | 39 | import de.willuhn.jameica.gui.util.TabGroup; |
39 | 40 | import de.willuhn.jameica.hbci.HBCI; |
40 | 41 | import de.willuhn.jameica.hbci.HBCIProperties; |
42 | import de.willuhn.jameica.hbci.gui.action.EmpfaengerNew; | |
41 | 43 | import de.willuhn.jameica.hbci.gui.filter.AddressFilter; |
42 | 44 | import de.willuhn.jameica.hbci.gui.formatter.IbanFormatter; |
43 | 45 | import de.willuhn.jameica.hbci.messaging.ImportMessage; |
60 | 62 | */ |
61 | 63 | public class EmpfaengerList extends TablePart implements Part |
62 | 64 | { |
65 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
66 | ||
63 | 67 | private Addressbook book = null; |
64 | 68 | private TextInput search = null; |
65 | private I18N i18n = null; | |
66 | 69 | private KeyAdapter listener = null; |
67 | 70 | private AddressFilter filter = null; |
68 | 71 | |
92 | 95 | super(action); |
93 | 96 | |
94 | 97 | this.filter = filter; |
95 | ||
96 | this.i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
97 | 98 | this.listener = new DelayedAdapter(); |
98 | 99 | |
99 | 100 | addColumn(i18n.tr("Name"),"name"); |
231 | 232 | tab.addLabelPair(i18n.tr("Suchbegriff"), this.search); |
232 | 233 | this.search.getControl().addKeyListener(this.listener); |
233 | 234 | |
235 | ButtonArea buttons = new ButtonArea(); | |
236 | buttons.addButton(i18n.tr("Neue Adresse"),new EmpfaengerNew(),null,true,"contact-new.png"); | |
237 | buttons.paint(parent); | |
234 | 238 | |
235 | 239 | // Damit wir den MessageConsumer beim Schliessen wieder entfernen |
236 | 240 | parent.addDisposeListener(new DisposeListener() { |
13 | 13 | import java.util.Arrays; |
14 | 14 | import java.util.List; |
15 | 15 | |
16 | import org.eclipse.swt.SWT; | |
16 | 17 | import org.eclipse.swt.events.DisposeEvent; |
17 | 18 | import org.eclipse.swt.events.DisposeListener; |
19 | import org.eclipse.swt.events.KeyAdapter; | |
20 | import org.eclipse.swt.events.KeyEvent; | |
21 | import org.eclipse.swt.events.KeyListener; | |
22 | import org.eclipse.swt.layout.GridData; | |
18 | 23 | import org.eclipse.swt.widgets.Composite; |
19 | 24 | import org.eclipse.swt.widgets.Event; |
20 | 25 | import org.eclipse.swt.widgets.Listener; |
26 | import org.eclipse.swt.widgets.TabFolder; | |
21 | 27 | import org.eclipse.swt.widgets.TableItem; |
22 | 28 | |
23 | import de.willuhn.datasource.GenericIterator; | |
24 | 29 | import de.willuhn.datasource.GenericObject; |
25 | import de.willuhn.datasource.rmi.DBIterator; | |
26 | 30 | import de.willuhn.jameica.gui.Action; |
27 | 31 | import de.willuhn.jameica.gui.GUI; |
28 | 32 | import de.willuhn.jameica.gui.Part; |
29 | import de.willuhn.jameica.gui.formatter.CurrencyFormatter; | |
30 | 33 | import de.willuhn.jameica.gui.formatter.DateFormatter; |
31 | 34 | import de.willuhn.jameica.gui.formatter.Formatter; |
32 | 35 | import de.willuhn.jameica.gui.formatter.TableFormatter; |
36 | import de.willuhn.jameica.gui.input.CheckboxInput; | |
37 | import de.willuhn.jameica.gui.input.SelectInput; | |
38 | import de.willuhn.jameica.gui.input.TextInput; | |
39 | import de.willuhn.jameica.gui.parts.ButtonArea; | |
33 | 40 | import de.willuhn.jameica.gui.parts.Column; |
34 | 41 | import de.willuhn.jameica.gui.parts.TablePart; |
42 | import de.willuhn.jameica.gui.parts.table.Feature; | |
43 | import de.willuhn.jameica.gui.parts.table.Feature.Context; | |
44 | import de.willuhn.jameica.gui.parts.table.FeatureSummary; | |
35 | 45 | import de.willuhn.jameica.gui.util.Color; |
46 | import de.willuhn.jameica.gui.util.ColumnLayout; | |
47 | import de.willuhn.jameica.gui.util.Container; | |
48 | import de.willuhn.jameica.gui.util.DelayedListener; | |
49 | import de.willuhn.jameica.gui.util.SimpleContainer; | |
50 | import de.willuhn.jameica.gui.util.TabGroup; | |
36 | 51 | import de.willuhn.jameica.hbci.HBCI; |
37 | 52 | import de.willuhn.jameica.hbci.HBCIProperties; |
38 | 53 | import de.willuhn.jameica.hbci.PassportRegistry; |
39 | import de.willuhn.jameica.hbci.Settings; | |
40 | 54 | import de.willuhn.jameica.hbci.gui.ColorUtil; |
55 | import de.willuhn.jameica.hbci.gui.action.KontoFetchFromPassport; | |
56 | import de.willuhn.jameica.hbci.gui.action.KontoNew; | |
57 | import de.willuhn.jameica.hbci.gui.filter.KontoFilter; | |
58 | import de.willuhn.jameica.hbci.gui.input.KontoartInput; | |
41 | 59 | import de.willuhn.jameica.hbci.messaging.ObjectChangedMessage; |
42 | 60 | import de.willuhn.jameica.hbci.messaging.ObjectMessage; |
43 | 61 | import de.willuhn.jameica.hbci.messaging.SaldoMessage; |
44 | 62 | import de.willuhn.jameica.hbci.passport.Passport; |
45 | 63 | import de.willuhn.jameica.hbci.rmi.Konto; |
64 | import de.willuhn.jameica.hbci.server.KontoUtil; | |
46 | 65 | import de.willuhn.jameica.messaging.Message; |
47 | 66 | import de.willuhn.jameica.messaging.MessageConsumer; |
67 | import de.willuhn.jameica.messaging.StatusBarMessage; | |
48 | 68 | import de.willuhn.jameica.system.Application; |
49 | 69 | import de.willuhn.logging.Logger; |
70 | import de.willuhn.util.ApplicationException; | |
50 | 71 | import de.willuhn.util.I18N; |
51 | 72 | |
52 | 73 | /** |
54 | 75 | */ |
55 | 76 | public class KontoList extends TablePart implements Part |
56 | 77 | { |
57 | ||
58 | // BUGZILLA 476 | |
78 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
79 | private final static de.willuhn.jameica.system.Settings settings = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getSettings(); | |
80 | ||
81 | private TextInput search = null; | |
82 | private CheckboxInput onlyActive = null; | |
83 | private SelectInput accountType = null; | |
84 | ||
59 | 85 | private MessageConsumer mc = null; |
60 | ||
61 | private I18N i18n; | |
62 | ||
63 | /** | |
64 | * @param action | |
65 | * @throws RemoteException | |
66 | */ | |
67 | public KontoList(Action action) throws RemoteException | |
68 | { | |
69 | this(init(), action); | |
70 | } | |
86 | private boolean showFilter = true; | |
87 | ||
88 | private Listener listener = new MyListener(); | |
89 | private KeyListener delayed = new MyDelayedListener(); | |
71 | 90 | |
72 | 91 | /** |
73 | 92 | * ct. |
74 | 93 | * @param konten |
75 | 94 | * @param action |
76 | 95 | */ |
77 | public KontoList(GenericIterator konten, Action action) | |
96 | public KontoList(List<Konto> konten, Action action) | |
78 | 97 | { |
79 | 98 | super(konten,action); |
80 | ||
81 | this.i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
99 | this.addFeature(new FeatureSummary()); | |
82 | 100 | |
83 | 101 | addColumn(i18n.tr("Kontonummer"),"kontonummer",null,false,Column.ALIGN_RIGHT); |
84 | 102 | addColumn(i18n.tr("Bankleitzahl"),"blz", new Formatter() { |
123 | 141 | } |
124 | 142 | }); |
125 | 143 | addColumn(i18n.tr("Saldo"),"saldo",null,false,Column.ALIGN_RIGHT); |
126 | addSaldoAvailable(konten); | |
144 | addColumn(i18n.tr("Verfügbar"),"saldo_available",null,false,Column.ALIGN_RIGHT); | |
127 | 145 | // BUGZILLA 108 http://www.willuhn.de/bugzilla/show_bug.cgi?id=108 |
128 | 146 | addColumn(i18n.tr("Saldo aktualisiert am"),"saldo_datum", new DateFormatter(HBCI.LONGDATEFORMAT)); |
129 | 147 | setFormatter(new TableFormatter() |
137 | 155 | if ((saldo == 0 && k.getSaldoDatum() == null) || Double.isNaN(saldo)) |
138 | 156 | item.setText(saldocolumn,""); |
139 | 157 | else |
140 | item.setText(saldocolumn,HBCI.DECIMALFORMAT.format(k.getSaldo()) + " " + k.getWaehrung()); | |
158 | item.setText(saldocolumn,HBCI.DECIMALFORMAT.format(saldo) + " " + k.getWaehrung()); | |
159 | ||
160 | double avail = k.getSaldoAvailable(); | |
161 | if ((avail == 0 && k.getSaldoDatum() == null) || Double.isNaN(avail)) | |
162 | item.setText(saldocolumn+1,""); | |
163 | else | |
164 | item.setText(saldocolumn+1,HBCI.DECIMALFORMAT.format(avail) + " " + k.getWaehrung()); | |
165 | ||
166 | item.setForeground(saldocolumn+1,ColorUtil.getForeground(k.getSaldoAvailable())); | |
141 | 167 | |
142 | 168 | // Checken, ob Konto deaktiviert ist |
143 | 169 | int flags = k.getFlags(); |
180 | 206 | { |
181 | 207 | public void handleEvent(Event event) |
182 | 208 | { |
183 | refreshSummary(); | |
209 | featureEvent(Feature.Event.REFRESH,null); | |
184 | 210 | } |
185 | 211 | }); |
186 | 212 | } |
187 | ||
188 | /** | |
189 | * Fuegt die Spalte "verfuegbarer Betrag" hinzu, wenn wenigstens ein Konto | |
190 | * aus der Liste einen solchen besitzt. | |
191 | * @param konten Liste der zu checkenden Konten. | |
192 | */ | |
193 | private void addSaldoAvailable(GenericIterator konten) | |
194 | { | |
195 | try | |
196 | { | |
197 | while (konten.hasNext()) | |
198 | { | |
199 | Konto k = (Konto) konten.next(); | |
200 | if ((k.getFlags() & Konto.FLAG_OFFLINE) == Konto.FLAG_OFFLINE) | |
201 | continue; // ignorieren | |
202 | double d = k.getSaldoAvailable(); | |
203 | if (!Double.isNaN(d)) | |
204 | { | |
205 | // Wir haben tatsaechlich eines, wo was drin steht | |
206 | Column col = new Column("saldo_available",i18n.tr("Verfügbar"),new CurrencyFormatter(k.getWaehrung(),HBCI.DECIMALFORMAT),false,Column.ALIGN_RIGHT); | |
207 | addColumn(col); | |
208 | return; | |
209 | } | |
210 | } | |
211 | } | |
212 | catch (RemoteException re) | |
213 | { | |
214 | Logger.error("unable to check if at least one account has an available value",re); | |
215 | } | |
216 | finally | |
217 | { | |
218 | try | |
219 | { | |
220 | konten.begin(); | |
221 | } | |
222 | catch (Exception e) | |
223 | { | |
224 | Logger.error("unable to reset iterator",e); | |
225 | } | |
226 | } | |
213 | ||
214 | /** | |
215 | * Legt fest, ob die Filtermoeglichkeiten angezeigt werden sollen. | |
216 | * @param b true, wenn die Filtermoeglichkeiten angezeigt werden sollen. | |
217 | */ | |
218 | public void setShowFilter(boolean b) | |
219 | { | |
220 | this.showFilter = b; | |
227 | 221 | } |
228 | 222 | |
229 | 223 | /** |
231 | 225 | */ |
232 | 226 | public synchronized void paint(Composite parent) throws RemoteException |
233 | 227 | { |
228 | if (this.showFilter) | |
229 | { | |
230 | // Daten initial laden | |
231 | reload(); | |
232 | ||
233 | final TabFolder folder = new TabFolder(parent, SWT.NONE); | |
234 | folder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
235 | TabGroup tab = new TabGroup(folder,i18n.tr("Anzeige einschränken")); | |
236 | ||
237 | ColumnLayout cols = new ColumnLayout(tab.getComposite(),2); | |
238 | ||
239 | { | |
240 | Container c = new SimpleContainer(cols.getComposite()); | |
241 | TextInput search = this.getText(); | |
242 | c.addInput(search); | |
243 | search.getControl().addKeyListener(this.delayed); | |
244 | ||
245 | c.addInput(this.getActiveOnly()); | |
246 | } | |
247 | ||
248 | { | |
249 | Container c = new SimpleContainer(cols.getComposite()); | |
250 | c.addInput(this.getAccountType()); | |
251 | } | |
252 | ||
253 | ButtonArea buttons = new ButtonArea(); | |
254 | buttons.addButton(i18n.tr("Konten über den Bank-Zugang importieren..."), new Action() { | |
255 | public void handleAction(Object context) throws ApplicationException | |
256 | { | |
257 | new KontoFetchFromPassport().handleAction(getSelection()); | |
258 | } | |
259 | },null,false,"mail-send-receive.png"); | |
260 | buttons.addButton(i18n.tr("Konto manuell anlegen"),new KontoNew(),null,false,"list-add.png"); | |
261 | buttons.paint(parent); | |
262 | } | |
263 | ||
234 | 264 | parent.addDisposeListener(new DisposeListener() { |
235 | 265 | public void widgetDisposed(DisposeEvent e) |
236 | 266 | { |
239 | 269 | }); |
240 | 270 | super.paint(parent); |
241 | 271 | } |
242 | ||
243 | /** | |
244 | * Initialisiert die Konten-Liste. | |
245 | * @return Liste der Konten. | |
272 | ||
273 | /** | |
274 | * Liefert das Eingabefeld mit dem Suchbegriff. | |
275 | * @return das Eingabefeld mit dem Suchbegriff. | |
276 | */ | |
277 | private TextInput getText() | |
278 | { | |
279 | if (this.search != null) | |
280 | return this.search; | |
281 | ||
282 | this.search = new TextInput(settings.getString("kontolist.filter.text",null),255); | |
283 | this.search.setName(i18n.tr("Suchbegriff")); | |
284 | return this.search; | |
285 | } | |
286 | ||
287 | /** | |
288 | * Liefert die Checkbox, mit der eingestellt werden kann, ob nur aktive Konten angezeigt werden sollen. | |
289 | * @return Checkbox. | |
290 | */ | |
291 | private CheckboxInput getActiveOnly() | |
292 | { | |
293 | if (this.onlyActive != null) | |
294 | return this.onlyActive; | |
295 | ||
296 | this.onlyActive = new CheckboxInput(settings.getBoolean("kontolist.filter.active",false)); | |
297 | this.onlyActive.setName(i18n.tr("Nur aktive Konten")); | |
298 | this.onlyActive.addListener(this.listener); | |
299 | return this.onlyActive; | |
300 | } | |
301 | ||
302 | /** | |
303 | * Liefert eine Auswahlbox mit der Kontoart. | |
304 | * @return eine Auswahlbox mit der Kontoart. | |
305 | */ | |
306 | private SelectInput getAccountType() | |
307 | { | |
308 | if (this.accountType != null) | |
309 | return this.accountType; | |
310 | ||
311 | this.accountType = new KontoartInput(settings.getInt("kontolist.filter.type",-1)); | |
312 | this.accountType.addListener(this.listener); | |
313 | return this.accountType; | |
314 | } | |
315 | ||
316 | /** | |
317 | * Laedt die Liste der Konten neu. | |
318 | */ | |
319 | private void reload() | |
320 | { | |
321 | GUI.startSync(new Runnable() { | |
322 | ||
323 | @Override | |
324 | public void run() | |
325 | { | |
326 | try | |
327 | { | |
328 | removeAll(); | |
329 | ||
330 | // Liste neu laden | |
331 | List<Konto> konten = getList(); | |
332 | if (konten == null) | |
333 | return; | |
334 | ||
335 | for (Konto k:konten) | |
336 | addItem(k); | |
337 | ||
338 | // Sortierung wiederherstellen | |
339 | sort(); | |
340 | } | |
341 | catch (Exception e) | |
342 | { | |
343 | Logger.error("error while reloading table",e); | |
344 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Fehler beim Aktualisieren der Tabelle"), StatusBarMessage.TYPE_ERROR)); | |
345 | } | |
346 | } | |
347 | }); | |
348 | } | |
349 | ||
350 | /** | |
351 | * Liefert die Liste der gefundenen Konten. | |
352 | * @return die Liste der Konten. | |
246 | 353 | * @throws RemoteException |
247 | 354 | */ |
248 | private static DBIterator init() throws RemoteException | |
249 | { | |
250 | DBIterator i = Settings.getDBService().createList(Konto.class); | |
251 | i.setOrder("ORDER BY LOWER(kategorie), blz, kontonummer, bezeichnung"); | |
252 | return i; | |
253 | } | |
254 | ||
255 | /** | |
256 | * @see de.willuhn.jameica.gui.parts.TablePart#getSummary() | |
257 | */ | |
258 | protected String getSummary() | |
355 | private List<Konto> getList() throws RemoteException | |
356 | { | |
357 | final String text = (String) this.getText().getValue(); | |
358 | final boolean activeOnly = ((Boolean)this.getActiveOnly().getValue()).booleanValue(); | |
359 | final Integer type = (Integer) getAccountType().getValue(); | |
360 | ||
361 | Integer flags = activeOnly ? Konto.FLAG_DISABLED : null; | |
362 | List<Konto> list = KontoUtil.getKonten(KontoFilter.SEARCH(text,flags,type)); | |
363 | ||
364 | // Speichern der Werte aus den Filter-Feldern. | |
365 | settings.setAttribute("kontolist.filter.text",text); | |
366 | settings.setAttribute("kontolist.filter.active",activeOnly); | |
367 | settings.setAttribute("kontolist.filter.type",type != null ? type.intValue() : -1); | |
368 | ||
369 | return list; | |
370 | } | |
371 | ||
372 | /** | |
373 | * @see de.willuhn.jameica.gui.parts.TablePart#createFeatureEventContext(de.willuhn.jameica.gui.parts.table.Feature.Event, java.lang.Object) | |
374 | */ | |
375 | @Override | |
376 | protected Context createFeatureEventContext(de.willuhn.jameica.gui.parts.table.Feature.Event e, Object data) | |
377 | { | |
378 | Context ctx = super.createFeatureEventContext(e, data); | |
379 | if (this.hasEvent(FeatureSummary.class,e)) | |
380 | ctx.addon.put(FeatureSummary.CTX_KEY_TEXT,this.getSummaryText()); | |
381 | return ctx; | |
382 | } | |
383 | ||
384 | /** | |
385 | * Liefert die Summenzeile. | |
386 | * @return die Summenzeile. | |
387 | */ | |
388 | private String getSummaryText() | |
259 | 389 | { |
260 | 390 | try |
261 | 391 | { |
280 | 410 | |
281 | 411 | if (selected) |
282 | 412 | return i18n.tr("{0} Konten markiert, Gesamt-Saldo: {1} {2}",new String[]{Integer.toString(items.size()),HBCI.DECIMALFORMAT.format(sum),HBCIProperties.CURRENCY_DEFAULT_DE}); |
283 | ||
413 | ||
284 | 414 | return i18n.tr("Gesamt-Saldo: {0} {1}",new String[]{HBCI.DECIMALFORMAT.format(sum),HBCIProperties.CURRENCY_DEFAULT_DE}); |
285 | 415 | } |
286 | catch (Exception e) | |
287 | { | |
288 | Logger.error("error while updating summary",e); | |
289 | } | |
290 | return super.getSummary(); | |
416 | catch (Exception ex) | |
417 | { | |
418 | Logger.error("error while updating summary",ex); | |
419 | } | |
420 | ||
421 | return null; | |
291 | 422 | } |
292 | 423 | |
293 | 424 | /** |
345 | 476 | select(o); |
346 | 477 | |
347 | 478 | // Summen-Zeile aktualisieren |
348 | refreshSummary(); | |
479 | featureEvent(Feature.Event.REFRESH,null); | |
349 | 480 | } |
350 | 481 | catch (Exception e) |
351 | 482 | { |
363 | 494 | return false; |
364 | 495 | } |
365 | 496 | } |
497 | ||
498 | /** | |
499 | * Listener zum Neuladen der Daten. | |
500 | */ | |
501 | private class MyListener implements Listener | |
502 | { | |
503 | /** | |
504 | * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) | |
505 | */ | |
506 | @Override | |
507 | public void handleEvent(Event event) | |
508 | { | |
509 | reload(); | |
510 | } | |
511 | } | |
512 | ||
513 | /** | |
514 | * Listener fuer das verzoegerte Reload. | |
515 | */ | |
516 | private class MyDelayedListener extends KeyAdapter | |
517 | { | |
518 | private Listener forward = new DelayedListener(700,listener); | |
519 | ||
520 | /** | |
521 | * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent) | |
522 | */ | |
523 | public void keyReleased(KeyEvent e) | |
524 | { | |
525 | forward.handleEvent(null); | |
526 | } | |
527 | } | |
366 | 528 | } |
198 | 198 | } |
199 | 199 | |
200 | 200 | ButtonArea buttons = new ButtonArea(); |
201 | buttons.addButton(i18n.tr("Kontoauszüge abrufen..."), new KontoAction(new KontoFetchKontoauszug(),this.getKontoAuswahl()),null,false,"mail-send-receive.png"); | |
202 | buttons.addButton(i18n.tr("Einstellungen"),new KontoAction(new KontoauszugPdfSettings(),this.getKontoAuswahl()),null,false,"document-properties.png"); | |
201 | buttons.addButton(i18n.tr("Kontoauszüge abrufen..."), new KontoAction(new KontoFetchKontoauszug()),null,false,"mail-send-receive.png"); | |
202 | buttons.addButton(i18n.tr("Einstellungen"),new KontoAction(new KontoauszugPdfSettings()),null,false,"document-properties.png"); | |
203 | 203 | buttons.addButton(i18n.tr("Aktualisieren"), new Action() |
204 | 204 | { |
205 | 205 | public void handleAction(Object context) throws ApplicationException |
460 | 460 | return false; |
461 | 461 | } |
462 | 462 | } |
463 | ||
464 | /** | |
465 | * Oeffnet die Einstellungen. | |
466 | * @throws ApplicationException | |
467 | */ | |
468 | public void handleSettings() throws ApplicationException | |
469 | { | |
470 | new KontoAction(new KontoauszugPdfSettings()).handleAction(null); | |
471 | } | |
463 | 472 | |
464 | 473 | /** |
465 | 474 | * Uebernimmt automatisch das ausgewaehlte Konto in die Action. |
467 | 476 | private class KontoAction implements Action |
468 | 477 | { |
469 | 478 | private Action redirect = null; |
470 | private KontoInput input = null; | |
471 | 479 | |
472 | 480 | /** |
473 | 481 | * ct. |
474 | 482 | * @param redirect |
475 | 483 | */ |
476 | private KontoAction(Action redirect, KontoInput input) | |
484 | private KontoAction(Action redirect) | |
477 | 485 | { |
478 | 486 | this.redirect = redirect; |
479 | this.input = input; | |
480 | 487 | } |
481 | 488 | |
482 | 489 | /** |
490 | 497 | Konto k = null; |
491 | 498 | try |
492 | 499 | { |
493 | Object o = input.getValue(); | |
500 | Object o = getKontoAuswahl().getValue(); | |
494 | 501 | if (o != null && (o instanceof Konto)) |
495 | 502 | k = (Konto) o; |
496 | 503 | } |
72 | 72 | { |
73 | 73 | Object data = item.getData(); |
74 | 74 | if (data instanceof ConfigObject) |
75 | item.setImage(SWTUtil.getImage("user-info.png")); | |
75 | { | |
76 | ConfigObject o = (ConfigObject) data; | |
77 | Passport p = o.passport; | |
78 | String icon = "system-users.png"; | |
79 | if (p instanceof de.willuhn.jameica.hbci.passports.pintan.rmi.Passport) | |
80 | icon = "hbci-pintan.png"; | |
81 | else if (p instanceof de.willuhn.jameica.hbci.passports.rdh.rmi.Passport) | |
82 | icon = "dialog-password.png"; | |
83 | else if (p instanceof de.willuhn.jameica.hbci.passports.ddv.rmi.Passport) | |
84 | icon = "gcr-smart-card.png"; | |
85 | ||
86 | item.setImage(SWTUtil.getImage(icon)); | |
87 | } | |
76 | 88 | } |
77 | 89 | }); |
78 | 90 | this.setMulti(false); |
22 | 22 | import org.eclipse.swt.widgets.Listener; |
23 | 23 | import org.eclipse.swt.widgets.TreeItem; |
24 | 24 | |
25 | import de.willuhn.datasource.BeanUtil; | |
26 | 25 | import de.willuhn.datasource.GenericIterator; |
27 | 26 | import de.willuhn.datasource.GenericObject; |
28 | 27 | import de.willuhn.datasource.pseudo.PseudoIterator; |
34 | 33 | import de.willuhn.jameica.gui.parts.table.Feature; |
35 | 34 | import de.willuhn.jameica.gui.parts.table.Feature.Context; |
36 | 35 | import de.willuhn.jameica.gui.parts.table.Feature.Event; |
36 | import de.willuhn.jameica.gui.parts.table.FeatureShortcut; | |
37 | 37 | import de.willuhn.jameica.gui.parts.table.FeatureSummary; |
38 | 38 | import de.willuhn.jameica.gui.util.Font; |
39 | 39 | import de.willuhn.jameica.hbci.HBCI; |
59 | 59 | private final static de.willuhn.jameica.system.Settings settings = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getSettings(); |
60 | 60 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
61 | 61 | private static Hashtable<String,Color> colorCache = new Hashtable<String,Color>(); |
62 | private boolean summary = false; | |
63 | 62 | |
64 | 63 | /** |
65 | 64 | * ct. |
69 | 68 | public UmsatzTree(GenericIterator list) throws RemoteException |
70 | 69 | { |
71 | 70 | super(list, new UmsatzDetail()); |
72 | ||
73 | try | |
74 | { | |
75 | BeanUtil.invoke(this,"addFeature",new Object[]{"de.willuhn.jameica.gui.parts.table.FeatureShortcut"}); | |
76 | } | |
77 | catch (Exception e) | |
78 | { | |
79 | Logger.warn("Shortcut feature not available in this jameica version"); | |
80 | } | |
81 | try | |
82 | { | |
83 | BeanUtil.invoke(this,"addFeature",new Object[]{"de.willuhn.jameica.gui.parts.table.FeatureSummary"}); | |
84 | this.summary = true; | |
85 | } | |
86 | catch (Exception e) | |
87 | { | |
88 | Logger.warn("Summary feature not available in this jameica version"); | |
89 | } | |
71 | this.addFeature(new FeatureShortcut()); | |
72 | this.addFeature(new FeatureSummary()); | |
90 | 73 | |
91 | 74 | this.setRememberColWidths(true); |
92 | 75 | this.setRememberOrder(true); |
164 | 147 | |
165 | 148 | this.setContextMenu(new UmsatzList()); |
166 | 149 | |
167 | if (this.summary) | |
168 | { | |
169 | this.addSelectionListener(new Listener() { | |
170 | @Override | |
171 | public void handleEvent(org.eclipse.swt.widgets.Event event) | |
172 | { | |
173 | featureEvent(Feature.Event.REFRESH,null); | |
174 | } | |
175 | }); | |
176 | } | |
150 | this.addSelectionListener(new Listener() { | |
151 | @Override | |
152 | public void handleEvent(org.eclipse.swt.widgets.Event event) | |
153 | { | |
154 | featureEvent(Feature.Event.REFRESH,null); | |
155 | } | |
156 | }); | |
177 | 157 | } |
178 | 158 | |
179 | 159 |
12 | 12 | import java.rmi.RemoteException; |
13 | 13 | import java.util.ArrayList; |
14 | 14 | import java.util.Calendar; |
15 | import java.util.Collections; | |
15 | 16 | import java.util.Date; |
16 | 17 | import java.util.HashMap; |
17 | 18 | import java.util.List; |
18 | ||
19 | import java.util.Set; | |
20 | ||
21 | import org.eclipse.swt.SWT; | |
22 | import org.eclipse.swt.events.SelectionAdapter; | |
23 | import org.eclipse.swt.events.SelectionEvent; | |
24 | import org.eclipse.swt.events.SelectionListener; | |
19 | 25 | import org.eclipse.swt.widgets.Composite; |
26 | import org.eclipse.swt.widgets.Menu; | |
27 | import org.eclipse.swt.widgets.MenuItem; | |
20 | 28 | |
21 | 29 | import de.willuhn.datasource.GenericObject; |
22 | 30 | import de.willuhn.jameica.gui.Part; |
39 | 47 | { |
40 | 48 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
41 | 49 | |
42 | private List data = null; | |
43 | private Date start = null; | |
44 | private Date stop = null; | |
45 | private LineChart chart = null; | |
50 | private List data = null; | |
51 | private Date start = null; | |
52 | private Date stop = null; | |
53 | private LineChart chart = null; | |
54 | private Interval interval = Interval.MONTH; | |
55 | ||
56 | /** | |
57 | * Enum fuer die Intervall-Varianten. | |
58 | */ | |
59 | private enum Interval | |
60 | { | |
61 | YEAR(Calendar.DAY_OF_YEAR,Calendar.YEAR,i18n.tr("Jahr")), | |
62 | MONTH(Calendar.DAY_OF_MONTH,Calendar.MONTH,i18n.tr("Monat")), | |
63 | WEEK(Calendar.DAY_OF_WEEK,Calendar.WEEK_OF_YEAR,i18n.tr("Woche")), | |
64 | ||
65 | ; | |
66 | ||
67 | private int type; | |
68 | private int size; | |
69 | private String name; | |
70 | ||
71 | /** | |
72 | * ct. | |
73 | * @param type | |
74 | * @param name | |
75 | */ | |
76 | private Interval(int type, int size, String name) | |
77 | { | |
78 | this.type = type; | |
79 | this.size = size; | |
80 | this.name = name; | |
81 | } | |
82 | ||
83 | /** | |
84 | * @see java.lang.Enum#toString() | |
85 | */ | |
86 | @Override | |
87 | public String toString() | |
88 | { | |
89 | return this.name; | |
90 | } | |
91 | } | |
46 | 92 | |
47 | 93 | /** |
48 | 94 | * Speichert die anzuzeigenden Daten. |
55 | 101 | this.data = data; |
56 | 102 | this.start = start; |
57 | 103 | this.stop = stop; |
58 | ||
59 | // Wenn das Start-Datum nicht angegeben ist, nehmen wir das | |
60 | // aktuelle Jahr | |
61 | if (this.start == null) | |
62 | { | |
63 | Calendar cal = Calendar.getInstance(); | |
64 | cal.set(Calendar.MONTH,Calendar.JANUARY); | |
65 | cal.set(Calendar.DATE,1); | |
66 | this.start = DateUtil.startOfDay(cal.getTime()); | |
67 | } | |
68 | if (this.stop == null || !this.stop.after(this.start)) | |
69 | this.stop = new Date(); // Wenn das Stop-Datum ungueltig ist, machen wir heute draus | |
70 | 104 | } |
71 | 105 | |
72 | 106 | /** |
85 | 119 | for (int i=0;i<this.data.size();++i) |
86 | 120 | { |
87 | 121 | UmsatzTreeNode group = (UmsatzTreeNode) this.data.get(i); |
88 | ChartDataUmsatz cd = new ChartDataUmsatz(group); | |
122 | ChartDataUmsatz cd = new ChartDataUmsatz(group, interval); | |
89 | 123 | if (cd.hasData) |
90 | 124 | { |
91 | 125 | this.chart.addData(cd); |
94 | 128 | } |
95 | 129 | |
96 | 130 | if (count <= 1) |
97 | this.chart.setTitle(i18n.tr("Bitte wählen Sie einen größeren Zeitraum (mindestens zwei Monate)")); | |
131 | this.chart.setTitle(i18n.tr("Bitte wählen Sie einen größeren Zeitraum")); | |
98 | 132 | else |
99 | this.chart.setTitle(i18n.tr("Umsätze der Kategorien im Verlauf (gruppiert nach Monat)")); | |
133 | this.chart.setTitle(i18n.tr("Umsätze der Kategorien im Verlauf (gruppiert nach {0})", this.interval.toString())); | |
100 | 134 | |
101 | 135 | this.chart.redraw(); |
102 | 136 | } |
110 | 144 | { |
111 | 145 | this.chart = new LineChart(); |
112 | 146 | this.chart.setStacked(false); // TODO Stacked Graph für "Umsätze nach Kategorieren" BUGZILLA 749 |
113 | this.chart.setTitle(i18n.tr("Umsätze der Kategorien im Verlauf (gruppiert nach Monat)")); | |
147 | this.chart.setTitle(i18n.tr("Umsätze der Kategorien im Verlauf (gruppiert nach {0})", this.interval.toString())); | |
114 | 148 | for (int i=0;i<this.data.size();++i) |
115 | 149 | { |
116 | 150 | UmsatzTreeNode group = (UmsatzTreeNode) this.data.get(i); |
117 | ChartDataUmsatz cd = new ChartDataUmsatz(group); | |
151 | ChartDataUmsatz cd = new ChartDataUmsatz(group, interval); | |
118 | 152 | if (cd.hasData) |
119 | 153 | this.chart.addData(cd); |
120 | 154 | } |
121 | 155 | this.chart.paint(parent); |
156 | addGroupingMenu(); | |
122 | 157 | } |
123 | 158 | catch (RemoteException re) |
124 | 159 | { |
128 | 163 | { |
129 | 164 | Logger.error("unable to create chart",e); |
130 | 165 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Fehler beim Erzeugen des Diagramms"),StatusBarMessage.TYPE_ERROR)); |
166 | } | |
167 | } | |
168 | ||
169 | /** | |
170 | * Erweitert das Contextmenu des Chart um einen Menupunkt "Gruppierung nach". | |
171 | */ | |
172 | private void addGroupingMenu() | |
173 | { | |
174 | Menu m = this.chart.getChart().getPlotArea().getMenu(); | |
175 | ||
176 | MenuItem groupMenuItem = new MenuItem(m, SWT.CASCADE, 0); | |
177 | groupMenuItem.setText(i18n.tr("Gruppierung nach")); | |
178 | ||
179 | new MenuItem(m,SWT.SEPARATOR,1); | |
180 | ||
181 | Menu groupMenu = new Menu(groupMenuItem); | |
182 | groupMenuItem.setMenu(groupMenu); | |
183 | ||
184 | final List<MenuItem> items = new ArrayList<MenuItem>(); | |
185 | SelectionListener l = new SelectionAdapter() | |
186 | { | |
187 | /** | |
188 | * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) | |
189 | */ | |
190 | @Override | |
191 | public void widgetSelected(SelectionEvent e) | |
192 | { | |
193 | MenuItem item = (MenuItem) e.getSource(); | |
194 | ||
195 | for (MenuItem i:items) | |
196 | { | |
197 | i.setSelection(i == item); | |
198 | } | |
199 | ||
200 | // aktuellen Wert uebernehmen | |
201 | interval = (Interval) item.getData(); | |
202 | ||
203 | // Und neu zeichnen | |
204 | try | |
205 | { | |
206 | redraw(); | |
207 | } | |
208 | catch (RemoteException re) | |
209 | { | |
210 | Logger.error("unable to redraw chart",re); | |
211 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Fehler beim Aktualisieren"), StatusBarMessage.TYPE_ERROR)); | |
212 | } | |
213 | } | |
214 | }; | |
215 | ||
216 | for (Interval i:Interval.values()) | |
217 | { | |
218 | final MenuItem item = new MenuItem(groupMenu, SWT.CHECK); | |
219 | item.setText(i.toString()); | |
220 | item.setSelection(this.interval == i); | |
221 | item.setData(i); | |
222 | item.addSelectionListener(l); | |
223 | items.add(item); | |
131 | 224 | } |
132 | 225 | } |
133 | 226 | |
139 | 232 | private UmsatzTreeNode group = null; |
140 | 233 | private List<Entry> entries = new ArrayList<Entry>(); |
141 | 234 | private boolean hasData = false; |
235 | private Date chartStartDate = null; | |
236 | private Date chartStopDate = null; | |
142 | 237 | |
143 | 238 | private List<Umsatz> getRecursiveUmsaetze(UmsatzTreeNode group) { |
144 | 239 | List<Umsatz> result = new ArrayList<Umsatz>(); |
152 | 247 | /** |
153 | 248 | * Erzeugt eine Liste mit den aggregierten Daten für eine Linie des Charts |
154 | 249 | * @param group |
250 | * @param interval das ausgewaehlte Intervall. | |
155 | 251 | * @throws RemoteException |
156 | 252 | */ |
157 | private ChartDataUmsatz(UmsatzTreeNode group) throws RemoteException | |
253 | private ChartDataUmsatz(UmsatzTreeNode group, final Interval interval) throws RemoteException | |
158 | 254 | { |
159 | 255 | HashMap<Date,Double> verteilung = new HashMap<Date, Double>(); |
160 | 256 | Calendar calendar = Calendar.getInstance(); |
161 | 257 | this.group = group; |
162 | 258 | this.entries.clear(); |
163 | 259 | |
164 | for (Umsatz umsatz: getRecursiveUmsaetze(group)) { | |
165 | if (umsatz.getDatum() == null) { | |
260 | for (Umsatz umsatz:getRecursiveUmsaetze(group)) | |
261 | { | |
262 | if (umsatz.getDatum() == null) | |
263 | { | |
166 | 264 | Logger.warn("no date found for umsatz, skipping record"); |
167 | 265 | continue; |
168 | 266 | } |
169 | 267 | this.hasData = true; |
170 | 268 | calendar.setTime(DateUtil.startOfDay(umsatz.getDatum())); |
171 | calendar.set(Calendar.DAY_OF_MONTH,1); | |
172 | double aggMonatsWert = verteilung.containsKey(calendar.getTime())?verteilung.get(calendar.getTime()):0; | |
173 | verteilung.put(calendar.getTime(), umsatz.getBetrag() + aggMonatsWert); | |
174 | } | |
175 | ||
176 | calendar.setTime(DateUtil.startOfDay(start)); | |
177 | calendar.set(Calendar.DAY_OF_MONTH, 1); | |
178 | Date monat = calendar.getTime(); | |
179 | ||
180 | // BUGZILLA 1604 - wir wollen im End-Datum kein oberes Jahr fest vorgeben. | |
181 | // Daher beenden wir hier die Iteration stattdessen nach maximal 1200 Monaten. | |
182 | // Das sind 100 Jahre. | |
183 | int limit = 0; | |
184 | while(monat.before(stop) && limit++ < 1200) { | |
185 | Entry aktuellerMonatswert = new Entry(); | |
186 | aktuellerMonatswert.monat = monat; | |
187 | if (verteilung.containsKey(monat)) { | |
188 | aktuellerMonatswert.betrag = verteilung.get(monat); | |
189 | } | |
190 | entries.add(aktuellerMonatswert); | |
191 | ||
192 | calendar.setTime(monat); | |
193 | calendar.add(Calendar.MONTH, 1); | |
194 | monat = calendar.getTime(); | |
195 | } | |
269 | calendar.set(interval.type, 1); | |
270 | ||
271 | Date key = calendar.getTime(); | |
272 | double aggMonatsWert = verteilung.containsKey(key) ? verteilung.get(key) : 0; | |
273 | verteilung.put(key, umsatz.getBetrag() + aggMonatsWert); | |
274 | } | |
275 | ||
276 | calculateChartInterval(verteilung.keySet()); | |
277 | ||
278 | calendar.setTime(DateUtil.startOfDay(chartStartDate)); | |
279 | calendar.set(interval.type, 1); | |
280 | Date next = calendar.getTime(); | |
281 | ||
282 | while(!next.after(chartStopDate)) | |
283 | { | |
284 | Entry aktuellerWert = new Entry(); | |
285 | aktuellerWert.monat = next; | |
286 | if (verteilung.containsKey(next)) | |
287 | aktuellerWert.betrag = verteilung.get(next); | |
288 | entries.add(aktuellerWert); | |
289 | ||
290 | calendar.setTime(next); | |
291 | calendar.add(interval.size, 1); | |
292 | next = calendar.getTime(); | |
293 | } | |
294 | ||
295 | //Dummy-Eintrag für das nächste Intervall, da das letzte reguläre sonst | |
296 | //aufgrund der Normalisierung auf den ersten Tag des Intervalls | |
297 | //ggf. gar nicht angezeigt wird | |
298 | Entry lastEntry = new Entry(); | |
299 | lastEntry.monat = next; | |
300 | entries.add(lastEntry); | |
301 | } | |
302 | ||
303 | /** | |
304 | * Ermittelt das Minimum und Maximum aus dem Set von Datumswerten. | |
305 | * @param chartDates das Set der Datumswerte. | |
306 | */ | |
307 | private void calculateChartInterval(Set<Date> chartDates) | |
308 | { | |
309 | Date min = new Date(); | |
310 | Date max = new Date(); | |
311 | ||
312 | if (!chartDates.isEmpty()) | |
313 | { | |
314 | min = Collections.min(chartDates); | |
315 | max = Collections.max(chartDates); | |
316 | } | |
317 | ||
318 | // Wenn ein explizites Start-Datum angegeben ist und es sich hinter | |
319 | // dem ermittelten befindet, nehmen wir das explizit angegebene | |
320 | this.chartStartDate = (start != null && start.after(min)) ? start : min; | |
321 | ||
322 | // Wenn ein explizites Stop-Datum angegeben ist und es sich vor | |
323 | // dem ermittelten befindet, nehmen wir das explizit angegebene | |
324 | this.chartStopDate = (stop != null && stop.before(max)) ? start : max; | |
196 | 325 | } |
197 | 326 | |
198 | 327 | /** |
13 | 13 | |
14 | 14 | import de.willuhn.jameica.gui.AbstractView; |
15 | 15 | import de.willuhn.jameica.gui.GUI; |
16 | import de.willuhn.jameica.gui.input.MultiInput; | |
16 | 17 | import de.willuhn.jameica.gui.util.ColumnLayout; |
17 | 18 | import de.willuhn.jameica.gui.util.SimpleContainer; |
18 | 19 | import de.willuhn.jameica.hbci.HBCI; |
78 | 79 | right.addHeadline(i18n.tr("Sonstige Informationen")); |
79 | 80 | right.addLabelPair(i18n.tr("Art der Buchung"), control.getArt()); |
80 | 81 | right.addLabelPair(i18n.tr("Kundenreferenz"), control.getCustomerRef()); |
81 | right.addLabelPair(i18n.tr("Primanota-Kennzeichen"), control.getPrimanota()); | |
82 | right.addLabelPair(i18n.tr("Geschäftsvorfall-Code"), control.getGvCode()); | |
82 | right.addInput(control.getEndToEndId()); | |
83 | right.addLabelPair(i18n.tr("Primanota/GV-Code"),new MultiInput(control.getPrimanota(),control.getGvCode())); | |
83 | 84 | |
84 | 85 | right.addHeadline(i18n.tr("Notizen")); |
85 | 86 | right.addPart(control.getKommentar()); |
28 | 28 | import de.willuhn.jameica.hbci.HBCI; |
29 | 29 | import de.willuhn.jameica.hbci.gui.action.EinnahmeAusgabeExport; |
30 | 30 | import de.willuhn.jameica.hbci.gui.controller.EinnahmeAusgabeControl; |
31 | import de.willuhn.jameica.hbci.server.EinnahmeAusgabe; | |
31 | import de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum; | |
32 | 32 | import de.willuhn.jameica.messaging.StatusBarMessage; |
33 | 33 | import de.willuhn.jameica.system.Application; |
34 | 34 | import de.willuhn.logging.Logger; |
60 | 60 | |
61 | 61 | Container left = new SimpleContainer(cols.getComposite()); |
62 | 62 | left.addInput(control.getKontoAuswahl()); |
63 | left.addInput(control.getInterval()); | |
63 | 64 | |
64 | 65 | Container right = new SimpleContainer(cols.getComposite()); |
65 | 66 | |
76 | 77 | { |
77 | 78 | try |
78 | 79 | { |
79 | List data = control.getTable().getItems(); | |
80 | new EinnahmeAusgabeExport().handleAction(data.toArray(new EinnahmeAusgabe[data.size()])); | |
80 | List data = control.getTree().getItems(); | |
81 | new EinnahmeAusgabeExport().handleAction(data.toArray(new EinnahmeAusgabeZeitraum[data.size()])); | |
81 | 82 | } |
82 | 83 | catch (RemoteException re) |
83 | 84 | { |
99 | 100 | },null,true,"view-refresh.png"); |
100 | 101 | buttons.paint(getParent()); |
101 | 102 | |
102 | control.getTable().paint(this.getParent()); | |
103 | control.getTree().paint(this.getParent()); | |
103 | 104 | } |
104 | 105 | } |
10 | 10 | |
11 | 11 | import de.willuhn.jameica.gui.AbstractView; |
12 | 12 | import de.willuhn.jameica.gui.GUI; |
13 | import de.willuhn.jameica.gui.parts.ButtonArea; | |
14 | 13 | import de.willuhn.jameica.hbci.HBCI; |
15 | import de.willuhn.jameica.hbci.gui.action.EmpfaengerNew; | |
16 | 14 | import de.willuhn.jameica.hbci.gui.controller.EmpfaengerControl; |
17 | 15 | import de.willuhn.jameica.system.Application; |
18 | 16 | import de.willuhn.util.I18N; |
34 | 32 | EmpfaengerControl control = new EmpfaengerControl(this); |
35 | 33 | |
36 | 34 | control.getEmpfaengerListe().paint(getParent()); |
37 | ||
38 | ButtonArea buttons = new ButtonArea(); | |
39 | buttons.addButton(i18n.tr("Neue Adresse"),new EmpfaengerNew(),null,true,"contact-new.png"); | |
40 | buttons.paint(getParent()); | |
41 | 35 | } |
42 | 36 | } |
43 | ||
44 | ||
45 | /********************************************************************** | |
46 | * $Log: EmpfaengerList.java,v $ | |
47 | * Revision 1.9 2011/04/08 15:19:13 willuhn | |
48 | * @R Alle Zurueck-Buttons entfernt - es gibt jetzt einen globalen Zurueck-Button oben rechts | |
49 | * @C Code-Cleanup | |
50 | * | |
51 | **********************************************************************/⏎ |
9 | 9 | package de.willuhn.jameica.hbci.gui.views; |
10 | 10 | |
11 | 11 | import de.willuhn.jameica.gui.AbstractView; |
12 | import de.willuhn.jameica.gui.Action; | |
13 | 12 | import de.willuhn.jameica.gui.GUI; |
14 | import de.willuhn.jameica.gui.parts.ButtonArea; | |
15 | 13 | import de.willuhn.jameica.hbci.HBCI; |
16 | import de.willuhn.jameica.hbci.gui.action.KontoNew; | |
17 | 14 | import de.willuhn.jameica.hbci.gui.controller.KontoControl; |
18 | 15 | import de.willuhn.jameica.system.Application; |
19 | import de.willuhn.util.ApplicationException; | |
20 | 16 | import de.willuhn.util.I18N; |
21 | 17 | |
22 | 18 | /** |
34 | 30 | { |
35 | 31 | |
36 | 32 | final KontoControl control = new KontoControl(this); |
37 | GUI.getView().setTitle(i18n.tr("Vorhandene Bankverbindungen")); | |
33 | GUI.getView().setTitle(i18n.tr("Vorhandene Konten")); | |
38 | 34 | |
39 | 35 | control.getKontoListe().paint(getParent()); |
40 | ||
41 | ButtonArea buttons = new ButtonArea(); | |
42 | buttons.addButton(i18n.tr("Konten über den Bank-Zugang importieren..."), new Action() { | |
43 | public void handleAction(Object context) throws ApplicationException | |
44 | { | |
45 | control.handleReadFromPassport(); | |
46 | } | |
47 | },null,false,"mail-send-receive.png"); | |
48 | buttons.addButton(i18n.tr("Konto manuell anlegen"),new KontoNew(),null,false,"list-add.png"); | |
49 | buttons.paint(getParent()); | |
50 | 36 | } |
51 | 37 | } |
14 | 14 | import org.eclipse.swt.widgets.Listener; |
15 | 15 | |
16 | 16 | import de.willuhn.jameica.gui.AbstractView; |
17 | import de.willuhn.jameica.gui.Action; | |
17 | 18 | import de.willuhn.jameica.gui.GUI; |
18 | 19 | import de.willuhn.jameica.gui.internal.parts.PanelButtonPrint; |
20 | import de.willuhn.jameica.gui.parts.PanelButton; | |
19 | 21 | import de.willuhn.jameica.hbci.HBCI; |
22 | import de.willuhn.jameica.hbci.gui.action.KontoauszugSettings; | |
20 | 23 | import de.willuhn.jameica.hbci.io.print.PrintSupportUmsatzList; |
21 | 24 | import de.willuhn.jameica.hbci.rmi.Konto; |
22 | 25 | import de.willuhn.jameica.system.Application; |
26 | import de.willuhn.jameica.system.OperationCanceledException; | |
27 | import de.willuhn.util.ApplicationException; | |
23 | 28 | import de.willuhn.util.I18N; |
24 | 29 | |
25 | 30 | /** |
50 | 55 | print.setEnabled(list.getSelection() != null); |
51 | 56 | } |
52 | 57 | }); |
53 | ||
58 | ||
59 | final PanelButton settings = new PanelButton("document-properties.png",new Action() { | |
60 | @Override | |
61 | public void handleAction(Object context) throws ApplicationException | |
62 | { | |
63 | try | |
64 | { | |
65 | new KontoauszugSettings().handleAction(null); | |
66 | // Ein einfaches Reload reicht nicht, da die Spalten ggf. geaendert wurden | |
67 | GUI.startView(GUI.getCurrentView(),getCurrentObject()); | |
68 | } | |
69 | catch (OperationCanceledException oce) | |
70 | { | |
71 | // ignore | |
72 | } | |
73 | } | |
74 | },i18n.tr("Einstellungen")); | |
75 | ||
76 | GUI.getView().addPanelButton(settings); | |
54 | 77 | GUI.getView().addPanelButton(print); |
55 | 78 | |
56 | 79 | list.paint(getParent()); |
10 | 10 | package de.willuhn.jameica.hbci.gui.views; |
11 | 11 | |
12 | 12 | import de.willuhn.jameica.gui.AbstractView; |
13 | import de.willuhn.jameica.gui.Action; | |
13 | 14 | import de.willuhn.jameica.gui.GUI; |
15 | import de.willuhn.jameica.gui.parts.PanelButton; | |
14 | 16 | import de.willuhn.jameica.hbci.HBCI; |
15 | 17 | import de.willuhn.jameica.hbci.gui.controller.KontoauszugPdfControl; |
16 | 18 | import de.willuhn.jameica.system.Application; |
19 | import de.willuhn.util.ApplicationException; | |
17 | 20 | import de.willuhn.util.I18N; |
18 | 21 | |
19 | 22 | /** |
33 | 36 | |
34 | 37 | final KontoauszugPdfControl control = new KontoauszugPdfControl(this); |
35 | 38 | final de.willuhn.jameica.hbci.gui.parts.KontoauszugPdfList list = control.getList(); |
39 | ||
36 | 40 | |
37 | 41 | list.paint(getParent()); |
42 | ||
43 | PanelButton button = new PanelButton("document-properties.png",new Action() { | |
44 | @Override | |
45 | public void handleAction(Object context) throws ApplicationException | |
46 | { | |
47 | list.handleSettings(); | |
48 | } | |
49 | },i18n.tr("Einstellungen")); | |
50 | GUI.getView().addPanelButton(button); | |
51 | ||
38 | 52 | } |
39 | 53 | |
40 | 54 | } |
11 | 11 | import de.willuhn.jameica.gui.AbstractView; |
12 | 12 | import de.willuhn.jameica.gui.GUI; |
13 | 13 | import de.willuhn.jameica.gui.parts.ButtonArea; |
14 | import de.willuhn.jameica.gui.util.ScrolledContainer; | |
14 | 15 | import de.willuhn.jameica.gui.util.SimpleContainer; |
15 | 16 | import de.willuhn.jameica.hbci.HBCI; |
16 | 17 | import de.willuhn.jameica.hbci.HBCIProperties; |
39 | 40 | |
40 | 41 | GUI.getView().setTitle(i18n.tr("System-Nachricht vom {0}", HBCI.DATEFORMAT.format(n.getDatum()))); |
41 | 42 | |
42 | SimpleContainer container = new SimpleContainer(getParent()); | |
43 | container.addText(i18n.tr("{0} [BLZ: {1}]", new String[] {HBCIProperties.getNameForBank(n.getBLZ()),n.getBLZ()}) + "\n",true); | |
44 | container.addText(n.getNachricht(),true); | |
43 | SimpleContainer container = new SimpleContainer(getParent(),true); | |
44 | String name = HBCIProperties.getNameForBank(n.getBLZ()); | |
45 | if (name != null) | |
46 | container.addText(i18n.tr("{0} [BLZ: {1}]", new String[] {name,n.getBLZ()}) + "\n",true); | |
47 | else | |
48 | container.addText(i18n.tr("BLZ: {0}", new String[] {n.getBLZ()}) + "\n",true); | |
49 | ||
50 | ScrolledContainer sc = new ScrolledContainer(container.getComposite()); | |
51 | String msg = n.getNachricht(); | |
52 | msg = msg.replace("\\n","\n"); // Falls die Zeilenumbrueche escaped waren | |
53 | sc.addText(msg,true); | |
45 | 54 | |
46 | 55 | ButtonArea buttons = new ButtonArea(); |
47 | 56 | buttons.addButton(i18n.tr("In Zwischenablage kopieren"),new NachrichtCopy(),n,false,"edit-copy.png"); |
49 | 58 | buttons.paint(getParent()); |
50 | 59 | } |
51 | 60 | } |
52 | ||
53 | ||
54 | /********************************************************************** | |
55 | * $Log: NachrichtDetails.java,v $ | |
56 | * Revision 1.2 2011/04/08 15:19:14 willuhn | |
57 | * @R Alle Zurueck-Buttons entfernt - es gibt jetzt einen globalen Zurueck-Button oben rechts | |
58 | * @C Code-Cleanup | |
59 | * | |
60 | * Revision 1.1 2009/07/17 08:42:57 willuhn | |
61 | * @N Detail-Ansicht fuer Systemnachrichten der Bank | |
62 | * @N Systemnachrichten in Zwischenablage kopieren | |
63 | * | |
64 | **********************************************************************/⏎ |
53 | 53 | |
54 | 54 | // Grund-Einstellungen |
55 | 55 | TabGroup system = new TabGroup(getTabFolder(),i18n.tr("Grundeinstellungen")); |
56 | system.addCheckbox(control.getOnlineMode(),i18n.tr("Dauerhafte Internetverbindung, Aufforderung zum Verbinden nicht erforderlich")); | |
57 | 56 | system.addCheckbox(control.getCachePin(),i18n.tr("PIN-Eingaben für die aktuelle Sitzung zwischenspeichern")); |
58 | 57 | system.addCheckbox(control.getStorePin(),i18n.tr("PIN-Eingaben permanent speichern (nur bei PIN/TAN)")); |
59 | system.addCheckbox(control.getDecimalGrouping(),i18n.tr("Tausender-Trennzeichen bei Geld-Beträgen anzeigen")); | |
60 | 58 | system.addCheckbox(control.getKontoCheck(),i18n.tr("Kontonummern und Bankleitzahlen mittels Prüfsumme testen")); |
61 | 59 | system.addCheckbox(control.getKontoCheckExcludeAddressbook(),i18n.tr("Aufler Bankverbindungen des Adressbuches")); |
62 | 60 | system.addLabelPair(i18n.tr("Limit für Aufträge"), control.getUeberweisungLimit()); |
63 | 61 | |
64 | 62 | // Farb-Einstellungen |
65 | TabGroup colors = new TabGroup(getTabFolder(),i18n.tr("Farben")); | |
66 | colors.addLabelPair(i18n.tr("Textfarbe von Sollbuchungen"),control.getBuchungSollForeground()); | |
67 | colors.addLabelPair(i18n.tr("Textfarbe von Habenbuchungen"),control.getBuchungHabenForeground()); | |
63 | TabGroup ui = new TabGroup(getTabFolder(),i18n.tr("Benutzeroberfläche")); | |
64 | ui.addLabelPair(i18n.tr("Textfarbe von Sollbuchungen"),control.getBuchungSollForeground()); | |
65 | ui.addLabelPair(i18n.tr("Textfarbe von Habenbuchungen"),control.getBuchungHabenForeground()); | |
66 | ui.addCheckbox(control.getDecimalGrouping(),i18n.tr("Tausender-Trennzeichen bei Geld-Beträgen anzeigen")); | |
68 | 67 | |
69 | 68 | // Umsatz-Kategorien |
70 | 69 | TabGroup umsatztypes = new TabGroup(getTabFolder(),i18n.tr("Umsatz-Kategorien")); |
20 | 20 | import org.apache.commons.lang.StringUtils; |
21 | 21 | import org.kapott.hbci.GV.generators.ISEPAGenerator; |
22 | 22 | import org.kapott.hbci.GV.generators.SEPAGeneratorFactory; |
23 | import org.kapott.hbci.sepa.PainVersion; | |
24 | import org.kapott.hbci.sepa.PainVersion.Type; | |
23 | import org.kapott.hbci.sepa.SepaVersion; | |
24 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
25 | 25 | |
26 | 26 | import de.willuhn.jameica.hbci.gui.dialogs.KontoAuswahlDialog; |
27 | 27 | import de.willuhn.jameica.hbci.gui.dialogs.PainVersionDialog; |
106 | 106 | |
107 | 107 | // User nach der SEPA-Version fragen, die verwendet werden soll. |
108 | 108 | PainVersionDialog d = new PainVersionDialog(this.getPainType()); |
109 | PainVersion version = (PainVersion) d.open(); | |
109 | SepaVersion version = (SepaVersion) d.open(); | |
110 | 110 | ctx.version = version; |
111 | 111 | |
112 | 112 | // Header-Infos zuweisen |
196 | 196 | */ |
197 | 197 | protected class JobContext |
198 | 198 | { |
199 | protected PainVersion version = null; | |
199 | protected SepaVersion version = null; | |
200 | 200 | protected Properties props = new Properties(); |
201 | 201 | protected Map meta = new HashMap(); |
202 | 202 |
21 | 21 | |
22 | 22 | import org.kapott.hbci.GV.parsers.ISEPAParser; |
23 | 23 | import org.kapott.hbci.GV.parsers.SEPAParserFactory; |
24 | import org.kapott.hbci.sepa.PainVersion; | |
24 | import org.kapott.hbci.sepa.SepaVersion; | |
25 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
25 | 26 | |
26 | 27 | import de.willuhn.io.IOUtil; |
27 | 28 | import de.willuhn.jameica.hbci.gui.dialogs.KontoAuswahlDialog; |
69 | 70 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
70 | 71 | IOUtil.copy(is,bos); |
71 | 72 | |
72 | PainVersion version = PainVersion.autodetect(new ByteArrayInputStream(bos.toByteArray())); | |
73 | SepaVersion version = SepaVersion.autodetect(new ByteArrayInputStream(bos.toByteArray())); | |
73 | 74 | if (version == null) |
74 | 75 | throw new ApplicationException(i18n.tr("SEPA-Version der XML-Datei nicht ermittelbar")); |
75 | 76 | |
76 | 77 | monitor.log(i18n.tr("SEPA-Version: {0}",version.getURN())); |
77 | 78 | |
78 | 79 | // PAIN-Typ nicht kompatibel. User fragen, ob er trotzdem importieren moechte |
79 | PainVersion.Type type = this.getSupportedPainType(); | |
80 | SepaVersion.Type type = this.getSupportedPainType(); | |
80 | 81 | if (type != null && type != version.getType()) |
81 | 82 | { |
82 | 83 | String l = i18n.tr("Lastschrift"); |
83 | 84 | String u = i18n.tr("Überweisung"); |
84 | 85 | String q = i18n.tr("Sie versuchen, eine {0} als {1} zu importieren.\nVorgang wirklich fortsetzen?"); |
85 | boolean b = type == PainVersion.Type.PAIN_001; | |
86 | boolean b = type == SepaVersion.Type.PAIN_001; | |
86 | 87 | if (!Application.getCallback().askUser(q,new String[]{b ? l : u, b ? u : l})) |
87 | 88 | throw new OperationCanceledException(); |
88 | 89 | } |
183 | 184 | * Wird benötigt, damit eine Lastschrift nicht versehentlich als Überweisung importiert wird. |
184 | 185 | * @return erlaubter SEPA PAIN-Typ. |
185 | 186 | */ |
186 | abstract PainVersion.Type getSupportedPainType(); | |
187 | abstract Type getSupportedPainType(); | |
187 | 188 | |
188 | 189 | } |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2004 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.io; | |
11 | ||
12 | import java.io.ByteArrayInputStream; | |
13 | import java.io.ByteArrayOutputStream; | |
14 | import java.io.InputStream; | |
15 | import java.rmi.RemoteException; | |
16 | import java.util.ArrayList; | |
17 | import java.util.List; | |
18 | ||
19 | import org.kapott.hbci.GV.parsers.ISEPAParser; | |
20 | import org.kapott.hbci.GV.parsers.SEPAParserFactory; | |
21 | import org.kapott.hbci.GV_Result.GVRKUms; | |
22 | import org.kapott.hbci.GV_Result.GVRKUms.BTag; | |
23 | import org.kapott.hbci.GV_Result.GVRKUms.UmsLine; | |
24 | import org.kapott.hbci.sepa.SepaVersion; | |
25 | ||
26 | import de.willuhn.io.IOUtil; | |
27 | import de.willuhn.jameica.hbci.HBCI; | |
28 | import de.willuhn.jameica.hbci.gui.dialogs.KontoAuswahlDialog; | |
29 | import de.willuhn.jameica.hbci.messaging.ImportMessage; | |
30 | import de.willuhn.jameica.hbci.rmi.Protokoll; | |
31 | import de.willuhn.jameica.hbci.rmi.Umsatz; | |
32 | import de.willuhn.jameica.hbci.server.Converter; | |
33 | import de.willuhn.jameica.system.Application; | |
34 | import de.willuhn.jameica.system.BackgroundTask; | |
35 | import de.willuhn.jameica.system.OperationCanceledException; | |
36 | import de.willuhn.logging.Logger; | |
37 | import de.willuhn.util.ApplicationException; | |
38 | import de.willuhn.util.I18N; | |
39 | import de.willuhn.util.ProgressMonitor; | |
40 | ||
41 | /** | |
42 | * Importer fuer Umsaetze im CAMT-Format. | |
43 | */ | |
44 | public class CamtUmsatzImporter implements Importer | |
45 | { | |
46 | ||
47 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
48 | ||
49 | /** | |
50 | * @see de.willuhn.jameica.hbci.io.Importer#doImport(java.lang.Object, de.willuhn.jameica.hbci.io.IOFormat, java.io.InputStream, de.willuhn.util.ProgressMonitor, de.willuhn.jameica.system.BackgroundTask) | |
51 | */ | |
52 | public void doImport(Object context, IOFormat format, InputStream is, ProgressMonitor monitor, BackgroundTask t) throws RemoteException, ApplicationException | |
53 | { | |
54 | ||
55 | if (is == null) | |
56 | throw new ApplicationException(i18n.tr("Keine zu importierende Datei ausgewählt")); | |
57 | ||
58 | if (format == null) | |
59 | throw new ApplicationException(i18n.tr("Kein Datei-Format ausgewählt")); | |
60 | ||
61 | try | |
62 | { | |
63 | ||
64 | de.willuhn.jameica.hbci.rmi.Konto konto = null; | |
65 | ||
66 | if (context != null && context instanceof de.willuhn.jameica.hbci.rmi.Konto) | |
67 | konto = (de.willuhn.jameica.hbci.rmi.Konto) context; | |
68 | ||
69 | if (konto == null) | |
70 | { | |
71 | KontoAuswahlDialog d = new KontoAuswahlDialog(KontoAuswahlDialog.POSITION_CENTER); | |
72 | d.setText(i18n.tr("Bitte wählen Sie das zu verwendende Konto aus.")); | |
73 | konto = (de.willuhn.jameica.hbci.rmi.Konto) d.open(); | |
74 | } | |
75 | ||
76 | if (monitor != null) | |
77 | monitor.setStatusText(i18n.tr("Lese Datei ein")); | |
78 | ||
79 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |
80 | IOUtil.copy(is,bos); | |
81 | ||
82 | SepaVersion version = SepaVersion.autodetect(new ByteArrayInputStream(bos.toByteArray())); | |
83 | if (version == null) | |
84 | throw new ApplicationException(i18n.tr("SEPA-Version der XML-Datei nicht ermittelbar")); | |
85 | ||
86 | SepaVersion.Type type = version.getType(); | |
87 | if (type == null || type != SepaVersion.Type.CAMT_052) | |
88 | throw new ApplicationException(i18n.tr("Keine gültige CAMT-Datei")); | |
89 | ||
90 | monitor.log(i18n.tr("SEPA-Version: {0}",version.getURN())); | |
91 | ||
92 | List<BTag> tage = new ArrayList<BTag>(); | |
93 | ISEPAParser<List<BTag>> parser = SEPAParserFactory.get(version); | |
94 | parser.parse(new ByteArrayInputStream(bos.toByteArray()),tage); | |
95 | ||
96 | List<UmsLine> lines = new ArrayList<UmsLine>(); | |
97 | for (BTag tag:tage) | |
98 | { | |
99 | lines.addAll(tag.lines); | |
100 | } | |
101 | ||
102 | if (lines.size() == 0) | |
103 | { | |
104 | konto.addToProtokoll(i18n.tr("Keine Umsätze importiert"),Protokoll.TYP_ERROR); | |
105 | return; | |
106 | } | |
107 | ||
108 | double factor = 100d / (double) lines.size(); | |
109 | ||
110 | int created = 0; | |
111 | int error = 0; | |
112 | ||
113 | for (int i=0;i<lines.size();++i) | |
114 | { | |
115 | if (monitor != null) | |
116 | { | |
117 | monitor.log(i18n.tr("Umsatz {0}", "" + (i+1))); | |
118 | // Mit diesem Factor sollte sich der Fortschrittsbalken | |
119 | // bis zum Ende der Swift-MT940-Datei genau auf 100% bewegen | |
120 | monitor.setPercentComplete((int)((i+1) * factor)); | |
121 | } | |
122 | ||
123 | try | |
124 | { | |
125 | if (t != null && t.isInterrupted()) | |
126 | throw new OperationCanceledException(); | |
127 | ||
128 | final Umsatz umsatz = Converter.HBCIUmsatz2HibiscusUmsatz((GVRKUms.UmsLine)lines.get(i)); | |
129 | umsatz.setKonto(konto); // muessen wir noch machen, weil der Converter das Konto nicht kennt | |
130 | umsatz.store(); | |
131 | created++; | |
132 | try | |
133 | { | |
134 | Application.getMessagingFactory().sendMessage(new ImportMessage(umsatz)); | |
135 | } | |
136 | catch (Exception ex) | |
137 | { | |
138 | Logger.error("error while sending import message",ex); | |
139 | } | |
140 | } | |
141 | catch (ApplicationException ae) | |
142 | { | |
143 | monitor.log(" " + ae.getMessage()); | |
144 | error++; | |
145 | } | |
146 | catch (Exception e) | |
147 | { | |
148 | Logger.error("unable to import line",e); | |
149 | monitor.log(" " + i18n.tr("Fehler beim Import des Datensatzes: {0}",e.getMessage())); | |
150 | error++; | |
151 | } | |
152 | } | |
153 | monitor.setStatusText(i18n.tr("{0} Umsätze erfolgreich importiert, {1} fehlerhafte übersprungen", new String[]{""+created,""+error})); | |
154 | monitor.addPercentComplete(1); | |
155 | } | |
156 | catch (OperationCanceledException oce) | |
157 | { | |
158 | Logger.warn("operation cancelled"); | |
159 | throw new ApplicationException(i18n.tr("Import abgebrochen")); | |
160 | } | |
161 | catch (ApplicationException ae) | |
162 | { | |
163 | throw ae; | |
164 | } | |
165 | catch (Exception e) | |
166 | { | |
167 | Logger.error("error while reading file",e); | |
168 | throw new ApplicationException(i18n.tr("Fehler beim Import der Datei")); | |
169 | } | |
170 | finally | |
171 | { | |
172 | IOUtil.close(is); | |
173 | } | |
174 | } | |
175 | ||
176 | /** | |
177 | * @see de.willuhn.jameica.hbci.io.IO#getName() | |
178 | */ | |
179 | public String getName() | |
180 | { | |
181 | return i18n.tr("SEPA CAMT-Format (XML)"); | |
182 | } | |
183 | ||
184 | /** | |
185 | * @see de.willuhn.jameica.hbci.io.IO#getIOFormats(java.lang.Class) | |
186 | */ | |
187 | public IOFormat[] getIOFormats(Class objectType) | |
188 | { | |
189 | if (!Umsatz.class.equals(objectType)) | |
190 | return null; // Wir bieten uns nur fuer Umsaetze an | |
191 | ||
192 | IOFormat f = new IOFormat() { | |
193 | public String getName() | |
194 | { | |
195 | return CamtUmsatzImporter.this.getName(); | |
196 | } | |
197 | ||
198 | /** | |
199 | * @see de.willuhn.jameica.hbci.io.IOFormat#getFileExtensions() | |
200 | */ | |
201 | public String[] getFileExtensions() | |
202 | { | |
203 | return new String[] {"*.xml"}; | |
204 | } | |
205 | }; | |
206 | return new IOFormat[] { f }; | |
207 | } | |
208 | } |
11 | 11 | |
12 | 12 | import java.io.OutputStream; |
13 | 13 | import java.rmi.RemoteException; |
14 | import java.util.Date; | |
14 | 15 | |
15 | 16 | import com.itextpdf.text.BaseColor; |
16 | 17 | import com.itextpdf.text.DocumentException; |
17 | 18 | import com.itextpdf.text.Element; |
18 | ||
19 | import com.itextpdf.text.Font; | |
20 | import com.itextpdf.text.pdf.PdfPCell; | |
21 | ||
22 | import de.willuhn.datasource.GenericIterator; | |
23 | import de.willuhn.datasource.GenericObject; | |
19 | 24 | import de.willuhn.jameica.hbci.HBCI; |
25 | import de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum; | |
20 | 26 | import de.willuhn.jameica.hbci.server.EinnahmeAusgabe; |
27 | import de.willuhn.jameica.hbci.server.EinnahmeAusgabeTreeNode; | |
21 | 28 | import de.willuhn.jameica.system.Application; |
22 | 29 | import de.willuhn.logging.Logger; |
23 | 30 | import de.willuhn.util.ApplicationException; |
36 | 43 | */ |
37 | 44 | public void doExport(Object[] objects, IOFormat format, OutputStream os, ProgressMonitor monitor) throws RemoteException, ApplicationException |
38 | 45 | { |
39 | if (objects == null || !(objects instanceof EinnahmeAusgabe[])) | |
46 | if (objects == null || !(objects instanceof EinnahmeAusgabeZeitraum[])) | |
40 | 47 | throw new ApplicationException(i18n.tr("Bitte wählen Sie die zu exportierenden Daten aus")); |
41 | 48 | |
42 | EinnahmeAusgabe[] ea = (EinnahmeAusgabe[]) objects; | |
43 | if (ea.length == 0) | |
49 | if (objects.length == 0) | |
44 | 50 | throw new ApplicationException(i18n.tr("Bitte wählen Sie die zu exportierenden Daten aus")); |
45 | 51 | |
52 | EinnahmeAusgabeZeitraum[] data = (EinnahmeAusgabeZeitraum[]) objects; | |
46 | 53 | Reporter reporter = null; |
47 | 54 | |
48 | 55 | try |
49 | 56 | { |
50 | String sub = ""; | |
51 | ||
52 | if (ea[0].getStartdatum() != null && ea[0].getEnddatum() != null) | |
53 | sub = i18n.tr("Zeitraum {0} - {1}", new String[]{HBCI.DATEFORMAT.format(ea[0].getStartdatum()),HBCI.DATEFORMAT.format(ea[0].getEnddatum())}); | |
54 | ||
55 | reporter = new Reporter(os, monitor, i18n.tr("Einnahmen/Ausgaben"), sub,ea.length); | |
57 | reporter = new Reporter(os, monitor, i18n.tr("Einnahmen/Ausgaben"), getZeitraum(data), data.length); | |
56 | 58 | reporter.addHeaderColumn(i18n.tr("Konto"), Element.ALIGN_CENTER, 100, BaseColor.LIGHT_GRAY); |
57 | 59 | reporter.addHeaderColumn(i18n.tr("Anfangssaldo"), Element.ALIGN_CENTER, 60, BaseColor.LIGHT_GRAY); |
58 | 60 | reporter.addHeaderColumn(i18n.tr("Einnahmen"), Element.ALIGN_CENTER, 60, BaseColor.LIGHT_GRAY); |
62 | 64 | reporter.addHeaderColumn(i18n.tr("Differenz"), Element.ALIGN_CENTER, 60, BaseColor.LIGHT_GRAY); |
63 | 65 | reporter.createHeader(); |
64 | 66 | |
65 | // Iteration ueber Umsaetze | |
66 | for (int i=0;i<ea.length; ++i) | |
67 | { | |
68 | reporter.addColumn(reporter.getDetailCell(ea[i].getText(), Element.ALIGN_LEFT)); | |
69 | reporter.addColumn(reporter.getDetailCell(ea[i].getAnfangssaldo())); | |
70 | reporter.addColumn(reporter.getDetailCell(ea[i].getEinnahmen())); | |
71 | reporter.addColumn(reporter.getDetailCell(ea[i].getAusgaben())); | |
72 | reporter.addColumn(reporter.getDetailCell(ea[i].getEndsaldo())); | |
73 | reporter.addColumn(reporter.getDetailCell(ea[i].getPlusminus())); | |
74 | reporter.addColumn(reporter.getDetailCell(ea[i].getDifferenz())); | |
75 | reporter.setNextRecord(); | |
76 | } | |
67 | for (EinnahmeAusgabeZeitraum e:data) | |
68 | { | |
69 | if (e instanceof EinnahmeAusgabeTreeNode) | |
70 | report((EinnahmeAusgabeTreeNode)e, reporter); | |
71 | else | |
72 | report((EinnahmeAusgabe)e, reporter, 0); | |
73 | } | |
74 | ||
77 | 75 | if (monitor != null) |
78 | 76 | monitor.setStatus(ProgressMonitor.STATUS_DONE); |
79 | 77 | } |
100 | 98 | } |
101 | 99 | } |
102 | 100 | } |
101 | ||
102 | /** | |
103 | * Liefert einen Text mit dem Zeitraum. | |
104 | * @param objects die zu exportierenden Daten. | |
105 | * @return der Text mit dem Zeitraum. | |
106 | */ | |
107 | private String getZeitraum(EinnahmeAusgabeZeitraum[] objects) | |
108 | { | |
109 | Date start = null; | |
110 | Date end = null; | |
111 | ||
112 | for (EinnahmeAusgabeZeitraum n:objects) | |
113 | { | |
114 | Date s = n.getStartdatum(); | |
115 | if (start == null || (s != null && s.before(start))) | |
116 | start = s; | |
117 | ||
118 | Date e = n.getEnddatum(); | |
119 | if (end == null || (e != null && e.after(end))) | |
120 | end = e; | |
121 | } | |
122 | ||
123 | if (start != null && end != null) | |
124 | return i18n.tr("Zeitraum {0} - {1}", new String[]{HBCI.DATEFORMAT.format(start),HBCI.DATEFORMAT.format(end)}); | |
125 | ||
126 | return ""; | |
127 | } | |
128 | ||
129 | /** | |
130 | * Erzeugt die Report-Zeilen fuer den Knoten. | |
131 | * @param treeNode der Knoten. | |
132 | * @param reporter der Reporter. | |
133 | * @throws RemoteException | |
134 | */ | |
135 | private void report(EinnahmeAusgabeTreeNode treeNode, Reporter reporter) throws RemoteException | |
136 | { | |
137 | String range = HBCI.DATEFORMAT.format(treeNode.getStartdatum()) + " - " + HBCI.DATEFORMAT.format(treeNode.getEnddatum()); | |
138 | PdfPCell cell = reporter.getDetailCell(range, Element.ALIGN_LEFT, null, null, Font.BOLD); | |
139 | cell.setColspan(7); | |
140 | reporter.addColumn(cell); | |
141 | reporter.setNextRecord(); | |
142 | GenericIterator eas = treeNode.getChildren(); | |
143 | while(eas.hasNext()) | |
144 | { | |
145 | GenericObject ea = eas.next(); | |
146 | report((EinnahmeAusgabe)ea, reporter,5); | |
147 | } | |
148 | } | |
149 | ||
150 | /** | |
151 | * Erzeugt eine Zeile fuer den Report. | |
152 | * @param ea die Zeile. | |
153 | * @param reporter der Reporter. | |
154 | * @param indent Einrueckungslevel. | |
155 | */ | |
156 | private void report(EinnahmeAusgabe ea, Reporter reporter, float indent) | |
157 | { | |
158 | PdfPCell cell = reporter.getDetailCell(ea.getText(), Element.ALIGN_LEFT); | |
159 | cell.setPaddingLeft(indent); | |
160 | reporter.addColumn(cell); | |
161 | reporter.addColumn(reporter.getDetailCell(ea.getAnfangssaldo(),BaseColor.BLACK)); | |
162 | reporter.addColumn(reporter.getDetailCell(ea.getEinnahmen(),BaseColor.BLACK)); | |
163 | reporter.addColumn(reporter.getDetailCell(ea.getAusgaben(),BaseColor.BLACK)); | |
164 | reporter.addColumn(reporter.getDetailCell(ea.getEndsaldo(),BaseColor.BLACK)); | |
165 | ||
166 | double sum = ea.getPlusminus(); | |
167 | reporter.addColumn(reporter.getDetailCell(sum,sum >= 0.01d ? BaseColor.GREEN : (sum <= -0.01d ? BaseColor.RED : BaseColor.BLACK))); | |
168 | ||
169 | double diff = ea.getDifferenz(); | |
170 | reporter.addColumn(reporter.getDetailCell(diff,Math.abs(diff) >= 0.01d ? BaseColor.RED : BaseColor.BLACK)); | |
171 | reporter.setNextRecord(); | |
172 | } | |
103 | 173 | |
104 | 174 | /** |
105 | 175 | * @see de.willuhn.jameica.hbci.io.Exporter#suppportsExtension(java.lang.String) |
116 | 186 | public IOFormat[] getIOFormats(Class objectType) |
117 | 187 | { |
118 | 188 | // Wir unterstuetzen nur Umsatz-Trees |
119 | if (!EinnahmeAusgabe.class.equals(objectType)) | |
189 | if (!EinnahmeAusgabeZeitraum.class.equals(objectType)) | |
120 | 190 | return null; |
121 | 191 | |
122 | 192 | IOFormat myFormat = new IOFormat() |
104 | 104 | out.write(NL); |
105 | 105 | |
106 | 106 | out.write(":20:Hibiscus" + NL); |
107 | out.write(":25:" + k.getBLZ() + "/" + k.getKontonummer() + curr + NL); | |
107 | out.write(":25:" + k.getBLZ() + "/" + k.getKontonummer() + NL); | |
108 | out.write(":28C:1" + NL); // Auszugsnummer. Belegen wir hart mit "1", damit das Feld vorhanden ist. SAP braucht das fuer den Import | |
108 | 109 | |
109 | 110 | if (showSaldo) |
110 | 111 | { |
107 | 107 | boolean showSaldo = (b == null || !b.booleanValue()); |
108 | 108 | |
109 | 109 | out.write(":20:Hibiscus" + NL); |
110 | out.write(":25:" + k.getBLZ() + "/" + k.getKontonummer() + curr + NL); | |
110 | out.write(":25:" + k.getBLZ() + "/" + k.getKontonummer() + NL); | |
111 | out.write(":28C:1" + NL); // Auszugsnummer. Belegen wir hart mit "1", damit das Feld vorhanden ist. SAP braucht das fuer den Import | |
111 | 112 | |
112 | 113 | for (int i=0;i<list.size();++i) |
113 | 114 | { |
260 | 260 | */ |
261 | 261 | public PdfPCell getDetailCell(double value) |
262 | 262 | { |
263 | Font f = FontFactory.getFont(FontFactory.HELVETICA, 8f, Font.NORMAL, value >= 0.01d ? BaseColor.BLACK : BaseColor.RED); | |
263 | return this.getDetailCell(value,value >= 0.01d ? BaseColor.BLACK : BaseColor.RED); | |
264 | } | |
265 | ||
266 | /** | |
267 | * Erzeugt eine Zelle fuer die uebergebene Zahl in der angegebenen Farbe. | |
268 | * @param value die Zahl. | |
269 | * @param color die Farbe. | |
270 | * @return die erzeugte Zelle. | |
271 | */ | |
272 | public PdfPCell getDetailCell(double value, BaseColor color) | |
273 | { | |
274 | Font f = FontFactory.getFont(FontFactory.HELVETICA, 8f, Font.NORMAL, color); | |
264 | 275 | PdfPCell cell = new PdfPCell(new Phrase(HBCI.DECIMALFORMAT.format(value), f)); |
265 | 276 | cell.setHorizontalAlignment(Element.ALIGN_RIGHT); |
266 | 277 | return cell; |
21 | 21 | import org.apache.commons.lang.StringUtils; |
22 | 22 | import org.kapott.hbci.GV.SepaUtil; |
23 | 23 | import org.kapott.hbci.manager.HBCIUtils; |
24 | import org.kapott.hbci.sepa.PainVersion.Type; | |
24 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
25 | 25 | |
26 | 26 | import de.willuhn.jameica.hbci.HBCI; |
27 | 27 | import de.willuhn.jameica.hbci.HBCIProperties; |
17 | 17 | import org.apache.commons.lang.StringUtils; |
18 | 18 | import org.kapott.hbci.GV.SepaUtil; |
19 | 19 | import org.kapott.hbci.GV.parsers.ISEPAParser; |
20 | import org.kapott.hbci.sepa.PainVersion; | |
20 | import org.kapott.hbci.sepa.SepaVersion; | |
21 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
21 | 22 | |
22 | 23 | import de.willuhn.datasource.rmi.DBService; |
23 | 24 | import de.willuhn.jameica.hbci.messaging.ImportMessage; |
87 | 88 | * @see de.willuhn.jameica.hbci.io.AbstractSepaImporter#getSupportedPainType() |
88 | 89 | */ |
89 | 90 | @Override |
90 | PainVersion.Type getSupportedPainType() | |
91 | Type getSupportedPainType() | |
91 | 92 | { |
92 | return PainVersion.Type.PAIN_008; | |
93 | return SepaVersion.Type.PAIN_008; | |
93 | 94 | } |
94 | 95 | |
95 | 96 | } |
22 | 22 | import org.apache.commons.lang.StringUtils; |
23 | 23 | import org.kapott.hbci.GV.SepaUtil; |
24 | 24 | import org.kapott.hbci.manager.HBCIUtils; |
25 | import org.kapott.hbci.sepa.PainVersion.Type; | |
25 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
26 | 26 | |
27 | 27 | import de.willuhn.jameica.hbci.HBCI; |
28 | 28 | import de.willuhn.jameica.hbci.HBCIProperties; |
18 | 18 | import org.apache.commons.lang.StringUtils; |
19 | 19 | import org.kapott.hbci.GV.SepaUtil; |
20 | 20 | import org.kapott.hbci.GV.parsers.ISEPAParser; |
21 | import org.kapott.hbci.sepa.PainVersion; | |
21 | import org.kapott.hbci.sepa.SepaVersion; | |
22 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
22 | 23 | |
23 | 24 | import de.willuhn.datasource.rmi.DBService; |
24 | 25 | import de.willuhn.jameica.hbci.HBCI; |
103 | 104 | * @see de.willuhn.jameica.hbci.io.AbstractSepaImporter#getSupportedPainType() |
104 | 105 | */ |
105 | 106 | @Override |
106 | PainVersion.Type getSupportedPainType() | |
107 | Type getSupportedPainType() | |
107 | 108 | { |
108 | return PainVersion.Type.PAIN_008; | |
109 | return SepaVersion.Type.PAIN_008; | |
109 | 110 | } |
110 | 111 | |
111 | 112 | } |
15 | 15 | import org.apache.commons.lang.StringUtils; |
16 | 16 | import org.kapott.hbci.GV.SepaUtil; |
17 | 17 | import org.kapott.hbci.manager.HBCIUtils; |
18 | import org.kapott.hbci.sepa.PainVersion.Type; | |
18 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
19 | 19 | |
20 | 20 | import de.willuhn.jameica.hbci.HBCIProperties; |
21 | 21 | import de.willuhn.jameica.hbci.MetaKey; |
18 | 18 | import org.apache.commons.lang.StringUtils; |
19 | 19 | import org.kapott.hbci.GV.SepaUtil; |
20 | 20 | import org.kapott.hbci.GV.parsers.ISEPAParser; |
21 | import org.kapott.hbci.sepa.PainVersion; | |
21 | import org.kapott.hbci.sepa.SepaVersion; | |
22 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
22 | 23 | |
23 | 24 | import de.willuhn.datasource.rmi.DBService; |
24 | 25 | import de.willuhn.jameica.hbci.HBCI; |
92 | 93 | * @see de.willuhn.jameica.hbci.io.AbstractSepaImporter#getSupportedPainType() |
93 | 94 | */ |
94 | 95 | @Override |
95 | PainVersion.Type getSupportedPainType() | |
96 | Type getSupportedPainType() | |
96 | 97 | { |
97 | return PainVersion.Type.PAIN_001; | |
98 | return SepaVersion.Type.PAIN_001; | |
98 | 99 | } |
99 | 100 | |
100 | 101 | } |
15 | 15 | import org.apache.commons.lang.StringUtils; |
16 | 16 | import org.kapott.hbci.GV.SepaUtil; |
17 | 17 | import org.kapott.hbci.manager.HBCIUtils; |
18 | import org.kapott.hbci.sepa.PainVersion.Type; | |
18 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
19 | 19 | |
20 | 20 | import de.willuhn.jameica.hbci.HBCIProperties; |
21 | 21 | import de.willuhn.jameica.hbci.rmi.AuslandsUeberweisung; |
17 | 17 | import org.apache.commons.lang.StringUtils; |
18 | 18 | import org.kapott.hbci.GV.SepaUtil; |
19 | 19 | import org.kapott.hbci.GV.parsers.ISEPAParser; |
20 | import org.kapott.hbci.sepa.PainVersion; | |
20 | import org.kapott.hbci.sepa.SepaVersion; | |
21 | import org.kapott.hbci.sepa.SepaVersion.Type; | |
21 | 22 | |
22 | 23 | import de.willuhn.datasource.rmi.DBService; |
23 | 24 | import de.willuhn.jameica.hbci.messaging.ImportMessage; |
75 | 76 | * @see de.willuhn.jameica.hbci.io.AbstractSepaImporter#getSupportedPainType() |
76 | 77 | */ |
77 | 78 | @Override |
78 | PainVersion.Type getSupportedPainType() | |
79 | Type getSupportedPainType() | |
79 | 80 | { |
80 | return PainVersion.Type.PAIN_001; | |
81 | return SepaVersion.Type.PAIN_001; | |
81 | 82 | } |
82 | 83 | |
83 | 84 | } |
50 | 50 | if (this.profile == null) |
51 | 51 | { |
52 | 52 | this.profile = new Profile(); |
53 | this.profile.setName(i18n.tr("Default-Profil")); | |
53 | 54 | this.profile.setSkipLines(1); |
54 | this.profile.setVersion(0); | |
55 | this.profile.setSystem(true); | |
55 | 56 | |
56 | 57 | Serializer ts = new DefaultSerializer(); |
57 | 58 |
40 | 40 | if (this.profile == null) |
41 | 41 | { |
42 | 42 | this.profile = new Profile(); |
43 | this.profile.setName(i18n.tr("Default-Profil")); | |
43 | 44 | this.profile.setSkipLines(1); |
44 | this.profile.setVersion(0); | |
45 | this.profile.setSystem(true); | |
45 | 46 | |
46 | 47 | Serializer s = new DefaultSerializer(); |
47 | 48 | List<Column> list = this.profile.getColumns(); |
138 | 138 | clone.serializer = this.serializer; |
139 | 139 | return clone; |
140 | 140 | } |
141 | ||
142 | /** | |
143 | * @see java.lang.Object#equals(java.lang.Object) | |
144 | */ | |
145 | @Override | |
146 | public boolean equals(Object obj) | |
147 | { | |
148 | if (!(obj instanceof Column)) | |
149 | return false; | |
150 | ||
151 | Column other = (Column) obj; | |
152 | return this.property.equals(other.property); | |
153 | } | |
141 | 154 | } |
142 | ||
143 | ||
144 | ||
145 | /********************************************************************** | |
146 | * $Log: Column.java,v $ | |
147 | * Revision 1.1 2010/03/16 00:44:18 willuhn | |
148 | * @N Komplettes Redesign des CSV-Imports. | |
149 | * - Kann nun erheblich einfacher auch fuer andere Datentypen (z.Bsp.Ueberweisungen) verwendet werden | |
150 | * - Fehlertoleranter | |
151 | * - Mehrfachzuordnung von Spalten (z.Bsp. bei erweitertem Verwendungszweck) moeglich | |
152 | * - modulare Deserialisierung der Werte | |
153 | * - CSV-Exports von Hibiscus koennen nun 1:1 auch wieder importiert werden (Import-Preset identisch mit Export-Format) | |
154 | * - Import-Preset wird nun im XML-Format nach ~/.jameica/hibiscus/csv serialisiert. Damit wird es kuenftig moeglich sein, | |
155 | * CSV-Import-Profile vorzukonfigurieren und anschliessend zu exportieren, um sie mit anderen Usern teilen zu koennen | |
156 | * | |
157 | **********************************************************************/⏎ |
15 | 15 | import java.io.IOException; |
16 | 16 | import java.io.InputStream; |
17 | 17 | import java.io.InputStreamReader; |
18 | import java.nio.charset.Charset; | |
19 | import java.nio.charset.UnsupportedCharsetException; | |
18 | 20 | import java.rmi.RemoteException; |
19 | 21 | import java.util.ArrayList; |
20 | 22 | import java.util.HashMap; |
91 | 93 | Profile p = (Profile) d.open(); |
92 | 94 | |
93 | 95 | CsvPreference prefs = p.createCsvPreference(); |
94 | csv = new CsvListReader(new InputStreamReader(new ByteArrayInputStream(data),p.getFileEncoding()),prefs); | |
96 | ||
97 | Charset charset = null; | |
98 | ||
99 | try | |
100 | { | |
101 | charset = Charset.forName(p.getFileEncoding()); | |
102 | } | |
103 | catch (UnsupportedCharsetException e) | |
104 | { | |
105 | Logger.warn("unsupported charset: " + p.getFileEncoding()); | |
106 | } | |
107 | ||
108 | csv = new CsvListReader(new InputStreamReader(new ByteArrayInputStream(data),charset != null ? charset : Charset.defaultCharset()),prefs); | |
95 | 109 | |
96 | 110 | List<String> line = csv.read(); |
97 | 111 | |
247 | 261 | } |
248 | 262 | catch (OperationCanceledException oce) |
249 | 263 | { |
250 | Logger.info("operation cancelled"); | |
251 | monitor.setStatus(ProgressMonitor.STATUS_CANCEL); | |
252 | monitor.setStatusText(i18n.tr("Import abgebrochen")); | |
253 | 264 | throw oce; |
254 | 265 | } |
255 | 266 | catch (ApplicationException ae) |
19 | 19 | /** |
20 | 20 | * Bean fuer ein Profil zum Import von CSV-Dateien. |
21 | 21 | */ |
22 | public class Profile implements Serializable | |
22 | public class Profile implements Serializable, Comparable | |
23 | 23 | { |
24 | private String name = null; | |
25 | private boolean system = false; | |
24 | 26 | private List<Column> columns = new ArrayList<Column>(); |
25 | 27 | private String separatorChar = ";"; |
26 | 28 | private String quotingChar = "\""; |
27 | 29 | private int skipLines = 0; |
28 | 30 | private String fileEncoding = System.getProperty("file.encoding"); |
29 | 31 | |
30 | private int version = 0; | |
31 | ||
32 | 32 | /** |
33 | 33 | * Liefert die Liste der Spalten fuer das Profil. |
34 | 34 | * @return columns Liste der Spalten fuer das Profil. |
125 | 125 | } |
126 | 126 | |
127 | 127 | /** |
128 | * Liefert die Versionsnummer des Profils. | |
129 | * Wenn das Default-Profil des Formats eine hoehere Versionsnummer | |
130 | * liefert als die ggf. serialisierte Version im Benutzerverzeichnis, | |
131 | * dann wird die serialisierte Version ignoriert und stattdessen | |
132 | * wieder das Default-Profil verwendet. Andernfalls muesste der | |
133 | * User die XML-Datei in ~/.jameica/hibiscus/csv manuell loeschen, | |
134 | * damit eine ggf. aktualisierte Profil-Version verwendet wird. | |
135 | * @return version Versionsnummer des Profils. | |
136 | */ | |
137 | public int getVersion() | |
138 | { | |
139 | return version; | |
140 | } | |
141 | ||
142 | /** | |
143 | * Speichert die Versionsnummer des Profils. | |
144 | * @param version version | |
145 | */ | |
146 | public void setVersion(int version) | |
147 | { | |
148 | this.version = version; | |
128 | * Liefert den Namen des Profils. | |
129 | * @return der Name des Profils. | |
130 | */ | |
131 | public String getName() | |
132 | { | |
133 | return name; | |
134 | } | |
135 | ||
136 | /** | |
137 | * Speichert den Namen des Profils. | |
138 | * @param name der Name des Profils. | |
139 | */ | |
140 | public void setName(String name) | |
141 | { | |
142 | this.name = name; | |
143 | } | |
144 | ||
145 | /** | |
146 | * Liefert true, wenn es sich um ein System-Profil handelt. | |
147 | * @return system true, wenn es sich um ein System-Profil handelt. | |
148 | */ | |
149 | public boolean isSystem() | |
150 | { | |
151 | return system; | |
152 | } | |
153 | ||
154 | /** | |
155 | * Legt fest, ob es sich um ein System-Profil handelt. | |
156 | * @param system true, wenn es sich um ein System-Profil handelt. | |
157 | */ | |
158 | public void setSystem(boolean system) | |
159 | { | |
160 | this.system = system; | |
149 | 161 | } |
150 | 162 | |
151 | 163 | /** |
168 | 180 | Builder builder = new CsvPreference.Builder(qc,sc,prefs.getEndOfLineSymbols()); |
169 | 181 | return builder.build(); |
170 | 182 | } |
183 | ||
184 | /** | |
185 | * @see java.lang.Object#equals(java.lang.Object) | |
186 | */ | |
187 | @Override | |
188 | public boolean equals(Object obj) | |
189 | { | |
190 | if (!(obj instanceof Profile)) | |
191 | return false; | |
192 | ||
193 | Profile other = (Profile) obj; | |
194 | return this.getName() != null && this.getName().equals(other.getName()); | |
195 | } | |
196 | ||
197 | /** | |
198 | * @see java.lang.Comparable#compareTo(java.lang.Object) | |
199 | */ | |
200 | @Override | |
201 | public int compareTo(Object o) | |
202 | { | |
203 | // System-Profil immer vorn | |
204 | if (this.isSystem()) | |
205 | return -1; | |
206 | ||
207 | Profile other = (Profile) o; | |
208 | if (other.isSystem()) | |
209 | return 1; | |
210 | ||
211 | if (this.getName() == null) | |
212 | return -1; | |
213 | ||
214 | // Rest alphabetisch | |
215 | return this.getName().compareTo(other.getName()); | |
216 | } | |
217 | ||
218 | /** | |
219 | * @see java.lang.Object#toString() | |
220 | */ | |
221 | @Override | |
222 | public String toString() | |
223 | { | |
224 | return this.getName() + ", encoding: " + this.getFileEncoding() + ", separator: " + this.getSeparatorChar() + ", quoting char: " + this.getQuotingChar() + ", skip lines: " + this.getSkipLines(); | |
225 | } | |
171 | 226 | } |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2018 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.io.csv; | |
11 | ||
12 | import java.beans.ExceptionListener; | |
13 | import java.beans.XMLDecoder; | |
14 | import java.beans.XMLEncoder; | |
15 | import java.io.BufferedInputStream; | |
16 | import java.io.BufferedOutputStream; | |
17 | import java.io.File; | |
18 | import java.io.FileInputStream; | |
19 | import java.io.FileOutputStream; | |
20 | import java.util.ArrayList; | |
21 | import java.util.Collections; | |
22 | import java.util.List; | |
23 | ||
24 | import org.apache.commons.lang.StringUtils; | |
25 | ||
26 | import de.willuhn.jameica.hbci.HBCI; | |
27 | import de.willuhn.jameica.hbci.gui.dialogs.CSVProfileStoreDialog; | |
28 | import de.willuhn.jameica.messaging.StatusBarMessage; | |
29 | import de.willuhn.jameica.system.Application; | |
30 | import de.willuhn.jameica.system.OperationCanceledException; | |
31 | import de.willuhn.logging.Logger; | |
32 | import de.willuhn.util.I18N; | |
33 | ||
34 | /** | |
35 | * Hilfeklasse zum Laden und Speichern von CSV-Import-Profilen. | |
36 | */ | |
37 | public class ProfileUtil | |
38 | { | |
39 | private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
40 | ||
41 | /** | |
42 | * Laedt die vorhandenen Profile fuer das Format. | |
43 | * @param format das Format. | |
44 | * @return die Liste der Profile. | |
45 | */ | |
46 | public static List<Profile> read(Format format) | |
47 | { | |
48 | List<Profile> result = new ArrayList<Profile>(); | |
49 | ||
50 | if (format == null) | |
51 | { | |
52 | Logger.warn("no format given"); | |
53 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Kein Format ausgewählt"),StatusBarMessage.TYPE_ERROR)); | |
54 | return result; | |
55 | } | |
56 | ||
57 | final Profile dp = format.getDefaultProfile(); | |
58 | result.add(dp); // System-Profil wird immer vorn einsortiert | |
59 | ||
60 | // 1. Mal schauen, ob wir gespeicherte Profil fuer das Format haben | |
61 | File dir = new File(Application.getPluginLoader().getPlugin(HBCI.class).getResources().getWorkPath(),"csv"); | |
62 | if (!dir.exists()) | |
63 | return result; | |
64 | ||
65 | File file = new File(dir,format.getClass().getName() + ".xml"); | |
66 | if (!file.exists() || !file.canRead()) | |
67 | return result; | |
68 | ||
69 | Logger.info("reading csv profile " + file); | |
70 | XMLDecoder decoder = null; | |
71 | try | |
72 | { | |
73 | decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream(file))); | |
74 | decoder.setExceptionListener(new ExceptionListener() | |
75 | { | |
76 | public void exceptionThrown(Exception e) | |
77 | { | |
78 | throw new RuntimeException(e); | |
79 | } | |
80 | }); | |
81 | ||
82 | ||
83 | // Es ist tatsaechlich so, dass "readObject()" nicht etwa NULL liefert, wenn keine Objekte mehr in der | |
84 | // Datei sind sondern eine ArrayIndexOutOfBoundsException wirft. | |
85 | try | |
86 | { | |
87 | for (int i=0;i<1000;++i) | |
88 | { | |
89 | Profile p = (Profile) decoder.readObject(); | |
90 | // Migration aus der Zeit vor dem Support mulitpler Profile: | |
91 | // Da konnte der User nur das eine existierende Profil aendern, es wurde automatisch gespeichert | |
92 | // Das hatte gar keinen Namen. Falls also ein Profil ohne Name existiert (inzwischen koennen keine | |
93 | // mehr ohne Name gespeichert werden), dann ist es das vom User geaenderte Profil. Das machen wir | |
94 | // automatisch zum ersten User-spezifischen Profil | |
95 | if (StringUtils.trimToNull(p.getName()) == null) | |
96 | { | |
97 | p.setName(dp.getName() + " 2"); | |
98 | p.setSystem(false); | |
99 | } | |
100 | result.add(p); | |
101 | } | |
102 | } | |
103 | catch (ArrayIndexOutOfBoundsException e) | |
104 | { | |
105 | // EOF | |
106 | } | |
107 | ||
108 | Logger.info("read " + (result.size() - 1) + " profiles from " + file); | |
109 | Collections.sort(result); | |
110 | ||
111 | // Der User hat beim letzten Mal eventuell nicht alle Spalten zugeordnet. | |
112 | // Die wuerden jetzt hier in dem Objekt fehlen. Daher nehmen wir | |
113 | // noch die Spalten aus dem Default-Profil und haengen die fehlenden noch an. | |
114 | } | |
115 | catch (Exception e) | |
116 | { | |
117 | Logger.error("unable to read profile " + file,e); | |
118 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Laden der Profile fehlgeschlagen: {0}",e.getMessage()),StatusBarMessage.TYPE_ERROR)); | |
119 | } | |
120 | finally | |
121 | { | |
122 | if (decoder != null) | |
123 | { | |
124 | try | |
125 | { | |
126 | decoder.close(); | |
127 | } | |
128 | catch (Exception e) { /* useless */} | |
129 | } | |
130 | } | |
131 | return result; | |
132 | } | |
133 | ||
134 | /** | |
135 | * Speichert die Profile. | |
136 | * @param format das Format. | |
137 | * @param profiles die zu speichernden Profile. | |
138 | */ | |
139 | public static void store(Format format, List<Profile> profiles) | |
140 | { | |
141 | if (format == null) | |
142 | { | |
143 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Kein Format ausgewählt"),StatusBarMessage.TYPE_ERROR)); | |
144 | return; | |
145 | } | |
146 | ||
147 | if (profiles == null) | |
148 | { | |
149 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Keine Profile angegeben"),StatusBarMessage.TYPE_ERROR)); | |
150 | return; | |
151 | } | |
152 | ||
153 | // 2. Mal schauen, ob wir ein gespeichertes Profil fuer das Format haben | |
154 | File dir = new File(Application.getPluginLoader().getPlugin(HBCI.class).getResources().getWorkPath(),"csv"); | |
155 | if (!dir.exists()) | |
156 | { | |
157 | Logger.info("creating dir: " + dir); | |
158 | if (!dir.mkdirs()) | |
159 | { | |
160 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Ordner {0} kann nicht erstellt werden",dir.getAbsolutePath()),StatusBarMessage.TYPE_ERROR)); | |
161 | return; | |
162 | } | |
163 | } | |
164 | ||
165 | File file = new File(dir,format.getClass().getName() + ".xml"); | |
166 | ||
167 | Logger.info("writing csv profile " + file); | |
168 | XMLEncoder encoder = null; | |
169 | try | |
170 | { | |
171 | encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(file))); | |
172 | encoder.setExceptionListener(new ExceptionListener() | |
173 | { | |
174 | public void exceptionThrown(Exception e) | |
175 | { | |
176 | throw new RuntimeException(e); | |
177 | } | |
178 | }); | |
179 | ||
180 | for (Profile p:profiles) | |
181 | { | |
182 | // Das System-Profil wird nicht mit gespeichert | |
183 | if (p.isSystem()) | |
184 | continue; | |
185 | ||
186 | // Ebenso Profile ohne Namen. | |
187 | if (StringUtils.trimToNull(p.getName()) == null) | |
188 | continue; | |
189 | ||
190 | encoder.writeObject(p); | |
191 | } | |
192 | } | |
193 | catch (Exception e) | |
194 | { | |
195 | Logger.error("unable to store profile " + file,e); | |
196 | } | |
197 | finally | |
198 | { | |
199 | if (encoder != null) { | |
200 | try { | |
201 | encoder.close(); | |
202 | } | |
203 | catch (Exception e) { /* useless */} | |
204 | } | |
205 | } | |
206 | } | |
207 | ||
208 | /** | |
209 | * Fuegt ein neues Profil hinzu. | |
210 | * @param format das Format. | |
211 | * @param profile das zu speichernde Profil. | |
212 | * @return das hinzugefuegte oder geaenderte Profil. NULL, wenn nicht gespeichert wurde. | |
213 | */ | |
214 | public static Profile add(Format format, Profile profile) | |
215 | { | |
216 | try | |
217 | { | |
218 | if (profile == null || format == null) | |
219 | { | |
220 | Application.getCallback().notifyUser(i18n.tr("Kein Profil angegeben")); | |
221 | return null; | |
222 | } | |
223 | ||
224 | // Der Dialog uebernimmt auch gleich das Speichern. | |
225 | CSVProfileStoreDialog d = new CSVProfileStoreDialog(format,profile); | |
226 | return (Profile) d.open(); | |
227 | } | |
228 | catch (OperationCanceledException oce) | |
229 | { | |
230 | // ignore | |
231 | } | |
232 | catch (Exception e) | |
233 | { | |
234 | Logger.error("unable to delete profile",e); | |
235 | } | |
236 | return null; | |
237 | } | |
238 | ||
239 | /** | |
240 | * Loescht das angegebene Profil. | |
241 | * @param format das Format. | |
242 | * @param profile das zu speichernde Profil. | |
243 | * @return true, wenn das Profil geloescht wurde. | |
244 | */ | |
245 | public static boolean delete(Format format, Profile profile) | |
246 | { | |
247 | if (profile == null || format == null) | |
248 | return false; | |
249 | ||
250 | try | |
251 | { | |
252 | if (profile.isSystem()) | |
253 | { | |
254 | Application.getCallback().notifyUser(i18n.tr("Das Default-Profil darf nicht gelöscht werden")); | |
255 | return false; | |
256 | } | |
257 | ||
258 | List<Profile> profiles = ProfileUtil.read(format); | |
259 | boolean found = false; | |
260 | for (Profile p:profiles) | |
261 | { | |
262 | if (p.isSystem()) | |
263 | continue; | |
264 | ||
265 | if (p.getName().equals(profile.getName())) | |
266 | { | |
267 | profiles.remove(p); | |
268 | found = true; | |
269 | break; | |
270 | } | |
271 | } | |
272 | ||
273 | // Nichts zum Loeschen gefunden | |
274 | if (!found) | |
275 | return false; | |
276 | ||
277 | // Speichern | |
278 | ProfileUtil.store(format,profiles); | |
279 | return true; | |
280 | } | |
281 | catch (OperationCanceledException oce) | |
282 | { | |
283 | // ignore | |
284 | } | |
285 | catch (Exception e) | |
286 | { | |
287 | Logger.error("unable to delete profile",e); | |
288 | } | |
289 | return false; | |
290 | } | |
291 | } | |
292 | ||
293 |
45 | 45 | if (this.profile == null) |
46 | 46 | { |
47 | 47 | this.profile = new Profile(); |
48 | this.profile.setName(i18n.tr("Default-Profil")); | |
48 | 49 | this.profile.setSkipLines(1); |
49 | this.profile.setVersion(0); | |
50 | this.profile.setSystem(true); | |
50 | 51 | |
51 | 52 | Serializer ts = new DefaultSerializer(); |
52 | 53 | Serializer vs = new ValueSerializer(); |
89 | 89 | { |
90 | 90 | control.handleChangeBankData(); |
91 | 91 | } |
92 | },null,false,"user-info.png"); | |
92 | },null,false,"system-user.png"); | |
93 | 93 | buttonArea.addButton(i18n.tr("Speichern"),new Action() |
94 | 94 | { |
95 | 95 | public void handleAction(Object context) throws ApplicationException |
37 | 37 | */ |
38 | 38 | public KontoList(DDVConfig config) throws RemoteException |
39 | 39 | { |
40 | super(PseudoIterator.fromArray(new Konto[0]),new KontoNew()); | |
40 | super(null,new KontoNew()); | |
41 | this.setShowFilter(false); | |
41 | 42 | this.setCheckable(true); |
42 | 43 | this.setSummary(false); |
43 | 44 | this.myConfig = config; |
134 | 134 | if (mech == null || !mech.useUSB()) |
135 | 135 | return; // brauchen wir gar nicht weiter ueberlegen |
136 | 136 | |
137 | // Checken, ob der User schon entschieden hatte, dass er chipTAN USB NICHT nutzen moechte | |
138 | Boolean use = config != null ? config.isChipTANUSB() : null; | |
139 | if (use != null && !use.booleanValue()) | |
140 | return; // User hat explizit entschieden, chipTAN USB NICHT zu nutzen | |
141 | ||
137 | 142 | // Versuchen, die Verbindung zum Kartenleser herzustellen |
138 | 143 | try |
139 | 144 | { |
145 | Logger.info("searching for smartcards, please wait..."); | |
140 | 146 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Legen Sie die bitte Chipkarte ein."),StatusBarMessage.TYPE_INFO)); |
141 | 147 | this.service = SmartCardService.createInstance(ChipTanCardService.class,this.config != null ? StringUtils.trimToNull(this.config.getCardReader()) : null); |
142 | 148 | |
143 | 149 | // Wir haben grundsaetzlich einen Kartenleser. |
144 | 150 | if (this.service != null && this.config != null) |
145 | 151 | { |
146 | if (config.isChipTANUSBAsked()) | |
152 | Logger.info("found smartcard, to be used: " + (use != null ? use : "<asking user>")); | |
153 | ||
154 | // User hat explizit entschieden, den Kartenleser per USB zu nutzen. | |
155 | if (use != null && use.booleanValue()) | |
147 | 156 | { |
148 | 157 | this.usb = this.config.isChipTANUSB(); |
149 | } | |
150 | else | |
151 | { | |
152 | // User fragen, ob er ihn auch nutzen moechte, wenn wir das noch nicht getan haben | |
153 | this.usb = Application.getCallback().askUser(i18n.tr("Es wurde ein USB-Kartenleser gefunden.\nMöchten Sie diesen zur Erzeugung der TAN verwenden?"),false); | |
154 | ||
155 | // Das Speichern der Antwort koennen wir nicht Jameica selbst ueberlassen, weil | |
156 | // die Entscheidung ja pro PIN/TAN-Config gelten soll und nicht global. | |
157 | this.config.setChipTANUSBAsked(true); | |
158 | this.config.setChipTANUSB(this.usb); | |
159 | } | |
158 | return; | |
159 | } | |
160 | ||
161 | // User fragen, ob er ihn auch nutzen moechte, wenn wir das noch nicht getan haben | |
162 | // Das Speichern der Antwort koennen wir nicht Jameica selbst ueberlassen, weil | |
163 | // die Entscheidung ja pro PIN/TAN-Config gelten soll und nicht global. | |
164 | this.usb = Application.getCallback().askUser(i18n.tr("Es wurde ein USB-Kartenleser gefunden.\nMöchten Sie diesen zur Erzeugung der TAN verwenden?"),false); | |
165 | this.config.setChipTANUSB(this.usb); | |
160 | 166 | } |
161 | 167 | } |
162 | 168 | catch (Throwable t) |
19 | 19 | |
20 | 20 | import org.apache.commons.lang.StringUtils; |
21 | 21 | import org.eclipse.swt.SWT; |
22 | import org.eclipse.swt.widgets.Button; | |
22 | 23 | import org.eclipse.swt.widgets.Event; |
23 | 24 | import org.eclipse.swt.widgets.Listener; |
24 | 25 | import org.kapott.hbci.passport.AbstractHBCIPassport; |
279 | 280 | if (this.useUsb != null) |
280 | 281 | return this.useUsb; |
281 | 282 | |
282 | this.useUsb = new CheckboxInput(this.getConfig().isChipTANUSB()); | |
283 | final Boolean b = this.getConfig().isChipTANUSB(); | |
284 | this.useUsb = new CheckboxInput(b == null || b.booleanValue()); | |
283 | 285 | this.useUsb.setName(i18n.tr("Kartenleser per USB zur TAN-Erzeugung verwenden")); |
284 | 286 | |
285 | 287 | final Listener l = new Listener() { |
289 | 291 | { |
290 | 292 | try |
291 | 293 | { |
292 | Boolean b = (Boolean) getChipTANUSB().getValue(); | |
293 | getCardReaders().setEnabled(b != null && b.booleanValue()); | |
294 | Boolean newValue = (Boolean) getChipTANUSB().getValue(); | |
295 | ||
296 | if (event != null && event.type == SWT.Selection) | |
297 | { | |
298 | // Wir kamen aus dem Gray-State. Der User hat entschieden | |
299 | org.eclipse.swt.widgets.Button bt = (org.eclipse.swt.widgets.Button) useUsb.getControl(); | |
300 | if (bt.getGrayed()) | |
301 | { | |
302 | bt.setGrayed(false); | |
303 | bt.setSelection(true); | |
304 | newValue = Boolean.TRUE; | |
305 | } | |
306 | } | |
307 | ||
308 | if (event != null) | |
309 | getCardReaders().setEnabled(newValue != null && newValue.booleanValue()); | |
310 | else | |
311 | getCardReaders().setEnabled(b != null && b.booleanValue()); | |
294 | 312 | |
295 | 313 | // Bei chipTAN USB wird die TAN grundsaetzlich angezeigt |
296 | if (b != null && b.booleanValue() && (event == null || event.type == SWT.Selection)) | |
314 | if (newValue != null && newValue.booleanValue() && (event == null || event.type == SWT.Selection)) | |
297 | 315 | { |
298 | 316 | Boolean showTan = (Boolean) getShowTan().getValue(); |
299 | 317 | if (showTan == null || !showTan.booleanValue()) |
440 | 458 | conf.setCurrentSecMech(null); |
441 | 459 | conf.setStoredSecMech(null); |
442 | 460 | conf.setTanMedia(null); |
443 | conf.setChipTANUSBAsked(false); | |
461 | conf.setChipTANUSB(null); | |
444 | 462 | |
445 | 463 | Application.getMessagingFactory().sendMessage(new StatusBarMessage(i18n.tr("Vorauswahl der TAN-Verfahren zurückgesetzt"),StatusBarMessage.TYPE_SUCCESS)); |
446 | 464 | } |
587 | 605 | config.setShowTan(((Boolean)getShowTan().getValue()).booleanValue()); |
588 | 606 | config.setHBCIVersion(version); |
589 | 607 | config.setPort((Integer)getPort().getValue()); |
590 | config.setChipTANUSB(((Boolean)getChipTANUSB().getValue()).booleanValue()); | |
591 | 608 | config.setCardReader((String) getCardReaders().getValue()); |
609 | ||
610 | PtSecMech secMech = config.getCurrentSecMech(); | |
611 | if (secMech != null && secMech.useUSB()) | |
612 | { | |
613 | CheckboxInput check = this.getChipTANUSB(); | |
614 | Button button = (Button)check.getControl(); | |
615 | if (button != null && !button.isDisposed()) | |
616 | { | |
617 | boolean gray = button.getGrayed(); | |
618 | config.setChipTANUSB((Boolean) (gray ? null : check.getValue())); | |
619 | } | |
620 | } | |
621 | ||
592 | 622 | |
593 | 623 | AbstractHBCIPassport p = (AbstractHBCIPassport)config.getPassport(); |
594 | 624 | PassportChangeRequest change = new PassportChangeRequest(p,(String)getCustomerId().getValue(),(String)getUserId().getValue()); |
11 | 11 | import de.willuhn.jameica.gui.AbstractView; |
12 | 12 | import de.willuhn.jameica.gui.Action; |
13 | 13 | import de.willuhn.jameica.gui.GUI; |
14 | import de.willuhn.jameica.gui.input.CheckboxInput; | |
14 | 15 | import de.willuhn.jameica.gui.parts.Button; |
15 | 16 | import de.willuhn.jameica.gui.parts.ButtonArea; |
16 | 17 | import de.willuhn.jameica.gui.util.ColumnLayout; |
69 | 70 | if (secMech != null && secMech.useUSB()) |
70 | 71 | { |
71 | 72 | group.addHeadline(i18n.tr("ChipTAN USB")); |
72 | group.addInput(control.getChipTANUSB()); | |
73 | ||
74 | CheckboxInput check = control.getChipTANUSB(); | |
75 | group.addInput(check); | |
73 | 76 | group.addInput(control.getCardReaders()); |
77 | ||
78 | // Wenn der User die Entscheidung noch nicht getroffen hat, dann ausgrauen | |
79 | if (control.getConfig().isChipTANUSB() == null) | |
80 | { | |
81 | org.eclipse.swt.widgets.Button b = (org.eclipse.swt.widgets.Button) check.getControl(); | |
82 | b.setGrayed(true); | |
83 | } | |
74 | 84 | } |
75 | 85 | } |
76 | 86 |
38 | 38 | */ |
39 | 39 | public KontoList(PinTanConfig config) throws RemoteException |
40 | 40 | { |
41 | super(PseudoIterator.fromArray(new Konto[0]),new KontoNew()); | |
41 | super(null,new KontoNew()); | |
42 | this.setShowFilter(false); | |
42 | 43 | this.setCheckable(true); |
43 | 44 | this.setSummary(false); |
44 | 45 | this.myConfig = config; |
142 | 142 | } |
143 | 143 | |
144 | 144 | /** |
145 | * Liefert true, wenn es ein Verfahren ist, das USB-tauglich ist. | |
146 | * @return true, wenn es ein Verfahren ist, das USB-tauglich ist. | |
145 | * Liefert true, wenn es ein Verfahren ist, das prinzipiell USB-tauglich ist. | |
146 | * @return true, wenn es ein Verfahren ist, das prinzipiell USB-tauglich ist. | |
147 | 147 | */ |
148 | 148 | public boolean useUSB() |
149 | 149 | { |
154 | 154 | return s.contains("usb") || |
155 | 155 | s.contains("optic") || |
156 | 156 | s.contains("optisch") || |
157 | s.contains("flicker") || | |
157 | 158 | s.contains("komfort") || |
158 | 159 | s.contains("comfort"); |
159 | 160 | } |
199 | 199 | public void setCurrentSecMech(PtSecMech mech) throws RemoteException; |
200 | 200 | |
201 | 201 | /** |
202 | * Prueft, ob der User schonmal gefragt wurde, ob er chipTAN USB nutzen moechte. | |
203 | * @return true, wenn der User schonmal gefragt wurde, ob er chipTAN USB nutzen moechte. | |
204 | * @throws RemoteException | |
205 | */ | |
206 | public boolean isChipTANUSBAsked() throws RemoteException; | |
207 | ||
208 | /** | |
209 | * Legt fest, ob der User schonmal gefragt wurde, ob er chipTAN USB nutzen moechte. | |
210 | * @param b true, wenn der User gefragt wurde, ob er chipTAN USB nutzen moechte. | |
211 | * @throws RemoteException | |
212 | */ | |
213 | public void setChipTANUSBAsked(boolean b) throws RemoteException; | |
214 | ||
215 | /** | |
216 | 202 | * Liefert true, wenn chipTAN USB verwendet werden soll. |
217 | 203 | * @return true, wenn chipTAN USB verwendet werden soll. |
218 | * @throws RemoteException | |
219 | */ | |
220 | public boolean isChipTANUSB() throws RemoteException; | |
204 | * false, wenn es nicht verwendet werden soll. | |
205 | * NULL, wenn der User die Entscheidung noch nicht getroffen hat. | |
206 | * @throws RemoteException | |
207 | */ | |
208 | public Boolean isChipTANUSB() throws RemoteException; | |
221 | 209 | |
222 | 210 | /** |
223 | 211 | * Legt fest, ob chipTAN USB genutzt werden soll. |
224 | 212 | * @param b true, wenn chipTAN USB genutzt werden soll. |
225 | * @throws RemoteException | |
226 | */ | |
227 | public void setChipTANUSB(boolean b) throws RemoteException; | |
213 | * false, wenn es nicht verwendet werden soll. | |
214 | * NULL, wenn der User die Entscheidung noch nicht getroffen hat. | |
215 | * @throws RemoteException | |
216 | */ | |
217 | public void setChipTANUSB(Boolean b) throws RemoteException; | |
228 | 218 | |
229 | 219 | /** |
230 | 220 | * Liefert eine optionale Bezeichnung fuer den zu nutzenden Karteleser. |
443 | 443 | * @see de.willuhn.jameica.hbci.passports.pintan.rmi.PinTanConfig#isChipTANUSB() |
444 | 444 | */ |
445 | 445 | @Override |
446 | public boolean isChipTANUSB() throws RemoteException | |
447 | { | |
448 | return settings.getBoolean(getID() + ".chiptan.usb.enabled",false); | |
449 | } | |
450 | ||
451 | /** | |
452 | * @see de.willuhn.jameica.hbci.passports.pintan.rmi.PinTanConfig#isChipTANUSBAsked() | |
446 | public Boolean isChipTANUSB() throws RemoteException | |
447 | { | |
448 | String s = StringUtils.trimToNull(settings.getString(getID() + ".chiptan.usb.enabled",null)); | |
449 | return s != null ? Boolean.valueOf(s) : null; | |
450 | } | |
451 | ||
452 | /** | |
453 | * @see de.willuhn.jameica.hbci.passports.pintan.rmi.PinTanConfig#setChipTANUSB(java.lang.Boolean) | |
453 | 454 | */ |
454 | 455 | @Override |
455 | public boolean isChipTANUSBAsked() throws RemoteException | |
456 | { | |
457 | return settings.getBoolean(getID() + ".chiptan.usb.asked",false); | |
458 | } | |
459 | ||
460 | /** | |
461 | * @see de.willuhn.jameica.hbci.passports.pintan.rmi.PinTanConfig#setChipTANUSB(boolean) | |
462 | */ | |
463 | @Override | |
464 | public void setChipTANUSB(boolean b) throws RemoteException | |
465 | { | |
466 | settings.setAttribute(getID() + ".chiptan.usb.enabled",b); | |
467 | } | |
468 | ||
469 | /** | |
470 | * @see de.willuhn.jameica.hbci.passports.pintan.rmi.PinTanConfig#setChipTANUSBAsked(boolean) | |
471 | */ | |
472 | @Override | |
473 | public void setChipTANUSBAsked(boolean b) throws RemoteException | |
474 | { | |
475 | settings.setAttribute(getID() + ".chiptan.usb.asked",b); | |
476 | } | |
477 | ||
456 | public void setChipTANUSB(Boolean b) throws RemoteException | |
457 | { | |
458 | settings.setAttribute(getID() + ".chiptan.usb.enabled",(String) (b != null ? b.toString() : null)); | |
459 | } | |
460 | ||
478 | 461 | /** |
479 | 462 | * @see de.willuhn.jameica.hbci.passports.pintan.rmi.PinTanConfig#getTanMedias() |
480 | 463 | */ |
38 | 38 | */ |
39 | 39 | public KontoList(RDHKey key) throws RemoteException |
40 | 40 | { |
41 | super(PseudoIterator.fromArray(new Konto[0]),new KontoNew()); | |
41 | super(null,new KontoNew()); | |
42 | this.setShowFilter(false); | |
42 | 43 | this.setCheckable(true); |
43 | 44 | this.setSummary(false); |
44 | 45 | this.myKey = key; |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2004 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.rmi; | |
11 | ||
12 | import java.util.Date; | |
13 | ||
14 | import de.willuhn.datasource.GenericObject; | |
15 | ||
16 | /** | |
17 | * Interface fuer einen Zeitraum von Einnahmen und Ausgaben. | |
18 | */ | |
19 | public interface EinnahmeAusgabeZeitraum extends GenericObject | |
20 | { | |
21 | /** | |
22 | * Liefert das Start-Datum. | |
23 | * @return das Start-Datum. | |
24 | */ | |
25 | public Date getStartdatum(); | |
26 | ||
27 | /** | |
28 | * Liefert das End-Datum. | |
29 | * @return das End-Datum. | |
30 | */ | |
31 | public Date getEnddatum(); | |
32 | } |
185 | 185 | * @throws RemoteException |
186 | 186 | */ |
187 | 187 | public boolean isAssigned() throws RemoteException; |
188 | ||
189 | /** | |
190 | * Liefert eine optionale Transaktions-ID, anhand derer der Umsatz eindeutig identifiziert werden kann. | |
191 | * Die ID ist nur bei Umsaetzen vorhanden, die per CAMT abgerufen wurden. | |
192 | * Wichtig: Hibiscus garantiert NICHT, dass die ID eindeutig ist. Weder durch Programmlogik noch durch einen Unique-Key. | |
193 | * Denn wuerde es das tun - und es wuerde tatsaechlich zu einer doppelten ID kommen, koennte der Umsatz | |
194 | * nicht angelegt werden. Die ID ist lediglich ein zusaetzliches Kriterium bei der Doppler-Erkennung. | |
195 | * @return optionale Transaktions-ID, anhand derer der Umsatz eindeutig identifiziert werden kann. | |
196 | * @throws RemoteException | |
197 | */ | |
198 | public String getTransactionId() throws RemoteException; | |
199 | ||
200 | /** | |
201 | * Speichert eine optionale Transaktions-ID, anhand derer der Umsatz eindeutig identifiziert werden kann. | |
202 | * Wichtig: Hibiscus garantiert NICHT, dass die ID eindeutig ist. Weder durch Programmlogik noch durch einen Unique-Key. | |
203 | * Denn wuerde es das tun - und es wuerde tatsaechlich zu einer doppelten ID kommen, koennte der Umsatz | |
204 | * nicht angelegt werden. Die ID ist lediglich ein zusaetzliches Kriterium bei der Doppler-Erkennung. | |
205 | * @param id die eindeutige Transaktions-ID. | |
206 | * @throws RemoteException | |
207 | */ | |
208 | public void setTransactionId(String id) throws RemoteException; | |
209 | ||
210 | /** | |
211 | * Liefert den Purpose-Code der Buchung. | |
212 | * Nur bei Umsaetzen vorhanden, die per CAMT abgerufen wurden. | |
213 | * @return der Purpose-Code der Buchung. | |
214 | * @throws RemoteException | |
215 | */ | |
216 | public String getPurposeCode() throws RemoteException; | |
217 | ||
218 | /** | |
219 | * Speichern den Purpose-Code der Buchung. | |
220 | * @param code der Purpose-Code der Buchung. | |
221 | * @throws RemoteException | |
222 | */ | |
223 | public void setPurposeCode(String code) throws RemoteException; | |
224 | ||
225 | ||
226 | /** | |
227 | * Liefert die EndToEnd-ID der Buchung. | |
228 | * Nur bei Umsaetzen vorhanden, die per CAMT abgerufen wurden. | |
229 | * @return der EndToEnd-ID der Buchung. | |
230 | * @throws RemoteException | |
231 | */ | |
232 | public String getEndToEndId() throws RemoteException; | |
233 | ||
234 | /** | |
235 | * Speichern die EndToEnd-ID der Buchung. | |
236 | * @param id die EndToEnd-ID der Buchung. | |
237 | * @throws RemoteException | |
238 | */ | |
239 | public void setEndToEndId(String id) throws RemoteException; | |
240 | ||
188 | 241 | } |
189 | ||
190 | ||
191 | /********************************************************************** | |
192 | * $Log: Umsatz.java,v $ | |
193 | * Revision 1.27 2011/10/18 09:28:14 willuhn | |
194 | * @N Gemeinsames Basis-Interface "HibiscusDBObject" fuer alle Entities (ausser Version und DBProperty) mit der Implementierung "AbstractHibiscusDBObject". Damit koennen jetzt zu jedem Fachobjekt beliebige Meta-Daten in der Datenbank gespeichert werden. Wird im ersten Schritt fuer die Reminder verwendet, um zu einem Auftrag die UUID des Reminders am Objekt speichern zu koennen | |
195 | * | |
196 | * Revision 1.26 2011-07-25 17:17:19 willuhn | |
197 | * @N BUGZILLA 1065 - zusaetzlich noch addkey | |
198 | * | |
199 | * Revision 1.25 2011-07-25 14:42:41 willuhn | |
200 | * @N BUGZILLA 1065 | |
201 | * | |
202 | * Revision 1.24 2010/04/22 12:42:02 willuhn | |
203 | * @N Erste Version des Supports fuer Offline-Konten | |
204 | * | |
205 | * Revision 1.23 2010/03/16 00:44:18 willuhn | |
206 | * @N Komplettes Redesign des CSV-Imports. | |
207 | * - Kann nun erheblich einfacher auch fuer andere Datentypen (z.Bsp.Ueberweisungen) verwendet werden | |
208 | * - Fehlertoleranter | |
209 | * - Mehrfachzuordnung von Spalten (z.Bsp. bei erweitertem Verwendungszweck) moeglich | |
210 | * - modulare Deserialisierung der Werte | |
211 | * - CSV-Exports von Hibiscus koennen nun 1:1 auch wieder importiert werden (Import-Preset identisch mit Export-Format) | |
212 | * - Import-Preset wird nun im XML-Format nach ~/.jameica/hibiscus/csv serialisiert. Damit wird es kuenftig moeglich sein, | |
213 | * CSV-Import-Profile vorzukonfigurieren und anschliessend zu exportieren, um sie mit anderen Usern teilen zu koennen | |
214 | * | |
215 | * Revision 1.22 2009/09/15 00:23:34 willuhn | |
216 | * @N BUGZILLA 745 | |
217 | * | |
218 | * Revision 1.21 2009/02/23 17:01:58 willuhn | |
219 | * @C Kein Abgleichen mehr bei vorgemerkten Buchungen sondern stattdessen vorgemerkte loeschen und neu abrufen | |
220 | * | |
221 | * Revision 1.20 2009/02/12 18:37:18 willuhn | |
222 | * @N Erster Code fuer vorgemerkte Umsaetze | |
223 | * | |
224 | * Revision 1.19 2009/02/12 16:14:34 willuhn | |
225 | * @N HBCI4Java-Version mit Unterstuetzung fuer vorgemerkte Umsaetze | |
226 | * | |
227 | * Revision 1.18 2009/02/04 23:06:24 willuhn | |
228 | * @N BUGZILLA 308 - Umsaetze als "geprueft" markieren | |
229 | * | |
230 | * Revision 1.17 2009/01/04 01:25:47 willuhn | |
231 | * @N Checksumme von Umsaetzen wird nun generell beim Anlegen des Datensatzes gespeichert. Damit koennen Umsaetze nun problemlos geaendert werden, ohne mit "hasChangedByUser" checken zu muessen. Die Checksumme bleibt immer erhalten, weil sie in UmsatzImpl#insert() sofort zu Beginn angelegt wird | |
232 | * @N Umsaetze sind nun vollstaendig editierbar | |
233 | * | |
234 | * Revision 1.16 2007/04/23 18:07:14 willuhn | |
235 | * @C Redesign: "Adresse" nach "HibiscusAddress" umbenannt | |
236 | * @C Redesign: "Transfer" nach "HibiscusTransfer" umbenannt | |
237 | * @C Redesign: Neues Interface "Transfer", welches von Ueberweisungen, Lastschriften UND Umsaetzen implementiert wird | |
238 | * @N Anbindung externer Adressbuecher | |
239 | * | |
240 | * Revision 1.15 2006/11/23 17:25:37 willuhn | |
241 | * @N Umsatz-Kategorien - in PROGRESS! | |
242 | * | |
243 | * Revision 1.14 2006/08/21 23:15:01 willuhn | |
244 | * @N Bug 184 (CSV-Import) | |
245 | * | |
246 | * Revision 1.13 2005/12/29 01:22:12 willuhn | |
247 | * @R UmsatzZuordnung entfernt | |
248 | * @B Debugging am Pie-Chart | |
249 | * | |
250 | * Revision 1.12 2005/12/05 20:16:15 willuhn | |
251 | * @N Umsatz-Filter Refactoring | |
252 | * | |
253 | * Revision 1.11 2005/11/14 23:47:21 willuhn | |
254 | * @N added first code for umsatz categories | |
255 | * | |
256 | * Revision 1.10 2005/06/30 21:48:56 web0 | |
257 | * @B bug 75 | |
258 | * | |
259 | * Revision 1.9 2005/06/13 23:11:01 web0 | |
260 | * *** empty log message *** | |
261 | * | |
262 | * Revision 1.8 2005/02/27 17:11:49 web0 | |
263 | * @N first code for "Sammellastschrift" | |
264 | * @C "Empfaenger" renamed into "Adresse" | |
265 | * | |
266 | * Revision 1.7 2004/10/23 17:34:31 willuhn | |
267 | * *** empty log message *** | |
268 | * | |
269 | * Revision 1.6 2004/10/17 16:28:46 willuhn | |
270 | * @N Die ersten Dauerauftraege abgerufen ;) | |
271 | * | |
272 | * Revision 1.5 2004/05/25 23:23:17 willuhn | |
273 | * @N UeberweisungTyp | |
274 | * @N Protokoll | |
275 | * | |
276 | * Revision 1.4 2004/04/27 22:23:56 willuhn | |
277 | * @N configurierbarer CTAPI-Treiber | |
278 | * @C konkrete Passport-Klassen (DDV) nach de.willuhn.jameica.passports verschoben | |
279 | * @N verschiedenste Passport-Typen sind jetzt voellig frei erweiterbar (auch die Config-Dialoge) | |
280 | * @N crc32 Checksumme in Umsatz | |
281 | * @N neue Felder im Umsatz | |
282 | * | |
283 | * Revision 1.3 2004/03/06 18:25:10 willuhn | |
284 | * @D javadoc | |
285 | * @C removed empfaenger_id from umsatz | |
286 | * | |
287 | * Revision 1.2 2004/03/05 00:04:10 willuhn | |
288 | * @N added code for umsatzlist | |
289 | * | |
290 | * Revision 1.1 2004/02/27 01:10:18 willuhn | |
291 | * @N passport config refactored | |
292 | * | |
293 | **********************************************************************/⏎ |
83 | 83 | |
84 | 84 | if (StringUtils.trimToNull(getGegenkontoName()) == null) |
85 | 85 | throw new ApplicationException(i18n.tr("Bitte geben Sie den Namen des Kontoinhabers des Gegenkontos ein")); |
86 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
86 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
87 | 87 | HBCIProperties.checkChars(getGegenkontoName(), HBCIProperties.HBCI_SEPA_VALIDCHARS); |
88 | 88 | |
89 | 89 | |
90 | HBCIProperties.checkLength(getZweck(), HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
90 | HBCIProperties.checkLength(getZweck(), HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
91 | 91 | HBCIProperties.checkChars(getZweck(), HBCIProperties.HBCI_SEPA_VALIDCHARS); |
92 | 92 | |
93 | 93 | HBCIProperties.checkLength(getEndtoEndId(), HBCIProperties.HBCI_SEPA_ENDTOENDID_MAXLENGTH); |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) 2018 Olaf Willuhn | |
3 | * All rights reserved. | |
4 | * | |
5 | * This software is copyrighted work licensed under the terms of the | |
6 | * Jameica License. Please consult the file "LICENSE" for details. | |
7 | * | |
8 | **********************************************************************/ | |
9 | ||
10 | package de.willuhn.jameica.hbci.server; | |
11 | ||
12 | import java.io.StringReader; | |
13 | import java.util.List; | |
14 | ||
15 | import de.willuhn.jameica.hbci.rmi.DBSupport; | |
16 | import de.willuhn.jameica.hbci.rmi.HBCIDBService; | |
17 | import de.willuhn.jameica.system.Application; | |
18 | import de.willuhn.logging.Logger; | |
19 | import de.willuhn.sql.ScriptExecutor; | |
20 | import de.willuhn.sql.version.Update; | |
21 | import de.willuhn.sql.version.UpdateProvider; | |
22 | import de.willuhn.util.ApplicationException; | |
23 | import de.willuhn.util.I18N; | |
24 | ||
25 | /** | |
26 | * Abstrakte Basis-Klasse fuer Datenbank-Updates. | |
27 | */ | |
28 | public abstract class AbstractUpdate implements Update | |
29 | { | |
30 | /** | |
31 | * @see de.willuhn.sql.version.Update#execute(de.willuhn.sql.version.UpdateProvider) | |
32 | */ | |
33 | public void execute(UpdateProvider provider) throws ApplicationException | |
34 | { | |
35 | HBCIUpdateProvider myProvider = (HBCIUpdateProvider) provider; | |
36 | I18N i18n = myProvider.getResources().getI18N(); | |
37 | ||
38 | try | |
39 | { | |
40 | String driver = HBCIDBService.SETTINGS.getString("database.driver",DBSupportH2Impl.class.getName()); | |
41 | Class<? extends DBSupport> driverClass = Application.getClassLoader().load(driver); | |
42 | ||
43 | List<String> sql = this.getStatements(driverClass); | |
44 | if (sql == null) | |
45 | throw new ApplicationException(i18n.tr("Datenbank {0} nicht wird unterstützt",driver)); | |
46 | ||
47 | if (sql.size() == 0) | |
48 | { | |
49 | myProvider.getProgressMonitor().log(i18n.tr("Update übersprungen, nicht notwendig")); | |
50 | return; | |
51 | } | |
52 | ||
53 | // Wir packen alle Zeilen in einen String, damit es in einer gemeinsamen Transaktion ausgefuehrt wird. | |
54 | StringBuilder sb = new StringBuilder(); | |
55 | for (String s:sql) | |
56 | { | |
57 | sb.append(s); | |
58 | sb.append("\n"); | |
59 | } | |
60 | ||
61 | ScriptExecutor.execute(new StringReader(sb.toString()),myProvider.getConnection(),myProvider.getProgressMonitor()); | |
62 | myProvider.getProgressMonitor().log(i18n.tr("Tabelle aktualisiert")); | |
63 | } | |
64 | catch (ApplicationException ae) | |
65 | { | |
66 | throw ae; | |
67 | } | |
68 | catch (Exception e) | |
69 | { | |
70 | Logger.error("unable to execute update",e); | |
71 | throw new ApplicationException(i18n.tr("Fehler beim Ausführen des Updates"),e); | |
72 | } | |
73 | } | |
74 | ||
75 | /** | |
76 | * Liefert die auszufuehrenden Datenbank-Updates fuer den jeweiligen Treiber. | |
77 | * @param driverClass die Klasse des Treibers. | |
78 | * @return die Statements. | |
79 | */ | |
80 | protected abstract List<String> getStatements(Class<? extends DBSupport> driverClass); | |
81 | ||
82 | /** | |
83 | * @see de.willuhn.sql.version.Update#getName() | |
84 | */ | |
85 | public String getName() | |
86 | { | |
87 | return "database update " + this.getClass().getSimpleName(); | |
88 | } | |
89 | } |
113 | 113 | |
114 | 114 | if (StringUtils.trimToNull(getGegenkontoName()) == null) |
115 | 115 | throw new ApplicationException(i18n.tr("Bitte geben Sie den Namen des Kontoinhabers des Gegenkontos ein")); |
116 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
116 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
117 | 117 | HBCIProperties.checkChars(getGegenkontoName(), HBCIProperties.HBCI_SEPA_VALIDCHARS); |
118 | 118 | |
119 | HBCIProperties.checkLength(getZweck(), HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
119 | HBCIProperties.checkLength(getZweck(), HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
120 | 120 | HBCIProperties.checkChars(getZweck(), HBCIProperties.HBCI_SEPA_VALIDCHARS); |
121 | 121 | |
122 | 122 | HBCIProperties.checkLength(getEndtoEndId(), HBCIProperties.HBCI_SEPA_ENDTOENDID_MAXLENGTH); |
65 | 65 | */ |
66 | 66 | KontoauszugPdf("KontoauszugPdf","HKEKP"), |
67 | 67 | |
68 | /** | |
69 | * Query fuer Abruf der Umsaetze im CAMT-Format. | |
70 | */ | |
71 | UmsatzCamt("KUmsZeitCamt","HKCAZ") | |
72 | ||
68 | 73 | ; |
69 | 74 | |
70 | 75 | private String query = null; |
364 | 369 | * Aktualisiert den Cache fuer den Passport. |
365 | 370 | * @param passport der Passport. |
366 | 371 | * @param prefix der Prefix. |
367 | */ | |
368 | public static void updateCache(HBCIPassport passport, Prefix prefix) | |
372 | * @return true, wenn der Cache aktualisiert wurde. | |
373 | */ | |
374 | public static boolean updateCache(HBCIPassport passport, Prefix prefix) | |
369 | 375 | { |
370 | 376 | if (passport == null) |
371 | return; | |
377 | return false; | |
372 | 378 | |
373 | 379 | try |
374 | 380 | { |
379 | 385 | if (version == null || version.length() == 0 || user == null || user.length() == 0 || data == null || data.size() == 0) |
380 | 386 | { |
381 | 387 | Logger.debug("[" + prefix + "] no version, no userid or no data found, skipping update"); |
382 | return; | |
388 | return false; | |
383 | 389 | } |
384 | 390 | |
385 | 391 | // Wir machen das Update nicht jedesmal sondern periodisch. Denn unter |
432 | 438 | |
433 | 439 | Logger.info(prefix + " cache update state [expired: " + expired + ", new version: " + newVersion + "]"); |
434 | 440 | if (!expired && !newVersion) |
435 | return; | |
441 | return false; | |
436 | 442 | |
437 | 443 | BeanService service = Application.getBootLoader().getBootable(BeanService.class); |
438 | 444 | SynchronizeSession session = service.get(HBCISynchronizeBackend.class).getCurrentSession(); |
450 | 456 | { |
451 | 457 | int deleted = DBPropertyUtil.deleteScope(prefix,customerId); |
452 | 458 | Logger.info("deleted " + deleted + " old " + prefix.name() + " cache entries"); |
459 | ||
460 | int count2 = 0; | |
453 | 461 | |
454 | 462 | for (Enumeration keys = data.keys();keys.hasMoreElements();) |
455 | 463 | { |
456 | 464 | String name = (String) keys.nextElement(); |
457 | 465 | if (DBPropertyUtil.insert(prefix,customerId,null,name,data.getProperty(name))) |
466 | { | |
458 | 467 | count++; |
468 | count2++; | |
469 | if (count2 > 0 && count2 % 50 == 0) | |
470 | { | |
471 | Logger.info("stored " + count2 + " " + prefix.name() + " entries"); | |
472 | ||
473 | if (monitor != null) | |
474 | monitor.log(i18n.tr(" {0} {1}-Parameter aktualisiert",Integer.toString(count),prefix.name())); | |
475 | } | |
476 | } | |
459 | 477 | |
460 | if (count > 0 && count % 20 == 0 && monitor != null) | |
461 | monitor.log(" " + i18n.tr("{0} Datensätze",Integer.toString(count))); | |
462 | 478 | } |
463 | 479 | } |
464 | 480 | Logger.info("created " + count + " new " + prefix.name() + " cache entries"); |
468 | 484 | |
469 | 485 | // Datum des letzten Abrufs speichern |
470 | 486 | DBPropertyUtil.set(prefix,user,null,"cacheupdate",Long.toString(now)); |
487 | return true; | |
471 | 488 | } |
472 | 489 | catch (Exception e) |
473 | 490 | { |
474 | 491 | Logger.error("error while updating " + prefix + " - will be ignored",e); |
492 | return false; | |
475 | 493 | } |
476 | 494 | } |
477 | 495 | |
479 | 497 | * Markiert den Cache als expired. |
480 | 498 | * @param passport der Passport. |
481 | 499 | * @param prefix der Prefix. |
482 | * @throws RemoteException | |
483 | */ | |
484 | public static void expireCache(HBCIPassport passport, Prefix prefix) throws RemoteException | |
500 | */ | |
501 | public static void expireCache(HBCIPassport passport, Prefix prefix) | |
485 | 502 | { |
486 | 503 | final String user = passport.getUserId(); |
487 | 504 | if (user == null || user.length() == 0) |
489 | 506 | Logger.debug("[" + prefix + "] no userid found, skipping cache expiry"); |
490 | 507 | return; |
491 | 508 | } |
492 | ||
493 | Logger.info("expire " + prefix.name() + " cache"); | |
494 | DBPropertyUtil.set(prefix,user,null,"cacheupdate","0"); | |
495 | } | |
496 | ||
509 | ||
510 | try | |
511 | { | |
512 | Logger.info("expire " + prefix.name() + " cache"); | |
513 | DBPropertyUtil.set(prefix,user,null,"cacheupdate","0"); | |
514 | } | |
515 | catch (Exception e) | |
516 | { | |
517 | Logger.error("error while expiring " + prefix + " cache",e); | |
518 | } | |
519 | } | |
497 | 520 | } |
8 | 8 | **********************************************************************/ |
9 | 9 | package de.willuhn.jameica.hbci.server; |
10 | 10 | |
11 | import java.math.BigDecimal; | |
11 | 12 | import java.rmi.RemoteException; |
13 | import java.util.Arrays; | |
12 | 14 | import java.util.Map; |
13 | 15 | |
14 | 16 | import org.apache.commons.lang.StringUtils; |
15 | 17 | import org.kapott.hbci.GV_Result.GVRDauerList; |
16 | 18 | import org.kapott.hbci.GV_Result.GVRKUms; |
19 | import org.kapott.hbci.GV_Result.GVRKUms.UmsLine; | |
17 | 20 | import org.kapott.hbci.GV_Result.GVRKontoauszug.Format; |
18 | 21 | import org.kapott.hbci.GV_Result.GVRKontoauszug.GVRKontoauszugEntry; |
19 | 22 | import org.kapott.hbci.structures.Konto; |
20 | 23 | import org.kapott.hbci.structures.Saldo; |
21 | 24 | import org.kapott.hbci.structures.Value; |
22 | import org.kapott.hbci.swift.DTAUS; | |
23 | 25 | |
24 | 26 | import de.jost_net.OBanToo.SEPA.IBAN; |
25 | 27 | import de.willuhn.datasource.rmi.DBIterator; |
28 | 30 | import de.willuhn.jameica.hbci.rmi.Address; |
29 | 31 | import de.willuhn.jameica.hbci.rmi.HibiscusAddress; |
30 | 32 | import de.willuhn.jameica.hbci.rmi.Kontoauszug; |
31 | import de.willuhn.jameica.hbci.rmi.SammelLastschrift; | |
32 | import de.willuhn.jameica.hbci.rmi.SammelTransfer; | |
33 | import de.willuhn.jameica.hbci.rmi.SammelTransferBuchung; | |
34 | import de.willuhn.jameica.hbci.rmi.SammelUeberweisung; | |
35 | 33 | import de.willuhn.jameica.hbci.rmi.SepaDauerauftrag; |
36 | 34 | import de.willuhn.jameica.hbci.rmi.Umsatz; |
37 | 35 | import de.willuhn.jameica.hbci.server.VerwendungszweckUtil.Tag; |
44 | 42 | */ |
45 | 43 | public class Converter |
46 | 44 | { |
45 | private final static double KURS_EUR = 1.95583; | |
47 | 46 | |
48 | 47 | /** |
49 | 48 | * Konvertiert einen einzelnen Umsatz von HBCI4Java nach Hibiscus. |
61 | 60 | umsatz.setArt(clean(u.text)); |
62 | 61 | umsatz.setCustomerRef(clean(u.customerref)); |
63 | 62 | umsatz.setPrimanota(clean(u.primanota)); |
64 | ||
65 | double kurs = 1.95583; | |
63 | umsatz.setTransactionId(u.id); | |
64 | umsatz.setPurposeCode(u.purposecode); | |
65 | umsatz.setEndToEndId(u.endToEndId); | |
66 | 66 | |
67 | 67 | //BUGZILLA 67 http://www.willuhn.de/bugzilla/show_bug.cgi?id=67 |
68 | 68 | Saldo s = u.saldo; |
75 | 75 | double saldo = v.getDoubleValue(); |
76 | 76 | String curr = v.getCurr(); |
77 | 77 | if (curr != null && "DEM".equals(curr)) |
78 | saldo /= kurs; | |
78 | saldo /= KURS_EUR; | |
79 | 79 | umsatz.setSaldo(saldo); |
80 | 80 | } |
81 | 81 | } |
86 | 86 | |
87 | 87 | // BUGZILLA 318 |
88 | 88 | if (curr != null && "DEM".equals(curr)) |
89 | betrag /= kurs; | |
89 | betrag /= KURS_EUR; | |
90 | 90 | |
91 | 91 | umsatz.setBetrag(betrag); |
92 | 92 | umsatz.setDatum(u.bdate); |
114 | 114 | |
115 | 115 | String[] lines = (String[]) u.usage.toArray(new String[u.usage.size()]); |
116 | 116 | |
117 | // die Bank liefert keine strukturierten Verwendungszwecke (gvcode=999). | |
118 | // Daher verwenden wir den gesamten "additional"-Block und zerlegen ihn | |
119 | // in 27-Zeichen lange Haeppchen | |
120 | if (lines.length == 0) | |
121 | lines = VerwendungszweckUtil.parse(u.additional); | |
122 | ||
123 | // Es gibt eine erste Bank, die 40 Zeichen lange Verwendungszwecke lieferte. | |
124 | // Siehe Mail von Frank vom 06.02.2014 | |
125 | lines = VerwendungszweckUtil.rewrap(HBCIProperties.HBCI_TRANSFER_USAGE_DB_MAXLENGTH,lines); | |
126 | VerwendungszweckUtil.apply(umsatz,lines); | |
117 | // Wenn es ein CAMT-Umsatz ist, koennen wir einfach die erste Zeile pauschal | |
118 | // uebernehmen. Da gibt es ohnehin nur noch diese eine Zeile | |
119 | if (u.isCamt) | |
120 | { | |
121 | if (lines.length > 0) | |
122 | umsatz.setZweck(lines[0]); | |
123 | } | |
124 | else | |
125 | { | |
126 | // die Bank liefert keine strukturierten Verwendungszwecke (gvcode=999). | |
127 | // Daher verwenden wir den gesamten "additional"-Block und zerlegen ihn | |
128 | // in 27-Zeichen lange Haeppchen | |
129 | if (lines.length == 0) | |
130 | lines = VerwendungszweckUtil.parse(u.additional); | |
131 | ||
132 | // Es gibt eine erste Bank, die 40 Zeichen lange Verwendungszwecke lieferte. | |
133 | // Siehe Mail von Frank vom 06.02.2014 | |
134 | lines = VerwendungszweckUtil.rewrap(HBCIProperties.HBCI_TRANSFER_USAGE_DB_MAXLENGTH,lines); | |
135 | VerwendungszweckUtil.apply(umsatz,lines); | |
136 | ||
137 | // Wir checken mal, ob wir eine EndToEnd-ID haben. Falls ja, tragen wir die gleich | |
138 | // in das dedizierte Feld ein | |
139 | final String eref = clean(VerwendungszweckUtil.getTag(umsatz,Tag.EREF)); | |
140 | if (eref != null && eref.length() > 0) | |
141 | umsatz.setEndToEndId(eref); | |
142 | } | |
127 | 143 | // |
128 | 144 | //////////////////////////////////////////////////////////////////////////// |
129 | 145 | |
198 | 214 | } |
199 | 215 | |
200 | 216 | /** |
217 | * Konvertiert einen einzelnen Umsatz von Hibiscus nach HBCI4Java. | |
218 | * @param u der zu convertierende Umsatz. | |
219 | * @return das neu erzeugte Umsatz-Objekt. | |
220 | * @throws RemoteException | |
221 | */ | |
222 | public static UmsLine HibiscusUmsatz2HBCIUmsatz(Umsatz u) throws RemoteException | |
223 | { | |
224 | final UmsLine line = new UmsLine(); | |
225 | ||
226 | final de.willuhn.jameica.hbci.rmi.Konto k = u.getKonto(); | |
227 | ||
228 | final String iban = u.getGegenkontoNummer(); | |
229 | final String bic = u.getGegenkontoBLZ(); | |
230 | final boolean isSepa = iban != null && iban.length() > HBCIProperties.HBCI_KTO_MAXLENGTH_HARD; | |
231 | final Konto other = new Konto(); | |
232 | other.name = u.getGegenkontoName(); | |
233 | if (isSepa) | |
234 | { | |
235 | other.iban = iban; | |
236 | other.bic = bic; | |
237 | } | |
238 | else | |
239 | { | |
240 | other.number = iban; | |
241 | other.blz = bic; | |
242 | } | |
243 | ||
244 | line.addkey = u.getAddKey(); | |
245 | line.bdate = u.getDatum(); | |
246 | line.customerref = u.getCustomerRef(); | |
247 | line.gvcode = u.getGvCode(); | |
248 | line.id = u.getTransactionId(); | |
249 | line.isCamt = line.id != null && line.id.length() > 0; | |
250 | line.isSepa = isSepa; | |
251 | line.isStorno = false; | |
252 | line.other = other; | |
253 | line.primanota = u.getPrimanota(); | |
254 | line.purposecode = u.getPurposeCode(); | |
255 | line.saldo = new Saldo(); | |
256 | line.saldo.timestamp = u.getDatum(); | |
257 | line.saldo.value = new Value(new BigDecimal(u.getSaldo()),k.getWaehrung()); | |
258 | line.text = u.getArt(); | |
259 | line.usage = Arrays.asList(VerwendungszweckUtil.toArray(u)); | |
260 | line.value = new Value(new BigDecimal(u.getBetrag()),k.getWaehrung()); | |
261 | line.valuta = u.getValuta(); | |
262 | ||
263 | return line; | |
264 | } | |
265 | ||
266 | /** | |
201 | 267 | * Entfernt Zeichen, die in den Strings nicht enthalten sein sollten. |
202 | 268 | * Typischerweise Zeilenumbrueche. |
203 | 269 | * @param s der String. |
435 | 501 | return e; |
436 | 502 | } |
437 | 503 | |
438 | /** | |
439 | * Konvertiert eine Sammel-Ueberweisung in DTAUS-Format. | |
440 | * @param su Sammel-Ueberweisung. | |
441 | * @return DTAUS-Repraesentation. | |
442 | * @throws RemoteException | |
443 | */ | |
444 | public static DTAUS HibiscusSammelUeberweisung2DTAUS(SammelUeberweisung su) throws RemoteException | |
445 | { | |
446 | // TYPE_CREDIT = Sammelüberweisung | |
447 | // TYPE_DEBIT = Sammellastschrift | |
448 | return HibiscusSammelTransfer2DTAUS(su, DTAUS.TYPE_CREDIT); | |
449 | } | |
450 | ||
451 | /** | |
452 | * Konvertiert eine Sammel-Lastschrift in DTAUS-Format. | |
453 | * @param sl Sammel-Lastschrift. | |
454 | * @return DTAUS-Repraesentation. | |
455 | * @throws RemoteException | |
456 | */ | |
457 | public static DTAUS HibiscusSammelLastschrift2DTAUS(SammelLastschrift sl) throws RemoteException | |
458 | { | |
459 | // TYPE_CREDIT = Sammelüberweisung | |
460 | // TYPE_DEBIT = Sammellastschrift | |
461 | return HibiscusSammelTransfer2DTAUS(sl, DTAUS.TYPE_DEBIT); | |
462 | } | |
463 | ||
464 | /** | |
465 | * Hilfsfunktion. Ist private, damit niemand aus Versehen den falschen Type angibt. | |
466 | * @param s Sammel-Transfer. | |
467 | * @param type Art des Transfers. | |
468 | * @see DTAUS#TYPE_CREDIT | |
469 | * @see DTAUS#TYPE_DEBIT | |
470 | * @return DTAUS-Repraesentation. | |
471 | * @throws RemoteException | |
472 | */ | |
473 | private static DTAUS HibiscusSammelTransfer2DTAUS(SammelTransfer s, int type) throws RemoteException | |
474 | { | |
475 | ||
476 | DTAUS dtaus = new DTAUS(HibiscusKonto2HBCIKonto(s.getKonto()),type); | |
477 | DBIterator buchungen = s.getBuchungen(); | |
478 | SammelTransferBuchung b = null; | |
479 | while (buchungen.hasNext()) | |
480 | { | |
481 | b = (SammelTransferBuchung) buchungen.next(); | |
482 | final DTAUS.Transaction tr = dtaus.new Transaction(); | |
483 | ||
484 | Konto other = new Konto("DE",b.getGegenkontoBLZ(),b.getGegenkontoNummer()); | |
485 | other.name = b.getGegenkontoName(); | |
486 | ||
487 | tr.otherAccount = other; | |
488 | tr.value = new Value(String.valueOf(b.getBetrag())); | |
489 | ||
490 | String key = b.getTextSchluessel(); | |
491 | if (key != null && key.length() > 0) | |
492 | tr.key = key; // Nur setzen, wenn in der Buchung definiert. Gibt sonst in DTAUS#toString eine NPE | |
493 | ||
494 | String[] lines = VerwendungszweckUtil.toArray(b); | |
495 | for (String line:lines) | |
496 | { | |
497 | tr.addUsage(line); | |
498 | } | |
499 | ||
500 | dtaus.addEntry(tr); | |
501 | } | |
502 | return dtaus; | |
503 | } | |
504 | ||
505 | 504 | } |
40 | 40 | /** |
41 | 41 | * Prefix fuer BPDs. |
42 | 42 | */ |
43 | BPD("bpd",new HashSet(Arrays.asList("DauerSEPAEditPar","KontoauszugPar","KontoauszugPdfPar"))), | |
43 | BPD("bpd",new HashSet(Arrays.asList("DauerSEPAEditPar","KontoauszugPar","KontoauszugPdfPar","KUmsZeitCamtPar"))), | |
44 | 44 | |
45 | 45 | /** |
46 | 46 | * Prefix fuer UPDs. |
13 | 13 | import java.rmi.RemoteException; |
14 | 14 | import java.util.Date; |
15 | 15 | |
16 | import de.willuhn.datasource.BeanUtil; | |
17 | import de.willuhn.datasource.GenericObject; | |
18 | import de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum; | |
16 | 19 | import de.willuhn.jameica.hbci.rmi.Konto; |
17 | 20 | |
18 | 21 | /** |
19 | 22 | * Container fuer die EinnahmeAusgabe-Daten. |
20 | 23 | */ |
21 | ||
22 | public class EinnahmeAusgabe | |
24 | public class EinnahmeAusgabe implements EinnahmeAusgabeZeitraum | |
23 | 25 | { |
24 | 26 | private String text; |
25 | 27 | private double anfangssaldo; |
149 | 151 | } |
150 | 152 | |
151 | 153 | /** |
152 | * Liefert das Start-Datum. | |
153 | * @return das Start-Datum. | |
154 | * @see de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum#getStartdatum() | |
154 | 155 | */ |
155 | 156 | public Date getStartdatum() |
156 | 157 | { |
167 | 168 | } |
168 | 169 | |
169 | 170 | /** |
170 | * Liefert das End-Datum. | |
171 | * @return das End-Datum. | |
171 | * @see de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum#getEnddatum() | |
172 | 172 | */ |
173 | 173 | public Date getEnddatum() |
174 | 174 | { |
201 | 201 | */ |
202 | 202 | public boolean hasDiff() |
203 | 203 | { |
204 | return Math.abs(this.getDifferenz()) >= 0.01; | |
204 | return Math.abs(this.getDifferenz()) >= 0.01d; | |
205 | 205 | } |
206 | 206 | |
207 | 207 | /** |
230 | 230 | { |
231 | 231 | this.isSumme = b; |
232 | 232 | } |
233 | ||
234 | /** | |
235 | * @see de.willuhn.datasource.GenericObject#equals(de.willuhn.datasource.GenericObject) | |
236 | */ | |
237 | @Override | |
238 | public boolean equals(GenericObject arg0) throws RemoteException | |
239 | { | |
240 | return arg0 == this; | |
241 | } | |
242 | ||
243 | /** | |
244 | * @see de.willuhn.datasource.GenericObject#getAttribute(java.lang.String) | |
245 | */ | |
246 | @Override | |
247 | public Object getAttribute(String arg0) throws RemoteException | |
248 | { | |
249 | try | |
250 | { | |
251 | // Wir koennen hier nicht direkt "BeanUtil.get(this,arg0)" aufrufen, | |
252 | // da EinnahmeAusgabe selbst ja ein GenericObject ist und "BeanUtil.get()" | |
253 | // in dem Fall intern wieder "this.getAttribute(arg0)" aufrufen wuerde. | |
254 | // Das gaebe eine Endlos-Rekursion. | |
255 | return BeanUtil.invoke(this,BeanUtil.toGetMethod(arg0),null); | |
256 | } | |
257 | catch (RemoteException re) | |
258 | { | |
259 | throw re; | |
260 | } | |
261 | catch (Exception e) | |
262 | { | |
263 | throw new RemoteException("unable to get value for attribute " + arg0,e); | |
264 | } | |
265 | } | |
266 | ||
267 | /** | |
268 | * @see de.willuhn.datasource.GenericObject#getAttributeNames() | |
269 | */ | |
270 | @Override | |
271 | public String[] getAttributeNames() throws RemoteException | |
272 | { | |
273 | return new String[] { | |
274 | "text", | |
275 | "anfangssaldo", | |
276 | "einnahmen", | |
277 | "ausgaben", | |
278 | "endsaldo", | |
279 | "startdatum", | |
280 | "enddatum" | |
281 | }; | |
282 | ||
283 | } | |
284 | ||
285 | /** | |
286 | * @see de.willuhn.datasource.GenericObject#getID() | |
287 | */ | |
288 | @Override | |
289 | public String getID() throws RemoteException | |
290 | { | |
291 | return null; | |
292 | } | |
293 | ||
294 | /** | |
295 | * @see de.willuhn.datasource.GenericObject#getPrimaryAttribute() | |
296 | */ | |
297 | @Override | |
298 | public String getPrimaryAttribute() throws RemoteException | |
299 | { | |
300 | return "text"; | |
301 | } | |
302 | ||
303 | /** | |
304 | * @see java.lang.Object#toString() | |
305 | */ | |
306 | @Override | |
307 | public String toString() | |
308 | { | |
309 | return this.text + ":" + | |
310 | this.anfangssaldo + ":" + | |
311 | this.einnahmen + ":" + | |
312 | this.ausgaben + ":" + | |
313 | this.endsaldo + ":" + | |
314 | this.getPlusminus() + ":" + | |
315 | this.getDifferenz(); | |
316 | } | |
233 | 317 | } |
234 | ||
235 | /******************************************************************************* | |
236 | * $Log: EinnahmeAusgabe.java,v $ | |
237 | * Revision 1.1 2010/08/24 17:38:04 willuhn | |
238 | * @N BUGZILLA 896 | |
239 | * | |
240 | * Revision 1.5 2010/06/07 22:41:13 willuhn | |
241 | * @N BUGZILLA 844/852 | |
242 | * | |
243 | * Revision 1.4 2010/04/06 22:49:54 willuhn | |
244 | * @B BUGZILLA 844 | |
245 | * | |
246 | * Revision 1.3 2010/02/17 10:43:41 willuhn | |
247 | * @N Differenz in Einnahmen/Ausgaben anzeigen, Cleanup | |
248 | ******************************************************************************/ |
0 | package de.willuhn.jameica.hbci.server; | |
1 | ||
2 | import java.rmi.RemoteException; | |
3 | import java.util.Date; | |
4 | import java.util.List; | |
5 | ||
6 | import de.willuhn.datasource.GenericIterator; | |
7 | import de.willuhn.datasource.GenericObject; | |
8 | import de.willuhn.datasource.GenericObjectNode; | |
9 | import de.willuhn.datasource.pseudo.PseudoIterator; | |
10 | import de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum; | |
11 | import de.willuhn.jameica.util.DateUtil; | |
12 | ||
13 | /** | |
14 | * Container für die EinnahmenAusgaben-Liste eines bestimmten Zeitraums. | |
15 | */ | |
16 | public class EinnahmeAusgabeTreeNode implements EinnahmeAusgabeZeitraum, GenericObjectNode | |
17 | { | |
18 | ||
19 | private Date startdatum; | |
20 | private Date enddatum; | |
21 | private List<EinnahmeAusgabe> children; | |
22 | ||
23 | /** | |
24 | * @param from Startdatum des Zeitraums | |
25 | * @param to Enddatum des Zeitraums | |
26 | * @param children Liste der EinnameAusgabe-Daten für diesen Zeitraum | |
27 | */ | |
28 | public EinnahmeAusgabeTreeNode(Date from, Date to, List<EinnahmeAusgabe> children) | |
29 | { | |
30 | this.startdatum = from; | |
31 | this.enddatum = to; | |
32 | this.children = children; | |
33 | } | |
34 | ||
35 | /** | |
36 | * @see de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum#getStartdatum() | |
37 | */ | |
38 | @Override | |
39 | public Date getStartdatum() | |
40 | { | |
41 | return this.startdatum; | |
42 | } | |
43 | ||
44 | /** | |
45 | * @see de.willuhn.jameica.hbci.rmi.EinnahmeAusgabeZeitraum#getEnddatum() | |
46 | */ | |
47 | @Override | |
48 | public Date getEnddatum() | |
49 | { | |
50 | return this.enddatum; | |
51 | } | |
52 | ||
53 | /** | |
54 | * @see de.willuhn.datasource.GenericObject#equals(de.willuhn.datasource.GenericObject) | |
55 | */ | |
56 | @Override | |
57 | public boolean equals(GenericObject arg0) throws RemoteException | |
58 | { | |
59 | return this == arg0; | |
60 | } | |
61 | ||
62 | /** | |
63 | * @see de.willuhn.datasource.GenericObject#getAttribute(java.lang.String) | |
64 | */ | |
65 | @Override | |
66 | public Object getAttribute(String arg0) throws RemoteException | |
67 | { | |
68 | if("text".equals(arg0)) | |
69 | return DateUtil.DEFAULT_FORMAT.format(this.startdatum) + " - " + DateUtil.DEFAULT_FORMAT.format(this.enddatum); | |
70 | ||
71 | if ("startdatum".equals(arg0)) | |
72 | return this.startdatum; | |
73 | ||
74 | if ("enddatum".equals(arg0)) | |
75 | return this.enddatum; | |
76 | ||
77 | if ("children".equals(arg0)) | |
78 | return this.children; | |
79 | ||
80 | return null; | |
81 | } | |
82 | ||
83 | /** | |
84 | * @see de.willuhn.datasource.GenericObject#getAttributeNames() | |
85 | */ | |
86 | @Override | |
87 | public String[] getAttributeNames() throws RemoteException | |
88 | { | |
89 | return new String[]{"text","startdatum","enddatum","children"}; | |
90 | } | |
91 | ||
92 | /** | |
93 | * @see de.willuhn.datasource.GenericObject#getID() | |
94 | */ | |
95 | @Override | |
96 | public String getID() throws RemoteException | |
97 | { | |
98 | return null; | |
99 | } | |
100 | ||
101 | /** | |
102 | * @see de.willuhn.datasource.GenericObject#getPrimaryAttribute() | |
103 | */ | |
104 | @Override | |
105 | public String getPrimaryAttribute() throws RemoteException | |
106 | { | |
107 | return "text"; | |
108 | } | |
109 | ||
110 | /** | |
111 | * @see de.willuhn.datasource.GenericObjectNode#getChildren() | |
112 | */ | |
113 | @Override | |
114 | public GenericIterator getChildren() throws RemoteException | |
115 | { | |
116 | return PseudoIterator.fromArray((EinnahmeAusgabe[]) children.toArray(new EinnahmeAusgabe[children.size()])); | |
117 | } | |
118 | ||
119 | /** | |
120 | * @see de.willuhn.datasource.GenericObjectNode#getParent() | |
121 | */ | |
122 | @Override | |
123 | public GenericObjectNode getParent() throws RemoteException | |
124 | { | |
125 | return null; | |
126 | } | |
127 | ||
128 | /** | |
129 | * @see de.willuhn.datasource.GenericObjectNode#getPath() | |
130 | */ | |
131 | @Override | |
132 | public GenericIterator getPath() throws RemoteException | |
133 | { | |
134 | throw new UnsupportedOperationException(); | |
135 | } | |
136 | ||
137 | /** | |
138 | * @see de.willuhn.datasource.GenericObjectNode#getPossibleParents() | |
139 | */ | |
140 | @Override | |
141 | public GenericIterator getPossibleParents() throws RemoteException | |
142 | { | |
143 | throw new UnsupportedOperationException(); | |
144 | } | |
145 | ||
146 | /** | |
147 | * @see de.willuhn.datasource.GenericObjectNode#hasChild(de.willuhn.datasource.GenericObjectNode) | |
148 | */ | |
149 | @Override | |
150 | public boolean hasChild(GenericObjectNode arg0) throws RemoteException | |
151 | { | |
152 | if (!(arg0 instanceof EinnahmeAusgabe)) | |
153 | return false; | |
154 | ||
155 | return this.children.contains((EinnahmeAusgabe)arg0); | |
156 | } | |
157 | }⏎ |
162 | 162 | } |
163 | 163 | } |
164 | 164 | |
165 | Logger.info("init update provider"); | |
166 | UpdateProvider provider = new HBCIUpdateProvider(getConnection(),version); | |
167 | Updater updater = new Updater(provider,"iso-8859-1"); | |
168 | updater.execute(); | |
169 | Logger.info("updates finished"); | |
165 | try | |
166 | { | |
167 | Logger.info("init update provider"); | |
168 | UpdateProvider provider = new HBCIUpdateProvider(getConnection(),version); | |
169 | Updater updater = new Updater(provider,"iso-8859-1"); | |
170 | updater.execute(); | |
171 | Logger.info("updates finished"); | |
172 | } | |
173 | catch (Exception e) | |
174 | { | |
175 | // Wir versuchen herauszufinden, ob es dieses Problem hier ist: | |
176 | // https://homebanking-hilfe.de/forum/topic.php?p=139423#real139423 | |
177 | // Siehe auch https://www.h2database.com/javadoc/org/h2/api/ErrorCode.html#c90131 | |
178 | Throwable t = e; | |
179 | ||
180 | for (int i=0;i<10;++i) | |
181 | { | |
182 | if (t == null) | |
183 | break; | |
184 | ||
185 | if (t instanceof SQLException) | |
186 | { | |
187 | SQLException se = (SQLException) t; | |
188 | int code = se.getErrorCode(); | |
189 | if (code == 90131) | |
190 | { | |
191 | Logger.error("found buggy h2 driver, update jameica first",e); | |
192 | ||
193 | I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); | |
194 | throw new ApplicationException(i18n.tr("Bitte aktualisiere erst Jameica auf Version 2.8.2 oder höher")); | |
195 | } | |
196 | } | |
197 | t = t.getCause(); | |
198 | } | |
199 | ||
200 | // Keine passende Exception gefunden. Dann Original weiterwerfen. | |
201 | throw new ApplicationException(e); | |
202 | } | |
170 | 203 | } |
171 | 204 | |
172 | 205 |
106 | 106 | } |
107 | 107 | if (bank != null && bank.length() > 0) |
108 | 108 | { |
109 | HBCIProperties.checkLength(bank, HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
109 | HBCIProperties.checkLength(bank, HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
110 | 110 | } |
111 | 111 | // |
112 | 112 | ////////////////////////////////////////////////////////////////////////// |
21 | 21 | import de.willuhn.datasource.rmi.DBIterator; |
22 | 22 | import de.willuhn.datasource.rmi.DBService; |
23 | 23 | import de.willuhn.datasource.rmi.ResultSetExtractor; |
24 | import de.willuhn.jameica.hbci.MetaKey; | |
24 | 25 | import de.willuhn.jameica.hbci.Settings; |
26 | import de.willuhn.jameica.hbci.gui.dialogs.CamtSetupDialog; | |
25 | 27 | import de.willuhn.jameica.hbci.gui.filter.KontoFilter; |
26 | 28 | import de.willuhn.jameica.hbci.rmi.HBCIDBService; |
27 | 29 | import de.willuhn.jameica.hbci.rmi.Konto; |
28 | 30 | import de.willuhn.jameica.hbci.rmi.Umsatz; |
31 | import de.willuhn.jameica.hbci.server.BPDUtil.Query; | |
32 | import de.willuhn.jameica.hbci.server.BPDUtil.Support; | |
33 | import de.willuhn.jameica.system.Application; | |
34 | import de.willuhn.jameica.system.OperationCanceledException; | |
29 | 35 | import de.willuhn.jameica.util.DateUtil; |
36 | import de.willuhn.logging.Logger; | |
30 | 37 | |
31 | 38 | /** |
32 | 39 | * Hilfsklasse mit statischen Funktionen fuer Konten. |
110 | 117 | |
111 | 118 | return null; |
112 | 119 | } |
120 | ||
121 | /** | |
122 | * Prueft, ob die Umsaetze eines Kontos per CAMT abgerufen werden sollen. | |
123 | * @param k das zu pruefende Konto. | |
124 | * @param ask true, wenn der User hier auch gefragt werden darf, falls er die Entscheidung noch nicht getroffen hat. | |
125 | * @return true, wenn CAMT verwendet werden soll. | |
126 | */ | |
127 | public static boolean useCamt(Konto k, boolean ask) | |
128 | { | |
129 | if (k == null) | |
130 | { | |
131 | Logger.warn("unable to check if CAMT is supported, no account given"); | |
132 | return false; | |
133 | } | |
134 | try | |
135 | { | |
136 | // Erstmal checken, ob wir grundsaetzlich Support fuer CAMT haben | |
137 | Logger.debug("checking if account supports CAMT"); | |
138 | Support support = BPDUtil.getSupport(k,Query.UmsatzCamt); | |
139 | if (support == null) | |
140 | { | |
141 | Logger.debug("unable to determine CAMT support"); | |
142 | return false; | |
143 | } | |
144 | ||
145 | if (!support.isSupported()) | |
146 | { | |
147 | Logger.debug("account does not support CAMT"); | |
148 | return false; | |
149 | } | |
150 | ||
151 | // Also grundsaetzlich haben wir Support. | |
152 | // Jetzt checken, wir, was fuer das Konto konfiguriert ist. | |
153 | String value = StringUtils.trimToNull(MetaKey.UMSATZ_CAMT.get(k)); | |
154 | ||
155 | // Wenn ein Wert drin steht, hat sich der User entschieden, dann halten wir uns dran | |
156 | if (value != null) | |
157 | { | |
158 | Logger.debug("CAMT usage configured as: " + value); | |
159 | return Boolean.valueOf(value); | |
160 | } | |
161 | ||
162 | // Wenn als Wert noch nichts drin steht, dann hat der User es noch nicht konfigutiert. In dem Fall entscheiden | |
163 | // wir erstmal basierend auf den vorhandenen Umsaetzen. Wenn das Konto noch keine Umsaetze hat, verwenden wir | |
164 | // CAMT und speichern das auch als Wert. Damit wird kuenftig bei neuen Usern automatisch CAMT verwendet. | |
165 | // Wenn es Umsaetze hat, fragen wir den User, ob er umstellen moechte. | |
166 | if (k.getNumUmsaetze() == 0) | |
167 | { | |
168 | Logger.debug("account does not have bookings yet, auto-activating CAMT"); | |
169 | MetaKey.UMSATZ_CAMT.set(k,Boolean.TRUE.toString()); | |
170 | return true; | |
171 | } | |
172 | ||
173 | if (!ask) | |
174 | { | |
175 | Logger.debug("CAMT support available but not yet activated"); | |
176 | return false; | |
177 | } | |
178 | ||
179 | // Wenn wir keine UI haben, koennen wir den User aber nicht fragen | |
180 | if (Application.inServerMode()) | |
181 | { | |
182 | Logger.debug("running in server mode, user cannot be asked if CAMT shall be used"); | |
183 | return false; | |
184 | } | |
185 | ||
186 | Logger.debug("asking user if CAMT shall be used"); | |
187 | CamtSetupDialog d = new CamtSetupDialog(k); | |
188 | Boolean b = (Boolean) d.open(); | |
189 | Logger.debug("user answered for CAMT: " + b); | |
190 | return b != null ? b.booleanValue() : false; | |
191 | } | |
192 | catch (OperationCanceledException oce) | |
193 | { | |
194 | Logger.debug("operation cancelled"); | |
195 | return false; | |
196 | } | |
197 | catch (Exception e) | |
198 | { | |
199 | Logger.error("unable to check if account supports CAMT",e); | |
200 | return false; | |
201 | } | |
202 | } | |
203 | ||
113 | 204 | |
114 | 205 | /** |
115 | 206 | * Sucht das Konto in der Datenbank. |
36 | 36 | import de.willuhn.jameica.hbci.Settings; |
37 | 37 | import de.willuhn.jameica.hbci.messaging.MessagingAvailableConsumer; |
38 | 38 | import de.willuhn.jameica.hbci.messaging.ObjectChangedMessage; |
39 | import de.willuhn.jameica.hbci.messaging.ObjectDeletedMessage; | |
39 | 40 | import de.willuhn.jameica.hbci.rmi.HBCIDBService; |
40 | 41 | import de.willuhn.jameica.hbci.rmi.Konto; |
41 | 42 | import de.willuhn.jameica.hbci.rmi.Kontoauszug; |
597 | 598 | Konto konto = k.getKonto(); |
598 | 599 | konto.addToProtokoll(i18n.tr("Elektronischen Kontoauszug gelöscht"),Protokoll.TYP_SUCCESS); |
599 | 600 | k.delete(); |
601 | Application.getMessagingFactory().sendMessage(new ObjectDeletedMessage(k)); | |
600 | 602 | count++; |
601 | 603 | } |
602 | 604 |
134 | 134 | |
135 | 135 | if (StringUtils.trimToNull(getGegenkontoName()) == null) |
136 | 136 | throw new ApplicationException(i18n.tr("Bitte geben Sie den Namen des Kontoinhabers des Gegenkontos ein")); |
137 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
137 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
138 | 138 | HBCIProperties.checkChars(getGegenkontoName(), HBCIProperties.HBCI_SEPA_VALIDCHARS); |
139 | 139 | |
140 | 140 | String zweck = this.getZweck(); |
141 | 141 | if (zweck == null || zweck.length() == 0) |
142 | 142 | throw new ApplicationException(i18n.tr("Bitte geben Sie einen Verwendungszweck ein")); |
143 | 143 | |
144 | HBCIProperties.checkLength(zweck, HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
144 | HBCIProperties.checkLength(zweck, HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
145 | 145 | HBCIProperties.checkChars(zweck, HBCIProperties.HBCI_SEPA_VALIDCHARS); |
146 | 146 | |
147 | 147 | HBCIProperties.checkLength(getEndtoEndId(), HBCIProperties.HBCI_SEPA_ENDTOENDID_MAXLENGTH); |
136 | 136 | |
137 | 137 | if (StringUtils.trimToNull(getGegenkontoName()) == null) |
138 | 138 | throw new ApplicationException(i18n.tr("Bitte geben Sie den Namen des Kontoinhabers des Gegenkontos ein")); |
139 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
139 | HBCIProperties.checkLength(getGegenkontoName(), HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
140 | 140 | HBCIProperties.checkChars(getGegenkontoName(), HBCIProperties.HBCI_SEPA_VALIDCHARS); |
141 | 141 | |
142 | HBCIProperties.checkLength(getZweck(), HBCIProperties.HBCI_FOREIGNTRANSFER_USAGE_MAXLENGTH); | |
142 | HBCIProperties.checkLength(getZweck(), HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
143 | 143 | HBCIProperties.checkChars(getZweck(), HBCIProperties.HBCI_SEPA_VALIDCHARS); |
144 | 144 | |
145 | 145 | HBCIProperties.checkLength(getEndtoEndId(), HBCIProperties.HBCI_SEPA_ENDTOENDID_MAXLENGTH); |
76 | 76 | if (getValuta() == null) |
77 | 77 | throw new ApplicationException(i18n.tr("Valuta fehlt.")); |
78 | 78 | |
79 | // "35" ist das DB-Limit | |
80 | int limit = HBCIProperties.HBCI_TRANSFER_USAGE_DB_MAXLENGTH; | |
81 | HBCIProperties.checkLength(getZweck(),limit); | |
79 | HBCIProperties.checkLength(getZweck(),HBCIProperties.HBCI_SEPATRANSFER_USAGE_MAXLENGTH); | |
80 | ||
81 | int limit = HBCIProperties.HBCI_TRANSFER_USAGE_DB_MAXLENGTH; | |
82 | 82 | HBCIProperties.checkLength(getZweck2(),limit); |
83 | 83 | String[] ewz = getWeitereVerwendungszwecke(); |
84 | 84 | if (ewz != null && ewz.length > 0) |
91 | 91 | |
92 | 92 | HBCIProperties.checkLength(this.getGvCode(),HBCIProperties.HBCI_GVCODE_MAXLENGTH); |
93 | 93 | HBCIProperties.checkLength(this.getAddKey(),HBCIProperties.HBCI_ADDKEY_MAXLENGTH); |
94 | ||
95 | // Bei TX-ID und PurposeCode muessen wir die Laenge nicht checken. Das sind CAMT-Umsaetze. | |
96 | // Und die kommen schema-validiert im XML-Format. Hier extra nochmal zu pruefen, waere redundant. | |
97 | // Zumal die korrespondierenden Datebank-Felder vorsorglich ohnehin deutlich laenger definiert | |
98 | // sind als es das Schema zulaesst | |
94 | 99 | } |
95 | 100 | catch (RemoteException e) |
96 | 101 | { |
113 | 118 | { |
114 | 119 | // Wir speichern die Checksumme nun grundsaetzlich beim |
115 | 120 | // Anlegen des Datensatzes. Dann koennen wir anschliessend |
116 | // beliebig aendern und muessens uns nicht mehr mit | |
121 | // beliebig aendern und muessen uns nicht mehr mit | |
117 | 122 | // "hasChangedByUser" herumschlagen |
118 | 123 | setAttribute("checksum",new Long(getChecksum())); |
119 | 124 | super.insert(); |
303 | 308 | String id2 = other.getID(); |
304 | 309 | if (id1 != null && id2 != null) |
305 | 310 | return id1.equals(id2); |
306 | ||
311 | ||
312 | // Wenn beide eine TX-ID haben, brauchen wir nur anhand der TX-ID vergleichen. | |
313 | id1 = this.getTransactionId(); | |
314 | id2 = other.getTransactionId(); | |
315 | if (id1 != null && id2 != null) | |
316 | return id1.equals(id2); | |
317 | ||
307 | 318 | return other.getChecksum() == getChecksum(); |
308 | 319 | } |
309 | 320 | catch (Exception e) |
406 | 417 | sv = valuta.toString(); |
407 | 418 | } |
408 | 419 | } |
409 | ||
420 | ||
410 | 421 | String s = (""+getArt()).toUpperCase() + |
411 | 422 | getKonto().getID() + // wenigstens die ID vom Konto muss mit rein. Andernfalls haben zwei gleich aussehende Umsaetze auf verschiedenen Konten die gleiche Checksumme |
412 | getBetrag() + | |
413 | getCustomerRef() + | |
414 | getGegenkontoBLZ() + | |
415 | getGegenkontoNummer() + | |
416 | (""+getGegenkontoName()).toUpperCase() + | |
417 | getPrimanota() + | |
423 | getBetrag() + | |
424 | getCustomerRef() + | |
425 | getGegenkontoBLZ() + | |
426 | getGegenkontoNummer() + | |
427 | (""+getGegenkontoName()).toUpperCase() + | |
428 | getPrimanota() + | |
418 | 429 | (Settings.getSaldoInChecksum() ? getSaldo() : "") + |
419 | ((String)getAttribute("mergedzweck")).toUpperCase() + | |
420 | sd + | |
421 | sv; | |
430 | ((String)getAttribute("mergedzweck")).toUpperCase() + | |
431 | sd + | |
432 | sv; | |
422 | 433 | |
423 | 434 | // Bei Vormerkbuchungen haengen wir noch was hinten dran. Da der |
424 | 435 | // Saldo per Default nicht mehr in der Checksumme ist, geht sonst |
743 | 754 | copy.setZweck2(this.getZweck2()); |
744 | 755 | copy.setWeitereVerwendungszwecke(this.getWeitereVerwendungszwecke()); |
745 | 756 | copy.setGvCode(this.getGvCode()); |
757 | copy.setPurposeCode(this.getPurposeCode()); | |
758 | ||
759 | // Das Duplizieren von Umsatzbuchungen machen wir z.Bsp. dann, wenn ein User | |
760 | // per Hand eine Gegenbuchung erzeugt (per Kontextmenu-Eintrag "Gegenbuchung erzeugen auf..."). | |
761 | // Das Duplikat darf nicht die selbe Transaction-ID haben, dann waere sie | |
762 | // nicht mehr eindeutig. Daher wird die TX-ID nicht mit dupliziert | |
763 | // copy.setTransactionId(this.getTransactionId()); | |
764 | ||
746 | 765 | return copy; |
747 | 766 | } |
767 | ||
768 | /** | |
769 | * @see de.willuhn.jameica.hbci.rmi.Umsatz#getTransactionId() | |
770 | */ | |
771 | @Override | |
772 | public String getTransactionId() throws RemoteException | |
773 | { | |
774 | return (String) this.getAttribute("txid"); | |
775 | } | |
776 | ||
777 | /** | |
778 | * @see de.willuhn.jameica.hbci.rmi.Umsatz#setTransactionId(java.lang.String) | |
779 | */ | |
780 | @Override | |
781 | public void setTransactionId(String id) throws RemoteException | |
782 | { | |
783 | this.setAttribute("txid",id); | |
784 | } | |
785 | ||
786 | /** | |
787 | * @see de.willuhn.jameica.hbci.rmi.Umsatz#getPurposeCode() | |
788 | */ | |
789 | @Override | |
790 | public String getPurposeCode() throws RemoteException | |
791 | { | |
792 | return (String) this.getAttribute("purposecode"); | |
793 | } | |
794 | ||
795 | /** | |
796 | * @see de.willuhn.jameica.hbci.rmi.Umsatz#setPurposeCode(java.lang.String) | |
797 | */ | |
798 | @Override | |
799 | public void setPurposeCode(String code) throws RemoteException | |
800 | { | |
801 | this.setAttribute("purposecode",code); | |
802 | } | |
803 | ||
804 | /** | |
805 | * @see de.willuhn.jameica.hbci.rmi.Umsatz#getEndToEndId() | |
806 | */ | |
807 | @Override | |
808 | public String getEndToEndId() throws RemoteException | |
809 | { | |
810 | return (String) this.getAttribute("endtoendid"); | |
811 | } | |
812 | ||
813 | /** | |
814 | * @see de.willuhn.jameica.hbci.rmi.Umsatz#setEndToEndId(java.lang.String) | |
815 | */ | |
816 | @Override | |
817 | public void setEndToEndId(String id) throws RemoteException | |
818 | { | |
819 | this.setAttribute("endtoendid",id); | |
820 | } | |
748 | 821 | } |
749 | ||
750 | ||
751 | /********************************************************************** | |
752 | * $Log: UmsatzImpl.java,v $ | |
753 | * Revision 1.92 2012/05/03 21:50:47 willuhn | |
754 | * @B BUGZILLA 1232 - Saldo des Kontos bei Offline-Konten nur bei neuen Umsaetzen uebernehmen - nicht beim Bearbeiten existierender | |
755 | * | |
756 | * Revision 1.91 2012/04/29 19:32:07 willuhn | |
757 | * @N Reihenfolge der Kategorien bei der Zuordnung beachten | |
758 | * | |
759 | * Revision 1.90 2012/04/05 21:44:18 willuhn | |
760 | * @B BUGZILLA 1219 | |
761 | * | |
762 | * Revision 1.89 2011/10/18 09:28:14 willuhn | |
763 | * @N Gemeinsames Basis-Interface "HibiscusDBObject" fuer alle Entities (ausser Version und DBProperty) mit der Implementierung "AbstractHibiscusDBObject". Damit koennen jetzt zu jedem Fachobjekt beliebige Meta-Daten in der Datenbank gespeichert werden. Wird im ersten Schritt fuer die Reminder verwendet, um zu einem Auftrag die UUID des Reminders am Objekt speichern zu koennen | |
764 | * | |
765 | * Revision 1.88 2011-07-25 17:17:19 willuhn | |
766 | * @N BUGZILLA 1065 - zusaetzlich noch addkey | |
767 | * | |
768 | * Revision 1.87 2011-07-25 14:42:40 willuhn | |
769 | * @N BUGZILLA 1065 | |
770 | * | |
771 | * Revision 1.86 2011-04-28 12:15:25 willuhn | |
772 | * @N Wenn beide Umsaetze eine ID haben, muss nur anhand derer verglichen werden | |
773 | * | |
774 | * Revision 1.85 2011-04-28 07:50:07 willuhn | |
775 | * @B BUGZILLA 692 | |
776 | * | |
777 | * Revision 1.84 2011-03-11 15:05:14 willuhn | |
778 | * @C Loeschen von Vormerkbuchungen nicht protokollieren - da Hibiscus die selbst loescht und das irritierende Protokoll-Meldungen fuer den User erzeugt | |
779 | * | |
780 | * Revision 1.83 2010-11-19 17:02:06 willuhn | |
781 | * @N VWZUtil#toString | |
782 | * | |
783 | * Revision 1.82 2010-09-28 21:40:27 willuhn | |
784 | * @C Vormerkbuchungen haben eine andere Checksumme als valutierte Buchungen - auch, wenn sie sonst identisch sind | |
785 | * | |
786 | * Revision 1.81 2010-09-27 11:51:38 willuhn | |
787 | * @N BUGZILLA 804 | |
788 | * | |
789 | * Revision 1.80 2010-08-30 14:25:37 willuhn | |
790 | * @B NPE, wenn Konto angegeben, jedoch ohne ID | |
791 | * | |
792 | * Revision 1.79 2010-08-27 09:24:58 willuhn | |
793 | * @B Generics-Deklaration im Cache hat javac nicht akzeptiert (der Eclipse-Compiler hats komischerweise gefressen) | |
794 | * | |
795 | * Revision 1.78 2010-08-26 12:53:08 willuhn | |
796 | * @N Cache nur befuellen, wenn das explizit gefordert wird. Andernfalls wuerde der Cache u.U. unnoetig gefuellt werden, obwohl nur ein Objekt daraus geloescht werden soll | |
797 | * | |
798 | * Revision 1.77 2010-08-26 11:31:23 willuhn | |
799 | * @N Neuer Cache. In dem werden jetzt die zugeordneten Konten von Auftraegen und Umsaetzen zwischengespeichert sowie die Umsatz-Kategorien. Das beschleunigt das Laden der Umsaetze und Auftraege teilweise erheblich | |
800 | * | |
801 | * Revision 1.76 2010-08-03 11:00:01 willuhn | |
802 | * @N Konto-ID mit in Checksumme | |
803 | * | |
804 | * Revision 1.75 2010-06-17 15:31:27 willuhn | |
805 | * @C BUGZILLA 622 - Defaultwert des checksum.saldo-Parameters geaendert - steht jetzt per Default auf false, sodass der Saldo NICHT mit in die Checksumme einfliesst | |
806 | * @B BUGZILLA 709 - Konto ist nun ENDLICH nicht mehr Bestandteil der Checksumme, dafuer sind jetzt alle Verwendungszweck-Zeilen drin | |
807 | * | |
808 | * Revision 1.74 2010/05/30 23:29:31 willuhn | |
809 | * @N Alle Verwendungszweckzeilen in Umsatzlist und -tree anzeigen (BUGZILLA 782) | |
810 | * | |
811 | * Revision 1.73 2010/05/06 22:08:45 willuhn | |
812 | * @N BUGZILLA 622 | |
813 | * | |
814 | * Revision 1.72 2010/04/27 11:02:32 willuhn | |
815 | * @R Veralteten Verwendungszweck-Code entfernt | |
816 | * | |
817 | * Revision 1.71 2010/04/22 12:42:03 willuhn | |
818 | * @N Erste Version des Supports fuer Offline-Konten | |
819 | * | |
820 | * Revision 1.70 2010/03/16 00:44:18 willuhn | |
821 | * @N Komplettes Redesign des CSV-Imports. | |
822 | * - Kann nun erheblich einfacher auch fuer andere Datentypen (z.Bsp.Ueberweisungen) verwendet werden | |
823 | * - Fehlertoleranter | |
824 | * - Mehrfachzuordnung von Spalten (z.Bsp. bei erweitertem Verwendungszweck) moeglich | |
825 | * - modulare Deserialisierung der Werte | |
826 | * - CSV-Exports von Hibiscus koennen nun 1:1 auch wieder importiert werden (Import-Preset identisch mit Export-Format) | |
827 | * - Import-Preset wird nun im XML-Format nach ~/.jameica/hibiscus/csv serialisiert. Damit wird es kuenftig moeglich sein, | |
828 | * CSV-Import-Profile vorzukonfigurieren und anschliessend zu exportieren, um sie mit anderen Usern teilen zu koennen | |
829 | * | |
830 | * Revision 1.69 2010/01/18 22:59:05 willuhn | |
831 | * @B BUGZILLA 808 | |
832 | * | |
833 | * Revision 1.68 2009/10/29 22:52:05 willuhn | |
834 | * *** empty log message *** | |
835 | * | |
836 | * Revision 1.67 2009/09/15 00:23:35 willuhn | |
837 | * @N BUGZILLA 745 | |
838 | * | |
839 | * Revision 1.66 2009/03/12 10:56:01 willuhn | |
840 | * @B Double.NaN geht nicht | |
841 | * | |
842 | * Revision 1.65 2009/03/11 17:53:12 willuhn | |
843 | * *** empty log message *** | |
844 | * | |
845 | * Revision 1.64 2009/02/23 17:01:58 willuhn | |
846 | * @C Kein Abgleichen mehr bei vorgemerkten Buchungen sondern stattdessen vorgemerkte loeschen und neu abrufen | |
847 | * | |
848 | * Revision 1.63 2009/02/13 10:52:18 willuhn | |
849 | * @N Verwendungszweck mit in Tiny-Checksum uebernehmen, damit die Buchungen auch dann gefunden werden, wenn das Gegenkonto von der Bank nicht gefuellt wird | |
850 | * | |
851 | * Revision 1.62 2009/02/12 18:37:18 willuhn | |
852 | * @N Erster Code fuer vorgemerkte Umsaetze | |
853 | * | |
854 | * Revision 1.61 2009/02/04 23:06:24 willuhn | |
855 | * @N BUGZILLA 308 - Umsaetze als "geprueft" markieren | |
856 | * | |
857 | * Revision 1.60 2009/01/04 01:32:57 willuhn | |
858 | * @N Laengen-Check - ist jetzt noetig, da Umsaetze nun manuell geaendert werden koennen | |
859 | * | |
860 | * Revision 1.59 2009/01/04 01:25:47 willuhn | |
861 | * @N Checksumme von Umsaetzen wird nun generell beim Anlegen des Datensatzes gespeichert. Damit koennen Umsaetze nun problemlos geaendert werden, ohne mit "hasChangedByUser" checken zu muessen. Die Checksumme bleibt immer erhalten, weil sie in UmsatzImpl#insert() sofort zu Beginn angelegt wird | |
862 | * @N Umsaetze sind nun vollstaendig editierbar | |
863 | * | |
864 | * Revision 1.58 2008/12/14 23:18:35 willuhn | |
865 | * @N BUGZILLA 188 - REFACTORING | |
866 | * | |
867 | * Revision 1.57 2008/12/02 10:52:23 willuhn | |
868 | * @B DecimalInput kann NULL liefern | |
869 | * @B Double.NaN beruecksichtigen | |
870 | * | |
871 | * Revision 1.56 2008/11/26 00:39:36 willuhn | |
872 | * @N Erste Version erweiterter Verwendungszwecke. Muss dringend noch getestet werden. | |
873 | * | |
874 | * Revision 1.55 2008/11/17 23:30:00 willuhn | |
875 | * @C Aufrufe der depeicated BLZ-Funktionen angepasst | |
876 | * | |
877 | * Revision 1.54 2008/09/03 21:29:44 willuhn | |
878 | * @C BUGZILLA 622 - Debug-Ausgaben | |
879 | * | |
880 | * Revision 1.53 2008/04/27 22:22:56 willuhn | |
881 | * @C I18N-Referenzen statisch | |
882 | * | |
883 | * Revision 1.52 2008/02/15 17:39:10 willuhn | |
884 | * @N BUGZILLA 188 Basis-API fuer weitere Zeilen Verwendungszweck. GUI fehlt noch | |
885 | * @N DB-Update 0005. Speichern des Textschluessels bei Sammelauftragsbuchungen in der Datenbank | |
886 | **********************************************************************/⏎ |
285 | 285 | // Erst Ausgaben, dann Einnahmen, dann Rest |
286 | 286 | int thisType = this.typ.getTyp(); |
287 | 287 | int otherType = other.typ.getTyp(); |
288 | if (thisType != otherType) | |
288 | if (thisType != otherType && thisType != UmsatzTyp.TYP_EGAL && otherType != UmsatzTyp.TYP_EGAL) | |
289 | 289 | return thisType < otherType ? -1 : 1; |
290 | 290 | |
291 | 291 | String n1 = this.typ.getNummer(); if (n1 == null) n1 = ""; |
267 | 267 | return false; |
268 | 268 | |
269 | 269 | String zweck = VerwendungszweckUtil.toString(umsatz,""); |
270 | String name = umsatz.getGegenkontoName(); | |
271 | String kto = umsatz.getGegenkontoNummer(); | |
272 | String kom = umsatz.getKommentar(); | |
273 | String art = umsatz.getArt(); | |
274 | ||
275 | if (name == null) name = ""; | |
276 | if (kto == null) kto = ""; | |
277 | if (kom == null) kom = ""; | |
278 | if (art == null) art = ""; | |
279 | ||
270 | String name = StringUtils.trimToEmpty(umsatz.getGegenkontoName()); | |
271 | String kto = StringUtils.trimToEmpty(umsatz.getGegenkontoNummer()); | |
272 | String kom = StringUtils.trimToEmpty(umsatz.getKommentar()); | |
273 | String art = StringUtils.trimToEmpty(umsatz.getArt()); | |
274 | String purp = StringUtils.trimToEmpty(umsatz.getPurposeCode()); | |
275 | ||
280 | 276 | if (!isRegex()) |
281 | 277 | { |
282 | 278 | zweck = zweck.toLowerCase(); |
284 | 280 | kto = kto.toLowerCase(); |
285 | 281 | kom = kom.toLowerCase(); |
286 | 282 | art = art.toLowerCase(); |
283 | purp = purp.toLowerCase(); | |
287 | 284 | |
288 | 285 | if (settings.getBoolean("search.ignore.whitespace",true)) |
289 | 286 | { |
301 | 298 | name.indexOf(test) != -1 || |
302 | 299 | kto.indexOf(test) != -1 || |
303 | 300 | kom.indexOf(test) != -1 || |
304 | art.indexOf(test) != -1) | |
301 | art.indexOf(test) != -1 || | |
302 | purp.indexOf(test) != -1) | |
305 | 303 | { |
306 | 304 | return true; |
307 | 305 | } |
325 | 323 | Matcher mKto = pattern.matcher(kto); |
326 | 324 | Matcher mKom = pattern.matcher(kom); |
327 | 325 | Matcher mArt = pattern.matcher(art); |
328 | Matcher mAll = pattern.matcher(name + " " + kto + " " + zweck + " " + kom + " " + art); | |
326 | Matcher mPurp = pattern.matcher(purp); | |
327 | Matcher mAll = pattern.matcher(name + " " + kto + " " + zweck + " " + kom + " " + art + " " + purp); | |
329 | 328 | |
330 | 329 | return (mZweck.matches() || |
331 | mName.matches() || | |
332 | mKto.matches() || | |
333 | mKom.matches() || | |
334 | mArt.matches() || | |
330 | mName.matches() || | |
331 | mKto.matches() || | |
332 | mKom.matches() || | |
333 | mArt.matches() || | |
334 | mPurp.matches() || | |
335 | 335 | mAll.matches() |
336 | 336 | ); |
337 | 337 | } |
122 | 122 | "LOWER(primanota) LIKE ? OR " + |
123 | 123 | "LOWER(art) LIKE ? OR " + |
124 | 124 | "LOWER(customerref) LIKE ? OR " + |
125 | "LOWER(purposecode) LIKE ? OR " + | |
125 | 126 | "LOWER(kommentar) LIKE ?)", |
126 | text,text,text,text,text,text,text,text); | |
127 | text,text,text,text,text,text,text,text,text); | |
127 | 128 | } |
128 | 129 | return list; |
129 | 130 | } |
163 | 163 | return null; |
164 | 164 | } |
165 | 165 | |
166 | return result.get(tag); | |
166 | // Sonderrolle SVWZ. | |
167 | // Es kann sein, dass der Verwendungszweck so aussieht: | |
168 | // "EREF+1234 MREF+1234 SVWZ+" | |
169 | // Sprich: Das Tag ist zwar da, aber leer. Macht die "S-Bahn Berlin GmbH". | |
170 | // In dem Fall liefern wir ebenfalls den kompletten Text | |
171 | String value = result.get(tag); | |
172 | if (tag == Tag.SVWZ && StringUtils.trimToNull(value) == null) | |
173 | return toString(t); | |
174 | ||
175 | return value; | |
167 | 176 | } |
168 | 177 | |
169 | 178 | /** |
48 | 48 | public abstract class AbstractHBCIJob |
49 | 49 | { |
50 | 50 | protected final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N(); |
51 | ||
52 | private final static String NL = System.getProperty("line.separator","\n"); | |
51 | 53 | |
52 | 54 | private org.kapott.hbci.GV.HBCIJob job = null; |
53 | 55 | private boolean exclusive = false; |
377 | 379 | } |
378 | 380 | String sDetail = sb.toString(); |
379 | 381 | if (sDetail != null && sDetail.length() > 0) |
380 | sr += System.getProperty("line.separator","\n") + sDetail; | |
382 | sr += NL + sDetail; | |
381 | 383 | if (sJob != null && sJob.length() > 0) |
382 | sr += System.getProperty("line.separator","\n") + sJob; | |
384 | sr += NL + sJob; | |
383 | 385 | if (sGlob != null && sGlob.length() > 0) |
384 | sr += System.getProperty("line.separator","\n") + sGlob; | |
386 | sr += NL + sGlob; | |
385 | 387 | } |
386 | 388 | catch (ArrayIndexOutOfBoundsException aio) |
387 | 389 | { |
31 | 31 | import de.willuhn.jameica.hbci.rmi.Protokoll; |
32 | 32 | import de.willuhn.jameica.hbci.rmi.Umsatz; |
33 | 33 | import de.willuhn.jameica.hbci.server.Converter; |
34 | import de.willuhn.jameica.hbci.server.KontoUtil; | |
34 | 35 | import de.willuhn.jameica.hbci.server.hbci.rewriter.RewriterRegistry; |
35 | 36 | import de.willuhn.jameica.hbci.server.hbci.rewriter.UmsatzRewriter; |
36 | 37 | import de.willuhn.jameica.messaging.StatusBarMessage; |
130 | 131 | * @see de.willuhn.jameica.hbci.server.hbci.AbstractHBCIJob#getIdentifier() |
131 | 132 | */ |
132 | 133 | public String getIdentifier() { |
133 | return "KUmsAll"; | |
134 | return KontoUtil.useCamt(this.konto,true) ? "KUmsAllCamt" : "KUmsAll"; | |
134 | 135 | } |
135 | 136 | |
136 | 137 | /** |
69 | 69 | * angezeigt werden sollen. Wird z.Bsp. vom ScriptingBackend verwendet, um dort |
70 | 70 | * die Zugangsdaten zur Webseite hinterlegen zu koennen, ohne dafuer Kontonummer, |
71 | 71 | * Benutzerkennung, usw. des Kontos "missbrauchen" zu muessen. |
72 | * Die vom Benutzer eingegebenen Werte werden als Meta-Daten zum Konto gespeichert. | |
73 | * Sie koennen mittels {@link Konto#getMeta(String, String)} wieder abgerufen werden. | |
74 | * Besitzt ein Property den Suffix "(true/false)" wird es als Checkbox angezeigt. | |
75 | * Besitzt ein Property den Suffix "(pwd)" oder "(password)" wird es als Passwort-Eingabe angezeigt. | |
76 | * Der Suffix wird vor dem Speichern des Property in den Meta-Daten des Konto entfernt. | |
72 | 77 | * @param k das Konto. |
73 | 78 | * @return Liste von lesbaren Property-Namen. Die werden dem Benutzer 1:1 als |
74 | 79 | * Label von Eingabefeldern angezeigt. |
68 | 68 | */ |
69 | 69 | public String getName() |
70 | 70 | { |
71 | return "HBCI"; | |
71 | return "FinTS/HBCI"; | |
72 | 72 | } |
73 | 73 | |
74 | 74 | /** |
19 | 19 | Mit einem Rechtsklick auf die Legende kann ein Kontext-Menü zum Ein- oder |
20 | 20 | Ausblenden aller Datenreihen geöffnet werden. |
21 | 21 | </p> |
22 | ||
22 | <p> | |
23 | <b>Hinweis:</b> Klicken Sie mit der rechten Maustaste in die Grafik | |
24 | und wählen Sie "Gruppierung nach", um nach Jahr, Monat oder Woche zu gruppieren. | |
25 | </p> | |
23 | 26 | </form>⏎ |
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
156 | 156 | Vorhandene\ SEPA-Sammellastschriften=Existing\ collective\ SEPA Direct\ Debits |
157 | 157 | BLZ\ nicht\ achtstellig=Bank\ Code\ (BLZ)\ must\ be\ eight\ Digits |
158 | 158 | Aktualisieren=Refresh |
159 | Ums\u00E4tze\ der\ Kategorien\ im\ zeitlichen\ Verlauf=Timeline\ of\ Transactions\ in\ Categories | |
159 | Fehler\ beim\ Aktualisieren=Error\ while\ refreshing | |
160 | Fehler\ beim\ Erzeugen\ des\ Diagramms=Error\ while\ creating\ the\ chart | |
161 | Ums\u00E4tze\ der\ Kategorien\ im\ Verlauf\ (gruppiert\ nach\ {0})=Timeline\ of\ Transactions\ in\ Categories\ (aggregated\ by\ {0}) | |
162 | Gruppierung\ nach=Aggregate\ by | |
163 | Bitte\ w\u00E4hlen\ Sie\ einen\ gr\u00F6ßeren\ Zeitraum=Please\ select\ a longer interval | |
164 | Woche=Week | |
160 | 165 | Neue\ Lastschrift...=New\ Direct\ Debit... |
161 | 166 | Ausgaben=Expense |
162 | 167 | SEPA-Sammel\u00FCberweisung\ {0}\:\ Buchung\ bearbeiten=Collective\ SEPA\ Credit\ Transfer\ {0}\:\ Edit\ Booking |
433 | 438 | SEPA-Lastschriften=SEPA\ Direct\ Debits |
434 | 439 | <Keine\ Kategorie>=<No\ Category> |
435 | 440 | Als\ gelesen\ markieren=Mark\ as\ read |
441 | Als\ ungelesen\ markieren=Mark\ as\ unread | |
436 | 442 | Gegenkonto/Betrag=Counter\ Account/Amount |
437 | 443 | Art=Type |
438 | 444 | Bezeichnung\ des\ Kontos=Account\ Description |
996 | 1002 | Valuta/Datum=Valuta/Date |
997 | 1003 | Zeitraum\:\ {0}\ -\ {1}=Timeframe\:\ {0}\ -\ {1} |
998 | 1004 | {0}\ Auftr\u00E4ge,\ {1}\ markiert,\ Summe\:\ {2}\ {3}={0}\ Records,\ {1}\ selected,\ Total\:\ {2}\ {3} |
999 | ||
1005 | Elektr.\ Kontoausz\u00E4ge=Electr.\ bank\ statements | |
1006 | Nur\ ungelesene\ Kontoausz\u00E4ge anzeigen=Show\ only\ unread\ bank\ statements | |
1007 | Speichern\ unter...=Save\ as... | |
1008 | Kontoausz\u00E4ge abrufen...=Fetch\ bank\ statements... | |
1009 | Empfangsquittung\ senden...=Send\ acknowledgment\ of\ receipt... | |
1010 | Jahr=Year | |
1011 | Nummer=Number | |
1012 | Abgerufen\ am=Fetched\ at | |
1013 | Quittiert\ am=Receipted\ at | |
1014 | Saldo=Balance | |
1015 | Letzte\ 30\ Tage=Last 30 Days | |
1016 | Letzte\ 7\ Tage=Last 7 Days | |
1017 | Kein\ Konto\ angegeben=No\ account\ specified | |
1018 | Bitte\ w\u00E4hlen\ Sie\ ein\ Konto\ aus=Please\ select\ an\ account | |
1019 | N\u00E4chster\ Abruf=Next\ call |
0 | /********************************************************************** | |
1 | * | |
2 | * Copyright (c) by Olaf Willuhn | |
3 | * All rights reserved | |
4 | * | |
5 | **********************************************************************/ | |
6 | ||
7 | import java.util.Arrays; | |
8 | import java.util.HashMap; | |
9 | import java.util.List; | |
10 | import java.util.Map; | |
11 | ||
12 | import de.willuhn.jameica.hbci.rmi.DBSupport; | |
13 | import de.willuhn.jameica.hbci.server.AbstractUpdate; | |
14 | import de.willuhn.jameica.hbci.server.DBSupportH2Impl; | |
15 | import de.willuhn.jameica.hbci.server.DBSupportMySqlImpl; | |
16 | import de.willuhn.jameica.hbci.server.DBSupportPostgreSQLImpl; | |
17 | ||
18 | ||
19 | /** | |
20 | * Macht die Umsatz-Tabelle fit fuer CAMT. | |
21 | */ | |
22 | public class update0063 extends AbstractUpdate | |
23 | { | |
24 | private Map<Class<? extends DBSupport>,List<String>> statements = new HashMap() | |
25 | {{ | |
26 | // Update fuer H2 | |
27 | put(DBSupportH2Impl.class,Arrays.asList( | |
28 | "ALTER TABLE umsatz ALTER COLUMN zweck varchar(255);", | |
29 | "ALTER TABLE umsatz ADD txid varchar(100);", | |
30 | "ALTER TABLE umsatz ADD purposecode varchar(10);" | |
31 | )); | |
32 | ||
33 | // Update fuer MySQL | |
34 | put(DBSupportMySqlImpl.class,Arrays.asList( | |
35 | "ALTER TABLE umsatz CHANGE zweck zweck varchar(255);", | |
36 | "ALTER TABLE umsatz ADD txid varchar(100);", | |
37 | "ALTER TABLE umsatz ADD purposecode varchar(10);" | |
38 | )); | |
39 | ||
40 | // Update fuer PostGreSQL | |
41 | put(DBSupportPostgreSQLImpl.class,Arrays.asList( | |
42 | "ALTER TABLE umsatz ALTER COLUMN zweck TYPE varchar(255);", | |
43 | "ALTER TABLE umsatz ADD txid varchar(100);", | |
44 | "ALTER TABLE umsatz ADD purposecode varchar(10);" | |
45 | )); | |
46 | }}; | |
47 | ||
48 | /** | |
49 | * @see de.willuhn.jameica.hbci.server.AbstractUpdate#getStatements(java.lang.Class) | |
50 | */ | |
51 | @Override | |
52 | protected List<String> getStatements(Class<? extends DBSupport> driverClass) | |
53 | { | |
54 | return statements.get(driverClass); | |
55 | } | |
56 | } |