/*
 * 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.arrebol.taxiservicios.controller.admin;

import com.arrebol.taxiservicios.controller.util.DateWrapper;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.admin.FinancingDriver;
import com.arrebol.taxiservicios.model.admin.Reference;
import com.arrebol.taxiservicios.model.admin.ReleaseResource;
import com.arrebol.taxiservicios.model.admin.Taxi;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.Address;
import com.arrebol.taxiservicios.model.core.ContactNumber;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.view.DriverInactiveAndBlackListView;
import com.arrebol.taxiservicios.model.view.PersonListCustomerFinancingView;
import com.arrebol.taxiservicios.model.view.PersonListFinancingView;
import com.arrebol.taxiservicios.model.view.PersonListView;
import com.crov.prase.model.prase.Incidence;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.persistence.criteria.CriteriaBuilder;
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;
import org.hibernate.query.Query;

/**
 *
 * @author Picasso
 */
public class DriverController extends GenericPersonController implements Serializable {

    public boolean editBlackListDriver(String id, String blackListDescription, Float adeudo, User lastUpdatedBy) {
        boolean success = false;
        Transaction transaction = null;

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

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<Person> update = builder.createCriteriaUpdate(Person.class);
            Root<Person> rootPerson = update.from(Person.class);

            update.set("blackListDescription", blackListDescription);
            update.set("adeudo", adeudo);
            update.set("lastUpdatedBy", lastUpdatedBy);

            update.where(builder.equal(rootPerson.get("id"), id));

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

            if (1 == total) {
                logger.info("Person updated employe_id: " + id);
                transaction.commit();

                success = true;
            } else {
                logger.error("Person can not be updated " + id);
                transaction.rollback();
            }
        } catch (HibernateException e) {
            logger.error("Person cannot be updated " + id, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method editBlackListDriver(" + id + ") ", e);
            rollback(transaction);
        }
        return success;
    }

    public boolean updatePersonById(String firstName, String secondName,
            String lastName, String middleName, Date birthdate,
            Date admissionDate, String personId, String userName, float adeudo, String locationId, BasicType juridico) {
        logger.info("updateEmployeeById");

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

            /**
             * Taxi Servicios goes for user details.
             */
            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<User> criteria = builder.createQuery(User.class);
            Root<User> root = criteria.from(User.class);
            Path<String> idPath = root.get("id");
            Path<String> userNamePath = root.get("userName");

            criteria.select(builder.construct(User.class, idPath, userNamePath));
            criteria.where(builder.equal(root.get("userName"), userName));

            User user = session.createQuery(criteria).uniqueResult();

            builder = session.getCriteriaBuilder();
            CriteriaUpdate<Person> update = builder.createCriteriaUpdate(Person.class);
            Root<Person> rootPerson = update.from(Person.class);

            update.set("firstName", firstName);
            update.set("secondName", secondName);
            update.set("lastName", lastName);
            update.set("middleName", middleName);
            update.set("birthdate", birthdate);
            update.set("admissionDate", admissionDate);
            update.set("lastUpdatedBy", user);
            update.set("lastUpdatedOn", new Date());
            update.set("adeudo", adeudo);
            update.set("juridico", juridico);
            update.set("location", new Location(locationId));

            update.where(builder.equal(rootPerson.get("id"), personId));

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

            if (1 == total) {
                logger.info("Person updated employe_id: " + personId);
                transaction.commit();

                success = true;
            } else {
                logger.error("Person can not be updated " + personId);
                transaction.rollback();
            }
        } catch (HibernateException e) {
            logger.error("Person cannot be updated " + personId, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updatePersonById(" + personId + ") ", e);
            rollback(transaction);
        }
        return success;
    }

    private static final long serialVersionUID = -6265444716269535946L;

    final Logger logger = LogManager.getLogger(DriverController.class);

    /**
     * Update Dirver card details
     *
     * @param ife IFE number.
     * @param license License number.
     * @param expirationLicense Expiration license date.
     * @param driverId Driver identify number.
     * @param userId Last updated user id.
     * @return True if details were saved otherwise talse.
     */
    public boolean updateDriverCardDetails(String ife, String license,
            Date expirationLicense, String driverId, String userId) {
        logger.info("updateDriverCardDetails");

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

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

            update.set("ife", ife);
            update.set("license", license);
            update.set("expirationLicenseDate", expirationLicense);
            update.set("lastUpdatedBy", new User(userId, ""));
            update.set("lastUpdatedOn", new Date());

            update.where(builder.equal(root.get("id"), driverId));

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

            if (1 == total) {
                transaction.commit();

                success = true;
                logger.info("Driver card details updated");
            } else {
                transaction.rollback();

                logger.error("Driver card details can't updated");
            }

        } catch (HibernateException e) {
            logger.error("Driver card details cannot be updated " + driverId, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveOrUpdateDriverCardDetails(" + driverId + ") ", e);
            rollback(transaction);
        }
        return success;
    }

    public boolean updateDriverAvalDetails(String name, String parentesco,
            String phone, String driverId, String userId) {
        logger.info("updateDriverAvalDetails");

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

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

            update.set("nameEndorsement", name);
            update.set("parentescoEndorsement", parentesco);
            update.set("phoneEndorsement", phone);
            update.set("lastUpdatedBy", new User(userId, ""));
            update.set("lastUpdatedOn", new Date());

            update.where(builder.equal(root.get("id"), driverId));

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

            if (1 == total) {
                transaction.commit();

                success = true;
                logger.info("Driver aval details updated");
            } else {
                transaction.rollback();

                logger.error("Driver aval details can't updated");
            }

        } catch (HibernateException e) {
            logger.error("Driver aval details cannot be updated " + driverId, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updateDriverAvalDetails(" + driverId + ") ", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     * Save personal references from taxi driver.
     *
     * @param references Reference details list (Name, Reference type, Contact
     * number).
     * @param save True save otherwise update.
     *
     * @return True is references were saved successfully otherwise false.
     */
    public boolean saveOrUpdateReference(List<Reference> references, boolean save) {
        logger.info("saveOrUpdateReference");

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

            if (save) {
                references.forEach((Reference reference) -> {
                    reference.setCreatedOn(new Date());
                    session.save(reference);
                    logger.info("Driver references " + reference + " before commit and save");
                });
            } else {
                CriteriaBuilder builder = session.getCriteriaBuilder();
                CriteriaUpdate<Reference> update = builder.createCriteriaUpdate(Reference.class);
                Root<Reference> root = update.from(Reference.class);

                references.forEach((Reference reference) -> {
                    update.set("completeName", reference.getCompleteName());
                    update.set("completeAddress", reference.getCompleteAddress());
                    update.set("phone", reference.getPhone());
                    update.set("referenceType", reference.getReferenceType());
                    update.set("lastUpdatedBy", reference.getLastUpdatedBy());
                    update.set("lastUpdatedOn", new Date());

                    update.where(builder.equal(root.get("id"), reference.getId()));
                    session.createQuery(update).executeUpdate();
                    logger.info("Driver references " + reference + " before commit and update");
                });
            }

            transaction.commit();

            success = true;
            logger.info("Driver references saved");
        } catch (HibernateException e) {
            logger.error("Driver references details cannot be updated " + references, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveOrUpdateReference(" + references + ") ", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     * Do a logical delete from an person in the system
     *
     * @param personId
     * @param user
     * @return True if employee was logical deleted otherwise false.
     */
    public boolean updateStatusDriverAndRemoveFromTaxi(String personId, User user) {
        logger.info("deletePersonById");

        boolean success = false;
        Transaction transaction = null;
        try {
            Person driver = new Person(personId);
            Taxi taxi = findTaxiByDriver(driver);

            if (removeDriverFromTaxi(driver)) {
                ReleaseResourceController releaseResourceController = new ReleaseResourceController();

                if (!releaseResourceController.findReleaseResourcesByIdAndActiveStatus(personId, GenericEnumType.ENABLED, true)) {
                    Date date = DateWrapper.getTodayMXTime();
                    ReleaseResource resource = new ReleaseResource(UUID.randomUUID().toString(), driver, date, GenericEnumType.ENABLED, user, date);

                    if (releaseResourceController.saveReleaseResource(resource) && null != taxi) {
                        resource = new ReleaseResource(UUID.randomUUID().toString(), taxi, date, GenericEnumType.ENABLED, user, date);
                        releaseResourceController.saveReleaseResource(resource);
                    }
                }

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

                CriteriaBuilder builder = session.getCriteriaBuilder();
                CriteriaUpdate<Person> update = builder.createCriteriaUpdate(Person.class);
                Root<Person> rootUpdate = update.from(Person.class);

                update.set("active", false);
                update.set("lastUpdatedBy", user);
                update.set("lastUpdatedOn", new Date());
                update.where(builder.equal(rootUpdate.get("id"), personId));

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

                if (1 == total) {
                    transaction.commit();
                    success = true;
                    logger.info("Person " + personId + " deleted");
                } else {
                    transaction.rollback();
                    logger.error("Error Person deleted total: " + total);
                }
            }
        } catch (HibernateException e) {
            logger.error("Person can not be deleted ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method deletePersonById() ", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     *
     * @param driver
     * @return
     */
    private boolean removeDriverFromTaxi(Person driver) {
        logger.info("removeDriverIdFromTaxi");

        boolean success = false;
        Transaction transaction = null;

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

            String hql = "SELECT t From Taxi t WHERE driver = :driver";

            Query query = session.createQuery(hql, Taxi.class);

            query.setParameter("driver", driver);

            List<Taxi> taxies = query.getResultList();

            taxies.stream().map(taxi -> {
                taxi.setDriver(null);
                return taxi;
            }).forEachOrdered(taxi -> {
                session.update(taxi);
            });

            transaction.commit();
            success = true;
        } catch (HibernateException e) {
            logger.error("Can not remove Driver Id From Taxi", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method removeDriverIdFromTaxi() ", e);
            rollback(transaction);
        }

        return success;
    }

    /**
     *
     * @param driver
     * @return
     */
    private Taxi findTaxiByDriver(Person driver) {
        logger.info("findTaxiByDriver");

        Taxi taxi = null;
        Transaction transaction = null;

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

            String hql = "SELECT t From Taxi t WHERE driver = :driver";

            Query query = session.createQuery(hql, Taxi.class);

            query.setParameter("driver", driver);

            taxi = (Taxi) query.uniqueResult();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not find taxiby driver", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findTaxiByDriver() ", e);
            rollback(transaction);
        }

        return taxi;
    }

    /**
     *
     * @param type
     * @return
     */
    public List<PersonListView> findListOfPersonsByType(PersonType type, Location location) {
        List<PersonListView> results = null;
        Transaction transaction = null;

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

            String hql = "FROM PersonListView WHERE type = :type AND location = :location";

            results = session.createQuery(hql).setParameter("type", type).setParameter("location", location).getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not list of persons", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findListOfPersonsByType() ", e);
            rollback(transaction);
        }
        return results;
    }

    public List<PersonListView> fillEmpleadosByLocationAndAjustador(Location location, Boolean ajustador) {
        logger.info("fillEmpleadosByLocationAndAjustador");
        List<PersonListView> resultList = null;
        Transaction transaction = null;
        try {
            logger.info("Searching person list view for location..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<PersonListView> criteria = builder.createQuery(PersonListView.class);
            Root<PersonListView> root = criteria.from(PersonListView.class);

            Predicate criterio1 = builder.equal(root.get("location"), location);
            Predicate criterio2 = builder.equal(root.get("ajustador"), ajustador);
            Predicate criterio3 = builder.equal(root.get("type"), PersonType.EMPLOYEE);
            criteria.where(builder.and(criterio1, criterio2, criterio3));

            resultList = session.createQuery(criteria).getResultList();

            logger.info("Total of person list view found: " + (null == resultList ? -1 : resultList.size()));
            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Person list view cannot be loade ");
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillEmpleadosByLocationAndAjustador ", e);
            rollback(transaction);
        }
        return resultList;
    }

    public List<PersonListCustomerFinancingView> findListOfCustomerByType(PersonType type, String idLocation) {
        List<PersonListCustomerFinancingView> results = null;
        Transaction transaction = null;

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

            String hql = "FROM PersonListCustomerFinancingView WHERE type = :type and location.id = :idLocation";

            results = session.createQuery(hql)
                    .setParameter("type", type)
                    .setParameter("idLocation", idLocation)
                    .getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not list of persons", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findListOfCustomerByType() ", e);
            rollback(transaction);
        }
        return results;
    }

    public List<PersonListFinancingView> findListOfPersonsByTypeFinancing(PersonType type, Location location) {
        List<PersonListFinancingView> results = null;
        Transaction transaction = null;

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

            String hql = "FROM PersonListFinancingView WHERE type = :type AND location = :location AND juridico = 'DISABLED'";

            results = session.createQuery(hql).setParameter("type", type).setParameter("location", location).getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not list of persons", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findListOfPersonsByType() ", e);
            rollback(transaction);
        }
        return results;
    }

