Cgridview - Operazioni Di Calcolo

Salve a tutti.

In un progetto sviluppato per la gestione delle vendite al banco ,di articoli di abbigliamento ,spesso i cassieri necessitano di visualizzare a piè di griglia l’importo totale delle vendite , gli sconti effettuati , l’importo dei resi , l’importo dei buoni emessi… etc. , insomma un sommario di tutte le operazioni effettuate sulla base dei criteria di ricerca messi a disposizione da CgridView. Tale sommario “dovrebbe” tener conto però dei record paginati e non.

Es.

Su una griglia con pageSize a 10 record ,attualmente, un sommario calcolerebbe solo la somma o la differenza dei dieci record, senza calcolare quelli nelle successive pagine. Certo si potrebbe aumentare il numero di paginazione degli elementi da visualizzare,ma ciò porterebbe tanta lentezza ,soprattutto se dietro vi è un relazionato complesso ed il dataset estratto non è conosciuto(chiaramente!).

Al momento, adotto questo tipo di soluzione che a dire il vero, ho preso in prestito da un altro post:




public function getSearchCriteria()

{

    $criteria=new CDbCriteria;


    $criteria->compare('id',$this->id);

    $criteria->compare('name',$this->data_vendita);

    $criteria->compare('stock',$this->stock);

    $criteria->compare('user_id',$this->user_id);

   //etc .. etc...

    return $criteria;

}


public function search()

{

    return new CActiveDataProvider(get_class($this), array(

        'criteria'=>$this->getSearchCriteria(),

    ));

}


public function totaleVenduto()

{

    $criteria=$this->getSearchCriteria();

    $criteria->select='SUM(somecolumn)';

    return $this->commandBuilder->createFindCommand($this->getTableSchema(),$criteria)->queryScalar();

}


public function totaleReso()

{

    $criteria=$this->getSearchCriteria();

    $criteria->select='SUM(somecolumn)';

    return $this->commandBuilder->createFindCommand($this->getTableSchema(),$criteria)->queryScalar();

}

public function totaleSospeso()

{

    $criteria=$this->getSearchCriteria();

    $criteria->select='SUM(somecolumn)';

    return $this->commandBuilder->createFindCommand($this->getTableSchema(),$criteria)->queryScalar();

}



Questo approccio è davvero funzionale!

Ma…profilando l’applicazione ,mi son reso conto che ognuno dei metodi che effettua il conteggio, richiama il criteria originario.

Ciò porta ad una duplicazione del criteria per ogni metodo di conteggio richiamato in griglia(cosa che rallenta tantissimo le performance globali del sistema).

Possibile che non esiste altra soluzione?

Ogni consiglio è ben accetto.

…non riesci a mettere tutto nelle relations del model ?

Duplicare i criteria non ha nessun impatto sulle performance, perche’ si tratta di semplici oggetti con pochi dati.

Quello che puo’ essere importante e’ fare 3 query quando ne potrebbe bastare una:


public function totali()

{

    $criteria=$this->getSearchCriteria();

    $criteria->group= 'id';

    $criteria->limit= null;

    $criteria->select='SUM(somecolumn) as Venduto, SUM(somecolumn) as Reso, SUM(somecolumn) as Sospeso ';

    return $this->commandBuilder->createFindCommand($this->getTableSchema(),$criteria)->queryRow();

}

Inoltre, perche’ il conto riesca, devi eliminare una eventuale limit e raggruppare per qualcosa

ok , ma l’esecuzione della query no.

Per ogni metodo accessorio ove richiamerò il criteria originario (getSearchCriteria()) ci sarà l’esecuzione di una query duplicata ,più quella che innesto nel metodo accessorio stesso.

chiaro, laddove i campi da conteggiare appartengono ad una stessa tabella.

Ma dove invece ci sono join molti a molti ove i risultati sono il prodotto della somma di campi sparsi su più tabelle , credo sia inevitabile.