Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/04/2016 in all areas

  1. I'm not sure why that is either, but I've added CORE-2154 to address it. I see staff listed under gateway logs, though. No staff entry would indicate it was performed by the system.
    2 points
  2. A few years ago, WHMCS didn't have client statements. Not sure if it does now. So I wrote this code and uploaded it to one of my servers. It's a set of custom mysql queries to calculate the amount owed, amount paid and amount of credits. Kind of like a simple bank statement - amount in and amount out, with balance. It takes all the information and uses FPDF to generate a downloadable PDF document. I then made an email template in WHMCS that included the link to the page on my server that served my script. I created MD5 hash from some of the user information, to check against, so that clients wouldn't have to log in when opening the link. When the link is openend, the user gets a download prompt from their browser, asking if they want to download or open the PDF document. The filename is "Statement_YYYY-mm-dd". All these variables can be changed easily, of course, including the date range. I'm attaching the code and a screenshot of what the statement looks like. It's definitely not perfect and probably has some flaws, but maybe it can be modified to work with Blesta. <?php ini_set( 'display_errors', 1 ); ## Path to logo $logo = 'logo_vector_2.jpg'; ## Company/organistion information # Name $org_name = 'Acme'; # Address $org_addr_1 = "Address 1"; $org_addr_2 = "Address 2"; $org_addr_3 = "Ireland"; # Contact information 1 $org_contact_1 = 'Phone: +353 xxxx'; # Tax ID $org_tax_id = "VAT ID: 1234567M"; ## Database information $dbhost = "example.com"; $dbuser = "xxx"; $dbpass = "xxx"; $dbname = "xxx"; $uid = isset( $_REQUEST['uid'] ) ? (int)$_REQUEST['uid'] : NULL; $key = isset( $_REQUEST['key'] ) ? $_REQUEST['key'] : NULL; if ( empty( $uid ) || empty( $key ) ) { die( 'Error: no user ID or access key supplied. The link you entered may have expired.' ); } $mysqli = new mysqli( $dbhost, $dbuser, $dbpass, $dbname ); if ( $mysqli->connect_errno ) { echo "Failed to connect to MySQL: ( " . $mysqli->connect_errno . " ) " . $mysqli->connect_error; exit; } $result = $mysqli->query( "SELECT *, CONCAT( firstname, ' ', lastname, ' (', companyname, ')' ) AS client FROM tblclients WHERE id='$uid' LIMIT 1" ); if ( $result->num_rows !== 1 ) { die( 'Error: we could not access any account data with the information that was provided.' ); } $d = $result->fetch_assoc(); $result->free_result(); $md5 = md5( $d['id'] . ' : ' . $d['client'] . ' : ' . $d['email'] ); if ( $key !== $md5 ) { die( 'Error: the access key provided could not be validated. The link you followed may have expired.' ); } $date = date( 'Y-m-d', mktime( 0, 0, 0, date( 'm' ), date( 'd' ), date( 'Y' ) -6 ) ); $result = $mysqli->query( "SELECT SUM(total) AS total FROM tblinvoices WHERE userid = '$uid' AND DATE_FORMAT(`date`, '%Y-%m-%d') < '$date' AND status != 'Cancelled'" ); $balforward = $result->fetch_array()[0]; $result->free_result(); $result = $mysqli->query( "SELECT SUM(amountin) FROM tblaccounts WHERE userid='$uid' AND DATE_FORMAT(`date`, '%Y-%m-%d') < '$date'" ); $balforward -= $result->fetch_array()[0]; $result->free_result(); $result = $mysqli->query( "SELECT SUM(amount) FROM tblcredit WHERE clientid='$uid' AND DATE_FORMAT(`date`, '%Y-%m-%d') < '$date'" ); $balforward += $result->fetch_array()[0]; $result->free_result(); $result = $mysqli->query( " (SELECT id, ( subtotal + tax ) AS `amount`, DATE_FORMAT(`date`, '%Y-%m-%d') AS `date`, 'Invoice' AS txtype FROM tblinvoices WHERE userid='$uid' AND `date` >= '$date' AND status != 'Cancelled' AND ( subtotal + tax ) != 0) UNION (SELECT id, amountin AS `amount`, DATE_FORMAT(`date`, '%Y-%m-%d') AS `date`, 'Payment' AS txtype FROM tblaccounts WHERE userid='$uid' AND `date` >= '$date') UNION (SELECT id, amount AS `amount`, DATE_FORMAT(`date`, '%Y-%m-%d') AS `date`, 'Credit' AS txtype FROM tblcredit WHERE clientid='$uid' AND `date` >= '$date') ORDER BY `date` ASC " ); $i = array(); $n = 0; $balance = $balforward; while( $r = $result->fetch_assoc() ) { $i[$n] = $r; if ( $r['txtype'] === 'Invoice' ) { $balance += $r['amount']; } else { $balance -= $r['amount']; } $i[$n]['balance'] = number_format( $balance, 2, '.', ',' ); $n++; } $result->free_result(); $mysqli->close(); define( 'FPDF_FONTPATH', '../includes/font/' ); require( '../includes/fpdf.php' ); $pdf = new FPDF(); //Column titles $header = array( 'Date', 'Type', 'ID', 'Amount', 'Balance' ); //Data loading //$data=$pdf->LoadData($i); //$pdf->AddPage(); //$pdf->BasicTable($header,$data); //$pdf->AddPage(); //$pdf->ImprovedTable($header,$data); $pdf->AddPage(); $pdf->Image( $logo, 0, 0 ); $pdf->SetFont( 'Arial', 'B', 10 ); $pdf->Cell( 120, 6, '', 0, 0, 'L' ); $pdf->Cell( 0, 6, $org_name, 0, 0, 'L' ); $pdf->Ln(); $pdf->SetFont( 'Arial', '', 10 ); $pdf->Cell( 120, 6, '', 0, 0, 'L' ); $pdf->Cell( 0, 6, $org_addr_1, 0, 0, 'L' ); $pdf->Ln(); $pdf->Cell( 120, 6, '', 0, 0, 'L' ); $pdf->Cell( 0, 6, $org_addr_2, 0, 0, 'L' ); $pdf->Ln(); $pdf->Cell( 120, 6, '', 0, 0, 'L' ); $pdf->Cell( 0, 6, $org_addr_3, 0, 0, 'L' ); $pdf->Ln( 8 ); $pdf->Cell( 120, 6, '', 0, 0, 'L' ); $pdf->Cell( 0, 6, $org_contact_1, 0, 0, 'L' ); $pdf->Ln(); $pdf->Cell( 120, 6, '', 0, 0, 'L' ); $pdf->Cell( 0, 6, $org_tax_id, 0, 0, 'L' ); $pdf->Ln( 18 ); $pdf->SetFont( 'Arial', '', 14 ); $pdf->Cell( 80, 6, 'Account Statement', 0, 0, 'L' ); $pdf->Cell( 80, 6, gmdate( 'Y-m-d'), 0, 0, 'R' ); $pdf->Ln(10); $pdf->SetFont( 'Arial', 'B', 10 ); $pdf->Cell( 0, 6, $d['client'] ); $pdf->Ln(); $pdf->SetFont( 'Arial', '', 10 ); $pdf->Cell( 0, 6, $d['address1'] . ', '. $d['city'] . ', ' . $d['state'] ); $pdf->Ln( 20 ); //$pdf->FancyTable($header,$data); $data = $i; //Colors, line width and bold font $pdf->SetFillColor( 90, 135, 190 ); $pdf->SetTextColor( 255 ); $pdf->SetDrawColor( 128, 0, 0 ); $pdf->SetLineWidth( .3 ); $pdf->SetFont( '', 'B', 11 ); //Header $w = array( 30, 40, 30, 40, 40 ); for ( $i = 0; $i < count( $header ); $i++ ) $pdf->Cell( $w[$i], 7, $header[$i], 1, 0, 'C', true ); $pdf->Ln(); //Color and font restoration $pdf->SetFillColor( 224, 235, 255 ); $pdf->SetTextColor( 0 ); $pdf->SetFont( '' ); //Data $fill = false; $pdf->Cell( 30, 6, $date, 0, 0, 'L', $fill ); $pdf->Cell( 40, 6, 'Balance Forward', 0, 0, 'C', $fill ); $pdf->Cell( 30, 6, '-', 0, 0, 'L', $fill ); $pdf->Cell( 40, 6, number_format( $balforward, 2, '.', ',' ), 0, 0, 'R', $fill ); $pdf->Cell( 40, 6, number_format( $balforward, 2, '.', ',' ), 0, 0, 'R', $fill ); $pdf->Ln(); foreach( $data as $row ) { $pdf->Cell( 30, 6, $row['date'], 0, 0, 'L', $fill ); $pdf->Cell (40, 6, $row['txtype'], 0, 0, 'C', $fill ); $pdf->Cell( 30, 6, $row['id'], 0, 0, 'L', $fill ); if ( $row['txtype'] === 'Payment' || $row['txtype'] === 'Credit' ) { $pdf->Cell( 40, 6, '-' . $row['amount'], 0, 0, 'R', $fill ); } else { $pdf->Cell( 40, 6, $row['amount'], 0, 0, 'R', $fill ); } $pdf->Cell( 40, 6, $row['balance'], 0, 0, 'R', $fill ); $pdf->Ln(); $fill =! $fill; } $pdf->Cell( array_sum( $w ), 0, '', 'T' ); $pdf->Ln( 20 ); $pdf->Cell( 80, 6, 'Your current account balance is:', 0, 0, 'L' ); $pdf->SetFont( 'Arial', 'B', 13 ); $pdf->Cell( 80, 6, number_format( $balance, 2, '.', ',' ), 0, 0, 'L' ); $pdf->Ln( 8 ); $pdf->SetFont( 'Arial', '', 8 ); $pdf->MultiCell( 150, 6, 'Please note this is not an official invoice. Errors and omissions excepted. Please refer to your invoice for transaction details and tax information. Please contact us with any questions.' ); $pdf->Ln(5); $pdf->Ln(1); header( "Cache-Control: no-cache, must-revalidate" ); // HTTP/1.1 header( "Expires: Sat, 26 Jul 1997 05:00:00 GMT" ); // Date in the past header( "Content-type: application/pdf" ); header( 'Content-Disposition: attachment; filename="Statement_' . gmdate( 'Y_m_d' ) . '.pdf"' ); $pdf->Output( 'Statement_' .gmdate( 'Y_m_d' ) . '.pdf', 'D' );
    2 points
  3. logicbox does not support utf8 caractere . and the adress lenth maximum is 64 . so in logicbox module find elseif ($key == "address-line-1") $vars[$key] = $client->address1; replace it by elseif ($key == "address-line-1") { $client->address1 = str_replace("NÂ", "N", $client->address1); $client->address1 = str_replace("°", ":", $client->address1); $client->address1 = strtr($client->address1,utf8_decode("ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ°º"),"aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn::"); $vars[$key] = substr($client->address1, 0, 63); }
    2 points
  4. cpanel working well , but in a big companies the actual cpanel plugin need some tweaks . actually, the module create account in the server selected in package , or if module groups created , the cpanel module use "first" methode free server to provision the account in it . so no options for staff to choose wish server to host the account . so , what i suggest a option to choose wish server to host the account , if not choosed then use the default method to host account . when thinking in this request make in consideration a park of 5 or 30 servers dedicated to host website . and some times we need to make a manual activation for account in some servers . another time v2, was this option
    1 point
  5. really i can't understand how blesta use date in the system . as we have a different result from v2 and v3 . service date renew is 09-04 . Invoice Days Before Renewal: 7 days both in v2 & v3 . v2 date billed 2-4 v3 date billed 3-4 if i told to my son what is 9 - 7 , he will answer 2 . screenshoot cron setting s & logs
    1 point
  6. Hello it would be helpfull in some case to see a private note for invoice when they are generated by the system Automatically Generated
    1 point
  7. or maybe we can all make it as a plugin
    1 point
  8. If you create a plugin that updates invoices from the Invoices.add event, then yes, it will also affect automatically-generated invoices.
    1 point
  9. in the logs n modules, gateway . the staff column is always empty . we can't know wish one has made the action , system or one of our staff .
    1 point
  10. Services are suspended if they are more than one day (>24 hours) in the past. So in your example, the 1 minute difference would not qualify it as suspendable even if that minute separated two calendar days. That behavior might be a good feature request, though.
    1 point
  11. What is the `invoices`.`date_billed` for that invoice in the database? And what is your timezone set to? v3 of Blesta stores all dates in UTC, so the issue may be that your old dates from v2 were not offset by your timezone.
    1 point
  12. Tyson

    Paypal To Stripe Switch

    We should be able to fix the fatal error you encountered in CORE-2153. However, Stripe thinks you have invalid authentication credentials. You should double-check that your API key is correct, e.g., doesn't contain any unnecessary spaces, etc.
    1 point
  13. Tyson

    Icon On Navigation

    Icons can be added into the client SUB-navigation, but not the primary navigation. See the docs. e.g.: array( 'action'=>"nav_primary_client", 'uri'=>"plugin/download_manager/client_main/", 'name'=>Language::_("DownloadManagerPlugin.client_main", true), 'secondary' => array( 'plugin/download_manager/client_main/' => array( 'name'=>Language::_("DownloadManagerPlugin.client_main", true), 'icon'=>"fa fa-download" ) ) )
    1 point
  14. we can run cron manually , but the action will just run the cron that should be run in the time set to it . it would be a good option to allow admin to force run a cron manually . like the suspend services, this very usefull for a cron that run 1 per day . today , we have found the suspend cron task stacked and has not ended . and no services was suspended . we can't run the cron again until the next day !!! so a option that allow admin force cron to run manually even if is not it time .
    1 point
  15. If a task stalled, it will attempt again in 6 hours. If the issue is caused by an error (e.g. some run-time error), you could remove the log for the offending task and run the cron again manually with error reporting on so you can determine the error and resolve it before the task runs next time. Adding the ability to run cron tasks outside of their scheduled time/interval to run can be dangerous, though, if it was already run today or is still running. You could end up with the same task being performed twice (or more) on identical data. It may be better, especially for your case, to make it easier to restart a stalled task. There have been some suggestions before, including adding a page that lists failed tasks, why they've failed (if available), and an option to restart them.
    1 point
  16. What if we tracked and displayed who created the invoice? ie System or Staff Name? That might be better, because if it's a manual invoice you will know who created it.
    1 point
  17. +1 we also add a lot of notes in invoices on WHMCS, its a must have We need private notes on almost everithing per client/service: -Services- Domains Ouhers/Hosting/Servers -Options- -Invoices- it helps a lot on this buisness @naja7host you are onstopable lol, now that you are on Blesta 3.0 Boat, you are seeing the true functionality missing thanks for all your harde work
    1 point
  18. +1, change due date as an option, we do it a lot in WHMCS, its a must have on any billing
    1 point
  19. ++1 very, very helpfull this
    1 point
  20. Michael

    Client Billing Statement

    Wow looks a mobile statement +1
    1 point
  21. Radix

    Include Js Using Sethtml

    Yes i fixed it. Thanks for the help. I really appreciate it.
    1 point
  22. if anyone want add this to the cpanel module . open cpanel.php module in getAdminAddFields function search $fields = new ModuleFields(); under add the fallowing code // Fetch all available server for this package $module_row = array() ; $rows = array() ; if (isset($package->module_group) && $package->module_group != "") { $rows = $this->getModuleRows($package->module_row); } else { $rows = $this->getModuleRows(); } foreach ($rows as $row){ $module_row[$row->id] = $row->meta->server_name; } // Create Server label $cpanel_server = $fields->label(Language::_("Cpanel.module_row", true), "module_row_id"); // Create Server field and attach to Server label $cpanel_server->attach($fields->fieldSelect("module_row_id", $module_row , $this->Html->ifSet($vars->module_row_id , $package->module_row) , array('id' => "module_row_id"))); // Set the label as a field $fields->setField($cpanel_server); this fucntion will respect the server group if set in package .
    1 point
  23. if this related to the timezone , maybe that other issue we have in suspending services , any other issue related to cron use the wrong date . waiting for blesta team to confirm , and a temporary fix as this is trivial for us .
    1 point
  24. you have remember me for this, in the module for v2 i have made some change . i will check it and back again to give you the solution .
    1 point
  25. Blesta Addons

    Search Result

    when you seach by client criteria . and you have result of multiple page , let say 3 . the result in page 1 is the same as page 2 and 3 . also , when i search with services criteria , i have a search term that return in v2 more than 100 result , but in v3 it return just 20 result (first page) !!!
    1 point
  26. the code you have pas should be like this : $fields->setHtml(" <script type = 'text/javascript' src = '/path-to-js/jquery.min.js'></script> <script type = 'text/javascript'> $(window).load(function(){ $('#selectId').prepend(\"<option value=''>__Select option__</option>\").val(); }); </script> ");
    1 point
  27. Paul

    Client Billing Statement

    Just a note on this. Since this thread was started, we added a setting under Settings > Company > Billing/Payments > Invoice Customization called "Payments/Credits". If this is checked, invoices will show any payments already applied to the invoice. If sending all open invoices to a client, they will be able to see how much is effectively due for each invoice when payments/credits are displayed. The only issue I think, is that it does not show a summary of the total due across all open invoices.
    1 point
  28. RonG

    Client Billing Statement

    It was suggested that I post a request for a Statement Feature by a Besta Support staffer. We genertae a number of recuring invoices per client, per month - AND we also genertate invoices for break/fix site repairs and on-site and off-site support functions - a statement that rolls up all charges in a given billing cycle would be most beneficial to clients
    1 point
  29. mrrsm

    Client Billing Statement

    The code snippit is not that useful unless I am adding it to an existing email or something similar. I am hoping for some client reports that would be editable in the email section. I guess another way it could work would be a plugin that allows you to create email templates, then allow you to email them out to customers on demand or at an interval. That would be more work I would have to do but it would be more flexible.
    1 point
×
×
  • Create New...