OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 142 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
25 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.erp.core.humanresources.employe.report;
15
 
16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
142 ilm 17
import org.openconcerto.erp.core.humanresources.payroll.report.FichePayeSheetXML;
18
import org.openconcerto.erp.generationDoc.DocumentLocalStorageManager;
25 ilm 19
import org.openconcerto.sql.Configuration;
20
import org.openconcerto.sql.element.SQLElement;
21
import org.openconcerto.sql.model.SQLRow;
22
import org.openconcerto.sql.model.SQLRowListRSH;
23
import org.openconcerto.sql.model.SQLSelect;
41 ilm 24
import org.openconcerto.sql.model.SQLTable;
25 ilm 25
import org.openconcerto.sql.model.Where;
41 ilm 26
import org.openconcerto.utils.ProductInfo;
80 ilm 27
import org.openconcerto.utils.StringUtils;
25 ilm 28
 
29
import java.io.File;
30
import java.io.IOException;
31
import java.io.PrintStream;
32
import java.text.DateFormat;
41 ilm 33
import java.text.DecimalFormat;
34
import java.text.DecimalFormatSymbols;
25 ilm 35
import java.text.Normalizer;
36
import java.text.Normalizer.Form;
37
import java.text.SimpleDateFormat;
38
import java.util.Date;
39
import java.util.List;
40
 
41 ilm 41
import javax.swing.JOptionPane;
42
import javax.swing.SwingUtilities;
43
 
25 ilm 44
public class N4DS {
45
 
142 ilm 46
    private DateFormat format = new SimpleDateFormat("ddMMyyyy");
25 ilm 47
    private ComptaPropsConfiguration conf = ((ComptaPropsConfiguration) Configuration.getInstance());
41 ilm 48
    private double masseSalarialeBrute;
25 ilm 49
    private static final byte[] retour = "'\n".getBytes();
50
    private PrintStream stream = null;
51
 
41 ilm 52
    DecimalFormat decimalFormat = new DecimalFormat("0.00");
53
 
73 ilm 54
    Date dateDebut, dateFin;
55
 
25 ilm 56
    // FIXME Salarie renvoye
57
 
58
    /**
59
     * Déclaration normale (type 51)
132 ilm 60
     */
25 ilm 61
    public N4DS() {
41 ilm 62
        DecimalFormatSymbols symbol = new DecimalFormatSymbols();
63
        symbol.setDecimalSeparator('.');
64
        this.decimalFormat.setDecimalFormatSymbols(symbol);
25 ilm 65
 
66
    }
67
 
41 ilm 68
    public File createDocument() {
69
        this.masseSalarialeBrute = 0;
142 ilm 70
        File dir = DocumentLocalStorageManager.getInstance().getDocumentOutputDirectory(FichePayeSheetXML.TEMPLATE_ID);
71
        dir.mkdirs();
72
        File f = new File(dir, "N4DS_" + format.format(new Date()) + ".txt");
25 ilm 73
 
142 ilm 74
        // File f = new File("N4DS_" + format.format(new Date()) + ".txt");
75
 
25 ilm 76
        try {
77
 
41 ilm 78
            this.stream = new PrintStream(f, "ISO-8859-1");
25 ilm 79
 
80
            SQLElement eltSalarie = this.conf.getDirectory().getElement("SALARIE");
81
 
82
            // Infos emetteur
83
            SQLRow rowSociete = this.conf.getRowSociete();
84
 
41 ilm 85
            writeS10(this.stream, rowSociete);
25 ilm 86
 
41 ilm 87
            writeS20(this.stream, rowSociete);
25 ilm 88
 
73 ilm 89
            SQLSelect sel = new SQLSelect();
25 ilm 90
            sel.addSelect(eltSalarie.getTable().getKey());
91
 
142 ilm 92
            final SQLElement infosElt = eltSalarie.getForeignElement("ID_INFOS_SALARIE_PAYE");
93
            // Date d1 = new Date(116, 0, 1);
156 ilm 94
            Date d2 = new Date(117, 11, 31);
142 ilm 95
 
96
            Where w = new Where(infosElt.getTable().getKey(), "=", eltSalarie.getTable().getField("ID_INFOS_SALARIE_PAYE"));
97
            w = w.and(new Where(infosElt.getTable().getField("DATE_ARRIVE"), "<=", d2));
98
            w = w.and(new Where(infosElt.getTable().getField("DATE_SORTIE"), "=", (Date) null).or(new Where(infosElt.getTable().getField("DATE_SORTIE"), "<=", d2)));
99
 
100
            sel.setWhere(w);
101
 
25 ilm 102
            @SuppressWarnings("unchecked")
103
            List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltSalarie.getTable()));
104
 
105
            for (SQLRow row : l) {
106
                N4DSSalarie s = new N4DSSalarie(this);
107
                s.write(row, rowSociete);
108
 
109
            }
41 ilm 110
            writeS80(this.stream, rowSociete);
111
            writeS90(this.stream);
25 ilm 112
 
113
        } catch (IOException e) {
114
            e.printStackTrace();
115
        } finally {
41 ilm 116
            if (this.stream != null) {
117
                this.stream.close();
25 ilm 118
            }
119
        }
41 ilm 120
        return f;
25 ilm 121
    }
122
 
123
    private void writeS80(PrintStream stream, SQLRow rowSociete) throws IOException {
124
 
90 ilm 125
        // final String nic =
126
        // StringUtils.limitLength(rowSociete.getString("NUM_SIRET").replaceAll(" ", ""), 9);
127
        final String siret = rowSociete.getString("NUM_SIRET").replaceAll(" ", "");
128
        String siren = StringUtils.limitLength(siret, 9);
129
        String nic = siret.substring(siren.length(), siret.length());
25 ilm 130
 
41 ilm 131
        // // SIREN
132
        // write("S80.G01.00.001.001", siren);
25 ilm 133
 
134
        // NIC
135
        write("S80.G01.00.001.002", nic);
136
 
137
        SQLRow rowAdr = rowSociete.getForeignRow("ID_ADRESSE_COMMON");
138
        String voie = rowAdr.getString("RUE");
139
 
140
        // Complement adresse
141
        if (voie.contains("\n")) {
142
            String[] sVoies = voie.split("\n");
143
            if (sVoies.length > 0) {
144
                voie = sVoies[0];
145
                String complement = "";
146
                for (int i = 1; i < sVoies.length; i++) {
147
                    complement += sVoies[i].trim() + " ";
148
                }
149
                if (complement.length() > 0) {
150
                    complement = complement.substring(0, complement.length() - 1);
151
                }
152
 
142 ilm 153
                write("S80.G01.00.003.001", normalizeString2(complement));
25 ilm 154
            }
155
        }
156
 
157
        // Voie
142 ilm 158
        write("S80.G01.00.003.006", normalizeString2(voie));
25 ilm 159
 
160
        // TODO Code INSEE, facultatif
161
        // stream.write("S80.G01.00.003.007",voie);
162
 
163
        // FIXME Service de distribution
164
        // stream.write("S80.G01.00.003.009",ville.getName());
165
 
166
        // Code postal
73 ilm 167
        write("S80.G01.00.003.010", rowAdr.getString("CODE_POSTAL"));
25 ilm 168
 
169
        // Localité
90 ilm 170
        write("S80.G01.00.003.012", normalizeString2(rowAdr.getString("VILLE")));
25 ilm 171
 
172
        // Code Pays, ne doit pas être renseigné pour une adresse en France
173
        // TODO support des autres pays
174
        // write("S80.G01.00.003.013", "");
175
 
176
        // FIXME effectif déclaré
177
        write("S80.G01.00.004.001", String.valueOf(getEffectifDeclare()));
178
 
179
        // TODO Code établissement sans salarié
180
        // write( "S80.G01.00.004.001", "2");
181
 
182
        // TODO Code assujettis taxe sur salaires
183
        write("S80.G01.00.005", "01");
184
 
185
        // Code NAF etablissement
186
        write("S80.G01.00.006", rowSociete.getString("NUM_APE"));
187
 
188
        // FIXME Code section prud'homale
156 ilm 189
        // write("S80.G01.00.007.001", "04");
25 ilm 190
 
191
        // TODO stecion principale dérogatoire
192
        // write( "S80.G01.00.004.001", "2");
193
 
194
        // TODO Institution Prevoyance sans salarie
195
        // write( "S80.G01.01.001", "P0012");
196
        // write( "S80.G01.01.002", "0003");
197
 
198
        // TODO Institution retraite sans salarie
199
        // write( "S80.G01.02.001", "G022");
200
 
201
        // FIXME Code assujettissement taxe et contribution apprentissage
73 ilm 202
        write("S80.G62.00.001", "01");
41 ilm 203
        double totalApprentissage = this.masseSalarialeBrute * 0.0068;
25 ilm 204
        System.err.println(this.masseSalarialeBrute);
73 ilm 205
        write("S80.G62.00.002", this.decimalFormat.format(totalApprentissage));
25 ilm 206
 
73 ilm 207
        write("S80.G62.00.003", "02");
25 ilm 208
        // FIXME Code assujettissement formation professionnelle continue
73 ilm 209
        write("S80.G62.00.005", "01");
41 ilm 210
        double totalFormation = this.masseSalarialeBrute * 0.0055;
73 ilm 211
        write("S80.G62.00.007", this.decimalFormat.format(totalFormation));
25 ilm 212
 
73 ilm 213
        write("S80.G62.00.008", "02");
214
 
25 ilm 215
    }
