KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

How can I join 3 datastores to 1 ? #2674

Open Francois DISSAIT opened this topic on on May 15, 2022 - 6 comments

Francois DISSAIT commented on May 15, 2022

Hello team! Please help me : I created a datasource, treePiped it to three sources according a filter. I have now 3 datasources, I can pipe them to 3 datastores (Rentres, Promis, Sortis, the view works with each one separately) but I want Join these 3 datastores into 1 (or perhaps the 3 datasources?) and view it. how to do ? The join I tried does not produce anything. Here is my source : * (is the problem on line 108 ?

 what does $join1, ? how to pipe it to a new datastore ?
can i do a $join2 to add the third datasore) *

<?php //Step 1: Load KoolReport require_once "../../../load.koolreport.php";

use \koolreport\processes\Group; use \koolreport\processes\Map; use \koolreport\processes\Sort; use \koolreport\processes\Filter; use \koolreport\processes\CopyColumn; use \koolreport\processes\ColumnRename;

//Step 2: Creating Report class class balance_articles extends \koolreport\KoolReport { use \koolreport\inputs\Bindable; use \koolreport\inputs\POSTBinding;

protected function defaultParamValues()
{
    return array(
		"Sel_Article"=>'%',
		"dateRange"=>array(date("2022-01-01"),date("2022-03-31")),			
    );
}
protected function bindParamsToInputs()
{
    return array(
        "Sel_Article"=>"Sel_Article",	
		"dateRange"=>"dateRange",   
    );
}
/*protected function settings()*/

public function settings()

{
    $config = include "../../../config.php";
    return array(
        "dataSources"=>array(
            "phamm"=>$config["phamm"]
							)
				);
}
  public function setup()	
{
    $this->src('phamm')
    ->query("
		SELECT
		  items.item AS 'Article',
		  items.balance AS 'Stock',
		  SUM(batches.quantity) AS 'Quantite',
		  batches.etat AS 'Etat'
		FROM
		  batches
		  INNER JOIN items ON (batches.item = items.id)
		WHERE
		  items.item LIKE :Sel_Article
		  AND
		  batches.manufacturing_date BETWEEN :start AND :end
		GROUP BY
		  items.item,
		  batches.etat
		")			
		->params(array(
		":Sel_Article"=>$this->params["Sel_Article"],
		":start"=>$this->params["dateRange"][0],
        ":end"=>$this->params["dateRange"][1],
		))	
	->pipe(new \koolreport\processes\Map(array(
	"{meta}" => function($meta) {
    foreach ($meta["columns"] as $colName => $colMeta) {
        $meta["columns"][$colName]["thousandSeparator"] = " ";
        $meta["columns"][$colName]["decimalPoint"] = ",";
    }
    return $meta;									}
		))) 
	->pipeTree(
		function ($node)
		{
			$node->pipe(new Filter(array(array("Etat","=","Prepare")
			)))
			->pipe(new ColumnRename(array(
			"Quantite"=>"Rentres",
			"Article"=>"Article_R"
			)))
			
			->pipe($this->dataStore("Rentres"));
		},
		function ($node)
		{
			$node->pipe(new Filter(array(array("Etat","=","Promis")
			)))
			->pipe(new ColumnRename(array(
			"Quantite"=>"Promis",
			"Article"=>"Article_P"
			)))
			->pipe($this->dataStore("Promis"));
		},
		function ($node)
		{
			$node->pipe(new Filter(array(array("Etat","notContain","Pr")
			)))
			->pipe(new ColumnRename(array(
			"Quantite"=>"Sortis",
			"Article"=>"Article_S"
			)))
			->pipe($this->dataStore("Sortis"));
		}
			);
		$join1 = $this->dataStore('Rentres')->leftJoin($this->dataStore('Promis'),array(
		"Article_R"=>"Article_P"__
		));	
}

}

Sebastian Morales commented on May 16, 2022

Hi, joining datastores works like sql join which combines tables using the same columns. What you want to do in this case is to pipe all to one datastore:

->pipeTree(
		function ($node)
		{
			$node->pipe(new Filter(array(array("Etat","=","Prepare")
			)))
			->pipe(new ColumnRename(array(
			"Quantite"=>"Rentres",
			"Article"=>"Article_R"
			)))
			
			->pipe($this->dataStore("one"));
		},
		function ($node)
		{
			$node->pipe(new Filter(array(array("Etat","=","Promis")
			)))
			->pipe(new ColumnRename(array(
			"Quantite"=>"Promis",
			"Article"=>"Article_P"
			)))
			->pipe($this->dataStore("one")); // use the same datastore
		},
		function ($node)
		{
			$node->pipe(new Filter(array(array("Etat","notContain","Pr")
			)))
			->pipe(new ColumnRename(array(
			"Quantite"=>"Sortis",
			"Article"=>"Article_S"
			)))
			->pipe($this->dataStore("one")); // use the same datastore
		}
			); 

Pls try this and let us know if it works for you. Tks,

Francois DISSAIT commented on May 19, 2022

Thanks for this answer, It did not the work, giving as many row as answers, not grouping :

So i take three data sources according to 3 select, and i join the three in one data store. unfortunately I only have the rows who where present in the three select .... see the result :

is it a problem like right or left join, to have the number values = 0 also prsent ?

Here is the report : <?php //Step 1: Load KoolReport require_once "../../../load.koolreport.php";

use \koolreport\processes\Group; use \koolreport\processes\Map; use \koolreport\processes\Sort; use \koolreport\processes\Filter; use \koolreport\processes\CopyColumn; use \koolreport\processes\RemoveColumn; use \koolreport\processes\ColumnRename; use \koolreport\processes\Join;

//Step 2: Creating Report class class balance_articles extends \koolreport\KoolReport { use \koolreport\inputs\Bindable; use \koolreport\inputs\POSTBinding;

protected function defaultParamValues()
{
    return array(
		"Sel_Article"=>'%',
		"dateRange"=>array(date("2022-01-01"),date("2022-03-31")),			
    );
}
protected function bindParamsToInputs()
{
    return array(
        "Sel_Article"=>"Sel_Article",	
		"dateRange"=>"dateRange",   
    );
}
/*protected function settings()*/

public function settings()

{
    $config = include "../../../config.php";
    return array(
        "dataSources"=>array(
            "phamm"=>$config["phamm"]
							)
				);
}
  public function setup()	
{
    $rentres_source=$this->src('phamm')
    ->query("
		SELECT 
			items.item AS Article,
			items.balance AS Stock,
			sum(batches.quantity) AS Rentres
		FROM
			batches
		INNER JOIN items ON (batches.item = items.id)
		WHERE
			items.item LIKE '%' 
			AND 
			batches.etat = 'Prepare' AND 
			batches.manufacturing_date BETWEEN '2022-01-01' AND '2022-06-31'
		GROUP BY
			items.item,
			items.balance
		")			
		->params(array(
		":Sel_Article"=>$this->params["Sel_Article"],
		":start"=>$this->params["dateRange"][0],
        ":end"=>$this->params["dateRange"][1],
		))	
	->pipe(new \koolreport\processes\Map(array(
	"{meta}" => function($meta) {
    foreach ($meta["columns"] as $colName => $colMeta) {
        $meta["columns"][$colName]["thousandSeparator"] = " ";
        }
    return $meta;				}
		)))
	;
	
	$promis_source=$this->src('phamm')
    ->query("
		SELECT 
			items.item AS ArticleP,
			sum(batches.quantity) AS Promis
		FROM
			batches
		INNER JOIN items ON (batches.item = items.id)
		WHERE
			items.item LIKE '%' AND 
			batches.etat = 'Promis' AND 
			batches.manufacturing_date BETWEEN '2022-01-01' AND '2022-03-31'
		GROUP BY
			items.item
		")			
		->params(array(
		":Sel_Article"=>$this->params["Sel_Article"],
		":start"=>$this->params["dateRange"][0],
        ":end"=>$this->params["dateRange"][1],
		))	
	->pipe(new \koolreport\processes\Map(array(
	"{meta}" => function($meta) {
    foreach ($meta["columns"] as $colName => $colMeta) {
        $meta["columns"][$colName]["thousandSeparator"] = " ";
        }
    return $meta;									}
		)))
	;
$sortis_source=$this->src('phamm')
    ->query("
		SELECT 
			items.item AS ArticleS,
			items.balance AS Stock,
			sum(batches.quantity) AS Sortis
		FROM
			batches
		INNER JOIN items ON (batches.item = items.id)
		WHERE
			items.item LIKE '%' AND 
			batches.etat NOT LIKE 'Pr' AND 
			batches.manufacturing_date BETWEEN '2022-01-01' AND '2022-03-31'
		GROUP BY
		items.item
		")			
		->params(array(
		":Sel_Article"=>$this->params["Sel_Article"],
		":start"=>$this->params["dateRange"][0],
        ":end"=>$this->params["dateRange"][1],
		))	
	->pipe(new \koolreport\processes\Map(array(
	"{meta}" => function($meta) {
    foreach ($meta["columns"] as $colName => $colMeta) {
        $meta["columns"][$colName]["thousandSeparator"] = " ";
        }
    return $meta;				}
		)))
		;
	$join = new Join($rentres_source,$promis_source,array("Article"=>"ArticleP"));
	$join1 = new Join ($join,$sortis_source,array("Article"=>"ArticleS"));
    $join1->pipe($this->dataStore('Stocks'));
}
	

}

Thanks for help, not emergency ! François




Sebastian Morales commented on May 21, 2022

I think your case is a good use for Cube process like this:

    ->query("
		SELECT 
                        items.item as Article,
			CONCAT(items.item, ' - ', items.balance) AS ArticleStock,
			batches.etat as Category,
                        batches.quantity as Quantity
		FROM
			batches
		INNER JOIN items ON (batches.item = items.id)
		WHERE
			items.item LIKE :Sel_Article
			AND batches.manufacturing_date BETWEEN :start AND :end
		")			
		->params(array(
		    ":Sel_Article"=>$this->params["Sel_Article"],
		    ":start"=>$this->params["dateRange"][0],
                    ":end"=>$this->params["dateRange"][1],
		))	
    ->pipe(new \koolreport\cube\processes\Cube(array(
        "row" => "ArticleStock", //or "Article"
        "column" => "Category",
        "sum" => "Quantity"
    ))) 
    ->pipe(new \koolreport\processes\Map(array(
	"{meta}" => function($meta) {
            $meta["columns"]["Prepare"] = ["label" => "Rentres"];
            $meta["columns"]["Promis"] = ["label" => "Promis"];
            $meta["columns"]["Pr"] = ["label" => "Sortis"];
            return $meta;				
        }
    )))
    ->pipe($this->dataStore("one"));

Let us know if you want a different result. Tks,

Francois DISSAIT commented on May 22, 2022

Hello Sebastian, thanks a lot, I used Cube and resulat is quite good

I used many processes over the columns, but i cannot format columns as I want.(color, justfication ...) It does not work if formating is on the view soft. here enclose the two softs //Step 1: Load KoolReport require_once "../../../load.koolreport.php";

use \koolreport\processes\Group; use \koolreport\processes\Map; use \koolreport\processes\Sort; use \koolreport\processes\Filter; use \koolreport\processes\CopyColumn; use \koolreport\processes\ColumnMeta; use \koolreport\processes\CalculatedColumn; use \koolreport\processes\RemoveColumn; use \koolreport\processes\ColumnRename; use \koolreport\processes\Join; use \koolreport\cube\processes\Cube;

//Step 2: Creating Report class class balance_articles extends \koolreport\KoolReport { use \koolreport\inputs\Bindable; use \koolreport\inputs\POSTBinding;

protected function defaultParamValues()
{
    return array(
		"Sel_Article"=>'%',
		"dateRange"=>array(date("2022-01-01"),date("2022-03-31")),			
    );
}
protected function bindParamsToInputs()
{
    return array(
        "Sel_Article"=>"Sel_Article",	
		"dateRange"=>"dateRange",   
    );
}
/*protected function settings()*/

public function settings()

{
    $config = include "../../../config.php";
    return array(
        "dataSources"=>array(
            "phamm"=>$config["phamm"]
							)
				);
}

public function setup()

{   
$this->src('phamm')
    ->query("
	SELECT 
        items.item as Article,
		
		batches.etat as Category,
        batches.quantity as Quantity
	FROM
		batches
	INNER JOIN items ON (batches.item = items.id)
	WHERE
		items.item LIKE :Sel_Article
		AND batches.manufacturing_date BETWEEN :start AND :end
	")			
	->params(array(
	    ":Sel_Article"=>$this->params["Sel_Article"],
	    ":start"=>$this->params["dateRange"][0],
        ":end"=>$this->params["dateRange"][1],
	))	
->pipe(new Sort(array(
	"Article"=>"asc"
	)))
->pipe(new \koolreport\cube\processes\Cube(array(
    "row" => "Article", 
    "column" => "Category",
    "sum" => "Quantity"
))) 
->pipe(new CalculatedColumn(array(
	"Sortis"=>"{Expedie}+{Detruit}+{Perdu}+{RemisAMembre}"
   		)))
->pipe(new RemoveColumn(array(
        "Expedie","Detruit","Perdu","RemisAMembre","{{all}}"
    )))
->pipe(new ColumnMeta(array(
        "Prepare"=>array(
            "type"=>"number"),
		"Promis"=>array(
            "type"=>"number"),
		"Sortis"=>array(
            "type"=>"number"),
                       )))
->pipe(new \koolreport\processes\Map(array(
	"{meta}" => function($meta) {
        $meta["columns"]["Prepare"] = ["label" => "Rentres"];
        $meta["columns"]["Promis"] = ["label" => "Promis"];
        $meta["columns"]["Sortis"] = ["label" => "Sortis"];
    return $meta;				
    }
)))
->pipe($this->dataStore("Stocks"));
}

}

and the .view

<?php

use \koolreport\widgets\koolphp\Table; 
use \koolreport\inputs\Select;
use \koolreport\inputs\DateRangePicker;

?> <div class="report-content">

<div class="text-center">
    <h1>MOUVEMENTS ARTICLES</h1>
    <p class="lead">Articles entrés ou sortis du stock récemment</p>
</div>
<form method="post">
<div class="col-md-12 form-group">
            <html lang="fr">
            <div class="row">
				<div class="col-md-6 form-group">
					<strong>Intervalle</strong>
					<?php
					DateRangePicker::create(array(
					"name"=>"dateRange",
					"language"=>"fr",
					"ranges"=>array(
						"Ce mois"=>DateRangePicker::thisMonth(),
						"Dernier mois"=>DateRangePicker::lastMonth(),
									)
					));
						?> 
				</div>
			<div class="col-md-3 ">
					<strong></strong>
					<?php
					/* instructions pour recherche d'un article, aussi ajouter Article entre les 2 strong au dessus
					Select::create(array(
					"name"=>"Sel_Article",
					"dataStore"=>$this->dataStore("Stocks"),
					"defaultOption"=>array("%"=>"%"),
					"dataBind"=>"Article",
					"attributes"=>array(
                    "class"=>"form-control",
					)
					)); */
					?>
				</div>
				<div class="col-md-3 " ;">
			<button class="btn btn-lg btn-primary">O.K.</button>
			</div>
			</div>
			                     
			<pre><code><?php json_encode($this->params,JSON_PRETTY_PRINT) ?></code></pre>
	</form>
	</div>
<?php
Table::create(array(
    "dataSource"=>$this->dataStore('Stocks'),
	/*"columns"=>array(
        "Article"=>array(
            "label"=>"Article"
						),
	/*	"Rentres"=>array(
            "label"=>"Rentres",
			"cssStyle"=>"text-align:right;color:green",
							),
     /*   "Promis"=>array(
            "label"=>"Promis",
			"cssStyle"=>"text-align:right;color:orange",
							),
		"Expedies"=>array(
            "label"=>"Sortis",
			"cssStyle"=>"text-align:right;color:red",
							),
						),
	*/
		"cssClass"=>array(
        "table"=>"table-bordered table-striped table-hover"
						)
		))    
?>
</div>

If I keep the statement "columns" of the table array, I have no more result ...

Sinc.yours François

Sebastian Morales commented on May 23, 2022

After the Cube process, your column key names should be "Prepare", "Promis", and "Sortis" which are values of your DB table field batches.etat.

I would suggest you printing out your datastore's data to see its columns names and values:

//MyReport.view.php
print_r($this->dataStore('Stocks')->data());
...

Therefore, your Table's "columns" setting should be:

    "columns"=>array(
        "Article"=>array(
            "label"=>"Article"
        ),
	"Prepare"=>array(
            "label"=>"Rentres",
            "cssStyle"=>"text-align:right;color:green",
	),
       "Promis"=>array(
            "label"=>"Promis",
            "cssStyle"=>"text-align:right;color:orange",
        ),
        "Sortis"=>array(
            "label"=>"Sortis",
            "cssStyle"=>"text-align:right;color:red",
        ),
    ), 
Francois DISSAIT commented on May 23, 2022

Hello Sebastion ! I was sleeping ! Confused the coulumn names ! I corrected the names and all is OK Kool report is a great software and the team is very powerful and sympathic. Thanks a lot ! François

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
help needed
solved

None