Pergunta

I have a repository that has two function that return the values from 3 related entities. Vehicle--OneToMany--Jobs, Vehivle--OneToMany--FuelPurchase

in vehicle I have the following working repository:

class VehicleRepository extends EntityRepository
{
public function findByFuelXVehicle ($dateStart = null, $dateEnd=null)
{
    $query = $this->createQueryBuilder('v')
            ->select('v.plateNumber',
                    'SUM(f.fuelUsed) as totalFuel',
                    'SUM(f.fuelUsed*f.fuelPrice) as totalFuelCost')
            ->join('v.fuelPurchaces', 'f')
            ->groupBy('v.plateNumber')
            ->getQuery()->getResult();

    return $query;
}
public function findByJobXVehicle($dateStart = null, $dateEnd=null){
    $query = $this->createQueryBuilder('v')
                ->select('v.plateNumber','SUM(j.kmOdoEnd - j.kmOdoStart)')
                ->join('v.jobs', 'j')
                ->groupBy('v.plateNumber');
             $q = $query->getQuery()->getResult();
    return $q;
}
}

How do I integrate the results of this two functions in only one in a way that I can give a result of both queries integrated by idVehicle represented by v in these functions. Something like this: Result table

I have tried a function that goes through the array but I can manage to make it work.

public function findByIntegrated ($dateStart = null, $dateEnd=null)
{
    $fuels = $this->findByFuelXVehicle($dateStart = null, $dateEnd=null);
    $jobs = $this->findByJobXVehicle($dateStart = null, $dateEnd=null);
    $jobAndFuel = null;
    foreach ($jobs as $key => $job){
         $jobAndFuel[$key]['plateNumber']=$job['plateNumber'];
         $jobAndFuel[$key]['totalDistance']=$job['totalDistance'];
         $jobAndFuel[$key]['countJob']=$job['countJob'];
    }
    for ($i =0;$i<count($fuels);$i++){
        for($k=0;$k<count($jobAndFuel);$k++){
            if ($jobAndFuel[$k]['plateNumber'] == $fuels[$i]['plateNumber']){
                $jobAndFuel[$k]['totalFuel']=$fuels[$i]['totalFuel'];
                $jobAndFuel[$k]['totalFuelCost']=$fuels[$i]['totalFuelCost'];
            }
        }
    }
    return $jobAndFuel;
}
}

The problem is that Is when not all the cars have or fuel logs or Jobs.

Foi útil?

Solução

It resulted bo be a little bit more complex than I thought, but I managed to make it work using information from here and there.

<?php

namespace TeamERP\TransportBundle\Entity;

use Doctrine\ORM\EntityRepository;

class VehicleRepository extends EntityRepository
{
/* Find vehicle fuel log stats*/
private function findByFuelXVehicle ($dateStart = null, $dateEnd=null)
{
    $query = $this->createQueryBuilder('v')
            ->select('v.plateNumber',
                    'SUM(f.fuelUsed) as totalFuel',
                    'SUM(f.fuelUsed*f.fuelPrice) as totalFuelCost')
            ->join('v.fuelPurchaces', 'f');
            if ($dateStart != null && $dateEnd != null){
                        $query->where('f.dateTime > :dateStart and f.dateTime < :dateEnd')
                        ->setParameter('dateStart', $dateStart)
                        ->setParameter('dateEnd', $dateEnd);
                    }
            $q =$query->groupBy('v.plateNumber')
            ->getQuery()->getResult();
    return $q;
}
/* Find vehicle Job stats*/
private function findByJobXVehicle($dateStart = null, $dateEnd=null){
    $query = $this->createQueryBuilder('v')
                ->select('v.plateNumber'
                        ,'SUM(j.kmOdoEnd - j.kmOdoStart) as totalDistance',
                    'COUNT(j.idJob) as countJob')
                ->join('v.jobs', 'j');
                if ($dateStart != null && $dateEnd != null){                
                    $query->where('j.dateTime > :dateStart and j.dateTime < :dateEnd')
                    ->setParameter('dateStart', $dateStart)
                    ->setParameter('dateEnd', $dateEnd);
                }
                $query->groupBy('v.plateNumber');
             $q = $query->getQuery()->getResult();
    return $q;
}
/* Join stats for fuel logs and Jobs*/
public function findByIntegrated ($dateStart = null, $dateEnd=null)
{
    $fuels = $this->findByFuelXVehicle($dateStart, $dateEnd);
    $jobs = $this->findByJobXVehicle($dateStart, $dateEnd);
    $jobAndFuel = null;
    foreach ($jobs as $key => $job){
         $jobAndFuel[$key]['plateNumber']=$job['plateNumber'];
         $jobAndFuel[$key]['totalDistance']=$job['totalDistance'];
         $jobAndFuel[$key]['countJob']=$job['countJob'];
    }
    return $this->mergeWithJobs($jobAndFuel, $fuels);
}
/* Merge arrays for fuel and jobs; join both array*/
private function mergeWithJobs ($jobAndFuel, $fuels){
    //var_dump($jobAndFuel);
        for ($i =0;$i<count($fuels);$i++){
            $key = $this->searchArray($jobAndFuel, $fuels[$i]['plateNumber']);
            if ($key != false) { 
                    $jobAndFuel[$key]['totalFuel']=$fuels[$i]['totalFuel'];
                    $jobAndFuel[$key]['totalFuelCost']=  round($fuels[$i]['totalFuelCost'], 2);                    
            } else {
                $aux = count($jobAndFuel);
                    $jobAndFuel[$aux+1]['plateNumber']=$fuels[$i]['plateNumber'];
                    $jobAndFuel[$aux+1]['totalFuel']=$fuels[$i]['totalFuel'];
                    $jobAndFuel[$aux+1]['totalFuelCost']=round($fuels[$i]['totalFuelCost'], 2);
            }
        }
    return $jobAndFuel;            
}
/*Serch for a value in a bidimantional array;
 * consider moving this function to a general class*/
private function searchArray ($arrayOfResults, $needle)
{
   foreach($arrayOfResults as $key => $arrayOfResult)
   {
      if ( $arrayOfResult['plateNumber'] === $needle )
         return $key;
   }
   return false;
}
}

Thank you all!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top