-
Posts
132 -
Joined
-
Last visited
-
Days Won
1
Posts posted by Kangaroo
-
-
I have a cheap monthly license ? hehe
-
I have seen a plugin for Wordpress here on the forum board. Do a quick search to locate and make it happen.
-
Do you have anything online to see maybe ? Or just new development /
-
This is what I follow for updates on Win10. http://windows.microsoft.com/en-US/windows/preview-download?OCID=WIP_r_Body_DL
-
I think my Chrome browser may be the offender. Looking deeper into this
-
Great work team. Appreciate all the good support. Currently checking all settings and a few updates for each client.
-
Full version coming out of the end of this month. Loving the win10 technical preview. I am confident that the full version is close and stable. If you have win 7 .8 or 8.1 you should see in the updates area to reserve your free copy of Win10.
Clone and backup
-
Followed the above instructions but unfortunately still having issues for tissues.
-
Thanks Paul. I am enjoying the team work here and look forward to more of Blesta.
-
hi there,
I would like to offer my services to test peoples ordering system. To screen shot different parts of the ordering system and the email I receive.
I think this would be great.
There is no charge for this service Just a little love around here.
I hope this is the right thread to paste this into.
Cheers,
Tom
-
hello,
Using the password reset link in my email doesnt allow me to reset the password.
Meaning, when entering my new password the login doesnt work.
Running v3.5 Blesta
T
-
Struggled like a litle B* but F* you whmcs here's the file used if anyone else has this issue.
<?php /** * Generic WHMCS Migrator * * @package blesta * @subpackage blesta.plugins.import_manager.components.migrators.whmcs * @copyright Copyright (c) 2010, Phillips Data, Inc. * @license http://www.blesta.com/license/'>http://www.blesta.com/license/ The Blesta License Agreement * @link http://www.blesta.com/ Blesta */ class WhmcsMigrator extends Migrator { /** * @var array An array of settings */ protected $settings; /** * @var boolean True to fetch all records instead of looping through PDOStatement */ protected $fetchall = false; /** * @var boolean Enable/disable debugging */ protected $enable_debug = false; /** * @var string The default country */ private $default_country = "US"; /** * @var string The default first name */ private $default_firstname = "unknown"; /** * @var string The default last name */ private $default_lastname = "unknown"; /** * @var array An array of credits */ private $credits = array(); private $default_currency = "AUD"; /** * Runs the import, sets any Input errors encountered */ public function import() { Loader::loadModels($this, array("Companies")); Configure::set("Whmcs.import_fetchall", false); if (Configure::get("Whmcs.import_fetchall")) { $this->fetchall = true; ini_set("memory_limit", "512M"); } $actions = array( "importStaff", // works "importClients", // works "importContacts", // works "importTaxes", // works "importCurrencies", // works "importInvoices", // works "importTransactions", // works "importPackages", // works "importPackageOptions", // works "importServices", // works "importSupportDepartments", // works "importSupportTickets", // works "importMisc" // works ); // I hate WHMCS!!!!!!!! $errors = array(); $this->startTimer("total time"); $this->decrypt_count = 0; $this->startTimer("decrypt"); $this->pauseTimer("decrypt"); foreach ($actions as $action) { try { // Only import packages if no mappings exist if ($action == "importPackages" && isset($this->mappings['packages'])) continue; $this->debug($action); $this->debug("-----------------"); $this->startTimer($action); $this->{$action}(); $this->endTimer($action); $this->debug("-----------------\n"); } catch (Exception $e) { $errors[] = $action . ": " . $e->getMessage() . " on line " . $e->getLine(); } } if (!empty($errors)) { array_unshift($errors, Language::_("Whmcs5_2.!error.import", true)); $this->Input->setErrors(array('error' => $errors)); } $this->debug("decrypted " . $this->decrypt_count . " values using WHMCS' custom algorithm"); $this->endTimer("decrypt"); $this->endTimer("total time"); if ($this->enable_debug) { $this->debug(print_r($this->Input->errors(), true)); exit; } } /** * Import staff */ protected function importStaff() { Loader::loadModels($this, array("StaffGroups")); Loader::loadModels($this, array("Users")); $this->loadModel("WhmcsAdmins"); // Create "Support" staff group (no permissions) $staff_group = array( 'company_id' => Configure::get("Blesta.company_id"), 'name' => "Support", 'permission_group' => array(), 'permission' => array() ); $this->StaffGroups->add($staff_group); $staff_groups = $this->StaffGroups->getAll(Configure::get("Blesta.company_id")); $groups = array(); foreach ($staff_groups as $group) { if ($group->name == "Administrators") { $groups[0] = $group->id; $groups[1] = $group->id; } elseif ($group->name == "Billing") { $groups[2] = $group->id; } elseif ($group->name == "Support") { $groups[3] = $group->id; } } $admins = $this->fetchall ? $this->WhmcsAdmins->get()->fetchAll() : $this->WhmcsAdmins->get(); foreach ($admins as $admin) { $this->Users->begin(); // Set aside assigned support departments $this->mappings['admin_departs'][$admin->id] = $admin->supportdepts; try { $user_id = $this->createUser(array( 'username' => $this->decode($admin->username), 'password' => $admin->password, 'date_added' => $this->Users->dateToUtc(date("c")) )); $vars = array( 'user_id' => $user_id, 'first_name' => $this->decode($admin->firstname), 'last_name' => $this->decode($admin->lastname), 'email' => $this->decode($admin->email), 'status' => $admin->disabled == "0" ? "active" : "inactive", 'groups' => isset($groups[$admin->roleid]) ? array($groups[$admin->roleid]) : null ); $staff_id = $this->addStaff($vars, $admin->id); if ($staff_id) $this->Users->commit(); else $this->Users->rollback(); } catch (Exception $e) { $this->local->reset(); $this->Users->rollback(); } } unset($admins); } /** * Import clients */ protected function importClients() { Loader::loadModels($this, array("Accounts", "Clients", "ClientGroups")); $this->loadModel("WhmcsClients"); // Initialize crypto (AES in ECB) Loader::loadComponents($this, array("Security")); $aes = $this->Security->create("Crypt", "AES", array(1)); // 1 = CRYPT_AES_MODE_ECB $aes->disablePadding(); // Set default client group $client_groups = $this->ClientGroups->getAll(Configure::get("Blesta.company_id")); $this->mappings['client_groups'][0] = $client_groups[0]->id; // Import client groups $groups = $this->fetchall ? $this->WhmcsClients->getGroups()->fetchAll() : $this->WhmcsClients->getGroups(); foreach ($groups as $group) { $group_id = $this->ClientGroups->add(array( 'name' => $this->decode($group->groupname), 'company_id' => Configure::get("Blesta.company_id"), 'color' => str_replace("#", "", $group->groupcolour) )); $this->mappings['client_groups'][$group->id] = $group_id; } unset($groups); // Import clients $clients = $this->fetchall ? $this->WhmcsClients->get()->fetchAll() : $this->WhmcsClients->get(); $this->local->begin(); foreach ($clients as $client) { // Create user $user_id = null; try { $user_id = $this->createUser(array( 'username' => $this->decode($client->email), 'password' => $client->password, 'date_added' => $client->datecreated )); } catch (Exception $e) { $this->local->reset(); } if (!$user_id) continue; // Create client $vars = array( 'id_format' => "{num}", 'id_value' => $client->id, 'user_id' => $user_id, 'client_group_id' => $this->mappings['client_groups'][$client->groupid], 'status' => strtolower($client->status) == "closed" ? "inactive" : "active" ); $this->local->insert("clients", $vars); $client_id = $this->local->lastInsertId(); $this->mappings['clients'][$client->id] = $client_id; // Create primary contact $vars = array( 'client_id' => $client_id, 'contact_type' => "primary", 'first_name' => $this->decode(trim($client->firstname) != "" ? $client->firstname : $this->default_firstname), 'last_name' => $this->decode(trim($client->lastname) != "" ? $client->lastname : $this->default_lastname), 'company' => $this->decode($client->companyname != "" ? $client->companyname : null), 'email' => $this->decode($client->email), 'address1' => $this->decode($client->address1), 'address2' => $this->decode($client->address2 != "" ? $client->address2 : null), 'city' => $this->decode($client->city), 'state' => $client->state != "" ? substr($client->state, 0, 3) : null, 'zip' => $this->decode($client->postcode != "" ? $client->postcode : null), 'country' => $client->country != "" ? $client->country : $this->default_country, 'date_added' => $this->Companies->dateToUtc($client->datecreated) ); $this->local->insert("contacts", $vars); $contact_id = $this->local->lastInsertId(); $this->mappings['primary_contacts'][$client->id] = $contact_id; // Save client settings $settings = array( 'autodebit' => $client->disableautocc == "on" ? "false" : "true", 'autosuspend' => "true", 'default_currency' => $client->currency_code, 'inv_address_to' => $contact_id, 'inv_method' => "email", 'language' => "en_us", 'tax_exempt' => $client->taxexempt == "on" ? "true" : "false", 'tax_id' => null, 'username_type' => "email" ); $this->Clients->setSettings($client_id, $settings); // Add contact phone number if ($client->phonenumber != "") { $vars = array( 'contact_id' => $contact_id, 'number' => $this->decode($client->phonenumber), 'type' => "phone", 'location' => "home" ); $this->local->insert("contact_numbers", $vars); } $aes->setKey($this->mysqlAesKey(md5($this->settings['key'] . $client->id))); if ($client->cardnum != "") $client->cardnum = $aes->decrypt($client->cardnum); if ($client->expdate != "") $client->expdate = $aes->decrypt($client->expdate); if ($client->bankacct != "") $client->bankacct = $aes->decrypt($client->bankacct); if ($client->bankcode != "") $client->bankcode = $aes->decrypt($client->bankcode); // Add the payment account if ($client->cardnum != "") { $vars = array( 'contact_id' => $this->mappings['primary_contacts'][$client->id], 'first_name' => $this->decode(trim($client->firstname) != "" ? $client->firstname : $this->default_firstname), 'last_name' => $this->decode(trim($client->lastname) != "" ? $client->lastname : $this->default_lastname), 'address1' => $this->decode($client->address1 != "" ? $client->address1 : null), 'address2' => $this->decode($client->address2 != "" ? $client->address2 : null), 'city' => $this->decode($client->city != "" ? $client->city : null), 'state' => $this->decode($client->state != "" ? $client->state : null), 'zip' => $this->decode($client->postcode != "" ? $client->postcode : null), 'country' => $client->country != "" ? $client->country : $this->default_country, 'number' => $client->cardnum, 'expiration' => "20" . substr($client->expdate, 2, 2) . substr($client->expdate, 0, 2) ); $account_id = $this->Accounts->addCc($vars); // Set account for autodebit if ($account_id) { $vars = array( 'client_id' => $this->mappings['clients'][$client->id], 'account_id' => $account_id, 'type' => "cc" ); $this->local->insert("client_account", $vars); } } } $this->local->commit(); unset($clients); // Import custom client fields $custom_fields = $this->WhmcsClients->getCustomFields()->fetchAll(); $this->local->begin(); foreach ($custom_fields as $custom_field) { // Add each field to each client group foreach ($this->mappings['client_groups'] as $remote_group_id => $group_id) { $vars = array( 'client_group_id' => $group_id, 'name' => $this->decode($custom_field->fieldname), 'type' => $this->getFieldType($this->decode($custom_field->fieldtype)), 'values' => $this->getFieldValues($this->decode($custom_field->fieldoptions)), 'regex' => $this->decode($custom_field->regexpr != "" ? $custom_field->regexpr : null), 'show_client' => $custom_field->adminonly == "on" ? "0" : "1" ); $this->local->insert("client_fields", $vars); $this->mappings['client_fields'][$custom_field->id][$remote_group_id] = $this->local->lastInsertId(); } // Insert custom client values for this field $custom_values = $this->fetchall ? $this->WhmcsClients->getCustomFieldValues($custom_field->id)->fetchAll() : $this->WhmcsClients->getCustomFieldValues($custom_field->id); foreach ($custom_values as $custom_value) { if (!isset($this->mappings['clients'][$custom_value->relid])) continue; $vars = array( 'client_field_id' => $this->mappings['client_fields'][$custom_field->id][$custom_value->groupid], 'client_id' => $this->mappings['clients'][$custom_value->relid], 'value' => $this->decode($custom_value->value) ); $this->local->duplicate("value", "=", $vars['value'])->insert("client_values", $vars); } unset($custom_values); } $this->local->commit(); // Import client notes $notes = $this->fetchall ? $this->WhmcsClients->getNotes()->fetchAll() : $this->WhmcsClients->getNotes(); $this->local->begin(); foreach ($notes as $note) { if (!isset($this->mappings['clients'][$note->userid])) continue; $note->note = $this->decode($note->note); $title = wordwrap($note->note, 32, "\n", true); if (strpos($title, "\n") > 0) $title = substr($title, 0, strpos($title, "\n")); $vars = array( 'client_id' => $this->mappings['clients'][$note->userid], 'staff_id' => isset($this->mappings['staff'][$note->adminid]) ? $this->mappings['staff'][$note->adminid] : 0, 'title' => $title, 'description' => trim($title) == trim($note->note) ? null : $note->note, 'stickied' => $note->sticky ? 1 : 0, 'date_added' => $this->Companies->dateToUtc($note->created), 'date_updated' => $this->Companies->dateToUtc($note->modified) ); $this->local->insert("client_notes", $vars); } $this->local->commit(); unset($notes); } /** * Import contacts */ protected function importContacts() { $this->loadModel("WhmcsContacts"); $contacts = $this->fetchall ? $this->WhmcsContacts->get()->fetchAll() : $this->WhmcsContacts->get(); $this->local->begin(); foreach ($contacts as $contact) { $vars = array( 'client_id' => $this->mappings['clients'][$contact->userid], 'contact_type' => "billing", 'first_name' => $this->decode($contact->firstname), 'last_name' => $this->decode($contact->lastname), 'company' => $this->decode($contact->companyname != "" ? $contact->companyname : null), 'email' => $this->decode($contact->email), 'address1' => $this->decode($contact->address1 != "" ? $contact->address1 : null), 'address2' => $this->decode($contact->address2 != "" ? $contact->address2 : null), 'city' => $this->decode($contact->city != "" ? $contact->city : null), 'state' => $this->decode($contact->state != "" ? substr($contact->state, 0, 3) : null), 'zip' => $this->decode($contact->postcode != "" ? $contact->postcode : null), 'country' => $contact->country != "" ? $contact->country : $this->default_country, 'date_added' => $this->Companies->dateToUtc(date("c")) ); $this->local->insert("contacts", $vars); $contact_id = $this->local->lastInsertId(); $this->mappings['contacts'][$contact->id] = $contact_id; // Add contact phone number if ($contact->phonenumber != "") { $vars = array( 'contact_id' => $contact_id, 'number' => $this->decode($contact->phonenumber), 'type' => "phone", 'location' => "home" ); $this->local->insert("contact_numbers", $vars); } } $this->local->commit(); unset($contacts); } /** * Import taxes */ protected function importTaxes() { $this->loadModel("WhmcsTaxes"); $taxes = $this->fetchall ? $this->WhmcsTaxes->get()->fetchAll() : $this->WhmcsTaxes->get(); $this->local->begin(); foreach ($taxes as $tax) { $state = $this->local->select()->from("states")-> where("country_alpha2", "=", $tax->country)-> where("name", "=", trim($tax->state))->fetch(); $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'level' => $tax->level, 'name' => $this->decode($tax->name), 'state' => $state ? $state->code : null, 'country' => $tax->country != "" ? $tax->country : null, 'amount' => $tax->taxrate ); $this->local->insert("taxes", $vars); $tax_id = $this->local->lastInsertId(); $this->mappings['taxes'][$tax->id] = $tax_id; } $this->local->commit(); unset($taxes); } /** * Import currencies */ protected function importCurrencies() { $this->loadModel("WhmcsCurrencies"); $currencies = $this->fetchall ? $this->WhmcsCurrencies->get()->fetchAll() : $this->WhmcsCurrencies->get(); foreach ($currencies as $currency) { $vars = array( 'code' => $currency->code, 'company_id' => Configure::get("Blesta.company_id"), 'format' => $this->getCurrencyFormat((int)$currency->format), 'prefix' => $this->decode($currency->prefix != "" ? $currency->prefix : null), 'suffix' => $this->decode($currency->suffix != "" ? $currency->suffix : null), 'exchange_rate' => $currency->rate, 'exchange_updated' => null ); $this->local-> duplicate("format", "=", $vars['format'])-> duplicate("prefix", "=", $vars['prefix'])-> duplicate("suffix", "=", $vars['suffix'])-> duplicate("exchange_rate", "=", $vars['exchange_rate'])-> insert("currencies", $vars); // Set default currency if ($currency->default == "1") { $this->Companies->setSetting(Configure::get("Blesta.company_id"), "default_currency", $currency->code); } } unset($currencies); } /** * Import invoices */ protected function importInvoices() { $this->loadModel("WhmcsConfiguration"); $this->loadModel("WhmcsInvoices"); Loader::loadModels($this, array("Invoices")); $cascade_tax = false; // Get compound tax setting $cascade = $this->WhmcsConfiguration->get("TaxL2Compound")->fetch(); if ($cascade && $cascade->value == "on") $cascade_tax = true; $invoices = $this->fetchall ? $this->WhmcsInvoices->get()->fetchAll() : $this->WhmcsInvoices->get(); $this->local->begin(); foreach ($invoices as $invoice) { // Get tax rules $level1 = $this->getTaxRule(1, $invoice->taxrate); $level2 = $this->getTaxRule(2, $invoice->taxrate2); $status = "active"; switch (strtolower($invoice->status)) { case "refunded": case "cancelled": $status = "void"; break; default: $status = "active"; break; } if (!$invoice->currency) { $invoice->currency = "AUD"; } $vars = array( 'id_format' => $this->decode($invoice->invoicenum != "" ? $invoice->invoicenum : "{num}"), 'id_value' => $invoice->invoicenum != "" ? 0 : $invoice->id, 'client_id' => $this->mappings['clients'][$invoice->userid], 'date_billed' => $this->Companies->dateToUtc($invoice->date), 'date_due' => $this->Companies->dateToUtc($invoice->duedate), 'date_closed' => strtolower($invoice->status) != "paid" || $invoice->datepaid == "0000-00-00 00:00:00" ? null : $this->Companies->dateToUtc($invoice->datepaid), 'date_autodebit' => null, 'status' => $status, 'previous_due' => 0, 'currency' => $invoice->currency, 'note_public' => $invoice->notes, 'note_private' => null, ); // Manually add the invoice so we can set the correct tax IDs and invoice ID $this->local->insert("invoices", $vars); $local_invoice_id = $this->local->lastInsertId(); $this->mappings['invoices'][$invoice->id] = $local_invoice_id; $this->mappings['invoice_tax_rules'][$invoice->id] = array( 'level1' => $level1, 'level2' => $level2 ); if (!$invoice->currency) { $invoice->currency = "AUD"; } if ($invoice->credit > 0) { $this->credits[] = array( 'invoice_id' => $local_invoice_id, 'client_id' => $this->mappings['clients'][$invoice->userid], 'amount' => $invoice->credit, 'currency' => $invoice->currency, 'transaction_id' => "invoice credit", 'transaction_type' => "other", 'transaction_type_id' => $this->getTransactionTypeId("in_house_credit"), 'status' => 'approved', 'date_added' => $this->Companies->dateToUtc($invoice->date, "c") ); } } $this->local->commit(); unset($invoices); // Import line items $lines = $this->fetchall ? $this->WhmcsInvoices->getLines()->fetchAll() : $this->WhmcsInvoices->getLines(); $this->local->begin(); foreach ($lines as $line) { if (!isset($this->mappings['invoices'][$line->invoiceid])) continue; // Import lines $vars = array( 'invoice_id' => $this->mappings['invoices'][$line->invoiceid], 'service_id' => null, 'description' => $this->decode($line->description), 'qty' => 1, 'amount' => $line->amount, 'order' => 0 ); $this->local->insert("invoice_lines", $vars); $line_id = $this->local->lastInsertId(); // Import tax lines if ($line->taxed > 0) { if ($this->mappings['invoice_tax_rules'][$line->invoiceid]['level1']) { $vars = array( 'line_id' => $line_id, 'tax_id' => $this->mappings['invoice_tax_rules'][$line->invoiceid]['level1']->id ); $this->local->insert("invoice_line_taxes", $vars); } if ($this->mappings['invoice_tax_rules'][$line->invoiceid]['level2']) { $vars = array( 'line_id' => $line_id, 'tax_id' => $this->mappings['invoice_tax_rules'][$line->invoiceid]['level2']->id, 'cascade' => $cascade_tax ? 1 : 0 ); $this->local->insert("invoice_line_taxes", $vars); } } } $this->local->commit(); unset($lines); // Update totals if (isset($this->mappings['invoices'])) { foreach ($this->mappings['invoices'] as $remote_invoice_id => $local_invoice_id) { $subtotal = $this->Invoices->getSubtotal($local_invoice_id); $total = $this->Invoices->getTotal($local_invoice_id); $this->local->where("id", "=", $local_invoice_id)-> update("invoices", array('subtotal' => $subtotal, 'total' => $total)); } } $periods = array( 'Days' => "day", 'Weeks' => "week", 'Months' => "month", 'Years' => "year" ); // Import recurring invoices $lines = $this->fetchall ? $this->WhmcsInvoices->getRecurringLines()->fetchAll() : $this->WhmcsInvoices->getRecurringLines(); $this->local->begin(); foreach ($lines as $line) { if (!$line->currency) { $line->currency = "AUD"; } if (!isset($periods[$line->recurcycle])) continue; $vars = array( 'client_id' => $this->mappings['clients'][$line->userid], 'term' => $line->recur, 'period' => $periods[$line->recurcycle], 'duration' => $line->recurfor > 0 ? $line->recurfor : null, 'date_renews' => $this->Companies->dateToUtc($line->duedate), 'currency' => $line->currency, 'lines' => array( array( 'description' => $this->decode($line->description), 'qty' => 1, 'amount' => $line->amount, 'tax' => 0 ) ), 'delivery' => array('email') ); $recurring_id = $this->Invoices->addRecurring($vars); if ($recurring_id) $this->mappings['recurring_invoices'][$line->id] = $recurring_id; } $this->local->commit(); unset($lines); if (isset($this->mappings['recurring_invoices'])) { // Record each recurring invoice instance $this->local->begin(); foreach ($this->mappings['recurring_invoices'] as $remote_id => $recurring_id) { $lines = $this->fetchall ? $this->WhmcsInvoices->getRecurInstances($remote_id)->fetchAll() : $this->WhmcsInvoices->getRecurInstances($remote_id); foreach ($lines as $line) { $vars = array( 'invoice_recur_id' => $recurring_id, 'invoice_id' => $this->mappings['invoices'][$line->invoiceid] ); $this->local->insert("invoices_recur_created", $vars); } unset($lines); } $this->local->commit(); } } /** * Import transactions */ protected function importTransactions() { $this->loadModel("WhmcsAccounts"); $this->loadModel("WhmcsCurrencies"); Loader::loadModels($this, array("Invoices")); $default_currency = $this->WhmcsCurrencies->getDefaultCode(); if (!$default_currency) { $default_currency = "AUD"; } $invoice_ids = array(); // Add invoice credits $this->local->begin(); foreach ($this->credits as $credit) { $transaction_id = $this->addTransaction($credit, null); $vars = array( 'date' => $credit['date_added'], 'amounts' => array( array( 'invoice_id' => $credit['invoice_id'], 'amount' => $credit['amount'], ) ) ); $this->Transactions->apply($transaction_id, $vars); if (!in_array($credit['invoice_id'], $invoice_ids)) $invoice_ids[] = $credit['invoice_id']; } $this->local->commit(); unset($this->credits); $transactions = $this->fetchall ? $this->WhmcsAccounts->get(true)->fetchAll() : $this->WhmcsAccounts->get(true); $this->local->begin(); foreach ($transactions as $transaction) { if (!isset($this->mappings['clients'][$transaction->userid])) continue; $currency = $default_currency; if (!$currency) { $currency = "AUD"; } if ($transaction->trans_currency != "") $currency = $transaction->trans_currency; elseif ($transaction->client_currency != "") $currency = $transaction->client_currency; // Only add income transactions if ($transaction->amountin > 0) { $status = ($transaction->refund > 0 ? "refunded" : "approved"); $vars = array( 'client_id' => $this->mappings['clients'][$transaction->userid], 'amount' => $transaction->amountin, 'currency' => $currency, 'transaction_id' => $transaction->transid, 'status' => $status, 'date_added' => $this->Companies->dateToUtc($transaction->date, "c") ); $transaction_id = $this->addTransaction($vars, $transaction->id); // If the transactions was refunded add a new transaction for the difference if ($status == "refunded" && $transaction->refund < $transaction->amountin) { $vars = array( 'client_id' => $this->mappings['clients'][$transaction->userid], 'amount' => $transaction->amountin - $transaction->refund, 'currency' => $currency, 'transaction_id' => $transaction->transid, 'status' => "approved", 'date_added' => $this->Companies->dateToUtc($transaction->date, "c") ); $transaction_id = $this->addTransaction($vars, $transaction->id); } } // Apply payment if (isset($this->mappings['invoices'][$transaction->invoiceid]) && $transaction->amountin > 0) { $vars = array( 'date' => $this->Companies->dateToUtc($transaction->date, "c"), 'amounts' => array( array( 'invoice_id' => $this->mappings['invoices'][$transaction->invoiceid], 'amount' => $transaction->amountin - ($transaction->refund > 0 ? $transaction->refund : 0), ) ) ); $this->Transactions->apply($transaction_id, $vars); if (!in_array($this->mappings['invoices'][$transaction->invoiceid], $invoice_ids)) $invoice_ids[] = $this->mappings['invoices'][$transaction->invoiceid]; } } $this->local->commit(); unset($transactions); // Add client credits $credits = $this->fetchall ? $this->WhmcsAccounts->getOpenCredits()->fetchAll() : $this->WhmcsAccounts->getOpenCredits(); $this->local->begin(); foreach ($credits as $credit) { if (!$credit->currency) { $credit->currency = "AUD"; } if (!isset($this->mappings['clients'][$credit->userid])) continue; $vars = array( 'client_id' => $this->mappings['clients'][$credit->userid], 'amount' => $credit->credit, 'currency' => $credit->currency, 'type' => 'other', 'transaction_type_id' => $this->getTransactionTypeId("in_house_credit"), 'transaction_id' => null, 'status' => 'approved', 'date_added' => $this->Companies->dateToUtc(date("c")) ); $transaction_id = $this->addTransaction($vars, $transaction->id); } $this->local->commit(); unset($credits); // Update paid totals $this->local->begin(); foreach ($invoice_ids as $invoice_id) { // Update paid total $paid = $this->Invoices->getPaid($invoice_id); $this->local->where("id", "=", $invoice_id)-> update("invoices", array('paid' => $paid)); } $this->local->commit(); $this->balanceClientCredit(); } /** * Verifies that total transaction credit for a each client matches credit * set in WHMCS */ protected function balanceClientCredit() { if ($this->settings['balance_credit'] != "true") return; $this->loadModel("WhmcsAccounts"); if (!isset($this->Transactions)) Loader::loadModels($this, array("Transactions")); if (!isset($this->Invoices)) Loader::loadModels($this, array("Invoices")); // Fetch all client credit values $credits = $this->WhmcsAccounts->getCredits(); $date = date("c"); foreach ($credits as $credit) { if (!isset($this->mappings['clients'][$credit->userid])) continue; $client_id = $this->mappings['clients'][$credit->userid]; $total_credit = $this->Transactions->getTotalCredit($client_id, $credit->currency); $credit_diff = round($total_credit-$credit->credit, 4); // We have excess credit, so consume it if ($credit_diff > 0) { // Create an invoice to balance credits $vars = array( 'client_id' => $client_id, 'currency' => $credit->currency, 'date_billed' => $date, 'date_due' => $date, 'status' => "active", 'lines' => array( array( 'description' => "Automatic credit balance adjustment.", 'qty' => 1, 'amount' => $credit_diff ) ) ); $invoice_id = $this->Invoices->add($vars); // Consume the credit $amounts = array( array( 'invoice_id' => $invoice_id, 'amount' => $credit_diff ) ); $this->Transactions->applyFromCredits($client_id, $credit->currency, $amounts); } elseif ($credit_diff < 0) { // Create transaction to hold the credit diff $vars = array( 'client_id' => $client_id, 'amount' => -1*$credit_diff, 'currency' => $credit->currency, 'type' => 'other', 'transaction_type_id' => $this->getTransactionTypeId("in_house_credit"), 'transaction_id' => null, 'status' => 'approved', 'date_added' => $this->Companies->dateToUtc($date) ); $transaction_id = $this->addTransaction($vars, $transaction->id); } } } /** * Import modules */ protected function importModules() { $this->loadModel("WhmcsProducts"); // Import generic server module required for all package assigned to no module $this->installModuleRow(array('id' => "generic_server", 'type' => "generic_server")); // Import servers $rows = $this->fetchall ? $this->WhmcsProducts->getServers()->fetchAll() : $this->WhmcsProducts->getServers(); foreach ($rows as $row) { $this->installModuleRow((array)$row); } unset($rows); // Import registrars foreach ($this->WhmcsProducts->getReigstrars() as $registrar) { $row = $this->WhmcsProducts->getRegistrarFields($registrar); foreach ($row as &$value) { $value = $this->decryptData($value); } $row['id'] = $registrar; $row['type'] = $registrar; $this->installModuleRow($row, "registrar"); } } /** * Import packages */ protected function importPackages() { $this->importModules(); $this->loadModel("WhmcsProducts"); $this->loadModel("WhmcsConfiguration"); Loader::loadModels($this, array("PackageGroups")); // Add imported package group $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'name' => "Imported", 'type' => "standard" ); $package_group_id = $this->PackageGroups->add($vars); $products = $this->WhmcsProducts->get()->fetchAll(); $i=1; $this->local->begin(); foreach ($products as $product) { if (!isset($this->mappings['modules'][$product->servertype])) $product->servertype = "generic_server"; $pricing = $this->WhmcsProducts->getPricing($product->id); $mapping = $this->getModuleMapping($product->servertype); // Add package $vars = array( 'id_format' => "{num}", 'id_value' => $product->id, 'module_id' => $this->mappings['modules'][$product->servertype], 'name' => $this->decode($product->name), 'description' => strip_tags($this->decode($product->description)), 'description_html' => $this->decode($product->description), 'qty' => $product->stockcontrol == "on" ? $product->qty : null, 'module_row' => 0, // WHMCS doesn't associate a service with a product 'module_group' => null, 'taxable' => $product->tax, 'status' => $product->retired == "1" ? "inactive" : "active", 'company_id' => Configure::get("Blesta.company_id") ); $this->local->insert("packages", $vars); $this->mappings['packages'][$product->id] = $this->local->lastInsertId(); // Assign group $this->local->insert("package_group", array('package_id' => $this->mappings['packages'][$product->id], 'package_group_id' => $package_group_id)); // Add package pricing $this->addPackagePricing($pricing, $this->mappings['packages'][$product->id]); // Import package meta $this->addPackageMeta((array)$product, $mapping); $i = max(++$i, $product->id); } $this->local->commit(); $taxable = 0; $tax_domains = $this->WhmcsConfiguration->get("TaxDomains")->fetch(); if ($tax_domains) $taxable = $tax_domains->value == "on" ? 1 : 0; $tlds = $this->WhmcsProducts->getTlds(); $this->local->begin(); foreach ($tlds as $tld) { $pricing = $this->WhmcsProducts->getTldPricing($tld->extension); $registrar = trim($tld->autoreg); if ($registrar == "") continue; $mapping = $this->getModuleMapping($registrar, "registrar"); $vars = array( 'id_format' => "{num}", 'id_value' => max($tld->id, $i++), 'module_id' => $this->mappings['modules'][$registrar], 'name' => "Domain Registration (" . $tld->extension . ")", 'description' => null, 'description_html' => null, 'qty' => null, 'module_row' => !isset($this->mappings['module_rows'][$registrar][$registrar]) ? 0 : $this->mappings['module_rows'][$registrar][$registrar], 'module_group' => null, 'taxable' => $taxable, 'status' => "active", 'company_id' => Configure::get("Blesta.company_id") ); // Add the package $this->local->insert("packages", $vars); $this->mappings['packages'][$tld->extension . $registrar] = $this->local->lastInsertId(); // Assign group $this->local->insert("package_group", array('package_id' => $this->mappings['packages'][$tld->extension . $registrar], 'package_group_id' => $package_group_id)); // Add package pricing $this->addPackagePricing($pricing, $this->mappings['packages'][$tld->extension . $registrar]); // Import package meta $product = array( 'id' => $tld->extension . $registrar, 'tlds' => array($tld->extension) ); $this->addPackageMeta($product, $mapping); } $this->local->commit(); } /** * Import package options */ protected function importPackageOptions() { $this->loadModel("WhmcsProducts"); Loader::loadModels($this, array("PackageOptionGroups", "PackageOptions")); $option_types = $this->WhmcsProducts->getConfigOptionTypes(); $option_groups = $this->WhmcsProducts->getConfigOptionGroups(); foreach ($option_groups as $option_group) { $packages = array(); // Map WHMCS packages to packages in Blesta foreach ($option_group->packages as $package_id) { if (isset($this->mappings['packages'][$package_id])) { $packages[] = $this->mappings['packages'][$package_id]; } } $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'name' => $option_group->name, 'description' => $option_group->description, 'packages' => $packages ); $option_group_id = $this->PackageOptionGroups->add($vars); // Record package group mapping $this->mappings['package_options_groups'][$option_group->id] = $option_group_id; // Import package options $options = $this->WhmcsProducts->getConfigOptions($option_group->id); foreach ($options as $option) { $values = array(); foreach ($option->values as $value) { $is_qty = isset($option_types[$option->optiontype]) && $option_types[$option->optiontype] == "quantity"; $values[] = array( 'name' => $value->optionname, 'value' => $is_qty ? null : $value->optionname, 'min' => $is_qty ? max(0, $option->qtyminimum) : null, 'max' => $is_qty && $option->qtymaximum > 0 ? max(1, $option->qtymaximum) : null, 'step' => $is_qty ? "1" : null, 'pricing' => $this->WhmcsProducts->getPricing($value->id, "configoptions") ); } // WHMCS only supports one group per option... weak! $groups = array($this->mappings['package_options_groups'][$option->gid]); $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'label' => $option->optionname, 'name' => $option->optionname, 'type' => isset($option_types[$option->optiontype]) ? $option_types[$option->optiontype] : "select", 'values' => $values, 'groups' => $groups ); $option_id = $this->PackageOptions->add($vars); // Record package option mapping $this->mappings['package_options'][$option->id] = $option_id; // Record package option value mappings $opt_values = $this->PackageOptions->getValues($option_id); foreach ($opt_values as $v => $val) { $this->mappings['option_values'][$option->values[$v]->id] = $val->id; } } } } /** * Import services */ protected function importServices() { $this->loadModel("WhmcsServices"); $this->loadModel("WhmcsProducts"); Loader::loadModels($this, array("Clients", "Packages")); $servers = array(); $rows = $this->fetchall ? $this->WhmcsProducts->getServers()->fetchAll() : $this->WhmcsProducts->getServers(); foreach ($rows as $row) { $servers[$row->id] = $row; } unset($rows); $services = $this->fetchall ? $this->WhmcsServices->get()->fetchAll() : $this->WhmcsServices->get(); $this->local->begin(); foreach ($services as $service) { // If the client doesn't exist, we can't import the service if (!isset($this->mappings['clients'][$service->userid])) continue; // If the package doesn't exist, we can't import the service if (!isset($this->mappings['packages'][$service->packageid])) continue; $package = $this->Packages->get($this->mappings['packages'][$service->packageid]); if (!isset($this->mappings['modules'])) { if (!isset($this->ModuleManager)) Loader::loadModels($this, array("ModuleManager")); $module = $this->ModuleManager->get($package->module_id, false, false); if ($module) $modules[$package->module_id] = $module->class; } else $modules = array_flip($this->mappings['modules']); $mapping = $this->getModuleMapping(isset($modules[$package->module_id]) ? $modules[$package->module_id] : "generic_server"); // Get currency this client is invoiced in $currency = $this->getCurrency($this->mappings['clients'][$service->userid]); if (!$currency) { $currency = "AUD"; } if ($package->module_row > 0) $module_row_id = $package->module_row; else { if (isset($mapping['module_row_key']) && isset($servers[$service->server]->{$mapping['module_row_key']})) $module_row_id = $this->getModuleRowId($package->module_id, $servers[$service->server]->{$mapping['module_row_key']}, null); else $module_row_id = $this->getModuleRowId($package->module_id, null, isset($modules[$package->module_id]) ? $modules[$package->module_id] : null); } if (!$module_row_id) continue; $status = $this->getServiceStatus($service->domainstatus); $pricing = $this->getPricing($this->WhmcsServices->getTerm($service->billingcycle), $package, $currency, $service->amount); $override_price = (($p = number_format($pricing->price, 2, '.', '')) == number_format($service->amount, 2, '.', '') ? $p : null); $override_currency = ($override_price === null ? null : $currency); $vars = array( 'parent_service_id' => null, 'package_group_id' => null, 'id_format' => "{num}", 'id_value' => $service->id, 'pricing_id' => $pricing->id, 'client_id' => $this->mappings['clients'][$service->userid], 'module_row_id' => $module_row_id, 'coupon_id' => null, 'qty' => 1, 'override_price' => $override_price, 'override_currency' => $override_currency, 'status' => $status, 'date_added' => $this->Companies->dateToUtc($service->regdate . " 00:00:00"), 'date_renews' => $service->nextinvoicedate == "0000-00-00" ? null : $this->Companies->dateToUtc($service->nextinvoicedate . " 00:00:00"), 'date_last_renewed' => null, 'date_suspended' => $status == "suspended" ? $this->Companies->dateToUtc(date("c")) : null, 'date_canceled' => $status == "canceled" ? $this->Companies->dateToUtc(date("c")) : null ); $this->local->insert("services", $vars); $service_id = $this->local->lastInsertId(); $this->mappings['services'][$service->id] = $service_id; $this->addServiceFields((array)$service, $mapping); } $this->local->commit(); unset($services); $option_types = $this->WhmcsProducts->getConfigOptionTypes(); // Import options for services $options = $this->WhmcsServices->getConfigOptions(); $this->local->begin(); foreach ($options as $option) { // Ensure parent service exists if (!isset($this->mappings['services'][$option->relid])) continue; $currency = $this->getCurrency($this->mappings['clients'][$option->userid]); if (!$currency) { $currency = "AUD"; } $value_id = $this->mappings['option_values'][$option->optionid]; $pricing = $this->getOptionPricing($this->WhmcsServices->getTerm($option->billingcycle), $value_id, $currency); if (!$pricing) { continue; } $vars = array( 'service_id' => $this->mappings['services'][$option->relid], 'option_pricing_id' => $pricing->id, // option isn't a quantity type, set qty to 1 'qty' => $option_types[$option->optiontype] == "quantity" ? $option->qty : 1 ); $this->local->insert("service_options", $vars); } $this->local->commit(); unset($options); $services = $this->fetchall ? $this->WhmcsServices->getDomains()->fetchAll() : $this->WhmcsServices->getDomains(); $this->local->begin(); foreach ($services as $service) { // If the client doesn't exist, we can't import the service if (!isset($this->mappings['clients'][$service->userid])) continue; if ($service->registrar == "") $service->registrar = "generic_registrar"; $tld = $this->getTld($service->domain, $service->registrar); // If package does not exist, we can't import the service if (!isset($this->mappings['packages'][$tld . $service->registrar])) continue; $package = $this->Packages->get($this->mappings['packages'][$tld . $service->registrar]); $mapping = $this->getModuleMapping($service->registrar, "registrar"); // Get currency this client is invoiced in $currency = $this->getCurrency($this->mappings['clients'][$service->userid]); if (!$currency) { $currency = "AUD"; } $module_row_id = $this->mappings['module_rows'][$service->registrar][$service->registrar]; if (!$module_row_id) continue; $status = $this->getServiceStatus($service->status); $pricing = $this->getPricing($this->WhmcsServices->getTerm($service->registrationperiod), $package, $currency, $service->recurringamount); $override_price = (($p = number_format($pricing->price, 2, '.', '')) == number_format($service->recurringamount, 2, '.', '') ? $p : null); $override_currency = ($override_price === null ? null : $currency); $vars = array( 'parent_service_id' => null, 'package_group_id' => null, 'id_format' => "{num}", 'id_value' => $service->id, 'pricing_id' => $pricing->id, 'client_id' => $this->mappings['clients'][$service->userid], 'module_row_id' => $module_row_id, 'coupon_id' => null, 'qty' => 1, 'override_price' => $override_price, 'override_currency' => $override_currency, 'status' => $status, 'date_added' => $this->Companies->dateToUtc($service->registrationdate . " 00:00:00"), 'date_renews' => $service->nextinvoicedate == "0000-00-00" ? null : $this->Companies->dateToUtc($service->nextinvoicedate . " 00:00:00"), 'date_last_renewed' => null, 'date_suspended' => $status == "suspended" ? $this->Companies->dateToUtc(date("c")) : null, 'date_canceled' => $status == "canceled" ? $this->Companies->dateToUtc(date("c")) : null ); $this->local->insert("services", $vars); $service_id = $this->local->lastInsertId(); $this->mappings['services'][$service->id] = $service_id; $this->addServiceFields((array)$service, $mapping); } $this->local->commit(); unset($services); } /** * Import support departments */ protected function importSupportDepartments() { Loader::loadModels($this, array("PluginManager")); // Install support plugin if not already installed if (!$this->PluginManager->isInstalled("support_manager", Configure::get("Blesta.company_id"))) $this->PluginManager->add(array('dir' => "support_manager", 'company_id' => Configure::get("Blesta.company_id"))); $this->loadModel("WhmcsSupportDepartments"); $departments = $this->fetchall ? $this->WhmcsSupportDepartments->get()->fetchAll() : $this->WhmcsSupportDepartments->get(); $this->local->begin(); foreach ($departments as $department) { $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'name' => $this->decode($department->name), 'description' => $this->decode($department->description), 'email' => $this->decode($department->email), 'method' => $department->piperepliesonly == "on" ? "pipe" : "pop3", 'default_priority' => "medium", 'host' => $this->decode($department->host), 'user' => $this->decode($department->login), 'pass' => $this->decryptData($department->password), 'port' => $department->port, 'security' => "none", 'box_name' => null, 'mark_messages' => "deleted", 'clients_only' => $department->clientsonly == "on" ? 1 : 0, 'status' => $department->hidden == "on" ? "hidden" : "visible" ); $this->local->insert("support_departments", $vars); $department_id = $this->local->lastInsertId(); $this->mappings['support_departments'][$department->id] = $department_id; } $this->local->commit(); unset($departments); // Assign admins to support departments $this->local->begin(); foreach ($this->mappings['admin_departs'] as $remote_admin_id => $departs) { if (!isset($this->mappings['staff'][$remote_admin_id])) continue; $departs = explode(",", $departs); foreach ($departs as $depart_id) { $depart_id = trim($depart_id); if (isset($this->mappings['support_departments'][$depart_id])) { $vars = array( 'department_id' => $this->mappings['support_departments'][$depart_id], 'staff_id' => $this->mappings['staff'][$remote_admin_id] ); $this->local-> duplicate("staff_id", "=", $this->mappings['staff'][$remote_admin_id])-> insert("support_staff_departments", $vars); } } // Add schedules $days = array("sun", "mon", "tue", "wed", "thu", "fri", "sat"); foreach ($days as $day) { $vars = array( 'staff_id' => $this->mappings['staff'][$remote_admin_id], 'company_id' => Configure::get("Blesta.company_id"), 'day' => $day, 'start_time' => "00:00:00", 'end_time' => "00:00:00" ); try { $this->local->insert("support_staff_schedules", $vars); } catch (Exception $e) { $this->local->reset(); } } // Add notices $keys = array("ticket_emails"); foreach ($keys as $key) { $vars = array( 'key' => $key, 'company_id' => Configure::get("Blesta.company_id"), 'staff_id' => $this->mappings['staff'][$remote_admin_id], 'value' => serialize(array('emergency' => "true", 'critical' => "true", 'high' => "true", 'medium' => "true", 'low' => "true")) ); try { $this->local->insert("support_staff_settings", $vars); } catch (Exception $e) { $this->local->reset(); } } } $this->local->commit(); } /** * Import support tickets */ protected function importSupportTickets() { $this->loadModel("WhmcsSupportTickets"); $priorities = array( 'High' => 'high', 'Medium' => 'medium', 'Low' => 'low' ); $statuses = array( 'Open' => 'open', 'Answered' => 'closed', 'Customer-Reply' => 'awaiting_reply', 'Closed' => 'closed', 'In Progress' => 'in_progress' ); $tickets = $this->fetchall ? $this->WhmcsSupportTickets->get()->fetchAll() : $this->WhmcsSupportTickets->get(); $this->local->begin(); foreach ($tickets as $ticket) { $vars = array( 'code' => is_numeric($ticket->tid) ? (int)$ticket->tid : preg_replace("/[^0-9]+/", "", $ticket->tid), 'department_id' => isset($this->mappings['support_departments'][$ticket->did]) ? $this->mappings['support_departments'][$ticket->did] : 0, 'staff_id' => null, 'service_id' => null, 'client_id' => $ticket->userid > 0 && isset($this->mappings['clients'][$ticket->userid]) ? $this->mappings['clients'][$ticket->userid] : null, 'email' => $this->decode($ticket->email != "" ? $ticket->email : null), 'summary' => $this->decode($ticket->title), 'priority' => isset($priorities[$ticket->urgency]) ? $priorities[$ticket->urgency] : 'medium', 'status' => isset($statuses[$ticket->status]) ? $statuses[$ticket->status] : 'open', 'date_added' => $this->Companies->dateToUtc($ticket->date), 'date_closed' => isset($statuses[$ticket->status]) && $statuses[$ticket->status] == "closed" ? $this->Companies->dateToUtc($ticket->lastreply) : null, ); $this->local->insert("support_tickets", $vars); $this->mappings['support_tickets'][$ticket->id] = $this->local->lastInsertId(); // Add ticket body $vars = array( 'ticket_id' => $this->mappings['support_tickets'][$ticket->id], 'staff_id' => $ticket->admin_id && isset($this->mappings['staff'][$ticket->admin_id]) ? $this->mappings['staff'][$ticket->admin_id] : null, 'type' => "reply", 'details' => $this->decode($ticket->message), 'date_added' => $this->Companies->dateToUtc($ticket->date), ); $this->local->insert("support_replies", $vars); } $this->local->commit(); unset($tickets); // Import ticket replies $replies = $this->fetchall ? $this->WhmcsSupportTickets->getReplies()->fetchAll() : $this->WhmcsSupportTickets->getReplies(); $this->local->begin(); foreach ($replies as $reply) { if (!isset($this->mappings['support_tickets'][$reply->tid])) continue; $vars = array( 'ticket_id' => $this->mappings['support_tickets'][$reply->tid], 'staff_id' => $reply->admin_id && isset($this->mappings['staff'][$reply->admin_id]) ? $this->mappings['staff'][$reply->admin_id] : null, 'type' => "reply", 'details' => $this->decode($reply->message), 'date_added' => $this->Companies->dateToUtc($reply->date), ); $this->local->insert("support_replies", $vars); } $this->local->commit(); unset($replies); // Import ticket notes $notes = $this->fetchall ? $this->WhmcsSupportTickets->getNotes()->fetchAll() : $this->WhmcsSupportTickets->getNotes(); $this->local->begin(); foreach ($notes as $note) { if (!isset($this->mappings['support_tickets'][$note->ticketid])) continue; $vars = array( 'ticket_id' => $this->mappings['support_tickets'][$note->ticketid], 'staff_id' => $note->admin_id && isset($this->mappings['staff'][$note->admin_id]) ? $this->mappings['staff'][$note->admin_id] : null, 'type' => "note", 'details' => $this->decode($note->message), 'date_added' => $this->Companies->dateToUtc($note->date), ); $this->local->insert("support_replies", $vars); } $this->local->commit(); unset($notes); // Import predefined categories $categories = $this->fetchall ? $this->WhmcsSupportTickets->getResponseCategories()->fetchAll() : $this->WhmcsSupportTickets->getResponseCategories(); $this->local->begin(); foreach ($categories as $category) { $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'parent_id' => isset($this->mappings['support_response_categories'][$category->parentid]) ? $this->mappings['support_response_categories'][$category->parentid] : null, 'name' => $this->decode($category->name) ); $this->local->insert("support_response_categories", $vars); $this->mappings['support_response_categories'][$category->id] = $this->local->lastInsertId(); } $this->local->commit(); unset($categories); // Import predefined replies $responses = $this->fetchall ? $this->WhmcsSupportTickets->getResponses()->fetchAll() : $this->WhmcsSupportTickets->getResponses(); $this->local->begin(); foreach ($responses as $response) { if (!isset($this->mappings['support_response_categories'][$response->catid])) continue; $vars = array( 'category_id' => $this->mappings['support_response_categories'][$response->catid], 'name' => $this->decode($response->name), 'details' => $this->decode($response->reply) ); $this->local->insert("support_responses", $vars); } $this->local->commit(); unset($responses); } /** * Import miscellaneous */ protected function importMisc() { $this->loadModel("WhmcsEmails"); $this->loadModel("WhmcsConfiguration"); $this->loadModel("WhmcsCalendar"); $from_name = $this->WhmcsConfiguration->get("SystemEmailsFromName")->fetch(); $from_email = $this->WhmcsConfiguration->get("SystemEmailsFromEmail")->fetch(); // Mail log $this->startTimer("mail log"); $this->local->begin(); foreach ($this->WhmcsEmails->get() as $message) { if ($message->to == "") continue; $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'to_client_id' => $message->userid > 0 && isset($this->mappings['clients'][$message->userid]) ? $this->mappings['clients'][$message->userid] : null, 'from_staff_id' => null, 'to_address' => $this->decode($message->to), 'from_address' => $this->decode($from_email->value), 'from_name' => $this->decode($from_name->value), 'cc_address' => $this->decode($message->cc != "" ? $message->cc : null), 'subject' => $this->decode($message->subject != "" ? $message->subject : " "), 'body_text' => strip_tags($this->decode($message->message)), 'body_html' => $this->decode($message->message), 'sent' => 1, 'error' => null, 'date_sent' => $this->Companies->dateToUtc($message->date) ); $this->local->insert("log_emails", $vars); } $this->local->commit(); $this->endTimer("mail log"); // Configurations $this->startTimer("settings"); $settings = $this->fetchall ? $this->WhmcsConfiguration->get()->fetchAll() : $this->WhmcsConfiguration->get(); $this->local->begin(); foreach ($settings as $setting) { $setting->value = $this->decode($setting->value); switch ($setting->setting) { case "MailType": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "mail_delivery", $setting->value == "mail" ? "php" : $setting->value); break; case "SMTPHost": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "smtp_host", $setting->value); break; case "SMTPUsername": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "smtp_user", $setting->value); break; case "SMTPPassword": if ($setting->value != "") $this->Companies->setSetting(Configure::get("Blesta.company_id"), "smtp_user", $this->decryptData($setting->value)); break; case "SMTPPort": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "smtp_port", $setting->value); break; case "SMTPSSL": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "smtp_security", $setting->value); break; case "CreateInvoiceDaysBefore": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "inv_days_before_renewal", $setting->value); break; case "SendInvoiceReminderDays": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "notice1", $setting->value != 0 ? -1 * $setting->value : "disabled"); break; case "SendFirstOverdueInvoiceReminder": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "notice2", $setting->value != 0 ? $setting->value : "disabled"); break; case "SendSecondOverdueInvoiceReminder": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "notice3", $setting->value != 0 ? $setting->value : "disabled"); break; case "CCProcessDaysBefore": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "autodebit_days_before_due", $setting->value); break; case "AutoSuspensionDays": $this->Companies->setSetting(Configure::get("Blesta.company_id"), "suspend_services_days_after_due", $setting->value); break; } } $this->local->commit(); $this->endTimer("settings"); unset($settings); // Import calendar events $this->startTimer("calendar events"); $events = $this->fetchall ? $this->WhmcsCalendar->get()->fetchAll() : $this->WhmcsCalendar->get(); $this->local->begin(); foreach ($events as $event) { $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'staff_id' => isset($this->mappings['staff'][$event->adminid]) ? $this->mappings['staff'][$event->adminid] : 0, 'shared' => 0, 'title' => $this->decode($event->title . " " . $event->desc), 'url' => null, 'start_date' => $this->Companies->dateToUtc($event->start), 'end_date' => $event->end != 0 ? $this->Companies->dateToUtc($event->end) : $this->Companies->dateToUtc($event->start), 'all_day' => $event->allday ); $this->local->insert("calendar_events", $vars); } $this->local->commit(); $this->endTimer("calendar events"); unset($events); // Import todo events $this->startTimer("todo events"); $events = $this->fetchall ? $this->WhmcsCalendar->getTodos()->fetchAll() : $this->WhmcsCalendar->getTodos(); $this->local->begin(); foreach ($events as $event) { $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'staff_id' => isset($this->mappings['staff'][$event->admin]) ? $this->mappings['staff'][$event->admin] : 0, 'shared' => 0, 'title' => $this->decode($event->title . " " . $event->description), 'url' => null, 'start_date' => $this->Companies->dateToUtc($event->date), 'end_date' => $this->Companies->dateToUtc($event->duedate), 'all_day' => 1 ); $this->local->insert("calendar_events", $vars); } $this->local->commit(); $this->startTimer("todo events"); unset($events); } /** * Load the given local model * * @param string $name The name of the model to load */ protected function loadModel($name) { $name = Loader::toCamelCase($name); $file = Loader::fromCamelCase($name); Loader::load($this->path . DS . "models" . DS . $file . ".php"); $this->{$name} = new $name($this->remote); } /** * Creates a user * * @param array $user An array of key/value pairs including: * - username * - password * - date_added */ private function createUser(array $user) { $this->local->insert("users", $user); return $this->local->lastInsertId(); } /** * Returns the field type * * @param string WHMCS field type * @return string Blesta field type */ private function getFieldType($type) { switch ($type) { case "text": case "textarea": return $type; break; case "dropdown": return "select"; case "tickbox": return "checkbox"; default: return "text"; } } /** * Returns the serialized selection of field values * * @param string WHMCS serialized values * @return string Blesta serialized values */ private function getFieldValues($values) { if ($values == "") return null; $values = explode(",", $values); return serialize(array_combine($values, $values)); } /** * Returns the currency format * * @param int WHMCS currency format value * @return string Blesta currency format value */ private function getCurrencyFormat($format) { switch ($format) { default: case 1: case 2: return "#,###.##"; case 3: return "#.###,##"; case 4: return "#,###"; } } /** * Returns the local tax rule for the given level and rate * * @param int $level * @param float $rate * @return mixed A stdClass object representing the local tax rule, false if no rule exists */ private function getTaxRule($level, $rate) { return $this->local->select()->from("taxes")-> where("company_id", "=", Configure::get("Blesta.company_id"))-> where("level", "=", $level)->where("amount", "=", $rate)->fetch(); } /** * Returns the transaction type ID * * @param string $type The version 2 transaction type * @return string The transaction type ID */ private function getTransactionTypeId($type) { static $trans_types = null; if (!isset($this->Transactions)) Loader::loadModels($this, array("Transactions")); if ($trans_types == null) $trans_types = $this->Transactions->getTypes(); switch ($type) { default: case "other": case "credit": return null; case "cash": case "check": foreach ($trans_types as $trans_type) { if ($trans_type->name == $type) return $trans_type->id; } case "in_house_credit": foreach ($trans_types as $trans_type) { if ($trans_type->name == "in_house_credit") return $trans_type->id; } case "money_order": foreach ($trans_types as $trans_type) { if ($trans_type->name == "money_order") return $trans_type->id; } } return null; } /** * Convert WHMCS service status into Blesta service status * * @param string $status * @return string The service status */ private function getServiceStatus($status) { $status = strtolower($status); switch ($status) { case "active": case "pending": case "suspended": return $status; case "fraud": case "terminated": case "cancelled": return "canceled"; } return "in_review"; } /** * Decrypts data from WHMCS * * @param string $data The data to decrypt * @return string The decrypted data */ private function decryptData($str) { $this->decrypt_count++; $this->unpauseTimer("decrypt"); $key = $this->settings['key']; $y = base64_decode($str); $x = null; // Key derivation $key = sha1(md5(md5($key)) . md5($key)); $temp_key = null; for ($i=0; $i<strlen($key); $i+=2) { $temp_key .= chr(hexdec($key[$i] . $key[$i + 1])); } $key = $temp_key; $key_length = strlen($key); // Extract key seed from input $key_seed = substr($y, 0, $key_length); $y = substr($y, $key_length, strlen($y) - $key_length); // Calculate final key $z = null; for ($i=0; $i<$key_length; $i++) { $z .= chr(ord($key_seed[$i]) ^ ord($key[$i])); } // Decrypt for ($i=0; $i<strlen($y); $i++) { // Generate new key schedule for each block if ($i != 0 && $i % $key_length == 0) { $temp = sha1($z . substr($x, $i - $key_length, $key_length)); $z = null; for ($j=0; $j<strlen($temp); $j+=2) { $z .= chr(hexdec($temp[$j] . $temp[$j+1])); } } $x .= chr(ord($z[$i % $key_length]) ^ ord($y[$i])); } $this->pauseTimer("decrypt"); return $x; } /** * Formats the given key into a mysql AES key * * @param string $key The AES key to format * @return string The mysql formatted AES key */ private function mysqlAesKey($key) { $new_key = str_repeat(chr(0), 16); for($i=0,$len=strlen($key);$i<$len;$i++) { $new_key[$i%16] = $new_key[$i%16] ^ $key[$i]; } return $new_key; } /** * Installs the module row * * @param array $row An array of key/value pairs, including but not limited to: * - type The module name in WHMCS * - id The row ID in WHMCS * @param string $module_type The type of module ('server' or 'registrar') * @return int The module row ID installed (also saved in mappings['modules'] property) */ private function installModuleRow($row, $module_type = "server") { if (!isset($this->ModuleManager)) Loader::loadModels($this, array("ModuleManager")); $mapping = $this->getModuleMapping($row['type'], $module_type); $module_id = $this->installModule($row['type'], $mapping); if (!$module_id) return null; // Install the module row $this->local->insert("module_rows", array('module_id' => $module_id)); $module_row_id = $this->local->lastInsertId(); $this->mappings['module_rows'][$row['type']][$row['id']] = $module_row_id; // Install the module row meta fields if (isset($mapping['module_row_meta'])) { foreach ($mapping['module_row_meta'] as $meta_row) { $vars = (array)$meta_row; $vars['value'] = null; $vars['module_row_id'] = $module_row_id; if (is_object($meta_row->value)) { $row_key = strtolower($meta_row->value->module); if (isset($meta_row->value->module) && array_key_exists($row_key, $row)) $vars['value'] = $row[$row_key]; } else $vars['value'] = $meta_row->value; if (isset($meta_row->callback)) $vars['value'] = call_user_func_array($meta_row->callback, array($vars['value'])); if ($vars['serialized'] == 1) $vars['value'] = serialize($vars['value']); if ($vars['encrypted'] == 1) $vars['value'] = $this->ModuleManager->systemEncrypt($vars['value']); $this->local->insert("module_row_meta", $vars, array("module_row_id", "key", "value", "serialized", "encrypted")); } } return $module_row_id; } /** * Installs the given module and returns the module ID, if already installed simply returns the module ID * * @param string $module The WHMCS module name * @param array An array of mapping fields for this particular module (optional, will automatically load if not given) * @return int The ID of the module in Blesta */ private function installModule($module, $mapping = null) { if (!isset($this->ModuleManager)) Loader::loadModels($this, array("ModuleManager")); if ($mapping == null) $mapping = $this->getModuleMapping($module); // Return module if already mapped if (isset($this->mappings['modules'][$module])) return $this->mappings['modules'][$module]; // Check if module is already installed $mod = $this->local->select(array("id"))->from("modules")-> where("company_id", "=", Configure::get("Blesta.company_id"))-> where("class", "=", $mapping['module'])->fetch(); if ($mod) { $this->mappings['modules'][$module] = $mod->id; return $mod->id; } // Install the module since it does not already exist $module_id = null; try { $vars = array( 'company_id' => Configure::get("Blesta.company_id"), 'class' => $mapping['module'] ); $module_id = $this->ModuleManager->add($vars); } catch (Exception $e) { // Module couldn't be added } $this->mappings['modules'][$module] = (int)$module_id; return $module_id; } /** * Adds package pricing * * @param array $pricing A numerically indexed array of pricing info including: * - term * - period * - price * - setup_fee * - cancel_fee * - currency * @param string $package_id The Blesta package ID to add pricing to */ private function addPackagePricing($pricing, $package_id) { // Add package pricing $pricing_id = null; foreach ($pricing as $price) { if (version_compare(BLESTA_VERSION, "3.1.0-b1", ">=")) { $vars = $price; $vars['company_id'] = Configure::get("Blesta.company_id"); $this->local->insert("pricings", $vars); $pricing_id = $this->local->lastInsertId(); $this->local->insert("package_pricing", array( 'package_id' => $package_id, 'pricing_id' => $pricing_id ) ); $pricing_id = $this->local->lastInsertId(); } else { $vars = $price; $vars['package_id'] = $package_id; $this->local->insert("package_pricing", $vars); $pricing_id = $this->local->lastInsertId(); } } return $pricing_id; } /** * Adds package meta for the given package * * @param array $package An array of package info including: * - id The ID of the package in WHMCS * - * misc package fields * @param array $mapping An array of module mapping config settings */ private function addPackageMeta($package, $mapping) { // Add package meta if (isset($mapping['package_meta'])) { foreach ($mapping['package_meta'] as $meta) { $vars = (array)$meta; $vars['package_id'] = $this->mappings['packages'][$package['id']]; $vars['value'] = null; if (is_object($meta->value)) { if (isset($meta->value->package)) { $meta_key = strtolower($meta->value->package); if (array_key_exists($meta_key, $package)) { $vars['value'] = $package[$meta_key]; if ($meta_key == "password") $vars['value'] = $this->decryptData($package[$meta_key]); } } } else $vars['value'] = $meta->value; if (isset($meta->callback)) $vars['value'] = call_user_func_array($meta->callback, array($vars['value'])); if ($vars['serialized'] == 1) $vars['value'] = serialize($vars['value']); if ($vars['encrypted'] == 1) $vars['value'] = $this->ModuleManager->systemEncrypt($vars['value']); $this->local->insert("package_meta", $vars, array("package_id", "key", "value", "serialized", "encrypted")); } } } /** * Adds service fields * * @param array $service An array of key/value pairs for the remote service including: * - id The ID of the service on the remote server * - * other fields * @param array $mapping An array of module mapping config settings */ private function addServiceFields($service, $mapping) { if (!isset($this->Services)) Loader::loadModels($this, array("Services")); foreach ($mapping['service_fields'] as $key => $field) { $value = array_key_exists($key, $service) ? $service[$key] : null; if ($key == "password" && $value != "") $value = $this->decryptData($value); if (!is_object($field)) continue; if (isset($field->callback)) $value = call_user_func_array($field->callback, array($value)); if ($field->serialized > 0) $value = serialize($value); if ($field->encrypted > 0) $value = $this->Services->systemEncrypt($value); $vars = array( 'service_id' => $this->mappings['services'][$service['id']], 'key' => $field->key, 'value' => $value != null ? $this->decode($value) : "", 'serialized' => $field->serialized, 'encrypted' => $field->encrypted ); $this->local->insert("service_fields", $vars); } } /** * Get the pricing for the given term, package, and currency * * @param array $term An array of term info including: * - term * - period * @param stdClass $package The package in Blesta * @param string $currency The currency to fetch the pricing ID in, will fallback to any currency for the matching term and period * @param string $amount The service amount * @return stdClass An object containing the pricing */ private function getPricing($term, $package, $currency = null, $amount = null) { if (!is_array($term)) return null; $pricing_id = null; if ($package) { foreach ($package->pricing as $price) { if ($price->term == $term['term'] && $price->period == $term['period']) { $pricing_id = $price->id; if ($price->currency == $currency) { return $price; } } } } // If no pricing found, add default pricing $pricing = array( array( 'term' => $term['term'], 'period' => $term['period'], 'currency' => $currency ? $currency : "USD", 'price' => $amount !== null ? $amount : 0, ) ); $pricing_id = $this->addPackagePricing($pricing, $package->id); $fields = array("package_pricing.id", "package_pricing.pricing_id", "package_pricing.package_id", "pricings.term", "pricings.period", "pricings.price", "pricings.setup_fee", "pricings.cancel_fee", "pricings.currency", "packages.taxable"); return $this->local->select($fields)->from("package_pricing")-> innerJoin("pricings", "pricings.id", "=", "package_pricing.pricing_id", false)-> innerJoin("packages", "packages.id", "=", "package_pricing.package_id", false)-> where("package_pricing.id", "=", $pricing_id)->fetch(); } /** * Get the pricing for the given term, option value ID, and currency * * @param array $term An array of term info including: * - term * - period * @param int $value_id The option value ID in Blesta * @param string $currency The currency to fetch the pricing ID in * @return stdClass An object containing the pricing */ private function getOptionPricing($term, $value_id, $currency) { if (!is_array($term)) return null; $fields = array("package_option_pricing.id", "package_option_pricing.pricing_id", "package_option_pricing.option_value_id", "pricings.term", "pricings.period", "pricings.price", "pricings.setup_fee", "pricings.cancel_fee", "pricings.currency"); return $this->local->select($fields)->from("package_option_pricing")-> innerJoin("pricings", "pricings.id", "=", "package_option_pricing.pricing_id", false)-> where("pricings.currency", "=", $currency)-> where("pricings.period", "=", $term['period'])-> where("pricings.term", "=", $term['term'])-> where("package_option_pricing.option_value_id", "=", $value_id)->fetch(); } /** * Returns the local module row ID used for the remote service * * @param int $local_module_id The local ID of the module * @param string $row_value The module row field value for the remote service that uniquely identifies the module row * @param string $remote_module The name of the module on the remote server * @return int The local module row ID for the service */ private function getModuleRowId($local_module_id, $row_value = null, $remote_module = null) { $module_row = false; if ($row_value) { $module_row = $this->local->select(array("module_rows.*"))->from("module_rows")-> innerJoin("module_row_meta", "module_row_meta.module_row_id", "=", "module_rows.id", false)-> where("module_row_meta.value", "=", $row_value)-> where("module_rows.module_id", "=", $local_module_id)->fetch(); } // If no field, attempt to look up module row based on module name, since // the universal module uses the module name to create module rows else { $module_row = $this->local->select(array("module_rows.*"))->from("module_rows")-> innerJoin("modules", "modules.id", "=", "module_rows.module_id", false)-> on("module_row_meta.module_row_id", "=", "module_rows.id", false)-> innerJoin("module_row_meta", "module_row_meta.key", "=", "name")-> where("modules.class", "=", "universal_module")-> where("module_row_meta.value", "=", $remote_module)-> where("module_rows.module_id", "=", $local_module_id)->fetch(); } if ($module_row) { return $module_row->id; } else { $module_row = $this->local->select(array("module_rows.*"))->from("module_rows")-> where("module_rows.module_id", "=", $local_module_id)->fetch(); return $module_row->id; } } /** * Fetch the currency in used by the given client * * @param int $client_id * @return string The currency code for the client */ private function getCurrency($client_id) { if (!isset($this->Clients)) Loader::loadModels($this, array("Clients")); static $currencies = array(); if (!isset($currencies[$client_id])) { $default_currency = $this->Clients->getSetting($client_id, "default_currency"); if ($default_currency) $currencies[$client_id] = $default_currency->value; } // Get currency this client is invoiced in return isset($currencies[$client_id]) ? $currencies[$client_id] : "USD"; } /** * Looks for the TLD of the given domain based on the packages created for the given registrar * * @param string $domain * @param string $registrar The registrar * @return string The TLD */ private function getTld($domain, $registrar) { $tld = $domain; do { $tld = strstr(ltrim($tld, "."), "."); } while (!isset($this->mappings['packages'][$tld . $registrar]) && $tld != ""); return $tld; } /** * Decodes the HTML entities of the given string * * @param string $str The string to decode * @return string The decoded string */ protected function decode($str) { if ($str === null) return $str; return html_entity_decode($str, ENT_QUOTES, "UTF-8"); } /** * Set debug data * * @param string $str The debug data */ protected function debug($str) { static $set_buffering = false; if ($this->enable_debug) { if (!$set_buffering) { ini_set('output_buffering', 'off'); ini_set('zlib.output_compression', false); @ob_end_flush(); ini_set('implicit_flush', true); ob_implicit_flush(true); header("Content-type: text/plain"); header('Cache-Control: no-cache'); $set_buffering = true; } echo $str . "\n"; @ob_flush(); flush(); } } /** * Start a timer for the given task * * @param string $task */ protected function startTimer($task) { $this->task[$task] = array('start' => microtime(true), 'end' => 0, 'total' => 0); } /** * Pause a timer for the given task * * @param string $task */ protected function pauseTimer($task) { $this->task[$task]['end'] = microtime(true); $this->task[$task]['total'] += ($this->task[$task]['end'] - $this->task[$task]['start']); } /** * Unpause a timer for the given task * * @param string $task */ protected function unpauseTimer($task) { $this->task[$task]['start'] = microtime(true); } /** * End a timer for the given task, output to debug * * @param string $task */ protected function endTimer($task) { if ($this->task[$task]['start'] > $this->task[$task]['end']) $this->pauseTimer($task); if ($this->enable_debug) { $this->debug($task . " took: " . round($this->task[$task]['total'], 4) . " seconds"); } } } ?>
-
Yes and also improve the login interface look.
-
hi there,
is it possible to make the login page to look similar to the rest of the website ?
T
-
what if I am using multiple currencies ?
-
Thank you. Thanks for your support once again.
-
Good morning to you all. Can someone please help me with this thanks.
-
importStaff ----------------- importStaff took: 0.0122 seconds ----------------- importClients ----------------- importClients took: 2.9123 seconds ----------------- importContacts ----------------- importContacts took: 0.0071 seconds ----------------- importTaxes ----------------- importTaxes took: 0.0005 seconds ----------------- importCurrencies ----------------- importCurrencies took: 0.0077 seconds ----------------- importInvoices ----------------- importInvoices took: 1.7244 seconds ----------------- importTransactions ----------------- importPackages ----------------- importPackageOptions ----------------- importServices ----------------- importSupportDepartments ----------------- importSupportTickets ----------------- importMisc ----------------- decrypted 0 values using WHMCS' custom algorithm decrypt took: 0 seconds total time took: 9.6978 seconds Array ( [error] => Array ( [0] => The import completed but the following errors ocurred: [1] => importTransactions: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'currency' cannot be null on line 124 [2] => importPackages: There is already an active transaction on line 163 [3] => importPackageOptions: There is already an active transaction on line 163 [4] => importServices: There is already an active transaction on line 163 [5] => importSupportDepartments: There is already an active transaction on line 163 [6] => importSupportTickets: There is already an active transaction on line 163 [7] => importMisc: There is already an active transaction on line 163 ) )
I've tried the SQL checks Cody provided in: http://www.blesta.com/forums/index.php?/topic/3426-whmcs-import-error-option-pricing-id-cannot-be-nul-migration-from-whmcs-5310-to-blesta-32/?hl=option_pricing_id
And also edited the importer to change:
$pricing = $this->getOptionPricing($this->WhmcsServices->getTerm($option->billingcycle), $value_id, $currency);
To:
$pricing = $this->getOptionPricing($this->WhmcsServices->getTerm($option->billingcycle), $value_id, $currency); if (!$pricing) { continue; }
No luck.
-
Thanks Serge. We have it sorted now.
-
Thats great guys. I have been supported well once again. Thank you.
-
thats cool. All fixed thank you Blesta.
-
-
Is this theme available online somewhere ?
-
Is there anyone else here in Melbourne using Blesta ? Is there a Blesta club close by?
I have just joined the forum and so far so good. The supports been great and Blesta excellent. I few bugs here and there but hey I hope to help with fixing a few things along the way.
I once used WH*MCS, so import was done in the last few days.
Anyways, have a great day and talk soon.
T
Update Field With Null
in General
Posted
Good work naja. I see your active posts and information is priceless. Keep up the good work