Jump to content

Blesta Addons

Alpha Developers
  • Posts

    4,868
  • Joined

  • Last visited

  • Days Won

    390

Everything posted by Blesta Addons

  1. I vote for your 2 cents . For any oposite vision i will use VITO vote .
  2. As mentioned in my first post . This is for using the invoice model . Passing status with the vars will cause a new database request for get() . So i prefer in some cases only work with one shoot
  3. The old version for mobile was wonderfull . Finnaly we will adapt with the new version
  4. i think the same thing for unsuspendServices() , processRenewingServices() , cancelScheduledServices() , addPaidPendingServices() !!!
  5. today i have constated that the Suspension Error email contain the same reason for all error suspensions emails . as the epp registrar retrun they own error , has nothing with cpanel server errors . a sample example . domain suspension error in email in other email for cpanel server i have the same reason . also when i go to the service i found it suspended well . what i suspect is that the cron is not releasing the $errors vars , so in any next service suspension it make it as error in suspension even if he is well suspended . i simple fix is to add unset($errors); under : $output = $this->setOutput(Language::_("Cron.suspendservices.suspend_error", true, $service->id, $service->client_id), $output); i hope is well described .
  6. i see more php files included in the package, are all them concerned to this advisory ? are they are some core-id corrected and fixed ?
  7. Are you sur PDO is enabled in your host . ?
  8. Normally the invoices info8 are generated the time it viewed . Blesta never store invoice . This maybe can be related to clients groups settings !!!.
  9. From database .
  10. This plugin was released before the kb was added in the support manager plugin . For me , it has no sense to have two active kb in the system . I will bring more feature to this plugin only when blesta will add option to disable the kb in support manager. The plugin as it now has the essential features can have .
  11. I have tried to make the same gateway a month ago . Stopped at the same step . I haven't spent a lot of time searching a tips we can go with it . But if i remember well, it was a cunction in the gateway called success i think it grap the response request .
  12. the class is totally clear to understand . the command should be public function add(array $vars, array $packages = null, $notify = false) and what you can pass as vars is explained here /** * Adds a new service to the system * * @param array $vars An array of service info including: * - parent_service_id The ID of the service this service is a child of (optional) * - package_group_id The ID of the package group this service was added from (optional) * - pricing_id The package pricing schedule ID for this service * - client_id The ID of the client to add the service under * - module_row_id The module row to add the service under (optional, default module will decide) * - coupon_id The ID of the coupon used for this service (optional) * - qty The quanity consumed by this service (optional, default 1) * - override_price The price to set for this service, overriding the package pricing value for the selected term (optional, default null) * - override_currency The currency to set for this service, overriding the package pricing value for the selected term (optional, default null) * - status The status of this service (optional, default 'pending'): * - active * - canceled * - pending * - suspended * - in_review * - date_added The date this service is added (default to today's date UTC) * - date_renews The date the service renews (optional, default calculated by package term) * - date_last_renewed The date the service last renewed (optional) * - date_suspended The date the service was last suspended (optional) * - date_canceled The date the service was last canceled (optional) * - use_module Whether or not to use the module when creating the service ('true','false', default 'true', forced 'false' if status is 'pending' or 'in_review') * - configoptions An array of key/value pairs of package options where the key is the package option ID and the value is the option value (optional) * - * Any other service field data to pass to the module * @param array $packages A numerically indexed array of packages ordered along with this service to determine if the given coupon may be applied * @param boolean $notify True to notify the client by email regarding this service creation, false to not send any notification (optional, default false) * @return int The ID of this service, void if error */ now it left what you need to store after the call is successfully done . what i recomand is to initialize the module init and call the module rather than the service add function . a sample code is the fallowing : $this->uses(array("ModuleManager")); $add_services = $this->ModuleManager->moduleRpc($package->module_id, "addService", array(($package, (array)$vars, $parent_package=null, $parent_service=null, $status="pending"))); that was the module will ad the service and store the service fields to the database .
  13. it a one class file ... this is the content <?php /******************************************************************************* @name Kloxo Module (AKA LXAdmin) @author Cody Phillips @date May 12, 2009 @version 1.0 @notes For use with Blesta version 1.0.0+ *******************************************************************************/ class kloxo implements ModuleInterface { private static $module; public function __construct() { // Adds a new Kloxo that can be added, edited, or deleted self::$module = new Module("kloxo", true, true, true); // Adds the given fields to the database for this module if it has not already // been created. WARNING: if the module has already been created with the name // given in the Module constructor you must delete the old module before the // new one will be created. This may have an adverse effect on services. self::$module->addDBField("varchar(255)", "server", "Server"); self::$module->addDBField("varchar(255)", "dnstemplate", "DNS Template"); self::$module->addDBField("varchar(255)", "user", "User Name"); self::$module->addDBField("varchar(255)", "password", "Password"); self::$module->addDBField("varchar(5)", "usessl", "Use SSL", "false"); self::$module->addDBField("int(11)", "max", "Limit", "0"); self::$module->addDBField("int(11)", "cur", "Current", "0"); // Options for creating a new module row // Example: Kloxo module may store multiple different servers. The HTML Fields below // allow you to create/edit a server for the Kloxo module // NOTE: The HTML Fields will appear in the order defined here on the module setup/edit pages self::$module->addModuleHTMLField("text", "Server", "server"); self::$module->addModuleHTMLField("text", "DNS Template", "dnstemplate"); self::$module->addModuleHTMLField("text", "User Name", "user"); self::$module->addModuleHTMLField("text", "Password", "password"); self::$module->addModuleHTMLField("select", "Use SSL", "usessl"); self::$module->addModuleHTMLSelectOption("usessl", "Yes", "true"); self::$module->addModuleHTMLSelectOption("usessl", "No", "false"); self::$module->addModuleHTMLField("text", "Account Limit", "max", "^[0-9]+", "Account Limit must be an integer."); self::$module->addModuleHTMLField("text", "Current Accounts", "cur", "^[0-9]+", "Current Accounts must be an integer."); // Module Options while creating a package with this module // NOTE: Only one field is accepted of this type and must be named "mstring" self::$module->addPackageHTMLField("text", "Plan Name", "mstring", "^(.)+$", "You must enter a plan name."); // This adds a note to be displayed along with the above package field self::$module->addPackageNote("mstring", "Plan Name (ex. bronze)"); // Specify which field from the module table to display in the drop down and give it a friendly name // By default items will be shown by ID and have the friendly name of "Module ID". // This appears when adding or editing a service for a user. self::$module->setModuleRowSelect("DNS Template", "dnstemplate"); // These are shown as column names for each service of this type. self::$module->addServiceColumn("user1", "Domain"); self::$module->addServiceColumn("user2", "Username"); self::$module->addServiceColumn("pass", "Password"); self::$module->addServiceColumn("dnstemplate", "DNS Template"); // These are displayed as tags and are usable when creating/editing a package's welcome e-mail self::$module->addServiceTag("user1", "domain"); self::$module->addServiceTag("user2", "username"); self::$module->addServiceTag("pass", "pass"); self::$module->addServiceTag("term", "term"); // These are the fields that may be edited when performing a local edit on this service self::$module->addServiceEditField("user1", "Domain"); self::$module->addServiceEditField("user2", "Username"); // Client username self::$module->addServiceEditField("pass", "Password"); self::$module->addServiceEditField("plan", "Package/Term"); // Package/Term self::$module->addServiceEditField("dnstemplate", "DNS Template"); self::$module->addServiceEditField("dated", "Date Deleted"); self::$module->addServiceEditField("datep", "Date Suspended"); self::$module->addServiceEditField("dater", "Date Renews"); self::$module->addServiceEditField("notes", "Notes"); // Fields that are shown to the admins when adding a service that uses this module. self::$module->addServiceHTMLField("text", "Domain Name", "user1", "^[a-z0-9._%-]+\.[a-z]{2,6}$", "The domain you entered does not appear to be valid. It should be lowercase and in the format: domain.com."); self::$module->addServiceHTMLField("text", "Password", "pass", "^.{4,16}$", "Passwords must be between 4 and 16 characters."); // Fields that are shown to the user when adding a service that uses this module. self::$module->addUserServiceHTMLField("text", "Domain Name", "user1", "^[a-z0-9._%-]+\.[a-z]{2,6}$", "The domain you entered does not appear to be valid. It should be lowercase and in the format: domain.com."); self::$module->addUserServiceHTMLField("text", "Password", "pass", "^.{4,16}$", "Passwords must be between 4 and 16 characters."); // Creates the module, adds the module to the database if the module table does not // already exist. WARNING: if a module has already been created and you attempt to // add additional fields they WILL NOT BE ADDED, and any refrence to those fields // WILL RESULT IN AN ERROR. self::$module->createModule(); } /** * Returns the module object, this function MUST be present */ public function getModule() { return self::$module; } /** * This is the MAGIC function. This function automatically creates a service * for a user. * * IT MUST BE DEFINED HERE OR AN E-MAIL WILL BE SENT TO ALL SUBSCRIBED ADMINS * NOTIFYING THEM THAT THE SERVICE MUST BE MANUALLY CREATED. * * IF THIS FUNCTION IS DEFINED AND RETURNS TRUE IT IS ASSUMED THAT IT PERFORMS * THE NECCESSARY ACTIONS TO AUTOMATICALLY ACTIVATE THE SERVICE. */ public function promodule($action, $serviceInfo, $packageInfo) { // packageInfo comes from packagesetinfos() function $plan = $packageInfo[4][2]; $conditions = array(array("field" => "id", "value" => $serviceInfo['mid'])); $data = self::$module->getRows($conditions); $serviceInfo['dnstemplate'] = $data[0]['dnstemplate']; $serviceInfo['plan'] = $plan; switch ($action) { case "add": // Ensure we do not exceed the maximum number of accounts for this server. if ($data[0]['cur'] >= $data[0]['max']) return false; $serviceInfo['user2'] = self::makeUserName($serviceInfo['user1']); if (DEMO) return $serviceInfo; elseif ($this->addClient($serviceInfo, $data)) { // Update the current number of accounts on this server self::$module->updateDBFields("cur", $data[0]['cur']+1, $serviceInfo['mid']); return $serviceInfo; // return the info that we want to be inserted into the services table } break; case "remove": if (DEMO) return true; elseif ($this->removeClient($serviceInfo['user2'], $data)) { // Update the current number of accounts on this server self::$module->updateDBFields("cur", $data[0]['cur']-1, $serviceInfo['mid']); return true; } break; case "suspend": if (DEMO) return true; return $this->suspendClient($serviceInfo['user2'], $data); break; case "unsuspend": if (DEMO) return true; return $this->unsuspendClient($serviceInfo['user2'], $data); break; } return false; } /** * Add a client to the VPS system * */ private function addClient(&$serviceInfo, &$data) { $params = array(); $params['login-class'] = "client"; $params['login-name'] = $data[0]['user']; $params['login-password'] = $data[0]['password']; $params['output-type'] = "json"; $params['class'] = "client"; $params['name'] = $serviceInfo['user2']; $params['action'] = "add"; $params['v-password'] = $serviceInfo['pass']; $params['v-type'] = "customer"; $params['v-plan_name'] = $serviceInfo['plan']; $params['v-domain_name'] = $serviceInfo['user1']; $params['v-dnstemplate_name'] = $serviceInfo['dnstemplate']; return $this->request($data[0]['server'], $data[0]['usessl'], $params); } /** * Remove a client from the VPS system * */ private function removeClient(&$username, &$data) { $params = array(); $params['login-class'] = "client"; $params['login-name'] = $data[0]['user']; $params['login-password'] = $data[0]['password']; $params['output-type'] = "json"; $params['class'] = "client"; $params['name'] = $username; $params['action'] = "delete"; return $this->request($data[0]['server'], $data[0]['usessl'], $params); } /** * Suspend a client on the VPS system * */ private function suspendClient(&$username, &$data) { $params = array(); $params['login-class'] = "client"; $params['login-name'] = $data[0]['user']; $params['login-password'] = $data[0]['password']; $params['output-type'] = "json"; $params['class'] = "client"; $params['name'] = $username; $params['action'] = "update"; $params['subaction'] = "disable"; return $this->request($data[0]['server'], $data[0]['usessl'], $params); } /** * Unsuspend a client on the VPS system * */ private function unsuspendClient(&$username, &$data) { $params = array(); $params['login-class'] = "client"; $params['login-name'] = $data[0]['user']; $params['login-password'] = $data[0]['password']; $params['output-type'] = "json"; $params['class'] = "client"; $params['name'] = $username; $params['action'] = "update"; $params['subaction'] = "enable"; return $this->request($data[0]['server'], $data[0]['usessl'], $params); } /* * Prepares and executes a CURL request that performs Kloxo API request * @return response */ private function request($host, &$usessl, &$params) { // Log data received from Kloxo self::$module->logData($params, "input", true); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http" . ($usessl == "true" ? "s" : "") . "://" . $host . "/webcommand.php"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $response = (array)json_decode(curl_exec($ch)); curl_close($ch); // Log data received from Kloxo self::$module->logData($response, "output", ($response['return'] == "success" ? true : false)); if ($response['return'] == "success") return true; return false; } // Creates a username that is between 5 and 8 characters long // Usernames that are generated randomly are 7 characters in length private static function makeUserName($domain) { // Remove everything except letters from the domain $temp = preg_replace('/[^a-zA-Z]/', '', $domain); // If what we have left to build the username is less than 5 characters // add in some random characters to create a unique username. if (strlen($temp) < 5) { // Add 3-random characters followed by the rest of temp. $chars = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t', 'u','v','w','x','y','z'); $count = count($chars) - 1; for ($i=0; $i<3; $i++) $temp = $chars[rand(0, $count)] . $temp; } return substr($temp, 0, 8); } } ?>
  14. UPDATE : the bugs is not related only to voided proforma, also to active proforma invoice . if the status is not set in the $vars , the invoice is converted to active invoice . this will cause a serious law problems for us , as proforma is not paid and converted to invoice, the client is required to pay it even if he doesn't want to renew or pay the services the proforma is for . and the client claim because they have not yet decided to pay or not , and we issue them a invoice without their acceptance . we are working a lot with invoice model , to edit private/public notes, date due ... ect PLEASE A QUICK FIX AS SOON AS POSSIBLE .
  15. i have a task to implement this in my system , and i have the fallowing two shema ways . 1 - option 1 : allow client to select service generate invoice with createFromServices() function , ($due_date = is renew date of service , $services_renew=true ) if the client pay the invoice , the service will be renewed here after a cronjob ? 2 - option 2 : (more complicated) the plugin will create a table that we will store in it the fallowing value ; task_id , invoice_id , services_ids, status allow client to select service or services generate invoice . a cronjob of plugin will check the open tasks that has a invoice in the table is paid totally , if yes, then renew the services attached to that invoice for x times . if task is success mark the status as closed . what do you think about this two ways ?
  16. If a note is issued , The client info related to the note will be fetched from Database or from a saved data ? The invoice can have multiple credit note , credit note should be only associated to a unique invoice . From admin staff , i preffer see a new link "credit note" near to edit , view , pay ... or a new staff action button in client profile , it lead to page listing all the invoices in table with invoice number , invoice date , invoice total due , invoice paid, invoice credit . Credit notes should be visible to all staff with billing permissions and clients . Credit notes amount should be considerated for calculation in revenue and credit/debit of clients . The credit notes should not be in edited once sent to client . A separate pdf for credit note is also accepted . Or group all credit notes for unique invoice in one pdf file .
  17. s this code safe ? $fields = array( "services.*", 'pricings.term', 'packages.id' => "packages_id", 'package_group.package_group_id' => "filled_package_group_id", 'packages.name', 'contacts.company' => "client_company" ); $this->Record->select($fields)-> from("services")-> innerJoin("package_pricing", "package_pricing.id", "=", "services.pricing_id", false)-> innerJoin("pricings", "pricings.id", "=", "package_pricing.pricing_id", false)-> innerJoin("packages", "packages.id", "=", "package_pricing.package_id", false)-> innerJoin("package_group", "package_group.package_id", "=", "packages.id", false)-> innerJoin("clients", "services.client_id", "=", "clients.id", false)-> innerJoin("client_groups", "client_groups.id", "=", "clients.client_group_id", false)-> on("contacts.contact_type", "=", "primary")-> innerJoin("contacts", "contacts.client_id", "=", "clients.id", false); // Filter on client ID if ($service_id != null) $this->Record->where("services.id", "=", $service_id); $this->Record->where("services.status", "!=", "canceled")-> where("services.package_group_id", "=", null); // Ensure only fetching records for the current company $this->Record->where("client_groups.company_id", "=", Configure::get("Blesta.company_id")); $services = $this->Record-> fetchAll(); foreach ($services as $service) $this->Record->where("services.id", "=", $service->id)->update("services", array('package_group_id' => $service->filled_package_group_id));
  18. yes , is a result of importation from v 2.5 i know the solution is to update the services.package_group_id . my concern here that we have more than 10000 services , and i can't play and testing in a live environement , i need a solid php code to update the fields . i hope tyson or cody can give a sample code that can be do the job .
  19. new release , version 1.0.6 . - fixed a bug in the cronjob . - if nothing has been cleaned no email will be sent
  20. still waiting for any help in this subject .
  21. are you moving from blesta v2.5 , i can give you the code you need to do it in the importer blesta file .
  22. pricing per groups/packages is a great option , we have request this in old time .
  23. Any chance to see "free domain" feature neerly . I can sponsor it , we are losing money and customers without this . I havn't the time to look in it or search a custom solution now , really 24 hours is not enough for a 1 day !!!!!
  24. I think is possible , i don't know if is safe to delete completed orders from list after xx days ?
  25. That is perfect ... better than coupons . I was the last days trying to get this done via our custom order type . We have done a great job in this sense we have played with cart event , the only obstacle is the client should be logged . This will be resolved in v4 with the new order forms visibility . When we are 100% success in it i will release my hosting odrer type (real hosting order type) .
×
×
  • Create New...