216
 
217
    private void writeS90(PrintStream stream) throws IOException {
218
        // Nombre total de rubrique + S90
219
        write("S90.G01.00.001", String.valueOf(this.nbRubrique + 2));
220
 
221
        // Nombre total de rubrique S20
222
        write("S90.G01.00.002", String.valueOf(1));
223
    }
224
 
225
    private int nbRubrique = 0;
226
 
227
    public void write(String rubriqueName, String value) throws IOException {
228
        String tmp = rubriqueName + ",'";
41 ilm 229
        this.stream.write(tmp.getBytes());
230
        this.stream.write(value.getBytes());
231
        this.stream.write(retour);
25 ilm 232
 
233
        // if (rubriqueName.startsWith("S20")) {
234
        // this.nbRubriqueS20++;
235
        // }
236
        this.nbRubrique++;
237
    }
238
 
239
    private int getEffectifDeclare() {
240
        // FIXME ne pas inclure les intérimaires
241
        SQLElement eltSalarie = this.conf.getDirectory().getElement("SALARIE");
242
        SQLElement eltInfos = this.conf.getDirectory().getElement("INFOS_SALARIE_PAYE");
80 ilm 243
        SQLSelect sel = new SQLSelect();
25 ilm 244
        sel.addSelect(eltSalarie.getTable().getKey());
142 ilm 245
        // Date d1 = new Date(116, 0, 1);
156 ilm 246
        Date d2 = new Date(117, 11, 31);
25 ilm 247
        Where w = new Where(eltSalarie.getTable().getField("ID_INFOS_SALARIE_PAYE"), "=", eltInfos.getTable().getKey());
142 ilm 248
        w = w.and(new Where(eltInfos.getTable().getField("DATE_SORTIE"), "=", (Date) null).or(new Where(eltInfos.getTable().getField("DATE_SORTIE"), "<=", d2)));
249
        w = w.and(new Where(eltInfos.getTable().getField("DATE_ARRIVE"), "=", (Date) null).or(new Where(eltInfos.getTable().getField("DATE_ARRIVE"), "<=", d2)));
25 ilm 250
 
251
        sel.setWhere(w);
252
        System.err.println(sel.asString());
253
        List<SQLRow> l = (List<SQLRow>) this.conf.getBase().getDataSource().execute(sel.asString(), new SQLRowListRSH(eltSalarie.getTable()));
254
 
255
        return (l == null ? 0 : l.size());
256
    }
257
 
258
    public static String normalizeString2(String s) {
259
        s = s.toUpperCase();
260
        String temp = Normalizer.normalize(s, Form.NFC);
261
        temp = temp.replaceAll("-", " ");
142 ilm 262
        temp = temp.replaceAll("é", "e");
263
        temp = temp.replaceAll("è", "e");
264
        temp = temp.replaceAll("ê", "e");
265
        temp = temp.replaceAll(",", "");
25 ilm 266
        return temp.replaceAll("[^\\p{ASCII}]", "");
267
    }
268
 
