com.nkapps.billing.services.BankStatementServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.nkapps.billing.services.BankStatementServiceImpl.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nkapps.billing.services;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.servlet.ServletContext;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import com.nkapps.billing.dao.BankStatementDao;
import com.nkapps.billing.models.BankStatement;
import com.nkapps.billing.models.BankStatementListPojo;
import com.nkapps.billing.models.InvoicePojo;
import com.nkapps.billing.models.PrintClaimPojo;
import com.nkapps.billing.models.PrintClaimRegisterPojo;
import com.nkapps.billing.models.PrintRegisterPojo;

/**
 *
 * @author nuraddin
 */
@Service("bankStatementService")
public class BankStatementServiceImpl implements BankStatementService {

    @Autowired
    private ServletContext servletContext;

    @Autowired
    private BankStatementDao bankStatementDao;

    @Autowired
    private NumberService numberService;

    @Autowired
    private MessageSource messageSource;

    Logger logger = LoggerFactory.getLogger(BankStatementServiceImpl.class);

    @Override
    public String getUploadDir() {
        return servletContext.getRealPath("uploads");
    }

    @Override
    public String getBackupDir() {
        return servletContext.getRealPath("backups");
    }

    @Override
    public File extractedFile(File file) throws Exception {
        File extractedFile = null;

        byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
        ZipEntry ze = zis.getNextEntry();
        while (ze != null) {
            String extFileName = ze.getName();
            extractedFile = new File(getUploadDir() + File.separator + extFileName);
            if (!extractedFile.exists()) {
                extractedFile.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(extractedFile);
            int len;
            while ((len = zis.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }
            fos.close();
            ze = zis.getNextEntry();
        }
        zis.closeEntry();
        zis.close();

        return extractedFile;
    }

    private String md5Encrypt(String in) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(in.getBytes("UTF-8"));
        byte byteData[] = md.digest();

        //convert the byte to hex format method 1
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < byteData.length; i++) {
            sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
        }
        return sb.toString();
    }

    private String replaceCyrillic(String str) {
        return str.replace("&#1179", "").replace("&#1178", "").replace("&#1171", "").replace("&#1170", "")
                .replace("&#1203", "").replace("&#1202", "").replace("&#1118", "").replace("&#1038", "");
    }

    private BankStatement bsFromCols(String[] cols, Long issuerSerialNumber, String issuerIp,
            LocalDateTime dateTime) throws Exception {
        BankStatement bs = new BankStatement();
        bs.setTin(cols[0]);
        bs.setChet(cols[1]);
        bs.setMfo(cols[2]);
        bs.setPaymentSum(new BigDecimal(cols[3]));
        bs.setPaymentDetails(cols[4]);
        bs.setPaymentNum(cols[5]);

        Date paymentDate = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yy");
        try {
            paymentDate = dateFormat.parse(cols[6]);
        } catch (ParseException e) {
        }

        bs.setPaymentDate(paymentDate);
        bs.setName(cols[7]);
        bs.setIssuerSerialNumber(issuerSerialNumber);
        bs.setIssuerIp(issuerIp);
        bs.setDateCreated(dateTime);
        bs.setDateUpdated(dateTime);
        bs.setId(md5Encrypt(bs.getTin() + bs.getName() + bs.getMfo() + bs.getChet() + bs.getPaymentNum()
                + dateFormat.format(bs.getPaymentDate()) + bs.getPaymentDetails()));

        return bs;
    }

    @Override
    public String parseAndSave(File file, Long issuerSerialNumber, String issuerIp) throws Exception {
        String errorMessages = "";

        FileInputStream fis = new FileInputStream(file);
        BufferedReader br = new BufferedReader(new InputStreamReader(fis, "windows-1251"));

        List<BankStatement> bsList = new ArrayList<>();
        LocalDateTime dateTime = LocalDateTime.now();

        boolean skipFirstLine = true;
        String line;
        int lineCurrent = 0;
        while ((line = br.readLine()) != null) {
            lineCurrent++;

            if (skipFirstLine) {
                skipFirstLine = false;
                continue;
            }
            line = replaceCyrillic(line);
            String[] cols = line.split("#");

            /***
             *   
             *  detali platejdagi '#' simvolni togirlash
             * 
             * int colSize = cols.length;
            for (int j = 0; j < colSize - 8; j++) {
                cols[4] = cols[4] + cols[5];
                List<String> temp = new ArrayList<String>(Arrays.asList(cols));
                temp.remove(5);
                cols = temp.toArray(new String[0]);
            }
             */
            if (cols.length > 8) {
                /***
                 *  
                 *   First of all we must define where contains # , or payment details or name,
                 *   maximum two # symbols we can convert, one of contains detail, another of contains name
                 *  
                 */
                int overSize = cols.length - 8;
                if (overSize == 1) {
                    String dateStr = cols[7]; // if dateStr is date then paymentdetails contains #, else name contains #
                    boolean detailContains = true;

                    SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yy");
                    try {
                        dateFormat.parse(dateStr);
                    } catch (ParseException e) {
                        detailContains = false;
                    }

                    if (detailContains) {
                        cols[4] = cols[4] + cols[5];
                        List<String> temp = new ArrayList<>(Arrays.asList(cols));
                        temp.remove(5);
                        cols = temp.toArray(new String[temp.size()]);

                    } else {
                        cols[7] = cols[7] + cols[8];
                        List<String> temp = new ArrayList<>(Arrays.asList(cols));
                        temp.remove(8);
                        cols = temp.toArray(new String[temp.size()]);
                    }
                } else if (overSize == 2) {
                    // first details contains 2 #
                    String dateStr = cols[8];
                    boolean detailTwoContains = true;

                    SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yy");
                    try {
                        dateFormat.parse(dateStr);
                    } catch (ParseException e) {
                        detailTwoContains = false;
                    }

                    if (detailTwoContains) { //

                        cols[4] = cols[4] + cols[5] + cols[6];
                        List<String> temp = new ArrayList<>(Arrays.asList(cols));
                        temp.remove(5);
                        temp.remove(6);
                        cols = temp.toArray(new String[temp.size()]);

                    } else {
                        dateStr = cols[6];
                        boolean nameTwoContains = true;

                        dateFormat = new SimpleDateFormat("dd.MM.yy");
                        try {
                            dateFormat.parse(dateStr);
                        } catch (ParseException e) {
                            nameTwoContains = false;
                        }

                        if (nameTwoContains) { //
                            cols[7] = cols[7] + cols[8] + cols[9];
                            List<String> temp = new ArrayList<>(Arrays.asList(cols));
                            temp.remove(8);
                            temp.remove(9);
                            cols = temp.toArray(new String[temp.size()]);

                        } else {
                            dateStr = cols[7];
                            boolean nameAndDetailsContains = true;

                            dateFormat = new SimpleDateFormat("dd.MM.yy");
                            try {
                                dateFormat.parse(dateStr);
                            } catch (ParseException e) {
                                nameAndDetailsContains = false;
                            }

                            if (nameAndDetailsContains) { //
                                cols[4] = cols[4] + cols[5];
                                cols[8] = cols[8] + cols[9];
                                List<String> temp = new ArrayList<>(Arrays.asList(cols));
                                temp.remove(5);
                                temp.remove(9);
                                cols = temp.toArray(new String[temp.size()]);
                            }
                        }
                    }

                }
            }

            if (cols.length == 8) {
                try {
                    BankStatement bs = bsFromCols(cols, issuerSerialNumber, issuerIp, dateTime);
                    bsList.add(bs);
                } catch (Exception e) {
                    errorMessages += messageSource.getMessage("upload.error_convert_bs", null,
                            LocaleContextHolder.getLocale()) + " " + lineCurrent + " <br/>";
                }
            } else {
                errorMessages += messageSource.getMessage("upload.error_over_columns", null,
                        LocaleContextHolder.getLocale()) + " " + lineCurrent + " <br/>";
            }

        }
        br.close();
        fis.close();

        bankStatementDao.saveBankStatements(bsList);
        bankStatementDao.saveToPayment();
        bankStatementDao.saveToReportClick();
        bankStatementDao.saveToReportSmst();

        return errorMessages;
    }

