Jump to content
Sign in to follow this  
Dgital Essence

Display all customers sticky notes on Admin Summary page

Recommended Posts

Hi,

 

I'm not sure if this has already been done but I use Sticky Notes to record additional work that needs to be invoiced at a later date but kept on forgetting who I'd done extra work for.

 

So I've created a widget for the Admin Summary page that displays all the Sticky Notes with links through to the Customers Note and also the customer summary.

 

sticky_notes.jpg

 

Just create a new file in modules/widgets and paste this code in. Then head over to Setup > Staff Management > Administrator Roles > Edit and scroll down to Widgets and then tick yours (in this example it's called "Display Customer\'s Sticky Notes".

 

This was created in Version: 5.3.11 and is still working in 6.1.1 but it if breaks yours or makes the sky fall down, I'm not liable...

 

?php
# WHMCS Widget to display sticky notes on the Admin Summary
# Hedley Phillips - Digital Essence
if (!defined("WHMCS"))
   die("This file cannot be accessed directly");

function widget_display_sticky_notes() {

$content = '<table bgcolor="#cccccc" align="center" style="margin-bottom:5px;width:100%;" cellspacing="1">
<tr bgcolor="#efefef" style="text-align:center;font-weight:bold;"><td>Customer</td><td>Note</td><td>Modified</td></tr>';

$x=1; $range = "<= 364";
   $result = mysql_query("SELECT * FROM `tblnotes` JOIN tblclients ON tblclients.id=tblnotes.userid  WHERE `sticky` = '1'");
   while ($data = @mysql_fetch_array ($result)) {
        $noteid = $data["id"];
        $userid = $data["userid"];
        $firstname = $data["firstname"];
        $lastname = $data["lastname"];
        $note = $data["note"];
        $date = $data["modified"];
       $content .= '<tr bgcolor="#ffffff" style="text-align:center;"><td><a href="/whmcsadmin/clientssummary.php?userid='.$userid.'">'.$firstname. ' ' .$lastname.'</a></td><td><a href="/whmcsadmin/clientsnotes.php?userid='.$userid.'&action=edit&id='.$noteid.'">'.$note.'</a></td><td>'.$date.'</td></tr>'; $x=0;
   }
   if($x) $content =  '<tr bgcolor="#ffffff" style="text-align:center;"><td colspan="7">No Sticky Notes to display</td></tr>';
   $content .= '</table>';

   return array( 'title' => 'Display Customer\'s Sticky Notes', 'content' => $content );
}

add_hook("AdminHomeWidgets",1,"widget_display_sticky_notes");

?>  

 

NOTE:

 

What I can't get to work and am looking for input from others on is the edit function.

 

I'm using:

 

<a href="/whmcsadmin/clientsnotes.php?userid='.$userid.'&action=edit&id='.$noteid.'">  

 

where:

 

$noteid = $data["id"];

$userid = $data["userid"];

 

but it keeps on putting the customer id in both $userid and $noteid and I can't work out why.

Share this post


Link to post
Share on other sites
What I can't get to work and am looking for input from others on is the edit function - it keeps on putting the customer id in both $userid and $noteid and I can't work out why.

it was because your SQL query contained two different 'id' fields and it was using the wrong one.

 

i've taken the liberty of cleaning up the widget code...

 

<?php
# WHMCS Widget to display sticky notes on the Admin Summary
# Hedley Phillips - Digital Essence
if (!defined("WHMCS"))
   die("This file cannot be accessed directly");

function widget_sticky_notes() {
       global $_ADMINLANG;

   $content = '<table bgcolor="#cccccc" align="center" style="margin-bottom:5px;width:100%;" cellspacing="1"><tr bgcolor="#efefef" style="text-align:center;font-weight:bold;"><td>'.$_ADMINLANG['fields']['client'].'</td><td>'.$_ADMINLANG['fields']['note'].'</td><td>'.$_ADMINLANG['fields']['lastmodified'].'</td></tr>';

   $x=1;
   $result = mysql_query("SELECT tblnotes.id,tblnotes.userid,tblnotes.modified,tblnotes.note,tblnotes.sticky,tblclients.firstname,tblclients.lastname FROM `tblnotes` JOIN tblclients ON tblclients.id=tblnotes.userid WHERE `sticky` = '1'");
   while ($data = @mysql_fetch_array ($result)) {
        $noteid = $data["id"];
        $userid = $data["userid"];
        $firstname = $data["firstname"];
        $lastname = $data["lastname"];
        $note = $data["note"];
        $date = $data["modified"];
       $content .= '<tr bgcolor="#ffffff" style="text-align:center;"><td><a href="clientssummary.php?userid='.$userid.'">'.$firstname. ' ' .$lastname.'</a></td><td><a href="clientsnotes.php?userid='.$userid.'&action=edit&id='.$noteid.'">'.$note.'</a></td><td>'.$date.'</td></tr>';
       $x=0;
   }
   if($x) $content =  '<p style="text-align:center;">No Sticky Notes to display';
   $content .= '</table>';

   return array( 'title' => 'Sticky Notes', 'content' => $content );
}

add_hook("AdminHomeWidgets",1,"widget_sticky_notes");

?>

Edited by brian!

Share this post


Link to post
Share on other sites
it was because your SQL query contained two different 'id' fields and it was using the wrong one.

 

i've taken the liberty of cleaning up the widget code...

 

Liberty? The pleasure is all mine ;-)

 