    /**
     *
     * @param blackList
     * @return
     */
    public List<DriverInactiveAndBlackListView> findListOfInactiveDriversByType(GenericEnumType blackList, Location location) {
        List<DriverInactiveAndBlackListView> results = null;
        Transaction transaction = null;

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

            String hql = "FROM DriverInactiveAndBlackListView WHERE blackList = :blackList AND location = :location";

            results = session.createQuery(hql).setParameter("blackList", blackList).setParameter("location", location).getResultList();

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not list of drivers", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findListOfInactiveDriversByType() ", e);
            rollback(transaction);
        }
        return results;
    }

    public boolean saveFinancingDriver(FinancingDriver financingDriver) {
        boolean success = false;
        Transaction transaction = null;

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

            session.save(financingDriver);
            transaction.commit();

            success = true;

            logger.info("New record was inserted in FinancingDriver");
        } catch (HibernateException e) {
            logger.error("Can not insert a FinancingDriver event", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveFinancingDriver()", e);
            rollback(transaction);
        }
        return success;
    }

    public boolean updateDriver(Person person, User user) {
        logger.info("updateDriver");
        boolean success = false;
        Transaction transaction = null;

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

            person.setLastUpdatedOn(new Date());
            person.setLastUpdatedBy(user);
            session.update(person);
            transaction.commit();
            logger.info("Person updated " + person.getId());

            success = true;
        } catch (HibernateException e) {
            logger.error("Person can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updateDriver() ", e);
            rollback(transaction);
        }
        return success;
    }

    public boolean addAddress(Address address, User user, boolean save) {
        logger.info("addAddress");
        boolean success = false;
        Transaction transaction = null;

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

            if (save) {
                address.setId(UUID.randomUUID().toString());
                address.setCreatedBy(user);
                address.setCreatedOn(new Date());
                session.save(address);
                transaction.commit();
                logger.info("Address saved " + address.getId());
            } else {
                address.setLastUpdatedOn(new Date());
                address.setLastUpdatedBy(user);
                session.update(address);
                transaction.commit();
                logger.info("Address updated " + address.getId());
            }

            success = true;
        } catch (HibernateException e) {
            logger.error("Incidence can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addAddress() ", e);
            rollback(transaction);
        }
        return success;
    }

    public boolean addContactNumber(ContactNumber number, User user, boolean save) {
        logger.info("addContactNumber");
        boolean success = false;
        Transaction transaction = null;

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

            if (save) {
                number.setId(UUID.randomUUID().toString());
                number.setCreatedBy(user);
                number.setCreatedOn(new Date());
                session.save(number);
                transaction.commit();
                logger.info("ContactNumber saved " + number.getId());
            } else {
                number.setLastUpdatedOn(new Date());
                number.setLastUpdatedBy(user);
                session.update(number);
                transaction.commit();
                logger.info("ContactNumber updated " + number.getId());
            }

            success = true;
        } catch (HibernateException e) {
            logger.error("ContactNumber can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addContactNumber() ", e);
            rollback(transaction);
        }
        return success;
    }

    public List<PersonListCustomerFinancingView> callReportCustomerFinancingQueryMySQL(String idLocation) {
        logger.info("PersonListCustomerFinancingView");

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

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

            List<Object> rows = session.createNativeQuery(query)
                    .setParameter("idLocation", idLocation)
                    .getResultList();

            transaction.commit();

            for (Object row : rows) {
                Object[] results = (Object[]) row;

                PersonListCustomerFinancingView pay = new PersonListCustomerFinancingView(
                        null == results[0] ? "" : results[0].toString(),
                        null == results[1] ? "" : results[1].toString(),
                        null == results[2] ? "" : results[2].toString(),
                        null == results[3] ? "" : results[3].toString(),
                        null == results[4] ? "" : results[4].toString(),
                        null == results[5] ? "" : results[5].toString(),
                        null == results[6] ? new Date() : new Date(results[6].toString()),
                        Float.valueOf(null == results[7] ? "0" : results[7].toString())
                );

                list.add(pay);
            };

            logger.info("Success PersonListCustomerFinancingView");
        } catch (HibernateException e) {
            logger.error("Report PersonListCustomerFinancingView", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method PersonListCustomerFinancingView() ", e);
            rollback(transaction);
        }
        return list;
    }

    private String query = "SELECT \n"
            + "        p.id AS id,\n"
            + "        CONCAT((CASE\n"
            + "                    WHEN\n"
            + "                        ((p.first_name IS NOT NULL)\n"
            + "                            AND (p.first_name <> ''))\n"
            + "                    THEN\n"
            + "                        CONCAT(SUBSTR(UPPER(p.first_name), 1, 1),\n"
            + "                                SUBSTR(LOWER(p.first_name), 2),\n"
            + "                                ' ')\n"
            + "                    ELSE ''\n"
            + "                END),\n"
            + "                (CASE\n"
            + "                    WHEN\n"
            + "                        ((p.second_name IS NOT NULL)\n"
            + "                            AND (p.second_name <> ''))\n"
            + "                    THEN\n"
            + "                        CONCAT(SUBSTR(UPPER(p.second_name), 1, 1),\n"
            + "                                SUBSTR(LOWER(p.second_name), 2),\n"
            + "                                ' ')\n"
            + "                    ELSE ''\n"
            + "                END),\n"
            + "                (CASE\n"
            + "                    WHEN\n"
            + "                        ((p.last_name IS NOT NULL)\n"
            + "                            AND (p.last_name <> ''))\n"
            + "                    THEN\n"
            + "                        CONCAT(SUBSTR(UPPER(p.last_name), 1, 1),\n"
            + "                                SUBSTR(LOWER(p.last_name), 2),\n"
            + "                                ' ')\n"
            + "                    ELSE ''\n"
            + "                END),\n"
            + "                (CASE\n"
            + "                    WHEN\n"
            + "                        ((p.middle_name IS NOT NULL)\n"
            + "                            AND (p.middle_name <> ''))\n"
            + "                    THEN\n"
            + "                        CONCAT(SUBSTR(UPPER(p.middle_name), 1, 1),\n"
            + "                                SUBSTR(LOWER(p.middle_name), 2))\n"
            + "                    ELSE ''\n"
            + "                END)) AS full_name,\n"
            + "        (SELECT \n"
            + "                cn.contact_number\n"
            + "            FROM\n"
            + "                CONTACT_NUMBER cn\n"
            + "            WHERE\n"
            + "                ((cn.number_type = 'HOME')\n"
            + "                    AND (cn.person_id = p.id)) LIMIT 1) AS contact_number_local,\n"
            + "        (SELECT \n"
            + "                cn.contact_number\n"
            + "            FROM\n"
            + "                CONTACT_NUMBER cn\n"
            + "            WHERE\n"
            + "                ((cn.number_type = 'MOBILE')\n"
            + "                    AND (cn.person_id = p.id)) LIMIT 1) AS contact_number_mobile,\n"
            + "        (SELECT \n"
            + "                a.address_google_maps\n"
            + "            FROM\n"
            + "                ADDRESS a\n"
            + "            WHERE\n"
            + "                ((a.address_type = 'HOME')\n"
            + "                    AND (a.person_id = p.id))LIMIT 1) AS address,\n"
            + "        (SELECT \n"
            + "                GROUP_CONCAT(CONCAT(TAXI.economic_number)\n"
            + "                        SEPARATOR ',')\n"
            + "            FROM\n"
            + "                TAXI\n"
            + "            WHERE\n"
            + "                (TAXI.customer_id = p.id)\n"
            + "            GROUP BY TAXI.customer_id) AS customer_vehicles,\n"
            + "        p.admission_date AS driver_admission_date,\n"
            + "        IF(((SELECT \n"
            + "                    SUM(TAXI.adeudo_customer)\n"
            + "                FROM\n"
            + "                    TAXI\n"
            + "                WHERE\n"
            + "                    (TAXI.customer_id = p.id AND TAXI.id_location = :idLocation)) IS NULL),\n"
            + "            0,\n"
            + "            (SELECT \n"
            + "                    SUM(TAXI.adeudo_customer)\n"
            + "                FROM\n"
            + "                    TAXI\n"
            + "                WHERE\n"
            + "                    (TAXI.customer_id = p.id AND TAXI.id_location = :idLocation))) AS customer_adeudo \n"
            + "    FROM\n"
            + "        PERSON p\n"
            + "    WHERE\n"
            + "        (p.active = 1) AND (SELECT COUNT(t.id) FROM TAXI t where t.id_location = :idLocation AND t.customer_id = p.id) > 0 \n"
            + "    ORDER BY CONCAT((CASE\n"
            + "                WHEN\n"
            + "                    ((p.first_name IS NOT NULL)\n"
            + "                        AND (p.first_name <> ''))\n"
            + "                THEN\n"
            + "                    CONCAT(SUBSTR(UPPER(p.first_name), 1, 1),\n"
            + "                            SUBSTR(LOWER(p.first_name), 2),\n"
            + "                            ' ')\n"
            + "                ELSE ''\n"
            + "            END),\n"
            + "            (CASE\n"
            + "                WHEN\n"
            + "                    ((p.second_name IS NOT NULL)\n"
            + "                        AND (p.second_name <> ''))\n"
            + "                THEN\n"
            + "                    CONCAT(SUBSTR(UPPER(p.second_name), 1, 1),\n"
            + "                            SUBSTR(LOWER(p.second_name), 2),\n"
            + "                            ' ')\n"
            + "                ELSE ''\n"
            + "            END),\n"
            + "            (CASE\n"
            + "                WHEN\n"
            + "                    ((p.last_name IS NOT NULL)\n"
            + "                        AND (p.last_name <> ''))\n"
            + "                THEN\n"
            + "                    CONCAT(SUBSTR(UPPER(p.last_name), 1, 1),\n"
            + "                            SUBSTR(LOWER(p.last_name), 2),\n"
            + "                            ' ')\n"
            + "                ELSE ''\n"
            + "            END),\n"
            + "            (CASE\n"
            + "                WHEN\n"
            + "                    ((p.middle_name IS NOT NULL)\n"
            + "                        AND (p.middle_name <> ''))\n"
            + "                THEN\n"
            + "                    CONCAT(SUBSTR(UPPER(p.middle_name), 1, 1),\n"
            + "                            SUBSTR(LOWER(p.middle_name), 2))\n"
            + "                ELSE ''\n"
            + "            END))";

}