269
    private void writeS20(PrintStream stream, SQLRow rowSociete) throws IOException {
270
 
271
        // Siren
272
 
90 ilm 273
        final String siret = rowSociete.getString("NUM_SIRET").replaceAll(" ", "");
274
        String siren = StringUtils.limitLength(siret, 9);
275
        String nic = siret.substring(siren.length(), siret.length());
25 ilm 276
        write("S20.G01.00.001", siren);
277
 
278
        // Raison sociale
142 ilm 279
        write("S20.G01.00.002", normalizeString2(rowSociete.getString("NOM")));
25 ilm 280
 
281
        // FIXME Debut periode
156 ilm 282
        write("S20.G01.00.003.001", "01012017");
25 ilm 283
 
284
        // FIXME Fin periode
156 ilm 285
        write("S20.G01.00.003.002", "31122017");
25 ilm 286
 
287
        // Code nature
288
        write("S20.G01.00.004.001", "01");
289
 
290
        // FIXME Code type (complement, Rectificatif, ...)
291
        write("S20.G01.00.004.002", "51");
292
 
293
        // fraction
294
        write("S20.G01.00.005", "11");
295
 
296
        // TODO debut periode rattachement
297
        // stream.write("S20.G01.00.006.001,'","11");
298
 
299
        // fin periode rattachement
300
        // stream.write("S20.G01.00.006.002,'","11");
301
 
302
        // Code devise de la déclaration
303
        write("S20.G01.00.007", "01");
304
 
305
        // NIC
306
        write("S20.G01.00.008", nic);
307
 
308
        SQLRow rowAdr = rowSociete.getForeignRow("ID_ADRESSE_COMMON");
309
        String voie = rowAdr.getString("RUE");
310
 
311
        // Complement adresse
312
        if (voie.contains("\n")) {
313
            String[] sVoies = voie.split("\n");
314
            if (sVoies.length > 0) {
315
                voie = sVoies[0];
316
                String complement = "";
317
                for (int i = 1; i < sVoies.length; i++) {
318
                    complement += sVoies[i].trim() + " ";
319
                }
320
                if (complement.length() > 0) {
321
                    complement = complement.substring(0, complement.length() - 1);
322
                }
323
 
142 ilm 324
                write("S20.G01.00.009.001", normalizeString2(complement));
25 ilm 325
            }
326
        }
327
 
328
        // Voie
142 ilm 329
        write("S20.G01.00.009.006", normalizeString2(voie));
25 ilm 330
 
331
        // Code postal
73 ilm 332
        write("S20.G01.00.009.010", rowAdr.getString("CODE_POSTAL"));
25 ilm 333
 
334
        // Localité
90 ilm 335
        write("S20.G01.00.009.012", normalizeString2(rowAdr.getString("VILLE")));
25 ilm 336
 
41 ilm 337
        write("S20.G01.00.013.002", "1");
25 ilm 338
 
339
        // Code periodicite
340
        write("S20.G01.00.018", "A00");
341
 
41 ilm 342
        write("S20.G01.05.014.001", siren);
343
        write("S20.G01.05.014.002", nic);
344
        write("S20.G01.05.016.001", rowSociete.getString("MAIL"));
345
 
25 ilm 346
    }
347
 
348
    /**
349
     * Strucuture S10, N4DS
132 ilm 350
     */
