www/prod_print.php

Sat, 23 Feb 2019 19:55:42 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 23 Feb 2019 19:55:42 +0100
changeset 282
f765249d57d7
parent 279
60d56f39e63e
child 289
4082c41f45e9
permissions
-rw-r--r--

ABV calculation uses Daniels method. sg_to_plato and plato_to_sg functions use brewersfriend calculation. Added sg_to_brix and brix_to_sg functions. Make brewdate tab read only when the primary fermentation is ready. Brix aid input functions for primary end sg and final sg fields. Added tooltips on the fermentation tab. Changes in the layout of the fermentation tab.

<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/includes/global.inc.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/includes/formulas.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/fpdf/fpdf.php');


$link = mysqli_connect(DBASE_HOST,DBASE_USER,DBASE_PASS,DBASE_NAME);
if (! $link) {
	die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
}
if (! mysqli_set_charset($link, "utf8" )) {
	echo "error";
	return 1;
}

setlocale ( LC_ALL, 'nl_NL.UTF-8');
$record = $_GET["record"];
$result = mysqli_query($link, "SELECT * FROM products WHERE record='".$record."'");
$row = mysqli_fetch_array($result);

$total_fermentables = 0.0;
$cost_fermentables = 0.0;
$total_hops = 0.0;
$cost_hops = 0.0;
$cost_yeasts = 0.0;
$cost_miscs = 0.0;
$pSugar = 0;
$pCara = 0;
$svg = 77;
$colorw = 0;
$total_ibus = 0;
$preboil_sg = 0;
$mashkg = 0;
date_default_timezone_set('Europe/Amsterdam');
$prdate = date(DATE_RFC2822);


class PDF_MySQL_Table extends FPDF
{
	protected $ProcessingTable=false;
	protected $aCols=array();
	protected $TableX;

	function Header() {
		// Print the table header if necessary
		if ($this->ProcessingTable)
			$this->TableHeader();
	}

	function TableHeader() {
		$this->SetFont('Helvetica','B',9);
		$this->SetX($this->TableX);
		$this->SetFillColor(255,150,100);
		foreach($this->aCols as $col)
			$this->Cell($col['w'],5,$col['c'],0,0,$col['a'],true);
		$this->Ln();
	}

	function AddCol($width=-1, $caption='', $align='L') {
		$this->aCols[]=array('c'=>$caption,'w'=>$width,'a'=>$align);
	}

	function TableGlobal($row) {
		/* 2 Columns */
		$recipetype = array( 'Extract', 'Deelmaisch', 'Mout' );
		$vul = $this->w - $this->rMargin - $this->lMargin - 160;
		$cMargin=$this->cMargin;
		$this->cMargin=2;
		$this->TableX=$this->lMargin;
		$this->SetFont('Helvetica','B',9);
		$this->SetX($this->TableX);
		$this->SetFillColor(255,150,100);
		$this->Cell(0, 5, 'Recept overzicht',0,0,'C',true);
		$this->Ln();

		$this->SetFont('Helvetica','',9);
		$this->SetFillColor(210,245,255);

		$this->SetX($this->TableX);
		$this->Cell(35,5,'Type',0,0,'L',true);
		$this->Cell(45,5,$recipetype[$row['type']],0,0,'L',true);
		$this->Cell($vul,5,'',0,0,'L',false);
		$this->Cell(35,5,'Batch grootte',0,0,'L',true);
		$this->Cell(45,5,$row['batch_size'].' liter',0,0,'L',true);
		$this->Ln();

		$this->SetX($this->TableX);
		$this->Cell(35,5,'Kooktijd',0,0,'L',true);
		$this->Cell(45,5,$row['boil_time'].' minuten',0,0,'L',true);
		$this->Cell($vul,5,'',0,0,'L',false);
		$this->Cell(35,5,'Brouwzaal rendement',0,0,'L',true);
		$this->Cell(45,5,$row['efficiency'].' %',0,0,'L',true);
		$this->Ln();

		$this->SetX($this->TableX);
		$this->Cell(35,5,'Bierstijl',0,0,'L',true);
		$this->Cell(45,5,$row['st_name'],0,0,'L',true);
		$this->Cell($vul,5,'',0,0,'L',false);
		$this->Cell(35,5,'Installatie',0,0,'L',true);
		$this->Cell(45,5,$row['eq_name'],0,0,'L',true);
		$this->Ln(10);

		$this->cMargin=$cMargin;
	}