Although I'm testing this and still seeing the same

 

The URL created is:

 

Before:

http://mydomain/whmcsadmin/clientsnotes.php?userid=59&action=edit&id=59

 

 

After:

http://mydomain/whmcsadmin/clientsnotes.php?userid=59&action=edit&id=59

Share this post


Link to post
Share on other sites

ah - that might be occurring because I changed the widget name and title in the code - it's definitely working here! :idea:

 

try the following - same code, but i've used your widget name and title...

 

<?php
# WHMCS Widget to display sticky notes on the Admin Summary
# Hedley Phillips - Digital Essence
if (!defined("WHMCS"))
   die("This file cannot be accessed directly");

function widget_display_sticky_notes() {
       global $_ADMINLANG;

   $content = '<table bgcolor="#cccccc" align="center" style="margin-bottom:5px;width:100%;" cellspacing="1"><tr bgcolor="#efefef" style="text-align:center;font-weight:bold;"><td>'.$_ADMINLANG['fields']['client'].'</td><td>'.$_ADMINLANG['fields']['note'].'</td><td>'.$_ADMINLANG['fields']['lastmodified'].'</td></tr>';

   $x=1;
   $result = mysql_query("SELECT tblnotes.id,tblnotes.userid,tblnotes.modified,tblnotes.note,tblnotes.sticky,tblclients.firstname,tblclients.lastname FROM `tblnotes` JOIN tblclients ON tblclients.id=tblnotes.userid WHERE `sticky` = '1'");
   while ($data = @mysql_fetch_array ($result)) {
        $noteid = $data["id"];
        $userid = $data["userid"];
        $firstname = $data["firstname"];
        $lastname = $data["lastname"];
        $note = $data["note"];
        $date = $data["modified"];
       $content .= '<tr bgcolor="#ffffff" style="text-align:center;"><td><a href="clientssummary.php?userid='.$userid.'">'.$firstname. ' ' .$lastname.'</a></td><td><a href="clientsnotes.php?userid='.$userid.'&action=edit&id='.$noteid.'">'.$note.'</a></td><td>'.$date.'</td></tr>';
       $x=0;
   }
   if($x) $content =  '<p style="text-align:center;">No Sticky Notes to display';
   $content .= '</table>';

   return array( 'title' => 'Display Customer\'s Sticky Notes', 'content' => $content );
}

add_hook("AdminHomeWidgets",1,"widget_display_sticky_notes");

?>

Share this post


Link to post
Share on other sites

one further update - the date format was annoying me, so it's now set to use the Admin date settings. :idea:

 

<?php
# WHMCS Widget to display sticky notes on the Admin Summary
# Hedley Phillips - Digital Essence
if (!defined("WHMCS"))
   die("This file cannot be accessed directly");

function widget_sticky_notes() {
       global $_ADMINLANG;

   $content = '<table bgcolor="#cccccc" align="center" style="margin-bottom:5px;width:100%;" cellspacing="1"><tr bgcolor="#efefef" style="text-align:center;font-weight:bold;"><td>'.$_ADMINLANG['fields']['client'].'</td><td>'.$_ADMINLANG['fields']['note'].'</td><td>'.$_ADMINLANG['fields']['lastmodified'].'</td></tr>';

   $x=1;
   $result = mysql_query("SELECT tblnotes.id,tblnotes.userid,tblnotes.modified,tblnotes.note,tblnotes.sticky,tblclients.firstname,tblclients.lastname FROM `tblnotes` JOIN tblclients ON tblclients.id=tblnotes.userid WHERE `sticky` = '1'");
   while ($data = @mysql_fetch_array ($result)) {
        $noteid = $data["id"];
        $userid = $data["userid"];
        $firstname = $data["firstname"];
        $lastname = $data["lastname"];
        $note = $data["note"];
        $date = $data["modified"];
       $content .= '<tr bgcolor="#ffffff" style="text-align:center;"><td><a href="clientssummary.php?userid='.$userid.'">'.$firstname. ' ' .$lastname.'</a></td><td><a href="clientsnotes.php?userid='.$userid.'&action=edit&id='.$noteid.'">'.$note.'</a></td><td>'.fromMySQLDate($date,$date).'</td></tr>';
       $x=0;
   }
   if($x) $content =  '<p style="text-align:center;">No Sticky Notes to display';
   $content .= '</table>';

   return array( 'title' => 'Sticky Notes', 'content' => $content );
}

add_hook("AdminHomeWidgets",1,"widget_sticky_notes");

?>

Share this post


Link to post
Share on other sites

Is this script provided by Dgital and corrected by brian work?

 

I mean also I want to show sticky note to all customers. I already use homepage.tpl to display but want to display note from admin area.

Share this post


Link to post
Share on other sites
Is this script provided by Dgital and corrected by brian work?

it's working quite happily on my v6 dev site :idea:

 

Screenshot_26.png

 

I mean also I want to show sticky note to all customers. I already use homepage.tpl to display but want to display note from admin area.

are you sure - Admin notes tend to be private for admins only...?

 

http://docs.whmcs.com/Clients:Emails/Notes/Logs_Tabs

 

Notes tab

 

Here staff can enter private notes about the client to be displayed to whoever views this Notes tab. The tab itself will display the number of notes in brackets. Separate notes sections are available available under the Products/Services, Domains and Profile tab.

 

Tick the Make Sticky checkbox and this note will be displayed throughout the client's account and on any tickets they submit in the admin area.

