/*
 * Arrebol Consultancy copyright.
 * 
 * This code belongs to Arrebol Consultancy
 * its use, redistribution or modification are prohibited 
 * without written authorization from Arrebol Consultancy.
 */
package com.arrebol.taxiservicios.controller.admin;

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.admin.AvisosChofer;
import com.arrebol.taxiservicios.model.admin.FeeByDriver;
import com.arrebol.taxiservicios.model.admin.FeeByDriverGroup;
import com.arrebol.taxiservicios.model.admin.Sanction;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.dashboard.FeeDashboardPersonListView;
import com.arrebol.taxiservicios.model.enums.FeeType;
import com.arrebol.taxiservicios.model.view.dashboard.FeeByDriverDashboardView;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author Carlos Janitzio Zavala Lopez <janitzio.zavala@arrebol.com.mx>
 */
public class FeeByDriverController extends ConnectionManager implements Serializable {

    /**
     *
     * @param feeByDriver
     * @return
     */
    public boolean saveFeeByDriver(FeeByDriver feeByDriver) {
        logger.info("saveFeeByDriver");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            session.save(feeByDriver);

            transaction.commit();
            success = true;

            logger.info("Fee by driver was saved " + feeByDriver);
        } catch (HibernateException e) {
            logger.error("Fee by driver can not be saved ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveFeeByDriver() ", e);
            rollback(transaction);
        }