25 ilm 351
    private void writeS10(PrintStream stream, SQLRow rowSociete) throws IOException {
352
 
353
        // Siren
354
 
90 ilm 355
        final String siret = rowSociete.getString("NUM_SIRET").replaceAll(" ", "");
356
        String siren = StringUtils.limitLength(siret, 9);
357
        String nic = siret.substring(siren.length(), siret.length());
25 ilm 358
        write("S10.G01.00.001.001", siren);
359
 
360
        // NIC
361
        write("S10.G01.00.001.002", nic);
362
 
363
        // Raison sociale
142 ilm 364
        write("S10.G01.00.002", normalizeString2(rowSociete.getString("NOM")));
25 ilm 365
 
366
        SQLRow rowAdr = rowSociete.getForeignRow("ID_ADRESSE_COMMON");
367
        String voie = rowAdr.getString("RUE");
368
 
369
        // Complement adresse
370
        if (voie.contains("\n")) {
371
            String[] sVoies = voie.split("\n");
372
            if (sVoies.length > 0) {
373
                voie = sVoies[0];
374
                String complement = "";
375
                for (int i = 1; i < sVoies.length; i++) {
376
                    complement += sVoies[i] + " ";
377
                }
378
                if (complement.length() > 0) {
379
                    complement = complement.substring(0, complement.length() - 1);
380
                }
381
 
142 ilm 382
                write("S10.G01.00.003.001", normalizeString2(complement));
25 ilm 383
            }
384
        }
385
 
386
        // Voie
142 ilm 387
        write("S10.G01.00.003.006", normalizeString2(voie));
25 ilm 388
 
389
        // TODO Code INSEE, facultatif
390
        // stream.write("S10.G01.00.003.007",voie);
391
 
392
        // TODO: Service de distribution
90 ilm 393
        write("S10.G01.00.003.009", normalizeString2(rowAdr.getString("VILLE")));
25 ilm 394
 
395
        // Code postal
73 ilm 396
        write("S10.G01.00.003.010", rowAdr.getString("CODE_POSTAL"));
25 ilm 397
 
398
        // Localité
90 ilm 399
        write("S10.G01.00.003.012", normalizeString2(rowAdr.getString("VILLE")));
25 ilm 400
 
401
        // Code Pays, ne doit pas être renseigné pour une adresse en France
402
        // TODO support des autres pays
403
        // write("S10.G01.00.003.013", "");
404
 
405
        // FIXME Référence de l'envoi
406
        // Incrémenté le numéro
407
        write("S10.G01.00.004,'", "1");
408
 
409
        // Nom du logiciel
410
        write("S10.G01.00.005", "OpenConcerto");
411
 
412
        // Nom de l'éditeur
413
        write("S10.G01.00.006", "ILM Informatique");
414
 
415
        // Numéro version
41 ilm 416
        write("S10.G01.00.007", ProductInfo.getInstance().getVersion());
25 ilm 417
 
418
        // Code service choisi
419
        write("S10.G01.00.009", "40");
420
 
421
        // Code envoi du fichier essai ou réel
422
        write("S10.G01.00.010", "02");
423
 
424
        // Norme utilisée
156 ilm 425
        write("S10.G01.00.011", "V01X12");
25 ilm 426
 
427
        // Code table char
428
        write("S10.G01.00.012", "01");
429
 
430
        // TODO Contact pour DADS
431
        // Code civilite
432
        write("S10.G01.01.001.001", "01");
41 ilm 433
 
25 ilm 434
        // Nom Contact
41 ilm 435
        SQLTable table = Configuration.getInstance().getRoot().findTable("CONTACT_ADMINISTRATIF");
436
        SQLSelect selContact = new SQLSelect(table.getBase());
437
        selContact.addSelectStar(table);
438
        selContact.setWhere(new Where(table.getField("N4DS"), "=", Boolean.TRUE));
439
        List<SQLRow> l = SQLRowListRSH.execute(selContact);
440
        if (l.size() == 0) {
441
            SwingUtilities.invokeLater(new Runnable() {
25 ilm 442
 
41 ilm 443
                @Override
444
                public void run() {
445
                    JOptionPane.showMessageDialog(null, "Aucun contact administratif pour la N4DS. Veuillez en définir un.");
446
                }
447
            });
448
        } else {
449
            SQLRow rowContact = l.get(0);
25 ilm 450
 
41 ilm 451
            // TODO Contact pour DADS
452
            write("S10.G01.01.001.002", rowContact.getString("NOM") + " " + rowContact.getString("PRENOM"));
25 ilm 453
 
41 ilm 454
            // Code domaine
455
            write("S10.G01.01.002", "03");
25 ilm 456
 
41 ilm 457
            // Adresse mail
458
            // TODO Contact pour DADS
459
            write("S10.G01.01.005", rowContact.getString("EMAIL"));
460
 
461
            // Tel
142 ilm 462
            String string = rowContact.getString("TEL_DIRECT");
463
            if (string.trim().length() == 0) {
464
                string = rowContact.getString("TEL_STANDARD");
465
            }
41 ilm 466
 
142 ilm 467
            write("S10.G01.01.006", string);
468
 
41 ilm 469
            // Fax
470
            write("S10.G01.01.007", rowContact.getString("FAX"));
471
        }
25 ilm 472
    }
473
 
474
    private String getNumeroVoie(String voie) {
475
        String numero = "";
476
        voie = voie.trim();
477
        for (int i = 0; i < voie.trim().length(); i++) {
478
            char c = voie.charAt(i);
479
            if (c >= '0' && c <= '9') {
480
                numero += c;
481
            } else {
482
                break;
483
            }
484
        }
485
        return numero;
486
    }
487
 
488
    private String getVoieWithoutNumber(String voie) {
489
        voie = voie.trim();
490
        String resultVoie = new String(voie);
491
 
492
        for (int i = 0; i < voie.trim().length(); i++) {
493
            char c = voie.charAt(i);
494
            if (c >= '0' && c <= '9') {
495
                resultVoie = resultVoie.substring(1);
496
            } else {
497
                break;
498
            }
499
        }
500
        return resultVoie.trim();
501
    }
502
 
41 ilm 503
    public void addMasseSalarialeBrute(double baseBrute) {
25 ilm 504
        this.masseSalarialeBrute += baseBrute;
505
    }
506
 
507
}