there's nothing to stop you from doing it (as it's just a query to the database), i'm just unsure if we're talking about the same thing, or whether you're talking about Notifications or a Home Page Panel ?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Similar Content

    • By JesusSuarz
      I hope someone has knowledge about this ..
      I find very little information about it. I hope someone helps me.
      I am trying to prevent users from being able to change some fields in their profile.
      I found the following function:
      https://developers.whmcs.com/hooks-reference/everything-else/#customfieldsave
      <?php add_hook('CustomFieldSave', 1, function($vars) { return array('value' => 'overridden value',); }); this prevents any field from being editable,
      however, how can I select a specific field?
      img: 

      someone posted an idea in 2019.
      however it doesn't work, because fieldid and relid return NULL from $vars
      any idea?
      I just need to select the fields that I want to prevent from being edited.
       
       
    • By Huseyin Telli
      Hello, I am designing a custom order form for myself in whmcs. I changed the domain name selection part when purchasing hosting. I did as in the attached image. The transfer part is not working. In the transfer part, it performs the domain inquiry part. However, when I click the continue button, the domain configuration page does not appear. In other words, the page where I will enter the transfer code does not open, it transfers it directly to the cart. The domain name I selected for the product does not appear in the cart. I will show them all in the appendices below. If it is a javascript-related problem, if there is javascript code that I need to share, if you let me know in the comments, I will share it. I don't know exactly what is causing the problem. I would be glad if you help. Thanks in advance.. 
       



    • By JesusSuarz
      whmcs dismisses the best ideas?
      for developers trying to create a better ecosystem for whmcs "they discard the best ideas"
      to get into context, some time ago while working with the whmcs API, I noticed that whmcs does not allow including "custom files within /includes/api"
      I'll leave a link on what I had to do to achieve it: 
      which is absurd if you think about it.
      if they allowed to include files (within the api roles) they would allow other developers to join the project and add new functions that WHMCS does not yet have.
      now I take it that someone posted the exact same question but it was discarded:  https://requests.whmcs.com/idea/custom-api-support
      it is very obnoxious that the WHMCS team does not allow one to create their own api functions.
      it is unfortunate that they do not listen to users.
      It is unfortunate that the vision of whmcs is not to allow the use of its software as a means of administration, but that we generate our own functions for our projects (in the case of my company, a laravel project).
      I wonder if the WHMCS team really listens to users.
      I wonder if they ever have ...
      I am very disappointed that whmcs does not allow the newly added files to appear in the api folder as shown in these images:
       

       

       
      as you can see from the images, we are unable to assign the role of the new file.
      instead I had to modify the table: tblapi_roles within my database directly to manually give the file permissions.
      WHMCS DOES NOT LISTEN TO ITS CUSTOMERS, WHMCS IS NOT INTERESTED IN THAT WE DO BETTER PROJECT, NOR THAT THE ECOSYSTEM IS IMPROVED!
      If an admin reads this topic, please understand that I am looking for WHMCS to be used more by developers.
      Currently we live very limited, the documentation and all the files written in / includes/api lack many features that we developers could include.
      We could provide more external functionalities. and we would have the ability to develop our own characteristics.
      this would open the doors much more for new customers to join in purchasing whmcs licenses.
      In addition to increasing sales of whmcs, it would also allow the possibility of writing our own characteristics, developing new modules that we would publish in the marketplace ecosystem, increasing the number of modules and characteristics that WHMCS currently has.
      I hope this topic has relevance to both whmcs and external developers.
      my point of view is that if they allow "Role Management" to detect the files included in /includes/api as roles. (similar to how it works when we add modules and plugins that automatically appear in the whmcs module manager). it would open new doors for developers.
      I am sure that this functionality could be done with a few lines and in a short time. as a developer I know that this would not take too much work.
      I hope they understand me. my english is not very good. 🙂
       
    • By Cubeboy
      this is a snippet of my quote/contract script
      it seems to know the recurring but not the onetime, it shows the "unit price" but no the "total price
      I need to have the one time and payments show up in the contract
      the 2 hooks you need to add in
      //term is the call 
      // 1 displays the number of months
      [term: 1]
      [recur:36]
      <?php
      $pdf->Image(ROOTDIR.'/assets/img/rwclogo.png', 63,10,75,'c');
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','B',11);
      $pdf->Cell(175,40,"CONTRACT FOR $subject ONLINE MARKETING SERVICES",25,1,'C');
      $total_onetime = 0;
      $total_recur = array();
      foreach ($lineitems AS $item) {
       
      $description = $item["description"]; 

      # find term 
      $matches = array();
      preg_match('/\[term:(.*?)\]/i', $description, $matches); 
      if (empty($matches)) { 
      $term = ''; 
      }
      else { 
      $term = strtolower(trim($matches[1])); 
      $description = str_replace($matches[0], '', $description); 
      }

      # find recur 
      $matches = array();
      preg_match('/\[recur:(.*?)\]/i', $description, $matches); 
      if (empty($matches)) { 
      $recur = ''; 
      }
      else { 
      $recur = strtolower(trim($matches[1])); 
      $description = trim(str_replace($matches[0], '', $description)); 
      }

      # get unit price and total price 
      $matches = array(); 
      preg_match('/\d+\.\d+/', $item['unitprice'], $matches); 
      $item_unitprice = (float)$matches[0];
      $matches = array(); 
      preg_match('/\d+\.\d+/', $item['total'], $matches); 
      $item_total = (float)$matches[0];
       
      # add onetime and recurring totals
       
      if ($recur == '') { 
      $total_onetime += $item_total; 
      }
      else { 
      if (!array_key_exists($recur, $total_recur)) { 

      $total_recur[$recur] = 0; 
      }

      $total_recur[$recur] += $item_total; 
      }
      }
      $pdf->SetFont('freesans','B',9);
      if ($total_onetime > 0) { 
      }
      foreach (array('monthly', 'quarterly', 'semi-annually', 'annually', 'biennially') as $recur) { 
      if (isset($total_recur[$recur]) && $total_recur[$recur] > 0) { 
      }
      unset($total_recur[$recur]);
      }
      # any remaining recurs
      foreach ($total_recur as $recur => $amount) { 
      }
      #==========================================================================
      # determine weather to show the ONE TIME payment or not
      #if ( $total_onetime < 100 ) {
      #$ot_show = false;
      #} 
      #else {
      #$ot_show = true;
      #}

      #==========================================================================
      # determines weather or not to split the initial payment in half
      #if ( $total_onetime >= 10000 ) {
      #$bulk = $total_onetime / 2;
      #$addtl_payment_msg = 'and the second half of $' .$bulk. ', will be due within 60 days. ';
      #} else {
      #$bulk = $total_onetime;
      #$addtl_payment_msg = '';
      }
      #==========================================================================
      #calculate One time payment using monthly pymts as a varible
      #==========================================================================
      #$otpp = ( $total_recur[$recur] * $recur );
      #$ots = ( $otpp * .1);
      #$ots = round( $ots, 2, PHP_ROUND_HALF_UP );
      #$otp = $otpp - ($otpp * .1);
      #$otp = round( $otp, 2, PHP_ROUND_HALF_UP );
      #==========================================================================
      #calculate One time payment and monthly payment to come up with a total
      #$totalot = ( $total_recur[$recur] * $recur + $bulk );
      #$totalot10 = ( $totalot - $ots );
      #==========================================================================
      $pdf->SetDrawColor(255);
      $pdf->SetFillColor(255);
      $pdf->SetFont('freesans','B',9);
      $pdf->Cell(170,5,"Authorization:",0,0,'L');
      $pdf->SetFont('freesans','',9);
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','',9,C); 
      $pdf->MultiCell(170,5,"
      This document defines the TERMS AND CONDITIONS (T&C) of our working relationship. All projects or services (“the work”) that AGENCY (or “we”) RWC ME 04401 may be contracted to produce or provide for CLIENT ($clientsdetails[companyname]) will be subject to and you the undersigned agree to the following:
      The CLIENT authorizes the AGENCY access CLIENT's current website, webhost, and all digital materials to transfer as needed from the CLIENT for the purposes of completeing the work on the domain $subject. The CLIENT authorizes use of CLIENT's logo and all brand identification in the creation of the website. The CLIENT understands they are entering into a$pdf->Cell $recur month contract with THE AGENCY.    
      The Agency will only begin work after CLIENT’s approval of the project authorization to proceed,(ATP) and the terms and conditions,(T&C) and after receipt of payment of the initial invoice $".$total_onetime.  ". Your signature/execution of the ATP and the T&C will constitute an AGREEMENT between us. 
                                                                                                                       ");
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','B',9);
      $pdf->Cell(170,5,"Description of the work:",0,0,'L');
      $pdf->SetFont('freesans','',9);
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','',9,L); 
      $pdf->MultiCell(170,5,"$notes",0,1,'C');

      if ($proposal) {
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','B',9);
      $pdf->Cell(170,5,"Installment Plan:",0,0,'L');
      $pdf->SetFont('freesans','',9);
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','',9,L); 
      $pdf->MultiCell(170,5,$proposal                  );
      }
      $pdf->AddPage();
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','B',9);
      $pdf->Cell(170,5,"Approvals:",0,0,'L');
      $pdf->SetFont('freesans','',9);
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','',9,L); 
      $pdf->MultiCell(170,5,"
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','B',9);
      $pdf->Cell(170,5,"Additions and Alterations:",0,0,'L');
      $pdf->SetFont('freesans','',9);
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','',9,C); 
      $pdf->MultiCell(170,5,"                              ");
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','B',9);
      $pdf->Cell(170,5,"Payments:",0,0,'L');
      $pdf->SetFont('freesans','',9);
      $pdf->MultiCell(170,5,"");
      $pdf->SetFont('freesans','',9,L); 
      $pdf->MultiCell(170,5,"The AGENCY is providing Online Marketing Services in advance of total payment. The CLIENT will have an initial down payment of $" . $bulk . ". that is due at the signing of this contract, " .$addtl_payment_msg. "Then an ongoing payment of $pdf->Cell $$total_recur[$recur], on a monthly basis for the following$pdf->Cell $recur months, starting from the date of signing this agreement.                                " );
      $pdf->MultiCell(170,5,"");
      $pdf->AddPage();
      $pdf->Image(ROOTDIR.'/assets/img/rwclogo.png', 63,10,75,'c');
      $pdf->SetFont('freesans','B',11);
      $pdf->Ln();

      $pdf->SetFont('freesans','B',9);
      $pdf->Ln();
      $pdf->SetFont('freesans','',9);
      $pdf->MultiCell(39,5,"");
      $pdf->Ln();
      $pdf->SetFont('freesans','B',9);
      $pdf->SetDrawColor(200);
      $pdf->SetFillColor(239);
      $pdf->SetFont('freesans','',9);
      $pdf->Cell(10,6,"Qty",1,0,'C','1');
      $pdf->Cell(80,6,"Description",1,0,'C','1');
      $pdf->Cell(20,6,"Recur",1,0,'C','1');
      $pdf->Cell(20,6,"Term",1,0,'C','1');
      $pdf->Cell(20,6,"Unit Price",1,0,'C','1');
      $pdf->Cell(20,6,"Total",1,0,'C','1');
      $pdf->Ln();
      $pdf->SetFont('freesans','B',9);
      $total_onetime = 0;
      $total_recur = array();
      foreach ($lineitems AS $item) {
       
      $description = $item["description"]; 
      #==========================================================================
      # find term 
      #==========================================================================
      $matches = array();
      preg_match('/\[term:(.*?)\]/i', $description, $matches); 
      if (empty($matches)) { 
      $term = ''; 
      }
      else { 
      $term = strtolower(trim($matches[1])); 
      $description = str_replace($matches[0], '', $description); 
      }
      #==========================================================================
      # find recur 
      #==========================================================================
      $matches = array();
      preg_match('/\[recur:(.*?)\]/i', $description, $matches); 
      if (empty($matches)) { 
      $recur = ''; 
      }
      else { 
      $recur = strtolower(trim($matches[1])); 
      $description = trim(str_replace($matches[0], '', $description)); 
      }
      #==========================================================================
      # get unit price and total price 
      #==========================================================================
      $matches = array(); 
      preg_match('/\d+\.\d+/', $item['unitprice'], $matches); 
      $item_unitprice = (float)$matches[0];
      $matches = array(); 
      preg_match('/\d+\.\d+/', $item['total'], $matches); 
      $item_total = (float)$matches[0];
      #==========================================================================
      # add onetime and recurring totals
      #========================================================================== 
      if ($recur == '') { 
      $total_onetime += $item_total; 
      }
      else { 
      if (!array_key_exists($recur, $total_recur)) { 

      $total_recur[$recur] = 0; 
      }

      $total_recur[$recur] += $item_total; 
      }
      #==========================================================================
      # display line items
      #==========================================================================
      $numlines = ceil(strlen($description)/55); 
      $cellheight = $numlines * 8;
      $pdf->MultiCell(10,$cellheight,$item["qty"],1,'C','',0);
      $pdf->MultiCell(80,$cellheight,$description,1,'L','',0);
      $pdf->MultiCell(20,$cellheight,$recur,'1','C','',0);
      $pdf->MultiCell(20,$cellheight,$term,'1','C','',0);
      $pdf->MultiCell(20,$cellheight,sprintf('$%.2f',$item_unitprice),1,'C','',0);
      $pdf->MultiCell(20,$cellheight,sprintf('$%.2f',$item_total),1,'C','',1);
      }
      $pdf->SetFont('freesans','B',9);
      /*
      $pdf->Cell(145,6,"Subtotal",1,0,'R','1');
      $pdf->Cell(25,6,$currencysymbol.$subtotal,1,0,'C','1');
      $pdf->Ln();
      if ($taxlevel1["rate"]>0) {
          $pdf->Cell(145,6,$taxlevel1["name"]." @ ".$taxlevel1["rate"]."%",1,0,'R','1');
          $pdf->Cell(25,6,$currencysymbol.$tax1,1,0,'C','1');
          $pdf->Ln();
      }
      if ($taxlevel2["rate"]>0) {
          $pdf->Cell(145,6,$taxlevel2["name"]." @ ".$taxlevel2["rate"]."%",1,0,'R','1');
          $pdf->Cell(25,6,$currencysymbol.$tax2,1,0,'C','1');
          $pdf->Ln();
      }
      $pdf->Cell(145,6,"Total",1,0,'R','1');
      $pdf->Cell(25,6,$currencysymbol.$total,1,0,'C','1');
      $pdf->Ln();
      */
      if ($total_onetime > 0) { 
      $pdf->Cell(150,6,'Pre-Pay',1,0,'R',1);
      $pdf->Cell(20,6,sprintf('$%.2f',$total_onetime),1,0,'C',1);
      $pdf->Ln();
      }
      foreach (array('monthly', 'quarterly', 'semi-annually', 'annually', 'biennially') as $recur) { 
      if (isset($total_recur[$recur]) && $total_recur[$recur] > 0) { 
      $pdf->Cell(150,6,ucfirst($recur) . ' Monthly Payments',1,0,'R',1);

      $pdf->Cell(20,6,sprintf('$%.2f',$total_recur[$recur]),1,0,'C',1);

      $pdf->Ln();
      }
      unset($total_recur[$recur]);
      }
      #==========================================================================
      # any remaining recurs
      #==========================================================================
      foreach ($total_recur as $recur => $amount) { 
      $pdf->Cell(150,6,ucfirst($recur) . ' Monthly Payments',1,0,'R',1); 
      $pdf->Cell(20,6,sprintf('$%.2f',$amount),1,0,'C',1);
      $pdf->Ln();
      }

      $pdf->SetFont('freesans','',9,l);
      $pdf->MultiCell(170,5,"
       
       
    • By JesusSuarz
      while working with the api I realized that getproducts (https://developers.whmcs.com/api-reference/getproducts/) does not bring up the field to know if the product is active or not.
      I saw someone post a similar idea several years ago: 
       
      so with a little engineer I made my own version of getproducts and uploaded it to /includes/api/
      Request Parameters "GetProductsActive"
      Parameter Type Description Required action string “GetProductsActive” Required pid int string Obtain a specific product id configuration. Can be a list of ids comma separated gid int Retrieve products in a specific group id Optional         Response Parameters
      Parameter Type Description result string The result of the operation: success or error totalresults int The total number of results available startnumber int The starting number for the returned results numreturned int The number of results returned products array An array of products matching the criteria passed I will leave the file called: getproductsactive.php
      however this may throw an api error, you have to give access in the table tblapi_roles in database, in the field: permissions add: ,"getproductsactive": 1 before closing }, This modification is due to WHMCS not showing the files added in includes/api as a role. (I do not know why).
      With this you can get the field: hidden which defines 0 if it is visible and 1 if it is hidden. (true or false also works)
      my code is a copy of includes/api/getproduct.php just add to show the hidden field (, "hidden" => $data["hidden"]), this would have been easier if WHMCS implemented it, it only took me 2 minutes to show this field.
       
      <?php if (!defined("WHMCS")) { exit("This file cannot be accessed directly"); } if (!function_exists("getCustomFields")) { require ROOTDIR . "/includes/customfieldfunctions.php"; } if (!function_exists("getCartConfigOptions")) { require ROOTDIR . "/includes/configoptionsfunctions.php"; } global $currency; $currency = getCurrency(); $pid = $whmcs->get_req_var("pid"); $gid = $whmcs->get_req_var("gid"); $module = $whmcs->get_req_var("module"); $where = array(); if ($pid) { if (is_numeric($pid)) { $where[] = "tblproducts.id=" . (int) $pid; } else { $pids = array(); foreach (explode(",", $pid) as $p) { $p = (int) trim($p); if ($p) { $pids[] = $p; } } if ($pids) { $where[] = "tblproducts.id IN (" . implode(",", $pids) . ")"; } } } if ($gid) { $where[] = "gid=" . (int) $gid; } if ($module && preg_match("/^[a-zA-Z0-9_\\.\\-]*\$/", $module)) { $where[] = "servertype='" . db_escape_string($module) . "'"; } $result = select_query("tblproducts", "tblproducts.*", implode(" AND ", $where), "tblproductgroups`.`order` ASC, `tblproductgroups`.`id` ASC, `tblproducts`.`order` ASC, `tblproducts`.`id", "ASC", "", "tblproductgroups ON tblproducts.gid = tblproductgroups.id"); $apiresults = array("result" => "success", "totalresults" => mysql_num_rows($result)); while ($data = mysql_fetch_array($result)) { $pid = $data["id"]; $productarray = array("pid" => $data["id"], "gid" => $data["gid"], "type" => $data["type"], "name" => $data["name"], "description" => $data["description"], "module" => $data["servertype"], "paytype" => $data["paytype"], "hidden" => $data["hidden"]); if ($language = $whmcs->get_req_var("language")) { $productarray["translated_name"] = WHMCS\Product\Product::getProductName($data["id"], $data["name"], $language); $productarray["translated_description"] = WHMCS\Product\Product::getProductDescription($data["id"], $data["description"], $language); } if ($data["stockcontrol"]) { $productarray["stockcontrol"] = "true"; $productarray["stocklevel"] = $data["qty"]; } $result2 = select_query("tblpricing", "tblcurrencies.code,tblcurrencies.prefix,tblcurrencies.suffix,tblpricing.msetupfee,tblpricing.qsetupfee,tblpricing.ssetupfee,tblpricing.asetupfee,tblpricing.bsetupfee,tblpricing.tsetupfee,tblpricing.monthly,tblpricing.quarterly,tblpricing.semiannually,tblpricing.annually,tblpricing.biennially,tblpricing.triennially", array("type" => "product", "relid" => $pid), "code", "ASC", "", "tblcurrencies ON tblcurrencies.id=tblpricing.currency"); while ($data = mysql_fetch_assoc($result2)) { $code = $data["code"]; unset($data["code"]); $productarray["pricing"][$code] = $data; } $customfieldsdata = array(); $customfields = getCustomFields("product", $pid, "", "", "on"); foreach ($customfields as $field) { $customfieldsdata[] = array("id" => $field["id"], "name" => $field["name"], "description" => $field["description"], "required" => $field["required"]); } $productarray["customfields"]["customfield"] = $customfieldsdata; $configoptiondata = array(); $configurableoptions = getCartConfigOptions($pid, array(), "", "", "", true); foreach ($configurableoptions as $option) { $options = array(); foreach ($option["options"] as $op) { $pricing = array(); $result4 = select_query("tblpricing", "code,msetupfee,qsetupfee,ssetupfee,asetupfee,bsetupfee,tsetupfee,monthly,quarterly,semiannually,annually,biennially,triennially", array("type" => "configoptions", "relid" => $op["id"]), "", "", "", "tblcurrencies ON tblcurrencies.id=tblpricing.currency"); while ($oppricing = mysql_fetch_assoc($result4)) { $currcode = $oppricing["code"]; unset($oppricing["code"]); $pricing[$currcode] = $oppricing; } $options["option"][] = array("id" => $op["id"], "name" => $op["name"], "rawName" => $op["rawName"], "recurring" => $op["recurring"], "required" => $op["required"], "pricing" => $pricing); } $configoptiondata[] = array("id" => $option["id"], "name" => $option["optionname"], "type" => $option["optiontype"], "options" => $options); } $productarray["configoptions"]["configoption"] = $configoptiondata; $apiresults["products"]["product"][] = $productarray; } $responsetype = "xml"; ?> Hope this helps others to show the field they need to show files and hidden products.
       
      getproductsactive.php
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated