Skip to content

Instantly share code, notes, and snippets.

@jazzsequence
Last active December 14, 2015 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jazzsequence/5120145 to your computer and use it in GitHub Desktop.
Save jazzsequence/5120145 to your computer and use it in GitHub Desktop.
Event Espresso invoice template including surcharge/VAT support. This file should go in your /wp-content/uploads/espresso/gateways/invoice directory.
<?php
/*Custom Log Function Include*/
// require('log.php');
/*End Custom Log Function Include*/
if (isset($_SESSION['espresso_session']['id'])) {
unset($_SESSION['espresso_session']['id']);
}
define('FPDF_FONTPATH', EVENT_ESPRESSO_PLUGINFULLPATH . 'class/fpdf/font/');
require_once EVENT_ESPRESSO_PLUGINFULLPATH . 'class/fpdf/fpdf.php';
global $espresso_premium; if ($espresso_premium != true) return;
global $wpdb, $org_options;
$invoice_payment_settings = get_option('event_espresso_invoice_payment_settings');
/*Initial query
* We are using your initial query to pull the 'attendee_session' from the database. This will be used in the main query.
* It might be an idea to use the 'attendee_session'in the generated invoice url as you could then eliminate this query alltogether.
* Ideally we would use a stored procedure to eliminate the need to lines 19-65
*/
$attendees = $wpdb->get_results("SELECT * FROM ". EVENTS_ATTENDEE_TABLE ." WHERE registration_id ='" . $_REQUEST['registration_id'] . "' LIMIT 0,1");
foreach ($attendees as $attendee){
$attendee_id = $attendee->id;
$attendee_last = $attendee->lname;
$attendee_first = $attendee->fname;
$attendee_address = $attendee->address;
$attendee_city = $attendee->city;
$attendee_state = $attendee->state;
$attendee_zip = $attendee->zip;
$attendee_email = $attendee->email;
//$attendee_organization_name = $attendee->organization_name;
//$attendee_country = $attendee->country_id;
$phone = $attendee->phone;
$date = $attendee->date;
//$num_people = $attendee->quantity;
$payment_status = $attendee->payment_status;
$txn_type = $attendee->txn_type;
$attendee_session = $attendee->attendee_session;
$event_price_type = $attendee->price_option;
$amount_pd = $attendee->amount_pd;
$payment_date = $attendee->payment_date;
$event_id = $attendee->event_id;
$registration_id=$attendee->registration_id;
}
/*
* Calculate the total cost for each event in the basket (without surcharge, in our case VAT)
* @param integer $event_cost
* @param integer $quantity //value calculated by the query
* @return double $total_cost
*/
function lh_calc_event_cost($event_cost, $quantity){
return doubleval($event_cost * $quantity);
}
/*
* Calculate the surcharge on an event (in our case VAT)
* @param integer $surcharge
* @param integer $quantity
* @param integer $event_cost
* @return integer $event_surcharge
*/
function lh_calc_event_tax($surcharge, $quantity, $event_cost){
$surcharge_rate = '0.' . $surcharge;
return ($event_cost * $surcharge_rate) * $quantity;
}
/*
* Query to pull all the information we need for our invoice from the database.
* $multi_events formatted as a numerically indexed array.
* Using $attendee_session we can evaluate all of the events in a single order using a single query.
* Structure of $multi_events:
* array (
* 0 =>
* array (
* 0 => <QUANTITY>,
* 1 => <EVENT NAME>,
* 2 => <EVENT DATE>,
* 3 => <EVENT COST>,
* 4 => <EVENT SURCHARGE>,
* )
*/
$multi_events = $wpdb->get_results("SELECT COUNT(*), " . EVENTS_DETAIL_TABLE . ".event_name, " . EVENTS_DETAIL_TABLE . ".start_date, " . EVENTS_PRICES_TABLE . ".event_cost, " . EVENTS_PRICES_TABLE . ".surcharge
FROM ". EVENTS_ATTENDEE_TABLE ."
LEFT JOIN " . EVENTS_DETAIL_TABLE . " ON " . EVENTS_ATTENDEE_TABLE . ".event_id = " . EVENTS_DETAIL_TABLE . ".id
LEFT JOIN " . EVENTS_PRICES_TABLE . " ON " . EVENTS_ATTENDEE_TABLE . ".event_id = " . EVENTS_PRICES_TABLE . ".event_id
WHERE " . EVENTS_ATTENDEE_TABLE . ".attendee_session = '" . $attendee_session . "'
GROUP BY " . EVENTS_DETAIL_TABLE . ".event_name;", ARRAY_N );
//invoice_log::singleton()->log( array ( 'file' => __FILE__, 'function' => __FUNCTION__, 'status' => "sqldump = " . var_export($multi_events, true) ) );
//Build the PDF
class PDF extends Espresso_FPDF
{
//Page header
function Header()
{
global $wpdb, $org_options;
$invoice_payment_settings = get_option('event_espresso_invoice_payment_settings');
//Logo
if (trim($invoice_payment_settings['image_url']) !=''){
$this->Image($invoice_payment_settings['image_url'],10,8,40,0);//Set the logo if it is available
}else{
$this->SetFont('Arial','B',15);
$this->Cell(10,10,iconv("UTF-8", "ISO-8859-1",$org_options['organization']),0,0,'L');//If no logo, then display the organizatin name
}
//Arial bold 15
$this->SetFont('Arial','B',15);
//Move to the right
$this->Cell(80);
//Title
$this->MultiCell(100,20,iconv("UTF-8", "ISO-8859-1",$invoice_payment_settings['pdf_title']),0,'R');//Set the right header
//Line break
$this->Ln(20);
}
function LoadData($file)
{
$lines=$file;
$data=array();
foreach($lines as $line)
$data[]=explode(';',chop($line));
return $data;
}
//Better table
function ImprovedTable($header,$event_data)
{
$options = get_option('events_organization_settings');
$currency = $options['currency_symbol'];
//Column widths
/*
* Extra columns added to the table layout
*/
$w=array(115,15,25,35);
//Header
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C');
$this->Ln();
$x = $this->GetX();
$y = $this->GetY();
/*
* The only modification needed to the function in order to display the extra data is
* an extra foreach loop. We also modified the positioning of the cells to account for the
* extra information we are displaying
*/
foreach($event_data as $data){
//invoice_log::singleton()->log( array ( 'file' => __FILE__, 'function' => __FUNCTION__, 'status' => "sqldump = " . var_export($event_data, true) ) );
foreach($data as $row)
{
//invoice_log::singleton()->log( array ( 'file' => __FILE__, 'function' => __FUNCTION__, 'status' => "sqldump = " . var_export($row, true) ) );
$y1 = $this->GetY();
$this->MultiCell($w[0],6,$row[0],'LBR');
$y2 = $this->GetY();
$yH = $y2 - $y1;
$this->SetXY($x + $w[0], $this->GetY() - $yH);
$this->Cell($w[1],$yH,$row[1],'LBR',0,'C');
$this->Cell($w[2],$yH,$row[2],'LBR',0,'C');
//$this->Cell($w[3],$yH,number_format($row[3],2, '.', ''),'LBR',0,'C');
$this->Cell($w[3],$yH,html_entity_decode($currency, ENT_QUOTES, 'ISO-8859-15') . number_format($row[3],2,'.',''),'LBR',0,'C');
$this->Ln();
}
}
//Closure line
$this->Cell(array_sum($w),0,'','T');
}
/*
* Function to display the totals that we have calculated. Mainly cosmetic.
* @param integer $sub_total (this is the total cost of the events without surcharge added)
* @param integer $vat (the total surcharge on the order)
*/
function InvoiceTotals($sub_total, $vat, $surcharge){
$options = get_option('events_organization_settings');
$currency = $options['currency_symbol'];
$total_cost = $sub_total + $vat;
$this->SetFillColor(192,192,192);
//Print sub total
$this->Cell(155, 10, 'Subtotal excluding VAT:', 0, 0, 'R', true);
$this->Cell(35, 10, html_entity_decode($currency, ENT_QUOTES, 'ISO-8859-15') . number_format($sub_total,2, '.', ''), 0, 1, 'C', true);
//Print total VAT
$this->Cell(155, 10, 'VAT @ ' . $surcharge . '%:', 0, 0, 'R', true);
$this->Cell(35, 10, html_entity_decode($currency, ENT_QUOTES, 'ISO-8859-15') . number_format($vat,2, '.', ''), 0, 1, 'C', true);
//Print total cost
$this->Cell(155, 10, 'Total:', 0, 0, 'R');
$this->Cell(35, 10, html_entity_decode($currency, ENT_QUOTES, 'ISO-8859-15') . number_format($total_cost,2, '.', ''), 0, 1, 'C');
$this->Ln(20);
$this->Cell(190, 10, 'VAT registration number: XXX XXXX XX.', 0, 0, 'R'); // replace with your VAT ID or comment this line out
}
//Page footer
function Footer()
{
//Position at 1.5 cm from bottom
$this->SetY(-15);
//Arial italic 8
$this->SetFont('Arial','I',8);
//Page number
$this->Cell(0,10, __('Page','event_espresso').$this->PageNo().'/{nb}',0,0,'C');
}
}
//Create a payment link
$payment_link = home_url() . "/?page_id=" . $org_options['return_url'] . "&id=" . $attendee_id;
//Instanciation of inherited class
$pdf=new PDF();
$pdf->AliasNbPages();
$pdf->SetAuthor(iconv("UTF-8", "ISO-8859-1",$org_options['organization']));
$pdf->SetTitle(iconv("UTF-8", "ISO-8859-1", $attendee_id . $attendee_last . ' - ' . $invoice_payment_settings['pdf_title']));
//$pdf->SetAutoPageBreak('auto');
$pdf->AddPage();
//Create the top right of invoice below header
$pdf->SetFont('Times','',12);
$pdf->Cell(180,0, __('Date: ','event_espresso'). date('m-d-Y'),0,1, 'R');//Set invoice date
$pdf->Cell(180,10,__('Primary Attendee ID: ','event_espresso'). $attendee_id,0,0, 'R');//Set Invoice number
$pdf->Ln(0);
//Set the top left of invoice below header
$pdf->SetFont('Times','BI',14);
$pdf->MultiCell(0,10,iconv("UTF-8", "ISO-8859-1",$invoice_payment_settings['payable_to']),0,'L');//Set payable to
$pdf->SetFont('Times','',12);
$pdf->MultiCell(50,5,iconv("UTF-8", "ISO-8859-1",$invoice_payment_settings['payment_address']),0, 'L');//Set address
$pdf->Ln(5);
//Set the biiling information
$pdf->SetFont('Times','B',12);
$pdf->Cell(50,5,__('Bill To: ','event_espresso'),0,1,'L');//Set biil to
$pdf->SetFont('Times','',12);
$pdf->Cell(50,5,iconv("UTF-8", "ISO-8859-1",$attendee_first . ' ' . $attendee_last),0,1, 'L');//Set attendee name
$pdf->Cell(50,5,$attendee_email,0,1,'L');//Set attendee email
//Set attendee address
$attendee_address != '' ? $pdf->Cell(100,5,$attendee_address,0,1,'L') :'';
$pdf->Cell(100,5,(iconv("UTF-8", "ISO-8859-1",$attendee_city != '' ? $attendee_city :''). ($attendee_state != '' ? ' ' . $attendee_state :'')),0,1,'L');
$attendee_zip != '' ? $pdf->Cell(50,5,$attendee_zip,0,1,'L') :'';
$pdf->Ln(10);
//Build the payment link and instructions
$pdf->MultiCell(100,5,iconv("UTF-8", "ISO-8859-1",$invoice_payment_settings['pdf_instructions']),0,'L');//Set instructions
$pdf->Ln(10);
//Build the table for the event details
//Column titles
$header=array(__('Event Name','event_espresso'),__('Qty.','event_espresso'),__('Event Date','event_espresso'),__('Price','event_espresso'));
//Event Data
/*
* Here we have make multiple calls to the 'LoadData' function in order to format the data we pulled from the database.
* As we are simply patching your code, this was the simplest solution.
*
*/
$tax_total = 0;
$cost_total = 0;
if($multi_events){
foreach($multi_events as $s_event){
$cost = lh_calc_event_cost($s_event[3], $s_event[0] );
$event_data[] = $pdf->LoadData (array(iconv("UTF-8", "ISO-8859-1",$s_event[1]) . ';' . iconv("UTF-8", "ISO-8859-1", $s_event[0]) . ';' . date('m-d-Y',strtotime($s_event[2])) . ';' . doubleval($s_event[3]) . ';' ) );
$tax_total += lh_calc_event_tax($s_event[4], $s_event[0], $s_event[3]);
$surcharge = $s_event[4];
$cost_total += $cost;
}
$pdf->ImprovedTable($header, $event_data);
}
$pdf->Ln();
/*
* Using the totals calculated above, add in the totals section of the pdf.
*/
$pdf->InvoiceTotals($cost_total, $tax_total, $surcharge);
$pdf->Ln(10);
$pdf->SetFont('Arial','BU',20);
//$pdf->Cell(200,20,'Pay Online',0,1,'C',0,$payment_link);//Set payment link
$pdf->Output($attendee_id . '-' . $attendee_last.'.pdf','D');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment