klarna_account.php (5935B)
1 <?php 2 class ModelExtensionPaymentKlarnaAccount extends Model { 3 public function getMethod($address, $total) { 4 $this->load->language('extension/payment/klarna_account'); 5 6 $status = true; 7 8 $klarna_account = $this->config->get('payment_klarna_account'); 9 10 if (!isset($klarna_account[$address['iso_code_3']])) { 11 $status = false; 12 } elseif (!$klarna_account[$address['iso_code_3']]['status']) { 13 $status = false; 14 } 15 16 if ($status) { 17 $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')"); 18 19 if ($klarna_account[$address['iso_code_3']]['total'] > 0 && $klarna_account[$address['iso_code_3']]['total'] > $total) { 20 $status = false; 21 } elseif (!$klarna_account[$address['iso_code_3']]['geo_zone_id']) { 22 $status = true; 23 } elseif ($query->num_rows) { 24 $status = true; 25 } else { 26 $status = false; 27 } 28 29 // Maps countries to currencies 30 $country_to_currency = array( 31 'NOR' => 'NOK', 32 'SWE' => 'SEK', 33 'FIN' => 'EUR', 34 'DNK' => 'DKK', 35 'DEU' => 'EUR', 36 'NLD' => 'EUR' 37 ); 38 39 if (!isset($country_to_currency[$address['iso_code_3']]) || !$this->currency->has($country_to_currency[$address['iso_code_3']])) { 40 $status = false; 41 } 42 43 if ($address['iso_code_3'] == 'NLD' && $this->currency->has('EUR') && $this->currency->format($total, 'EUR', '', false) > 250.00) { 44 $status = false; 45 } 46 } 47 48 $payment_option = array(); 49 50 if ($status) { 51 $total = $this->currency->format($total, $country_to_currency[$address['iso_code_3']], '', false); 52 53 $pclasses = $this->config->get('klarna_account_pclasses'); 54 55 if (isset($pclasses[$address['iso_code_3']])) { 56 $pclasses = $pclasses[$address['iso_code_3']]; 57 } else { 58 $pclasses = array(); 59 } 60 61 foreach ($pclasses as $pclass) { 62 // 0 - Campaign 63 // 1 - Account 64 // 2 - Special 65 // 3 - Fixed 66 if (!in_array($pclass['type'], array(0, 1, 3))) { 67 continue; 68 } 69 70 if ($pclass['type'] == 2) { 71 $monthly_cost = -1; 72 } else { 73 if ($total < $pclass['minamount']) { 74 continue; 75 } 76 77 if ($pclass['type'] == 3) { 78 continue; 79 } else { 80 $sum = $total; 81 82 $lowest_payment = $this->getLowestPaymentAccount($address['iso_code_3']); 83 $monthly_cost = 0; 84 85 $monthly_fee = $pclass['invoicefee']; 86 $start_fee = $pclass['startfee']; 87 88 $sum += $start_fee; 89 90 $base = ($pclass['type'] == 1); 91 92 $minimum_payment = ($pclass['type'] === 1) ? $this->getLowestPaymentAccount($address['iso_code_3']) : 0; 93 94 if ($pclass['months'] == 0) { 95 $payment = $sum; 96 } elseif ($pclass['interestrate'] == 0) { 97 $payment = $sum / $pclass['months']; 98 } else { 99 $interest_rate = $pclass['interestrate'] / (100.0 * 12); 100 101 $payment = $sum * $interest_rate / (1 - pow((1 + $interest_rate), -$pclass['months'])); 102 } 103 104 $payment += $monthly_fee; 105 106 $balance = $sum; 107 $pay_data = array(); 108 109 $months = $pclass['months']; 110 111 while (($months != 0) && ($balance > 0.01)) { 112 $interest = $balance * $pclass['interestrate'] / (100.0 * 12); 113 $new_balance = $balance + $interest + $monthly_fee; 114 115 if ($minimum_payment >= $new_balance || $payment >= $new_balance) { 116 $pay_data[] = $new_balance; 117 break; 118 } 119 120 $new_payment = max($payment, $minimum_payment); 121 122 if ($base) { 123 $new_payment = max($new_payment, $balance / 24.0 + $monthly_fee + $interest); 124 } 125 126 $balance = $new_balance - $new_payment; 127 128 $pay_data[] = $new_payment; 129 130 $months -= 1; 131 } 132 133 $monthly_cost = round(isset($pay_data[0]) ? ($pay_data[0]) : 0, 2); 134 135 if ($monthly_cost < 0.01) { 136 continue; 137 } 138 139 if ($pclass['type'] == 1 && $monthly_cost < $lowest_payment) { 140 $monthly_cost = $lowest_payment; 141 } 142 143 if ($pclass['type'] == 0 && $monthly_cost < $lowest_payment) { 144 continue; 145 } 146 } 147 } 148 149 $payment_option[$pclass['id']]['monthly_cost'] = $monthly_cost; 150 $payment_option[$pclass['id']]['pclass_id'] = $pclass['id']; 151 $payment_option[$pclass['id']]['months'] = $pclass['months']; 152 } 153 } 154 155 if (!$payment_option) { 156 $status = false; 157 } 158 159 $sort_order = array(); 160 161 foreach ($payment_option as $key => $value) { 162 $sort_order[$key] = $value['monthly_cost']; 163 } 164 165 array_multisort($sort_order, SORT_ASC, $payment_option); 166 167 if ($address['company']) { 168 $status = false; 169 } 170 171 $method = array(); 172 173 if ($status) { 174 $method = array( 175 'code' => 'klarna_account', 176 '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)), 177 'terms' => sprintf($this->language->get('text_terms'), $klarna_account[$address['iso_code_3']]['merchant'], strtolower($address['iso_code_2'])), 178 'sort_order' => $klarna_account[$address['iso_code_3']]['sort_order'], 179 ); 180 } 181 182 return $method; 183 } 184 185 private function getLowestPaymentAccount($country) { 186 switch ($country) { 187 case 'SWE': 188 $amount = 50.0; 189 break; 190 case 'NOR': 191 $amount = 95.0; 192 break; 193 case 'FIN': 194 $amount = 8.95; 195 break; 196 case 'DNK': 197 $amount = 89.0; 198 break; 199 case 'DEU': 200 case 'NLD': 201 $amount = 6.95; 202 break; 203 default: 204 $log = new Log('klarna_account.log'); 205 $log->write('Unknown country ' . $country); 206 207 $amount = null; 208 break; 209 } 210 211 return $amount; 212 } 213 }