Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 07/09/13 in all areas

  1. 13 points
    The WHMCS.Community is intended to provide a place for users of WHMCS to discuss, share and interact with each other as well as WHMCS Staff. To ensure we maintain a friendly environment, we ask users to respect the following rules and guidelines. Please let us know via the WHMCS.Community Assitance category should you have any questions or comments, posts in this category are visible between yourself and the WHMCS.Community Team. WHMCS reserves the right to alter these rules from time to time. 1.User Accounts Each person may have (one) 1 forum login regardless of the number of companies you may be part of. Duplicate accounts will be removed from WHMCS.Community Please do not share your user account with others - each person should retain their own username and password Usernames must not be created that contain any of the items listed below: An email address A website address The following words WHMCS cPanel Staff Moderator Admin Any word determined to cause offence or be deemed inappropriate. Usernames or Users that do not comply with these rules may be removed from WHMCS.Community 2. Behaviour on the Community We expect all users to be friendly and polite. While we understand that users will disagree and have different points of view at times, this can be communicated in a civil manner Please do not post rude, insulting or inflammatory posts. Personal attacks, name-calling and insults will not be tolerated on WHMCS.Community. Profanity and inappropriate images (including porn or gross violence) may not be posted anywhere on the WHMCS.Community. WHMCS.Community Staff & Moderators use their sole discretion as to what is deemed unacceptable behaviour in the community and may remove content at any time. Your posts assist other users, please do not delete content if you find an answer, please share this solution to help other users. 3. Advertising on WHMCS.Community Advertising, offers or self-promotion are to be posted only in the Third Party Add-ons section of the community. Community users seeking to hire a developer may post within the Service Offers & Requests section. Advertising is limited to one advertisement per seven (7) day period on a rolling 7-day basis. Additional or excessive advertising will be removed by the moderation team and your ability to post in advertising boards removed. Soliciting and/or self-promotion via the private messaging (PM) system is strictly prohibited. The sale or reselling of WHMCS Licenses is strictly prohibited on the community. Affiliate and referral links may not be used, these links are those that link to a site and contain information crediting the person with that referral 4. Posting and Moderation on WHMCS.Community The WHMCS.Community is moderated by WHMCS.Community Moderators and Staff. When a post is deemed to be in breach of the rules it will be removed and the user advised via a warning. Please do not cross-post across the community. If your topic is better suited to another section one of the WHMCS.Community team will move it to the best category for you. You may report your post if you wish to have it moved by a moderator. For privacy reasons please do not post any personally identifiable information including Usernames, Passwords, Contact Numbers, Email Addresses and/or Credit Card Numbers As WHMCS.Community is a moderated community we have implemented a Warning System. When a post is removed for breaching the community rules we’ll be sure to let you know. We allocate points to a warning and once you have a set number of points you may be suspended from posting on the community. Users that do not comply with the rules for WHMCS.Community may be banned temporarily. Ongoing temporary bans may result in a permanent ban from WHMCS.Community. The public discussion of moderation decisions is not permitted, these will be removed without notice and may result in a community ban. 5. Signature and Profile Rules Your signature may include links, however, please ensure these are reasonable (no more than 4) and they must not include Referral/Affiliate links. This includes pricing and plan details Signatures may not contain more than 4 lines at a 1024x768 resolution Please do not sell or rent your signature space, your signature is yours alone. Where your signature does not comply with these rules you may be asked to alter or remove it 6. WHMCS.Community Ranks Official WHMCS Staff & Moderators are identified by one of the following ranks located below their profile image, in addition, their posts are highlighted blue WHMCS CEO WHMCS Community Manager WHMCS Customer Service WHMCS Developer WHMCS Marketing WHMCS Staff WHMCS Support Manager WHMCS Technical Analyst WHMCS.Community runs a ranking system, new community members start with the rank of Newbie and can progress based on the number of posts, reputation points and length of time active on the community Some users have a special “Super Users” rank. These members are a select group of elite community members that are long-standing mentors in the community, courteous to other members, always providing technical insight and advice, and generally helping to make our community a better place to learn, troubleshoot and advance. The WHMCS.Community ranking formula is changed from time to time and without notice. The algorithm used is not published or discussed with users to prevent gaming the system 7. Contacting the WHMCS.Community Team You may contact a member of the WHMCS.Community via the WHMCS.Community Assitance board If you would prefer to email you may open a ticket by emailing forums@whmcs.com Thank you for helping to keep WHMCS.Community a great place
  2. 10 points
    Some people want to show their client's credit balance when they login to client area, as the option not implemented by default in Six Template here is how to do it: 1) Upload the PHP file from Attachements to -> /WHMCS-Path/includes/hooks/ directory. WHMCS_SixTemplateCreditBalance.zip
  3. 9 points
    in v8, the summary stats were removed from the admin display - e.g Pending Orders, Overdue Invoices and Tickets Awaiting Reply - the simple hook below adds them back to the output in a similar location (top of the page)... <?php # Stats Info Bar for v8 Blend # Written by brian! use WHMCS\Database\Capsule; use WHMCS\Billing\Invoice; function admin_v8_infobar_hook($vars) { $pendingstatuslist = Capsule::table('tblorderstatuses')->where('showpending','1')->pluck('title'); $pendingorders = Capsule::table('tblorders')->whereIn('status',$pendingstatuslist)->count(); $overdueinvoices = Invoice::overdue()->count(); $awaitingreplylist = Capsule::table('tblticketstatuses')->where('showawaiting','1')->pluck('title'); $ticketsawaiting = Capsule::table('tbltickets')->whereIn('status',$awaitingreplylist)->count(); $headerreturn = '<div style="margin: 0; padding: 5px; background-color: #1a4d80; display: block; width: 100%; max-height: 20px;"> <div style="text-align: center; color: #fff; font-size: .8em; margin: 0;"> <a href="orders.php?status=Pending" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$pendingorders.'</span> '.AdminLang::trans('stats.pendingorders').'</a> | <a href="invoices.php?status=Overdue" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$overdueinvoices.'</span> '.AdminLang::trans('stats.overdueinvoices').'</a> | <a href="supporttickets.php" style="color: #fff;"><span style="font-weight: 700; color: #fc0;">'.$ticketsawaiting.'</span> '.AdminLang::trans('stats.ticketsawaitingreply').'</a> </div> </div>'; return $headerreturn; } add_hook("AdminAreaHeaderOutput",1,"admin_v8_infobar_hook"); this was originally written for v8.0.0 betas, but the code has now been updated for v8.0.1 (where the $sidebarstats array no longer exists and the values now have to be calculated from database queries).
  4. 8 points
    Not everyone is happy with the general way v7 is going, (v6 and v5 where better) and since it seems v8 is coming next year or is planned at least. What are your main wish lists for that new version looking it from a developer or business view. What do you like WHMCS to change, improve or even remove in the future? Here is my list: More opt-in Make things more opt-in. Some things in v7 are not useful for more advanced users, like auto update, or the market store. I would like to have that stuff removed. Now I have more files and more bloat on my installation which I don't use and never will. This things should come as a separated module and if they are disabled or not installed, the code should not even be live in your server for security reasons, performance and just general simplicity. Less is more sometimes and many of those features I don't require as they are targeted to click one night operations, and not more longer power users that want to tweak and adapt WHMCS to their own operations. Bug Tracking A better bug tracker. Asking with a ticket if a bug is fixed or having to hunt down the change long on each release is painful and time consuming. Sometimes I think WHMCS as a company is very inefficient with some operations. Hiring people costs them money, so why do they want to babysit things like this. Having to answer tickets costs them time and this could be avoided with a proper bug tracker. This can't scale. Better feedback from users Feature requests. This is completely broken. Why use a different system when you have a nice community here? Build the feature requests and vote system here. If you don't want to build a bug tracker, you can even do the same here on the community for bugs and only customers with a valid license can access assuming WHMCS does not want to make this public. Slow down with features Longer releases. This could be a bit controversial but I would rather prefer WHMCS to slow down a bit. Every new release introduces more bugs than features. The Beta testing should be longer and I would be ok with maybe only 2 major releases per year. Just keep releasing patches for bugs. They are adding so many new things which are related to external services and I don't think they are aware the minefield they are creating. WHMCS should not be heavily coded to work with remote stuff. Try to build more things that work locally in your server instead of just releasing new features that require third party services. Longer Releases Longer LTS releases. They are not long releases if they only last a year. Look how Microsoft does it, 10-15 years. Or even Red Hat. The people using LTS are companies or enterprises and I'm not saying WHMCS should support them 10 years, but seriously 1 year or just a bit longer? Most developers even support their normal releases for at least 3 years. The LTS should be a minimum 3 years unless the PHP or code they rely on is not supported anymore, which is a different story. Can you imagine if everyone else did the same to WHMCS developers? Imagine if PHP was only supported 1 year, or Smarty, or anything. It would be a nightmare for them. So if they are aware that they rely on such much external code now, they should give the same considerations towards their customers. Not everyone has the time to update and make all their integrations the day they are released. This is a billing and cloud/hosting automation software. Not a blog like WordPress!!! And with that I mean security patches. Not even bug fixes. They don't have to even fix bugs or release new features on those versions. But please, at least still support them with security patches for 3 years after launch. It's the responsible thing to do. Better Mobile Mobile app is not updated for years. Show more love or open it up so we can add things. I have to rely on external services for ticket notifications and other things when this makes no sense if you have a mobile app. Instead of building things for something like Slack I'm seriously disappointed that WHMCS developers give more attention to external services then their own products. I can receive mobile notifications on third party services but not push notifications on my WHMCS mobile app. Shocking their own products are left to die. Finally, open up. You are benefiting from open source developers work but do the opposite to your own customers that are developers. Open up your code. Please just open up your code or at least the most important chunks to particular partners or companies. Make them sign what ever non disclosure agreement you want or even charge them. Your competition has none of your problems because the community can see and fix things. What is WHMCS so keen to protect here? Business users are not going to stop paying support and updates and they surely are not going to pirate the software. It's a bit childish, in particular because WHMCS would not exist today without open source work from others. WHMCS relies heavily on external third party open source code yet they even encode that. This is an insult to developers. They are taking all the code that is free and releases from other developers, and then pass Ioncube over it. One thing is protecting your code and licensing, the other thing is trying to protect code that is not even yours. WHMCS is encoding so much garbage that I'm sure this is the root of most of their bugs and problem because we cannot fix or see what they do. This is the biggest downside of using WHMCS. I don't think any serious provider will consider WHMCS for this reason. It's a blackbox. And I'm not talking here about the core, or billing stuff, or API stuff. No, WHMCS even encode things that affect your public website and cannot be easily modified or changed unless you make hacks around them software. You constantly have to intercept what WHMCS does and then transform the output because you have no idea what it does and how. It's a game I'm not willing to play in the future. Their competition advertises that they are 99% open code and only encode a few files related to the license. I don't expect WHMCS to do this but PLEASE if someone from the company is reading this, this is going to be your doom as a company in the next years. The minute competition comes up and is more open than WHMCS, those people are not coming back. Everyone is opening up in the software and technology industry. Even WHMCS would not exist as a company if it was not for other services developing API's which WHMCS is relies on for most of their connection. This is not the proper way to behave towards your developer customers. What exactly are they are trying to protect is beyond me. Even third party developers like Modules Garden and many others at least have an open version of their encoded modules. Everyone does at this point because they understand business users will not run things on their server they cannot fix, see what it does or just maintain. It's a trust thing. You would sell far more licenses and to people that actually have the money to pay. Do they distrust their own code so much? Well, the community would be able to constantly improve it with suggestions and fixes. Less work for their developers and the product would move forwards on its own. I just love how your competition works. The whole code is open, their whole bug tracker is open. This is causing frustration to those using the software and worse, forcing them to move out to custom solutions or more open platforms. WHMCS is never going to be flexible this way. And I would not complain about this if it was not for the fact that WHMCS is putting more and more code that was open in the past behind their ioncube wall. v6 and v5 had less encoded code/features, not more. I'm shocked on much WHMCS hates developers or people building their own sites around WHMCS because every new release is worse with more features behind the black box. This is now seriously affecting my business with things I cannot fix anymore or integrate. Everyone in the technology world understand proprietary standards are bad. And this is what WHMCS is doing, they are forcing people to even make simple changes using their own way of doing things. Why would I do this? Why should a PHP developer, or a HTML coder, or a JavaScript person learn how to do things the WHMCS way which is inefficient, buggy and even performs bad on a server? Those people want to use the standard coding procedures WHMCS developers use. Not the stupid hooks and API to even change something like a link. And I say stupid because this is exactly how I feel about WHMCS v7 at this point. You have to make a special PHP hook code (the WHMCS way) to change the sidebar text, colors or links. In the past I could just open the .tpl file and change it. Why? Because WHMCS is removing code from templates and putting it behind the IonCube wall. One day, the templates will be worthless and most WHMCS websites that are customized are going to be horrible slow because users have to create 240 hooks to change colors, links, or even text. Personally, I have access to all the database. And if I see v8 is not being more open but more closed. I'm moving out. I cannot trust my business operations to a company that wants to keep their customers under ransom. And this is how I feel when I cannot even fix the most simple bugs because the files are encoded. So my biggest wish list for v8 is for WHMCS to start being more open and trying to move towards that trend. They profit from open source but seem to hate open source which is a rather a strange business approach. One day, some of those developers may change their licenses and forbid their codes from being used in obfuscated software. If that day comes, WHMCS will have to remove that code from their software or change the way they work in terms of developing.
  5. 7 points
    I believe (as software engineer I am). WHCMS should make this new SSL monitoring feature fully optional and allowing easy enable/disable settings in the configuration panel or in the configuration.php file in the simplest case. And that is because adding invasive new features must be done with quirurgical precision and always having in mind: maybe some customers does not want what we think they want. No mentioning that evidently the feature was not fully tested before released as stable. Recommending customer to edit files in your theme is not a smart move, since the new SSL monitoring bug is not only estetical problem, there are some backend processes involved... and also because mostly of your customers are not coders and expect a "working product". Next time guys you think in adding a new invasive feature, please consider giving us (your customers) the power to enable/disable as will any idea that maybe WHMCS think is good, but ends being a bad idea. I've been with WHMCS since almost 8 years ago.
  6. 6 points
    i've posted the hook for the admin info bar in the thread below - should work on both v8.0.0 and v8.0.1 🙂
  7. 6 points
    the idea for this widget was started in the feedback thread below, but rather than hijack that thread with this project, it was easier to start a new thread in Third Party Addons. this "Enhanced ToDo List" admin widget, expands on the default widget by showing client names (or Company Name), service details (name/domain) and domain names as mouseover tooltips (I could put them in the body, but then space might become an issue)... for those that want to use this widget, i've attached it to this post - simply upload to /modules/widgets and the next time you go to the admin homepage, it should be there (assuming your admin role allows viewing of the ToDo List). i've called the file "EnhancedToDo.php", so you'll end up with two ToDo widgets on your homepage, just disable the default one using the Show/Hide widgets option top right... I could have called it ToDo.php, but then the WHMCS auto-updater would have overwritten it during the next update - so it's easier to keep it separate until WHMCS improve how they handle ToDo's. it's written for WHMCS v7.6, but will work on v7.5.x too... it might work on earlier v7 versions, but I haven't tested it on them - there is a WHMCS version check inside the widget that chooses FontAwesome 5 icons if using v7.6 or later, or FA4 if using an earlier WHMCS version. if you spot any ToDo's that don't behave correctly (e.g a third-party addon might add a ToDo that doesn't follow the WHMCS convention), then feel free to reply about it (or PM me) - it shouldn't break the output, it will likely just not show the icon(s) for that ToDo. EnhancedToDo.php
  8. 5 points
    I've seen there's a feature request submitted 7 years ago about bulk auto recalculate. I know you can do that from phpMyAdmin or with a script but enough is enough. <? /** * Bulk Auto Recalculate Client Domain & Products/Services * * @writtenby Kian * */ use WHMCS\Database\Capsule; add_hook('AdminAreaHeaderOutput', 1, function($vars) { if ($vars['filename'] == 'clientssummary' AND $_GET['userid'] AND in_array($_GET['kata'], array('bulkAutoRecalculateP', 'bulkAutoRecalculateD'))) { $adminUsername = ''; // Optional for WHMCS 7.2 and later if ($_GET['kata'] == 'bulkAutoRecalculateP') { foreach(Capsule::table('tblhosting')->where('userid', '=', $_GET['userid'])->pluck('id') as $v) { localAPI('UpdateClientProduct', array('serviceid' => $v, 'autorecalc' => true), $adminUsername); } header('Location: clientssummary.php?userid=' . $_GET['userid']); die(); } elseif ($_GET['kata'] == 'bulkAutoRecalculateD') { foreach (Capsule::table('tbldomains')->where('userid', '=', $_GET['userid'])->pluck('id') as $v) { localAPI('UpdateClientDomain', array('domainid' => $v, 'autorecalc' => true), $adminUsername); } header('Location: clientssummary.php?userid=' . $_GET['userid']); die(); } } return <<<HTML <script> $(document).ready(function(){ $('[href*="affiliates.php?action=edit&id="], [href*="clientssummary.php?userid="][href*="&activateaffiliate=true&token="]').closest('li').after(('<li><a href="#" id="kata_BulkAutoRecalculate"><i class="fas fa-fw fa-sliders-h" style="width:16px;text-align:center;"></i> Bulk Auto Recalculate</a></li>')); $('#kata_BulkAutoRecalculate').on('click', function(e){ e.preventDefault(); $('#modalAjaxTitle').html('Bulk Auto Recalculate'); $('#modalAjaxBody').html('<div class="container col-md-12"><div class="row"><div class="col-md-6 text-center"><div class="panel panel-default"><div class="panel-body"><p><i class="fas fa-box fa-5x"></i></p><p><small>Auto Recalculate Customer\'s <strong>Products/Services</strong></small></p><p><a href="clientssummary.php?userid={$_GET['userid']}&kata=bulkAutoRecalculateP" class="btn btn-info btn-block">Recalculate Now »</a></p></div></div></div><div class="col-md-6 text-center"><div class="panel panel-default"><div class="panel-body"><p><i class="fas fa-globe fa-5x"></i></p><p><small>Auto Recalculate Customer\'s <strong>Domains</strong></small></p><p><a href="clientssummary.php?userid={$_GET['userid']}&kata=bulkAutoRecalculateD" class="btn btn-info btn-block">Recalculate Now »</a></p></div></div></div></div></div>'); $('#modalAjax .modal-submit').addClass('hidden'); $('#modalAjaxLoader').hide(); $('#modalAjax .modal-dialog').addClass('modal-lg'); $('#modalAjax').modal('show'); }) }) </script> HTML; });
  9. 5 points
    WHMCS was one of the companies which take average 6 - 8 hours to respond to our support requests. Even if the answer requires canned responses. But recently since this month precisely, WHMCS support staffs impress me by sending their responses in less than five minutes. Read me, the last response I received from WHMCS staff about is just after one minute of my post. 👏 👏 👏 To all of their efforts.
  10. 5 points
    Hello Good People, Main site was built with WordPress, using a premium theme, with a heavy modification in design. WHMCS part was done using SIX as base, with mostly css modification, some html modification (mostly header and footer). Front end: https://dctit.host/ WHMCS: https://dctit.host/shop/ View Cart page: https://dctit.host/shop/cart.php?a=view Will appreciate your feedback. Kindly let me know your thoughts. Thanks.
  11. 5 points
    Lagom WHMCS Email Template - FREE We’ve just released a Lagom WHMCS Email Template, it’s available in our store completly for Free!! With active license of Lagom WHMCS Theme you will gain access to the simple email template management from the WHMCS addon. You won’t need to have any HTML and CSS knowledge, to customize the Lagom WHMCS Email Template to your needs. You can choose from 3 styles: Futuristic Style - live demo Depth Style - live demo Minimal Style - live demo Lagom Extension Configure Header Text Configure Social Links Configure Footer Links Choose Style Live Preview
  12. 5 points
    Hello there, After a lot of thinking, here you have a template for the Upcoming Domain Renewal Notice that will cover all scenarios. Subject: Domain {$domain_name} is due to expire in {$domain_days_until_expiry} days Dear {$client_name}, Domain {$domain_name} is due to expire in {$domain_days_until_expiry} days - {if $domain_do_not_renew eq "0"}Auto Renew On{else}Auto Renew Off{/if}. {if $domain_days_until_expiry eq "60"}{if $domain_do_not_renew eq "0"}As you have Auto Renew On, you will receive the renewal invoice 30 days before the expiration date.{else}If you would like to have the domain renewed, please access client area and turn On the Auto Renew option.{/if}{else}{if $domain_do_not_renew eq "0"}As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration.{else}To renew the domain, please click on the following url {$domain_renewal_url}.{/if}{/if} {if $domain_days_until_expiry eq "7"}If domain {$domain_name} expires, the website and emails using this domain will no longer work.{/if} {if $domain_days_until_expiry eq "3"}If domain {$domain.name} expires, the website and emails using this domain will no longer work, and the domain may be available to be registered by someone else. WARNING: To renew an expired domain, when possible, you may have to pay a fee of up to $250.{/if} Explanation If you have configured the First Renewal Notice to be sent 60 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 60 days - Auto Renew On. As you have Auto Renew On, you will receive the renewal invoice 30 days before the expiration date. If you have configured the First Renewal Notice to be sent 60 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 60 days - Auto Renew Off. If you would like to have the domain renewed, please access client area and turn On the Auto Renew option. If you have configured the Second Renewal Notice to be sent 30 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 30 days - Auto Renew On. As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration. If you have configured the Second Renewal Notice to be sent 30 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 30 days - Auto Renew Off. To renew the domain, please click on the following url {$domain_renewal_url}. If you have configured the Third Renewal Notice to be sent 7 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 7 days - Auto Renew On. As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration. If domain example.com expires, the website and emails using this domain will no longer work. If you have configured the Third Renewal Notice to be sent 7 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 7 days - Auto Renew Off. To renew the domain, please click on the following url {$domain_renewal_url}. If domain example.com expires, the website and emails using this domain will no longer work. If you have configured the Fourth Renewal Notice to be sent 3 days prior to the expiration date, and the customer has Auto Renew On, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 3 days - Auto Renew On. As you have Auto Renew On, you should have already received the renewal invoice. If you still didn't received the invoice, please contact our sales department. If you have already received the renewal invoice, please pay it as soon as possible to avoid the risk of domain expiration. If domain example.com expires, the website and emails using this domain will no longer work, and the domain may be available to be registered by someone else. WARNING: To renew an expired domain, when possible, you may have to pay a fee of up to $250. If you have configured the Fourth Renewal Notice to be sent 3 days prior to the expiration date, and the customer has Auto Renew Off, here you have the content he will receive on that Notice: Dear Customer Name, Domain example.com is due to expire in 3 days - Auto Renew Off. To renew the domain, please click on the following url {$domain_renewal_url}. If domain example.com expires, the website and emails using this domain will no longer work, and the domain may be available to be registered by someone else. WARNING: To renew an expired domain, when possible, you may have to pay a fee of up to $250. I hope that this will be useful for someone. Best regards, David Duarte
  13. 5 points
    I wouldn't argue with one word of that... the stuff about bug tracking is interesting - i've been here too long and have just got used to CORE-xxxxx being top secret for staff eyes only.... but taking a step back and thinking about other software bug tracking, yes it should be more accessible.... I found it far better years ago when submitting bugs was done here in the f0rum - you could actually see where the bugs are, and so try to work around them.... with BT being outside of here, then only the person submitting the bug, and WHMCS, know about it - until the next maintenance release and you can see the changelog... that's no way to do it.... at least using older releases, you know where the bugs are and that no new ones will be added - with latest versions, it's Russian roulette where the bugs are and if you're going to hit one. feature requests is a joke (and sadly not a funny one) - as you say, why have a nice community hall where we can all gather together, but when we want to make a suggestion, we need to go to the little shed at the bottom of the lane and make a note of it in there... it's ridiculous... you get users making feature requests... that nobody else knows have been created... so they then don't receive many votes... so they don't get implemented by WHMCS... and so the frustration builds.... on so many levels, WHMCS is a company that enjoys to shoot itself in the foot by its own actions. ... and if WHMCS development slowed down any more it would be going backwards - but I know what you meant.... less new features, but get them right before launch. openness applies to communication too... there's no harm in pre-warning us what's going to be in a beta before the code has been released... there might be a crap idea that we can nip in the bud before any coding time is wasted (e.g removing the domain pricing tables and then having to put them back a year later).... once they've released something as a beta, then it's a hell of a task to get a feature removed before general release... and once released, it's in there and then you're left to the feature request path to get it removed... (or apparently just have a few words with some WHMCS employees!). it's the general pervasive attitude of only WHMCS knows best that does my head in (e.g let's change how invoices are calculated and not even disucss it first), and the subsequence lack of communication - when was the last time they ever did a full survey of it's userbase and ask them what they want in the future releases (I can't ever recall one).... and i'm not counting the requests system in that, because that's a flawed broken system that needs ditching asap. v8 should be designed from a blank sheet of paper - because if it's just going to be a slight evolution from v7.6, then they might as well call it v7.7 and we can all go and find something else to use.
  14. 4 points
    Although it seems small but for us the users every extra action we need to do is important. Please bring back the fixed search box as I am sure every one is using it many times everyday. Thank You Giora
  15. 4 points
    When choosing a product that has a recurring billing cycle, WHMCS will show the price in one of two fixed ways – depending on whether the "Monthly Pricing Breakdown" checkbox is ticked in the "Ordering" settings tab within the Admin Area. If it is not ticked, then the price will be displayed alongside the cycle names (taken from the language files) for the available cycles – if there are setup fees included for the cycle, they will be added to the end of the text (shown below on the left). However, if the checkbox is ticked, then WHMCS will not display the total cost of the cycles, but will calculate an equivalent monthly price for each of them instead (shown below on the right). A question was asked in the Community Forum by Ambarella about how to show the total price, the saving from the minimum cycle and also the monthly price for each cycle – e.g. for a layout such as this: http://forum.whmcs.com/showthread.php?84298-How-to-display-discounted-pricing-on-order-pages I was intrigued to see if there was an answer to this question as it has previously been asked many times and as far as I could tell, never really answered. Unfortunately, it is not possible to do this solely by changing any admin settings – the above two methods for displaying the cost of recurring billing cycles are hard-coded into WHMCS. If we were looking to only make a minor change to either layout, it would be possible to do so by slightly modifying the language files and tweaking the existing billing cycle variable in the template. However, Ambarella’s desired layout uses aspects of both methods and then additionally wishes to show the saving too - minor tweaking wouldn’t be sufficient to do this and so a more thorough solution has to be developed. The final solution turned out to be far simpler, from a coding point of view, than I had first imagined as most of the required variables were easily obtainable. I have also tried to keep it flexible and simple enough for others to modify for their own needs. This has been tested using the latest release of WHMCS as I write this, v5.3.4, and will work with all of the default order form templates (Ajaxcart, Boxes, Cart, Comparison, Modern, Slider, Verticalsteps and Web20Cart). If they’re similar in design to the default templates, I can see no reason why this solution shouldn’t work with customised order form templates either. There are three steps to this solution, listed below, and I will go through each of them briefly before bringing them all together to show the completed result. Possible changes to the language file(s). Creation of the new variables to calculate and store the required values. Modifying the template to use these new variables. Language Files The two default methods for showing recurring billing cycles use existing language variables in their display. When “Monthly Pricing Breakdown” is enabled, the following variables are used. In the example below, this is their values from the english.php language file: $_LANG['orderpaymentterm1month'] = "1 Month Price"; $_LANG['orderpaymentterm3month'] = "3 Month Price"; $_LANG['orderpaymentterm6month'] = "6 Month Price"; $_LANG['orderpaymentterm12month'] = "12 Month Price"; $_LANG['orderpaymentterm24month'] = "24 Month Price"; $_LANG['orderpaymentterm36month'] = "36 Month Price"; When disabled, it uses the following variables: $_LANG['orderpaymenttermmonthly'] = "Monthly"; $_LANG['orderpaymenttermquarterly'] = "Quarterly"; $_LANG['orderpaymenttermsemiannually'] = "Semi-Annually"; $_LANG['orderpaymenttermannually'] = "Annually"; $_LANG['orderpaymenttermbiennially'] = "Biennially"; $_LANG['orderpaymenttermtriennially'] = "Triennially"; Ideally, if you can use any of the above groups of variables without modifying them, then it is probably easier to do so. But if you feel that you need to modify any of them for use with this method, I would strongly urge you to consider the consequences carefully before doing so. The second group of variables (Monthly, Quarterly, Semi-Annually etc) are also used on the cart summary page, viewcart.tpl, and so any changes you make to them for use in the billing cycle page, will also affect their display on the cart summary page too. As an aside, I should probably add that if your WHMCS site only uses one language, then you could code the language directly in the template rather than using language variables – but for the sake of this tutorial, I will assume you are not and use the language files. Using the example of Ambarella’s desired output of "Monthly Cost", "Quarterly Cost" etc, you might think that it would be easier to use the existing variable for "Monthly", add another variable to store "Cost" - then use them together. While this might work in English, it would not necessary be grammatically correct in other languages – for example, in the French.php language file, the value for "Monthly" is: $_LANG['orderpaymenttermmonthly'] = "Mensuel"; The French word for "Cost" is "coût" – so if we put them together, we would get "Mensuel coût". Using my (limited!) understanding of French, I think that it should really be "coût mensuel" – and this appears to be confirmed by Google Translate. So to make things easier, we will start by creating six new language variables for use with this recurring billing cycle solution and add them to the language override file(s). Language Overrides Although we can edit the existing language files in WHMCS, it is recommended that you do not because when you update WHMCS, you will overwrite these language files – and subsequently lose any changes that you have made to them. http://docs.whmcs.com/Language_Overrides To create a Language Override file, we would follow this procedure: Create the folder 'overrides' within the 'lang' folder. Create or copy the language file you want to override. For example, to create an override for the French language you create ./lang/overrides/french.php Open the newly created file in your preferred editor. Start the file with a PHP tag '<?php' indicating PHP code is to be used. Try to use variable names that make sense to where they’re being used, and have not previously been used. So, for our six recurring billing cycles, let’s use the following: $_LANG['billingcyclemonth'] = "Monthly Cost"; $_LANG['billingcyclequart'] = "Quarterly Cost"; $_LANG['billingcyclesemi'] = "Semi-Annual Cost"; $_LANG['billingcycleannual'] = "Annual Cost"; $_LANG['billingcyclebienn'] = "Biennial Cost"; $_LANG['billingcycletrienn'] = "Triennial Cost"; To get Ambarella’s output, we will need two additional new language variables – one for “Saving” and another for “Per Month”. $_LANG['cyclesaving'] = "Save"; $_LANG['permonth'] = "P/m"; Now that we have these language variables created, we can move on to making the calculations and saving them for use in the display. Calculations and Variables As the template system used by WHMCS is based on Smarty, I have used only Smarty code for this solution. It would be possible to perform these calculations using PHP within the template, but it is often frowned upon to use {php} tags in the templates. Also, I believe that as of Smarty v3, the option to do use {php} has been removed. Although WHMCS currently uses Smarty v2, I am sure that at some point it will be upgraded. Therefore, as it should be easier for others to follow, and hopefully avoid future upgrade complications, I decided to write the solution entirely using Smarty tags. We need to calculate the saving of a recurring billing cycle compared to the minimum billing cycle – this would probably be the monthly cycle, but this is not always the case. Usefully, the variable that stores the minimum billing cycle is available to us and so we can use it in our calculations to determine the correct savings for each enabled recurring billing cycle based on the minimum cycle. Additionally, we need to calculate the price per month of a recurring billing cycle – but this is simple as it is just the total price for the billing cycle divided by its total number of months. So let’s start with the easier step first – calculating the price per month of a cycle. Obviously, we don’t have to calculate the price per month for the monthly cycle, so we just need to work out the other five. For this we need two variables - the total billing cycle cost (which we can obtain from existing variables) and the number of months in each cycle (which we will define ourselves). First, we create a new variable and give it a value of zero to ensure that any calculations are not added to any previous total. Then, using the {math} Smarty tag, we assign our result to this variable; define what the equation is; specify the variables we’re using in the equation and set the format of the resulting answer... and then repeat the same process for the remaining recurring billing cycles. {assign var="qmonthprice" value=0} {math assign="qmonthprice" equation="d / b" b=3 d=$pricing.rawpricing.quarterly format="%.2f"} {assign var="smonthprice" value=0} {math assign="smonthprice" equation="d / b" b=6 d=$pricing.rawpricing.semiannually format="%.2f"} {assign var="amonthprice" value=0} {math assign="amonthprice" equation="d / b" b=12 d=$pricing.rawpricing.annually format="%.2f"} {assign var="bmonthprice" value=0} {math assign="bmonthprice" equation="d / b" b=24 d=$pricing.rawpricing.biennially format="%.2f"} {assign var="tmonthprice" value=0} {math assign="tmonthprice" equation="d / b" b=36 d=$pricing.rawpricing.triennially format="%.2f"} The above code will create the price per month for each recurring billing cycle and store it to two decimal places. Next we need to calculate the savings – this uses a similar method to the previous example, but there are more variables required and thus the equation itself is more complicated - we will also use an {if} statement to determine what the minimum billing cycle is. To calculate the saving, we also take into account any setup fees for each cycle. For the previous “price per month” calculation, I have ignored any setup fees – but these could easily be added by modifying the previous equations if you wished to include them. As the minimum billing cycle increases, there are fewer additional cycles available and so fewer calculations will be required. For "Monthly", there are five saving calculations to be made – but by the time the minimum cycle is "Biennial", there is only one calculation required. If the minimum billing cycle is "Triennial", then it will not necessary to calculate any savings as there will only be one recurring billing cycle available. Here is a small example of the required code... {if $pricing.minprice.cycle eq "monthly"} {assign var="qsaving" value=0} {math assign="qsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=3 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.quarterly e=$pricing.rawpricing.qsetupfee format="%.2f"} {/if} The above code will calculate the savings for the quarterly billing cycle based on the minimum billing cycle being monthly, and store it to two decimal places. So we have our modified language variables; we have created our equations to calculate the price per month / cycle savings and assigned them to new variables – the third step is to integrate these into the templates. Template Modifications As I stated earlier in this tutorial, this solution will work for all of the default order form templates and should work for customised order form templates too. While there might be slight variations in the code used to create the billing cycle table in the different order form templates, the six important variables remain the same – and it is only these that you will need to replace with my new code. If we use "Comparison" as an example and look at the current code for displaying the monthly cycle: {if $pricing.monthly}<tr><td class="radiofield"> <input type="radio" name="billingcycle" id="cycle1" value="monthly"{if $billingcycle eq "monthly"} checked{/if} onclick="submit()" /></td><td class="fieldarea"><label for="cycle1">{$pricing.monthly}</label></td></tr>{/if} To use the new modified code to display our customised layout, you need to replace the above with: As you can see, the basics of the layout remain exactly the same, all we have done is replaced {$pricing.monthly} with the following: {$LANG.billingcyclemonth} {$currency.prefix}{$pricing.rawpricing.monthly}{$currency.suffix}{if $pricing.rawpricing.msetupfee neq 0} + {$currency.prefix}{$pricing.rawpricing.msetupfee}{$currency.suffix} {$LANG.ordersetupfee}{/if} Some of these variables you will recognise as we have created them previously – the others are defined by WHMCS, either to store price / setup fee values, or currency strings. {$currency.prefix} - The prefix defined in your currency settings, e.g. $, £, € etc or left blank. {$currency.suffix} - The suffix defined in your currency settings, e.g. USD, GBP, EUR etc or left blank. If we take a look at the next billing cycle, in this case quarterly, you will see some additional code that will generate the saving text (which obviously is not used on the minimum billing cycle). After adding the code for the remaining billing cycles, the output using the Comparison order form would be as follows: In the above examples, I’ve intentionally setup some billing cycles to have setup fees and others not – this was to thoroughly test the equations used. So that’s a brief explanation of the theory, next we will assemble the three steps and bring them together for the finished solution. Language Files As I previously listed, here are the eight new language variables - if you want to use them, remember to add them to your language override file(s). Should you need to add more or change these, please do so! $_LANG['billingcyclemonth'] = "Monthly Cost"; $_LANG['billingcyclequart'] = "Quarterly Cost"; $_LANG['billingcyclesemi'] = "Semi-Annual Cost"; $_LANG['billingcycleannual'] = "Annual Cost"; $_LANG['billingcyclebienn'] = "Biennial Cost"; $_LANG['billingcycletrienn'] = "Triennial Cost"; $_LANG['cyclesaving'] = "Save"; $_LANG['permonth'] = "P/m"; Calculations and Variables If you require calculations and new variables for your solution, add them to the template before the lines in which these newly created variables are called. For this solution, we will need to add the following to the 'configureproduct.tpl' order form template(s) *before* the template modifications of step 3. {* Calculate the price per month *} {assign var="qmonthprice" value=0} {math assign="qmonthprice" equation="d / b" b=3 d=$pricing.rawpricing.quarterly format="%.2f"} {assign var="smonthprice" value=0} {math assign="smonthprice" equation="d / b" b=6 d=$pricing.rawpricing.semiannually format="%.2f"} {assign var="amonthprice" value=0} {math assign="amonthprice" equation="d / b" b=12 d=$pricing.rawpricing.annually format="%.2f"} {assign var="bmonthprice" value=0} {math assign="bmonthprice" equation="d / b" b=24 d=$pricing.rawpricing.biennially format="%.2f"} {assign var="tmonthprice" value=0} {math assign="tmonthprice" equation="d / b" b=36 d=$pricing.rawpricing.triennially format="%.2f"} {* Calculate the cycle savings *} {if $pricing.minprice.cycle eq "monthly"} {assign var="qsaving" value=0} {math assign="qsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=3 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.quarterly e=$pricing.rawpricing.qsetupfee format="%.2f"} {assign var="ssaving" value=0} {math assign="ssaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=6 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.semiannually e=$pricing.rawpricing.ssetupfee format="%.2f"} {assign var="asaving" value=0} {math assign="asaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=12 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.annually e=$pricing.rawpricing.asetupfee format="%.2f"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=24 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.monthly b=36 c=$pricing.rawpricing.msetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "quarterly"} {assign var="ssaving" value=0} {math assign="ssaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=2 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.semiannually e=$pricing.rawpricing.ssetupfee format="%.2f"} {assign var="asaving" value=0} {math assign="asaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=4 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.annually e=$pricing.rawpricing.asetupfee format="%.2f"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=8 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.quarterly b=12 c=$pricing.rawpricing.qsetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "semiannually"} {assign var="asaving" value=0} {math assign="asaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.semiannually b=2 c=$pricing.rawpricing.ssetupfee d=$pricing.rawpricing.annually e=$pricing.rawpricing.asetupfee format="%.2f"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.semiannually b=4 c=$pricing.rawpricing.ssetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.semiannually b=8 c=$pricing.rawpricing.ssetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "annually"} {assign var="bsaving" value=0} {math assign="bsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.annually b=2 c=$pricing.rawpricing.asetupfee d=$pricing.rawpricing.biennially e=$pricing.rawpricing.bsetupfee format="%.2f"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.annually b=3 c=$pricing.rawpricing.asetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {elseif $pricing.minprice.cycle eq "biennially"} {assign var="tsaving" value=0} {math assign="tsaving" equation="((a * b) + c) - (d + e)" a=$pricing.rawpricing.biennially b=1.5 c=$pricing.rawpricing.bsetupfee d=$pricing.rawpricing.triennially e=$pricing.rawpricing.tsetupfee format="%.2f"} {/if} Template Modifications In the previous step, we modified the 'configureproduct.tpl' to calculate and assign some new variables. Next, we will replace the existing recurring billing cycle code in that same template file with the new code. To make this solution complete, I will go through the default order form templates and show the existing code, plus the new code to replace it with. Ajaxcart The default recurring billing cycle code for Ajaxcart (configureproduct.tpl) is... Replace the above with the new modified code... Please note: This code appeared not to work in v5.3.3, but following the v5.3.4 maintenance release, the pricing bugs have been fixed in WHMCS and this solution now works using Ajaxcart in v5.3.4 Boxes The original code and the replacement code are the same as for Ajaxcart. Cart The original code and the replacement code are the same as for Ajaxcart. Comparison The default recurring billing cycle code for Comparison (configureproduct.tpl) is... Replace the above with the new modified code... Modern & Slider The default recurring billing cycle code for Modern & Slider (configureproduct.tpl) is... Replace the above with the new modified code... Verticalsteps The original code and the replacement code are the same as for Ajaxcart. Web20Cart The original code and the replacement code are the same as for Ajaxcart. Taking the solution to the next level During this tutorial, I’ve shown how, instead of using either of the default WHMCS predefined displays of recurring billing cycles, we can define and use our own specified layout. But, why stop there? Now that we are no longer constrained by hardcoded displays, we could take this further and make other changes... some trivial, others cosmetic and perhaps one or two that are very powerful! Ok, let’s start off with something trivial that you can use on those templates that don’t have a dropdown to display the cycles – e.g., Comparison, Modern and Slider. If you wanted to bold the billing cycle names, and perhaps highlight any potential savings by showing them in red, you could use the following code: When originally working out the Smarty code for this tutorial, I did consider using combined variables as WHMCS currently does, e.g $pricing.monthly etc, where a number of variables are assembled together to create a single easily callable variable. However, I decided against doing this for a number of reasons – firstly, I wanted to show all the component variables separately to make it easier for others to remove or add variables themselves; Secondly, because the variables are separate, each can be modified (either with Smarty code or as with the above html/css) individually and thirdly, in most circumstances I can foresee with this, I don’t think there’s any real advantage in doing so! So we’ve modified the display a little, but why don’t we try to do something a little more powerful! Up until this point, we have simply been replacing the default method of displaying the recurring billing cycles with our customised solution - but if we can create one solution, why not a second, a third or a hundred? We are now in a position where, instead of WHMCS just using one recurring billing cycle display method for the entire site, we can specify different cycle displays for each product and/or product group. Put simply – each individual product or product group can use its own method for displaying recurring billing cycles, as defined by you! The code itself is straightforward and uses the variables for Group ID (gid) and Product ID (pid) – these values can be obtained from the “Direct Cart Links” section of the Product or Product Group in the Admin Area - http://docs.whmcs.com/Products_and_Services#Links_tab As an example, let’s use Ajaxcart and specify a custom display method for one product – all other products will use the default method of display (in practice this could be another custom layout, but to save time and keep things simple, we’ll use the default display code). in basic terms, this: In actual code... If you wanted to select product groups and individual products to use the same display method, then you could use... You can add as many products and/or groups you want to the above statement or use multiple {if} statements - just remember to end the block of code with a closing {/if}, This advanced solution should hopefully allow you to make the shopping process slightly easier for your customers by enabling you to use more appropriate billing cycle text for each product and/or group. I suspect that I've only scratched the surface of what is possible with this technique... so if anyone turns this into a commercial addon, I'd appreciate a share of the profits, a mention - or at the very least, a small glass of cooking sherry to get me through the day.* * I'd add a smilie at this point, but I'm limited to ten images and can't add one! lol
  16. 4 points
    Hi everyone! Since I spend most of my time during the day on the WHMCS admin dashboard, answering tickets, activating services, following up with stuff, etc. I wanted to keep eye strain to a minimum, so I recently created this CSS file to turn our admin area into a dark look and feel. ------- Today, I'd like to share with you steps to achieve that. The file is compatible with Blend theme of v7.9.2 of WHMCS, I haven't tested it on the other versions yet. The process is pretty simple and straightforward IF YOU HAVEN'T MADE ANY CUSTOMIZATIONS to your Blend theme already. So just download the attached file (blend-dark.zip) and extract it anywhere in your computer. Next, open the folder and then the "images" folder to locate the (logo-dark.psd) file to edit it by placing your own logo there. Then save it as "logo-dark.gif" replacing the already existing file. Now you should end up with a file tree like this ... blend |__ css | |__ admin-dark.css | | |__ images | |__ logo-dark.gif | |__ logo-dark.psd | |__ header.tpl Now back top and compress your "blend" folder ... Name it something memorable, like "blend-2222.zip" in this example. Next navigate to the "admin" folder inside your WHMCS installation, and open the "templates" folder (based on your customizations, the "admin" folder name may differ, so this here presumes the default setting). /path/to/whmcs/admin/templates/ Next make sure to ZIP and backup your current Blend theme folder (name it something like "blend-original.zip). Next, upload the "blend-2222.zip" you compressed earlier to the "templates" folder and unzip it, and you should be all set and ready! If you have any notes or additions, please feel free to add! Also, any mistakes or errors are unintentional, please feel free to share and highlight them. Wishing everyone a good day! - Mohamed
  17. 4 points
    $38.14 + 18% = $45 if the tax is inclusive, then the price already contains the tax... so if the price were $118, the tax would be $18 and the subtotal $100 https://docs.whmcs.com/Tax/VAT#Inclusive.2FExclusive_Tax Tax Amount = ( Item Price / ( 100 + Tax Rate ) ) x Tax Rate Tax Amount = ( 45 / ( 100 + 18 ) ) x 18 = 6.86
  18. 4 points
    in response to the thread below, please find attached two hooks to generate Homepage Panels to output a clients email history (with clickable links) - don't use both, just choose one! 🙂 The "original" version, that I quickly wrote as a demo for the above thread, links each row to open that email in a new tab/window... The updated "popup" version includes a clickable "button" that opens the email in a popup window (as per the Email History page accessible from the secondary navbar menu)... both panels use Language Translations to display the phrases "Email History", "View All" and "View" in the client's language. the date output uses the Global Date Format (as specified in your general settings -> localisation) - you could easily make it use the Client Date Format, but because we only have limited space for date and subject, I thought it easier to use the shorter global format. currently, the hook obtains ALL of your clients email history - if you want to limit that to a certain amount, e.g 100, then you would add a limit to the query... $clientemails = Capsule::table('tblemails')->where('userid', $client->id)->select('id','subject','date')->orderBy('date','desc')->limit(100)->get(); with additional coding, and probably some new Language Overrides, you should be able to identify each email type (based on the subject), and color the "button" links accordingly... i'm not going to include that version here - not least because it would require a lot of coding (which I haven't done!) to thoroughly cover all email templates and languages , but it would be achievable given the required effort.
  19. 4 points
    @bullten picks up gun and shoots himself in the foot with his own argument - if they understand it so much.... why are there long outstanding bugs in the core software that never get fixed ? why does every major release need a maintenance release to within a fortnight to fix the newly introduced bugs ? why does it take them three weeks to write a one-line change of URL in a hotfix for pre-v7.6 releases ? why do feature requests take upto five years to get implemented ? why do some new features get introduced with no beta testing, no pre-announcement and seemingly no public requests for it through the usual channels ? why during beta testing is there no documentation on new features ? they publicly release into general availability and LATER release the documentation - by which time the bugs are already in place and they've moved on to the next feature. I could go on, but I fear that i'd just be wasting my time explaining it to you. 🙄 you seem to assume that we're all saying WHMCS is great, their business is great, we agree with how they do things - many of us believe the opposite... except we're wise enough to grudgingly accept that WHMCS is what it is and it sadly isn't going to change. plus the idea of relying of WHMCS for basic security is the equivalent of you picking up the gun and shooting yourself in the other foot. 👣 the only person who annoyingly keeps on throwing the word "impossible" around is you - WHMCS isn't a democracy, you (or I) don't have any say on what's going to be implemented... they're not going to be swayed by a post here; they're not going to make a rod for their own back by doing what you suggest. how sad - some of us are paid to DO things with what we've learnt - others seemingly just want to talk to hear their own voice... so i'll plonk you on the ignore list and walk away from the thread - it's now becoming pointless.
  20. 4 points
    then the simplest solution would be to edit /templates/six (or custom)/includes/verifyemail.tpl and add the following to the end of the file... {if $clientsdetails.twofaenabled === false} <div class="email-verification"> <div class="container"> <div class="row"> <div class="col-xs-2 col-xs-push-10 col-sm-1 col-sm-push-11"> <button type="button" class="btn close"><span aria-hidden="true">×</span></button> </div> <div class="col-xs-10 col-xs-pull-2 col-sm-7 col-sm-pull-1 col-md-8"> <i class="fas fa-tablet-alt"></i> <span class="text">{$LANG.twofaactivationintro}</span> </div> <div class="col-xs-12 col-sm-4 col-md-3 col-sm-pull-1"> <a href="clientarea.php?action=security" class="btn btn-default btn-sm btn-block btn-resend-verify-email">{$LANG.twofaenable}</a> </button> </div> </div> </div> </div> {/if} i've used an existing 2FA language string as an example (though it's too long for this purpose), so you should probably create your own custom string using Language Overrides, or if your site is only using one language, use that directly in the template instead of a language string. also, remember that you'll need to update the template after each update if the auto-updater overwrites it.
  21. 4 points
    Impressive, @Matt. It's not every day the CEO of a software company personally attends to and responds to customer issues like this. I'm truly impressed in the dedication to our community.
  22. 4 points
    I think one of the fundamental problems that we have, and that are demonstrated even within this thread, is that everybody has different priorities. Brian has the bugs he's reported, Tom has his, yggdrasil I’m sure you have yours. Similarly Agentblack has feature requests he wants that are different to the ones Brian wants, and different to the ones Tom wants. In an ideal world we would love to be able to implement every requested feature, and fix every reported bug, but that simply isn't reality. As a software company, we have to pick and choose what we work on. And we use a number of factors to help us decide what we work on. Firstly, we look at how many people have reported the issue. Issues that are reported by multiple people are obviously prioritized. Other factors that affect the decision are what is the impact of the issue, how many people are using the area of the product it affects and do workarounds exist. Looking at the changelogs from the past year of releases, there's been over 700 cases addressed that related to bugs and reported issues. That's not the number of a company that is ignoring bug reports. Now are there some we haven’t fixed? Sure. Your’s may be one of them and we know that’s frustrating. New features in that time have included things such as support for Premium Domains, New Product and Domain Statuses, Product Addons Module Support, API Tokens, Module Queue, Automation Insights, Improved ACL Controls, Direct Debit Support, SSL Automation, New Payment Gateways including Stripe and Accept.js, and soon features including MailChimp integration, More Backup Options, Social Sign-In Integration and more. These are all big ticket features that have a real positive impact on the businesses of our users, allowing them to do more, sell more and ultimately we hope, be more successful, which is always our goal - enabling our customers to be as successful as possible. We have these forums so that issues can be discussed, and a healthy discussion is welcome. We do read the forums and do have discussions internally based on the issues raised here. We’re always on the lookout for issues gaining a lot of traction. The new community forums are the first of a number of projects we have planned to grow community involvement and deliver a more integrated experience between us and our customer base. At the end of the day we will always have to prioritise and we know that will end up disappointing some users some times. But we are always happy to revisit anything our users bring to our attention. Matt
  23. 4 points
    I ran into an issue with this hook today - it works fine on a product linked to cPanel, but with other products it shows a blank page. with the assistance of sentq, I was able to tweak it to work correctly. <?php use WHMCS\View\Menu\Item as MenuItem; add_hook('ClientAreaPrimarySidebar', 1, function(MenuItem $primarySidebar) { $service = Menu::context('service'); $domain = $service->domain; $servertype = $service->product->servertype; # Not cPanel, no links added if ($servertype!="cpanel"){ return; } if (!is_null($primarySidebar->getChild('Service Details Actions'))) { $primarySidebar->getChild('Service Details Actions') ->getChild('Login to cPanel') ->setUri('http://'.$domain.'/cpanel'); $primarySidebar->getChild('Service Details Actions') ->getChild('Login to Webmail') ->setUri('http://'.$domain.'/webmail'); } });
  24. 3 points
    Hi all, I'm pleased to confirm that v8.0.2 addressed the issue related to domain sync Next Due Dates and an improvement to the reporting when an invalid domain is encountered: CORE-15468 - Correct reporting of Domain Sync Next Due Dates CORE-15461 - Provide context for Invalid Domain errors in Domain Sync Thank you for reporting those issues.
  25. 3 points
    methinks he was being sarcastic - as the three of us all posted in that now-deleted (sorry hidden!) thread... which, for the benefit of others, is worth mentioning that it was started at the beginning of August (2 months ago)...
  26. 3 points
    For v8 I really would like WHMCS to separate the market connect files, that includes the languages and the module. Have it as a separated download or installation. MarketConnect is a very different customer target to the original WHMCS clients. I surely don't need uploading and upgrading all those extra files for something I have no interested on using. I also paid the non-branded version but I see that lately WHMCS keeps renaming more and more files to whmcs.ext, in particular CSS and JS on the frontend. Personally I think this defeats the remove the branding option license. Its undesired for most installations as bots and spammers constantly scan WHMCS installations. This is not going to protect against security but I don't think it's a great idea to expose the WHMCS name on every single file. It also looks sloppy from the developing naming side. In the past WHMCS used more generic names for files which was a better fit because naming something WHMCS.js does not really tell me anything about what that file does and its purpose either. Files should be named based on what they do. Changes like this require almost no effort on WHMCS part or their development team and it would at least improve something. WHMCS is getting huge and I seriously think there are so many redundant files and things that most people don't need. It's not about saving space, but just being more efficient. I don't need thousands of files living on a production server that I will never use.
  27. 3 points
    Hello @WHMCS Sachin Thanks for letting us be more open to share our ideas.😄 Al WHMCS users like this software a lot, so even that we know that software belongs to WHMCS, we would like to have it with our branded name on it, so my suggestion is that app could import our company name (that already exists on WHMCS admin>Setup>General settings) And display that name on app somewhere, on top or not, it is up to WHMCS where would be more convenient during developing , my print suggestion bellow. PS: this option to show company name could be also optional, so this mean if a user do not want to see their company name there , he\she could go to app settings and disable it with tick on\off so every one will be happy. Personally I think having a possibility to see our company name on APP make, make us feel like ...this is our app too, also perhaps could be users that have several WHMCS installations, so when they switch from one to another they could know easily on what installation is 👌
  28. 3 points
    Following a question from @Mauwiks... natively in WHMCS, there is no way to do this - but with the help of the attached hook, it is possible - just upload the hook to /includes/hooks the hook currently includes EIGHT different parameter options - I can think of at least 4 more options that I could add, and may do so at a later date, but I think 8 is plenty to be going on with. 🙂 note: the addon's ID value can be found when in the URL when you edit that product addon in the admin area - configaddons.php?action=manage&id=1 Linking to one specific product addon cart.php?gid=addons&id=1 Linking to Market Connect product addons by brand cart.php?gid=addons&id=codeguard cart.php?gid=addons&id=sitelock cart.php?gid=addons&id=spamexperts cart.php?gid=addons&id=ssl cart.php?gid=addons&id=weebly these addons are found by the hook searching whether specific terms are found at the START of the product addon descriptions, e.g Codeguard etc Linking to multiple product addons cart.php?gid=addons&multi[]=1&multi[]=32&multi[]=54 Linking to a predefined group of product addons cart.php?gid=addons&id=group1 $group1 is a predefined array of product addon IDs that you can edit in the hook.. $group1 = array(12,28,20); you could, in theory, have multiple groups (arrays of addon IDs) predefined in the hook, but it's currently only coded for 1 group - but it would be simple enough to change. if you pass a numeric addon ID value that doesn't exist for the particular client, then you'll get the no addons available error message... ... I did toy with the idea of showing all addons under those circumstances, but I decided against it for now - not least because it keeps the coding simplified! 😉 if you pass an undefined non-numeric id, e.g cart.php?gid=addons&id=brian, then there is nothing for the hook to remove and it will show all addons as per normal. you can only use one parameter option in a URL - e.g., you can't use cart.php?gid=addons&id=43&multi[]=32 addons_mauwiks.php
  29. 3 points
    I think you've really overcomplicated this by using multiple hooks and the way you're using each of them - it can be simplified to something more clearer... in fact, it could be reduced far more than i'm going to post here as i'm trying to keep it understandable for all. to a certain extent, that bit is fine... i'd argue that removing the affiliates link for everyone, then wanting to add it back just for clients, is a little silly - just remove it for non-clients. i'm not sure that you have going from that screenshot. you have to be careful because just one character wrong and it won't necessarily throw an error, the hook just won't work. out of the box, I don't think that Lagom does anything kinky with the navbars (other than to split the primary / secondary locations) - using hooks on them should still work... and i'm speaking as someone who was generously given a Lagom developers license by a client. 😎 one way I would write that hook would be... <?php add_hook('ClientAreaPrimaryNavbar', 1, function($primaryNavbar) { $client = Menu::context('client'); # remove for all if (!is_null($primaryNavbar->getChild('Home'))) { $primaryNavbar->removeChild('Home'); } # remove for non-clients if (is_null($client) && !is_null($primaryNavbar->getChild('Store'))) { $primaryNavbar->removeChild('Store'); } if (is_null($client) && !is_null($primaryNavbar->getChild('Affiliates'))) { $primaryNavbar->removeChild('Affiliates'); } if (is_null($client) && !is_null($primaryNavbar->getChild('Knowledgebase'))) { $primaryNavbar->removeChild('Knowledgebase'); } if (is_null($client) && !is_null($primaryNavbar->getChild('Announcements'))) { $primaryNavbar->removeChild('Announcements'); } # add for non-clients if (is_null($client)) { $primaryNavbar->addChild('hosting')->setLabel(Lang::trans('Hosting'))->setOrder(11); if (!is_null($primaryNavbar->getChild('hosting'))) { $primaryNavbar->getChild('hosting')->addChild('sharedhosting')->setLabel(Lang::trans('Shared Hosting'))->setURI('cart.php?gid=1')->setOrder(1); $primaryNavbar->getChild('hosting')->addChild('wordpresshosting')->setLabel(Lang::trans('WordPress Hosting'))->setURI('cart.php?gid=34')->setOrder(2); } $primaryNavbar->addChild('ecommerce')->setLabel(Lang::trans('Ecommerce Hosting'))->setOrder(12); if (!is_null($primaryNavbar->getChild('ecommerce'))) { $primaryNavbar->getChild('ecommerce')->addChild('ecommerce1')->setLabel(Lang::trans('CS-Cart Hosting'))->setURI('cart.php?gid=36')->setOrder(1); $primaryNavbar->getChild('ecommerce')->addChild('ecommerce2')->setLabel(Lang::trans('Magento Hosting'))->setOrder(2); } $primaryNavbar->addChild('vps')->setLabel(Lang::trans('Virtual Private Servers'))->setOrder(13); if (!is_null($primaryNavbar->getChild('vps'))) { $primaryNavbar->getChild('vps')->addChild('vps1')->setLabel(Lang::trans('VPS Cloud Shared'))->setURI('cart.php?gid=33')->setOrder(1); $primaryNavbar->getChild('vps')->addChild('vps2')->setLabel(Lang::trans('VPS Cloud Dedicated'))->setURI('cart.php?gid=31')->setOrder(2); } $primaryNavbar->addChild('dedicated')->setLabel(Lang::trans('Dedicated Servers'))->setURI('cart.php?gid=14')->setOrder(14); $primaryNavbar->addChild('cscart')->setLabel(Lang::trans('CS-Cart'))->setOrder(15); if (!is_null($primaryNavbar->getChild('cscart'))) { $primaryNavbar->getChild('cscart')->addChild('cscartlicenses')->setLabel(Lang::trans('CS-Cart Licenses'))->setURI('cart.php?gid=2')->setOrder(1); $primaryNavbar->getChild('cscart')->addChild('cscarthosting')->setLabel(Lang::trans('CS-Cart Hosibg'))->setURI('cart.php?gid=36')->setOrder(2); } } # add for clients only if (!is_null($client)) { $primaryNavbar->addChild('kb')->setLabel(Lang::trans('knowledgebasetitle'))->setURI('knowledgebase.php')->setOrder(50); } }); possibly an oversight on your part, but the magento child doesn't contain a link. in terms of how to add menu items for logged in users, i've done that at the end of the above hook where i've added a kb link back in for clients only. if you mean Services/Domains/Billing/Support, and removing them entirely/individually, then you don't really need to check whether the user is logged in or not - the same as you don't need to (though I do in the above hook) check that the client is not logged in when removing the "Store" link... it doesn't matter because only non-clients see the store link, clients don't (at least out of the box)... as an aside, you could nuke them with about 4 lines of code if you had to - but there are only four elements to remove, so let's not be deploying weapons of mass destruction for something so small. ☢️ note this quick method works because these default navbar children have unique names - if you had a situation where a link exists in both logged non-logged navbars (home being the obvious example), and you wanted to change their links depending on client logged in status, then under those circumstances, you would check first whether they were logged in or not... but I think for your purpose, you won't have to. so if you wanted to remove the Services tab for logged in users... if (!is_null($primaryNavbar->getChild('Services'))) { $primaryNavbar->removeChild('Services'); } that works because it checks to see of the parent exists, and only if it does, does it try to remove it - so for a non-client, it wouldn't get past the if statement. for kb, see above; for affiliates, I solved the issue by only removing it for non-logged in users - for new menu items, see above (re: kb and how I added the non-logged in parents with their kids).
  30. 3 points
    why? are they going to have a survey or a vote on what to add ?? (even if they did, how many users would vote??) no - they will already know what's going to change, and the user base will either have to like it or lump it.
  31. 3 points
    When displaying your payment options during the final stages of the checkout process, the available payment gateway options are shown as text – in a number of different ways based upon the order form template being used. If we wanted to make this more attractive, we could replace the text of any or all of the gateways, with an image or logo, by editing the viewcart.tpl template within the active order form template. In order to do this, we can use one of the WHMCS variables that we have access to during the checkout process - $gateway.sysname - the variable stores in lowercase, the unique name used by WHMCS for the payment gateway. This is not the value you entered for the gateway in the “Display Name” field in the “Payment Gateways” section of the Admin Area. The next step is to create or find images for each of the gateways that you wish to replace with a graphic, all in the same graphic format (PNG, JPG or GIF) and save them with a lowercase filename. For example, if you were using PNG format, then your “PayPal” image would be called ‘paypal.png’; your “Bank Transfer” image is called ‘banktransfer.png’; and the “Mail-In Payment” gateway (in the above example, named ‘Cheque’) would be ‘mailin.png’. I believe the filename to be used is based upon the filename of the gateway file in ‘modules/gateways’, but you should be able to find its value by viewing the source of your cart page in your browser... [<label><input type="radio" name="paymentmethod" value="paypal" onclick="hideCCForm()" /> <img src=images/paypal.png /> So the part of interest above is: value=”paypal”. You would then upload these images to your “images” directory within WHMCS. If you wanted to put them in their own folder within the “images” directory, you can – but you will need to adjust the URL in the code below to take account of the slightly different path (see end of tutorial). The images directory i'm using in these examples is whmcs/images - and not the template(s) images folder. The replacement code works by first creating a new variable to store the URL of the gateway logo, then it will check to see if the image exists in the “images” folder (remember that it must have a lowercase filename on the server otherwise it will not be found) – if the image exists, it will display the image; if no image is found, it will display the text (as it does now). In the examples above, I have only uploaded a ‘paypal’ logo and hence only that gateway is using a replacement image – if I were to upload logos for the other two gateways, they would also be used instead of their text names. So, I will now go through each of the eight existing order form templates and show the code to be replaced, the replacement code and an image of how the cart checkout page looks when the new code is added. Ajaxcart Replace.... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {$gateway.name}</label>{/foreach}</div> With... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</div> Boxes Replace.... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label> {/foreach}</p> With... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}</label> {/foreach}</p> Cart Replace... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label> {/foreach}</p> With... <p align="center">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</p> Comparison Replace... <p class="paymentmethods">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label><br />{/foreach}</p> With... <p class="paymentmethods">{foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label><br />{/foreach}</p> Modern Replace... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {$gateway.name}</label> {/foreach} With... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach} Slider Replace... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{$gateway.name}</label> {/foreach} With... {foreach key=num item=gateway from=$gateways}<label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} />{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach} Verticalsteps Replace... <p align="center">{foreach key=num item=gateway from=$gateways}<input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /><label for="pgbtn{$num}">{$gateway.name}</label> {/foreach}</p> With... <p align="center">{foreach key=num item=gateway from=$gateways}<input type="radio" name="paymentmethod" value="{$gateway.sysname}" id="pgbtn{$num}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /><label for="pgbtn{$num}">{assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</p> Web20Cart Replace... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {$gateway.name}</label> {/foreach}</div> With... <div class="cartbox">{foreach key=num item=gateway from=$gateways} <label><input type="radio" name="paymentmethod" value="{$gateway.sysname}" onclick="{if $gateway.type eq "CC"}showCCForm(){else}hideCCForm(){/if}"{if $selectedgateway eq $gateway.sysname} checked{/if} /> {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if}</label> {/foreach}</div> Customised Order Form Templates If you are using a customised order form, perhaps supplied with a purchased WHMCS theme, this solution may still work with your template - in viewcart.tpl, you simply replace... {$gateway.name} With... {assign var="paylogo" value="images/`$gateway.sysname`.png"} {if file_exists($paylogo)} <img src={$paylogo} /> {else} {$gateway.name}{/if} In these examples, I have used .PNG images - if you wanted to use .JPG or .GIF instead, then you would replace .png in the code with .jpg or .gif - remember, they must all use the same format! if you wanted to put the gateway images in their own folder, e.g 'paylogos', then you would replace the code... {assign var="paylogo" value="images/`$gateway.sysname`.png"} with... {assign var="paylogo" value="images/paylogos/`$gateway.sysname`.png"} I hope this helps anyone who wants to replace their payment gateways text with images. I should also add that this is tested and working on the latest WHMCS release as of this tutorial - v5.3.3
  32. 3 points
    then you wouldn't use this hook, you would instead use ClientAreaProductDetailsOutput hook and specify what output occurs with specific service(s). <?php add_hook('ClientAreaProductDetailsOutput', 1, function($service) { $serviceID = $service['service']->Id; if ($serviceID == '600') { $output .= '<div class="alert alert-success" role="alert"><div class="row"><div class="col-sm-1"><i class="fab fa-whmcs fa-3x"></i></div><div class="col-sm-11">Welcome to WHMCS!<br><small>buy the addon!</small></div></div></div>'; } if ($output) { return $output; } }); it's worth noting that the location of this specific hook output is determined by the Smarty template and not the hook itself - if you were displaying MarketConnect banners on that page, it would display below them. if you have an unpaid/overdue invoice, then there is a default alert shown at the top of the page... ... but that output is specified in the template itself and only triggered if/when hardcoded conditions are passed to the template. if you wanted to output your alert elsewhere on the page, you would be looking at either editing the template to define exactly where the output should be (you could still trigger it, and specify it's content, with a hook), or using another output hook, containing JS to specify the exact location of the output (though can be difficult depending on where you want to output).
  33. 3 points
    One thing to note is that WHMCS will redirect from contact.php to submitticket.php (your specific department) if you select a ticket department under WHMCS admin > setup > general settings > mail > Presales Form Destination
  34. 3 points
    you might want to share what the solution was in case others read this thread in the future.
  35. 3 points
    I've expanded this hook a bit to also cover failed transfers and log everything it does to the activity log. <?php use WHMCS\Database\Capsule; add_hook('DomainTransferCompleted', 1, function($vars) { //This hook will complete to-do items for transfers when the transfer is completed. $toDoID = Capsule::table('tbltodolist') ->where('status', 'In Progress') ->where('title', 'Domain Pending Transfer') ->where('description', 'LIKE', '% ' . $vars['domain'] . '%') ->get(); //Loop through the ID's and set them as completed. foreach ($toDoID as $entry) { $command = 'UpdateToDoItem'; $postData = array( 'itemid' => $entry->id, 'adminid' => '1', //Update this ID to an admin ID 'status' => 'Completed', ); localAPI($command, $postData); logActivity('Clean-up To-do List: ID ' . $entry->id . ' has been set as complete as the transfer completed successfully - Domain ID: ' . $vars['domainid'] . ' - Domain: ' . $vars['domain']); } }); add_hook('DomainTransferFailed', 1, function($vars) { //This hook will update to-do items for ttransfer that fails. $toDoID = Capsule::table('tbltodolist') ->where('status', 'In Progress') ->where('title', 'Domain Pending Transfer') ->where('description', 'LIKE', '% ' . $vars['domain'] . '%') ->get(); foreach ($toDoID as $entry) { $description = Capsule::table('tbltodolist') ->where('id', $entry->id) ->value('description'); $command = 'UpdateToDoItem'; $postData = array( 'itemid' => $entry->id, 'adminid' => '1', //Update this ID to an admin ID 'status' => 'Incomplete', 'description' => '*FAILED* '.$description, ); localAPI($command, $postData); logActivity('Clean-up To-do List: ID ' . $entry->id . ' has been set as incomplete as the transfer has failed - Domain ID: ' . $vars['domainid'] . ' - Domain: ' . $vars['domain']); } });
  36. 3 points
    you could try the following hook, which redirects users who are not logged in from viewcart to checkout... <?php # ViewCart For Clients Only Hook # Written by brian! function viewcart_for_clients_only_hook($vars) { $client = Menu::context('client'); if (!$client && $vars['templatefile'] === 'viewcart' && $vars['checkout'] !== true) { header("Location: cart.php?a=checkout"); exit; } } add_hook("ClientAreaPageCart", 1, "viewcart_for_clients_only_hook"); logged in users, e.g clients, will still able to go to viewcart as normal.
  37. 3 points
    Let's stop trying, every solution is a bad hack that tampers with parameters. It gives at best a false sense of security that makes you more prone to errors when it fails. If it's not removed in the next version I will seriously consider moving away from the platform.
  38. 3 points
    Very sad day for hosting companies.. We trusted cPanel for years and now they didnt even think about us.. just a massive increase and survive if you could.
  39. 3 points
    it looks like the SQL queries needed tweaking - i'll attach the updated file rather than posting the entire code, but basically i've just changed the three references of... tblpaymentgateways.* to... tblpaymentgateways.value .. and it's still on my list of things to do to update this widget properly for v7.7+ 📅 admin.php
  40. 3 points
    there will be at least two short-term ways to do it... edit the code in the above template. edit scripts.min.js (where there URL is defined). method 2 implies that you should be able to do it via a hook (which would be a better long-term solution), but i've not been able to get it working yet... besides, now that v7.7.1 is released, I suspect there won't be any more updates, apart from hotfixes, until May 2019 and so no harm in editing the template or js files. so if you want to edit the template... {if $service.sslStatus} {if $service.sslStatus->getClass() eq "ssl-state ssl-inactive"}<a href="cart.php?gid=11">{/if}<img src="{$service.sslStatus->getImagePath()}" data-toggle="tooltip" title="{$service.sslStatus->getTooltipContent()}" />{if $service.sslStatus->getClass() eq "ssl-state ssl-inactive"}</a>{/if} {elseif !$service.isActive} <img src="{$BASE_PATH_IMG}/ssl/ssl-inactive-domain.png" data-toggle="tooltip" title="{lang key='sslState.sslInactiveService'}"> {/if} alternatively, in scripts.js (not used by WHMCS), you can change... jQuery(document).on('click', '.ssl-state.ssl-inactive', function(e) { e.preventDefault(); window.location.href = WHMCS.utils.getRouteUrl('/ssl-purchase'); }); to... jQuery(document).on('click', '.ssl-state.ssl-inactive', function(e) { e.preventDefault(); var gidvalue="11"; window.location.href = "cart.php?gid=" + gidvalue; }); minify/compress it and save it as /templates/six/js/scripts.min.js - or if you're familiar with the minified files, you could edit scripts.min.js directly... either method should work, there is no need to do both! it's probably easier to use the template edit, but I posted the js solution because it was the first one that I wrote for this and it seems a shame to let it go to waste if others want to use or improve upon it (e.g the basis of a hook).
  41. 3 points
    typical - i'm here for 50 weeks of the year, and I miss out on a freebie when i'm away. 🎄 that said, is it a sign of the times that my first thought was to wonder whether the pen was permanently on, or if the user has the option to turn it on and off. 😜
  42. 3 points
    do you think the timing of launching a beta testing period one week before Christmas might have had something to do with that? 🙄
  43. 3 points
    In 2016 I have questioned the WHMCS team about this function, I found the reply:
  44. 3 points
    Accept Order can be used when you accept an order - inside the hook, you could either run a SQL database update query or use the UpdateClient API to change the group value... you could also do a query to check if that client has unpaid/overdue invoices for your conditionality. InvoicePaid can be used after an invoice is marked as paid.
  45. 3 points
    Hello there, On V 7.6 we now have the notifications NEW string ready for translation. Before having this option available, we decided to replace the text NEW by the number of notifications, as we think this can easily attract the user attention. On this minimalistic version, if the user don't have any notification the div is not displayed, we only show what needs to be shown 😉 Feel free to use it. {if count($clientAlerts) > 0} <div class="notifications"> <li> <a href="#" data-toggle="popover" id="accountNotifications" data-placement="bottom"> {$LANG.notifications} <span class="label label-info">{count($clientAlerts)}</span> <b class="caret"></b> </a> <div id="accountNotificationsContent" class="hidden"> <ul class="client-alerts"> {foreach $clientAlerts as $alert} <li> <a href="{$alert->getLink()}"> <i class="fas fa-fw fa-{if $alert->getSeverity() == 'danger'}exclamation-circle{elseif $alert->getSeverity() == 'warning'}exclamation-triangle{elseif $alert->getSeverity() == 'info'}info-circle{else}check-circle{/if}"></i> <div class="message">{$alert->getMessage()}</div> </a> </li> {foreachelse} <li class="none"> {$LANG.notificationsnone} </li> {/foreach} </ul> </div> </li></div>{else}<br /><br />{/if} Best regards, David Duarte
  46. 3 points
    errr... really? did anyone genuinely ask for such a feature... ?? feel free to point to a feature request where this occurred and received an overwhelming number of votes. it's an admin lookup tool, not a sales tool... if I want suggestions, I can get them in the client area... and nice to see the usual same old WHMCS trick of sneaking a new feature in between RC and GA, without the slightest hint of a mention of it in any of the previous two v7.6 betas... I couldn't find any obvious admin method to disable the output - nothing in general settings... only option seems to be going to domain pricing and removing the alternate TLDs from Standard Whois or WHMCS Namespinning... which then removes them from the clientarea searches too... absolutely ridiculous, but sadly not surprising. in the end, I wrote an admin hook to hide the suggestions output from that whois page... needless to say, there are no unique IDs used in the HTML, so using css in a custom css file wasn't an option(!)... if anyone wants the hook, feel free to PM me - but i'm not posting any code in a temporary community like this one. btw - did you decide not to fix the obvious twitter fontawesome icon bug that's been in twitterfeed.tpl since the first v7.6 beta.. <i class="fas fa-twitter fa-2x"></i> with it being a brand icon, shouldn't it be... <i class="fab fa-twitter fa-2x"></i> even though I did mention it to a WHMCS staff member on June 29 when the first beta was released, I guess it's easily missed by WHMCS - it's only visible on the front page of the client homepage that every (if twitter account enabled) v7.6 end-user will now see when they upgrade. oh boy.
  47. 3 points
    It's funny how this is the main reason why several softwares (and videogames 😀) I loved evolved into a total mess. I'm a developer too but frankly I don't get this frenzy of adding untested stuff especially when the foundations of the house are buring. I mean when the software is new it's obvious that you have to add features non-stop but yeah, I agree with this point a lot. They should slow down. Quality > Quantity. I know that this may sound unpopular but I'm against it. Open source leads to hundreds of different variations of the same file. Multiply it for hundreds files during a time span of a couple of years and boom! You created Android 😀 the stupidest software ever created by human being. With such a fragmentated software it's impossible to deliver updates even for its publisher. Just look at Wordpress. It's full of "modifications" made by unknown people that expose your website to vulnerabilities. Of course this is just my rigid opinion about open source.
  48. 3 points
    @twhiting9275, And here I thought we where actually getting along, but nope, wasn't to last you're back to jumping to unfounded, incorrect conclusions based on a Marketing Email that has an Unsubscribe option. Firstly, we are not selling client/user emails. This webinar is organised by us and the email was sent by us, had you have even bothered to review the headers for the message you would have seen this. Of course, I appreciate you prefer to cry wolf and jump to conclusions, so lets include the headers below for you. Furthermore, the View in Browser Link goes to whmcs.com https://www.whmcs.com/members/mailings/?k=webinaroct17 and the register now hits go.whmcs.com which is controlled by us here at WHMCS. https://go.whmcs.com/1317/free-ssl-webinar-registration the email had a footer stating why you received it and an option to remove yourself from the mailing list. The email, Live Webinar: Profit by Selling SSL & TLS was sent to all active WHMCS License Holders it was a relevant promotional email targeted at providing users with an educational opportunity around WHMCS MarketConnect & SSL Certificates. When you sign up for a WHMCS License you also receive news and information about the product, newsletters and select promotional mailings. You may unsubscribe from any non-operational and security emails at any time. I would note we did exactly the same earlier this year with the Weebly Webinar. The MarketPlace Terms of Service & Privacy Policy both outline how we handle your data and cover the fact that we don't sell your data. Your accusations that we have or may sell this are not only unfounded, but also unfair to us and our clients who trust us with their private information. Moving on to your comments on our price changes. We made an adjustment on Support & Updates to reflect the value WHMCS is delivering along with the costs of providing 24x7 support and allowing us to provide on-going product enhancements, yes. Not everyone will like what we're doing but we're providing an off the shelf solution that needs to meet the requirements of a number of people. The changes to a tiered licensing structure are also part of this and allow us to provide a price point that works for various sized businesses, whilst reflecting the cost savings that automation offers these organisations. It's been an adjustment and it doesn't work for everyone but we're committed to improving the product and delivering quarterly updates. To finish Tom, let me point out as the WHMCS.Community Manager I appreciate your feedback, what I am not going to tolerate is the consistent negativity you bring, if you aren't able to be more balanced I'd recommend finding somewhere else to post.
  49. 3 points
    thank you all for the reception. Hello, my name is Jarlles, I have a host company in Brazil for 6 years. And I am here in this forum, to help also in developing the best system for host company: WHMCS. Thank you!
  50. 3 points
    ye of little faith - this is not the WHMCS Feature Requests Dept where you can wait for years and still not see any end result - I said that I was would try to take a look at it on Sunday and I did! so I am now in a position to answer your important questions on this... Q. Can it be done without access to core WHMCS files? A. Yes. Q. Is it perfect and bug-free? A. Not yet. take a look at the video below as to what it can do so far - probably better viewed full screen with captions on... so I won't embed the video here... https://youtu.be/wlGWi3clXcY first let me tell you about the good points before I move on to the current issues... I can create relationships between radio, checkboxes, text boxes and even sliders... I just need to figure out dropdowns and then that's the complete set! any radio or checkbox can manipulate any other (or multiple) radio/checkbox/text/sliders - certainly the radio/checkbox link that you originally asked about works, but I thought i'd take a look at the other options... working on the theory that someone will ask about them! all options auto-calculate the price correctly - you can't see it on the video when I move the sliders because I moved them back to the zero before the summary could update - what an idiot! - but they do work! so to the issues... 1. it doesn't currently work with "standard_cart" - I know why it doesn't, so i'm trying to figure out if there is a way to code around it or whether i'll need to write another version that works with standard_cart... you can't believe the time I wasted on Sunday looking at perfectly good code and wondering why it wasn't working! *sighs* it works with Modern (as shown in the video), probably most custom carts not based on SC and would even work on v5 I suspect - it can also be used on any WHMCS v6 page outside of the cart too... there's nothing really specific to WHMCS about the code, so it would work outside of WHMCS (though that bit I knew already). 2. changing the billingcycle loses the relationships - that's annoying... oh I hate jquery coding! 3. there's an issue with disabled sliders still passing on their values - though that should be easier to fix... disabled radio values aren't passed, but still a lot of test ordering to do before its finished. 4. there's also a problem with default radio values - but there's a simple solution to that though. the changes required so far are just a handful of edits to the configureproduct.tpl template and adding the js code... now that I understand the relationships, I can see that the .js code could be written as a hook and there might be a away to make an addon out of it (e.g some visual way for newbies to link the options)... though whether I would want to do that would depend on if I can iron out the wrinkles, or find a collaborator who's more knowledgeable at jquery... worst case, i'd write what I know as a tutorial and leave others to solve the issues! that will probably wait until v6.3 has had its full release - with WHMCS making changes to the orderforms (though nothing in the release notes yet), i'd be reluctant to release anything public until tested on v6.3 - i'm not going to get the chance to install the RC until at least next week, and I might leave it until the full release anyway. so, all being well, I'll try to work on this further on Sunday.
×
×
  • 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