OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Blame | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.erp.panel.compta;

import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.utils.StringUtils;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.dbutils.handlers.ArrayListHandler;

public class ExportToQuadraCompta extends AbstractExport {
    private static final Charset CHARSET = StringUtils.Cp1252;
    private List<Object[]> data;

    protected ExportToQuadraCompta(DBRoot rootSociete) {
        super(rootSociete, "QuadraCompta", ".txt");
    }

    @Override
    protected int fetchData(Date from, Date to, SQLRow selectedJournal, boolean onlyNew) {
        final SQLTable tableEcriture = getEcritureT();
        final SQLTable tableMouvement = tableEcriture.getForeignTable("ID_MOUVEMENT");
        final SQLTable tableCompte = tableEcriture.getForeignTable("ID_COMPTE_PCE");
        final SQLTable tableJrnl = tableEcriture.getForeignTable("ID_JOURNAL");
        final SQLTable tablePiece = tableMouvement.getForeignTable("ID_PIECE");

        final SQLSelect sel = createSelect(from, to, selectedJournal, onlyNew);
        
        sel.addSelect(tableCompte.getField("NUMERO"));
        sel.addSelect(tableJrnl.getField("CODE"));
        sel.addSelect(tableEcriture.getField("DATE"));
        sel.addSelect(tableEcriture.getField("NOM"));
        sel.addSelect(tableEcriture.getField("DEBIT"));
        sel.addSelect(tableEcriture.getField("CREDIT"));
        sel.addSelect(tablePiece.getField("NOM"));
        
        @SuppressWarnings("unchecked")
        final List<Object[]> l = (List<Object[]>) this.getRootSociete().getDBSystemRoot().getDataSource().execute(sel.asString(), new ArrayListHandler());
        this.data = l;
        
        return l == null ? 0 : l.size();
    }

    @Override
    protected void export(OutputStream out) throws IOException, ParseException {
        final Writer bufOut = new OutputStreamWriter(out, CHARSET);
        SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyy");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        
        for (final Object[] array : this.data) {
            
            bufOut.write("M");
            bufOut.write(matchStringToFixedLength(array[0],8,'0', true, false ));
            bufOut.write(matchStringToFixedLength(array[1],2,' '));
            bufOut.write("000");

            Date date1 = simpleDateFormat.parse(String.valueOf(array[2]).trim());
            bufOut.write(dateFormat.format(date1));
            bufOut.write(" ");
            bufOut.write(matchStringToFixedLength("",20,' '));
            
            long debit = ((Number)array[4]).longValue();
            long credit = ((Number)array[5]).longValue();           
            
            // Exception si débit et crédit > 0
            bufOut.write(getDebitOrCredit(debit,credit));
            bufOut.write(getAmountSign(getAmount(debit,credit)));
            bufOut.write(matchStringToFixedLength(getAmount(debit,credit),12,'0', false, false));
            bufOut.write(matchStringToFixedLength("",44,' '));
            bufOut.write(matchStringToFixedLength(array[6],8,' ',false, true));
            bufOut.write("EUR");
            bufOut.write(matchStringToFixedLength(array[1],3,' '));
            bufOut.write(matchStringToFixedLength(array[3],30,' ', false, false));
            bufOut.write(matchStringToFixedLength("",12,' '));

            bufOut.write("\r\n");            
        }
        bufOut.flush();
    }

    /**
     * Adapte une chaine à une longueur (champs à longueur fixe).
     * @param : un objet que l'on va transformer en chaine.
     * @param : une longueur. 
     * @param : un caractère pour le remplissage si la chaine est plus petite que la longueur fixée.
     * @param : placement du remplissage, true = à droite.
     * @param : le coté de la chaine à garder, true = à droite.
     * 
     */
    private String matchStringToFixedLength(Object o, int length, char filler, boolean fillRight, boolean keepRight) {
        String str = String.valueOf(o).trim();
        
        if(str.length() >=  length) {
            if(keepRight) {
                return str.substring(str.length()-length, str.length());                
            }else {
                return str.substring(0,length);
            }
        }else {
            String format;
            if(fillRight) {
                format = "%-"+length+"s";
            }else {
                format = "%"+length+"s";
            }
            return String.format(format, str).replace(' ',filler);
        }        
    }
    
    private String matchStringToFixedLength(Object o, int length, char filler) {
        return matchStringToFixedLength(o, length, filler, true, true);
    }
    
    private String getDebitOrCredit(final long debit, final long credit) {       
        if(debit > 0 && credit > 0) {
            throw new IllegalStateException("Both credit and debit");
        }else if(debit == 0) {
            return "C";
        }else {
            return "D";
        }
    }
    
    private String getAmountSign(final long amount) {
        if(amount < 0) {
            return "-";
        }else {
            return "+";
        }
    }
    
    private long getAmount(final long debit, final long credit) {
        if(debit > 0) {
            return debit;
        }else {
            return credit;
        }
    }    
}