Jump to content

Hooks for Show Invoices due in Sidebar


lims

Recommended Posts

i have build this hook for show invoices due in sidebar

<?php

use WHMCS\View\Menu\Item as MenuItem;

add_hook('ClientAreaPrimarySidebar', 1, function(MenuItem $primarySidebar){

    $filename = APP::getCurrentFileName();
    $client = Menu::context("client");
    $clientid = (int) $client->id;
    if ($filename!=='clientarea' || $clientid===0){
        return;
    }
    $primarySidebar->addChild('My Invoices Summary', array(
        'label' => Lang::trans("invoicesdue"),
        'uri' => '#',
        'order' => '1',
        'icon' => 'fa-money-bill-wave'
    ));
    
    $invoicesbar = $primarySidebar->getChild('My Invoices Summary');
    $invoicesbar->addChild('invoicesdue', array(
        'uri' => 'clientarea.php?action=masspay&all=true',
        'label' => '<div style="text-align:center;">'.Lang::trans("invoicesduemsg").'</div>',
        'order' => 1
    ));
    
    $invoicesbar->setFooterHtml(
        '<div style="text-align:center;"><a href="clientarea.php?action=masspay&all=true" class="btn btn-danger">'.formatcurrency($client['dueinvoicesbalance']).'</a></div>'
    );
});

but only show like this

ss_invoice.PNG.ce9581731bee37e62cacc84fff50b867.PNG

when try change

$client['dueinvoicesbalance']

to

$client['credit']

that work for credit balance

==> in template i use this {$clientsstats.dueinvoicesbalance}

my question :

1. need more code for show $client['dueinvoicesbalance']

2. invoices sidebar only show  if client have unpaid invoices

thanks before...

Link to comment
Share on other sites

11 hours ago, steven99 said:

Don't recall right off if $client is a WHMCS\User\Client or an array as you show here, but either way there likely isn't a variable of dueinvoicesbalance and you need to get the invoices and loop through and add up the ones marked not paid.  

this use only for same as {if $loggedin} any idea ?

8 hours ago, gbotica said:

Maybe check whether $stats[dueinvoicesbalance] is available? Otherwise, you need to use https://developers.whmcs.com/api-reference/getclientsdetails/ to get the $client array, which includes everything you need.

already try but not work, maybe other code to use call

Link to comment
Share on other sites

This is what you will need to add to your code:

$command = 'GetClientsDetails';
$postData = array(
    'clientid' => '1',
    'stats' => true,
);
$adminUsername = 'ADMIN_USERNAME'; // Optional for WHMCS 7.2 and later

$results = localAPI($command, $postData, $adminUsername);

Then $results will contain a JSON object with $stats[dueinvoicesbalance]

Link to comment
Share on other sites

6 minutes ago, gbotica said:

This is what you will need to add to your code:


$command = 'GetClientsDetails';
$postData = array(
    'clientid' => '1',
    'stats' => true,
);
$adminUsername = 'ADMIN_USERNAME'; // Optional for WHMCS 7.2 and later

$results = localAPI($command, $postData, $adminUsername);

Then $results will contain a JSON object with $stats[dueinvoicesbalance]

can u help where is this added ?

Link to comment
Share on other sites

18 hours ago, lims said:

i have build this hook for show invoices due in sidebar 

I assume you know that the sidebar already exists, but is only shown on the invoices page?

17 hours ago, steven99 said:

Don't recall right off if $client is a WHMCS\User\Client or an array as you show here, but either way there likely isn't a variable of dueinvoicesbalance and you need to get the invoices and loop through and add up the ones marked not paid. 

no you don't - if the client is logged in, you can access the $clientsstats Smarty array from the hook and the variables you need are already there (effectively it's just the same as accessing $vars) - there's no need to go looping though invoices or using the API just to get two variables... and if the client isn't logged in, then the sidebar won't show anyway.

1ueEOmS.pngS4r6VII.png

the top sidebar is your sidebar (fixed by me!), the bottom is the default one shown on the invoices page... your sidebar will overwrite the default one if the menuitemname values are the same and will appear elsewhere in the clientarea.

<?php

# Unpaid Invoices Sidebar Hook
# Written by brian!

use WHMCS\View\Menu\Item as MenuItem;

add_hook('ClientAreaPrimarySidebar', 1, function(MenuItem $primarySidebar){

	GLOBAL $smarty;
	$dueinvoices = $smarty->getTemplateVars()['clientsstats']['numunpaidinvoices'];
	$duebalance = $smarty->getTemplateVars()['clientsstats']['unpaidinvoicesamount'];	
	$filename = APP::getCurrentFileName();
	$client = Menu::context("client");
	$clientid = (int) $client->id;
	if ($filename!=='clientarea' || $clientid===0 || $dueinvoices===0){
		return;
	}
	$primarySidebar->addChild('My Invoices Summary', array('label' => Lang::trans("invoicesdue"),'order' => 1,'icon' => 'fa-money-bill-wave'));
	$primarySidebar->getChild('My Invoices Summary')
	->setBodyHtml(sprintf(Lang::trans("invoicesduemsg"),$dueinvoices,$duebalance))
	->setFooterHtml('<a href="clientarea.php?action=masspay&all=true" class="btn btn-danger btn-sm btn-block">'.$duebalance.'</a>');
});

I suspect the default sidebar will use the Invoice class method to get the number/balance, but there seems little point in reinventing the wheel when we only need two variables and they're both accessible via Smarty. 🙂

Link to comment
Share on other sites

1 hour ago, brian! said:

I assume you know that the sidebar already exists, but is only shown on the invoices page? 

yes, i know that, I deliberately used this code,

'My Invoices Summary'

for replace default in invoices page, its can be change to other, but will show two alert invoice

thank you so much @brian! your code is perfect and work...

Edited by lims
Link to comment
Share on other sites

4 hours ago, brian! said:

no you don't - if the client is logged in, you can access the $clientsstats Smarty array from the hook and the variables you need are already there (effectively it's just the same as accessing $vars) - there's no need to go looping though invoices or using the API just to get two variables... and if the client isn't logged in, then the sidebar won't show anyway.

I was talking only about the $client object given by the the context function and what it returned.   Your method still adds code and behind that code is still a loop that does the same thing.  And though it comes down to personal preference, I would use the internal class and a loop because it is more readable, would not have to find the doc on smarty functions, would not have to var_dump or print_r to find out the available variables.

Link to comment
Share on other sites

1 minute ago, steven99 said:

Your method still adds code and behind that code is still a loop that does the same thing.

I give up...  the point being that i'm not having to calculate what I want, I can go to where the values already exist and are easily obtainable... 🔍

you can easily bake a cake every time if you choose to, but sometimes it's just easier to go to the shop and get one off the shelf! 🍰

2 minutes ago, steven99 said:

And though it comes down to personal preference, I would use the internal class and a loop because it is more readable,

then post your code using the internal classes and let's see... 🙂

everything is readable if you know what you're using... anything else will look double-dutch until you do. celestial5.gif

6 minutes ago, steven99 said:

would not have to find the doc on smarty functions

neither would I - they're already in my head! 🙂

9 minutes ago, steven99 said:

would not have to var_dump or print_r to find out the available variables. 

except the OP already knew the existing variables (he mentions them in his post)... and even if he hadn't, I knew them. 🙄

now I will agree that if those variables didn't already exist, you would need to create them, and I could do that by a variety of methods, including the internal classes... but i'll be damned if i'm going to spend time reinventing code when I don't need to (except perhaps for your coding approval!)...

sure, one day in the future this method might not work, but neither might internal classes or any API I choose to use today... golden rule with WHMCS is not to worry about tomorrow, let's just get through the day without banging our heads against a brick wall!

Link to comment
Share on other sites

On 3/27/2019 at 12:38 AM, steven99 said:

I would use the internal class and a loop because it is more readable, would not have to find the doc on smarty functions, would not have to var_dump or print_r to find out the available variables. 

Let's we see your CODE ?

======================

source code

$client = Menu::context("client");
$clientid = (int) $client->id;
	if ($clientid===0 || $dueinvoices===0){
		return;
	}

here is the same as above

	$client = Menu::context("client");
	if (!is_null($client) && $dueinvoices > 0) {
	// function here....
	}

 

Link to comment
Share on other sites

12 hours ago, lims said:

Let's we see your CODE ?

Sure:


<?php

/**
 * @author steven99
 */

use WHMCS\View\Menu\Item as MenuItem;

add_hook('ClientAreaPrimarySidebar', 1, function(MenuItem $primarySidebar){

    //get invocies, aka reinvent the wheel
    $client = Menu::context("client");
    if ($client)
    {
        $TotalDue = 0;
        $TotalUnpaidInvoices = 0;
        foreach($client->invoices as $invoice)
        {
            if ($invoice->status === "Unpaid")
            {
                $TotalDue += $invoice->balance;
                $TotalUnpaidInvoices ++;
            }
        }
        //get invoices end

        if (APP::getCurrentFileName() !=='clientarea' OR $client->id === 0 OR $TotalUnpaidInvoices === 0){
            return; // not valid for this request
        }
        $primarySidebar->addChild('My Invoices Summary', array('label' => Lang::trans("invoicesdue"),'order' => 1,'icon' => 'fa-money-bill-wave'));
        $primarySidebar->getChild('My Invoices Summary')
            ->setBodyHtml(sprintf(Lang::trans("invoicesduemsg"),$TotalUnpaidInvoices,formatcurrency($TotalDue)))
            ->setFooterHtml('<a href="clientarea.php?action=masspay&all=true" class="btn btn-danger btn-sm btn-block">'.formatcurrency($TotalDue).'</a>');
    } // if client
});
On 3/26/2019 at 2:19 PM, brian! said:

now I will agree that if those variables didn't already exist, you would need to create them, and I could do that by a variety of methods, including the internal classes... but i'll be damned if i'm going to spend time reinventing code when I don't need to (except perhaps for your coding approval!)...

@brian! as I said it comes down to personal preference and so not sure why you have stated that you need my code approval.  Did I say your code is garbage or would not work?  No as I am not Linus.   I gave the method I would use just as you gave your code.  Do I need your permission to give my opinions just like you need my code approval?  I try to code in a way that future me that has not looked at the code in a while OR anyone not aware of the code could look at it and see what is going on, where information came from, etc especially when the docs for the app writing on are duplicated in 2 or 3 spots with varying amounts of info.   I prefer objects over arrays as objects can be documented in the IDE for quick hinting.  Or use stubs when available .   I also try to code in a way that the code could be used in different spots with minimal changes. 

Edited by steven99
Link to comment
Share on other sites

  • 4 years later...
  • 4 months later...
On 4/2/2023 at 3:31 PM, robetus said:

I've attached a screenshot of what I think would be amazing to have in a product's details.

Screenshot 2023-04-02 at 04.01.04.png

 

I have made it. You can get the warning message once the invoice is due and the invoice id and amount to pay with clickable link to pay it.

 

259203131-2e715814-99f0-4be4-9177-629986

 

259203366-d78d8e17-dcf2-4f90-b19d-ae91d0

 

 

For Paid and Unpaid invoice.

 

259205120-de519bc4-a661-4025-b610-b10ea0

 

Edited by Saurabh S
image size
Link to comment
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.

  • 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