	function TableFermentables($row) {
		global $cost_fermentables;
		global $total_fermentables;
		global $pSugar;
		global $pCara;
		global $colorw;
		global $preboil_sg;
		global $mashkg;
		$added = array( 'Maischen', 'Koken', 'Vergisten', 'Nagisten/lageren', 'Bottelen' );
		$vul = $this->w - $this->rMargin - $this->lMargin - 132;
		$this->AddCol($vul,'Grondstof','L');
		$this->AddCol(30,'Leverancier','L');
		$this->AddCol(15,'EBC','R');
		$this->AddCol(17,'Moment','L');
		$this->AddCol(20,'Kg','R');
		$this->AddCol(15,'Procent','R');
		$this->AddCol(15,'Opbr.','R');
		$this->AddCol(20,'Prijs','R');

		$cMargin=$this->cMargin;
		$this->cMargin=2;
		$this->TableX=$this->lMargin;
		$this->TableHeader();
		$this->ProcessingTable=true;

		$sugarsf = 0;
		$sugarsm = 0;
		$mashkg = 0;
		$this->SetFont('Helvetica','',9);
		$this->SetFillColor(250, 195, 65);
		$arr = json_decode($row['json_fermentables'], true);
		foreach($arr as $item) { //foreach element in $arr
			$name     = iconv('UTF-8','windows-1252',$item['f_name']);
			$supplier = iconv('UTF-8','windows-1252',$item['f_supplier']);
			$amount   = floatval($item['f_amount']);
			$costkg   = floatval($item['f_cost']);
			$yield    = floatval($item['f_yield']);
			$moisture = floatval($item['f_moisture']);
			$color    = floatval($item['f_color']);
			$percent  = floatval($item['f_percentage']);

			if ($item['f_type'] == 1)			// Sugar
				$pSugar += $percent;
			if ($item['f_graintype'] == 2)		// Crystal
				$pCara += $percent;

			$cost = $amount * $costkg;
			$cost_fermentables += $cost;
			$total_fermentables += $amount;
			/* Calculate the amount of sugars */
			$d = $amount * ($yield / 100) * (1 - $moisture / 100);
			if ($item['f_added']  == 0) {
				$d = floatval($row['efficiency']) / 100 * $d;
				$sugarsm += $d;
				$mashkg += $amount;
			}
			$sugarsf += $d;
			$colorw += ($amount * ebc_to_srm($color) / $row['batch_size']) * 8.34436;

			$this->Cell($vul,5,$name,0,0,'L',true);
			$this->Cell(30,5,$supplier,0,0,'L',true);
			$this->Cell(15,5,sprintf("%.0f",$color),0,0,'R',true);
			$this->Cell(17,5,$added[$item['f_added']],0,0,'L',true);
			$this->Cell(20,5,sprintf("%8.3f",$amount),0,0,'R',true);
			$this->Cell(15,5,sprintf("%.1f%%",$percent),0,0,'R',true);
			$this->Cell(15,5,sprintf("%.1f%%",$yield),0,0,'R',true);
			$this->Cell(20,5,sprintf("%8.3f",$cost).EURO,0,0,'R',true);
			$this->Ln();
		}

		$row['est_og'] = estimate_sg($sugarsf, floatval($row['batch_size']));
		$preboil_sg = estimate_sg($sugarsm, floatval($row['boil_size']));
		$this->SetFillColor(210,245,255);
		$this->Cell($vul+62,5,'',0,0,'L',false);
		$this->Cell(20,5,sprintf("%8.3f",$total_fermentables),0,0,'R',true);
		$this->Cell(30,5,'',0,0,'L',false);
		$this->Cell(20,5,sprintf("%8.3f",$cost_fermentables).EURO,0,0,'R',true);
		$this->Ln(10);
		$this->ProcessingTable=false;
		$this->cMargin=$cMargin;
		$this->aCols=array();
	}

	function TableHops($row) {
		global $total_hops;
		global $total_ibus;
		global $cost_hops;
		global $preboil_sg;
		$hopform = array( 'Pellets', 'Plugs', 'Bellen' );
		$hopuse  = array( 'Maischen', 'First wort', 'Koken', 'Vlamuit', 'Whirlpool', 'Koudhop' );
		$vul = $this->w - $this->rMargin - $this->lMargin - 135;
		$this->AddCol($vul,'Hop','L');
		$this->AddCol(35,'Land','L');
		$this->AddCol(15,'Soort','L');
		$this->AddCol(20,'Moment','L');
		$this->AddCol(15,'Alpha','R');
		$this->AddCol(12,'IBU','R');
		$this->AddCol(18,'Gram','R');
		$this->AddCol(20,'Prijs','R');

		$cMargin=$this->cMargin;
		$this->cMargin=2;
		$this->TableX=$this->lMargin;
		$this->TableHeader();
		$this->ProcessingTable=true;

		$this->SetFont('Helvetica','',9);
		$this->SetFillColor(100, 250, 65);

		$arr = json_decode($row['json_hops'], true);
		foreach($arr as $item) { //foreach element in $arr
			$name     = iconv('UTF-8','windows-1252',$item['h_name']);
			$origin   = iconv('UTF-8','windows-1252',$item['h_origin']);
			$amount   = floatval($item['h_amount']) * 1000;
			$mass     = $amount;
			$costkg   = floatval($item['h_cost']);
			$time     = floatval($item['h_time']);
			$alpha    = floatval($item['h_alpha']);

			$cost = ($amount * $costkg) / 1000;
			$cost_hops += $cost;
			$total_hops += $amount;

			$moment = $hopuse[$item['h_useat']];
			if ($item['h_useat'] == 2) {    // Boil
				$moment   = "Kook@".$time;
			}
			$ibu = calc_IBU($item['h_useat'], $item['h_form'], $preboil_sg, floatval($row['batch_size']), $mass, $time, $alpha, $row['ibu_method']);
			$total_ibus += $ibu;

			$this->Cell($vul,5,$name,0,0,'L',true);
			$this->Cell(35,5,$origin,0,0,'L',true);
			$this->Cell(15,5,$hopform[$item['h_form']],0,0,'L',true);
			$this->Cell(20,5,$moment,0,0,'L',true);
			$this->Cell(15,5,sprintf("%.1f%%",$alpha),0,0,'R',true);
			$this->Cell(12,5,sprintf("%.1f",$ibu),0,0,'R',true);
			$this->Cell(18,5,sprintf("%.1f",$amount),0,0,'R',true);
			$this->Cell(20,5,sprintf("%8.3f",$cost).EURO,0,0,'R',true);
			$this->Ln();
		}

		$this->SetFillColor(210,245,255);
		$this->Cell($vul+85,5,'',0,0,'L',false);
		$this->Cell(12,5,sprintf("%.1f",$total_ibus),0,0,'R',true);
		$this->Cell(18,5,sprintf("%.1f",$total_hops),0,0,'R',true);
		$this->Cell(20,5,sprintf("%8.3f",$cost_hops).EURO,0,0,'R',true);
		$this->Ln(10);
		$this->ProcessingTable=false;
		$this->cMargin=$cMargin;
		$this->aCols=array();
	}

