sonuyos Posted May 15, 2021 Share Posted May 15, 2021 (edited) This is my code, it is in WIP, and i am facing issue. Theorotically it works fine, however for some reason the vars are not passing thru, the service id & product type are empty, causing ALL the invoices to get cancelled, anyway to solve this? I do not know what i am doing wrong, it should work. <?php if (!defined("WHMCS")) die("This file cannot be accessed directly"); use WHMCS\Database\Capsule; add_hook('AfterModuleTerminate', 1, function($vars) { $serviceid=$vars['serviceid']; $producttype=$vars['producttype']; $invoices=Capsule::table("tblinvoiceitems")->where("relid","$serviceid")->where("type","$producttype")->get(); foreach($invoices as $invoice) { $results = localAPI("GetInvoice",array("invoiceid"=>$invoice->id); if ($results["status"]=="Unpaid") { $cancelinvoiceid=$results["invoiceid"]; $results = localAPI("UpdateInvoice",array("invoiceid"=>"$cancelinvoiceid","status"=>"Cancelled")); logactivity("[INVOICECANCELHOOK] has cancelled Invoice ID: $cancelinvoiceid automatically."); } } }); Edited May 15, 2021 by sonuyos 0 Quote Link to comment Share on other sites More sharing options...
sonuyos Posted May 15, 2021 Author Share Posted May 15, 2021 (edited) <?php if (!defined("WHMCS")) die("This file cannot be accessed directly"); use WHMCS\Database\Capsule; add_hook('AfterModuleTerminate', 1, function($vars) { $serviceid=$vars['serviceid']; $producttype=$vars['producttype']; $invoices=Capsule::table("tblinvoiceitems")->where("relid","$serviceid")->where("type","$producttype")->get(); foreach($invoices as $invoice) { $results = localAPI("GetInvoice",array("invoiceid"=>$invoice->invoiceid,"status"=>"Unpaid")); if ($results["status"]=="Unpaid") { $cancelinvoiceid=$results["invoiceid"]; $results = localAPI("UpdateInvoice",array("invoiceid"=>"$cancelinvoiceid","status"=>"Cancelled")); logactivity("[INVOICECANCELHOOK] has cancelled Invoice ID: $cancelinvoiceid automatically."); } } }); Updated the code a litter bit to make sure it works if serviceid is provided. The code is working now, but still unable to set it to cancel automatically becausse there is way i can pass serviceid variable. Edited May 15, 2021 by sonuyos Made code tidier 0 Quote Link to comment Share on other sites More sharing options...
brian! Posted May 15, 2021 Share Posted May 15, 2021 if you're passing a variable name in a where condition, then you don't need to quote it, e.g with regards to the capsule query... $invoices = Capsule::table("tblinvoiceitems")->where("relid",$serviceid)->where("type",$producttype)->get(); assuming the two variables contain valid values, then $invoices should contain the intended result. 0 Quote Link to comment Share on other sites More sharing options...
sonuyos Posted May 15, 2021 Author Share Posted May 15, 2021 (edited) 9 minutes ago, brian! said: if you're passing a variable name in a where condition, then you don't need to quote it, e.g with regards to the capsule query... $invoices = Capsule::table("tblinvoiceitems")->where("relid",$serviceid)->where("type",$producttype)->get(); assuming the two variables contain valid values, then $invoices should contain the intended result. No no, you got that wrong, my code works completely, its just that i am unable to pass $serviceid & $producttype from vars. This section does not work. add_hook('AfterModuleTerminate', 1, function($vars) { $serviceid=$vars['serviceid']; $producttype=$vars['producttype']; Edited May 15, 2021 by sonuyos 0 Quote Link to comment Share on other sites More sharing options...
sonuyos Posted May 15, 2021 Author Share Posted May 15, 2021 @brian! According to this page - https://developers.whmcs.com/hooks-reference/module/#aftermoduleterminate and this - https://developers.whmcs.com/provisioning-modules/module-parameters/ The module should provide serviceid by defualt and producttype too, but it does not. i am doing something wrong? 0 Quote Link to comment Share on other sites More sharing options...
brian! Posted May 15, 2021 Share Posted May 15, 2021 1 minute ago, sonuyos said: The module should provide serviceid by default and producttype too, but it does not. i am doing something wrong? did you try...? $serviceid = $vars['params']['serviceid']; 0 Quote Link to comment Share on other sites More sharing options...
sonuyos Posted May 15, 2021 Author Share Posted May 15, 2021 7 minutes ago, brian! said: did you try...? $serviceid = $vars['params']['serviceid']; YESSS THAT WORKS. However now, when i try to terminate it from the panel, it works fine and marks invoice cancelled, but if i run cron, it doesnt, shouldnt it mark it cancelled even with cron? 0 Quote Link to comment Share on other sites More sharing options...
Synister Posted May 15, 2021 Share Posted May 15, 2021 I use this and it works fine. <?php use WHMCS\Database\Capsule; add_hook('PreModuleTerminate', 1, function($vars) { $invoices = Capsule::table('tblinvoiceitems') ->where('relid', $vars['params']['serviceid']) ->where('type', '!=', 'GroupDiscount') ->get(); logActivity('Auto Cancel Invoice: Starting...'); foreach($invoices as $key){ $invoiceIDs = Capsule::table('tblinvoices') ->where('id', $key->invoiceid) ->where('status', 'Unpaid') ->value('id'); $invoiceLine = Capsule::table('tblinvoiceitems') ->where('invoiceid', $invoiceIDs) ->where('relid', $vars['params']['serviceid']) ->value('id'); $invoiceLines = Capsule::table('tblinvoiceitems') ->where('invoiceid', $invoiceIDs) ->get(); $description = Capsule::table('tblinvoiceitems') ->where('relid', $vars['params']['serviceid']) ->where('invoiceid', $invoiceIDs) ->value('description'); $discountLine = Capsule::table('tblinvoiceitems') ->where('invoiceid', $invoiceIDs) ->where('type', 'GroupDiscount') ->where('description', 'like', '% '.$description.'%') ->value('id'); if($invoiceIDs){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' has had a line removed. This invoice previously had ' . count($invoiceLines) . ' lines.'); if(count($invoiceLines) > 1){ $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'deletelineids' => array($invoiceLine), ); $results = localAPI($command, $postData); }elseif(count($invoiceLines) == 1){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' has been cancelled because the product was terminated.'); $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'status' => 'Cancelled', ); $results = localAPI($command, $postData); } if(count($invoiceLines) <= 2 && Capsule::table('tblinvoiceitems')->where('invoiceid', $invoiceIDs)->where('type', 'LateFee')->get()){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' has been cancelled because the only line was a Late Fee.'); $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'status' => 'Cancelled', ); $results = localAPI($command, $postData); } if($discountLine){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' had a Group Discount. This has been removed.'); $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'deletelineids' => array($discountLine), ); $results = localAPI($command, $postData); } } } }); 0 Quote Link to comment Share on other sites More sharing options...
brian! Posted May 15, 2021 Share Posted May 15, 2021 2 minutes ago, Synister said: I use this and it works fine. original source thread below.... 1 Quote Link to comment Share on other sites More sharing options...
Synister Posted May 15, 2021 Share Posted May 15, 2021 6 minutes ago, brian! said: original source thread below.... Thanks Brian. I couldn't remember where I got it Just know it works 0 Quote Link to comment Share on other sites More sharing options...
sonuyos Posted May 15, 2021 Author Share Posted May 15, 2021 58 minutes ago, Synister said: I use this and it works fine. <?php use WHMCS\Database\Capsule; add_hook('PreModuleTerminate', 1, function($vars) { $invoices = Capsule::table('tblinvoiceitems') ->where('relid', $vars['params']['serviceid']) ->where('type', '!=', 'GroupDiscount') ->get(); logActivity('Auto Cancel Invoice: Starting...'); foreach($invoices as $key){ $invoiceIDs = Capsule::table('tblinvoices') ->where('id', $key->invoiceid) ->where('status', 'Unpaid') ->value('id'); $invoiceLine = Capsule::table('tblinvoiceitems') ->where('invoiceid', $invoiceIDs) ->where('relid', $vars['params']['serviceid']) ->value('id'); $invoiceLines = Capsule::table('tblinvoiceitems') ->where('invoiceid', $invoiceIDs) ->get(); $description = Capsule::table('tblinvoiceitems') ->where('relid', $vars['params']['serviceid']) ->where('invoiceid', $invoiceIDs) ->value('description'); $discountLine = Capsule::table('tblinvoiceitems') ->where('invoiceid', $invoiceIDs) ->where('type', 'GroupDiscount') ->where('description', 'like', '% '.$description.'%') ->value('id'); if($invoiceIDs){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' has had a line removed. This invoice previously had ' . count($invoiceLines) . ' lines.'); if(count($invoiceLines) > 1){ $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'deletelineids' => array($invoiceLine), ); $results = localAPI($command, $postData); }elseif(count($invoiceLines) == 1){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' has been cancelled because the product was terminated.'); $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'status' => 'Cancelled', ); $results = localAPI($command, $postData); } if(count($invoiceLines) <= 2 && Capsule::table('tblinvoiceitems')->where('invoiceid', $invoiceIDs)->where('type', 'LateFee')->get()){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' has been cancelled because the only line was a Late Fee.'); $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'status' => 'Cancelled', ); $results = localAPI($command, $postData); } if($discountLine){ logActivity('Auto Cancel Invoice: Invoice ' . $invoiceIDs . ' had a Group Discount. This has been removed.'); $command = 'UpdateInvoice'; $postData = array( 'invoiceid' => $invoiceIDs, 'deletelineids' => array($discountLine), ); $results = localAPI($command, $postData); } } } }); Does that work for cron as well? 0 Quote Link to comment Share on other sites More sharing options...
Synister Posted May 15, 2021 Share Posted May 15, 2021 Yes it works for Cron as well 0 Quote Link to comment Share on other sites More sharing options...
sonuyos Posted May 15, 2021 Author Share Posted May 15, 2021 1 minute ago, Synister said: Yes it works for Cron as well I wonder why my code isnt working with cron. 0 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.