    @Override
    public void backupAndRelease(File file, File extractedFile) throws Exception {
        /**
         * Release extracted file
         */
        if (extractedFile != null && extractedFile.exists()) {
            extractedFile.delete();
        }
        if (file != null && file.exists()) {
            file.delete();
        }

        /**
         * Backup file
         */
        //        File backupFile = new File(getBackupDir() + File.separator + file.getName());
        //        if (file.exists()) {
        //            boolean renamed = file.renameTo(backupFile);
        //
        //            /**
        //             * Force renaming
        //             */
        //            if (!renamed) {
        //                byte[] buffer = new byte[4096];
        //                try {
        //                    FileInputStream fis = new FileInputStream(file);
        //                    FileOutputStream fout = new FileOutputStream(backupFile);
        //                    int bytesRead;
        //                    while ((bytesRead = fis.read(buffer)) != -1) {
        //                        fout.write(buffer, 0, bytesRead);
        //                    }
        //                    fis.close();
        //                    fout.close();
        //                } catch (IOException ex) {
        //                    throw new Exception(ex.getMessage());
        //                }
        //                file.delete();
        //            }
        //        }

    }

    @Override
    public List<BankStatementListPojo> getList(HashMap parameters) throws Exception {
        return bankStatementDao.list(parameters);
    }

    @Override
    public void editPaymentDate(String bankStatementId, Date paymentDate, Long issuerSerialNumber, String issuerIp)
            throws Exception {
        bankStatementDao.editPaymentDate(bankStatementId, paymentDate, issuerSerialNumber, issuerIp);
    }

    @Override
    public void editActionKey(String bankStatementId, String tin, Long issuerSerialNumber, String issuerIp)
            throws Exception {
        bankStatementDao.editActionKey(bankStatementId, tin, issuerSerialNumber, issuerIp);
    }

    @Override
    public void remove(String bankStatementId) throws Exception {
        bankStatementDao.checkAndRemoveBankStatement(bankStatementId);
    }

    @Override
    public List<InvoicePojo> getSingleInvoice(String bankStatementId) throws Exception {
        BankStatement bs = bankStatementDao.getByBankStatementId(bankStatementId);
        if (bs.getInvoiceNum() == null) {
            int year = Integer.parseInt(new SimpleDateFormat("yyyy").format(bs.getPaymentDate()));
            bankStatementDao.updateInvoiceNums(year);

            bs = bankStatementDao.getByBankStatementId(bankStatementId);
        }
        List<InvoicePojo> inList = new ArrayList<>();
        inList.add(getInvoicePojoFromBankStatement(bs));

        return inList;
    }

    @Override
    public List<InvoicePojo> getFullInvoice(Integer year, Long from, Long to) throws Exception {
        bankStatementDao.updateInvoiceNums(year);

        List<InvoicePojo> inList = new ArrayList<>();
        List<BankStatement> bsList = bankStatementDao.getListByInvoice(year, from, to);
        for (BankStatement bs : bsList) {
            inList.add(getInvoicePojoFromBankStatement(bs));
        }

        return inList;
    }

    private InvoicePojo getInvoicePojoFromBankStatement(BankStatement bs) {
        InvoicePojo in = new InvoicePojo();

        in.setTin(bs.getTin());
        in.setName(bs.getName());
        in.setMfo(bs.getMfo());
        in.setChet(bs.getChet());
        in.setInvoiceNum(bs.getInvoiceNum());
        in.setPaymentNum(bs.getPaymentNum());
        in.setPaymentDate(new SimpleDateFormat("dd.MM.yyyy").format(bs.getPaymentDate()));
        in.setPaymentSum(bs.getPaymentSum());
        in.setPaymentSumText(numberService.convertToText(bs.getPaymentSum().doubleValue()));
        in.setPaymentDetails(bs.getPaymentDetails());

        return in;
    }

    @Override
    public List<PrintClaimPojo> getPrintClaimList(Date periodStart, Date periodEnd) throws Exception {
        return bankStatementDao.getPrintClaimList(periodStart, periodEnd);
    }

    @Override
    public List<PrintRegisterPojo> getPrintRegisterList(Date periodStart, Date periodEnd) throws Exception {
        return bankStatementDao.getPrintRegisterList(periodStart, periodEnd);
    }

    @Override
    public List<PrintClaimRegisterPojo> getPrintClaimRegisterList(Date periodStart, Date periodEnd)
            throws Exception {
        return bankStatementDao.getPrintClaimRegisterList(periodStart, periodEnd);
    }

    @Override
    public BankStatement getBankStatementForPaymentManual(String bankStatementId) throws Exception {
        return bankStatementDao.getByBankStatementId(bankStatementId);
    }

}