diff options
Diffstat (limited to 'public/catalog/model/extension/payment/klarna_account.php')
-rw-r--r-- | public/catalog/model/extension/payment/klarna_account.php | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/public/catalog/model/extension/payment/klarna_account.php b/public/catalog/model/extension/payment/klarna_account.php new file mode 100644 index 0000000..93a1610 --- /dev/null +++ b/public/catalog/model/extension/payment/klarna_account.php @@ -0,0 +1,213 @@ +<?php +class ModelExtensionPaymentKlarnaAccount extends Model { + public function getMethod($address, $total) { + $this->load->language('extension/payment/klarna_account'); + + $status = true; + + $klarna_account = $this->config->get('payment_klarna_account'); + + if (!isset($klarna_account[$address['iso_code_3']])) { + $status = false; + } elseif (!$klarna_account[$address['iso_code_3']]['status']) { + $status = false; + } + + if ($status) { + $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$klarna_account[$address['iso_code_3']]['geo_zone_id'] . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')"); + + if ($klarna_account[$address['iso_code_3']]['total'] > 0 && $klarna_account[$address['iso_code_3']]['total'] > $total) { + $status = false; + } elseif (!$klarna_account[$address['iso_code_3']]['geo_zone_id']) { + $status = true; + } elseif ($query->num_rows) { + $status = true; + } else { + $status = false; + } + + // Maps countries to currencies + $country_to_currency = array( + 'NOR' => 'NOK', + 'SWE' => 'SEK', + 'FIN' => 'EUR', + 'DNK' => 'DKK', + 'DEU' => 'EUR', + 'NLD' => 'EUR' + ); + + if (!isset($country_to_currency[$address['iso_code_3']]) || !$this->currency->has($country_to_currency[$address['iso_code_3']])) { + $status = false; + } + + if ($address['iso_code_3'] == 'NLD' && $this->currency->has('EUR') && $this->currency->format($total, 'EUR', '', false) > 250.00) { + $status = false; + } + } + + $payment_option = array(); + + if ($status) { + $total = $this->currency->format($total, $country_to_currency[$address['iso_code_3']], '', false); + + $pclasses = $this->config->get('klarna_account_pclasses'); + + if (isset($pclasses[$address['iso_code_3']])) { + $pclasses = $pclasses[$address['iso_code_3']]; + } else { + $pclasses = array(); + } + + foreach ($pclasses as $pclass) { + // 0 - Campaign + // 1 - Account + // 2 - Special + // 3 - Fixed + if (!in_array($pclass['type'], array(0, 1, 3))) { + continue; + } + + if ($pclass['type'] == 2) { + $monthly_cost = -1; + } else { + if ($total < $pclass['minamount']) { + continue; + } + + if ($pclass['type'] == 3) { + continue; + } else { + $sum = $total; + + $lowest_payment = $this->getLowestPaymentAccount($address['iso_code_3']); + $monthly_cost = 0; + + $monthly_fee = $pclass['invoicefee']; + $start_fee = $pclass['startfee']; + + $sum += $start_fee; + + $base = ($pclass['type'] == 1); + + $minimum_payment = ($pclass['type'] === 1) ? $this->getLowestPaymentAccount($address['iso_code_3']) : 0; + + if ($pclass['months'] == 0) { + $payment = $sum; + } elseif ($pclass['interestrate'] == 0) { + $payment = $sum / $pclass['months']; + } else { + $interest_rate = $pclass['interestrate'] / (100.0 * 12); + + $payment = $sum * $interest_rate / (1 - pow((1 + $interest_rate), -$pclass['months'])); + } + + $payment += $monthly_fee; + + $balance = $sum; + $pay_data = array(); + + $months = $pclass['months']; + + while (($months != 0) && ($balance > 0.01)) { + $interest = $balance * $pclass['interestrate'] / (100.0 * 12); + $new_balance = $balance + $interest + $monthly_fee; + + if ($minimum_payment >= $new_balance || $payment >= $new_balance) { + $pay_data[] = $new_balance; + break; + } + + $new_payment = max($payment, $minimum_payment); + + if ($base) { + $new_payment = max($new_payment, $balance / 24.0 + $monthly_fee + $interest); + } + + $balance = $new_balance - $new_payment; + + $pay_data[] = $new_payment; + + $months -= 1; + } + + $monthly_cost = round(isset($pay_data[0]) ? ($pay_data[0]) : 0, 2); + + if ($monthly_cost < 0.01) { + continue; + } + + if ($pclass['type'] == 1 && $monthly_cost < $lowest_payment) { + $monthly_cost = $lowest_payment; + } + + if ($pclass['type'] == 0 && $monthly_cost < $lowest_payment) { + continue; + } + } + } + + $payment_option[$pclass['id']]['monthly_cost'] = $monthly_cost; + $payment_option[$pclass['id']]['pclass_id'] = $pclass['id']; + $payment_option[$pclass['id']]['months'] = $pclass['months']; + } + } + + if (!$payment_option) { + $status = false; + } + + $sort_order = array(); + + foreach ($payment_option as $key => $value) { + $sort_order[$key] = $value['monthly_cost']; + } + + array_multisort($sort_order, SORT_ASC, $payment_option); + + if ($address['company']) { + $status = false; + } + + $method = array(); + + if ($status) { + $method = array( + 'code' => 'klarna_account', + 'title' => sprintf($this->language->get('text_title'), $this->currency->format($this->currency->convert($payment_option[0]['monthly_cost'], $country_to_currency[$address['iso_code_3']], $this->session->data['currency']), 1, 1)), + 'terms' => sprintf($this->language->get('text_terms'), $klarna_account[$address['iso_code_3']]['merchant'], strtolower($address['iso_code_2'])), + 'sort_order' => $klarna_account[$address['iso_code_3']]['sort_order'], + ); + } + + return $method; + } + + private function getLowestPaymentAccount($country) { + switch ($country) { + case 'SWE': + $amount = 50.0; + break; + case 'NOR': + $amount = 95.0; + break; + case 'FIN': + $amount = 8.95; + break; + case 'DNK': + $amount = 89.0; + break; + case 'DEU': + case 'NLD': + $amount = 6.95; + break; + default: + $log = new Log('klarna_account.log'); + $log->write('Unknown country ' . $country); + + $amount = null; + break; + } + + return $amount; + } +}
\ No newline at end of file |