	function TableYeasts($row) {
		global $cost_yeasts;
		global $svg;
		$yeastform = array( 'Vloeibaar', 'Droog', 'Schuine buis', 'Slurry', 'Ingevroren', 'Depot' );
		$yeastuse  = array( 'Hoofdgisting', 'Nagisting', 'Lagering', 'Bottelen' );
		$vul = $this->w - $this->rMargin - $this->lMargin - 140;
		$this->AddCol(27,'Laboratorium','L');
		$this->AddCol(18,'Product','L');
		$this->AddCol($vul,'Gist','L');
		$this->AddCol(20,'Gebruik','L');
		$this->AddCol(15,'Attn','R');
		$this->AddCol(22,'Vorm','L');
		$this->AddCol(18,'Gram','R');
		$this->AddCol(20,'Prijs','R');

		$cMargin=$this->cMargin;
		$this->cMargin=2;
		$this->TableX=$this->lMargin;
		$this->TableHeader();
		$this->ProcessingTable=true;

		$this->SetFont('Helvetica','',9);
		$this->SetFillColor(175, 175, 255);

		$arr = json_decode($row['json_yeasts'], true);
		foreach($arr as $item) { //foreach element in $arr
			$name       = iconv('UTF-8','windows-1252',$item['y_name']);
			$laboratory = iconv('UTF-8','windows-1252',$item['y_laboratory']);
			$product_id = iconv('UTF-8','windows-1252',$item['y_product_id']);
			$attenuation = floatval($item['y_attenuation']);
			$cost        = floatval($item['y_amount']) * floatval($item['y_cost']);
			$cost_yeasts += $cost;

			if ($item['y_use'] == 0)        // Primary
				$svg = $attenuation;
			if ($item['y_form'] == 0)       // Liquid
				$amount = sprintf("%.0f",floatval($item['y_amount']))." pak";
			else if ($item['y_form'] == 1)  // Dry
				$amount = sprintf("%.1f",floatval($item['y_amount'])*1000)." gr";
			else
				$amount = sprintf("%.0f",floatval($item['y_amount'])*1000)." ml";

			$this->Cell(27,5,$laboratory,0,0,'L',true);
			$this->Cell(18,5,$product_id,0,0,'L',true);
			$this->Cell($vul,5,$name,0,0,'L',true);
			$this->Cell(20,5,$yeastuse[$item['y_use']],0,0,'L',true);
			$this->Cell(15,5,sprintf("%.1f%%",$attenuation),0,0,'R',true);
			$this->Cell(22,5,$yeastform[$item['y_form']],0,0,'L',true);
			$this->Cell(18,5,$amount,0,0,'R',true);
			$this->Cell(20,5,sprintf("%8.3f",$cost).EURO,0,0,'R',true);
			$this->Ln();
		}

		$this->SetFillColor(210,245,255);
		$this->Cell($vul+120,5,'',0,0,'L',false);
		$this->Cell(20,5,sprintf("%8.3f",$cost_yeasts).EURO,0,0,'R',true);
		$this->Ln(10);
		$this->ProcessingTable=false;
		$this->cMargin=$cMargin;
		$this->aCols=array();
	}

	function TableMiscs($row) {
		global $cost_miscs;
		$misctype = array( 'Specerij', 'Kruid', 'Smaakstof', 'Klaringsmiddel', 'Brouwzout', 'Gistvoeding', 'Anders' );
		$miscuse  = array( 'Starter', 'Maischen', 'Koken', 'Hoofdvergisting', 'Nagisting/lagering', 'Bottelen' );
		$vul = $this->w - $this->rMargin - $this->lMargin - 100;
		$this->AddCol($vul,'Naam','L');
		$this->AddCol(30,'Soort','L');
		$this->AddCol(30,'Gebruik','L');
		$this->AddCol(20,'Hoeveel','R');
		$this->AddCol(20,'Prijs','R');

		$cMargin=$this->cMargin;
		$this->cMargin=2;
		$this->TableX=$this->lMargin;
		$this->TableHeader();
		$this->ProcessingTable=true;

		$this->SetFont('Helvetica','',9);
		$this->SetFillColor(175, 175, 255);

		$arr = json_decode($row['json_miscs'], true);
		foreach($arr as $item) {
			$name       = iconv('UTF-8','windows-1252',$item['m_name']);
			$type       = $item['m_type'];
			$use_use    = $item['m_use_use'];
			$amount     = floatval($item['m_amount']) * 1000;
			$costg      = floatval($item['m_cost']) / 1000;
			$time       = floatval($item['m_time']);
			$aiw        = $item['m_amount_is_weight'];
			$cost       = $amount * $costg;
			$cost_miscs += $cost;

			if ($type == 4)	// Water agent
				$this->SetFillColor(240,140,130);
			else if ($type == 3)	// Fining
				$this->SetFillColor(95,180,25);
			else if (($type == 0) || ($type == 1) || ($type == 2) || ($type == 5))	// Spice, Herb, Flavour, Yeast nutrient
				$this->SetFillColor(240,250,65);
			else
				$this->SetFillColor(210,245,255);

			if ($use_use == 2)	// Boil
				$gebruik = sprintf("%s %d min",$miscuse[$use_use],$time);
			else
				$gebruik = $miscuse[$use_use];

			$hoeveel = sprintf("%.1f %s",$amount,$aiw ? "gr":"ml");
			$this->Cell($vul,5,$name,0,0,'L',true);
			$this->Cell(30,5,$misctype[$type],0,0,'L',true);
			$this->Cell(30,5,$gebruik,0,0,'L',true);
			$this->Cell(20,5,$hoeveel,0,0,'R',true);
			$this->Cell(20,5,sprintf("%8.3f",$cost).EURO,0,0,'R',true);
			$this->Ln();
		}

		$this->SetFillColor(210,245,255);
		$this->Cell($vul+80,5,'',0,0,'L',false);
		$this->Cell(20,5,sprintf("%8.3f",$cost_miscs).EURO,0,0,'R',true);
		$this->Ln(10);

		$this->ProcessingTable=false;
		$this->cMargin=$cMargin;
		$this->aCols=array();
	}

	// Watercolor $this->SetFillColor(120,255,250);

	function TableSummary($row) {
		global $pSugar;
		global $pCara;
		global $svg;
		global $colorw;
		global $cost_fermentables;
		global $cost_hops;
		global $cost_miscs;
		global $cost_yeasts;
		global $mashkg;
		/* 2 Columns */
		$vul = $this->w - $this->rMargin - $this->lMargin - 170;
		$cMargin=$this->cMargin;
		$this->cMargin=2;
		$this->TableX=$this->lMargin;
		$this->SetFont('Helvetica','B',9);
		$this->SetX($this->TableX);
		$this->SetFillColor(255,150,100);
		$this->Cell(0, 5, 'Recept samenvatting',0,0,'C',true);
		$this->Ln();

		$this->SetFont('Helvetica','',9);
		$this->SetFillColor(210,245,255);

		$mashtime = 0;
		$mashtemp = 0;
		$mash_infuse = 0;
		$arr = json_decode($row['json_mashs'], true);
		foreach($arr as $item) {
			if ($item['step_type'] == 0) { // infusion
				$mash_infuse += floatval($item['step_infuse_amount']);
			}
			if ($item['step_temp'] < 75) { // ignore mashout temps
				$mashtime += floatval($item['step_time']);
				$mashtemp += floatval($item['step_time']) * floatval($item['step_temp']);
			}
		}
		$mashtemp = $mashtemp / $mashtime;
		if (($mashkg > 0) && ($mash_infuse > 0) && ($mashtime > 0) && ($mashtemp > 0)) {
			$row['est_fg'] = estimate_fg($pSugar, $pCara, $mash_infuse / $mashkg, $mashtime, $mashtemp, $svg, $row['est_og']);
		} else {
			$row['est_fg'] = estimate_fg($pSugar, $pCara, 0, 0, 0, $svg, $row['est_og']);
		}

		$this->SetX($this->TableX);
		$this->Cell(35,5,'Start SG',0,0,'L',true);
		$this->Cell(25,5,sprintf("%.3f",$row['est_og']),0,0,'L',true);
		$this->Cell(25,5,'('.sprintf("%.3f",$row['st_og_min']).' - '.sprintf("%.3f",$row['st_og_max']).')',0,0,'L',true);
		$this->Cell($vul,5,'',0,0,'L',false);
		$this->Cell(35,5,'Eind SG',0,0,'L',true);
		$this->Cell(25,5,sprintf("%.3f",$row['est_fg']),0,0,'L',true);
		$this->Cell(25,5,'('.sprintf("%.3f",$row['st_fg_min']).' - '.sprintf("%.3f",$row['st_fg_max']).')',0,0,'L',true);
		$this->Ln();

		$row['est_abv'] = abvol($row['est_og'], $row['est_fg']);
		$this->SetX($this->TableX);
		$this->Cell(35,5,'Geschat alcohol',0,0,'L',true);
		$this->Cell(25,5,sprintf("%.1f",$row['est_abv']).'%',0,0,'L',true);
		$this->Cell(25,5,'('.sprintf("%.1f",$row['st_abv_min']).' - '.sprintf("%.1f",$row['st_abv_max']).'%)',0,0,'L',true);
		$this->Cell($vul,5,'',0,0,'L',false);
		$this->Cell(35,5,'CO2',0,0,'L',true);
		$this->Cell(25,5,sprintf("%.1f",$row['est_carb']).'%',0,0,'L',true);
		$this->Cell(25,5,'('.sprintf("%.1f",$row['st_carb_min']).' - '.sprintf("%.1f",$row['st_carb_max']).'%)',0,0,'L',true);
		$this->Ln();

		$row['est_color'] = kw_to_ebc($row['color_method'], $colorw);
		$this->SetX($this->TableX);
		$this->Cell(35,5,'Kleur ('.$row['color_method'].')',0,0,'L',true);
		$beercolor = ebc_to_color($row['est_color']);
		if ($row['est_color'] > 30)
			$this->SetTextColor(250);
		$this->SetFillColor($beercolor[0],$beercolor[1],$beercolor[2]);
		$this->Cell(25,5,$row['est_color'].' EBC',0,0,'L',true);
		$this->Cell(25,5,'('.$row['st_color_min'].' - '.$row['st_color_max'].' EBC)',0,0,'L',true);
		$this->SetTextColor(0);
		$this->SetFillColor(210,245,255);
		$this->Cell($vul,5,'',0,0,'L',false);
		$this->Cell(35,5,'Bitterheid ('.$row['ibu_method'].')',0,0,'L',true);
		$this->Cell(25,5,sprintf("%.0f",$row['est_ibu']).' IBU',0,0,'L',true);
		$this->Cell(25,5,'('.$row['st_ibu_min'].' - '.$row['st_ibu_max'].' IBU)',0,0,'L',true);
		$this->Ln();

		$this->SetX($this->TableX);
		$cost_total = $cost_fermentables + $cost_hops + $cost_miscs + $cost_yeasts;
		$this->Cell(35,5,'Kosten',0,0,'L',true);
		$this->Cell(25,5,sprintf("%.2f",$cost_total).EURO,0,0,'L',true);
		$this->Cell(25,5,sprintf("%.2f",$cost_total/$row['batch_size']).EURO.' / liter',0,0,'L',true);
		$this->Ln(10);


		// Kostprijs per liter, calorieren
		$this->cMargin=$cMargin;
	}

