/**
  * Create or Updates Prestashop address
  * @return Address Address object
  */
 protected function createAddress($addressInformations, $address = null)
 {
     $country = $this->getCountryByCode($addressInformations->country->alpha2Code);
     if (!$country->active) {
         $this->addError(sprintf($this->module->l('This country is not active : %s'), $addressInformations->country->alpha2Code), PowaTagErrorType::$MERCHANT_WRONG_COUNTRY);
         return false;
     }
     if (!isset($addressInformations->friendlyName)) {
         $friendlyName = $this->module->l('My address');
     } else {
         $friendlyName = $addressInformations->friendlyName;
     }
     if (PowaTagAPI::apiLog()) {
         PowaTagLogs::initAPILog('Create address', PowaTagLogs::IN_PROGRESS, $addressInformations->lastName . ' ' . $addressInformations->firstName . ' : ' . $friendlyName);
     }
     $address = $address != null ? $address : Address::initialize();
     $address->id_customer = (int) $this->customer->id;
     $address->id_country = (int) $country->id;
     $address->alias = $friendlyName;
     $address->lastname = $addressInformations->lastName;
     $address->firstname = $addressInformations->firstName;
     $address->address1 = $addressInformations->line1;
     $address->address2 = $addressInformations->line2;
     $address->postcode = $addressInformations->postCode;
     $address->city = $addressInformations->city;
     $address->phone = isset($addressInformations->phone) ? $addressInformations->phone : '0000000000';
     $address->id_state = isset($addressInformations->state) ? (int) State::getIdByIso($addressInformations->state, (int) $country->id) : 0;
     if (!$address->save()) {
         $this->addError($this->module->l('Impossible to save address'), PowaTagErrorType::$INTERNAL_ERROR);
         if (PowaTagAPI::apiLog()) {
             PowaTagLogs::initAPILog('Create address', PowaTagLogs::ERROR, $this->error['message']);
         }
         return false;
     }
     if (PowaTagAPI::apiLog()) {
         PowaTagLogs::initAPILog('Create address', PowaTagLogs::SUCCESS, 'Address ID : ' . $address->id);
     }
     return $address;
 }
 /**
  * Orders endpoint
  */
 protected function orders($args)
 {
     // Manage informations
     $datas = $this->data;
     if (is_null($datas)) {
         $error = PowaTagErrorType::$BAD_REQUEST;
         return PowaTagAPI::powaError($error);
     }
     if ($this->verb == 'costs') {
         if (isset($datas->order)) {
             $customer = $datas->order->customer;
         } else {
             $customer = current($datas->orders)->customer;
         }
         if (PowaTagAPI::apiLog()) {
             PowaTagLogs::initAPILog('Process calculate Costs', PowaTagLogs::IN_PROGRESS, 'Customer : ' . $customer->firstName . ' ' . $customer->lastName);
         }
         if (PowaTagAPI::requestLog()) {
             PowaTagLogs::initRequestLog('Process calculate Costs', PowaTagLogs::IN_PROGRESS, $datas);
         }
         $powatagcosts = new PowaTagCosts($datas);
         if ($error = $powatagcosts->getError()) {
             $message = $error['message'];
             if (PowaTagAPI::apiLog()) {
                 PowaTagLogs::initAPILog('Process order', PowaTagLogs::ERROR, $message);
             }
             return PowaTagAPI::powaError($error);
         }
         if ($value = $powatagcosts->getSummary()) {
             if (PowaTagAPI::apiLog()) {
                 PowaTagLogs::initAPILog('Process calculate Costs', PowaTagLogs::SUCCESS, 'Customer : ' . $customer->firstName . ' ' . $customer->lastName);
             }
             if (PowaTagAPI::requestLog()) {
                 PowaTagLogs::initRequestLog('Process calculate Costs', PowaTagLogs::SUCCESS, $value);
             }
             return $value;
         } else {
             $error = $powatagcosts->getError();
             if (PowaTagAPI::apiLog()) {
                 PowaTagLogs::initAPILog('Process calculate Costs', PowaTagLogs::ERROR, $error['message']);
             }
             return PowaTagAPI::powaError($error);
         }
     } else {
         if (count($args) == 2 && Validate::isInt($args[0]) && ($args[1] = 'confirm-payment')) {
             //Three step payment confirmation
             if (PowaTagAPI::apiLog()) {
                 PowaTagLogs::initAPILog('Process payment', PowaTagLogs::IN_PROGRESS, 'Order ID : ' . $args[0]);
             }
             if (PowaTagAPI::requestLog()) {
                 PowaTagLogs::initRequestLog('Create payment', PowaTagLogs::IN_PROGRESS, $datas);
             }
             $payment = new PowaTagPayment($datas, (int) $args[0]);
             if ($id_order = $payment->confirmPayment()) {
                 if (PowaTagAPI::apiLog()) {
                     PowaTagLogs::initAPILog('Process payment', PowaTagLogs::SUCCESS, 'ID Order : ' . $id_order);
                 }
                 if (PowaTagAPI::requestLog()) {
                     PowaTagLogs::initRequestLog('Process payment', PowaTagLogs::SUCCESS, $id_order);
                 }
                 $data = array('providerTxCode' => isset($datas->paymentResult->providerTxCode) ? $datas->paymentResult->providerTxCode : 'providerTxCode Empty', 'message' => 'Authorization success order ' . $id_order . ' created');
                 if ($payment->checkOrderState($id_order, $data) == 'error') {
                     $this->setResponse($data['response']);
                 }
                 return $data;
             } else {
                 $error = $payment->getError();
                 if (PowaTagAPI::apiLog()) {
                     PowaTagLogs::initAPILog('Process payment', PowaTagLogs::ERROR, $error['message']);
                 }
                 return PowaTagAPI::powaError($error);
             }
         } else {
             if (!count($args)) {
                 //Two step payment or three step payment
                 if (isset($datas->order)) {
                     $customer = $datas->order->customer;
                 } else {
                     $customer = current($datas->orders)->customer;
                 }
                 if (PowaTagAPI::apiLog()) {
                     PowaTagLogs::initAPILog('Process order 123', PowaTagLogs::IN_PROGRESS, 'Customer : ' . $customer->firstName . ' ' . $customer->lastName);
                 }
                 if (PowaTagAPI::requestLog()) {
                     PowaTagLogs::initRequestLog('Create order', PowaTagLogs::IN_PROGRESS, $datas);
                 }
                 $order = new PowaTagOrders($datas);
                 if ($error = $order->getError()) {
                     $message = $error['message'];
                     if (PowaTagAPI::apiLog()) {
                         PowaTagLogs::initAPILog('Process order', PowaTagLogs::ERROR, $message);
                     }
                     return PowaTagAPI::powaError($error);
                 }
                 list($id_cart, $id_order, $message) = $order->validateOrder();
                 if ($id_order || $id_cart) {
                     if (PowaTagAPI::apiLog()) {
                         PowaTagLogs::initAPILog('Process order', PowaTagLogs::SUCCESS, 'Order has been created : ' . $id_order);
                     }
                     $link = new Link();
                     $cart = new Cart($id_cart);
                     $data = array('orderResults' => array(array('orderId' => $id_order ? $id_order : $id_cart, 'message' => $message, 'redirectUrl' => $link->getModuleLink('powatag', 'confirmation', array('id_cart' => (int) $id_cart, 'id_customer' => (int) $cart->id_customer)))));
                     if ($error = $order->getError()) {
                         return PowaTagAPI::powaError($error);
                     }
                     if ($order->checkOrderState($id_order, $data)) {
                         $this->setResponse($data['response']);
                     }
                     return $data;
                 } else {
                     $message = '';
                     $errorCode = '';
                     if ($error = $order->getError()) {
                         $message = $error['message'];
                     }
                     if (PowaTagAPI::apiLog()) {
                         PowaTagLogs::initAPILog('Process order', PowaTagLogs::ERROR, $message);
                     }
                     return PowaTagAPI::powaError($error);
                 }
             }
         }
     }
 }
 /**
  * Add Products to cart
  * @param Cart $cart Cart object
  */
 private function addProductsToCart($cart, $codeCountry)
 {
     $products = $this->datas->orderLineItems;
     $country = $this->getCountry($codeCountry);
     $address = Address::initialize();
     $address->id_country = $country->id;
     if ($products && count($products)) {
         foreach ($products as $p) {
             if (PowaTagAPI::apiLog()) {
                 PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::IN_PROGRESS, 'Product : ' . $p->product->code);
             }
             $product = PowaTagProductHelper::getProductByCode($p->product->code, $this->context->language->id);
             if (!Validate::isLoadedObject($product)) {
                 $this->addError(sprintf($this->module->l('This product does not exists : %s'), $p->product->code), PowaTagErrorType::$SKU_NOT_FOUND);
                 if (PowaTagAPI::apiLog()) {
                     PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::ERROR, 'Product : ' . $this->error['message']);
                 }
                 return false;
             }
             $variants = $p->product->productVariants;
             $product_rate = 1 + $product->getTaxesRate($address) / 100;
             foreach ($variants as $variant) {
                 $variantCurrency = $this->getCurrencyByIsoCode($variant->finalPrice->currency);
                 if (!PowaTagValidate::currencyEnable($variantCurrency)) {
                     $this->addError(sprintf($this->module->l('Currency not found : %s'), $variant->code), PowaTagErrorType::$CURRENCY_NOT_SUPPORTED);
                     if (PowaTagAPI::apiLog()) {
                         PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::ERROR, 'Product : ' . $this->error['message']);
                     }
                     return false;
                 }
                 $variantAmount = $variant->finalPrice->amount;
                 $id_product_attribute = false;
                 $combination = false;
                 if ($id_product_attribute = PowaTagProductAttributeHelper::getCombinationByCode($product->id, $variant->code)) {
                     $combination = new Combination($id_product_attribute);
                     $priceAttribute = $product->getPrice($this->display_taxes, $id_product_attribute);
                     $qtyInStock = PowaTagProductQuantityHelper::getProductQuantity($product, $id_product_attribute);
                 } else {
                     if ($product) {
                         $priceAttribute = $product->getPrice($this->display_taxes);
                         $qtyInStock = PowaTagProductQuantityHelper::getProductQuantity($product);
                     } else {
                         $this->addError(sprintf($this->module->l('This variant does not exist : %s'), $variant->code), PowaTagErrorType::$SKU_NOT_FOUND);
                         if (PowaTagAPI::apiLog()) {
                             PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::ERROR, 'Product : ' . $this->error['message']);
                         }
                         return false;
                     }
                 }
                 if ($qtyInStock == 0) {
                     $this->addError(sprintf($this->module->l('No Stock Available')), PowaTagErrorType::$SKU_OUT_OF_STOCK);
                     if (PowaTagAPI::apiLog()) {
                         PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::ERROR, 'Product : ' . $this->error['message']);
                     }
                     return false;
                 }
                 if ($qtyInStock < $p->quantity) {
                     $this->addError(sprintf($this->module->l('Quantity > Stock Count')), PowaTagErrorType::$INSUFFICIENT_STOCK);
                     if (PowaTagAPI::apiLog()) {
                         PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::ERROR, 'Product : ' . $this->error['message']);
                     }
                     return false;
                 }
                 if ($p->quantity < $product->minimal_quantity || $combination && $combination->minimal_quantity > $p->quantity) {
                     $this->addError(sprintf($this->module->l('Quantity < minimal quantity for product')), PowaTagErrorType::$OTHER_STOCK_ERROR);
                     if (PowaTagAPI::apiLog()) {
                         PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::ERROR, 'Product : ' . $this->error['message']);
                     }
                     return false;
                 }
                 $cart->updateQty($p->quantity, $product->id, $id_product_attribute);
                 if (PowaTagAPI::apiLog()) {
                     PowaTagLogs::initAPILog('Add product to cart', PowaTagLogs::SUCCESS, 'Cart ID : ' . $cart->id . ' - Product ID : ' . $product->id);
                 }
                 break;
             }
         }
     } else {
         $this->addError($this->module->l('No product found in request'), PowaTagErrorType::$SKU_NOT_FOUND);
         return false;
     }
     // add vouchers
     if (isset($this->datas->vouchers)) {
         $this->context->cart = $cart;
         $vouchers = $this->datas->vouchers;
         if ($vouchers && count($vouchers)) {
             foreach ($vouchers as $voucher) {
                 $ci = CartRule::getIdByCode($voucher);
                 if (!$ci) {
                     continue;
                 }
                 $cr = new CartRule($ci);
                 if (!$cr) {
                     continue;
                 }
                 if ($error = $cr->checkValidity($this->context, false, true)) {
                     continue;
                 }
                 $this->context->cart->addCartRule($cr->id);
                 if (PowaTagAPI::apiLog()) {
                     PowaTagLogs::initAPILog('Added voucher', PowaTagLogs::SUCCESS, 'Cart ID : ' . $cart->id . ' - Voucher : ' . $voucher);
                 }
             }
         }
     }
     return true;
 }
 private function checkTotalToPaid($amountPaid, $currency)
 {
     if (!$currency instanceof Currency) {
         if (Validate::isInt($currency)) {
             $currency = new Currency((int) $currency);
         } else {
             $currencyCode = $currency;
             if (!($currency = PowaTagPayment::getCurrencyByIsoCode($currency))) {
                 $currency = $currencyCode;
             }
         }
     }
     if (!PowaTagValidate::currencyEnable($currency)) {
         $this->addError(sprintf($this->module->l('Currency is not enable : %s'), isset($currency->iso_code) ? $currency->iso_code : $currency), PowaTagErrorType::$CURRENCY_NOT_SUPPORTED);
         return false;
     }
     //We change context currency to be sure that calculs are made with correct currency
     $context = Context::getContext();
     $context->currency = $currency;
     $context->country = $this->getCountry($this->datas->customer->shippingAddress->country->alpha2Code);
     $price_cart = $this->cart->getOrderTotal(true, Cart::BOTH, null, Configuration::get('POWATAG_SHIPPING'));
     if (abs($price_cart - $amountPaid) >= 0.01) {
         $msg = "Cart: " . $price_cart . " != Payment: " . $amountPaid;
         $this->addError($this->module->l('Amount paid is not same as the cart: ' . $msg), PowaTagErrorType::$INTERNAL_ERROR);
         if (PowaTagAPI::apiLog()) {
             PowaTagLogs::initAPILog('Amount paid is not same as the cart', PowaTagLogs::ERROR, $msg);
         }
         return false;
     }
     return true;
 }