Page 341 of 356 FirstFirst ... 241291331339340341342343351 ... LastLast
Results 3,401 to 3,410 of 3558
  1. #3401
    Join Date
    Nov 2005
    Location
    France
    Posts
    577
    Plugin Contributions
    8

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    Quote Originally Posted by mc12345678 View Post
    These changes resolved the issue.
    Thanks McNumbers

  2. #3402
    Join Date
    Jul 2012
    Posts
    16,732
    Plugin Contributions
    17

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    Quote Originally Posted by strelitzia View Post
    @mc12345678
    A quick preview of the modified layout for the first section of the page (pending your response re the 'search' button.

    Attachment 19591
    Strelitzia, I really apologize for the delay in responding to this and your probable loss of steam. Let me just say that a lot has/had happened that weekend and in a way still recovering from those events. Some time was necessary to mentally review what had happened in that area and why there were two buttons to perform the same action.

    So, it somewhat went like this: wanted to provide a "tool" that was consistent across other operations within the ZC software and wanted to make updating it as easy as possible in the event that its use/creation changed within the ZC source code. So, it seemed that the best way to accommodate that was to reuse existing code as much and in the same way as possible. In doing so, I was also trying to work through a specific issue related to using these additional dropdowns (I don't think that even still that I have fully/successfully addressed all that I wanted to address) so had attempted to duplicate the code even though I may have also had an alternate action button that did the same thing. Then there was also the desire to try to ensure that the page passed html validation (I think with the duplicate buttons as they were in that area that two buttons had the same id parameter which doesn't pass validation).

    Anyways, I wanted to be sure that removal of one or the other button would still fully support the operation even if the look was improved. I hadn't quite finished that review when I was pulled away. To me it looks right and good and I would think that the operation would be improved with the "loss" of one or the other buttons.

    As for removal of one of the buttons... So, I have a few ideas about it and at least a partial reason for them both to be present/exist... So the removal of the search button would mean that it would be present unless we were looking at and have selected a product from the product list... Even with nothing else in mind, that seems like a lot of logic to address... The alternate being that the display button not be shown in that same condition, but then in use, selecting a product from the list makes one question "where" to make a selection on screen. Then there is one of the other reasons I keep the text of the search in the search field with the search button next to it is that the search "criteria" is clickable (copy/paste) and can be used elsewhere in the ZC system regardless of how the URI is formatted/generated. While a ***VERY*** rudimentary search facility is used, one could amplify how it works and the results, so I don't really want to remove the search button per se because one could possibly support (add code for) searching on specific attribute criteria or other aspects and it would be intuitive to click the search button next to that search text...

    I guess I would say, even though the code looks the "same" for the two, these clickable options are provided based on an end user perspective of what makes sense and offers functionality.
    ZC Installation/Maintenance Support <- Site
    Contribution for contributions welcome...

  3. #3403
    Join Date
    Nov 2005
    Location
    France
    Posts
    577
    Plugin Contributions
    8

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    I'll pick up the interface changes as soon as I get some time.

    On a separate note, I've found that fpdf generates an error when creating an invoice for items with a custom id since updating SBA.

    The error logged is
    Code:
    PHP Fatal error: Uncaught Error: Call to undefined function zen_get_customid() in /fpdf/genpdf.php:161
    I suspect that's due to you having moved zen_get_customid() from includes/functions/extra_functions/products_with_attributes.php to includes/classes/class.products_with_attributes_class_stock.php

    What is the recommended fix for this issue?

  4. #3404
    Join Date
    Jul 2012
    Posts
    16,732
    Plugin Contributions
    17

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    Quote Originally Posted by strelitzia View Post
    I'll pick up the interface changes as soon as I get some time.

    On a separate note, I've found that fpdf generates an error when creating an invoice for items with a custom id since updating SBA.

    The error logged is
    Code:
    PHP Fatal error: Uncaught Error: Call to undefined function zen_get_customid() in /fpdf/genpdf.php:161
    I suspect that's due to you having moved zen_get_customid() from includes/functions/extra_functions/products_with_attributes.php to includes/classes/class.products_with_attributes_class_stock.php

    What is the recommended fix for this issue?
    Prepend your call to zen_get_customid() with: $_SESSION['pwas_class2']->
    so

    zen_get_customid()

    would become:

    $_SESSION['pwas_class2']->zen_get_customid()
    ZC Installation/Maintenance Support <- Site
    Contribution for contributions welcome...

  5. #3405
    Join Date
    Nov 2005
    Location
    France
    Posts
    577
    Plugin Contributions
    8

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    Quote Originally Posted by mc12345678 View Post
    Prepend your call to zen_get_customid() with: $_SESSION['pwas_class2']->
    so

    zen_get_customid()

    would become:

    $_SESSION['pwas_class2']->zen_get_customid()
    Worked like a charm. Useful info to file away for future reference. Thanks McNumbers

  6. #3406
    Join Date
    Nov 2005
    Location
    France
    Posts
    577
    Plugin Contributions
    8

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    Quote Originally Posted by strelitzia View Post
    Worked like a charm. Useful info to file away for future reference. Thanks McNumbers
    Seems I have another issue after the last update.

    Now logging the following error
    Code:
    PHP Fatal error: order::main(): The script tried to execute a 
    method or access a property of an incomplete object. Please ensure that 
    the class definition "products_with_attributes_class_stock" of the 
    object you are trying to operate on was loaded _before_ unserialize() 
    gets called or provide an autoloader to load the class definition in 
    /fpdf/genpdf.php on line 161.
    The genpdf.php code block in question is
    Code:
    for ($i = 0; $i < sizeof($this->products); $i++) {
    	$attribute_customid = '';
    	$attribute_names = array();
    	$x = strip_tags($this->products[$i]['name']);
    	
    	// Process attributes
    	if (isset($this->products[$i]['attributes']) && sizeof($this->products[$i]['attributes']) > 0) {
    		foreach ($this->products[$i]['attributes'] as $attributes) {
    			$attribute_names[] = $attributes['option'] . ': ' . $attributes['value'];
    		
    			$attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
    		}
    		
    		if (isset($attribute_names) && is_array($attribute_names)) {
    			$attribute_string = implode(', ', $attribute_names);
    			$x .= ' ' . $attribute_string;
    		}
    	}
    	
    	$y = $this->products[$i]['qty'];
    	$z = ($this->products[$i]['final_price'] > 0 ? $this->products[$i]['final_price'] : $this->products[$i]['price']);
    	$t = $this->products[$i]['tax'];
    	$m = ($this->products[$i]['model'] == '' && $attribute_customid != '' ? $attribute_customid : $this->products[$i]['model']);
    	$x = str_replace("<br>", "", $x );
    
    	$itemname = "$y x $x";
    	$totalexvat = $z * $y;
    	$totalcost = (zen_add_tax($z, $t) * $y) + zen_add_tax($this->products[$i]['onetime_charges'], $t);
    
    	$thistax = zen_calculate_tax($z, $t);
    	$pwt = $z + $thistax;
    	// $totaltax += zen_calculate_tax($z, $t) * $this->products[$i]['qty'];
    	
    	$z = number_format($z, 2, '.', '');
    	$totalcost = number_format($totalcost, 2, '.', '');
    	$pwt = number_format($pwt, 2, '.', '');
    	// $totaltax = number_format($totaltax, 2, '.', '');
    	$totalexvat = number_format($totalexvat, 2, '.', '');
    	$t = $t . "%";
    	// $total += $totalcost;
    	$lines[$i] = "$itemname|$m|$t|$pwt|$totalcost";
    }
    with line 161 being
    Code:
    $attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
    Can you shed any light on this?
    Last edited by strelitzia; 22 Jul 2021 at 04:22 PM.

  7. #3407
    Join Date
    Jul 2012
    Posts
    16,732
    Plugin Contributions
    17

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    Quote Originally Posted by strelitzia View Post
    Seems I have another issue after the last update.

    Now logging the following error
    Code:
    PHP Fatal error: order::main(): The script tried to execute a 
    method or access a property of an incomplete object. Please ensure that 
    the class definition "products_with_attributes_class_stock" of the 
    object you are trying to operate on was loaded _before_ unserialize() 
    gets called or provide an autoloader to load the class definition in 
    /fpdf/genpdf.php on line 161.
    The genpdf.php code block in question is
    Code:
    for ($i = 0; $i < sizeof($this->products); $i++) {
        $attribute_customid = '';
        $attribute_names = array();
        $x = strip_tags($this->products[$i]['name']);
        
        // Process attributes
        if (isset($this->products[$i]['attributes']) && sizeof($this->products[$i]['attributes']) > 0) {
            foreach ($this->products[$i]['attributes'] as $attributes) {
                $attribute_names[] = $attributes['option'] . ': ' . $attributes['value'];
            
                $attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
            }
            
            if (isset($attribute_names) && is_array($attribute_names)) {
                $attribute_string = implode(', ', $attribute_names);
                $x .= ' ' . $attribute_string;
            }
        }
        
        $y = $this->products[$i]['qty'];
        $z = ($this->products[$i]['final_price'] > 0 ? $this->products[$i]['final_price'] : $this->products[$i]['price']);
        $t = $this->products[$i]['tax'];
        $m = ($this->products[$i]['model'] == '' && $attribute_customid != '' ? $attribute_customid : $this->products[$i]['model']);
        $x = str_replace("<br>", "", $x );
    
        $itemname = "$y x $x";
        $totalexvat = $z * $y;
        $totalcost = (zen_add_tax($z, $t) * $y) + zen_add_tax($this->products[$i]['onetime_charges'], $t);
    
        $thistax = zen_calculate_tax($z, $t);
        $pwt = $z + $thistax;
        // $totaltax += zen_calculate_tax($z, $t) * $this->products[$i]['qty'];
        
        $z = number_format($z, 2, '.', '');
        $totalcost = number_format($totalcost, 2, '.', '');
        $pwt = number_format($pwt, 2, '.', '');
        // $totaltax = number_format($totaltax, 2, '.', '');
        $totalexvat = number_format($totalexvat, 2, '.', '');
        $t = $t . "%";
        // $total += $totalcost;
        $lines[$i] = "$itemname|$m|$t|$pwt|$totalcost";
    }
    with line 161 being
    Code:
    $attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
    Can you shed any light on this?
    Did a little research on the message that is logged.

    Appears that the message is related to the "sequence" of session_start and use of session variables. That said, I wouldn't (necessarily) expect an issue if includes/application_top.php were loaded before getting to this point and also, the fact that the class is used as a session variable is something I *do* want to change, which was done as a minor work around to a portion of the checkout process.

    So the real question here is, when accessing this "file", how does it interact with the rest of Zen Cart? It could be possible to "prepare" the variable for use here (actually before the loop), but understanding the integration really helps such as is this on the admin side, is there some sort of load point at which it is brought in and how does that load point compare to what SBA does?

    On another side note, I see that only a single option value is ever presented to the zen_get_customid method. Are all product being offered where each option value is listed uniquely and there are no combined option values? Are both types being populated and only the single option value is being given a customid? The method supports being handed all of the option values associated with the product and then providing a sort of "formatted" customid.
    ZC Installation/Maintenance Support <- Site
    Contribution for contributions welcome...

  8. #3408
    Join Date
    Nov 2005
    Location
    France
    Posts
    577
    Plugin Contributions
    8

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    The file in question is invoked when an order is placed so that it can generate a pdf invoice to attach to the order confirmation email.
    Code:
    require_once(DIR_FS_CATALOG . 'fpdf/genpdf.php');
    is located in the order class, right before the //send additional emails code block.

    The directory 'fpdf' is in the site root, and full content of that file is
    Code:
    <?php
    // Process order totals
    if (!isset($order_totals) || isset($order_totals) && !is_array($order_totals) || isset($order_totals) && is_array($order_totals) && sizeof($order_totals) < 1)  $order_totals = $order_total_modules->process();
    if (is_array($order_totals)) {
    	foreach ($order_totals as $totals) {
    		$pdf_totals[$totals['code']] = $totals['value'];
    	}
    }
    
    if (isset($pdf_totals['ot_coupon'])) {
    	$discount_coupon = number_format($pdf_totals['ot_coupon'], 2, '.', '');
    	unset($pdf_totals['ot_coupon']);
    }
    if (isset($pdf_totals['ot_gv'])) {
    	$gift_certificate = number_format($pdf_totals['ot_gv'], 2, '.', '');
    	unset($pdf_totals['ot_gv']);
    }
    $total = number_format($pdf_totals['ot_subtotal'], 2, '.', '');
    $sc = number_format($pdf_totals['ot_shipping'], 2, '.', '');
    $totaltax = number_format($pdf_totals['ot_tax'], 2, '.', '');
    $final = number_format($pdf_totals['ot_total'], 2, '.', '');
    unset($pdf_totals['ot_subtotal']);
    unset($pdf_totals['ot_shipping']);
    unset($pdf_totals['ot_tax']);
    unset($pdf_totals['ot_total']);
    
    // Will the products fit on one page?
    $next_page = false;
    if ((sizeof($this->products) > 8 && !isset($discount_coupon) && !isset($gift_certificate)) || (sizeof($this->products) > 7 && isset($discount_coupon)) || (sizeof($this->products) > 7 && isset($gift_certificate)) || (sizeof($this->products) > 6 && isset($discount_coupon) && isset($gift_certificate))) $next_page = true;
    
    error_reporting(0);
    define('FPDF_FONTPATH', DIR_FS_CATALOG . 'fpdf/font/');
    require('fpdf.php');
    $str = utf8_decode("£");
    $err = 0;
    $tnow = date('Y-m-d H:i:s');
    
    function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
    		$err = 0;
    		$file = $path.$filename;
    		$fp = fopen($file, "rb"); //Open it
    		$data = fread($fp, filesize($file)); //Read it
    		$data = chunk_split(base64_encode($data)); //Chunk it up and encode it as base64 so it can emailed
    		fclose($fp);
    		
    		$headers = "From: $name<" . $from_name . ">\n";
    		$headers .= "Reply-to: <" . $replyto . ">\n";
    		$headers .= "MIME-Version: 1.0\n";
    		$headers .= "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----=MIME_BOUNDRY_main_message\"\n";
    		$headers .= "X-sender: $name<" . $from_name . ">\n";
    		$headers .= "X-mailer: PHP mail\n";
    		$headers .= "X-Priority: 3\n"; //1 = Urgent, 3 = Normal
    		$headers .= "Return-Path: <" . $from_name . ">\n";
    		$headers .= "This is a multi-part message in MIME format.\n";
    		$headers .= "------=MIME_BOUNDRY_main_message \n";
    		$headers .= "Content-Type: multipart/alternative; boundary=\"----=MIME_BOUNDRY_message_parts\"\n"; 
    		
    		$message2 = "------=MIME_BOUNDRY_message_parts\n";
    		$message2 .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
    		$message2 .= "Content-Transfer-Encoding: quoted-printable\n";
    		$message2 .= "\n";
    		/* Add our message, in this case it's plain text. You could also add HTML by changing the Content-Type to text/html */
    		$message2 .= "$message\n";
    		$message2 .= "\n";
    		$message2 .= "------=MIME_BOUNDRY_message_parts--\n";
    		$message2 .= "\n";
    		$message2 .= "------=MIME_BOUNDRY_main_message\n";
    		$message2 .= "Content-Type: application/pdf;\n\tname=\"" . $filename . "\"\n";
    		$message2 .= "Content-Transfer-Encoding: base64\n";
    		$message2 .= "Content-Disposition: attachment;\n\tfilename=\"" . $filename . "\"\n\n";
    		$message2 .= $data; //The base64 encoded message
    		$message2 .= "\n";
    		$message2 .= "------=MIME_BOUNDRY_main_message--\n"; 
    		
    		if (mail($mailto, $subject, $message2, $headers)) {
    			//echo("mail send ... OK"); // or use booleans here
    		} else {
    			//echo("mail send ... ERROR!");
    			$err++;
    		}
    		return ($err);
    }
    
    
    class PDF extends FPDF
    {
    	
    	function FancyTable($titles,$data,$c,$start)
    	{
    		$str = utf8_decode("£");
    		$this->SetFillColor(255,0,0);
    		$this->SetTextColor(255);
    		$this->SetDrawColor(128,0,0);
    		$this->SetLineWidth(.4);
    		$this->SetFont('Arial','B',8);
    		//Header
    		$w=array(108,30,10,18,24);
    		for($i=0;$i<count($titles);$i++)
    			$this->Cell($w[$i],5,$titles[$i],1,0,'C',true);
    		$this->Ln();
    		//Color and font restoration
    		$this->SetFillColor(224,235,255);
    		$this->SetTextColor(0);
    		$this->SetFont('');
    		//Data
    		$fill=false;
    		$p = 0;
    		
    		foreach($data as $row)
    		{
    			if ($p >= $start) {
    				$this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
    				$this->Cell($w[1],6,$row[1],'LR',0,'R',$fill);
    				$this->Cell($w[2],6,$row[2],'LR',0,'L',$fill);
    				$this->Cell($w[3],6,$str . $row[3],'LR',0,'R',$fill);
    				$this->Cell($w[4],6,$str . $row[4],'LR',0,'R',$fill);
    				$this->Ln();
    				$fill=!$fill;
    			}
    			$p++;
    			if ($c == 0 && $p >= 8) { break; }
    			
    		}
    		$this->Cell(array_sum($w),0,'','T');
    		
    	}
    
    	//Page header
    	function Header()
    	{
    	}
    
    	//Page footer
    	function Footer()
    	{
    	}
    }
    
    //Instanciation of inherited class
    
    $i = 1;
    $pdf = new PDF();
    $pdf->AliasNbPages();
    $pdf->AddPage();
    
    $pi = 1;
    require ("invoice_top.php");
    
    // $total = 0.00;
    
    for ($i = 0; $i < sizeof($this->products); $i++) {
    	$attribute_customid = '';
    	$attribute_names = array();
    	$x = strip_tags($this->products[$i]['name']);
    	
    	// Process attributes
    	if (isset($this->products[$i]['attributes']) && sizeof($this->products[$i]['attributes']) > 0) {
    		foreach ($this->products[$i]['attributes'] as $attributes) {
    			$attribute_names[] = $attributes['option'] . ': ' . $attributes['value'];
    		
    			$attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
    		}
    		
    		if (isset($attribute_names) && is_array($attribute_names)) {
    			$attribute_string = implode(', ', $attribute_names);
    			$x .= ' ' . $attribute_string;
    		}
    	}
    	
    	$y = $this->products[$i]['qty'];
    	$z = ($this->products[$i]['final_price'] > 0 ? $this->products[$i]['final_price'] : $this->products[$i]['price']);
    	$t = $this->products[$i]['tax'];
    	$m = ($this->products[$i]['model'] == '' && $attribute_customid != '' ? $attribute_customid : $this->products[$i]['model']);
    	$x = str_replace("<br>", "", $x );
    
    	$itemname = "$y x $x";
    	$totalexvat = $z * $y;
    	$totalcost = (zen_add_tax($z, $t) * $y) + zen_add_tax($this->products[$i]['onetime_charges'], $t);
    
    	$thistax = zen_calculate_tax($z, $t);
    	$pwt = $z + $thistax;
    	// $totaltax += zen_calculate_tax($z, $t) * $this->products[$i]['qty'];
    	
    	$z = number_format($z, 2, '.', '');
    	$totalcost = number_format($totalcost, 2, '.', '');
    	$pwt = number_format($pwt, 2, '.', '');
    	// $totaltax = number_format($totaltax, 2, '.', '');
    	$totalexvat = number_format($totalexvat, 2, '.', '');
    	$t = $t . "%";
    	// $total += $totalcost;
    	$lines[$i] = "$itemname|$m|$t|$pwt|$totalcost";
    }
    
    // $total = number_format($total, 2, '.', '');
    // $totaltax = number_format($totaltax, 2, '.', '');
    // $final = $total + $sc;
    // $final = number_format($final, 2, '.', '');
    
    $pdf->ln(2);
    
    foreach($lines as $line) $data[]=explode('|',chop($line));
    
    $titles = array('Products','Stock Code','Tax','Unit Price', 'Line Total' );
    $pdf->FancyTable($titles,$data, 0, 0);
    $pdf->ln(1);
    $pdf->SetFont('Arial','',12);
    $pdf->Cell(0,25,"Payment Method: $payment_method", 0, 0, "L");
    $pdf->SetFont('Arial','B',12);
    $pdf->Cell(0,25,"Sub Total: " . $str . "$total", 0, 0, "R");$pdf->ln(8);
    $pdf->SetFont('Arial','I',12);
    if ($sc == "3.5") { $sc = "3.50"; }
    if ($sc == "8.5") { $sc = "8.50"; }
    if ($sc > 0) {
    	$pdf->Cell(0,25,"Shipping Cost: " . $str . "$sc", 0, 0, "R");$pdf->ln(8);
    }
    if (isset($discount_coupon) && $discount_coupon > 0) {
    	$pdf->Cell(0,25,"Discount Coupon: -" . $str . "$discount_coupon", 0, 0, "R");$pdf->ln(8);
    }
    $pdf->Cell(0,25,"Includes VAT of " . $str . "$totaltax", 0, 0, "R");$pdf->ln(8);
    if (isset($gift_certificate) && $gift_certificate > 0) {
    	$pdf->Cell(0,25,"Gift Certificates: -" . $str . "$gift_certificate", 0, 0, "R");$pdf->ln(8);
    }
    $pdf->SetFont('Arial','B',14);
    $pdf->Cell(0,25,"Total: " . $str . "$final", 0, 0, "R");
    
    if (!$next_page) {
    	$pdf->ln(18);
    
    	$pdf->SetFont('Arial','B',18);
    
    	$pdf->SetTextColor(205, 116, 66);
    	$pdf->SetX(64);
    	$pdf->Write(1,"Thank You");
    	$pdf->SetTextColor(220, 155, 115);
    
    	$pdf->Write(1," for your custom!");
    	$pdf->SetTextColor(0,0,0);
    
    	$pdf->SetFont('Arial','B',14);
    }
    
    //Label Part
    //Higher is higher, lower = lower on the page
    $pdf->SetFont('Arial','',8);
    $pdf->SetY(-96);
    $pdf->SetX(34);
    $pdf->Cell(0,5,"Return to:  Tudor Rose Patchwork", 0, 1);$pdf->SetX(48);
    $pdf->Cell(0,5,"C/o Bacchus Marsh Ltd", 0, 1);$pdf->SetX(48); 
    $pdf->Cell(0,5,"Unit 1, Station Road", 0, 1);$pdf->SetX(48); 
    $pdf->Cell(0,5,"Oakley MK43 7RB", 0, 1);$pdf->SetX(48);
    $pdf->Cell(0,5,"United Kingdom", 0, 1); 
    
    $pdf->SetY(-60);
    $pdf->SetX(85);
    $pdf->SetFont('Arial','B',16);
    $pdf->Cell(0,8,"$delfname $delsname", 0, 1);$pdf->SetX(85);
    $pdf->SetFont('Arial','B',14);
    if (strlen($delstreet) > 0) { $pdf->Cell(0,5,"$delstreet", 0, 1);$pdf->SetX(85); }
    if (strlen($delsuburb) > 0) { $pdf->Cell(0,5,"$delsuburb", 0, 1);$pdf->SetX(85); }
    $pdf->Cell(0,5,"$delcity", 0, 1);$pdf->SetX(85);
    if (strlen($delstate) > 0) { $pdf->Cell(0,5,"$delstate", 0, 1);$pdf->SetX(85); }
    $pdf->Cell(0,5,"$delpostcode", 0, 1);$pdf->SetX(85);
    $pdf->Cell(0,5,"$delcountry", 0, 1);
    
    if ($next_page) {
    	$pdf->AddPage();
    	$pi = 2;
    	require ("invoice_top.php");
    	$pdf->ln(2);
    	$pdf->FancyTable($titles,$data, 1, 8);
    }
    
    if ($next_page) {
    	$pdf->ln(25);
    
    	$pdf->SetFont('Arial','B',18);
    
    	$pdf->SetTextColor(205, 116, 66);
    	$pdf->SetX(64);
    	$pdf->Write(1,"Thank You");
    	$pdf->SetTextColor(220, 155, 115);
    
    	$pdf->Write(1," for your custom!");
    	$pdf->SetTextColor(0,0,0);
    
    	$pdf->SetFont('Arial','B',14);
    }
    
    $pdf->Output(DIR_FS_CATALOG . "download/$zf_insert_id.pdf",F);
    
    $x = DIR_FS_CATALOG . "download/$zf_insert_id.pdf";
    
    if ($err == 0) {
    	$mailerr == 0;
    	$my_file = "$zf_insert_id.pdf";
    	$my_path = DIR_FS_CATALOG . "download/";
    	$my_name = "Sandra";
    	$my_mail = "[email protected]";
    	$my_replyto = "[email protected]";
    	$my_subject = "PDF for TRP Order No $zf_insert_id";
    	$my_message = "Tudor Rose order number $zf_insert_id";
    	$mailerr = mail_attachment($my_file, $my_path, "[email protected]", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);
    	if ($mailerr > 0) {
    		error_log("$tnow - An error occured while sending the following attachment by email, $zf_insert_id.pdf\n", 3, DIR_FS_CATALOG . "error_log");
    	} else {
    		//chmod (DIR_FS_CATALOG . "orders/$zf_insert_id.pdf", 0700) or $err++;		
    	}
    } else {
    	error_log("$tnow - An error occured while modifying the permissions on, $zf_insert_id.pdf\n", 3, DIR_FS_CATALOG . "error_log");
    }

  9. #3409
    Join Date
    Jul 2012
    Posts
    16,732
    Plugin Contributions
    17

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    Quote Originally Posted by strelitzia View Post
    The file in question is invoked when an order is placed so that it can generate a pdf invoice to attach to the order confirmation email.
    Code:
    require_once(DIR_FS_CATALOG . 'fpdf/genpdf.php');
    is located in the order class, right before the //send additional emails code block.

    The directory 'fpdf' is in the site root, and full content of that file is
    Code:
    <?php
    // Process order totals
    if (!isset($order_totals) || isset($order_totals) && !is_array($order_totals) || isset($order_totals) && is_array($order_totals) && sizeof($order_totals) < 1)  $order_totals = $order_total_modules->process();
    if (is_array($order_totals)) {
        foreach ($order_totals as $totals) {
            $pdf_totals[$totals['code']] = $totals['value'];
        }
    }
    
    if (isset($pdf_totals['ot_coupon'])) {
        $discount_coupon = number_format($pdf_totals['ot_coupon'], 2, '.', '');
        unset($pdf_totals['ot_coupon']);
    }
    if (isset($pdf_totals['ot_gv'])) {
        $gift_certificate = number_format($pdf_totals['ot_gv'], 2, '.', '');
        unset($pdf_totals['ot_gv']);
    }
    $total = number_format($pdf_totals['ot_subtotal'], 2, '.', '');
    $sc = number_format($pdf_totals['ot_shipping'], 2, '.', '');
    $totaltax = number_format($pdf_totals['ot_tax'], 2, '.', '');
    $final = number_format($pdf_totals['ot_total'], 2, '.', '');
    unset($pdf_totals['ot_subtotal']);
    unset($pdf_totals['ot_shipping']);
    unset($pdf_totals['ot_tax']);
    unset($pdf_totals['ot_total']);
    
    // Will the products fit on one page?
    $next_page = false;
    if ((sizeof($this->products) > 8 && !isset($discount_coupon) && !isset($gift_certificate)) || (sizeof($this->products) > 7 && isset($discount_coupon)) || (sizeof($this->products) > 7 && isset($gift_certificate)) || (sizeof($this->products) > 6 && isset($discount_coupon) && isset($gift_certificate))) $next_page = true;
    
    error_reporting(0);
    define('FPDF_FONTPATH', DIR_FS_CATALOG . 'fpdf/font/');
    require('fpdf.php');
    $str = utf8_decode("£");
    $err = 0;
    $tnow = date('Y-m-d H:i:s');
    
    function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
            $err = 0;
            $file = $path.$filename;
            $fp = fopen($file, "rb"); //Open it
            $data = fread($fp, filesize($file)); //Read it
            $data = chunk_split(base64_encode($data)); //Chunk it up and encode it as base64 so it can emailed
            fclose($fp);
            
            $headers = "From: $name<" . $from_name . ">\n";
            $headers .= "Reply-to: <" . $replyto . ">\n";
            $headers .= "MIME-Version: 1.0\n";
            $headers .= "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----=MIME_BOUNDRY_main_message\"\n";
            $headers .= "X-sender: $name<" . $from_name . ">\n";
            $headers .= "X-mailer: PHP mail\n";
            $headers .= "X-Priority: 3\n"; //1 = Urgent, 3 = Normal
            $headers .= "Return-Path: <" . $from_name . ">\n";
            $headers .= "This is a multi-part message in MIME format.\n";
            $headers .= "------=MIME_BOUNDRY_main_message \n";
            $headers .= "Content-Type: multipart/alternative; boundary=\"----=MIME_BOUNDRY_message_parts\"\n"; 
            
            $message2 = "------=MIME_BOUNDRY_message_parts\n";
            $message2 .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
            $message2 .= "Content-Transfer-Encoding: quoted-printable\n";
            $message2 .= "\n";
            /* Add our message, in this case it's plain text. You could also add HTML by changing the Content-Type to text/html */
            $message2 .= "$message\n";
            $message2 .= "\n";
            $message2 .= "------=MIME_BOUNDRY_message_parts--\n";
            $message2 .= "\n";
            $message2 .= "------=MIME_BOUNDRY_main_message\n";
            $message2 .= "Content-Type: application/pdf;\n\tname=\"" . $filename . "\"\n";
            $message2 .= "Content-Transfer-Encoding: base64\n";
            $message2 .= "Content-Disposition: attachment;\n\tfilename=\"" . $filename . "\"\n\n";
            $message2 .= $data; //The base64 encoded message
            $message2 .= "\n";
            $message2 .= "------=MIME_BOUNDRY_main_message--\n"; 
            
            if (mail($mailto, $subject, $message2, $headers)) {
                //echo("mail send ... OK"); // or use booleans here
            } else {
                //echo("mail send ... ERROR!");
                $err++;
            }
            return ($err);
    }
    
    
    class PDF extends FPDF
    {
        
        function FancyTable($titles,$data,$c,$start)
        {
            $str = utf8_decode("£");
            $this->SetFillColor(255,0,0);
            $this->SetTextColor(255);
            $this->SetDrawColor(128,0,0);
            $this->SetLineWidth(.4);
            $this->SetFont('Arial','B',8);
            //Header
            $w=array(108,30,10,18,24);
            for($i=0;$i<count($titles);$i++)
                $this->Cell($w[$i],5,$titles[$i],1,0,'C',true);
            $this->Ln();
            //Color and font restoration
            $this->SetFillColor(224,235,255);
            $this->SetTextColor(0);
            $this->SetFont('');
            //Data
            $fill=false;
            $p = 0;
            
            foreach($data as $row)
            {
                if ($p >= $start) {
                    $this->Cell($w[0],6,$row[0],'LR',0,'L',$fill);
                    $this->Cell($w[1],6,$row[1],'LR',0,'R',$fill);
                    $this->Cell($w[2],6,$row[2],'LR',0,'L',$fill);
                    $this->Cell($w[3],6,$str . $row[3],'LR',0,'R',$fill);
                    $this->Cell($w[4],6,$str . $row[4],'LR',0,'R',$fill);
                    $this->Ln();
                    $fill=!$fill;
                }
                $p++;
                if ($c == 0 && $p >= 8) { break; }
                
            }
            $this->Cell(array_sum($w),0,'','T');
            
        }
    
        //Page header
        function Header()
        {
        }
    
        //Page footer
        function Footer()
        {
        }
    }
    
    //Instanciation of inherited class
    
    $i = 1;
    $pdf = new PDF();
    $pdf->AliasNbPages();
    $pdf->AddPage();
    
    $pi = 1;
    require ("invoice_top.php");
    
    // $total = 0.00;
    
    for ($i = 0; $i < sizeof($this->products); $i++) {
        $attribute_customid = '';
        $attribute_names = array();
        $x = strip_tags($this->products[$i]['name']);
        
        // Process attributes
        if (isset($this->products[$i]['attributes']) && sizeof($this->products[$i]['attributes']) > 0) {
            foreach ($this->products[$i]['attributes'] as $attributes) {
                $attribute_names[] = $attributes['option'] . ': ' . $attributes['value'];
            
                $attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
            }
            
            if (isset($attribute_names) && is_array($attribute_names)) {
                $attribute_string = implode(', ', $attribute_names);
                $x .= ' ' . $attribute_string;
            }
        }
        
        $y = $this->products[$i]['qty'];
        $z = ($this->products[$i]['final_price'] > 0 ? $this->products[$i]['final_price'] : $this->products[$i]['price']);
        $t = $this->products[$i]['tax'];
        $m = ($this->products[$i]['model'] == '' && $attribute_customid != '' ? $attribute_customid : $this->products[$i]['model']);
        $x = str_replace("<br>", "", $x );
    
        $itemname = "$y x $x";
        $totalexvat = $z * $y;
        $totalcost = (zen_add_tax($z, $t) * $y) + zen_add_tax($this->products[$i]['onetime_charges'], $t);
    
        $thistax = zen_calculate_tax($z, $t);
        $pwt = $z + $thistax;
        // $totaltax += zen_calculate_tax($z, $t) * $this->products[$i]['qty'];
        
        $z = number_format($z, 2, '.', '');
        $totalcost = number_format($totalcost, 2, '.', '');
        $pwt = number_format($pwt, 2, '.', '');
        // $totaltax = number_format($totaltax, 2, '.', '');
        $totalexvat = number_format($totalexvat, 2, '.', '');
        $t = $t . "%";
        // $total += $totalcost;
        $lines[$i] = "$itemname|$m|$t|$pwt|$totalcost";
    }
    
    // $total = number_format($total, 2, '.', '');
    // $totaltax = number_format($totaltax, 2, '.', '');
    // $final = $total + $sc;
    // $final = number_format($final, 2, '.', '');
    
    $pdf->ln(2);
    
    foreach($lines as $line) $data[]=explode('|',chop($line));
    
    $titles = array('Products','Stock Code','Tax','Unit Price', 'Line Total' );
    $pdf->FancyTable($titles,$data, 0, 0);
    $pdf->ln(1);
    $pdf->SetFont('Arial','',12);
    $pdf->Cell(0,25,"Payment Method: $payment_method", 0, 0, "L");
    $pdf->SetFont('Arial','B',12);
    $pdf->Cell(0,25,"Sub Total: " . $str . "$total", 0, 0, "R");$pdf->ln(8);
    $pdf->SetFont('Arial','I',12);
    if ($sc == "3.5") { $sc = "3.50"; }
    if ($sc == "8.5") { $sc = "8.50"; }
    if ($sc > 0) {
        $pdf->Cell(0,25,"Shipping Cost: " . $str . "$sc", 0, 0, "R");$pdf->ln(8);
    }
    if (isset($discount_coupon) && $discount_coupon > 0) {
        $pdf->Cell(0,25,"Discount Coupon: -" . $str . "$discount_coupon", 0, 0, "R");$pdf->ln(8);
    }
    $pdf->Cell(0,25,"Includes VAT of " . $str . "$totaltax", 0, 0, "R");$pdf->ln(8);
    if (isset($gift_certificate) && $gift_certificate > 0) {
        $pdf->Cell(0,25,"Gift Certificates: -" . $str . "$gift_certificate", 0, 0, "R");$pdf->ln(8);
    }
    $pdf->SetFont('Arial','B',14);
    $pdf->Cell(0,25,"Total: " . $str . "$final", 0, 0, "R");
    
    if (!$next_page) {
        $pdf->ln(18);
    
        $pdf->SetFont('Arial','B',18);
    
        $pdf->SetTextColor(205, 116, 66);
        $pdf->SetX(64);
        $pdf->Write(1,"Thank You");
        $pdf->SetTextColor(220, 155, 115);
    
        $pdf->Write(1," for your custom!");
        $pdf->SetTextColor(0,0,0);
    
        $pdf->SetFont('Arial','B',14);
    }
    
    //Label Part
    //Higher is higher, lower = lower on the page
    $pdf->SetFont('Arial','',8);
    $pdf->SetY(-96);
    $pdf->SetX(34);
    $pdf->Cell(0,5,"Return to:  Tudor Rose Patchwork", 0, 1);$pdf->SetX(48);
    $pdf->Cell(0,5,"C/o Bacchus Marsh Ltd", 0, 1);$pdf->SetX(48); 
    $pdf->Cell(0,5,"Unit 1, Station Road", 0, 1);$pdf->SetX(48); 
    $pdf->Cell(0,5,"Oakley MK43 7RB", 0, 1);$pdf->SetX(48);
    $pdf->Cell(0,5,"United Kingdom", 0, 1); 
    
    $pdf->SetY(-60);
    $pdf->SetX(85);
    $pdf->SetFont('Arial','B',16);
    $pdf->Cell(0,8,"$delfname $delsname", 0, 1);$pdf->SetX(85);
    $pdf->SetFont('Arial','B',14);
    if (strlen($delstreet) > 0) { $pdf->Cell(0,5,"$delstreet", 0, 1);$pdf->SetX(85); }
    if (strlen($delsuburb) > 0) { $pdf->Cell(0,5,"$delsuburb", 0, 1);$pdf->SetX(85); }
    $pdf->Cell(0,5,"$delcity", 0, 1);$pdf->SetX(85);
    if (strlen($delstate) > 0) { $pdf->Cell(0,5,"$delstate", 0, 1);$pdf->SetX(85); }
    $pdf->Cell(0,5,"$delpostcode", 0, 1);$pdf->SetX(85);
    $pdf->Cell(0,5,"$delcountry", 0, 1);
    
    if ($next_page) {
        $pdf->AddPage();
        $pi = 2;
        require ("invoice_top.php");
        $pdf->ln(2);
        $pdf->FancyTable($titles,$data, 1, 8);
    }
    
    if ($next_page) {
        $pdf->ln(25);
    
        $pdf->SetFont('Arial','B',18);
    
        $pdf->SetTextColor(205, 116, 66);
        $pdf->SetX(64);
        $pdf->Write(1,"Thank You");
        $pdf->SetTextColor(220, 155, 115);
    
        $pdf->Write(1," for your custom!");
        $pdf->SetTextColor(0,0,0);
    
        $pdf->SetFont('Arial','B',14);
    }
    
    $pdf->Output(DIR_FS_CATALOG . "download/$zf_insert_id.pdf",F);
    
    $x = DIR_FS_CATALOG . "download/$zf_insert_id.pdf";
    
    if ($err == 0) {
        $mailerr == 0;
        $my_file = "$zf_insert_id.pdf";
        $my_path = DIR_FS_CATALOG . "download/";
        $my_name = "Sandra";
        $my_mail = "[email protected]";
        $my_replyto = "[email protected]";
        $my_subject = "PDF for TRP Order No $zf_insert_id";
        $my_message = "Tudor Rose order number $zf_insert_id";
        $mailerr = mail_attachment($my_file, $my_path, "[email protected]", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);
        if ($mailerr > 0) {
            error_log("$tnow - An error occured while sending the following attachment by email, $zf_insert_id.pdf\n", 3, DIR_FS_CATALOG . "error_log");
        } else {
            //chmod (DIR_FS_CATALOG . "orders/$zf_insert_id.pdf", 0700) or $err++;        
        }
    } else {
        error_log("$tnow - An error occured while modifying the permissions on, $zf_insert_id.pdf\n", 3, DIR_FS_CATALOG . "error_log");
    }
    So, I don't see if/how perhaps the $_SESSION is affected, but my idea to address this (as a work around which is not always the best way to implement) is to modify:
    Code:
    // $total = 0.00;
    
    for ($i = 0; $i < sizeof($this->products); $i++) {
        $attribute_customid = '';
        $attribute_names = array();
        $x = strip_tags($this->products[$i]['name']);
        
        // Process attributes
        if (isset($this->products[$i]['attributes']) && sizeof($this->products[$i]['attributes']) > 0) {
            foreach ($this->products[$i]['attributes'] as $attributes) {
                $attribute_names[] = $attributes['option'] . ': ' . $attributes['value'];
            
                $attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
            }
            
            if (isset($attribute_names) && is_array($attribute_names)) {
                $attribute_string = implode(', ', $attribute_names);
                $x .= ' ' . $attribute_string;
            }
        }
        
        $y = $this->products[$i]['qty'];
        $z = ($this->products[$i]['final_price'] > 0 ? $this->products[$i]['final_price'] : $this->products[$i]['price']);
        $t = $this->products[$i]['tax'];
        $m = ($this->products[$i]['model'] == '' && $attribute_customid != '' ? $attribute_customid : $this->products[$i]['model']);
        $x = str_replace("<br>", "", $x );
    
        $itemname = "$y x $x";
        $totalexvat = $z * $y;
        $totalcost = (zen_add_tax($z, $t) * $y) + zen_add_tax($this->products[$i]['onetime_charges'], $t);
    
        $thistax = zen_calculate_tax($z, $t);
        $pwt = $z + $thistax;
        // $totaltax += zen_calculate_tax($z, $t) * $this->products[$i]['qty'];
        
        $z = number_format($z, 2, '.', '');
        $totalcost = number_format($totalcost, 2, '.', '');
        $pwt = number_format($pwt, 2, '.', '');
        // $totaltax = number_format($totaltax, 2, '.', '');
        $totalexvat = number_format($totalexvat, 2, '.', '');
        $t = $t . "%";
        // $total += $totalcost;
        $lines[$i] = "$itemname|$m|$t|$pwt|$totalcost";
    }
    To add the following that is in blue:
    Code:
    // $total = 0.00;
    
    if (!class_exists('products_with_attributes_class_stock')) {
        include_once DIR_FS_CATALOG . DIR_WS_CLASSES . 'class.products_with_attributes_class_stock.php';
    }
    if (empty($_SESSION['pwas_class2'])) {
        $_SESSION['pwas_class2'] = new products_with_attributes_class_stock();
    }
    
    for ($i = 0; $i < sizeof($this->products); $i++) {
        $attribute_customid = '';
        $attribute_names = array();
        $x = strip_tags($this->products[$i]['name']);
        
        // Process attributes
        if (isset($this->products[$i]['attributes']) && sizeof($this->products[$i]['attributes']) > 0) {
            foreach ($this->products[$i]['attributes'] as $attributes) {
                $attribute_names[] = $attributes['option'] . ': ' . $attributes['value'];
            
                $attribute_customid = $_SESSION['pwas_class2']->zen_get_customid($this->products[$i]['id'], array($attributes['value_id']));
            }
            
            if (isset($attribute_names) && is_array($attribute_names)) {
                $attribute_string = implode(', ', $attribute_names);
                $x .= ' ' . $attribute_string;
            }
        }
        
        $y = $this->products[$i]['qty'];
        $z = ($this->products[$i]['final_price'] > 0 ? $this->products[$i]['final_price'] : $this->products[$i]['price']);
        $t = $this->products[$i]['tax'];
        $m = ($this->products[$i]['model'] == '' && $attribute_customid != '' ? $attribute_customid : $this->products[$i]['model']);
        $x = str_replace("<br>", "", $x );
    
        $itemname = "$y x $x";
        $totalexvat = $z * $y;
        $totalcost = (zen_add_tax($z, $t) * $y) + zen_add_tax($this->products[$i]['onetime_charges'], $t);
    
        $thistax = zen_calculate_tax($z, $t);
        $pwt = $z + $thistax;
        // $totaltax += zen_calculate_tax($z, $t) * $this->products[$i]['qty'];
        
        $z = number_format($z, 2, '.', '');
        $totalcost = number_format($totalcost, 2, '.', '');
        $pwt = number_format($pwt, 2, '.', '');
        // $totaltax = number_format($totaltax, 2, '.', '');
        $totalexvat = number_format($totalexvat, 2, '.', '');
        $t = $t . "%";
        // $total += $totalcost;
        $lines[$i] = "$itemname|$m|$t|$pwt|$totalcost";
    }
    ZC Installation/Maintenance Support <- Site
    Contribution for contributions welcome...

  10. #3410
    Join Date
    Jun 2012
    Posts
    412
    Plugin Contributions
    0

    Default Re: Stock by Attribute v4.0 for Zen Cart 1.5.1+

    This post picks up following the discussion of "How to control extra_cart_actions file loading order" in the General Questions forum.

    The offer for mc... to add a notifier in the includes/extra_cart_actions/stock_by_attributes.php file would most likely solve my problem, but I'm not sure it's the best solution. If a notifier is added, it should be at the start of the file.

    I need to bring up a form and process the customer's responses to the form when a certain product with attributes is added to the shopping cart. So my extra_cart_actions file detects the product being added to the cart, saves the $_POST variables (because $_POST data is lost on redirect), and redirects to files that display the form and when the form is submitted, processes the responses. For reasons that escape me at the moment, the $_POST variables are not restored until the extra_cart_actions file is executed again later in the add product to cart process. When I developed this code, SBA did not have an extra_cart_action file, so the missing $_POST data was not missed by other extra_cart_actions files. But now, SBA has a file there, and it runs before my file, and it doesn't like missing $_POST data. I get a undefined index products_id notice on or about lines 372, 492, and 513.

    So while a notifier in SBA could trigger an observer that restores the $_POST data if not present, I think a better solution is to try and display the form, process the results, and restore $_POST (if necessary) all at once, instead of over two cycles through extra_cart_actions. I'm not sure I can accomplish that but that's what I'm going to try.

    Dave

 

 

Similar Threads

  1. Problems with addon: Dynamic Drop Downs for Stock By Attribute
    By Dunk in forum All Other Contributions/Addons
    Replies: 56
    Last Post: 30 Apr 2014, 07:55 PM
  2. MySQL Problem with Product with Attribute Stock addon
    By rtwingfield in forum All Other Contributions/Addons
    Replies: 1
    Last Post: 20 Sep 2011, 03:35 PM
  3. Hide Zero Quantity Attributes with attribute-stock addon
    By leevil123 in forum All Other Contributions/Addons
    Replies: 1
    Last Post: 11 Feb 2010, 05:06 PM
  4. Replies: 4
    Last Post: 22 Jan 2010, 10:43 PM
  5. Price Products in the grid by 'Stock by Attribute' addon?
    By Salixia in forum Setting Up Categories, Products, Attributes
    Replies: 0
    Last Post: 27 Oct 2009, 06:03 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
disjunctive-egg
Zen-Cart, Internet Selling Services, Klamath Falls, OR