        return success;
    }

    /**
     *
     * @param feeId
     * @return
     */
    public boolean deleteFeeByDriverById(String feeId) {
        logger.info("deleteFeeByDriverById");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaDelete<FeeByDriver> delete = builder.createCriteriaDelete(FeeByDriver.class);
            Root<FeeByDriver> root = delete.from(FeeByDriver.class);

            delete.where(builder.equal(root.get("id"), feeId));

            session.createQuery(delete).executeUpdate();

            transaction.commit();
            success = true;

            logger.info("Fee by driver was deleted");
        } catch (HibernateException e) {
            logger.error("Fee by driver could not be deleted", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method deleteFeeByDriverById()", e);
            rollback(transaction);
        }

        return success;
    }

    /**
     *
     * @param feeId
     * @param status
     * @param comment
     * @param lastUpdatedBy
     * @param sanction
     * @return
     */
    public boolean updateFeeStatusById(String feeId, FeeType status, String comment, User lastUpdatedBy, Sanction sanction) {
        logger.info("updateFeeStatusById");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<FeeByDriver> updateQuery = builder.createCriteriaUpdate(FeeByDriver.class);
            Root<FeeByDriver> root = updateQuery.from(FeeByDriver.class);

            updateQuery.set(root.get("status"), status);
            updateQuery.set(root.get("comment"), comment);
            updateQuery.set(root.get("lastUpdatedBy"), lastUpdatedBy);
            updateQuery.set(root.get("lastUpdatedOn"), new Date());

            updateQuery.where(builder.equal(root.get("id"), feeId));

            session.createQuery(updateQuery).executeUpdate();

            if (null != sanction && FeeType.PAID.equals(status)) {
                sanction.setActive(false);
                session.save(sanction);
                logger.info("Sanction saved " + sanction);
            }

            transaction.commit();
            success = true;

            logger.info("Fee by driver was updated");
        } catch (HibernateException e) {
            logger.error("Fee by driver could not be updated", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updateFeeStatusById()", e);
            rollback(transaction);
        }

        return success;
    }

    /**
     *
     * @param startDate
     * @param endDate
     * @param driverId
     * @return
     */
    public List<FeeByDriverDashboardView> findFeesByDriverBetweenDates(Date startDate, Date endDate, String driverId) {
        List<FeeByDriverDashboardView> results = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            StringBuilder hql = new StringBuilder("FROM FeeByDriverDashboardView WHERE driverId = :driverId ");

            hql.append("AND DATE(feeDate) BETWEEN DATE(:startDate) AND DATE(:endDate) ");
            hql.append("ORDER BY feeDate");

            results = session.createQuery(hql.toString(), FeeByDriverDashboardView.class)
                    .setParameter("driverId", driverId)
                    .setParameter("startDate", startDate)
                    .setParameter("endDate", endDate)
                    .getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Fees from view can not be loaded", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeesByDriverBetweenDates()", e);
            rollback(transaction);
        }

        return results;
    }

    /**
     *
     * @param startDate
     * @param endDate
     * @param driveId
     * @return
     */
    public List<FeeByDriver> findFeesBetweenDatesByDriver(Date startDate, Date endDate, String driveId) {
        logger.info("findFeesBetweenDatesByDriver");

        List<FeeByDriver> results = new ArrayList<>();
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<FeeByDriver> query = builder.createQuery(FeeByDriver.class);
            Root<FeeByDriver> root = query.from(FeeByDriver.class);

            Path<String> id = root.get("id");
            Path<Person> driver = root.get("driver");
            Path<Date> feeDate = root.get("feeDate");
            Path<Double> amount = root.get("amount");
            Path<String> comment = root.get("comment");

            Predicate eqDriver = builder.equal(root.get("driver"), new Person(driveId));
            Predicate gtEqStartDate = builder.greaterThanOrEqualTo(root.get("feeDate"), startDate);
            Predicate ltEqEndDate = builder.lessThanOrEqualTo(root.get("feeDate"), endDate);
            Predicate eqStatus = builder.equal(root.get("status"), FeeType.NO_PAID);

            query.select(
                    builder.construct(FeeByDriver.class,
                            id, driver, feeDate, amount, comment
                    ));
            query.where(eqDriver, gtEqStartDate, ltEqEndDate, eqStatus);
            query.orderBy(builder.asc(root.get("feeDate")));

            results = session.createQuery(query).getResultList();

            transaction.commit();

            logger.info("Total of fees loaded " + results.size());
        } catch (HibernateException e) {
            logger.error("Fees by driver could not be loaded", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeesBetweenDatesByDriver()", e);
            rollback(transaction);
        }

        return results;
    }

    /**
     *
     * @param startDate
     * @param endDate
     * @param driveId
     * @return
     */
    public List<FeeByDriver> findFeesPaidBetweenDatesByDriver(Date startDate, Date endDate, String driveId) {
        logger.info("findFeesBetweenDatesByDriver");

        List<FeeByDriver> results = new ArrayList<>();
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<FeeByDriver> query = builder.createQuery(FeeByDriver.class);
            Root<FeeByDriver> root = query.from(FeeByDriver.class);

            Path<String> id = root.get("id");
            Path<Person> driver = root.get("driver");
            Path<Date> feeDate = root.get("feeDate");
            Path<Double> amount = root.get("amount");
            Path<String> comment = root.get("comment");

            Predicate eqDriver = builder.equal(root.get("driver"), new Person(driveId));
            Predicate gtEqStartDate = builder.greaterThanOrEqualTo(root.get("feeDate"), startDate);
            Predicate ltEqEndDate = builder.lessThanOrEqualTo(root.get("feeDate"), endDate);
            Predicate eqStatus = builder.equal(root.get("status"), FeeType.PAID);

            query.select(
                    builder.construct(FeeByDriver.class,
                            id, driver, feeDate, amount, comment
                    ));
            query.where(eqDriver, gtEqStartDate, ltEqEndDate, eqStatus);
            query.orderBy(builder.asc(root.get("feeDate")));

            results = session.createQuery(query).getResultList();

            transaction.commit();

            logger.info("Total of fees loaded " + results.size());
        } catch (HibernateException e) {
            logger.error("Fees by driver could not be loaded", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeesBetweenDatesByDriver()", e);
            rollback(transaction);
        }

        return results;
    }

    /**
     *
     * @param driver
     * @param user
     * @return
     */
    public boolean payAllFeesByDriverId(Person driver, User user) {
        logger.info("payAllFeesByDriverId");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<FeeByDriver> updateQuery = builder.createCriteriaUpdate(FeeByDriver.class);
            Root<FeeByDriver> root = updateQuery.from(FeeByDriver.class);

            updateQuery.set(root.get("status"), FeeType.PAID);
            updateQuery.set(root.get("comment"), "Multa pagada desde 'Pagar todas las multas en Administración / Ventas / Multas'");
            updateQuery.set(root.get("lastUpdatedBy"), user);
            updateQuery.set(root.get("lastUpdatedOn"), new Date());

            updateQuery.where(builder.equal(root.get("driver"), driver));

            int total = session.createQuery(updateQuery).executeUpdate();

            transaction.commit();
            logger.info("Total of fees paid " + total);

            success = true;
        } catch (HibernateException e) {
            logger.error("Fees by driver could not be loaded", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method payAllFeesByDriverId()", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     *
     * @param driver
     * @param status
     * @return
     */
    public List<FeeByDriver> findAllFeesByDriverAndStatus(Person driver, FeeType status) {
        logger.info("findAllFeesByDriverAndStatus");

        List<FeeByDriver> results = new ArrayList<>();
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<FeeByDriver> query = builder.createQuery(FeeByDriver.class);
            Root<FeeByDriver> root = query.from(FeeByDriver.class);

            Path<String> id = root.get("id");
            Path<Person> person = root.get("driver");
            Path<Date> feeDate = root.get("feeDate");
            Path<Double> amount = root.get("amount");
            Path<String> comment = root.get("comment");

            Predicate equalsToDriver = builder.equal(root.get("driver"), driver);
            Predicate equalsToStatus = builder.equal(root.get("status"), status);

            query.select(
                    builder.construct(FeeByDriver.class,
                            id, person, feeDate, amount, comment
                    ));
            query.where(equalsToDriver, equalsToStatus);
            query.orderBy(builder.asc(root.get("feeDate")));

            results = session.createQuery(query).getResultList();

            transaction.commit();

            logger.info("Total of fees loaded " + results.size());
        } catch (HibernateException e) {
            logger.error("Fees by driver list could not be found", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findAllFeesByDriverAndStatus()", e);
            rollback(transaction);
        }

        return results;
    }

    /**
     *
     * @return
     */
    public List<FeeByDriver> findAllFeesNoPaid() {
        logger.info("findAllFeesNoPaid");

        List<FeeByDriver> results = new ArrayList<>();
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<FeeByDriver> query = builder.createQuery(FeeByDriver.class);
            Root<FeeByDriver> root = query.from(FeeByDriver.class);

            Path<String> id = root.get("id");
            Path<Person> driver = root.get("driver");
            Path<Date> feeDate = root.get("feeDate");
            Path<Double> amount = root.get("amount");
            Path<String> comment = root.get("comment");

            Predicate equalsToStatus = builder.equal(root.get("status"), FeeType.NO_PAID);

            query.select(
                    builder.construct(FeeByDriver.class,
                            id, driver, feeDate, amount, comment
                    ));
            query.where(equalsToStatus);
            query.orderBy(builder.asc(root.get("driver")));
            query.orderBy(builder.asc(root.get("feeDate")));

            results = session.createQuery(query).getResultList();

            transaction.commit();

            logger.info("Total of fees no paid loaded " + results.size());
        } catch (HibernateException e) {
            logger.error("Fees no paid list could not be found", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findAllFeesNoPaid()", e);
            rollback(transaction);
        }

        return results;
    }

    /**
     *
     * @param status
     * @return
     */
    public List<FeeByDriver> findTotalFeesByStatus(FeeType status) {
        logger.info("findTotalFeesByStatus");

        List<FeeByDriver> parseResults = new ArrayList<>();
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            String query = "SELECT fee.driver, SUM(fee.amount), COUNT(fee.id) "
                    + "FROM FeeByDriver fee "
                    + "WHERE fee.status = :status "
                    + "GROUP BY fee.driver ";

            List<Object[]> results = session.createQuery(query, Object[].class)
                    .setParameter("status", status)
                    .getResultList();

            transaction.commit();

            results.forEach(row -> {
                parseResults.add(new FeeByDriver(row));
            });

            logger.info("Find total fees by status loaded " + parseResults.size());
        } catch (HibernateException e) {
            logger.error("Fees no paid list could not be found", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findTotalFeesByStatus()", e);
            rollback(transaction);
        }

        return parseResults;
    }

    /**
     *
     * @return
     */
    public List<FeeDashboardPersonListView> findFeeDashboardPersonListViewByStatus() {
        List<FeeDashboardPersonListView> results = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            results = session.createQuery("FROM FeeDashboardPersonListView")
                    .getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Fees no paid list could not be found", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findFeeDashboardPersonListViewByStatus()", e);
            rollback(transaction);
        }

        return results;
    }

    /**
     *
     * @param selectedFees
     * @param status
     * @param user
     * @param comments
     * @param sanction
     * @return
     */
    public boolean updateAllFeesSelected(List<String> selectedFees, FeeType status, User user, String comments, Sanction sanction) {
        logger.info("updateAllFeesSelected");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<FeeByDriver> updateQuery = builder.createCriteriaUpdate(FeeByDriver.class);
            Root<FeeByDriver> root = updateQuery.from(FeeByDriver.class);

            updateQuery.set(root.get("status"), status);
            updateQuery.set(root.get("comment"), comments);
            updateQuery.set(root.get("lastUpdatedBy"), user);
            updateQuery.set(root.get("lastUpdatedOn"), new Date());

            updateQuery.where(root.get("id").in(selectedFees));

            int total = session.createQuery(updateQuery).executeUpdate();

            if (null != sanction && FeeType.PAID.equals(status)) {
                sanction.setActive(false);
                session.save(sanction);
                logger.info("Sanction saved " + sanction);
            }

            transaction.commit();
            logger.info("Total of fees updated " + total);

            success = true;
        } catch (HibernateException e) {
            logger.error("Update all fees selected", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updateAllFeesSelected()", e);
            rollback(transaction);
        }
        return success;
    }
    
    public List<FeeByDriverGroup> callReportFeeByDriverGroupToMySQLQuery(String starDate, String endDate, Location location) {
        logger.info("callReportFeeByDriverGroupToMySQLQuery");
        logger.info("Fecha inicial de reporte ReportCustomerPay: " + starDate);
        logger.info("Fecha final de reporte ReportCustomerPay: " + endDate);

        List<FeeByDriverGroup> list = new ArrayList<>();
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            List<Object> rows = session.createNativeQuery(queryMySQL)
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("location", location.getId())
                    .getResultList();

            transaction.commit();

            rows.forEach((row) -> {
                Object[] results = (Object[]) row;

                FeeByDriverGroup pay = new FeeByDriverGroup(
                        null == results[0] ? null : results[0].toString(),
                        null == results[1] ? null : results[1].toString(),
                        Long.valueOf(null == results[2] ? "0" : results[2].toString()),
                        Long.valueOf(null == results[3] ? "0" : results[3].toString()),
                        Long.valueOf(null == results[4] ? "0" : results[4].toString()),
                        Long.valueOf(null == results[5] ? "0" : results[5].toString()),
                        Double.valueOf(null == results[6] ? "0" : results[6].toString()),
                        Double.valueOf(null == results[7] ? "0" : results[7].toString()),
                        null == results[8] ? null : results[8].toString(),
                        Integer.valueOf(null == results[9] ? "0" : results[9].toString()),
                        null == results[10] ? null : results[10].toString()
                );

                list.add(pay);
            });

            logger.info("Success callReportFeeByDriverGroupToMySQLQuery");
        } catch (HibernateException e) {
            logger.error("Report customer pay", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method callReportFeeByDriverGroupToMySQLQuery(" + starDate + " " + endDate + ") ", e);
            rollback(transaction);
        }
        return list;
    }
    
    public boolean saveAvisosByDriver(AvisosChofer avisos) {
        logger.info("saveAvisosByDriver");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            session.save(avisos);

            transaction.commit();
            success = true;

            logger.info("Avsiso by driver was saved " + avisos);
        } catch (HibernateException e) {
            logger.error("Avisos by driver can not be saved ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveAvisosByDriver() ", e);
            rollback(transaction);
        }

        return success;
    }
    
    public List<AvisosChofer> findAvisosChofer(String driverId) {
        List<AvisosChofer> results = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            StringBuilder hql = new StringBuilder("FROM AvisosChofer WHERE person.id = :driverId ORDER BY createdOn DESC");

            results = session.createQuery(hql.toString(), AvisosChofer.class)
                    .setParameter("driverId", driverId)
                    .getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Avisos from view can not be loaded", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findAvisosChofer()", e);
            rollback(transaction);
        }

        return results;
    }
    
    private static final long serialVersionUID = -1L;

    final Logger logger = LogManager.getLogger(getClass());
    
    private final String queryMySQL = "SELECT " +
    "p.id, " +
    "CONCAT(p.first_name , ' ', p.last_name) as chofer, " +
    "(SELECT COUNT(id) FROM FEE_BY_DRIVER where driver_id = p.id AND fee_status IN ('PAID','NO_PAID','DELETED') and DATE(created_on) between STR_TO_DATE(:starDate, '%Y-%m-%d') AND STR_TO_DATE(:endDate,'%Y-%m-%d')) as num_fee, " +
    "(SELECT COUNT(id) FROM FEE_BY_DRIVER where driver_id = p.id AND fee_status IN ('PAID') and DATE(last_updated_on) between STR_TO_DATE(:starDate, '%Y-%m-%d') AND STR_TO_DATE(:endDate,'%Y-%m-%d')) as total_num_fee_paid, " +
    "(SELECT COUNT(id) FROM FEE_BY_DRIVER where driver_id = p.id AND fee_status IN ('NO_PAID') and DATE(created_on) between STR_TO_DATE(:starDate, '%Y-%m-%d') AND STR_TO_DATE(:endDate,'%Y-%m-%d')) as total_num_fee_to_paid, " +
    "(SELECT COUNT(id) FROM FEE_BY_DRIVER where driver_id = p.id AND fee_status IN ('DELETED') and DATE(last_updated_on) between STR_TO_DATE(:starDate, '%Y-%m-%d') AND STR_TO_DATE(:endDate,'%Y-%m-%d')) as total_num_fee_condonadas, " +
    "(SELECT IF(ISNULL(sum(amount)) , 0 , sum(amount)) FROM FEE_BY_DRIVER where driver_id = p.id AND fee_status IN ('PAID') and DATE(last_updated_on) between STR_TO_DATE(:starDate, '%Y-%m-%d') AND STR_TO_DATE(:endDate,'%Y-%m-%d')) as total_fee_paid, " +
    "(SELECT IF(ISNULL(sum(amount)) , 0 , sum(amount)) FROM FEE_BY_DRIVER where driver_id = p.id AND fee_status IN ('NO_PAID') and DATE(created_on) between STR_TO_DATE(:starDate, '%Y-%m-%d') AND STR_TO_DATE(:endDate,'%Y-%m-%d')) as total_fee_to_paid, " +
    "DATE(p.admission_date) as fechaRegisto, " + 
    "(SELECT COUNT(id) FROM AVISOS_CHOFER WHERE id_person = p.id) as numAvisos, "+
    "CASE WHEN p.active = 1 THEN 'Activo' \n" +
"    WHEN p.active = 0 AND (black_list = 'DISABLED' OR black_list is null) THEN 'Banca'\n" +
"    WHEN p.active = 0 AND black_list = 'ENABLED' THEN 'Lista negra'\n" +
"    END as status "+
    "FROM PERSON p where p.person_type = 'DRIVER' AND p.id_location = :location "
    + "ORDER BY (SELECT COUNT(id) FROM FEE_BY_DRIVER where driver_id = p.id AND fee_status IN ('PAID','NO_PAID','DELETED') and DATE(created_on) between STR_TO_DATE(:starDate, '%Y-%m-%d') AND STR_TO_DATE(:endDate,'%Y-%m-%d')) DESC";
}
