diff --git a/admin-dev/pdf.php b/admin-dev/pdf.php index 4fa1ea20c..5ed11ab79 100644 --- a/admin-dev/pdf.php +++ b/admin-dev/pdf.php @@ -1,6 +1,6 @@ $function) function generateInvoicePDF() { - if (!isset($_GET['id_order'])) + if (!isset($_GET['id_order'])) die (Tools::displayError('Missing order ID')); $order = new Order((int)($_GET['id_order'])); if (!Validate::isLoadedObject($order)) die(Tools::displayError('Cannot find order in database')); - PDF::invoice($order); + + generatePDF($order, PDF::TEMPLATE_INVOICE); } function generateOrderSlipPDF() @@ -67,7 +68,8 @@ function generateOrderSlipPDF() die(Tools::displayError('Cannot find order in database')); $order->products = OrderSlip::getOrdersSlipProducts($orderSlip->id, $order); $tmp = NULL; - PDF::invoice($order, 'D', false, $tmp, $orderSlip); + + generatePDF($order, PDF::TEMPLATE_ORDER_SLIP); } function generateDeliverySlipPDF() @@ -75,38 +77,62 @@ function generateDeliverySlipPDF() $order = Order::getByDelivery((int)($_GET['id_delivery'])); if (!Validate::isLoadedObject($order)) die(Tools::displayError('Cannot find order in database')); - $tmp = NULL; - PDF::invoice($order, 'D', false, $tmp, false, $order->delivery_number); + + generatePDF($order, PDF::TEMPLATE_DELIVERY_SLIP); } function generateInvoicesPDF() { - $orders = Order::getOrdersIdInvoiceByDate($_GET['date_from'], $_GET['date_to'], NULL, 'invoice'); - if (!is_array($orders)) + $id_orders_list = Order::getOrdersIdInvoiceByDate($_GET['date_from'], $_GET['date_to'], NULL, 'invoice'); + if (!is_array($id_orders_list)) die (Tools::displayError('No invoices found')); - PDF::multipleInvoices($orders); + + $orders = array(); + foreach ($id_orders_list as $id_order) + $orders[] = new Order((int)$id_order); + + generatePDF($orders, PDF::TEMPLATE_INVOICE); } function generateInvoicesPDF2() { - $allOrders = array(); + $id_orders_list = array(); foreach (explode('-', Tools::getValue('id_order_state')) as $id_order_state) - if (is_array($orders = Order::getOrderIdsByStatus((int)$id_order_state))) - $allOrders = array_merge($allOrders, $orders); - PDF::multipleInvoices($allOrders); + if (is_array($id_orders = Order::getOrderIdsByStatus((int)$id_order_state))) + $id_orders_list = array_merge($id_orders_list, $id_orders); + + $orders = array(); + foreach ($id_orders_list as $id_order) + $orders[] = new Order((int)$id_order); + + generatePDF($orders, PDF::TEMPLATE_INVOICE); } function generateOrderSlipsPDF() { - $orderSlips = OrderSlip::getSlipsIdByDate($_GET['date_from'], $_GET['date_to']); - if (!count($orderSlips)) + $id_order_slips_list = OrderSlip::getSlipsIdByDate($_GET['date_from'], $_GET['date_to']); + if (!count($id_order_slips_list)) die (Tools::displayError('No order slips found')); - PDF::multipleOrderSlips($orderSlips); + + $order_slips = array(); + foreach ($id_order_slips_list as $id_order_slips) + $order_slips[] = new OrderSlip((int)$id_order_slips); + + generatePDF($order_slips, PDF::TEMPLATE_ORDER_SLIP); } function generateDeliverySlipsPDF() { $slips = unserialize(urldecode($_GET['deliveryslips'])); if (is_array($slips)) - PDF::multipleDelivery($slips); + generatePDF($slips, PDF::TEMPLATE_DELIVERY_SLIP); } + + +function generatePDF($object, $template) +{ + global $smarty; + $pdf = new PDF($object, $template, $smarty); + $pdf->render(); +} + diff --git a/classes/Order.php b/classes/Order.php index cd83bae0b..803727708 100644 --- a/classes/Order.php +++ b/classes/Order.php @@ -55,7 +55,7 @@ class OrderCore extends ObjectModel /** @var string Secure key */ public $secure_key; - /** @var string Payment method id */ + /** @var string Payment method */ public $payment; /** @var string Payment module */ @@ -79,9 +79,18 @@ class OrderCore extends ObjectModel /** @var float Discounts total */ public $total_discounts; + public $total_discounts_tax_incl; + public $total_discounts_tax_excl; + /** @var float Total to pay */ public $total_paid; + /** @var float Total to pay tax included */ + public $total_paid_tax_incl; + + /** @var float Total to pay tax excluded */ + public $total_paid_tax_excl; + /** @var float Total really paid */ public $total_paid_real; @@ -94,12 +103,24 @@ class OrderCore extends ObjectModel /** @var float Shipping total */ public $total_shipping; + /** @var float Shipping total tax included */ + public $total_shipping_tax_incl; + + /** @var float Shipping total tax excluded */ + public $total_shipping_tax_excl; + /** @var float Shipping tax rate */ public $carrier_tax_rate; /** @var float Wrapping total */ public $total_wrapping; + /** @var float Wrapping total tax included */ + public $total_wrapping_tax_incl; + + /** @var float Wrapping total tax excluded */ + public $total_wrapping_tax_excl; + /** @var integer Invoice number */ public $invoice_number; @@ -219,13 +240,21 @@ class OrderCore extends ObjectModel $fields['gift_message'] = pSQL($this->gift_message); $fields['shipping_number'] = pSQL($this->shipping_number); $fields['total_discounts'] = (float)($this->total_discounts); + $fields['total_discounts_tax_incl'] = (float)($this->total_discounts_tax_incl); + $fields['total_discounts_tax_excl'] = (float)($this->total_discounts_tax_excl); $fields['total_paid'] = (float)($this->total_paid); + $fields['total_paid_tax_incl'] = (float)($this->total_paid_tax_incl); + $fields['total_paid_tax_excl'] = (float)($this->total_paid_tax_excl); $fields['total_paid_real'] = (float)($this->total_paid_real); $fields['total_products'] = (float)($this->total_products); $fields['total_products_wt'] = (float)($this->total_products_wt); $fields['total_shipping'] = (float)($this->total_shipping); + $fields['total_shipping_tax_incl'] = (float)($this->total_shipping_tax_incl); + $fields['total_shipping_tax_excl'] = (float)($this->total_shipping_tax_excl); $fields['carrier_tax_rate'] = (float)($this->carrier_tax_rate); $fields['total_wrapping'] = (float)($this->total_wrapping); + $fields['total_wrapping_tax_incl'] = (float)($this->total_wrapping_tax_incl); + $fields['total_wrapping_tax_excl'] = (float)($this->total_wrapping_tax_excl); $fields['invoice_number'] = (int)($this->invoice_number); $fields['delivery_number'] = (int)($this->delivery_number); $fields['invoice_date'] = pSQL($this->invoice_date); @@ -1146,4 +1175,133 @@ class OrderCore extends ObjectModel return false; } + /** + * This method returns true if at least one order details uses the + * One After Another tax computation method. + * + * @since 1.5.0.1 + * @return boolean + */ + public function useOneAfterAnotherTaxComputationMethod() + { + // if one of the order details use the tax computation method the display will be different + return Db::getInstance()->getValue(' + SELECT od.`tax_computation_method` + FROM `'._DB_PREFIX_.'order_detail_tax` odt + LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON (od.`id_order_detail` = odt.`id_order_detail`) + WHERE od.`id_order` = '.(int)$this->id.' + AND od.`tax_computation_method` = '.(int)TaxCalculator::ONE_AFTER_ANOTHER_METHOD + ); + + } + + + /** + * Returns the correct product taxes breakdown. + * + * @since 1.5.0.1 + * @return array + */ + public function getProductTaxesBreakdown() + { + $tmp_tax_infos = array(); + if ($this->useOneAfterAnotherTaxComputationMethod()) + { + // sum by taxes + $taxes_by_tax = Db::getInstance()->executeS(' + SELECT odt.`id_order_detail`, t.`name`, t.`rate`, SUM(`total_amount`) AS `total_amount` + FROM `'._DB_PREFIX_.'order_detail_tax` odt + LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = odt.`id_tax`) + LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON (od.`id_order_detail` = odt.`id_order_detail`) + WHERE od.`id_order` = '.(int)$this->id.' + GROUP BY odt.`id_tax` + '); + + // format response + $tmp_tax_infos = array(); + foreach ($taxes_infos as $tax_infos) + { + $tmp_tax_infos[$tax_infos['rate']]['total_amount'] = $tax_infos['tax_amount']; + $tmp_tax_infos[$tax_infos['rate']]['name'] = $tax_infos['name']; + } + } + else + { + // sum by order details in order to retrieve real taxes rate + $taxes_infos = Db::getInstance()->executeS(' + SELECT odt.`id_order_detail`, t.`rate` AS `name`, SUM(od.`total_price_tax_excl`) AS total_price_tax_excl, SUM(t.`rate`) AS rate, SUM(`total_amount`) AS `total_amount` + FROM `'._DB_PREFIX_.'order_detail_tax` odt + LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = odt.`id_tax`) + LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON (od.`id_order_detail` = odt.`id_order_detail`) + WHERE od.`id_order` = '.(int)$this->id.' + GROUP BY odt.`id_order_detail` + '); + + // sum by taxes + $tmp_tax_infos = array(); + foreach ($taxes_infos as $tax_infos) + { + if (!isset($tmp_tax_infos[$tax_infos['rate']])) + $tmp_tax_infos[$tax_infos['rate']] = array('total_amount' => 0, + 'name' => 0, + 'total_price_tax_excl' => 0); + + $tmp_tax_infos[$tax_infos['rate']]['total_amount'] += $tax_infos['total_amount']; + $tmp_tax_infos[$tax_infos['rate']]['name'] = $tax_infos['name']; + $tmp_tax_infos[$tax_infos['rate']]['total_price_tax_excl'] += $tax_infos['total_price_tax_excl']; + } + } + + return $tmp_tax_infos; + } + + /** + * Returns the shipping taxes breakdown + * + * @since 1.5.0.1 + * @return array + */ + public function getShippingTaxesBreakdown() + { + $taxes_breakdown = array(); + + $shipping_tax_amount = $this->total_shipping_tax_incl - $this->total_shipping_tax_excl; + + if ($shipping_tax_amount > 0) + $taxes_breakdown[] = array( + 'rate' => $this->carrier_tax_rate, + 'total_amount' => $shipping_tax_amount + ); + + return $taxes_breakdown; + } + + /** + * Returns the wrapping taxes breakdown + * @todo + + * @since 1.5.0.1 + * @return array + */ + public function getWrappingTaxesBreakdown() + { + $taxes_breakdown = array(); + return $taxes_breakdown; + } + + /** + * Returns the ecotax taxes breakdown + * + * @since 1.5.0.1 + * @return array + */ + public function getEcoTaxTaxesBreakdown() + { + return Db::getInstance()->executeS(' + SELECT `ecotax_tax_rate`, SUM(`ecotax`) as `ecotax_tax_excl`, SUM(`ecotax`) as `ecotax_tax_incl` + FROM `'._DB_PREFIX_.'order_detail` + WHERE `id_order` = '.(int)$this->id + ); + } } + diff --git a/classes/OrderDetail.php b/classes/OrderDetail.php index 90dea7995..c6bf35047 100644 --- a/classes/OrderDetail.php +++ b/classes/OrderDetail.php @@ -60,6 +60,18 @@ class OrderDetailCore extends ObjectModel /** @var float */ public $product_price; + /** @var float */ + public $unit_price_tax_incl; + + /** @var float */ + public $unit_price_tax_excl; + + /** @var float */ + public $total_price_tax_incl; + + /** @var float */ + public $total_price_tax_excl; + /** @var float */ public $reduction_percent; @@ -87,12 +99,6 @@ class OrderDetailCore extends ObjectModel /** @var float */ public $product_weight; - /** @var string */ - public $tax_name; - - /** @var float */ - public $tax_rate; - /** @var float */ public $ecotax; @@ -111,12 +117,18 @@ class OrderDetailCore extends ObjectModel /** @var date */ public $download_deadline; + /** @var string $tax_name **/ + public $tax_name; + + /** @var float $tax_rate **/ + public $tax_rate; + protected $tables = array('order_detail'); protected $fieldsRequired = array( - 'id_order', - 'product_name', - 'product_quantity', + 'id_order', + 'product_name', + 'product_quantity', 'product_price'); protected $fieldsValidate = array( @@ -146,7 +158,11 @@ class OrderDetailCore extends ObjectModel 'discount_quantity_applied' => 'isInt', 'download_hash' => 'isGenericName', 'download_nb' => 'isInt', - 'download_deadline' => 'isDateFormat' + 'download_deadline' => 'isDateFormat', + 'unit_price_tax_incl' => 'isPrice', + 'unit_price_tax_excl' => 'isPrice', + 'total_price_tax_incl' => 'isPrice', + 'total_price_tax_excl' => 'isPrice' ); protected $table = 'order_detail'; @@ -164,22 +180,22 @@ class OrderDetailCore extends ObjectModel 'download_deadline' => array() ) ); - + /** @var bool */ protected $outOfStock = false; - + /** @var TaxCalculator object */ protected $tax_calculator = null; - + /** @var Address object */ protected $vat_address = null; - + /** @var Address object */ protected $specificPrice = null; - + /** @var Customer object */ protected $customer = null; - + /** @var Context object */ protected $context = null; @@ -187,7 +203,7 @@ class OrderDetailCore extends ObjectModel { $this->context = $context; } - + public function getFields() { $this->validateFields(); @@ -218,6 +234,10 @@ class OrderDetailCore extends ObjectModel $fields['download_hash'] = pSQL($this->download_hash); $fields['download_nb'] = (int)$this->download_nb; $fields['download_deadline'] = pSQL($this->download_deadline); + $fields['unit_price_tax_incl'] = (float)$this->unit_price_tax_incl; + $fields['unit_price_tax_excl'] = (float)$this->unit_price_tax_excl; + $fields['total_price_tax_incl'] = (float)$this->total_price_tax_incl; + $fields['total_price_tax_excl'] = (float)$this->total_price_tax_excl; return $fields; } @@ -245,6 +265,7 @@ class OrderDetailCore extends ObjectModel /** * Returns the tax calculator associated to this order detail. + * @since 1.5.0.1 * @return TaxCalculator */ public function getTaxCalculator() @@ -254,6 +275,7 @@ class OrderDetailCore extends ObjectModel /** * Return the tax calculator associated to this order_detail + * @since 1.5.0.1 * @param int $id_order_detail * @return TaxCalculator */ @@ -279,26 +301,36 @@ class OrderDetailCore extends ObjectModel /** * Save the tax calculator - * @param int $id_order_detail - * @param TaxCalculator $tax_calculator + * @since 1.5.0.1 * @return boolean */ - public static function saveTaxCalculatorStatic($id_order_detail, TaxCalculator $tax_calculator) + public function saveTaxCalculator() { - if (count($tax_calculator->taxes) == 0) + // Nothing to save + if ($this->tax_calculator == null) + return true; + + if (!($this->tax_calculator instanceOf TaxCalculator)) + return false; + + if (count($this->tax_calculator->taxes) == 0) return true; $values = ''; - foreach ($tax_calculator->taxes as $tax) - $values .= '('.(int)$id_order_detail.','.(float)$tax->id.'),'; + foreach ($this->tax_calculator->getTaxesAmount($this->unit_price_tax_excl) as $id_tax => $amount) + { + $unit_amount = (float)Tools::ps_round($amount, 2); + $total_amount = $unit_amount * $this->product_quantity; + $values .= '('.(int)$this->id.','.(float)$id_tax.','.$unit_amount.','.(float)$total_amount.'),'; + } $values = rtrim($values, ','); - $sql = 'INSERT INTO `'._DB_PREFIX_.'order_detail_tax` (id_order_detail, id_tax) + $sql = 'INSERT INTO `'._DB_PREFIX_.'order_detail_tax` (id_order_detail, id_tax, unit_amount, total_amount) VALUES '.$values; return Db::getInstance()->execute($sql); - } - + } + /** * Get a detailed order list of an id_order * @param int $id_order @@ -308,14 +340,14 @@ class OrderDetailCore extends ObjectModel { $sql = ' SELECT * - FROM `'._DB_PREFIX_.'`order_detail + FROM `'._DB_PREFIX_.'order_detail` WHERE `id_order` = '.(int)$id_order; - + return Db::getInstance()->executeS($sql); } - + /* - * Set virtual product information + * Set virtual product information * @param array $product */ protected function setVirtualProductInformation($product) @@ -323,17 +355,17 @@ class OrderDetailCore extends ObjectModel // Add some informations for virtual products $this->download_deadline = '0000-00-00 00:00:00'; $this->download_hash = null; - + if ($id_product_download = ProductDownload::getIdFromIdProduct((int)($product['id_product']))) { $productDownload = new ProductDownload((int)($id_product_download)); $this->download_deadline = $productDownload->getDeadLine(); $this->download_hash = $productDownload->getHash(); - + unset($productDownload); } } - + /** * Check the order state * @param array $product @@ -350,7 +382,7 @@ class OrderDetailCore extends ObjectModel Product::updateDefaultAttribute($product['id_product']); } } - + /** * Apply tax to the product * @param object $order @@ -359,7 +391,7 @@ class OrderDetailCore extends ObjectModel protected function setProductTax(Order $order, $product) { $this->ecotax = Tools::convertPrice(floatval($product['ecotax']), intval($order->id_currency)); - + // Exclude VAT if (!Tax::excludeTaxeOption()) { @@ -372,19 +404,19 @@ class OrderDetailCore extends ObjectModel $this->ecotax_tax_rate = 0; if (!empty($product['ecotax'])) $this->ecotax_tax_rate = Tax::getProductEcotaxRate($order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); - + $this->tax_computation_method = (int)$this->tax_calculator->computation_method; } - + /** * Set specific price of the product * @param object $order */ protected function setSpecificPrice(Order $order) { - $this->reduction_amont = 0.00; + $this->reduction_amount = 0.00; $this->reduction_percent = 0.00; - + if ($this->specificPrice) switch($this->specificPrice['reduction_type']) { @@ -393,11 +425,11 @@ class OrderDetailCore extends ObjectModel break; case 'amount': $price = Tools::convertPrice($this->specificPrice['reduction'], $order->id_currency); - $this->reduction_amont = (float)(!$this->specificPrice['id_currency'] ? + $this->reduction_amount = (float)(!$this->specificPrice['id_currency'] ? $price : $this->specificPrice['reduction']); } } - + /** * Set detailed product price to the order detail * @param object $order @@ -406,34 +438,42 @@ class OrderDetailCore extends ObjectModel */ protected function setDetailProductPrice(Order $order, Cart $cart, $product) { - $this->specificPrice = null; - - $this->product_price = (float)Product::getPriceStatic((int)($product['id_product']), false, - ($product['id_product_attribute'] ? (int)($product['id_product_attribute']) : null), - (Product::getTaxCalculationMethod((int)($order->id_customer)) == PS_TAX_EXC ? 2 : 6), - null, false, false, $product['cart_quantity'], false, (int)($order->id_customer), - (int)($order->id_cart), (int)($order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}), $this->specificPrice, false, false); - + $customer = new Customer((int)$order->id_customer); + $customer_address = new Address((int)$order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); + + $this->specificPrice = SpecificPrice::getSpecificPrice((int)$product['id_product'], + (int)$order->id_shop, + (int)$order->id_currency, + (int)$customer_address->id_country, + (int)$customer->id_default_group, + (int)$product['cart_quantity']); + + $this->product_price = (float)$product['price']; + $this->unit_price_tax_incl = (float)$product['price_wt']; + $this->unit_price_tax_excl = (float)$product['price']; + $this->total_price_tax_incl = (float)$product['total_wt']; + $this->total_price_tax_excl = (float)$product['total']; + $this->setSpecificPrice($order); - + $this->group_reduction = (float)(Group::getReduction((int)($order->id_customer))); - - $quantityDiscount = SpecificPrice::getQuantityDiscount((int)$product['id_product'], $this->context->shop->getID(), + + $quantityDiscount = SpecificPrice::getQuantityDiscount((int)$product['id_product'], $this->context->shop->getID(), (int)$cart->id_currency, (int)$this->vat_address->id_country, (int)$this->customer->id_default_group, (int)$product['cart_quantity']); - - $unitPrice = Product::getPriceStatic((int)$product['id_product'], true, - ($product['id_product_attribute'] ? intval($product['id_product_attribute']) : null), + + $unitPrice = Product::getPriceStatic((int)$product['id_product'], true, + ($product['id_product_attribute'] ? intval($product['id_product_attribute']) : null), 2, null, false, true, 1, false, (int)$order->id_customer, null, (int)$order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); - - $this->product_quantity_discount = (float)($quantityDiscount ? - ((Product::getTaxCalculationMethod((int)$order->id_customer) == PS_TAX_EXC ? - Tools::ps_round($unitPrice, 2) : $unitPrice) - $this->tax_calculator->addTaxes($quantityDiscount['price'])) : + + $this->product_quantity_discount = (float)($quantityDiscount ? + ((Product::getTaxCalculationMethod((int)$order->id_customer) == PS_TAX_EXC ? + Tools::ps_round($unitPrice, 2) : $unitPrice) - $this->tax_calculator->addTaxes($quantityDiscount['price'])) : 0.00); - + $this->discount_quantity_applied = (($this->specificPrice && $this->specificPrice['from_quantity'] > 1) ? 1 : 0); } - + /** * Create an order detail liable to an id_order * @param object $order @@ -444,38 +484,38 @@ class OrderDetailCore extends ObjectModel protected function create(Order $order, Cart $cart, $product, $id_order_state) { $this->tax_calculator = new TaxCalculator(); - + $this->id = null; - + $this->product_id = (int)($product['id_product']); $this->product_attribute_id = (int)($product['id_product_attribute'] ? (int)($product['id_product_attribute']) : null); $this->product_name = pSQL($product['name']. - ((isset($product['attributes']) && $product['attributes'] != null) ? + ((isset($product['attributes']) && $product['attributes'] != null) ? ' - '.$product['attributes'] : '')); - + $this->product_quantity = (int)($product['cart_quantity']); $this->product_ean13 = empty($product['ean13']) ? null : pSQL($product['ean13']); $this->product_upc = empty($product['upc']) ? null : pSQL($product['upc']); $this->product_reference = empty($product['reference']) ? null : pSQL($product['reference']); $this->product_supplier_reference = empty($product['supplier_reference']) ? null : pSQL($product['supplier_reference']); $this->product_weight = (float)$product['id_product_attribute'] ? $product['weight_attribute'] : $product['weight']; - + $productQuantity = (int)(Product::getQuantity($this->product_id, $this->product_attribute_id)); - $this->product_quantity_in_stock = ($productQuantity - (int)($product['cart_quantity']) < 0) ? + $this->product_quantity_in_stock = ($productQuantity - (int)($product['cart_quantity']) < 0) ? $productQuantity : (int)($product['cart_quantity']); - + $this->setVirtualProductInformation($product); $this->checkProductStock($product, $id_order_state); $this->setProductTax($order, $product); - $this->setDetailProductPrice($order, $cart, $product); - - // Add new entry to the table - $this->save(); + $this->setDetailProductPrice($order, $cart, $product); - OrderDetail::saveTaxCalculatorStatic($this->id, $this->tax_calculator); + // Add new entry to the table + $this->save(); + + $this->saveTaxCalculator(); unset($this->tax_calculator); } - + /** * Create a list of order detail for a specified id_order using cart * @param object $order @@ -483,22 +523,22 @@ class OrderDetailCore extends ObjectModel * @param int $id_order_status */ public function createList(Order $order, Cart $cart, $id_order_state) - { + { $this->vat_address = new Address((int)($order->{Configuration::get('PS_TAX_ADDRESS_TYPE')})); $this->customer = new Customer((int)($order->id_customer)); - + $this->id_order = $order->id; $products = $cart->getProducts(); $this->outOfStock = false; - + foreach ($products as $product) $this->create($order, $cart, $product, $id_order_state); - + unset($this->vat_address); unset($products); unset($this->customer); } - + /** * Get the state of the current stock product * @return array diff --git a/classes/pdf/HTMLTemplate.php b/classes/pdf/HTMLTemplate.php new file mode 100755 index 000000000..fd96aebfc --- /dev/null +++ b/classes/pdf/HTMLTemplate.php @@ -0,0 +1,151 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 8797 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * @since 1.5 + */ +abstract class HTMLTemplateCore +{ + public $title; + public $date; + public $address; + public $available_in_your_account = true; + public $smarty; + + /** + * Returns the template's HTML header + * @return string HTML header + */ + public function getHeader() + { + $this->assignHookData(); + + $this->smarty->assign(array( + 'logo_path' => $this->getLogo(), + 'img_ps_dir' => 'http://'.Tools::getMediaServer(_PS_IMG_)._PS_IMG_, + 'img_update_time' => Configuration::get('PS_IMG_UPDATE_TIME'), + 'title' => $this->title, + 'date' => $this->date, + 'shop_name' => Configuration::get('PS_SHOP_NAME') + )); + + return $this->smarty->fetch(_PS_THEME_DIR_.'/pdf/header.tpl'); + } + + /** + * Returns the template's HTML footer + * @return string HTML footer + */ + public function getFooter() + { + $shop_address = ''; + if (isset($this->address) && $this->address instanceof Address) + $shop_address = AddressFormat::generateAddress($this->address, array(), ' - ', ' '); + + $this->smarty->assign(array( + 'available_in_your_account' => $this->available_in_your_account, + 'shop_address' => $shop_address, + 'shop_fax' => Configuration::get('PS_SHOP_FAX'), + 'shop_phone' => Configuration::get('PS_SHOP_PHONE'), + 'shop_details' => Configuration::get('PS_SHOP_DETAILS'), + 'free_text' => Configuration::get('PS_INVOICE_FREE_TEXT') + )); + return $this->smarty->fetch(_PS_THEME_DIR_.'/pdf/footer.tpl'); + } + + /** + * Returns the invoice logo + */ + protected function getLogo() + { + $logo = ''; + + if (file_exists(_PS_IMG_DIR_.'logo_invoice.jpg')) + $logo = 'img/logo_invoice.jpg'; + else if (file_exists(_PS_IMG_DIR_.'logo.jpg')) + $logo = 'img/logo.jpg'; + + return Tools::getShopDomain(true).__PS_BASE_URI__.'/'.$logo; + } + + /** + * Returns the HTML content of the template's footer + */ + public function assignHookData() + { + $data = array('title' => 'cool', + 'delivery' => array('date' => '25/11/11', 'delay' => '3')); + + foreach ($data as $key => $value) + $this->smarty->assign($key, $value); + } + + /** + * Returns the template's HTML content + * @return string HTML content + */ + abstract public function getContent(); + + + /** + * Returns the template filename + * @return string filename + */ + abstract public function getFilename(); + + /** + * Returns the template filename when using bulk rendering + * @return string filename + */ + abstract public function getBulkFilename(); + + + /** + * Translatation method + * @param string $string + * @return string translated text + */ + protected static function l($string) + { + $iso = Context::getContext()->language->iso_code; + + if (!Validate::isLangIsoCode($iso)) + die('Invalid iso lang ('.$iso.')'); + + if (@!include(_PS_THEME_DIR_.'pdf/'.'fr'.'.php')) + die('Cannot include PDF translation language file : '._PS_THEME_DIR_.'pdf/'.$iso.'.php'); + + if (!isset($_LANGPDF) OR !is_array($_LANGPDF)) + return str_replace('"', '"', $string); + $key = md5(str_replace('\'', '\\\'', $string)); + $str = (key_exists('PDF_invoice'.$key, $_LANGPDF) ? $_LANGPDF['PDF_invoice'.$key] : $string); + + return $str; + } +} + diff --git a/classes/pdf/HTMLTemplateDeliverySlip.php b/classes/pdf/HTMLTemplateDeliverySlip.php new file mode 100755 index 000000000..8f9ea5a5b --- /dev/null +++ b/classes/pdf/HTMLTemplateDeliverySlip.php @@ -0,0 +1,97 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 8797 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * @since 1.5 + */ +class HTMLTemplateDeliverySlipCore extends HTMLTemplate +{ + public $order; + + public function __construct(Order $order, $smarty) + { + $this->order = $order; + $this->smarty = $smarty; + + // header informations + $this->date = Tools::displayDate($order->invoice_date, (int)$order->id_lang); + $this->title = 'Invoice '.Configuration::get('PS_INVOICE_PREFIX').sprintf('%06d', $order->invoice_number); + + // footer informations + $shop = new Shop((int)$order->id_shop); + $this->address = $shop->getAddress(); + } + + /** + * Returns the template's HTML content + * @return string HTML content + */ + public function getContent() + { + $country = new Country((int)$this->order->id_address_invoice); + + $delivery_address = new Address((int)$this->order->id_address_delivery); + $formatted_delivery_address = AddressFormat::generateAddress($delivery_address, array(), '
', ' '); + $formatted_invoice_address = ''; + + if ($this->order->id_address_delivery != $this->order->id_address_invoice) + { + $invoice_address = new Address((int)$id_address_invoice); + $formatted_invoice_address = AddressFormat::generateAddress($invoice_address, array(), '
', ' '); + } + + $customer = new Customer($this->order->id_customer); + + $this->smarty->assign(array( + 'order' => $this->order, + 'order_details' => $this->order->getProducts(), + 'delivery_address' => $formatted_delivery_address, + 'invoice_address' => $formatted_invoice_address, + )); + + return $this->smarty->fetch(_PS_THEME_DIR_.'/pdf/delivery-slip.tpl'); + } + + /** + * Returns the template filename when using bulk rendering + * @return string filename + */ + public function getBulkFilename() + { + return 'deliveries.pdf'; + } + + /** + * Returns the template filename + * @return string filename + */ + public function getFilename() + { + return Configuration::get('PS_DELIVERY_PREFIX').sprintf('%06d', $this->order->invoice_number).'.pdf'; + } +} + diff --git a/classes/pdf/HTMLTemplateInvoice.php b/classes/pdf/HTMLTemplateInvoice.php new file mode 100755 index 000000000..3d2db53f1 --- /dev/null +++ b/classes/pdf/HTMLTemplateInvoice.php @@ -0,0 +1,137 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 8797 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * @since 1.5 + */ +class HTMLTemplateInvoiceCore extends HTMLTemplate +{ + public $order; + + public $available_in_your_account = false; + + public function __construct(Order $order, $smarty) + { + $this->order = $order; + $this->smarty = $smarty; + + // header informations + $this->date = Tools::displayDate($order->invoice_date, (int)$order->id_lang); + $this->title = self::l('Invoice ').Configuration::get('PS_INVOICE_PREFIX').sprintf('%06d', $order->invoice_number); + + // footer informations + $shop = new Shop((int)$order->id_shop); + $this->address = $shop->getAddress(); + } + + /** + * Returns the template's HTML content + * @return string HTML content + */ + public function getContent() + { + $country = new Country((int)$this->order->id_address_invoice); + $invoice_address = new Address((int)$this->order->id_address_invoice); + $formatted_invoice_address = AddressFormat::generateAddress($invoice_address, array(), '
', ' '); + $formatted_delivery_address = ''; + + if ($this->order->id_address_delivery != $this->order->id_address_invoice) + { + $delivery_address = new Address((int)$this->order->id_address_delivery); + $formatted_delivery_address = AddressFormat::generateAddress($delivery_address, array(), '
', ' '); + } + + $customer = new Customer($this->order->id_customer); + + $this->smarty->assign(array( + 'order' => $this->order, + 'order_details' => $this->order->getProducts(), + 'delivery_address' => $formatted_delivery_address, + 'invoice_address' => $formatted_invoice_address, + 'tax_excluded_display' => Group::getPriceDisplayMethod($customer->id_default_group), + 'tax_tab' => $this->getTaxTabContent() + )); + + return $this->smarty->fetch($this->getTemplate($country->iso_code)); + } + + /** + * Returns the tax tab content + */ + public function getTaxTabContent() + { + $invoice_address = new Address((int)$this->order->id_address_invoice); + $tax_exempt = Configuration::get('VATNUMBER_MANAGEMENT') + AND !empty($invoiceAddress->vat_number) + AND $invoiceAddress->id_country != Configuration::get('VATNUMBER_COUNTRY'); + + $this->smarty->assign(array( + 'tax_exempt' => $tax_exempt, + 'use_one_after_another_method' => $this->order->useOneAfterAnotherTaxComputationMethod(), + 'product_tax_breakdown' => $this->order->getProductTaxesBreakdown(), + 'shipping_tax_breakdown' => $this->order->getShippingTaxesBreakdown(), + 'ecotax_tax_breakdown' => $this->order->getEcoTaxTaxesBreakdown(), + 'order' => $this->order, + )); + + return $this->smarty->fetch(_PS_THEME_DIR_.'/pdf/invoice.tax-tab.tpl'); + } + + /** + * Returns the invoice template associated to the country iso_code + * @param string $iso_country + */ + protected function getTemplate($iso_country) + { + $template = _PS_THEME_DIR_.'/pdf/invoice.tpl'; + + $iso_template = _PS_THEME_DIR_.'/pdf/invoice.'.$iso_country.'.tpl'; + if (file_exists($iso_template)) + $template = $iso_template; + + return $template; + } + + /** + * Returns the template filename when using bulk rendering + * @return string filename + */ + public function getBulkFilename() + { + return 'invoices.pdf'; + } + + /** + * Returns the template filename + * @return string filename + */ + public function getFilename() + { + return Configuration::get('PS_INVOICE_PREFIX').sprintf('%06d', $this->order->invoice_number).'.pdf'; + } +} + diff --git a/classes/pdf/HTMLTemplateOrderReturn.php b/classes/pdf/HTMLTemplateOrderReturn.php new file mode 100755 index 000000000..1f9f38c71 --- /dev/null +++ b/classes/pdf/HTMLTemplateOrderReturn.php @@ -0,0 +1,96 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 8797 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * @since 1.5 + */ +class HTMLTemplateOrderReturnCore extends HTMLTemplate +{ + public $order_return; + public $order; + + public function __construct(OrderReturn $order_return, $smarty) + { + $this->order_return = $order_return; + $this->smarty = $smarty; + $this->order = new Order($order_return->id_order); + + // header informations + $this->date = Tools::displayDate($this->order->invoice_date, (int)$this->order->id_lang); + $this->title = 'Order Return '.sprintf('%06d', $this->order_return->id); // TODO + + // footer informations + $shop = new Shop((int)$this->order->id_shop); + $this->address = $shop->getAddress(); + } + + /** + * Returns the template's HTML content + * @return string HTML content + */ + public function getContent() + { + $delivery_address = new Address((int)$this->order->id_address_delivery); + $formatted_delivery_address = AddressFormat::generateAddress($delivery_address, array(), '
', ' '); + $formatted_invoice_address = ''; + + if ($this->order->id_address_delivery != $this->order->id_address_invoice) + { + $invoice_address = new Address((int)$id_address_invoice); + $formatted_invoice_address = AddressFormat::generateAddress($invoice_address, array(), '
', ' '); + } + + $this->smarty->assign(array( + 'order_return' => $this->order_return, + 'return_nb_days' => (int)Configuration::get('PS_ORDER_RETURN_NB_DAYS'), + 'products' => OrderReturn::getOrdersReturnProducts($this->order_return->id, $this->order), + 'delivery_address' => $formatted_delivery_address, + 'invoice_address' => $formatted_invoice_address, + 'shop_address' => AddressFormat::generateAddress($this->address, array(), '
', ' ') + )); + return $this->smarty->fetch(_PS_THEME_DIR_.'/pdf/order-return.tpl'); + } + + /** + * Returns the template filename + * @return string filename + */ + public function getFilename() + { + return sprintf('%06d', $this->order_return->id).'.pdf'; // TODO + } + + /** + * Returns the template filename when using bulk rendering + * @return string filename + */ + public function getBulkFilename() + { + return 'invoices.pdf'; + } +} + diff --git a/classes/pdf/HTMLTemplateOrderSlip.php b/classes/pdf/HTMLTemplateOrderSlip.php new file mode 100644 index 000000000..f3ed44fd5 --- /dev/null +++ b/classes/pdf/HTMLTemplateOrderSlip.php @@ -0,0 +1,106 @@ + + * @copyright 2007-2011 PrestaShop SA + * @version Release: $Revision: 8797 $ + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + */ + +/** + * @since 1.5 + */ +class HTMLTemplateOrderSlipCore extends HTMLTemplateInvoice +{ + public $order; + public $order_slip; + + public function __construct(OrderSlip $order_slip, $smarty) + { + $this->order_slip = $order_slip; + $this->order = new Order((int)$order_slip->id_order); + + $products = OrderSlip::getOrdersSlipProducts($this->order_slip->id, $this->order); + $customizedDatas = Product::getAllCustomizedDatas((int)($this->order->id_cart)); + Product::addCustomizationPrice($products, $customizedDatas); + + $this->order->products = $products; + $this->smarty = $smarty; + + // header informations + $this->date = Tools::displayDate($this->order->invoice_date, (int)$this->order->id_lang); + $this->title = self::l('Slip #').sprintf('%06d', $this->order_slip->id); + + // footer informations + $shop = new Shop((int)$this->order->id_shop); + $this->address = $shop->getAddress(); + } + + /** + * Returns the template's HTML content + * @return string HTML content + */ + public function getContent() + { + $country = new Country((int)$this->order->id_address_invoice); + $invoice_address = new Address((int)$this->order->id_address_invoice); + $formatted_invoice_address = AddressFormat::generateAddress($invoice_address, array(), '
', ' '); + $formatted_delivery_address = ''; + + if ($this->order->id_address_delivery != $this->order->id_address_invoice) + { + $delivery_address = new Address((int)$this->order->id_address_delivery); + $formatted_delivery_address = AddressFormat::generateAddress($delivery_address, array(), '
', ' '); + } + + $customer = new Customer($this->order->id_customer); + + $this->smarty->assign(array( + 'order' => $this->order, + 'order_details' => $this->order->products, + 'delivery_address' => $formatted_delivery_address, + 'invoice_address' => $formatted_invoice_address, + 'tax_excluded_display' => Group::getPriceDisplayMethod($customer->id_default_group), + 'tax_tab' => '', + )); + + return $this->smarty->fetch(_PS_THEME_DIR_.'/pdf/invoice.tpl'); + } + + /** + * Returns the template filename when using bulk rendering + * @return string filename + */ + public function getBulkFilename() + { + return 'order-slips.pdf'; + } + + /** + * Returns the template filename + * @return string filename + */ + public function getFilename() + { + return 'order-slip-'.sprintf('%06d', $this->order_slip->id).'.pdf'; + } +} + diff --git a/classes/pdf/PDF.php b/classes/pdf/PDF.php new file mode 100755 index 000000000..a7175ee45 --- /dev/null +++ b/classes/pdf/PDF.php @@ -0,0 +1,101 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 8797 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * @since 1.5 + */ +class PDFCore +{ + public $filename; + public $pdf_renderer; + public $objects; + public $template; + + const TEMPLATE_INVOICE = 'Invoice'; + const TEMPLATE_ORDER_RETURN = 'OrderReturn'; + const TEMPLATE_ORDER_SLIP = 'OrderSlip'; + const TEMPLATE_DELIVERY_SLIP = 'DeliverySlip'; + + public function __construct($objects, $template, $smarty) + { + $this->pdf_renderer = new PDFGenerator(); + $this->template = $template; + $this->smarty = $smarty; + + $this->objects = $objects; + if (!is_array($objects)) + $this->objects = array($objects); + } + + public function render() + { + + $render = false; + $this->pdf_renderer->setFontForLang('fr'); + foreach ($this->objects as $object) + { + $template = $this->getTemplateObject($object); + if (!$template) + continue; + + if (empty($this->filename)) + { + $this->filename = $template->getFilename(); + if (count($this->objects) > 1) + $this->filename = $template->getBulkFilename(); + } + + $this->pdf_renderer->createHeader($template->getHeader()); + $this->pdf_renderer->createFooter($template->getFooter()); + $this->pdf_renderer->createContent($template->getContent()); + $this->pdf_renderer->writePage(); + $render = true; + + unset($template); + } + + if ($render) + $this->pdf_renderer->render($this->filename); + + } + + public function getTemplateObject($object) + { + $class = false; + $classname = 'HTMLTemplate'.$this->template; + + if (class_exists($classname)) + { + $class = new $classname($object, $this->smarty); + if (!($class instanceof HTMLTemplate)) + throw new PrestashopException('Invalid class. It should be an instance of HTMLTemplate'); + } + + return $class; + } +} + diff --git a/classes/pdf/PDFGenerator.php b/classes/pdf/PDFGenerator.php new file mode 100755 index 000000000..2763cf5aa --- /dev/null +++ b/classes/pdf/PDFGenerator.php @@ -0,0 +1,145 @@ + +* @copyright 2007-2011 PrestaShop SA +* @version Release: $Revision: 8797 $ +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * @since 1.5 + */ +class PDFGeneratorCore extends TCPDF +{ + const DEFAULT_FONT = 'dejavusans'; + + public $header; + public $footer; + public $content; + public $font; + + public $font_by_lang = array('jp' => 'cid0jp'); + + /** + * set the PDF encoding + * @param string $encoding + */ + public function setEncoding($encoding) + { + $this->encoding = $encoding; + } + + /** + * + * set the PDF header + * @param string $header HTML + */ + public function createHeader($header) + { + $this->header = $header; + } + + /** + * + * set the PDF footer + * @param string $footer HTML + */ + public function createFooter($footer) + { + $this->footer = $footer; + } + + /** + * + * create the PDF content + * @param string $content HTML + */ + public function createContent($content) + { + $this->content = $content; + } + + /** + * Change the font + * @param unknown_type $iso_lang + */ + public function setFontForLang($iso_lang) + { + $this->font = self::DEFAULT_FONT; + if (array_key_exists($iso_lang, $this->font_by_lang)) + $this->font = $this->font_by_lang[$iso_lang]; + } + + /** + * @see TCPDF::Header() + */ + public function Header() + { + $this->setFont($this->font); + $this->writehtml($this->header); + } + + /** + * @see TCPDF::Footer() + */ + public function Footer() + { + $this->setFont($this->font); + $this->writehtml($this->footer); + } + + /** + * Render the pdf file + * + * @param string $filename + * @throws PrestashopException + */ + public function render($filename) + { + if (empty($filename)) + throw new PrestashopException('Missing filename.'); + + $this->lastPage(); + $this->output($filename, 'I'); + } + + /** + * Write a PDF page + */ + public function writePage() + { + + $this->SetHeaderMargin(5); + $this->SetFooterMargin(18); + $this->setMargins(10, 40, 10); + $this->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM); + + $this->AddPage(); + + $this->writehtml($this->content, true, false, true, false, ''); + } +} + diff --git a/classes/tax/TaxCalculator.php b/classes/tax/TaxCalculator.php index 9ae34db6d..2078d1f5d 100644 --- a/classes/tax/TaxCalculator.php +++ b/classes/tax/TaxCalculator.php @@ -131,11 +131,11 @@ class TaxCalculatorCore { if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD) { - $taxes_amounts[$tax->rate] = $price_te * (abs($tax->rate) / 100); + $taxes_amounts[$tax->id] = $price_te * (abs($tax->rate) / 100); $price_te = $price_te + $taxes_amounts[$tax->rate]; } else - $taxes_amounts[$tax->rate] = ($price_te * (abs($tax->rate) / 100)); + $taxes_amounts[$tax->id] = ($price_te * (abs($tax->rate) / 100)); } return $taxes_amounts; diff --git a/config/defines.inc.php b/config/defines.inc.php index 8e96ead94..d5fcafe24 100755 --- a/config/defines.inc.php +++ b/config/defines.inc.php @@ -65,7 +65,8 @@ define('_PS_TOOL_DIR_', _PS_ROOT_DIR_.'/tools/'); define('_PS_GEOIP_DIR_', _PS_TOOL_DIR_.'geoip/'); define('_PS_SWIFT_DIR_', _PS_TOOL_DIR_.'swift/'); define('_PS_GENDERS_DIR_', _PS_IMG_DIR_.'genders/'); -define('_PS_FPDF_PATH_', _PS_TOOL_DIR_.'fpdf/'); +define('_PS_FPDF_PATH_', _PS_TOOL_DIR_.'fpdf/'); // @deprecated will be removed in 1.6 +define('_PS_TCPDF_PATH_', _PS_TOOL_DIR_.'tcpdf/'); define('_PS_TAASC_PATH_', _PS_TOOL_DIR_.'taasc/'); define('_PS_PEAR_XML_PARSER_PATH_', _PS_TOOL_DIR_.'pear_xml_parser/'); define('_PS_CACHE_DIR_', _PS_ROOT_DIR_.'/cache/'); diff --git a/config/smartyadmin.config.inc.php b/config/smartyadmin.config.inc.php index fa9c1d82d..0e12967cb 100644 --- a/config/smartyadmin.config.inc.php +++ b/config/smartyadmin.config.inc.php @@ -31,8 +31,34 @@ function smartyTranslate($params, &$smarty) { global $_LANGADM; $htmlentities = !isset($params['js']); + $pdf = isset($params['pdf']); $addslashes = !isset($params['slashes']); + if ($pdf) + { + global $_LANGPDF; + $iso = Context::getContext()->language->iso_code; + if (!Validate::isLanguageIsoCode($iso)) + throw PrestashopException('Invalid iso lang!'); + + $translationsFile = _PS_THEME_DIR_.'pdf/lang/'.$iso.'.php'; + + if (Tools::file_exists_cache($translationsFile)) + @include_once($translationsFile); + + $key = 'PDF'.md5($params['s']); + $lang_array = $_LANGPDF; + + $msg = $params['s']; + if (is_array($lang_array) AND key_exists($key, $lang_array)) + $msg = $lang_array[$key]; + elseif (is_array($lang_array) AND key_exists(Tools::strtolower($key), $lang_array)) + $msg = $lang_array[Tools::strtolower($key)]; + + return $msg; + } + + $filename = ((!isset($smarty->compiler_object) OR !is_object($smarty->compiler_object->template)) ? $smarty->template_resource : $smarty->compiler_object->template->getTemplateFilepath()); $class = Tools::substr(basename($filename), 0, -4); diff --git a/config/smartyfront.config.inc.php b/config/smartyfront.config.inc.php index 0716c4e52..1e9848200 100644 --- a/config/smartyfront.config.inc.php +++ b/config/smartyfront.config.inc.php @@ -29,8 +29,9 @@ $smarty->template_dir = _PS_THEME_DIR_.'tpl'; function smartyTranslate($params, &$smarty) { - global $_LANG, $_MODULES, $cookie, $_MODULE; + global $_LANG, $_MODULES, $cookie, $_MODULE, $_LANGPDF; if (!isset($params['js'])) $params['js'] = 0; + if (!isset($params['pdf'])) $params['pdf'] = false; if (!isset($params['mod'])) $params['mod'] = false; $string = str_replace('\'', '\\\'', $params['s']); @@ -58,7 +59,18 @@ function smartyTranslate($params, &$smarty) if(is_array($_MODULE)) $_MODULES = array_merge($_MODULES, $_MODULE); $lang_array = $_MODULES; - } + } + else if ($params['pdf']) + { + $iso = Language::getIsoById($cookie->id_lang); + $translationsFile = _PS_THEME_DIR_.'pdf/lang/'.$iso.'.php'; + + if (Tools::file_exists_cache($translationsFile)) + @include_once($translationsFile); + + $key = 'PDF'.md5($string); + $lang_array = $_LANGPDF; + } if (is_array($lang_array) AND key_exists($key, $lang_array)) $msg = $lang_array[$key]; @@ -69,5 +81,6 @@ function smartyTranslate($params, &$smarty) if ($msg != $params['s']) $msg = $params['js'] ? addslashes($msg) : stripslashes($msg); + return $params['js'] ? $msg : Tools::htmlentitiesUTF8($msg); } diff --git a/controllers/admin/AdminTaxesController.php b/controllers/admin/AdminTaxesController.php index 7cf746e9b..a263f786d 100644 --- a/controllers/admin/AdminTaxesController.php +++ b/controllers/admin/AdminTaxesController.php @@ -245,3 +245,4 @@ class AdminTaxesControllerCore extends AdminController } } } + diff --git a/controllers/admin/AdminTranslationsController.php b/controllers/admin/AdminTranslationsController.php index 58abc87f9..e9db98b14 100644 --- a/controllers/admin/AdminTranslationsController.php +++ b/controllers/admin/AdminTranslationsController.php @@ -528,7 +528,7 @@ class AdminTranslationsControllerCore extends AdminController { if (!Validate::isLanguageIsoCode(Tools::strtolower(Tools::getValue('lang')))) die(Tools::displayError()); - $this->writeTranslationFile('PDF', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/pdf.php', 'PDF'); + $this->writeTranslationFile('PDF', _PS_THEME_DIR_.'pdf/lang/'.Tools::strtolower(Tools::getValue('lang')).'.php', 'PDF'); } else $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); @@ -1624,25 +1624,46 @@ class AdminTranslationsControllerCore extends AdminController { $lang = Tools::strtolower(Tools::getValue('lang')); $_LANG = array(); + $str_output = ''; - if (!file_exists(_PS_TRANSLATIONS_DIR_.$lang)) - if (!mkdir(_PS_TRANSLATIONS_DIR_.$lang, 0700)) - die('Please create a "'.$iso.'" directory in '._PS_TRANSLATIONS_DIR_); - if (!file_exists(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php')) - if (!file_put_contents(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php', "")) + if (!Validate::isLangIsoCode($lang)) + die('Invalid iso lang ('.$lang.')'); + + $i18n_dir = _PS_THEME_DIR_.'pdf/lang/'; + $i18n_file = $i18n_dir.$lang.'.php'; + if (!file_exists($i18n_file)) + if (!mkdir($i18n_dir, 0700)) + die('Please create a "'.$lang.'" directory in '._PS_TRANSLATIONS_DIR_); + + if (!file_exists($i18n_file)) + if (!file_put_contents($i18n_file, "")) die('Please create a "'.Tools::strtolower($lang).'.php" file in '.realpath(_PS_ADMIN_DIR_.'/')); unset($_LANGPDF); - @include(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php'); + @include($i18n_file); $files = array(); $count = 0; - $tab = 'PDF_invoice'; + $tab = 'PDF'; $tabsArray = array($tab=>array()); $regex = '/self::l\(\''._PS_TRANS_PATTERN_.'\'[\)|\,]/U'; // need to parse PDF.php in order to find $regex and add this to $tabsArray // this has to be done for the core class, and eventually for the override - $tabsArray = $this->_parsePdfClass(_PS_CLASS_DIR_.'PDF.php', $regex, $_LANGPDF, $tab, $tabsArray); - if(file_exists(_PS_ROOT_DIR_.'/override/classes/PDF.php')) - $tabsArray = $this->_parsePdfClass(_PS_ROOT_DIR_.'/override/classes/PDF.php', $regex, $_LANGPDF, $tab, $tabsArray); + foreach (glob(_PS_CLASS_DIR_.'pdf/'."*.php") as $filename) + { + $tabsArray = $this->_parsePdfClass($filename, $regex, $_LANGPDF, $tab, $tabsArray); + if (file_exists(_PS_ROOT_DIR_.'/override/classes/pdf/'.basename($filename))) + $tabsArray = $this->_parsePdfClass(_PS_ROOT_DIR_.'/override/classes/pdf/'.basename($filename), $regex, $_LANGPDF, $tab, $tabsArray); + } + + // parse pdf template + /* Search language tags (eg {l s='to translate'}) */ + $regex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( js=1)?( pdf=\'true\')?\}/U'; + foreach (glob( _PS_THEME_DIR_.'/pdf/*.tpl') as $filename) + { + preg_match_all($regex, file_get_contents($filename), $matches); + foreach ($matches[1] as $key) + $tabsArray[$tab][$key] = stripslashes(key_exists($tab.md5(addslashes($key)), $_LANGPDF) ? html_entity_decode($_LANGPDF[$tab.md5(addslashes($key))], ENT_COMPAT, 'UTF-8') : ''); + + } $count += isset($tabsArray[$tab]) ? sizeof($tabsArray[$tab]) : 0; diff --git a/controllers/front/OrderFollowController.php b/controllers/front/OrderFollowController.php index 87c9539ca..7b23f1b4e 100644 --- a/controllers/front/OrderFollowController.php +++ b/controllers/front/OrderFollowController.php @@ -104,3 +104,4 @@ class OrderFollowControllerCore extends FrontController $this->addJS(_THEME_JS_DIR_.'history.js'); } } + diff --git a/controllers/front/OrderReturnController.php b/controllers/front/OrderReturnController.php index 9108cf3bc..e3eef1518 100644 --- a/controllers/front/OrderReturnController.php +++ b/controllers/front/OrderReturnController.php @@ -84,5 +84,10 @@ class OrderReturnControllerCore extends FrontController )); $this->setTemplate(_PS_THEME_DIR_.'order-return.tpl'); } + + public function displayAjax() + { + $this->context->smarty->display($this->template); + } } diff --git a/controllers/front/PdfInvoiceController.php b/controllers/front/PdfInvoiceController.php index f941b5b09..84cd9028f 100644 --- a/controllers/front/PdfInvoiceController.php +++ b/controllers/front/PdfInvoiceController.php @@ -25,29 +25,66 @@ * International Registered Trademark & Property of PrestaShop SA */ + + class PdfInvoiceControllerCore extends FrontController { protected $display_header = false; protected $display_footer = false; + public $content_only = true; + + protected $template; + public $filename; + public function postProcess() { + $id_order = (int)Tools::getValue('id_order'); + if (!$this->context->customer->isLogged() && !Tools::getValue('secure_key')) Tools::redirect('index.php?controller=authentication&back=pdf-invoice'); if (!(int)Configuration::get('PS_INVOICE')) die(Tools::displayError('Invoices are disabled in this shop.')); - if (isset($_GET['id_order']) && Validate::isUnsignedId($_GET['id_order'])) - $order = new Order($_GET['id_order']); + if (isset($id_order) && Validate::isUnsignedId($id_order)) + $order = new Order($id_order); if (!isset($order) || !Validate::isLoadedObject($order)) die(Tools::displayError('Invoice not found')); - else if ((isset($this->context->customer->id) && $order->id_customer != $this->context->customer->id) || (Tools::isSubmit('secure_key') && $order->secure_key != Tools::getValue('secure_key'))) + + if ((isset($this->context->customer->id) && $order->id_customer != $this->context->customer->id) || (Tools::isSubmit('secure_key') && $order->secure_key != Tools::getValue('secure_key'))) die(Tools::displayError('Invoice not found')); - else if (!OrderState::invoiceAvailable($order->getCurrentState()) && !$order->invoice_number) + + if (!OrderState::invoiceAvailable($order->getCurrentState()) && !$order->invoice_number) die(Tools::displayError('No invoice available')); - else - PDF::invoice($order); + + // assignments + $country = new Country((int)$order->id_address_invoice); + + $this->order = $order; } -} \ No newline at end of file + + public function display() + { + $pdf = new PDF($this->order, PDF::TEMPLATE_INVOICE, $this->context->smarty, $this->context->language->id); + $pdf->render(); + } + + + /** + * Returns the invoice template associated to the country iso_code + * @param string $iso_user + */ + public function getTemplate($iso_country) + { + $template = _PS_THEME_PDF_DIR_.'/invoice.tpl'; + + $iso_template = _PS_THEME_PDF_DIR_.'/invoice.'.$iso_country.'.tpl'; + if (file_exists($iso_template)) + $template = $iso_template; + + return $template; + } +} + diff --git a/controllers/front/PdfOrderReturnController.php b/controllers/front/PdfOrderReturnController.php index 58537936f..6d5cf3f27 100644 --- a/controllers/front/PdfOrderReturnController.php +++ b/controllers/front/PdfOrderReturnController.php @@ -35,16 +35,22 @@ class PdfOrderReturnControllerCore extends FrontController if (!$this->context->customer->isLogged()) Tools::redirect('index.php?controller=authentication&back=order-follow'); - if (isset($_GET['id_order_return']) && Validate::isUnsignedId($_GET['id_order_return'])) - $orderReturn = new OrderReturn($_GET['id_order_return']); + if (isset(Tools::getValue('id_order_return')) && Validate::isUnsignedId(Tools::getValue('id_order_return'))) + $this->orderReturn = new OrderReturn(Tools::getValue('id_order_return')); - if (!isset($orderReturn) || !Validate::isLoadedObject($orderReturn)) + if (!isset($this->orderReturn) || !Validate::isLoadedObject($this->orderReturn)) die(Tools::displayError('Order return not found')); - else if ($orderReturn->id_customer != $this->context->customer->id) + else if ($this->orderReturn->id_customer != $this->context->customer->id) die(Tools::displayError('Order return not found')); - else if ($orderReturn->state < 2) + else if ($this->orderReturn->state < 2) die(Tools::displayError('Order return not confirmed')); - else - PDF::orderReturn($orderReturn); + } -} \ No newline at end of file + + public function display() + { + $pdf = new PDF($this->orderReturn, PDF::TEMPLATE_ORDER_RETURN, $this->context->smarty); + $pdf->render(); + } +} + diff --git a/controllers/front/PdfOrderSlipController.php b/controllers/front/PdfOrderSlipController.php index 6efd57d6c..5401ebe76 100644 --- a/controllers/front/PdfOrderSlipController.php +++ b/controllers/front/PdfOrderSlipController.php @@ -30,25 +30,29 @@ class PdfOrderSlipControllerCore extends FrontController protected $display_header = false; protected $display_footer = false; + protected $order_slip; + + public function postProcess() { if (!$this->context->customer->isLogged()) Tools::redirect('index.php?controller=authentication&back=order-follow'); if (isset($_GET['id_order_slip']) && Validate::isUnsignedId($_GET['id_order_slip'])) - $orderSlip = new OrderSlip($_GET['id_order_slip']); + $this->order_slip = new OrderSlip($_GET['id_order_slip']); - if (!isset($orderSlip) || !Validate::isLoadedObject($orderSlip)) - die(Tools::displayError('Order return not found')); - else if ($orderSlip->id_customer != $this->context->customer->id) + if (!isset($this->order_slip) || !Validate::isLoadedObject($this->order_slip)) die(Tools::displayError('Order return not found')); - $order = new Order($orderSlip->id_order); - if (!Validate::isLoadedObject($order)) - die(Tools::displayError('Order not found')); + else if ($this->order_slip->id_customer != $this->context->customer->id) + die(Tools::displayError('Order return not found')); - $order->products = OrderSlip::getOrdersSlipProducts((int)$orderSlip->id, $order); - $ref = null; - PDF::invoice($order, 'D', false, $ref, $orderSlip); + } + + public function display() + { + $pdf = new PDF($this->order_slip, PDF::TEMPLATE_ORDER_SLIP, $this->context->smarty); + $pdf->render(); } } + diff --git a/install-dev/sql/db.sql b/install-dev/sql/db.sql index 8c644babc..a8cf76b4f 100644 --- a/install-dev/sql/db.sql +++ b/install-dev/sql/db.sql @@ -1028,7 +1028,9 @@ CREATE TABLE `PREFIX_orders` ( CREATE TABLE IF NOT EXISTS `PREFIX_order_detail_tax` ( `id_order_detail` int(11) NOT NULL, - `id_tax` int(11) NOT NULL + `id_tax` int(11) NOT NULL, + `unit_amount` DECIMAL( 10,6 ) NOT NULL default '0.00', + `total_amount` DECIMAL( 10, 6 ) NOT NULL default '0.00' ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; CREATE TABLE `PREFIX_order_detail` ( @@ -1052,15 +1054,23 @@ CREATE TABLE `PREFIX_order_detail` ( `product_reference` varchar(32) default NULL, `product_supplier_reference` varchar(32) default NULL, `product_weight` float NOT NULL, + `tax_computation_method` tinyint(1) unsigned NOT NULL default '0', `tax_name` varchar(16) NOT NULL, `tax_rate` DECIMAL(10,3) NOT NULL DEFAULT '0.000', - `tax_computation_method` tinyint(1) unsigned NOT NULL default '0', `ecotax` decimal(21,6) NOT NULL default '0.00', `ecotax_tax_rate` DECIMAL(5,3) NOT NULL DEFAULT '0.000', `discount_quantity_applied` TINYINT(1) NOT NULL DEFAULT 0, `download_hash` varchar(255) default NULL, `download_nb` int(10) unsigned default '0', `download_deadline` datetime default '0000-00-00 00:00:00', + `total_price_tax_incl` DECIMAL(20, 6) NOT NULL default '0.000000', + `total_price_tax_excl` DECIMAL(20, 6) NOT NULL default '0.000000', + `unit_price_tax_incl` DECIMAL(20, 6) NOT NULL default '0.000000', + `unit_price_tax_excl` DECIMAL(20, 6) NOT NULL default '0.000000', + `total_shipping_price_tax_incl` DECIMAL(20, 6) NOT NULL default '0.000000', + `total_shipping_price_tax_excl` DECIMAL(20, 6) NOT NULL default '0.000000', + `purchase_supplier_price` DECIMAL(20, 6) NOT NULL default '0.000000', + `original_product_price` DECIMAL(20, 6) NOT NULL default '0.000000', PRIMARY KEY (`id_order_detail`), KEY `order_detail_order` (`id_order`), KEY `product_id` (`product_id`), @@ -1068,6 +1078,7 @@ CREATE TABLE `PREFIX_order_detail` ( KEY `id_order_id_order_detail` (`id_order`, `id_order_detail`) ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; + CREATE TABLE `PREFIX_order_cart_rule` ( `id_order_cart_rule` int(10) unsigned NOT NULL auto_increment, `id_order` int(10) unsigned NOT NULL, @@ -2011,7 +2022,7 @@ CREATE TABLE `PREFIX_stock` ( `usable_quantity` INT(11) UNSIGNED NOT NULL, `price_te` DECIMAL(20,6) DEFAULT '0.000000', PRIMARY KEY (`id_stock`), - KEY `id_warehouse` (`id_warehouse`), + KEY `id_warehouse` (`id_warehouse`), KEY `id_product` (`id_product`), KEY `id_product_attribute` (`id_product_attribute`) ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8; diff --git a/install-dev/sql/upgrade/1.5.0.1.sql b/install-dev/sql/upgrade/1.5.0.1.sql index 1e30d5a3f..1b968b97f 100644 --- a/install-dev/sql/upgrade/1.5.0.1.sql +++ b/install-dev/sql/upgrade/1.5.0.1.sql @@ -150,10 +150,6 @@ ALTER TABLE `PREFIX_tax` ADD `deleted` INT NOT NULL AFTER `active`; /* PHP:update_order_detail_taxes(); */; -ALTER TABLE `PREFIX_order_detail` - DROP `tax_name`, - DROP `tax_rate`; - CREATE TABLE `PREFIX_customer_message_sync_imap` ( `md5_header` varbinary(32) NOT NULL, KEY `md5_header_index` (`md5_header`(4)) @@ -485,6 +481,11 @@ UPDATE `PREFIX_hook` SET `name` = 'actionAttributeDelete' WHERE `name` = 'afterD UPDATE `PREFIX_hook` SET `name` = 'actionAttributeSave' WHERE `name` = 'afterSaveAttribute'; UPDATE `PREFIX_hook` SET `name` = 'actionTaxManager' WHERE `name` = 'taxManager'; +ALTER TABLE `PREFIX_order_detail_tax` +ADD `unit_amount` DECIMAL( 10, 6 ) NOT NULL AFTER `id_tax` , +ADD `total_amount` DECIMAL( 10, 6 ) NOT NULL AFTER `unit_amount`; + + ALTER TABLE `PREFIX_specific_price` ADD `id_product_attribute` INT UNSIGNED NOT NULL AFTER `id_product`; ALTER TABLE `PREFIX_specific_price` DROP INDEX `id_product`; ALTER TABLE `PREFIX_specific_price` ADD INDEX `id_product` (`id_product`, `id_product_attribute`, `id_shop`, `id_currency`, `id_country`, `id_group`, `from_quantity`, `from`, `to`); diff --git a/themes/prestashop/order-return.tpl b/themes/prestashop/order-return.tpl index 97c148f26..f5bf8d6f7 100644 --- a/themes/prestashop/order-return.tpl +++ b/themes/prestashop/order-return.tpl @@ -1,5 +1,5 @@ {* -* 2007-2011 PrestaShop +* 2007-2011 PrestaShop * * NOTICE OF LICENSE * @@ -24,7 +24,7 @@ * International Registered Trademark & Property of PrestaShop SA *} {include file="$tpl_dir./errors.tpl"} -{if isset($orderRe)} +{if isset($orderRet)}

{l s='RE#'}{$orderRet->id|string_format:"%06d"} {l s='on'} {dateFormat date=$order->date_add full=0}

{l s='We have logged your return request.'}

@@ -43,7 +43,7 @@ {foreach from=$products item=product name=products} - + {assign var='quantityDisplayed' value=0} {foreach from=$returnedCustomizations item='customization' name=products} {if $customization.product_id == $product.product_id} @@ -78,7 +78,7 @@ {assign var='quantityDisplayed' value=$quantityDisplayed+$customization.product_quantity} {/if} {/foreach} - + {if $product.product_quantity > $quantityDisplayed} {if $product.product_reference}{$product.product_reference|escape:'htmlall':'UTF-8'}{else}--{/if} @@ -105,4 +105,5 @@ {elseif $orderRet->state == 1}

{l s='You must wait for our confirmation before returning any merchandise.'}

{/if} -{/if} \ No newline at end of file +{/if} + diff --git a/themes/prestashop/pdf/delivery-slip.tpl b/themes/prestashop/pdf/delivery-slip.tpl new file mode 100755 index 000000000..464d88c8b --- /dev/null +++ b/themes/prestashop/pdf/delivery-slip.tpl @@ -0,0 +1,95 @@ +
+ + + +
 
+ + + + + + + +
+ {if !empty($invoice_address)} + + + + + +
+ {ŀ s='Delivery Address' pdf='true'}
+ {$delivery_address} +
+ {l s='Billing Address' pdf='true'}
+ {$invoice_address} +
+ {else} + + + + + +
+ {l s='Billing & Delivery Address' pdf='true'}
+ {$delivery_address} +
+ +
+ {/if} +
+ + + + +
 
+ + + + + + + +
+ + {l s='Order Number:' pdf='true'}
+ {'%06d'|sprintf:$order->id}
+
+ {l s='Order Date:' pdf='true'}
+ {$order->date_add|date_format:"%d-%m-%Y %H:%M"}
+
+ {l s='Payment Method:' pdf='true'}
+ {$order->payment}
+
+ +
+ + + + + + + {foreach $order_details as $product} + {cycle values='#FFF,#DDD' assign=bgcolor} + + + + + + {/foreach} +
{l s='ITEMS MARKED AS RETURNED' pdf='true'}{l s='REFERENCE' pdf='true'}{l s='QTY' pdf='true'}
{$product.product_name} + {if empty($product.product_reference)} + --- + {else} + {$product.product_reference} + {/if} + {$product.product_quantity}
+
+ + + + +
 
+ +
+ diff --git a/themes/prestashop/pdf/footer.tpl b/themes/prestashop/pdf/footer.tpl new file mode 100755 index 000000000..3e0f0ea3c --- /dev/null +++ b/themes/prestashop/pdf/footer.tpl @@ -0,0 +1,32 @@ + + + + +
+ {if $available_in_your_account} + {l s='An electronic version of this invoice is available in your account. To access it, log in to our website using your e-mail address and password (which you created when placing your first order).' pdf='true'} +
+ {/if} + {$shop_address|escape:'htmlall':'UTF-8'}
+ + {if !empty($shop_phone) OR !empty($shop_fax)} + {l s='For more assistance, contact Support:' pdf='true'}
+ {if !empty($shop_phone)} + Tel: {$shop_phone|escape:'htmlall':'UTF-8'} + {/if} + + {if !empty($shop_fax)} + Fax: {$shop_fax|escape:'htmlall':'UTF-8'} + {/if} +
+ {/if} + + {if isset($shop_details)} + {$shop_details|escape:'htmlall':'UTF-8'}
+ {/if} + + {if isset($free_text)} + {$free_text|escape:'htmlall':'UTF-8'}
+ {/if} +
+ diff --git a/themes/prestashop/pdf/fr.php b/themes/prestashop/pdf/fr.php new file mode 100644 index 000000000..55a7bec66 --- /dev/null +++ b/themes/prestashop/pdf/fr.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/themes/prestashop/pdf/header.tpl b/themes/prestashop/pdf/header.tpl new file mode 100755 index 000000000..d43d836a2 --- /dev/null +++ b/themes/prestashop/pdf/header.tpl @@ -0,0 +1,23 @@ + + + + + +
+ {if $logo_path} + + {/if} + + + + + + + + + + + +
{$shop_name|escape:'htmlall':'UTF-8'}
{$date|escape:'htmlall':'UTF-8'}
{$title|escape:'htmlall':'UTF-8'}
+
+ diff --git a/themes/prestashop/pdf/invoice.tax-tab.tpl b/themes/prestashop/pdf/invoice.tax-tab.tpl new file mode 100755 index 000000000..87c2d9606 --- /dev/null +++ b/themes/prestashop/pdf/invoice.tax-tab.tpl @@ -0,0 +1,46 @@ + + + + + + +
+ {if $tax_exempt} + {l s='Exempt of VAT according section 259B of the General Tax Code.' pdf='true'} + {else if (count($shipping_tax_breakdown) + count($product_tax_breakdown) == 0)} + {l s='No tax' pdf='true'} + {else} + + + + + + + + + {foreach $product_tax_breakdown as $rate => $product_tax_infos} + + + + + + + {/foreach} + + {foreach $shipping_tax_breakdown as $shipping_tax_infos} + + + + + + + {/foreach} +
{l s='Tax Detail' pdf='true'}{l s='Tax Rate' pdf='true'}{l s='Total Tax Excl' pdf='true'}{l s='Total Tax' pdf='true'}
{l s='Products' pdf='true'}{$rate} + {if !$use_one_after_another_method} + {displayPrice currency=$order->id_currency price=$product_tax_infos.total_price_tax_excl} + {/if} + {displayPrice currency=$order->id_currency price=$product_tax_infos.total_amount}
{l s='Shipping' pdf='true'}{$shipping_tax_infos.rate}{displayPrice currency=$order->id_currency price=$order->total_shipping_tax_excl}{displayPrice currency=$order->id_currency price=$shipping_tax_infos.total_amount}
+ {/if} +
+ + diff --git a/themes/prestashop/pdf/invoice.tpl b/themes/prestashop/pdf/invoice.tpl new file mode 100755 index 000000000..8f44c0067 --- /dev/null +++ b/themes/prestashop/pdf/invoice.tpl @@ -0,0 +1,206 @@ +
+ + + +
 
+ + + + + + + +
+ {if !empty($delivery_address)} + + + + + +
+ {l s='Delivery Address' pdf='true'}
+ {$delivery_address} +
+ {l s='Billing Address' pdf='true'}
+ {$invoice_address} +
+ {else} + + + + + +
+ {l s='Billing & Delivery Address.' pdf='true'}
+ {$invoice_address} +
+ +
+ {/if} +
+ + +
 
+ + + + + + + +
+ + {l s='Order Number:' pdf='true'}
+ {'%06d'|sprintf:$order->id}
+
+ {l s='Order Date:' pdf='true'}
+ {$order->date_add|date_format:"%d-%m-%Y %H:%M"}
+
+ {l s='Payment Method:' pdf='true'}
+ {$order->payment}
+
+ +
+ + + + + {if !$tax_excluded_display} + + {/if} + + + + + + {foreach $order_details as $order_detail} + {cycle values='#FFF,#DDD' assign=bgcolor} + + + + {if !$tax_excluded_display} + + {/if} + + + + + + {foreach $order_detail.customizedDatas as $customization} + + + + + + + {/foreach} + {/foreach} +
{l s='Product / Reference' pdf='true'}{l s='Unit Price' pdf='true'}
{l s='(Tax Excl.)' pdf='true'}
{l s='Unit Price' pdf='true'}{l s='Discount' pdf='true'}{l s='Qty' pdf='true'}{l s='Total' pdf='true'}
{$order_detail.product_name} + {displayPrice currency=$order->id_currency price=$order_detail.unit_price_tax_excl} + + {if $tax_excluded_display} + {displayPrice currency=$order->id_currency price=$order_detail.unit_price_tax_excl} + {else} + {displayPrice currency=$order->id_currency price=$order_detail.unit_price_tax_incl} + {/if} + + {if (isset($order_detail.reduction_amount) && $order_detail.reduction_amount > 0)} + -{displayPrice currency=$order->id_currency price=$order_detail.reduction_amount} + {else if (isset($order_detail.reduction_percent) && $order_detail.reduction_percent > 0)} + -{$order_detail.reduction_percent}% + {else} + -- + {/if} + {$order_detail.product_quantity} + {if $tax_excluded_display} + {displayPrice currency=$order->id_currency price=$order_detail.total_price_tax_excl} + {else} + {displayPrice currency=$order->id_currency price=$order_detail.total_price_tax_incl} + {/if} +
+ {foreach $customization.datas as $customization_types} +
+ {foreach $customization_types as $customization_infos name=custo_foreach} + {$customization_infos.name}: {$customization_infos.value} + {if !$smarty.foreach.custo_foreach.last}
+ {else} +
 
+ {/if} + {/foreach} +
+ {/foreach} +
({$customization.quantity})
+ + + {if (($order->total_paid_tax_incl - $order->total_paid_tax_excl) > 0)} + + + + + + + + + + {else} + + + + + {/if} + + {if $order->total_discounts_tax_incl > 0} + + + + + {/if} + + {if $order->total_wrapping_tax_incl > 0} + + + + + {/if} + + {if $order->total_shipping_tax_incl > 0} + + + + + {/if} + + {if ($order->total_paid_tax_incl - $order->total_paid_tax_excl) > 0} + + + + + {/if} + + + + + +
{l s='Product Total (Tax Excl.)' pdf='true'}{displayPrice currency=$order->id_currency price=$order->total_products}
{l s='Product Total (Tax Incl.)' pdf='true'}{displayPrice currency=$order->id_currency price=$order->total_products_wt}
{l s='Product Total' pdf='true'}{displayPrice currency=$order->id_currency price=$order->total_products}
{l s='Total Vouchers' pdf='true'}-{displayPrice currency=$order->id_currency price=$order->total_discounts_tax_incl}
{l s='Wrapping Cost' pdf='true'} + {if $tax_excluded_display} + {displayPrice currency=$order->id_currency price=$order->total_wrapping_tax_excl} + {else} + {displayPrice currency=$order->id_currency price=$order->total_wrapping_tax_incl} + {/if} +
{l s='Shipping Cost' pdf='true'} + {if $tax_excluded_display} + {displayPrice currency=$order->id_currency price=$order->total_shipping_tax_excl} + {else} + {displayPrice currency=$order->id_currency price=$order->total_shipping_tax_incl} + {/if} +
{l s='Total Tax' pdf='true'}{displayPrice currency=$order->id_currency price=($order->total_paid_tax_incl - $order->total_paid_tax_excl)}
{l s='Total' pdf='true'}{displayPrice currency=$order->id_currency price=$order->total_paid_tax_incl}
+ +
+ + +
 
+ +{$tax_tab} + +
+ diff --git a/themes/prestashop/pdf/lang/fr.php b/themes/prestashop/pdf/lang/fr.php new file mode 100644 index 000000000..485325039 --- /dev/null +++ b/themes/prestashop/pdf/lang/fr.php @@ -0,0 +1,38 @@ + \ No newline at end of file diff --git a/themes/prestashop/pdf/order-return.tpl b/themes/prestashop/pdf/order-return.tpl new file mode 100755 index 000000000..bf943ab6d --- /dev/null +++ b/themes/prestashop/pdf/order-return.tpl @@ -0,0 +1,129 @@ +
+ + + +
 
+ + + + + + + +
+ {if !empty($invoice_address)} + + + + + +
+ {l s='Delivery Address' pdf='true'}
+ {$delivery_address} +
+ {l s='Billing Address' pdf='true'}
+ {$invoice_address} +
+ {else} + + + + + +
+ {l s='Billing & Delivery Address' pdf='true'}
+ {$delivery_address} +
+ +
+ {/if} +
+ + + + +
 
+ + + + + + + +
+ + {l s='We have logged your return request.' pdf='true'}
+ {l s='Your package must be returned to us within' pdf='true'} {$return_nb_days} {l s='days of receiving your order.' pdf='true'}
+
+ + + + + + + +
+ + {l s='Return Number:' pdf='true'}
+ {'%06d'|sprintf:$order_return->id}
+
+ {l s='Date:' pdf='true'}
+ {$order_return->date_add|date_format:"%d-%m-%Y %H:%M"}
+
+ +
+ + + + + + + {foreach $products as $product} + {cycle values='#FFF,#DDD' assign=bgcolor} + + + + + + {/foreach} +
{l s='ITEMS MARKED AS RETURNED' pdf='true'}{l s='REFERENCE' pdf='true'}{l s='QTY' pdf='true'}
{$product.product_name} + {if empty($product.product_reference)} + --- + {else} + {$product.product_reference} + {/if} + {$product.product_quantity}
+
+ + + + + + +
+ + + + + + + + +
{l s='If the following conditions are not respected we reserve the rights to refuse your package and/or reimbursement:' pdf='true'}
+
    +
  • {l s='Please include this number return reference on your return package:' pdf='true'} {$order_return->id}
  • +
  • {l s='All products must be returned in their original package without damage or wear.' pdf='true'}
  • +
  • {l s='Please print out this document and slip it into your package.' pdf='true'}
  • +
  • {l s='The package should be sent to the following address:' pdf='true'}
  • +
+ {$shop_address} +
+ +
+ {l s='Upon receiving your package, we will notify you by e-mail. We will then begin processing the reimbursement of your order total. +Let us know if you have any questions' pdf='true'} +
+ + +
+ diff --git a/translations/fr/pdf.php b/translations/fr/pdf.php index 955305318..952b39f6b 100644 --- a/translations/fr/pdf.php +++ b/translations/fr/pdf.php @@ -2,68 +2,7 @@ global $_LANGPDF; $_LANGPDF = array(); -$_LANGPDF['PDF_invoicee0036b67b754e9f6442f9f9e6b200c33'] = 'Retour n°'; -$_LANGPDF['PDF_invoice77c3e447f60541a1c346a08134078c7f'] = 'Avoir n°'; -$_LANGPDF['PDF_invoicecb5efbba6a6babef9082ca6976928ca7'] = 'Bon de livraison n°'; -$_LANGPDF['PDF_invoicefe4da50838bb10dcbf1bf8dcd9b12ab5'] = 'Facture n°'; -$_LANGPDF['PDF_invoiceba160acb58001c904c57507da3689265'] = 'Commande n°'; -$_LANGPDF['PDF_invoice808a04117534f9dfb63b9accd7efc609'] = 'Siège social'; -$_LANGPDF['PDF_invoicea54cedc1e053a70d4a6319feccf531ca'] = 'Téléphone :'; -$_LANGPDF['PDF_invoice2babe53026309ed1bc4d26626dbaf9b3'] = 'Détails :'; -$_LANGPDF['PDF_invoice15b57bef332e7e0327d89fe93711a954'] = 'Une version électronique est conservée sur votre compte. Pour y accéder, identifiez-vous sur le site'; -$_LANGPDF['PDF_invoiceb1fb57b55075a4a51cf83e44d0440358'] = 'avec vos identifiants (créés lors de votre première commande).'; -$_LANGPDF['PDF_invoiced98a07f84921b24ee30f86fd8cd85c3c'] = 'du'; -$_LANGPDF['PDF_invoice88be9ea838e21273267409d76af3b284'] = 'Nous avons bien enregistré votre demande de retour.'; -$_LANGPDF['PDF_invoicedd0b8feb4eb6c389c284518f5683017c'] = 'Nous vous rappelons que votre colis doit nous être retourné dans les'; -$_LANGPDF['PDF_invoiceea62a2e28a800c367509773730120a67'] = 'jours après réception de votre commande.'; -$_LANGPDF['PDF_invoice3d2f834cf879baebfdbe52c1c14d9d53'] = 'Liste des produits faisant l\'objet d\'un retour :'; -$_LANGPDF['PDF_invoice9fad4fa5f3fa5caad9b506bbdd9f35d4'] = 'Votre n° de retour :'; -$_LANGPDF['PDF_invoicefb902bc4807c307b9309f2b528b96f2b'] = 'RET'; -$_LANGPDF['PDF_invoiceec9d9f81be48dabb74bcdad5312816af'] = 'Merci de faire figurer ce numéro sur votre colis de retour.'; -$_LANGPDF['PDF_invoicefbbd47b7e45c0ad3fe0bf70539b5a2d4'] = 'RAPPEL :'; -$_LANGPDF['PDF_invoicea3852e23346f6f1e29e1683991690af3'] = '- Tous les produits doivent être retournés dans leur emballage et leur état d\'origine.'; -$_LANGPDF['PDF_invoice0e9a828e54995e48083a072205493fb4'] = '- Veuillez imprimer ce document et le glisser dans votre colis.'; -$_LANGPDF['PDF_invoicead500469c8dc258dcebb89c9efe15de7'] = '- Le paquet devra être envoyé à l\'adresse suivante :'; -$_LANGPDF['PDF_invoice9f68b11daca41ccf9fdc9d2f69901c9c'] = 'Dès réception de votre colis nous procéderons alors au remboursement du montant de votre commande et vous en informerons par mail.'; -$_LANGPDF['PDF_invoice2d0620950a4d96ae301ba7a98e528714'] = 'Merci de nous contacter pour toutes questions.'; -$_LANGPDF['PDF_invoice25e12a86579549b9f88117615eb05e4b'] = 'Si les conditions de retour listées ci-dessus n\'étaient pas respectées,'; -$_LANGPDF['PDF_invoicec896fe3f3895e8ef54194eec601b8f3c'] = 'nous nous réservons le droit de refuser votre colis ou votre remboursement.'; -$_LANGPDF['PDF_invoiceb5a7adde1af5c87d7fd797b6245c2a39'] = 'Description'; -$_LANGPDF['PDF_invoice63d5049791d9d79d86e9a108b0a999ca'] = 'Référence'; -$_LANGPDF['PDF_invoice03ab340b3f99e03cff9e84314ead38c0'] = 'Qté'; $_LANGPDF['PDF_invoice396124314c5fd1fa5bf463274896dc80'] = 'Pas de méthode d\'affichage de prix défini pour ce groupe d\'utilisateur'; -$_LANGPDF['PDF_invoice065ab3a28ca4f16f55f103adc7d0226f'] = 'Livraison'; -$_LANGPDF['PDF_invoice6bdf2efe1a99072849d4e87baee37dbe'] = 'Facturation'; -$_LANGPDF['PDF_invoice60da3bd6867e3952ef0057a0772ea885'] = 'Numéro d\'indentification fiscale:'; -$_LANGPDF['PDF_invoice7b13afd12d6d91d52aa9f857d23f96ef'] = 'Projet de facture'; -$_LANGPDF['PDF_invoiced1228f5476d15142b1358ae4b5fa2454'] = 'Commande n°'; -$_LANGPDF['PDF_invoicef8617a92ba0a0a4eabee724eab7c9f48'] = 'Transporteur :'; -$_LANGPDF['PDF_invoicec1f6368d15f7c13c4e5e8f70c68c747f'] = 'Méthode de paiement :'; -$_LANGPDF['PDF_invoicea3a79b28bc45b7fd393effd056b917e1'] = 'Date d\'expédition :'; -$_LANGPDF['PDF_invoice115dfa9ced2cf136ae677b9a389a5e60'] = 'Emballage cadeau'; -$_LANGPDF['PDF_invoice2370a4958c4ebe6d6c8045cd49a6b392'] = 'Total produits HT'; -$_LANGPDF['PDF_invoiceebaee01719541f61281c16ba22ebbfde'] = 'Total produits TTC'; -$_LANGPDF['PDF_invoicea0eb2cd0b3deb5444102e9a82edae11e'] = 'Total produits'; -$_LANGPDF['PDF_invoicef3e545fccad720e197b9ca3b8b658440'] = 'Totals réductions TTC'; -$_LANGPDF['PDF_invoice9cc000efe3e783af5bf114f2e6573156'] = 'Total emballage cadeau'; -$_LANGPDF['PDF_invoicef4e8b53a114e5a17d051ab84d326cae5'] = 'Total livraison'; -$_LANGPDF['PDF_invoice96b0141273eabab320119c467cdcaf17'] = 'Total'; -$_LANGPDF['PDF_invoice54732c5d0a3f0d597312b0ee55d71fca'] = 'TTC'; -$_LANGPDF['PDF_invoiceac5831c7ec2fed92c7bb73e9962003a4'] = 'HT'; -$_LANGPDF['PDF_invoiceafd42dfebce46ec93972b2e0cbb8b83f'] = 'Prix unitaire'; -$_LANGPDF['PDF_invoice1d744a9ad1dac20645cfc4a36b77323b'] = 'image(s)'; -$_LANGPDF['PDF_invoicec2808546f3e14d267d798f4e0e6f102e'] = 'Personnalisé'; -$_LANGPDF['PDF_invoicea1e7379abfdbc3b8e03506e5489c6110'] = 'Réduction :'; -$_LANGPDF['PDF_invoicee7bbf027179f23c92bec649fa6ae78e4'] = 'Exonéré de la TVA selon l\'article 259B du Code Général des Impôts. '; -$_LANGPDF['PDF_invoice42c26bf38ece1dcd27aca8c6f8c076ed'] = 'Détails de taxe'; -$_LANGPDF['PDF_invoice4b78ac8eb158840e9638a3aeb26c4a9d'] = 'Taxe'; -$_LANGPDF['PDF_invoicecd6576cc33506a6c44e2debbde5c14d9'] = 'Total HT'; -$_LANGPDF['PDF_invoiceb602e0d0c6a72053d0a5be60cb2f8126'] = 'Taxe totale'; -$_LANGPDF['PDF_invoicefe1218d355367ae728ae5bf4bbf0019e'] = 'Ecotaxe TTC'; -$_LANGPDF['PDF_invoiceae5c2883df7651730799e1036984a6a3'] = 'Total TTC'; -$_LANGPDF['PDF_invoice068f80c7519d0528fb08e82137a72131'] = 'Produits'; -$_LANGPDF['PDF_invoice914419aa32f04011357d3b604a86d7eb'] = 'Transporteur'; -$_LANGPDF['PDF_invoice41c1d61bfff3fc9b1fd8f195061b8caa'] = 'Emballage cadeau'; -$_LANGPDF['PDF_invoice6f3455d187a23443796efdcbe044096b'] = 'Aucune taxe'; +$_LANGPDF['PDF_invoice5082245495aa792b3d0874088d2b111b'] = 'plopd'; -?> \ No newline at end of file +?>