Index: modules/Quotes/CreatePDF.php =================================================================== --- modules/Quotes/CreatePDF.php (revision 3) +++ modules/Quotes/CreatePDF.php (working copy) @@ -20,9 +20,9 @@ $currency_symbol = $adb->query_result($result,0,'currency_symbol'); // would you like and end page? 1 for yes 0 for no -$endpage="1"; +$endpage="0"; global $products_per_page; -$products_per_page="6"; +$products_per_page="9"; $focus = new Quote(); $focus->retrieve_entity_info($_REQUEST['record'],"Quotes"); @@ -57,6 +57,16 @@ $description = $focus->column_fields["description"]; $status = $focus->column_fields["quotestage"]; +// DG 30 Aug 2006 +# This function is in include/utils/Commonutils.php included from Quote.php +$contact_name = getContactName($focus->column_fields[contact_id]); + +// and this one I wrote myself, also in CommonUtils.php +$user_name = getUserFullName($focus->column_fields[assigned_user_id1]); + +// Get the date too +$todays_date = getNewDisplayDate(); + // Company information $add_query = "select * from vtiger_organizationdetails"; $result = $adb->query($add_query); @@ -84,14 +94,22 @@ $price_total = $currency_symbol.number_format(StripLastZero($focus->column_fields["hdnGrandTotal"]),2,'.',','); //getting the Product Data -$query="select vtiger_products.productname, vtiger_products.unit_price, vtiger_products.product_description, vtiger_inventoryproductrel.* from vtiger_inventoryproductrel inner join vtiger_products on vtiger_products.productid=vtiger_inventoryproductrel.productid where id=".$quote_id; +// DG 15 Aug 2006 +// Add "ORDER BY sequence_no to preserve add order in printed version +// Seems not to be strictly necessary as the upstream ORDER BY in EditView appears to produce this behaviour by default +// Having this here makes sure though. +// DG 30 Aug 2006 +// Drop "product_description" in favour of part number ("productcode") +$query="select vtiger_products.productname, vtiger_products.unit_price, vtiger_products.productcode, vtiger_inventoryproductrel.* from vtiger_inventoryproductrel inner join vtiger_products on vtiger_products.productid=vtiger_inventoryproductrel.productid where id=".$quote_id." ORDER BY sequence_no"; global $result; $result = $adb->query($query); $num_products=$adb->num_rows($result); for($i=0;$i<$num_products;$i++) { $product_name[$i]=$adb->query_result($result,$i,'productname'); - $prod_description[$i]=$adb->query_result($result,$i,'product_description'); + // DG 30 Aug 2006 + // Drop "product_description" in favour of part number ("productcode") + $part_no[$i]=$adb->query_result($result,$i,'productcode'); $product_id[$i]=$adb->query_result($result,$i,'productid'); $qty[$i]=$adb->query_result($result,$i,'quantity'); @@ -113,47 +131,83 @@ } $product_line[] = array( "Product Name" => $product_name[$i], - "Description" => $prod_description[$i], + // DG 30 Aug 2006 + // Drop description for part no + "Part No" => $part_no[$i], "Qty" => $qty[$i], "List Price" => $list_price[$i], "Unit Price" => $unit_price[$i], "Tax" => $currency_symbol.$total_taxes, "Total" => $currency_symbol.$prod_total[$i] ); + + // DG 1 Sept 2006 + // We use the "Comment" field for each product as a way of adding subheadings to Quotes + // So we need to collect the comments as well. + // Could probably simplify this but for now I'm going to copy&paste stuff I know works + $dg_comment[$i]=$adb->query_result($result,$i,'comment'); + $dg_comment_line[] = array( "Product Name" => $dg_comment[$i], + "Part No" => '', + "Qty" => '', + "List Price" => '', + "Unit Price" => '', + "Tax" => '', + "Total" => '' + ); } - $total[]=array("Unit Price" => $app_strings['LBL_SUB_TOTAL'], + // DG 30 Aug 2006 + // Change the column the totals data goes in to match our new arrangement + $total[]=array("Tax" => $app_strings['LBL_SUB_TOTAL'], "Total" => $price_subtotal); - $total[]=array("Unit Price" => $app_strings['LBL_ADJUSTMENT'], + $total[]=array("Tax" => $app_strings['LBL_ADJUSTMENT'], "Total" => $price_adjustment); - $total[]=array("Unit Price" => $app_strings['LBL_TAX'], + $total[]=array("Tax" => $app_strings['LBL_TAX'], "Total" => $price_tax); - $total[]=array("Unit Price" => $app_strings['LBL_GRAND_TOTAL'], + $total[]=array("Tax" => $app_strings['LBL_GRAND_TOTAL'], "Total" => $price_total); +// DG 31 Aug 2006 +// Get the global terms and conditions (if any) +$dg_query = "select * from vtiger_inventory_tandc"; +$result = $adb->query($dg_query); +$num_rows = $adb->num_rows($result); +if($num_rows == 1) +{ + $org_termsconditions = $adb->query_result($result,0,"tandc"); +} + // ************************ END POPULATE DATA ***************************8 $page_num='1'; $pdf = new PDF( 'P', 'mm', 'A4' ); +$pdf->AliasNbPages("maxpages"); $pdf->Open(); $num_pages=ceil(($num_products/$products_per_page)); - $current_product=0; for($l=0;$l<$num_pages;$l++) { $line=array(); + // DG 01 Sept 2006 + // Comment support + $dg_page_comment_line=array(); + if($num_pages == $page_num) $lastpage=1; while($current_product != $page_num*$products_per_page) { $line[]=$product_line[$current_product]; + // DG 01 Sept 2006 + // Need to catch which page each comment is on + // or we get repeating comments on each page + $dg_page_comment_line[]=$dg_comment_line[$current_product]; $current_product++; } @@ -173,7 +227,21 @@ } } +// DG 01 Sept 2006 +// Print the global terms and conditions as an appendix +// Whoops! This needs to go outside the main page loop, or we get +// this after every page! +if ($org_termsconditions) { + $pdf->AddPage(); + $pdf->SetFontSize(8); + $pdf->Write(3.5,$org_termsconditions); + //$pdf->MultiCell(0,3,$org_termsconditions); +} -$pdf->Output('Quotes.pdf','D'); //added file name to make it work in IE, also forces the download giving the user the option to save +// DG 31 Aug 2006 +// Filename needs to reflect date +$today = date("M-j-Y"); +$filename = "Quote-$id-$today.pdf"; +$pdf->Output($filename,'D'); //added file name to make it work in IE, also forces the download giving the user the option to save ?> Index: modules/Quotes/pdf_templates/header.php =================================================================== --- modules/Quotes/pdf_templates/header.php (revision 1) +++ modules/Quotes/pdf_templates/header.php (working copy) @@ -11,11 +11,17 @@ // ************** Begin company information ***************** -$imageBlock=array("10","3","0","0"); +// DG 30 Aug 2006 +// Specify explicit image width +// Will need to be tweaked per logo depending on shape +$imageBlock=array("10","3","75","0"); $pdf->addImage( $logo_name, $imageBlock); // x,y,width -$companyBlockPositions=array( "10","23","60" ); +// DG 30 Aug 2006 +// Tweaked the Y pos to better match our logo +// This needs to be a config option of some sort +$companyBlockPositions=array( "10","16","60" ); $companyText=$org_address."\n".$org_city.", ".$org_state." ".$org_code." ".$org_country; $pdf->addTextBlock( $org_name, $companyText ,$companyBlockPositions ); @@ -34,19 +40,27 @@ // page number $pageBubble=array("180","17",0); -$pdf->addBubbleBlock($page_num, "Page", $pageBubble); +// DG 30 Aug 2006 +// Add total number of pages to bubble +$pagenotext = $page_num.' / maxpages'; +$pdf->addBubbleBlock($pagenotext, "Page", $pageBubble); // ************** End Top-Right Header ***************** +// DG 30 Aug 2006 +// Move company name up here +$companyLocation = array("10","35","100"); +$pdf->addTextBlock($account_name, "", $companyLocation); - // ************** Begin Addresses ************** +// DG 30 Aug 2006 +// Moved these around a little bit // shipping Address -$shipLocation = array("10","43","60"); +$shipLocation = array("80","43","60"); $shipText=$ship_street."\n".$ship_city.", ".$ship_state." ".$ship_code."\n".$ship_country; $pdf->addTextBlock( "Shipping Address:", $shipText, $shipLocation ); // billing Address -$billPositions = array("147","43","60"); +$billPositions = array("10","43","60"); $billText=$bill_street."\n".$bill_city.", ".$bill_state." ".$bill_code."\n".$bill_country; $pdf->addTextBlock("Billing Address:",$billText, $billPositions); // ********** End Addresses ****************** @@ -56,14 +70,22 @@ /* ******** Begin Quote Data ************************ */ // terms block $termBlock=array("10","65"); -$pdf->addRecBlock($account_name, "Customer Name", $termBlock); +$pdf->addRecBlock($contact_name, "Prepared For", $termBlock); +$termBlock=array("80","65"); +$pdf->addRecBlock($user_name, "Prepared By", $termBlock); + // due date block -$dueBlock=array("80","65"); +$dueBlock=array("147","65"); $pdf->addRecBlock($valid_till, "Valid Till",$dueBlock); +// DG 30 Aug 2006 +// Date block +$dateBlock=array("147","51"); +$pdf->addRecBlock($todays_date, "Date Issued",$dateBlock); + // vtiger_invoice number block -$invBlock=array("147","65"); +$invBlock=array("147","37"); $pdf->addRecBlock($quote_id, "Quote Number",$invBlock); /* ************ End Quote Data ************************ */ Index: include/fpdf/pdf.php =================================================================== --- include/fpdf/pdf.php (revision 1) +++ include/fpdf/pdf.php (working copy) @@ -202,7 +202,7 @@ $this->Cell($width,5, $title, 0, 0, "C"); $this->SetXY( $r1 + ($r2-$r1)/2 - 5, $y1 + 9 ); $this->SetFont( "Helvetica", "", 10); - $this->MultiCell($width,5,$page, 0,0, "C"); + $this->MultiCell($width,5,$page,0,0, 'C'); } // bubble blocks @@ -222,7 +222,7 @@ $this->Cell($width,5, $title, 0, 0, "C"); $this->SetXY( $r1 + ($r2-$r1)/2 - 5, $y1 + 9 ); $this->SetFont( "Helvetica", "", 10); - $this->Cell($width,5,$page, 0,0, "C"); + $this->Cell($width,5,$page, 0,0, 'L'); } // record blocks @@ -289,7 +289,10 @@ $x1 = $positions[1]; $y2 = $bottom; $this->SetXY( $r1, $y1 ); - $this->SetFont( "Helvetica", "", 10); + //DG 30 Aug 2006 + //Smaller font to give us a little more room + //And while we're at it, make col headings bold + $this->SetFont( "Helvetica", 'B', 8); $colX = $r1; $columns = $tab; @@ -306,6 +309,9 @@ break; } } + // DG 1 Sept 2006 + // Reset font back to normal + $this->SetFont(''); } function addLineFormat( $tab ) @@ -342,6 +348,35 @@ return ( $maxSize - $line ); } +// DG 01 Sept 2006 +// Add support for comment-subheadings in the Quote etc body +function addCommentLine( $line, $tab ) +{ + global $columns, $format; + + $ordonnee = 10; + $maxSize = $line; + + reset( $columns ); + while ( list( $lib, $pos ) = each ($columns) ) + { + $longCell = $pos -2; + $text = $tab[ $lib ]; + $length = $this->GetStringWidth( $text ); + $formText = $format[ $lib ]; + $this->SetXY( $ordonnee, $line); + if ($text) { + $this->SetFont('', 'BU'); + $this->MultiCell( $longCell, 3 , $text, 3, $formText); + $this->SetFont(''); + } + if ( $maxSize < ($this->GetY() ) ) + $maxSize = $this->GetY() ; + $ordonnee += $pos; + } + return ( $maxSize - $line ); +} + function addTotalsRec($names, $totals, $positions) { $this->SetFont( "Arial", "B", 8); Index: include/fpdf/templates/body.php =================================================================== --- include/fpdf/templates/body.php (revision 1) +++ include/fpdf/templates/body.php (working copy) @@ -1,7 +1,7 @@ watermark( $status, $waterMarkPositions, $waterMarkRotate ); @@ -18,22 +18,44 @@ // total of columns needs to be 190 in order to fit the table // correctly // alignment of each column -$colsAlign=array( "Product Name" => "L", - "Description" => "L", - "Qty" => "C", +// DG 30 Aug 2006 +// Change this around to fit actual useage at ATI +$colsAlign=array( "Qty" => "C", + "Part No" => "C", + "Product Name" => "L", "List Price" => "R", + "Unit Price" => "R", "Tax" => "R", - "Unit Price" => "R", "Total" => "R" ); + +//$colsAlign=array( "Product Name" => "L", +// "Description" => "L", +// "Qty" => "C", +// "List Price" => "R", +// "Tax" => "R", +// "Unit Price" => "R", +// "Total" => "R" ); + $prodTable=array("10","60"); -$cols=array( "Product Name" => 25, - "Description" => 75, - "Qty" => 10, - "List Price" => 20, - "Tax" => 15, - "Unit Price" => 25, - "Total" => 20 - ); + +// DG 30 Aug 2006 +// Same deal - rearrange cols according to ATI practice +$cols=array( "Qty" => 10, + "Part No" => 25, + "Product Name" => 75, + "List Price" => 20, + "Unit Price" => 20, + "Tax" => 20, + "Total" => 20 ); + +//$cols=array( "Product Name" => 25, +// "Description" => 75, +// "Qty" => 10, +// "List Price" => 20, +// "Tax" => 15, +// "Unit Price" => 25, +// "Total" => 20 +// ); $pdf->addCols( $cols,$prodTable,$bottom ); $pdf->addLineFormat( $colsAlign); @@ -43,9 +65,21 @@ /* ************* Begin Product Population *************** */ -$ppad=3; +$ppad=1.5; $y = $top+10; for($i=0;$iaddCommentLine( $y, $dg_page_comment_line[$i] ); + $y += $size+$ppad; + } + $size = $pdf->addProductLine( $y, $line[$i] ); $y += $size+$ppad; } @@ -64,14 +98,16 @@ // These are the lines in-between the totals, remove if you want // $x,$y,$length -$lineData=array("155",$bottom+73,"44"); +// DG 31 Aug 2006 +// Tweaked values to match new column spacing +$lineData=array("160",$bottom+72,"39"); $pdf->drawLine($lineData); -$lineData=array("155",$lineData[1]-$pad,"44"); +$lineData=array("160",$lineData[1]-$pad,"39"); $pdf->drawLine($lineData); -$lineData=array("155",$lineData[1]-$pad,"44"); +$lineData=array("160",$lineData[1]-$pad,"39"); $pdf->drawLine($lineData); -$lineData=array("155",$lineData[1]-$pad,"44"); +$lineData=array("160",$lineData[1]-$pad,"39"); $pdf->drawLine($lineData); /* ************* End Totals *************************** */ Index: include/utils/CommonUtils.php =================================================================== --- include/utils/CommonUtils.php (revision 1) +++ include/utils/CommonUtils.php (working copy) @@ -407,7 +407,10 @@ $result = $adb->query($sql); $firstname = $adb->query_result($result,0,"firstname"); $lastname = $adb->query_result($result,0,"lastname"); - $contact_name = $lastname.' '.$firstname; + // DG 30 Aug 2006 + // BUG - should be Firstname.Lastname + //$contact_name = $lastname.' '.$firstname; + $contact_name = $firstname.' '.$lastname; $log->debug("Exiting getContactName method ..."); return $contact_name; } @@ -600,9 +603,6 @@ /** * Get the username by giving the user id. This method expects the user id - * param $label_list - the array of strings to that contains the option list - * param $key_list - the array of strings to that contains the values list - * param $selected - the string which contains the default value */ function getUserName($userid) @@ -623,6 +623,29 @@ } /** + * Get the user full name by giving the user id. This method expects the user id + * DG 30 Aug 2006 + */ + +function getUserFullName($userid) +{ + global $log; + $log->debug("Entering getUserFullName(".$userid.") method ..."); + $log->info("in getUserFullName ".$userid); + + global $adb; + if($userid != '') + { + $sql = "select first_name, last_name from vtiger_users where id=".$userid; + $result = $adb->query($sql); + $first_name = $adb->query_result($result,0,"first_name"); + $last_name = $adb->query_result($result,0,"last_name"); + $user_name = $first_name." ".$last_name; + } + $log->debug("Exiting getUserName method ..."); + return $user_name; +} +/** * Creates and returns database query. To be used for search and other text links. This method expects the module object. * param $focus - the module object contains the column vtiger_fields */