	function Checkheader($text) {
		$this->SetFont('Arial','B',10);
		$this->Cell(0, 4,$text,0,0,'L',true);
		$this->SetFont('Arial','',10);
		$this->Ln(6);
	}

	function Checkline($text) {
		//	$this->SetX(5);
		$this->Cell(2, 4,' ',0,0,'L',true);
		$this->Cell(4, 4,' ',1,0,'L',true);
	//	$this->Rect(10,$this->GetY(),4,4);
	//	$this->SetX(15);
		$this->Cell(0, 4,' '.$text,0,1,'L',true);
		$this->Ln(1);
	}

	function Checklist($row) {

		global $my_grain_absorbtion;
		global $my_brix_correction;
		$mashwater = 0;
		$numsalts = 0;

		$this->AddPage();
		$this->SetFillColor(255,255,255);

		if ($row['starter_enable'] && $row['prop1_volume']) {
			$this->Checkheader('Giststarter maken');
			$days = 0;
			$last = 0;
			for ($i = 1; $i < 5; $i++) {
				$pt = "prop".$i."_type";
				$pv = "prop".$i."_volume";
				if (floatval($row[$pv])) {
					$last = $i;
					if ($row[$pt] == 0)
						$days += 2;
					else if ($row[$pt] == 1)
						$days += 4;
					else
						$days += 6;
				}
			}
			$this->Checkline("begin ongeveer ".$days." dagen voor de brouwdag met de giststarter");
			for ($i = 1; $i < 5; $i++) {
				$pt = "prop".$i."_type";
				$pv = "prop".$i."_volume";
				if (floatval($row[$pv])) {
					$s  = "Starter stap ".$i.", van ".sprintf("%.3f",floatval($row[$pv]));
					$s .= " liter maken met SG ".sprintf("%.3f",floatval($row['starter_sg']));
					$this->Checkline($s);
					if ($row[$pt] == 0) {
						$s = "ongeveer 24 uur op een magneetroerder";
					} else if ($row[$pt] == 1) {
						$s = "enkele dagen regelmatig schudden";
					} else {
						$s = "bijna een week rustig laten staan";
					}
					$s .= " tot er voldoende gist is";
					$this->Checkline($s);
					if ($i < $last) {
						$this->Checkline("starter minstens 24 uur in de koeling laten uitzakken");
						$this->Checkline("starter uit de koelkast halen en afgieten");
					} else {
						$this->Checkline("starter in de koeling zetten tot de brouwdag");
						$this->Checkline("starter op de brouwdag uit de koelkast halen en afgieten");
					}
				}
			}
			$this->Ln(5);
		}

		$this->Checkheader('Water en -behandeling');
		if ($row['w1_name']) {
			$this->Checkline(sprintf("%.1f",floatval($row['w1_amount'])).' liter water '.$row['w1_name']);
			$mashwater += floatval($row['w1_amount']);
		}
		if ($row['w2_name']) {
			$this->Checkline(sprintf("%.1f",floatval($row['w2_amount'])).' liter water '.$row['w2_name']);
			$mashwater += floatval($row['w2_amount']);
		}
		$arr = json_decode($row['json_miscs'], true);
		foreach($arr as $item) {
			if ($item['m_type'] == 4) {	// Only the water agents
				$unit = ($item['m_amount_is_weight']) ? " gram ":" ml ";
				$this->Checkline(sprintf("%.1f",floatval($item['m_amount'] * 1000)).$unit.$item['m_name']);
				$numsalts++;
			}
		}
		$this->Ln(5);

		$this->Checkheader('Mout afwegen en schroten');
		$arr = json_decode($row['json_fermentables'], true);
		foreach($arr as $item) {
			if ($item['f_added'] == 0) {	// to mash
				$s = sprintf("%.3f",floatval($item['f_amount'])).' kg ';
				$s .= iconv('UTF-8','windows-1252',$item['f_name']);
				$s .= ' ('.iconv('UTF-8','windows-1252',$item['f_supplier']).')';
				$this->Checkline($s);
			}
		}
		$this->Checkline('mout schroten');
		$this->Ln(5);

		$this->Checkheader('Maischen');
		$mvol = 0;
		$msugars = 0;	// mash sugars
		$grainabsorbtion = 0;
		$arr = json_decode($row['json_mashs'], true);
		if (count($arr) > 0) {
			$loop = 0;
			foreach($arr as $item) {
				if ($item['step_type'] == 0)
					$mvol += $item['step_infuse_amount'];	// We need this later.
				if ($loop == 0) {
					$s = sprintf("%.1f",$mashwater).' liter water opwarmen tot ';
					$s .= sprintf("%.1f",$item['step_temp']).' '.DEG.'C (';
					$s .= sprintf("%.1f",kettle_cm($mashwater,$row['eq_tun_volume'],$row['eq_tun_height']));
					$s .= ' cm onder de rand)';
					$this->Checkline($s);
					if ($numsalts > 0)
						$this->Checkline('brouwzouten en -zuren toevoegen');
					$this->Checkline('mout storten en inmaischen');
					$hops = json_decode($row['json_hops'], true);
					foreach($hops as $item2) {
						if ($item2['h_useat'] == 0) {
							$s = sprintf("%.1f",$item2['h_amount']*1000).' gr ';
							$s .= iconv('UTF-8','windows-1252',$item2['h_name']).' toevoegen';
							$this->Checkline($s);
						}
					}
					$this->Checkline($item['step_time'].' min. bij '.$item['step_temp'].' '.DEG.'C');
					$this->Checkline('pH meten en bijstellen (doel pH beslag: '.sprintf("%.1f",$row['mash_ph']).' pH)');
				} else {
					if ($item['step_type'] == 0) {	// Infusion
						$s = 'toevoegen '.$item['step_infuse_amount'].' liter water van xx '.DEG.'C';
					} else if ($item['step_type'] == 1) {	// Direct heat
						$s = 'opwarmen tot '.$item['step_temp'].' '.DEG.'C';
					} else {	// Decoction
						$s = 'uitnemen, opwarmen, koken en terugstorten van '.$item['step_infuse_amount'].' liter deelbeslag';
					}
					$this->Checkline($s);
					$this->Checkline($item['step_time'].' min. bij '.$item['step_temp'].' '.DEG.'C');
				}
				$loop++;
			}
			$est_mash_sg = 0;
			$ferms = json_decode($row['json_fermentables'], true);
			foreach($ferms as $item) {
				if ($item['f_added'] == 0) {
					$d = $item['f_amount'] * ($item['f_yield'] / 100) * (1 - $item['f_moisture'] / 100);
					$mvol += $item['f_amount'] * $item['f_moisture'] / 100;
					$grainabsorbtion += $my_grain_absorbtion * $item['f_amount'];
					$msugars += $d;
				}
			}
			$sugardensity = 1.611;
			$v = $msugars / $sugardensity + $mvol;
			$plato = 1000 * $msugars / ($v * 10);	// deg. Plato
			$mash_sg = plato_to_sg($plato);
			$brix = $plato * $my_brix_correction;
			$s = 'doel sg eind maischen: '.sprintf("%.3f",$mash_sg);
			$s .= ' SG ('.sprintf("%.1f",$brix).' '.DEG.'Brix, '.sprintf("%.1f",$plato).' '.DEG.'P)';
			$this->Checkline($s);
		}
		if ($this->GetY() > 200)
			$this->AddPage();
		else
			$this->Ln(5);

		$acidtype = array( 'Melkzuur', 'Zoutzuur', 'Fosforzuur', 'Zwavelzuur' );
		$this->Checkheader('Filteren en spoelen');
		$s = sprintf("%.1f",$row['sparge_volume']).' liter spoelwater opwarmen tot '.sprintf("%.1f",$row['sparge_temp']).' '.DEG.'C';
		$this->Checkline($s);
		$s = 'spoelwater aanzuren tot pH <= '.sprintf("%.1f",$row['sparge_ph']).' met ';
		$s .= sprintf("%.1f",$row['sparge_acid_amount']*1000).' ml. '.$acidtype[$row['sparge_acid_type']];
		$this->Checkline($s);
		$spoelw = ($row['boil_size'] - $mashwater + $grainabsorbtion + $row['eq_lauter_deadspace']) * 1.03;	// A small heat correction
		$this->Checkline('spoelen met ongeveer '.sprintf("%.1f",$spoelw).' liter spoelwater');
		$s = 'doelvolume in kookketel: '.sprintf("%.1f",$row['boil_size'] * 1.04).' liter (';
		$s .= sprintf("%.1f",kettle_cm($row['boil_size'] * 1.04,$row['eq_kettle_volume'],$row['eq_kettle_height'])).' cm onder de rand)';
		$this->Checkline($s);
		$pre_sg = estimate_sg($msugars * floatval($row['efficiency']) / 100,floatval($row['boil_size']));
		$plato = sg_to_plato($pre_sg);
		$brix = $plato * $my_brix_correction;
		$s = 'doel SG in kookketel: '.sprintf("%.3f",$pre_sg).' SG ('.sprintf("%.1f",$brix).' '.DEG.'Brix, '.sprintf("%.1f",$plato).' '.DEG.'P)';
		$this->Checkline($s);
		$hops = json_decode($row['json_hops'], true);
		foreach($hops as $item2) {
			if ($item2['h_useat'] == 1) {
				$s = sprintf("%.1f",$item2['h_amount']*1000).' gr ';
				$s .= iconv('UTF-8','windows-1252',$item2['h_name']).' toevoegen na het spoelen';
				$this->Checkline($s);
			}
		}
		if ($this->GetY() > 200)
			$this->AddPage();
		else
			$this->Ln(5);

		$this->Checkheader('Koken');
		$this->Checkline('totale kooktijd: '.$row['boil_time'].' min.');
		for ($i = $row['boil_time']; $i >= 0; $i--) {
			if ($i == 10) {
				$ferms = json_decode($row['json_fermentables'], true);
				foreach($ferms as $item1) {
					if ($item1['f_added'] == 1) {
						$s = sprintf("%.3f",$item1['f_amount']).' kg ';
						$s .= iconv('UTF-8','windows-1252',$item1['f_name']).' bij 10 minuten voor einde koken';
						$this->Checkline($s);
					}
				}
				if ($row['brew_cooling_method'] == 1)
					$this->Checkline('Plaats dompelkoeler bij 10 minuten voor einde koken');
			}
			$hops = json_decode($row['json_hops'], true);
			foreach($hops as $item2) {
				if (($item2['h_useat'] == 2 || $item2['h_useat'] == 3) && ($item2['h_time'] == $i)) {
					$s = sprintf("%.1f",$item2['h_amount']*1000).' gr ';
					$s .= iconv('UTF-8','windows-1252',$item2['h_name']).' bij ';
					if ($i > 0)
						$s .= $i.' minuten voor einde koken';
					else
						$s .= 'vlamuit';
					$this->Checkline($s);
				}
			}
			$miscs = json_decode($row['json_miscs'], true);
			foreach($miscs as $item3) {
				if ($item3['m_use_use'] == 2 && $item3['m_time'] == $i) {
					$s = sprintf("%.1f",$item3['m_amount']*1000).' gr ';
					$s .= iconv('UTF-8','windows-1252',$item3['m_name']).' bij ';
					if ($i > 0)
						$s .= $i.' minuten voor einde koken';
					else
						$s .= 'vlamuit';
					$this->Checkline($s);
				}
			}

		}
		$s = 'doelvolume einde koken: '.sprintf("%.1f",$row['batch_size']*1.04).' liter (';
		$s .= sprintf("%.1f",kettle_cm($row['batch_size']*1.04,$row['eq_kettle_volume'],$row['eq_kettle_height']));
		$s .= ' cm onder de rand)';
		$this->Checkline($s);
		$plato = sg_to_plato($row['est_og']);
		$brix = $plato * $my_brix_correction;
		$s = 'doel SG einde koken: '.sprintf("%.3f",$row['est_og']).' SG (';
		$s .= sprintf("%.1f",$brix).' '.DEG.'Brix, '.sprintf("%.1f",$plato).' '.DEG.'P)';
		$this->Checkline($s);
		if ($this->GetY() > 200)
			$this->AddPage();
		else
			$this->Ln(5);

		if (($row['brew_whirlpool9'] + $row['brew_whirlpool7'] + $row['brew_whirlpool6'] + $row['brew_whirlpool2']) > 0) {
			$this->Checkheader('Whirlpool en koelen');
			if ($row['brew_whirlpool9'] > 0) {
				$s = 'Whirlpool voor '.$row['brew_whirlpool9'].' min. Temperatuur boven 85 '.DEG.'C houden';
				$this->Checkline($s);
			}
			if ($row['brew_whirlpool7'] > 0) {
				$this->Checkline('koelen tot 79 '.DEG.'C');
				$s = 'Whirlpool voor '.$row['brew_whirlpool7'].' min. Temperatuur tussen 72 en 79 '.DEG.'C houden';
				$this->Checkline($s);
			}
			if ($row['brew_whirlpool6'] > 0) {
				$this->Checkline('koelen tot 66 '.DEG.'C');
				$s = 'Whirlpool voor '.$row['brew_whirlpool6'].' min. Temperatuur tussen 60 en 66 '.DEG.'C houden';
				$this->Checkline($s);
			}
			$this->Checkline('koelen tot '.sprintf("%.1f",$row['brew_cooling_to']).' '.DEG.'C');
			if ($row['brew_whirlpool2'] > 0) {
				$s = 'Whirlpool voor '.$row['brew_whirlpool2'].' min.';
				$this->Checkline($s);
			}
		} else {
			$this->Checkheader('Koelen');
			$this->Checkline('koelen tot '.sprintf("%.1f",$row['brew_cooling_to']).' '.DEG.'C');
		}
		$this->Checkline('gistvat ontsmetten en evt. pomp en slangen ontsmetten');
		$this->Checkline('wort naar gistvat overbrengen');
		if ($this->GetY() > 200)
			$this->AddPage();
		else
			$this->Ln(5);

		$this->Checkheader('Gist enten');
		$dry = 0;
		$yeasts = json_decode($row['json_yeasts'], true);
		foreach ($yeasts as $item) {
			if ($item['y_use'] == 0) { // primary
				if ($item['y_form'] == 0) { // Liquid
					$this->Checkline($item['y_amount'].' pak '.$item['y_product_id'].', '.$item['y_name'].' gist');
				} else if ($item['y_form'] == 1) { // Dry
					$s = sprintf("%.1f",$item['y_amount']*1000).' gram '.$item['y_product_id'].', '.$item['y_name'];
					$s .= ' gist';
					$dry += $item['y_amount']*10000;
					$this->Checkline($s);
				} else { // Slant/Culture/Frozen/Bottle
					$s = sprintf("%.0f",$item['y_amount']*1000).' ml '.$item['y_product_id'].', '.$item['y_name'].' gist';
					$this->Checkline($s);
				}
			}
		}
		if ($dry > 0) {
			$this->Checkline(' gist hydrateren in '.$dry.' ml gedesinfecteerd water van 32 '.DEG.'C');
			$this->Checkline(' 15 minuten laten staan bij 32 '.DEG.'C');
			$this->Checkline(' gistmengsel voorzichtig roeren en laten afkoelen tot temperatuur wort');
			$this->Checkline(' gist toevoegen');
			$this->Checkline('Of');
			$this->Checkline(' gist rechtstreeks over het wort strooien');
		} else {
			if ($row['starter_enable'] && $row['prop1_volume'])
				$this->Checkline('giststarter toevoegen');
			else
				$this->Checkline('gist toevoegen');
		}
		if ($row['brew_fermenter_extrawater'] > 0)
			$this->Checkline(sprintf("%.1f", $row['brew_fermenter_extrawater']).' liter water toevoegen in gistvat');
		if ($row['brew_aeration_type'] > 0) {
			$s = 'wort '.$row['brew_aeration_time'].' minuten beluchten met ';
			$s .= ($row['brew_aeration_type'] == 1) ? "lucht":"zuurstof";
			$this->Checkline($s);
		}
		if ($this->GetY() > 200)
			$this->AddPage();
		else
			$this->Ln(5);

		$this->Checkheader('Vergisting starten');
		$this->Checkline('klimaatkast instellen op '.sprintf("%.1f",$row['brew_cooling_to']).' '.DEG.'C');

		// 'Toevoegingen tijdens vergisting'
		// 'Toevoegingen tijdens nagisting/lagering'
		// fermentables & hops & miscs  verdelen over primary/secondary/teriary

		// 'Toevoegingen tijdens bottelen/op fust zetten'
	}
}



