* @copyright 2007-2011 PrestaShop SA
* @version Release: $Revision: 6844 $
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
abstract class PaymentModuleCore extends Module
{
/** @var integer Current order's id */
public $currentOrder;
public $currencies = true;
public $currencies_mode = 'checkbox';
public function install()
{
if (!parent::install())
return false;
// Insert currencies availability
if ($this->currencies_mode == 'checkbox')
{
if (!Db::getInstance()->execute('
INSERT INTO `'._DB_PREFIX_.'module_currency` (id_module, id_currency)
SELECT '.(int)$this->id.', id_currency FROM `'._DB_PREFIX_.'currency` WHERE deleted = 0'))
return false;
}
elseif ($this->currencies_mode == 'radio')
{
if (!Db::getInstance()->execute('
INSERT INTO `'._DB_PREFIX_.'module_currency` (id_module, id_currency)
VALUES ('.(int)$this->id.', -2)'))
return false;
}
else
Tools::displayError('No currency mode for payment module');
// Insert countries availability
$return = Db::getInstance()->execute('
INSERT INTO `'._DB_PREFIX_.'module_country` (id_module, id_country)
SELECT '.(int)$this->id.', id_country FROM `'._DB_PREFIX_.'country` WHERE active = 1');
return $return;
}
public function uninstall()
{
if (!Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'module_country` WHERE id_module = '.(int)$this->id)
|| !Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'module_currency` WHERE id_module = '.(int)$this->id)
|| !Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'module_group` WHERE id_module = '.(int)$this->id))
return false;
return parent::uninstall();
}
/**
* Validate an order in database
* Function called from a payment module
*
* @param integer $id_cart Value
* @param integer $id_order_state Value
* @param float $amount_paid Amount really paid by customer (in the default currency)
* @param string $payment_method Payment method (eg. 'Credit card')
* @param string $message Message to attach to order
*/
public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown',
$message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false,
$secure_key = false, Shop $shop = null)
{
$cart = new Cart($id_cart);
$this->context->cart = $cart;
if (!$shop)
$shop = Context::getContext()->shop;
// Does order already exists ?
if (Validate::isLoadedObject($cart) && $cart->OrderExists() == false)
{
if ($secure_key !== false && $secure_key != $cart->secure_key)
die(Tools::displayError());
// For each package, generate an order
$delivery_option_list = $cart->getDeliveryOptionList();
$package_list = $cart->getPackageList();
$cart_delivery_option = $cart->getDeliveryOption();
// If some delivery options are not defined, or not valid, use the first valid option
foreach ($delivery_option_list as $id_address => $package)
if (!isset($cart_delivery_option[$id_address]) || !array_key_exists($cart_delivery_option[$id_address], $package))
foreach ($package as $key => $val)
{
$cart_delivery_option[$id_address] = $key;
break;
}
$order_list = array();
$order_detail_list = array();
$reference = Order::generateReference();
$this->currentOrderReference = $reference;
$id_currency = $currency_special ? (int)$currency_special : (int)$cart->id_currency;
$currency = new Currency($id_currency);
$cart->order_reference = $reference;
$order_creation_failed = false;
$cart_total_paid = (float)Tools::ps_round((float)$cart->getOrderTotal(true, Cart::BOTH), 2);
if ($cart->orderExists())
{
$error = Tools::displayError('An order has already been placed using this cart.');
Logger::addLog($error, 4, '0000001', 'Cart', intval($cart->id));
die($error);
}
$order_status = new OrderState((int)$id_order_state, (int)$cart->id_lang);
if (!Validate::isLoadedObject($order_status))
throw new PrestaShopException('Can\'t load Order state status');
foreach ($cart_delivery_option as $id_address => $key_carriers)
foreach ($delivery_option_list[$id_address][$key_carriers]['carrier_list'] as $id_carrier => $data)
foreach ($data['package_list'] as $id_package)
{
$product_list = $package_list[$id_address][$id_package]['product_list'];
$carrier = new Carrier($id_carrier, $cart->id_lang);
$order = new Order();
$order->id_carrier = (int)$carrier->id;
$order->id_customer = (int)$cart->id_customer;
$order->id_address_invoice = (int)$cart->id_address_invoice;
$order->id_address_delivery = (int)$id_address;
$order->id_currency = $id_currency;
$order->id_lang = (int)$cart->id_lang;
$order->id_cart = (int)$cart->id;
$order->reference = $reference;
$order->id_shop = (int)($shop->getID() ? $shop->getID() : $cart->id_shop);
$order->id_group_shop = (int)($shop->getID() ? $shop->getGroupID() : $cart->id_group_shop);
$customer = new Customer($order->id_customer);
$order->secure_key = ($secure_key ? pSQL($secure_key) : pSQL($customer->secure_key));
$order->payment = $payment_method;
if (isset($this->name))
$order->module = $this->name;
$order->recyclable = $cart->recyclable;
$order->gift = (int)$cart->gift;
$order->gift_message = $cart->gift_message;
$order->conversion_rate = $currency->conversion_rate;
$amount_paid = !$dont_touch_amount ? Tools::ps_round((float)$amount_paid, 2) : $amount_paid;
$order->total_paid_real = $amount_paid;
$order->total_products = (float)$cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $product_list, $id_carrier);
$order->total_products_wt = (float)$cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $product_list, $id_carrier);
$order->total_discounts = (float)abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list, $id_carrier));
$order->total_discounts_tax_excl = (float)abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $product_list, $id_carrier));
$order->total_discounts_tax_incl = (float)abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list, $id_carrier));
$order->total_shipping = (float)$cart->getPackageShippingCost((int)$id_carrier, true, null, $product_list, $id_carrier);
$order->total_shipping_tax_excl = (float)$cart->getPackageShippingCost((int)$id_carrier, false, null, $product_list, $id_carrier);
$order->total_shipping_tax_incl = (float)$cart->getPackageShippingCost((int)$id_carrier, true, null, $product_list, $id_carrier);
if (Validate::isLoadedObject($carrier))
$order->carrier_tax_rate = $carrier->getTaxesRate(new Address($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$order->total_wrapping = (float)abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $product_list, $id_carrier));
$order->total_wrapping_tax_excl = (float)abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $product_list, $id_carrier));
$order->total_wrapping_tax_incl = (float)abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $product_list, $id_carrier));
$order->total_paid = (float)Tools::ps_round((float)$cart->getOrderTotal(true, Cart::BOTH, $product_list, $id_carrier), 2);
$order->total_paid_tax_excl = (float)Tools::ps_round((float)$cart->getOrderTotal(false, Cart::BOTH, $product_list, $id_carrier), 2);
$order->total_paid_tax_incl = (float)Tools::ps_round((float)$cart->getOrderTotal(true, Cart::BOTH, $product_list, $id_carrier), 2);
$order->invoice_date = '0000-00-00 00:00:00';
$order->delivery_date = '0000-00-00 00:00:00';
// Amount paid by customer is not the right one -> Status = payment error
// We don't use the following condition to avoid the float precision issues : http://www.php.net/manual/en/language.types.float.php
// if ($order->total_paid != $order->total_paid_real)
// We use number_format in order to compare two string
if (number_format($cart_total_paid, 2) != number_format($order->total_paid_real, 2))
$id_order_state = Configuration::get('PS_OS_ERROR');
// Creating order
$result = $order->add();
// Register Payment only if the order status validate the order
if ($result && $order_status->logable)
{
if (!$order->addOrderPayment($amount_paid))
throw new PrestaShopException('Can\'t save Order Payment');
}
$order_list[] = $order;
// Insert new Order detail list using cart for the current order
$order_detail = new OrderDetail(null, null, $this->context);
$order_detail->createList($order, $cart, $id_order_state, $product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
$order_detail_list[] = $order_detail;
// Adding an entry in order_carrier table
$order_carrier = new OrderCarrier();
$order_carrier->id_order = (int)$order->id;
$order_carrier->id_carrier = (int)$carrier->id;
$order_carrier->weight = (float)$order->getTotalWeight();
$order_carrier->shipping_cost_tax_excl = (float)$order->total_shipping_tax_excl;
$order_carrier->shipping_cost_tax_incl = (float)$order->total_shipping_tax_incl;
$order_carrier->add();
}
// Next !
foreach ($order_detail_list as $key => $order_detail)
{
$order = $order_list[$key];
if (!$order_creation_failed & isset($order->id))
{
if (!$secure_key)
$message .= '
'.Tools::displayError('Warning : the secure key is empty, check your payment account before validation');
// Optional message to attach to this order
if (isset($message) & !empty($message))
{
$msg = new Message();
$message = strip_tags($message, '
');
if (Validate::isCleanHtml($message))
{
$msg->message = $message;
$msg->id_order = intval($order->id);
$msg->private = 1;
$msg->add();
}
}
// Insert new Order detail list using cart for the current order
//$orderDetail = new OrderDetail(null, null, $this->context);
//$orderDetail->createList($order, $cart, $id_order_state);
// Construct order detail table for the email
$products_list = '';
$products = $cart->getProducts();
foreach ($products as $key => $product)
{
$price = Product::getPriceStatic((int)$product['id_product'], false, ($product['id_product_attribute'] ? (int)$product['id_product_attribute'] : null), 6, null, false, true, $product['cart_quantity'], false, (int)$order->id_customer, (int)$order->id_cart, (int)$order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
$price_wt = Product::getPriceStatic((int)$product['id_product'], true, ($product['id_product_attribute'] ? (int)$product['id_product_attribute'] : null), 2, null, false, true, $product['cart_quantity'], false, (int)$order->id_customer, (int)$order->id_cart, (int)$order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
$customization_quantity = 0;
if (isset($customized_datas[$product['id_product']][$product['id_product_attribute']]))
{
$customization_text = '';
foreach ($customized_datas[$product['id_product']][$product['id_product_attribute']] as $customization)
{
if (isset($customization['datas'][Product::CUSTOMIZE_TEXTFIELD]))
foreach ($customization['datas'][Product::CUSTOMIZE_TEXTFIELD] as $text)
$customization_text .= $text['name'].': '.$text['value'].'
';
if (isset($customization['datas'][Product::CUSTOMIZE_FILE]))
$customization_text .= count($customization['datas'][Product::CUSTOMIZE_FILE]).' '.Tools::displayError('image(s)').'
';
$customization_text .= '---
';
}
$customization_text = rtrim($customization_text, '---
');
$customization_quantity = (int)$product['customizationQuantityTotal'];
$products_list .=
'