ControllerExtensionPaymentKlarnaCheckout::addressUpdate PHP Method

addressUpdate() public method

public addressUpdate ( )
    public function addressUpdate()
    {
        $this->load->language('extension/payment/klarna_checkout');
        $this->load->model('account/customer');
        $this->load->model('checkout/order');
        $this->load->model('extension/payment/klarna_checkout');
        $this->load->model('localisation/zone');
        if (!$this->config->get('klarna_checkout_status')) {
            return false;
        }
        $process = true;
        $request = json_decode(file_get_contents('php://input'));
        $json = array();
        $http_response_code = 400;
        // Check to see if request data is complete
        if (!$request || !isset($request->order_lines) || empty($request->order_lines) || !isset($request->shipping_address) || empty($request->shipping_address)) {
            $this->model_extension_payment_klarna_checkout->log('Request data incomplete. Full request below:');
            $this->model_extension_payment_klarna_checkout->log($request);
            $process = false;
        }
        // Get Klarna order info from db
        if ($process) {
            $order_id = null;
            foreach ($request->order_lines as $order_line) {
                if ($order_line->type == 'physical' || $order_line->type == 'digital' || $order_line->type == 'gift_card') {
                    $order_id = $this->encryption->decrypt($order_line->merchant_data);
                    break;
                }
            }
            if ($order_id) {
                // Get klarna order data from db
                $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrderByOrderId($order_id);
                if (!$klarna_checkout_order || !$klarna_checkout_order['data']) {
                    $this->model_extension_payment_klarna_checkout->log('No klarna order found using order_id: ' . $order_id);
                    $process = false;
                }
            } else {
                $process = false;
            }
        }
        if ($process) {
            $klarna_checkout_order_data = json_decode($this->encryption->decrypt($klarna_checkout_order['data']), true);
            // Check credentials in request with ones stored in db
            $valid_request = false;
            foreach ($this->config->get('klarna_checkout_account') as $account) {
                if ($account['merchant_id'] == $klarna_checkout_order_data['merchant_id'] && $account['secret'] == $klarna_checkout_order_data['secret']) {
                    $valid_request = true;
                    break;
                }
            }
            if (!$valid_request) {
                $this->model_extension_payment_klarna_checkout->log('Cannot validate request. Terminating.');
                $process = false;
            }
        }
        // Request is valid, we can spoof/simulate the customer to calculate shipping
        if ($process) {
            session_destroy();
            session_id($klarna_checkout_order_data['session_id']);
            session_start();
            $this->session->start('default', $klarna_checkout_order_data['session_key']);
            if ($klarna_checkout_order_data['customer_id']) {
                $customer_info = $this->model_account_customer->getCustomer($klarna_checkout_order_data['customer_id']);
                if ($customer_info) {
                    $this->customer->login($customer_info['email'], '', true);
                }
            }
            $order_info = $this->model_checkout_order->getOrder($order_id);
            if (!$order_info) {
                $this->model_extension_payment_klarna_checkout->log('No order found using order_id: ' . $order_id . '. Full request below:');
                $this->model_extension_payment_klarna_checkout->log($request);
                $process = false;
            }
            // Set more session data from the order
            $this->session->data['currency'] = $order_info['currency_code'];
            $this->session->data['language'] = $order_info['language_code'];
            $country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($request->shipping_address->country);
            if (!$country_info) {
                $this->model_extension_payment_klarna_checkout->log('No country found using: ' . $request->shipping_address->country . '. Full request below:');
                $this->model_extension_payment_klarna_checkout->log($request);
            }
            if ($order_info && $country_info) {
                $zones = $this->model_localisation_zone->getZonesByCountryId($country_info['country_id']);
                $zone = array();
                if (isset($request->shipping_address->region) && !empty($request->shipping_address->region)) {
                    $zone = $this->model_extension_payment_klarna_checkout->getZoneByCode($request->shipping_address->region, $country_info['country_id']);
                }
                if ($zone || $zones) {
                    $this->session->data['shipping_address'] = array('address_id' => null, 'firstname' => null, 'lastname' => null, 'company' => null, 'address_1' => null, 'address_2' => null, 'postcode' => null, 'city' => null, 'zone_id' => $zone ? $zone['zone_id'] : $zones[0]['zone_id'], 'zone' => $zone ? $zone['name'] : $zones[0]['name'], 'zone_code' => $zone ? $zone['code'] : $zones[0]['code'], 'country_id' => $country_info['country_id'], 'country' => $country_info['name'], 'iso_code_2' => $country_info['iso_code_2'], 'iso_code_3' => $country_info['iso_code_3'], 'address_format' => '', 'custom_field' => array());
                    $this->session->data['klarna_checkout_data'] = array('email' => $request->billing_address->email, 'firstname' => $request->billing_address->given_name, 'lastname' => $request->billing_address->family_name, 'telephone' => $request->billing_address->phone, 'iso_code_2' => $this->session->data['shipping_address']['iso_code_2'], 'zone_code' => $this->session->data['shipping_address']['zone_code']);
                    // Unset $tax_rates
                    $this->tax->unsetRates();
                    $this->tax->setShippingAddress($country_info['country_id'], $zone ? $zone['zone_id'] : $zones[0]['zone_id']);
                    $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id'));
                    //Check if customer is US. If so, send taxes differently
                    if ($this->session->data['shipping_address']['iso_code_2'] === 'US') {
                        $include_taxes = false;
                    } else {
                        $include_taxes = true;
                    }
                    $method_data = array();
                    $this->load->model('extension/extension');
                    $results = $this->model_extension_extension->getExtensions('shipping');
                    foreach ($results as $result) {
                        if ($this->config->get($result['code'] . '_status')) {
                            $this->load->model('extension/shipping/' . $result['code']);
                            $quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($this->session->data['shipping_address']);
                            if ($quote) {
                                $method_data[$result['code']] = array('title' => $quote['title'], 'quote' => $quote['quote'], 'sort_order' => $quote['sort_order'], 'error' => $quote['error']);
                            }
                        }
                    }
                    $sort_order = array();
                    foreach ($method_data as $key => $value) {
                        $sort_order[$key] = $value['sort_order'];
                    }
                    array_multisort($sort_order, SORT_ASC, $method_data);
                    $shipping_methods = $method_data;
                    if ($shipping_methods) {
                        list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $this->session->data['currency']);
                        if ($klarna_account && $connector) {
                            list($klarna_order_data, $encrypted_order_data) = $this->klarnaOrderData($klarna_account);
                            if ($this->cart->hasShipping()) {
                                $shipping_method = array();
                                if (isset($this->session->data['shipping_method']) && !empty($this->session->data['shipping_method'])) {
                                    foreach ($shipping_methods as $individual_shipping_method) {
                                        if ($individual_shipping_method['quote']) {
                                            foreach ($individual_shipping_method['quote'] as $quote) {
                                                if ($this->session->data['shipping_method']['code'] == $quote['code'] && $this->session->data['shipping_method']['title'] == $quote['title'] && $this->session->data['shipping_method']['cost'] == $quote['cost'] && $this->session->data['shipping_method']['tax_class_id'] == $quote['tax_class_id']) {
                                                    $shipping_method = $quote;
                                                    break 2;
                                                }
                                            }
                                        }
                                    }
                                }
                                // If the current shipping method isn't in the available shipping methods, assign default
                                if (!$shipping_method) {
                                    $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($shipping_methods);
                                }
                                $total_amount = $this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], $include_taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100;
                                if ($include_taxes) {
                                    $total_tax_amount = $this->currency->format($this->tax->getTax($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id']), $order_info['currency_code'], $order_info['currency_value'], false) * 100;
                                } else {
                                    $total_tax_amount = 0;
                                }
                                $total_sub_amount = $this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], false), $order_info['currency_code'], $order_info['currency_value'], false) * 100;
                                $tax_rate = 0;
                                if ($include_taxes && $total_tax_amount && $total_sub_amount) {
                                    $tax_rate = $total_tax_amount / $total_sub_amount * 100;
                                }
                                foreach ($klarna_order_data['order_lines'] as $key => $order_line) {
                                    if ($order_line['type'] == 'shipping_fee') {
                                        unset($klarna_order_data['order_lines'][$key]);
                                        break;
                                    }
                                }
                                $klarna_order_data['order_lines'][] = array('type' => 'shipping_fee', 'name' => $this->session->data['shipping_method']['title'], 'quantity' => '1', 'unit_price' => round($this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], $include_taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'tax_rate' => round($tax_rate * 100), 'total_amount' => round($total_amount), 'total_tax_amount' => round($total_tax_amount), 'total_discount_amount' => 0);
                            }
                            list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals();
                            //If $include_taxes is false, means customer is US so we add a new sales_tax order line with all the tax
                            if (!$include_taxes) {
                                foreach ($klarna_order_data['order_lines'] as $key => $order_line) {
                                    if ($order_line['type'] == 'sales_tax') {
                                        unset($klarna_order_data['order_lines'][$key]);
                                        break;
                                    }
                                }
                                $klarna_order_data['order_lines'][] = array('type' => 'sales_tax', 'name' => $this->language->get('text_sales_tax'), 'quantity' => '1', 'unit_price' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'tax_rate' => 0, 'total_amount' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'total_tax_amount' => 0, 'total_discount_amount' => 0);
                            }
                            $http_response_code = 200;
                            $json = array('order_amount' => round($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'order_tax_amount' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'order_lines' => array_values($klarna_order_data['order_lines']));
                        }
                    }
                }
            }
        }
        $this->model_extension_payment_klarna_checkout->log($http_response_code);
        $this->model_extension_payment_klarna_checkout->log($json);
        http_response_code($http_response_code);
        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($json));
    }