class PDF extends PDF_MySQL_Table {
	function Header() {
		global $row;
		global $prdate;
		$stage = array( 'Plan', 'Wacht', 'Brouwen', 'Hoofdgisting', 'Nagisting', 'Lagering', 'Afvullen', 'Hergisten', 'Rijpen', 'Proeven', 'Gereed', 'Afgesloten' );
		$this->Image('images/logo.png',10,10,30);
		// Title
		$this->SetFont('Helvetica','B',18);
		$this->SetX(45);
		$this->Cell(0,8,$row['code'].' '.$row['name'],0,1,'L');
		$this->Ln(1);
		$this->SetFont('Helvetica','',10);
		$this->SetX(45);
		$this->Cell(17,5,'Datum:',0,0,'L');
		$this->Cell(0,5,$prdate,0,1,'L');
		$this->SetX(45);
		$this->Cell(17,5,'Stijl:',0,0,'L');
		$this->Cell(0,5,$row['st_name'],0,1,'L');
		$this->SetX(45);
		$this->Cell(17,5,'Fase:',0,0,'L');
		$this->Cell(0,5,$stage[$row['stage']],0,1,'L');
		$this->Ln(6);
		// Ensure table header is printed
		parent::Header();
	}
}


/*
 * Generate PDF from recipe data
 */
$pdf = new PDF();
$pdf->AddPage();
$pdf->TableGlobal($row);
$pdf->TableFermentables($row);
$pdf->TableHops($row);
$pdf->TableYeasts($row);
$pdf->TableMiscs($row);
$pdf->TableSummary($row);
if (strlen($row['notes'])) {
	$pdf->SetFillColor(255,150,100);
	$pdf->Cell(0, 5, 'Recept opmerkingen',0,0,'C',true);
	$pdf->Ln();
	$pdf->SetFillColor(210,245,255);
	$pdf->MultiCell(0,4,$row['notes'],0,'L',true);
}

if ($row['stage'] == 1 || $row['stage'] == 2) {
	// Checklist
	$pdf->Checklist($row);
}
if ($row['stage'] > 2) {
	// Brouw rapport
}
if ($row['stage'] > 3) {
	// Vergisting gegevens
}
if ($row['stage'] > 6) {
	// Package report
}
if ($row['stage'] > 9) {
	// Taste notes
}


$pdf->Output();

mercurial