From 806525e28c287e63e24e0b5e6bb0e1f8a3757364 Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 23 Jun 2014 17:04:23 -0400 Subject: [PATCH 1/6] Fetch service id from whmcs api for upgrades --- .../controllers/BillingController.php | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 3747b2ee7..34590a3e1 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -21,11 +21,12 @@ class BillingController extends Zend_Controller_Action { $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "upgradeproduct"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; - //TODO: do not hardcode - //$postfields["serviceid"] = self::getClientInstanceId(); - $postfields["serviceid"] = "1678"; + + $postfields["serviceid"] = self::getClientServiceId(); + $postfields["type"] = "product"; $postfields["newproductid"] = $formData["newproductid"]; $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; @@ -33,15 +34,17 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $upgrade_query_string = ""; - foreach ($postfields AS $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; //update client info $clientfields = array(); $clientfields["username"] = $credentials["username"]; $clientfields["password"] = md5($credentials["password"]); $clientfields["action"] = "updateclient"; + //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["clientid"] = 1846; + $clientfields["responsetype"] = "json"; unset($formData["newproductid"]); unset($formData["newproductbillingcycle"]); @@ -51,17 +54,22 @@ class BillingController extends Zend_Controller_Action { unset($clientfields["password2verify"]); unset($clientfields["submit"]); $client_query_string = ""; - foreach ($clientfields AS $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; + foreach ($clientfields as $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $client_query_string); - Logging::info($result); + if ($result["result"] == "error") { $this->setErrorMessage(); $this->view->form = $form; } else { - //$result = $this->makeRequest($credentials["url"], $upgrade_query_string); - //self::viewInvoice($result["invoiceid"]); - self::viewInvoice(5108); + $result = $this->makeRequest($credentials["url"], $upgrade_query_string); + if ($result["result"] == "error") { + Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed. - ".$result["message"]); + $this->setErrorMessage(); + $this->view->form = $form; + } else { + self::viewInvoice($result["invoiceid"]); + } } } else { $this->view->form = $form; @@ -102,7 +110,7 @@ class BillingController extends Zend_Controller_Action { { $whmcsurl = "https://account.sourcefabric.com/dologin.php"; $autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"]; - $timestamp = time(); //whmcs timezone? + $timestamp = time(); $client = self::getClientDetails(); $email = $client["email"]; $hash = sha1($email.$timestamp.$autoauthkey); @@ -124,15 +132,17 @@ class BillingController extends Zend_Controller_Action { $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "updateclient"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; + $postfields["responsetype"] = "json"; $postfields = array_merge($postfields, $formData); unset($postfields["password2verify"]); unset($postfields["submit"]); $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $query_string); @@ -165,7 +175,7 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); $this->view->invoices = $result["invoices"]["invoice"]; @@ -178,9 +188,10 @@ class BillingController extends Zend_Controller_Action { self::viewInvoice($invoice_id); } - //TODO: this does not return a service id. why? - private static function getClientInstanceId() + private static function getClientServiceId() { + $service_id = null; + $credentials = self::getAPICredentials(); $postfields = array(); @@ -192,10 +203,21 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); - Logging::info($result); + if (empty($result["products"])) { + Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed - Could not find service id"); + } else { + foreach ($result["products"]["product"] as $product) { + if (array_key_exists("groupname", $product) && $product["groupname"] == "Airtime") { + $service_id = $product["id"]; + } + break; + } + } + + return $service_id; } public static function getProducts() @@ -211,7 +233,7 @@ class BillingController extends Zend_Controller_Action { $postfields["gid"] = "15"; $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); return $result["products"]["product"]; @@ -232,7 +254,7 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $arr = self::makeRequest($credentials["url"], $query_string); return $arr["client"]; From 73724bdd042f2fe9c4be2f90c36f6a4292c86054 Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 24 Jun 2014 12:46:11 -0400 Subject: [PATCH 2/6] Custom fields were not saving --- .../application/controllers/BillingController.php | 7 +++++-- airtime_mvc/application/forms/BillingClient.php | 10 ++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 34590a3e1..92592ccab 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -125,13 +125,16 @@ class BillingController extends Zend_Controller_Action { if ($request->isPost()) { $formData = $request->getPost(); if ($form->isValid($formData)) { - + $credentials = self::getAPICredentials(); $postfields = array(); $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "updateclient"; + + $postfields["customfields"] = base64_encode(serialize($formData["customfields"])); + unset($formData["customfields"]); //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; @@ -140,7 +143,7 @@ class BillingController extends Zend_Controller_Action { $postfields = array_merge($postfields, $formData); unset($postfields["password2verify"]); unset($postfields["submit"]); - + $query_string = ""; foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; diff --git a/airtime_mvc/application/forms/BillingClient.php b/airtime_mvc/application/forms/BillingClient.php index 2b889a52e..d0cb60729 100644 --- a/airtime_mvc/application/forms/BillingClient.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -140,15 +140,16 @@ class Application_Form_BillingClient extends Zend_Form $this->addElement($securityqans); foreach ($client["customfields"] as $field) { - if ($field["id"] == 7) { + if ($field["id"] == "7") { $vatvalue = $field["value"]; - } elseif ($field["id"] == 71) { + } elseif ($field["id"] == "71") { $subscribevalue = $field["value"]; } } - $vat = new Zend_Form_Element_Text('customfield7'); + $vat = new Zend_Form_Element_Text("7"); $vat->setLabel(_('VAT/Tax ID (EU only)')) + ->setBelongsTo('customfields') ->setValue($vatvalue) ->setAttrib('class', 'input_text') //->setRequired(true) @@ -156,9 +157,10 @@ class Application_Form_BillingClient extends Zend_Form ->addFilter('StringTrim'); $this->addElement($vat); - $subscribe = new Zend_Form_Element_Checkbox('customfield71'); + $subscribe = new Zend_Form_Element_Checkbox('71'); $subscribe->setLabel(_('Subscribe to Sourcefabric newsletter')) ->setValue($subscribevalue) + ->setBelongsTo('customfields') ->setAttrib('class', 'input_text') ->setRequired(true) ->addValidator($notEmptyValidator) From 5d69ba5f91cb6d0da5675d6ac1a885c9dd5abf5a Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 24 Jun 2014 12:51:02 -0400 Subject: [PATCH 3/6] Custom fields were not saving --- airtime_mvc/application/controllers/BillingController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 92592ccab..4ade2cd6f 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -45,6 +45,9 @@ class BillingController extends Zend_Controller_Action { //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["clientid"] = 1846; + $clientfields["customfields"] = base64_encode(serialize($formData["customfields"])); + unset($formData["customfields"]); + $clientfields["responsetype"] = "json"; unset($formData["newproductid"]); unset($formData["newproductbillingcycle"]); From 8c205924233de8efa4ea86c991fb122993494583 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Tue, 24 Jun 2014 15:52:43 -0400 Subject: [PATCH 4/6] Start of form customization for billing --- .../controllers/BillingController.php | 72 ++++++----------- .../application/forms/BillingClient.php | 2 +- .../forms/BillingUpgradeDowngrade.php | 11 ++- .../views/scripts/billing/upgrade.phtml | 80 ++++++++++++++++++- airtime_mvc/public/css/billing.css | 33 ++++++++ 5 files changed, 144 insertions(+), 54 deletions(-) create mode 100644 airtime_mvc/public/css/billing.css diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 4ade2cd6f..6cb18550d 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -9,6 +9,10 @@ class BillingController extends Zend_Controller_Action { public function upgradeAction() { + $CC_CONFIG = Config::getConfig(); + $baseUrl = Application_Common_OsPath::getBaseDir(); + $this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']); + $request = $this->getRequest(); $form = new Application_Form_BillingUpgradeDowngrade(); if ($request->isPost()) { @@ -21,12 +25,11 @@ class BillingController extends Zend_Controller_Action { $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "upgradeproduct"; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; - - $postfields["serviceid"] = self::getClientServiceId(); - + //TODO: do not hardcode + //$postfields["serviceid"] = self::getClientInstanceId(); + $postfields["serviceid"] = "1678"; $postfields["type"] = "product"; $postfields["newproductid"] = $formData["newproductid"]; $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; @@ -34,20 +37,15 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $upgrade_query_string = ""; - foreach ($postfields as $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; //update client info $clientfields = array(); $clientfields["username"] = $credentials["username"]; $clientfields["password"] = md5($credentials["password"]); $clientfields["action"] = "updateclient"; - //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["clientid"] = 1846; - - $clientfields["customfields"] = base64_encode(serialize($formData["customfields"])); - unset($formData["customfields"]); - $clientfields["responsetype"] = "json"; unset($formData["newproductid"]); unset($formData["newproductbillingcycle"]); @@ -57,22 +55,17 @@ class BillingController extends Zend_Controller_Action { unset($clientfields["password2verify"]); unset($clientfields["submit"]); $client_query_string = ""; - foreach ($clientfields as $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; + foreach ($clientfields AS $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $client_query_string); - + Logging::info($result); if ($result["result"] == "error") { $this->setErrorMessage(); $this->view->form = $form; } else { - $result = $this->makeRequest($credentials["url"], $upgrade_query_string); - if ($result["result"] == "error") { - Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed. - ".$result["message"]); - $this->setErrorMessage(); - $this->view->form = $form; - } else { - self::viewInvoice($result["invoiceid"]); - } + //$result = $this->makeRequest($credentials["url"], $upgrade_query_string); + //self::viewInvoice($result["invoiceid"]); + self::viewInvoice(5108); } } else { $this->view->form = $form; @@ -113,7 +106,7 @@ class BillingController extends Zend_Controller_Action { { $whmcsurl = "https://account.sourcefabric.com/dologin.php"; $autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"]; - $timestamp = time(); + $timestamp = time(); //whmcs timezone? $client = self::getClientDetails(); $email = $client["email"]; $hash = sha1($email.$timestamp.$autoauthkey); @@ -128,27 +121,22 @@ class BillingController extends Zend_Controller_Action { if ($request->isPost()) { $formData = $request->getPost(); if ($form->isValid($formData)) { - + $credentials = self::getAPICredentials(); $postfields = array(); $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "updateclient"; - - $postfields["customfields"] = base64_encode(serialize($formData["customfields"])); - unset($formData["customfields"]); - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; - $postfields["responsetype"] = "json"; $postfields = array_merge($postfields, $formData); unset($postfields["password2verify"]); unset($postfields["submit"]); - + $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $query_string); @@ -181,7 +169,7 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); $this->view->invoices = $result["invoices"]["invoice"]; @@ -194,10 +182,9 @@ class BillingController extends Zend_Controller_Action { self::viewInvoice($invoice_id); } - private static function getClientServiceId() + //TODO: this does not return a service id. why? + private static function getClientInstanceId() { - $service_id = null; - $credentials = self::getAPICredentials(); $postfields = array(); @@ -209,21 +196,10 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); - if (empty($result["products"])) { - Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed - Could not find service id"); - } else { - foreach ($result["products"]["product"] as $product) { - if (array_key_exists("groupname", $product) && $product["groupname"] == "Airtime") { - $service_id = $product["id"]; - } - break; - } - } - - return $service_id; + Logging::info($result); } public static function getProducts() @@ -239,7 +215,7 @@ class BillingController extends Zend_Controller_Action { $postfields["gid"] = "15"; $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); return $result["products"]["product"]; @@ -260,7 +236,7 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $arr = self::makeRequest($credentials["url"], $query_string); return $arr["client"]; diff --git a/airtime_mvc/application/forms/BillingClient.php b/airtime_mvc/application/forms/BillingClient.php index d0cb60729..8ade507f2 100644 --- a/airtime_mvc/application/forms/BillingClient.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -4,7 +4,7 @@ require_once 'Zend/Locale.php'; class Application_Form_BillingClient extends Zend_Form { public function init() - { + { /*$this->setDecorators(array( array('ViewScript', array('viewScript' => 'form/billing-purchase.phtml'))));*/ $client = BillingController::getClientDetails(); diff --git a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php index 8a7d8a084..10f2b8be7 100644 --- a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php +++ b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php @@ -6,7 +6,7 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form $productPrices = array(); $productTypes = array(); $products = BillingController::getProducts(); - + foreach ($products as $k => $p) { $productPrices[$p["name"]] = array( "monthly" => $p["pricing"]["USD"]["monthly"], @@ -18,23 +18,26 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form //$currentPlanType = ucfirst(Application_Model_Preference::GetPlanLevel()); $currentPlanType = "Hobbyist"; if (($key = array_search($currentPlanType, $productTypes)) !== false) { - unset($productTypes[$key]); + //unset($productTypes[$key]); } $pid = new Zend_Form_Element_Radio('newproductid'); $pid->setLabel(_('Plan type:')) ->setMultiOptions($productTypes) + ->setRequired(true) ->setValue(26); - $this->addElement($pid); - + $this->addElement($pid); + $billingcycle = new Zend_Form_Element_Radio('newproductbillingcycle'); $billingcycle->setLabel(_('Billing cycle:')) ->setMultiOptions(array('monthly' => 'monthly', 'annually' => 'annually')) + ->setRequired(true) ->setValue('monthly'); $this->addElement($billingcycle); $paymentmethod = new Zend_Form_Element_Radio('paymentmethod'); $paymentmethod->setLabel(_('Payment method:')) + ->setRequired(true) ->setMultiOptions(array( 'paypal' => _('PayPal'), 'tco' => _('Credit Card via 2Checkout'))) diff --git a/airtime_mvc/application/views/scripts/billing/upgrade.phtml b/airtime_mvc/application/views/scripts/billing/upgrade.phtml index 6d40d3b0d..c111765b5 100644 --- a/airtime_mvc/application/views/scripts/billing/upgrade.phtml +++ b/airtime_mvc/application/views/scripts/billing/upgrade.phtml @@ -1,8 +1,86 @@ +form; + $form->setAttrib('id', 'upgrade-downgrade'); +?>
+

Account Plans

+
+pricing grid here +
errorMessage)) {?>
errorMessage ?>
Plan Level:
-form ?> + + + +
+ +
+ newproductid ?> +
+
+ newproductbillingcycle ?> +
+
+ paymentmethod ?> +
+ +
+ getSubform("billing_client_info") ?> +
+ firstname?> +
+
+ lastname?> +
+
+ companyname?> +
+
+ email?> +
+
+ address1?> +
+
+ address2?> +
+
+ city?> +
+
+ state?> +
+
+ postcode?> +
+
+ country?> +
+
+ phonenumber?> +
+
+ securityqid?> +
+
+ securityqans?> +
+
+ getElement("7"); ?> +
+
+ getElement("71"); ?> +
+
+ password2?> +
+
+ password2verify?> +
+ +




\ No newline at end of file diff --git a/airtime_mvc/public/css/billing.css b/airtime_mvc/public/css/billing.css new file mode 100644 index 000000000..da9ab49be --- /dev/null +++ b/airtime_mvc/public/css/billing.css @@ -0,0 +1,33 @@ +@CHARSET "UTF-8"; + +#upgrade-downgrade dl +{ + width: 300px; +} + +#upgrade-downgrade dt, #upgrade-downgrade dd +{ + margin: 0px; +} + +#upgrade-downgrade dd +{ + margin-bottom: 10px; +} + +#plantype +{ + float: left; + +} + +#billingcycle +{ + float: left; +} + +#paymentmethod +{ + float: left; + +} \ No newline at end of file From bfb5631105600311caf8f9e412ebf3c693b51f0c Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 24 Jun 2014 16:23:23 -0400 Subject: [PATCH 5/6] Removed hardcoded client ids. Added a function that calculates vat and adds it to an invoice --- .../controllers/BillingController.php | 74 +++++++++++++++---- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 4ade2cd6f..5406ffee5 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -12,7 +12,15 @@ class BillingController extends Zend_Controller_Action { $request = $this->getRequest(); $form = new Application_Form_BillingUpgradeDowngrade(); if ($request->isPost()) { - //$formData = $form->getValues(); + + /* + * TODO: determine if VAT shoould be charged on the invoice or not. + * We'll need to check if a VAT number was supplied in the form and if so, + * validate it somehow. We'll also need to make sure the country given is + * in the EU + */ + $apply_vat = false; + $formData = $request->getPost(); if ($form->isValid($formData)) { $credentials = self::getAPICredentials(); @@ -22,8 +30,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "upgradeproduct"; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["serviceid"] = self::getClientServiceId(); @@ -37,13 +44,13 @@ class BillingController extends Zend_Controller_Action { foreach ($postfields as $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; //update client info + $clientfields = array(); $clientfields["username"] = $credentials["username"]; $clientfields["password"] = md5($credentials["password"]); $clientfields["action"] = "updateclient"; - //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); - $clientfields["clientid"] = 1846; + $clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["customfields"] = base64_encode(serialize($formData["customfields"])); unset($formData["customfields"]); @@ -71,6 +78,9 @@ class BillingController extends Zend_Controller_Action { $this->setErrorMessage(); $this->view->form = $form; } else { + if ($apply_vat) { + $this->addVatToInvoice($result["invoiceid"]); + } self::viewInvoice($result["invoiceid"]); } } @@ -82,6 +92,47 @@ class BillingController extends Zend_Controller_Action { } } + private function addVatToInvoice($invoice_id) + { + $credentials = self::getAPICredentials(); + + //First we need to get the invoice details: sub total, and total + //so we can calcuate the amount of VAT to add + $invoicefields = array(); + $invoicefields["username"] = $credentials["username"]; + $invoicefields["password"] = md5($credentials["password"]); + $invoicefields["action"] = "getinvoice"; + $invoicefields["invoiceid"] = $invoice_id; + $invoicefields["responsetype"] = "json"; + + $invoice_query_string = ""; + foreach ($invoicefields as $k=>$v) $invoice_query_string .= "$k=".urlencode($v)."&"; + + //TODO: error checking + $result = $this->makeRequest($credentials["url"], $invoice_query_string); + + $vat_rate = 19.00; + $vat_amount = $result["subtotal"] * ($vat_rate/100); + $invoice_total = $result["total"] + $vat_amount; + + //Second, update the invoice with the VAT amount and updated total + $postfields = array(); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); + $postfields["action"] = "updateinvoice"; + $postfields["invoiceid"] = $invoice_id; + $postfields["tax"] = "$vat_amount"; + $postfields["taxrate"] = "$vat_rate"; + $postfields["total"] = "$invoice_total"; + $postfields["responsetype"] = "json"; + + $query_string = ""; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + //TODO: error checking + $result = $this->makeRequest($credentials["url"], $query_string); + } + private function setErrorMessage($msg=null) { if (!is_null($msg)) { @@ -139,8 +190,7 @@ class BillingController extends Zend_Controller_Action { $postfields["customfields"] = base64_encode(serialize($formData["customfields"])); unset($formData["customfields"]); - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["responsetype"] = "json"; $postfields = array_merge($postfields, $formData); @@ -177,13 +227,13 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getinvoices"; $postfields["responsetype"] = "json"; - $postfields["userid"] = 1846; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); + $this->view->invoices = $result["invoices"]["invoice"]; } @@ -205,8 +255,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getclientsproducts"; $postfields["responsetype"] = "json"; - $postfields["clientid"] = 1846; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; @@ -255,8 +304,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getclientsdetails"; $postfields["stats"] = true; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["responsetype"] = "json"; $query_string = ""; From d92e5197e1afc92c599531b38d15a40087f340e2 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 25 Jun 2014 18:58:54 -0400 Subject: [PATCH 6/6] Design and overhaul of Account Plans screen * Basically working now except for VAT calculation * Includes pricing grid, basic total calculation * Revamped layout * Implemented getting the service ID in BillingController.php --- airtime_mvc/application/Bootstrap.php | 1 + airtime_mvc/application/configs/constants.php | 6 + .../controllers/BillingController.php | 71 +++++- .../controllers/WhmcsLoginController.php | 3 - .../application/forms/BillingClient.php | 4 +- .../forms/BillingUpgradeDowngrade.php | 18 +- .../views/scripts/billing/client.phtml | 1 + .../views/scripts/billing/upgrade.phtml | 225 +++++++++++++++--- .../views/scripts/partialviews/trialBox.phtml | 2 +- airtime_mvc/public/css/billing.css | 113 ++++++++- 10 files changed, 393 insertions(+), 51 deletions(-) diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index fc9f6c7e4..d66c680c5 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -14,6 +14,7 @@ require_once "DateHelper.php"; require_once "OsPath.php"; require_once "Database.php"; require_once "Timezone.php"; +require_once "Auth.php"; require_once __DIR__.'/forms/helpers/ValidationTypes.php'; require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php'; require_once __DIR__.'/controllers/plugins/Maintenance.php'; diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index 9e2563d0f..69ce78d19 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -64,3 +64,9 @@ define('UI_BLOCK_SESSNAME', 'BLOCK');*/ define('SOUNDCLOUD_NOT_UPLOADED_YET' , -1); define('SOUNDCLOUD_PROGRESS' , -2); define('SOUNDCLOUD_ERROR' , -3); + + +//WHMCS integration +define("WHMCS_API_URL", "https://account.sourcefabric.com/includes/api.php"); +define("SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME", "Choose your domain"); + diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index ffe90234f..e8aeea0f5 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -12,6 +12,7 @@ class BillingController extends Zend_Controller_Action { $CC_CONFIG = Config::getConfig(); $baseUrl = Application_Common_OsPath::getBaseDir(); $this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']); + BillingController::ensureClientIdIsValid(); $request = $this->getRequest(); $form = new Application_Form_BillingUpgradeDowngrade(); @@ -35,7 +36,7 @@ class BillingController extends Zend_Controller_Action { $postfields["action"] = "upgradeproduct"; $postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["serviceid"] = self::getClientServiceId(); + $postfields["serviceid"] = self::getClientInstanceId(); $postfields["type"] = "product"; $postfields["newproductid"] = $formData["newproductid"]; $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; @@ -175,6 +176,7 @@ class BillingController extends Zend_Controller_Action { { $request = $this->getRequest(); $form = new Application_Form_BillingClient(); + BillingController::ensureClientIdIsValid(); if ($request->isPost()) { $formData = $request->getPost(); if ($form->isValid($formData)) { @@ -218,6 +220,7 @@ class BillingController extends Zend_Controller_Action { public function invoicesAction() { + BillingController::ensureClientIdIsValid(); $credentials = self::getAPICredentials(); $postfields = array(); @@ -237,6 +240,7 @@ class BillingController extends Zend_Controller_Action { public function invoiceAction() { + BillingController::ensureClientIdIsValid(); $request = $this->getRequest(); $invoice_id = $request->getParam('invoiceid'); self::viewInvoice($invoice_id); @@ -259,10 +263,52 @@ class BillingController extends Zend_Controller_Action { $result = self::makeRequest($credentials["url"], $query_string); Logging::info($result); + + if ($_SERVER['SERVER_NAME'] == "airtime.localhost") { + return "1384"; + } + //This code must run on airtime.pro for it to work... it's trying to match + //the server's hostname with the client subdomain. + foreach ($result["products"] as $product) + { + if (strpos($product[0]["groupname"], "Airtime") === FALSE) + { + //Ignore non-Airtime products + continue; + } + else + { + if ($product[0]["status"] === "Active") { + $airtimeProduct = $product[0]; + $subdomain = ''; + + foreach ($airtimeProduct['customfields']['customfield'] as $customField) + { + if ($customField['name'] === SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME) + { + $subdomain = $customField['value']; + if (($subdomain . ".airtime.pro") === $_SERVER['SERVER_NAME']) + { + return $airtimeProduct['id']; + } + } + } + } + } + } + throw new Exception("Unable to match subdomain to a service ID"); } public static function getProducts() { + //Making this static to cache the products during a single HTTP request. + //This saves us roundtrips to WHMCS if getProducts() is called multiple times. + static $result = array(); + if (!empty($result)) + { + return $result["products"]["product"]; + } + $credentials = self::getAPICredentials(); $postfields = array(); @@ -279,6 +325,21 @@ class BillingController extends Zend_Controller_Action { $result = self::makeRequest($credentials["url"], $query_string); return $result["products"]["product"]; } + + public static function getProductPricesAndTypes() + { + $products = BillingController::getProducts(); + + foreach ($products as $k => $p) { + $productPrices[$p["name"]] = array( + "monthly" => $p["pricing"]["USD"]["monthly"], + "annually" => $p["pricing"]["USD"]["annually"] + ); + $productTypes[$p["pid"]] = $p["name"] . " ($" . $productPrices[$p['name']]['monthly'] . "/mo)"; + } + return array($productPrices, $productTypes); + } + public static function getClientDetails() { @@ -325,4 +386,12 @@ class BillingController extends Zend_Controller_Action { Logging::info($e->getMessage()); } } + + private static function ensureClientIdIsValid() + { + if (Application_Model_Preference::GetClientId() == null) + { + throw new Exception("Invalid client ID: " . Application_Model_Preference::GetClientId()); + } + } } \ No newline at end of file diff --git a/airtime_mvc/application/controllers/WhmcsLoginController.php b/airtime_mvc/application/controllers/WhmcsLoginController.php index 0f0e327de..2f78ce5ed 100644 --- a/airtime_mvc/application/controllers/WhmcsLoginController.php +++ b/airtime_mvc/application/controllers/WhmcsLoginController.php @@ -1,8 +1,5 @@ setLabel(_('Company Name:')) ->setValue($client["companyname"]) ->setAttrib('class', 'input_text') - ->setRequired(true) + ->setRequired(false) ->addValidator($notEmptyValidator) ->addFilter('StringTrim'); $this->addElement($companyname); @@ -85,7 +85,7 @@ class Application_Form_BillingClient extends Zend_Form $this->addElement($state); $postcode = new Zend_Form_Element_Text('postcode'); - $postcode->setLabel(_('Zip Code:')) + $postcode->setLabel(_('Zip Code / Postal Code:')) ->setValue($client["postcode"]) ->setAttrib('class', 'input_text') ->setRequired(true) diff --git a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php index 10f2b8be7..b89136689 100644 --- a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php +++ b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php @@ -4,17 +4,9 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form public function init() { $productPrices = array(); - $productTypes = array(); - $products = BillingController::getProducts(); - - foreach ($products as $k => $p) { - $productPrices[$p["name"]] = array( - "monthly" => $p["pricing"]["USD"]["monthly"], - "annualy" => $p["pricing"]["USD"]["annually"] - ); - $productTypes[$p["pid"]] = $p["name"]; - } - + $productTypes = array(); + list($productPrices, $productTypes) = BillingController::getProductPricesAndTypes(); + //$currentPlanType = ucfirst(Application_Model_Preference::GetPlanLevel()); $currentPlanType = "Hobbyist"; if (($key = array_search($currentPlanType, $productTypes)) !== false) { @@ -30,7 +22,7 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form $billingcycle = new Zend_Form_Element_Radio('newproductbillingcycle'); $billingcycle->setLabel(_('Billing cycle:')) - ->setMultiOptions(array('monthly' => 'monthly', 'annually' => 'annually')) + ->setMultiOptions(array('monthly' => 'Monthly', 'annually' => 'Annually')) ->setRequired(true) ->setValue('monthly'); $this->addElement($billingcycle); @@ -50,6 +42,8 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form $this->addElement($submit);*/ $client = new Application_Form_BillingClient(); + $client->removeElement("password2"); + $client->removeElement("password2verify"); $this->addSubForm($client, 'billing_client_info'); } } diff --git a/airtime_mvc/application/views/scripts/billing/client.phtml b/airtime_mvc/application/views/scripts/billing/client.phtml index 980288c81..a38b8f685 100644 --- a/airtime_mvc/application/views/scripts/billing/client.phtml +++ b/airtime_mvc/application/views/scripts/billing/client.phtml @@ -1,4 +1,5 @@
+

Account Details

errorMessage)) {?>
errorMessage ?>
successMessage)) {?> diff --git a/airtime_mvc/application/views/scripts/billing/upgrade.phtml b/airtime_mvc/application/views/scripts/billing/upgrade.phtml index c111765b5..8a482ea80 100644 --- a/airtime_mvc/application/views/scripts/billing/upgrade.phtml +++ b/airtime_mvc/application/views/scripts/billing/upgrade.phtml @@ -1,19 +1,162 @@ form; $form->setAttrib('id', 'upgrade-downgrade'); + ?> -
-

Account Plans

+ + +
+

+

-pricing grid here + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HobbyistStarterPlusPremium
1 Stream + 2 Streams + 2 Streams + 3 Streams +
64kbps Stream Quality + 64kbps and 128kbps Stream Quality + 64kbps and 196kbps Stream Quality + 64kbps, 128kbps, and 196kbps Stream Quality +
5 Listeners + 40 Listeners per stream + 100 Listeners per stream + 500 Listeners per stream +
2GB Storage + 5GB Storage + 30GB Storage + 150GB Storage +
Ticket, Email, Forum Support + Live Chat, Ticket, Email, Forum Support + Live Chat, Ticket, Email, Forum Support + Live Chat, Ticket, Email, Forum Support +
+ Save 15% if paid annually + Save 15% if paid annually + Save 15% if paid annually +
+ + + +
-errorMessage)) {?> -
errorMessage ?>
- -
Plan Level:
- - + +

Current Plan: +

+

Choose a plan:

@@ -23,36 +166,51 @@ pricing grid here
newproductbillingcycle ?>
-
- paymentmethod ?> +
+ Save 15% on annual plans (Hobbyist plan excluded). +
+
+
Total:
+ +
+ Plus VAT if you are an EU resident without a valid VAT number.
-
+

Enter your payment details:

+ errorMessage)) {?> +
errorMessage ?>
+ + + getSubform("billing_client_info") ?> -
+
firstname?>
-
+
lastname?>
-
+
+
companyname?>
-
+
email?>
-
+
+
address1?>
-
+
address2?> -
-
+
+
+
city?>
-
+
state?>
+
postcode?>
@@ -68,19 +226,30 @@ pricing grid here
securityqans?>
+

VAT will be added to your invoice if you are an EU resident without a valid VAT number.

+
getElement("7"); ?>
+
+
- getElement("71"); ?> + getElement("71"); ?> +
+ getElement("71")->renderViewHelper(); ?> +
+ getElement("71")->renderLabel(); ?>
-
- password2?> +
+ +

After submitting your order, you will be redirected to an invoice with payment buttons.

-
- password2verify?> +
+ paymentmethod ?>
- + +
+ +
-



\ No newline at end of file diff --git a/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml b/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml index 691d2983a..c0abffc89 100644 --- a/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml +++ b/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml @@ -6,7 +6,7 @@
diff --git a/airtime_mvc/public/css/billing.css b/airtime_mvc/public/css/billing.css index da9ab49be..c34e8ad49 100644 --- a/airtime_mvc/public/css/billing.css +++ b/airtime_mvc/public/css/billing.css @@ -1,5 +1,28 @@ @CHARSET "UTF-8"; +.billing-panel +{ + width: 400px; + margin: 0 auto; + margin-bottom: 30px; +} + +#upgrade-downgrade +{ + border: 0px solid #000; + margin: 0 auto; + color: #000; +} + +#upgrade-downgrade label +{ + color: rgb(28,28,28); +} +#upgrade-downgrade label.disabled +{ + color: rgb(108,108,108); +} + #upgrade-downgrade dl { width: 300px; @@ -15,19 +38,101 @@ margin-bottom: 10px; } +.pricing-grid table +{ + border-spacing: 0px; + border-collapse: separate; + border: 1px solid #777; + width: 600px; + margin-left: -100px; + /*background-color: #555;*/ + table-layout: fixed; + margin-top: 20px; + margin-bottom: 20px; + box-shadow: 0px 5px 5px rgba(0,0,0,0.5); +} + +.pricing-grid td, .pricing-grid th +{ + border-bottom: 1px solid #999; + border-right: 1px solid #bbb; + background-color: #ccc; + padding: 10px; +} + +.pricing-grid th +{ + border-top-left-radius: 5px; + border-top-right-radius: 5px; + border: 0px; +} + + +.pricing-grid tr.price td +{ + text-align: right; + background-color: #ddd; + font-weight: bold; +} + +#current_plan +{ + text-align: center; +} + #plantype { - float: left; - + float: left; } #billingcycle { float: left; + margin-left: 30px; +} + +#billingcycle_disclaimer +{ + float: left; + margin-left: 30px; + width: 200px; +} + +#vat_disclaimer +{ + text-align: right; + font-size: 0.9em; + margin-bottom: 30px; +} + +#total_box +{ + text-align: right; + margin-top: 30px; + margin-bottom: 10px; + border: 1px solid #777; + background: #ccc; + padding: 5px; } #paymentmethod { - float: left; - +} + +.billing_col1, .billing_col2 +{ + float: left; + margin-right: 10px; +} + +.billing_checkbox +{ + float: left; + margin-right: 5px; + margin-bottom: 10px; +} + +#upgrade-downgrade input[type=submit] +{ + float: right; } \ No newline at end of file