November 10, 2014
Preface: this post is part of the SFDC99 Challenges series.
For this challenge, you need to write all the code from scratch!
Your mission, should you choose to accept it…
- Write a trigger that will prevent each user from creating more than 99 cases a month!
- The maximum number of cases per user should be configurable without code. Each user will have the same maximum.
- Users should see the following error message if they break their max:
Too many cases created this month for user <<Name>> (<<User ID>>): <<Maximum>>
- Don’t forget your test class!

Post your code in the comments if you’re feeling brave!
trigger testcase on Case (before insert, before update) {
set ownerIDs = new set();
for(case cs : Trigger.new){
ownerIDs.add(cs.OwnerId);
}
Map ownerCount = new Map();
for(aggregateResult agg : [Select count(ID), OwnerID from case where ownerID in : ownerIDs and createddate = THIS_MONTH group by OwnerID ] ){
ownerCount.put(string.valueOF(agg.get(‘OwnerID’)),integer.valueOF( agg.get(‘expr0’)) );
}
for(case cs : Trigger.new){
if( ownerCount.get(cs.OwnerID) > 2){ // use cousome metadata to set the value either 90 or anything.
cs.addError(‘ this owner have more than 2 cases’);
}
}
}
// Assuming on case owners not on createdby or loggedin user because
// in bulk load case owner could be different not the logged in user
// more than 99 cases shud not be assigned to 1 owner/user
trigger restrictMaxCasesOnUser on Case (before insert) {
//List
// get map1(ownerid,countof new cases)
// aggre on existing cases by ownerid where above map.keyset
// in case of new owner then u have to consider in the scenario
Map newCaseMap = new Map();
public static final Integer MAX_CASE = 99;
Integer count=0;
Integer existingCount;
for(Case c: Trigger.new){
if(newCaseMap.containsKey(c.ownerId)){
existingCount = newCaseMap.get(c.OwnerId);
newCaseMap.put(c.ownerId,existingCount);
}else{
newCaseMap.put(c.ownerId,count++);
}
if(newCaseMap.get(c.ownerId) > 99){
// in bulk load if more than 99 cases assigned to 1 owner
c.addError(‘You have exceeded limit of creating case or owning case’);
}
}
Map aggCaseResults = new Map([select ownerId,count(Id)
from Case where ownerId IN : newCaseMap.keySet() group by ownerId]);
//ID ownerId;
Map userMap = new Map([select id,Name from User where Id in :newCaseMap.keySet()]);
for(Case c: Trigger.new){
Object existingCountOfOwner = aggCaseResults.get(c.ownerId);
Integer exisCount = (Integer)existingCountOfOwner;
if((newCaseMap.get(c.ownerId) + exisCount) > MAX_CASE){
//c.addError(‘Too many cases created/owned by user ‘+UserInfo.getFirstName());
c.addError(‘Too many cases created/owned by user ‘+userMap.get(c.ownerId).Name);
}
}
}
public static void checkMaxNoOfCase(List lstCase){
Integer maxCase = Integer.valueOf(Label.Max_No_of_Case);
String userId = UserInfo.getUserId();
Integer count = Database.countQuery(‘SELECT count() FROM Case WHERE CreatedDate=THIS_MONTH AND CreatedById=:userId’);
System.debug(‘maxCase:-‘+maxCase+’ — count:-‘+count);
if(lstCase.size() + count > maxCase){
lstCase[0].addError(‘Max’);
}
}
//Limit each user to create 99 cases per month
trigger 99CaseLimit on Case (before Insert) {
//Custom setting config for case max limit
CaseLimt__c customSetting = new CaseLimit__c();
Integer configCaseMaxCount = customSetting.confiLimit__c;
//copying all the case owners to set
Set caseOwnerIds = new Set();
for (Case cr : Trigger.New ) {
caseOwnerIds.add(cr.OwnerIds);
}
//get the current month count for all the case owners
List caseCountList = new List(select OwnerId, owner.name,count(Id) from case where createddate = THIS_MONTH group by OwnerId ) ;
//add details to map for index based search
Map caseMap = new Map();
for (Case cRecord : caseCountList) {
caseMap.put(cRecord.ownerId , cRecord.count(Id) );
}
//actual logic
for ( Case insertedRec : Trigger.New) {
Case caseMapRec = caseMap.get(insertedRec.ownerId);
if (caseMapRec.count(Id) >= configCaseMaxCount ) {
//throw an error message
String errMsg = ‘Too many cases created this month for user ‘+caseMapRec.owner.name + ‘ (‘ + caseMapRec.ownerId + ‘): ‘ + configCaseMaxCount ;
casecount.addError(errMsg);
}
}
}
@DavidLiu
trigger CaseCreationLimit on Case (before insert){
//Fetch and store case creation limit via custom setting
User_DML_Limits__c CustomUserSettings = User_DML_Limits__c.getValues(‘Case’);
Integer intLimit = CustomUserSettings.Monthly_Create_Limit__c; //default value is 99
//Initialize a map of users who have already reached the case creation limit for fast lookup
Map userLimitMap = new Map([SELECT CreatedById Id,
Count(id) monthCount, CreatedBy.Name uName
FROM Case
WHERE CreatedDate = THIS_MONTH
GROUP BY CreatedById, CreatedBy.Name
HAVING Count(Id) > :intLimit]);
if(userLimitMap.size() > 0){
for(case newCase : Trigger.new){
if(userLimitMap.containsKey(newCase.CreatedById)){
String ErrorMsg = ‘Too many cases created this month for user ‘ +
userLimitMap.get(newCase.CreatedById).get(‘uName’) +
‘(‘ + newCase.CreatedById + ‘): ‘ + intLimit;
newCase.addError(ErrorMsg);
}
}
}
}
*EDIT*
//correct map syntax
Map userLimitMap = new Map :intLimit]);
nvm, formatting stripped characters away from code. Anyways, here’s what the SOQL query would look like in the initialized map:
SELECT CreatedById Id, count(id) monthCount, CreatedBy.Name uName
FROM Case
WHERE CreatedDate = THIS_MONTH
GROUP BY CreatedById, CreatedBy.Name
HAVING Count(Id) \> :intLimit
//Trigger fires whenever a new case is created and whenever the case owner is changed.
trigger CaseTrigger on Case (before insert, before update) {
Decimal maxCases =
Case_Settings__c.getValues(‘Default’).Maximum_Cases_per_User__c;
Set userIds = new Set();
for(Case c: trigger.new){
userIds.add(c.OwnerId);
}
Map<Id, List> userCases = new Map<Id, List>();
for(Case c2: [Select Id, OwnerId From Case Where OwnerId IN
:userIds AND CreatedDate = THIS_MONTH
AND CreatedDate = THIS_YEAR]){
if(!userCases.containsKey(c2.OwnerId)){
userCases.put(c2.OwnerId, new List{c2});
}else{
userCases.get(c2.OwnerId).add(c2);
}
}
for(Case c3: trigger.New){
System.debug(userCases.get(c3.OwnerId).size());
if(userCases.get(c3.OwnerId).size() > maxCases){
c3.addError(‘Too many cases created this month for user ‘ + UserInfo.getName() + ‘(‘ + UserInfo.getUserId() +’): maximum Cases allowed per user are: ‘ +maxCases);
}
}
}
trigger maxcases on Case (before insert) {
integer casecount = [select count() from case where ownerid = :userinfo.getuserId() and CreatedDate >= :(date.today()- 30 )];
casecount = casecount +1;
for(case c: trigger.new){
if(casecount> 99)
c.addError(‘Too many cases created this month for user ‘+UserInfo.getName()+'(‘+userinfo.getuserId()+’):99′);
}
trigger maxcases on Case (before insert)
{
list cList;
for(case cnew:trigger.new)
{
clist = [select id,ownerid from case where ownerid=:cnew.OwnerId];
for(case c:clist)
{
if(clist.size()>99)
{
user username = [select name from user where id=:c.ownerid][0];
cnew.adderror(‘ Too many cases created this month for user <> (<>): <>’);
}
}
}
}
testclass(coverage:100%)
@istest
public class maxcasestest
{
static testmethod void dotest()
{
list li = new list();
for(integer i= 0;i<100;i++)
{
case ca = new case();
ca.Subject = 'Subject'+i;
ca.Status = 'New';
ca.Origin = 'Web';
li.add(ca);
}
insert li;
test.startTest();
case ca = new case();
ca.Subject = 'Subject';
ca.Status = 'New';
ca.Origin = 'Web';
insert ca;
test.stopTest();
}
}
trigger CaseLimit on Case (before insert) {
Integer Total_cases=[select count() from case where createddate= This_Month];
for(Case cs: Trigger.new)
{
if(Total_cases>=99)
{
cs.addError(‘Too many cases has created this Month for User ‘+ userInfo.getName( )+’ ‘ + ‘(‘ + userInfo.getUserId() +’)’ +’:99′);
}
}
}
trigger CaseCreationLimit on Case (before insert) {
if(Trigger.isInsert) {
Transient Date selectedDate = Date.today() -12; //Give your date
Transient Date firstDate = selectedDate.toStartOfMonth();
Transient Date lastDate = firstDate.addDays(date.daysInMonth(selectedDate.year() , selectedDate.month()) – 1);
system.debug(firstDate + ‘ **** ‘ +lastDate );
Integer caseCurrentCount = 0;
Integer caseCount = [SELECT count() FROM Case where CreatedById =: UserInfo.getUserId()
AND CreatedDate >=:firstDate AND CreatedDate = 0 && caseCount = 99) {
cse.addError(‘Too many cases created this month for user : ‘+UserInfo.getUserName() +’ : 99 ‘);
}
else {
caseCurrentCount++;
}
}
}
}
trigger CaseCreationLimit on Case (before insert) {
if(Trigger.isInsert) {
Transient Date selectedDate = Date.today() -12; //Give your date
Transient Date firstDate = selectedDate.toStartOfMonth();
Transient Date lastDate = firstDate.addDays(date.daysInMonth(selectedDate.year() , selectedDate.month()) – 1);
system.debug(firstDate + ‘ **** ‘ +lastDate );
Integer caseCurrentCount = 0;
Integer caseCount = [SELECT count() FROM Case where CreatedById =: UserInfo.getUserId()
AND CreatedDate >=:firstDate AND CreatedDate = 0 && caseCount = 99) {
cse.addError(‘Too many cases created this month for user : ‘+UserInfo.getUserName() +’ : 99 ‘);
}
else {
caseCurrentCount++;
}
}
}
}
trigger CaseCreationLimit on Case (before insert) {
Integer caseCount=0; //Integer value can pass using Custom Settings
List caseResults = [SELECT Id, Status, OwnerId,CreatedById FROM Case WHERE CreatedDate = THIS_MONTH AND CreatedById =: Userinfo.getUserId()];
for(Case existingCase : caseResults)
{
caseCount++;
}
for (Case newCase : Trigger.new) {
if (caseCount <= 99) {
newCase.Subject = 'My New Case -'+caseCount+'';
newCase.ownerId = Userinfo.getUserId();
}
else {
caseCount–;
newCase.addError('Too many cases created this month for user '+Userinfo.getName()+' ('+Userinfo.getUserId()+'): '+caseCount+'');
}
}
}
@David Liu
trigger noMoreCases on Case (before insert) {
No_More_Cases__c settings = No_More_Cases__c.getInstance(‘caseLimit’);
Decimal max_cases = settings.Maximum_Cases__c;
Set ownerIds = new Set();
for (Case c : Trigger.new) {
ownerIds.add(c.OwnerId);
System.debug(c.OwnerId);
}
System.debug(‘Hello World’);
List usrCases = [SELECT OwnerId, COUNT(Id)ids FROM Case WHERE OwnerId IN :ownerIds
GROUP BY ownerId];
Map numCasesUser = new Map();
for (AggregateResult ar : usrCases) {
System.debug(‘OwnerID ‘ + ar.get(‘OwnerId’));
System.debug(‘Number ‘ + ar.get(‘ids’));
numCasesUser.put((Id) ar.get(‘OwnerId’), (Integer) ar.get(‘ids’));
}
for (Case c : Trigger.new) {
if (numCasesUser.get(UserInfo.getUserId()) > max_cases) {
c.addError(‘Monthly Case Limit has been exceeded ‘ + UserInfo.getUserName() + ‘ has total : ‘ + numCasesUser.get(UserInfo.getUserId()));
}
}
}
trigger MaxCases on Case (before insert) {
Integer maxCases = null;
CaseSettings__c settings = CaseSettings__c.getValues(‘default’);
if (settings != null) {
maxCases = Integer.valueOf(settings.MaxCases__c);
}
Map caseCountMap = new Map([select count(Id), OwnerId Id, Owner.Name from Case where CreatedDate = THIS_MONTH group by OwnerId,Owner.Name having count(id) >: maxCases]);
//{00Gg0000001aNhLEAU=AggregateResult:{expr0=7, Id=00Gg0000001aNhLEAU, Name=Test}}
for (Case c: trigger.new) {
AggregateResult ar = caseCountMap.get(c.OwnerId);
if (ar != null) {
c.addError(‘Too many cases created this month for user ‘ + ar.get(‘Name’) + ‘(‘ + c.OwnerId + ‘): ‘ + maxCases);
}
}
}
trigger user on Candidate_Information__c (before Insert) {
User u = [select firstname,name from user where id=:userinfo.getuserid()];
string username = u.firstname;
public list x = [Select id,CreatedBy.Name,createdDate from Candidate_Information__c];
public list sam = new list();
Date today = system.Today();
integer month = today.month();
for(Candidate_Information__c crt : x){
if(crt.CreatedBy.Name == u.Name && crt.createdDate.month() == month){
sam.add(crt);
}
}
system.debug(‘size of created users this month’+sam.size());
if(trigger.isBefore){
if(trigger.isInsert){
list candinsert = new list();
for(Candidate_Information__c s : Trigger.New){
system.debug(‘size of the query’+sam.size());
if(sam.size()<= 20){
candinsert.add(s);
}else{s.addError('You have inserted more records this month');}
}
/* if(candinsert != null)
insert candi */
}
}
Correct me if something is wrong with the code , the only question here is will this code work if bulk records are inserted , would like to know if for every iteratio of trigger.New , will the query size gets updated
pcon code is superb
trigger MonthlyCases on Case (before insert) {
//Get the instance of custom setting Max Record
Max_Record__c MR = Max_Record__c.getInstance(‘CSR’);
// Get the value of maximum cases allowed per month
decimal max = MR.max_value__c;
system.debug(‘maximum cases ‘ + max);
// get current month
date td = system.today();
integer month = td.month();
system.debug(‘current month ‘+month);
// get the count of cases created by user for current month
decimal cl = [select count() from case where createdByID =:userinfo.getuserid() and CALENDAR_MONTH(CreatedDate) = :month];
system.debug(‘no of cases created by current user for current month : ‘+cl);
for(case c : trigger.new){
if(cl > max )
{
c.addError(‘Too many cases created for user ‘+userinfo.getFirstname());
}
else{
system.debug(‘case inserted succesfully’);
}
}
}
Hi David,
Will you please rate this trigger?
Two things I would point out is that your trigger does not take into account. One, you are assuming that the creator is the same as the owner which is not always true. Two, if you bulk add cases with different owners. If you add two cases with different owners and one owner has met the limit and the other has not then this will behave weirdly. Also, the cases are being inserted by a 3rd party (an API user for example) the API user may not be the owner of the case but they will be the creator.
Hello,
Below is my Code for this. It seems to be working fine, but not sure if this was what was required. If possible, someone please have a look and let me know. Thanks!!
trigger limitCases on Case (before insert) {
Max_Cases__c caseSettings = Max_Cases__c.getInstance(‘Max Cases’);
Decimal maxNoOfCases = caseSettings.Max_no_of_cases__c;
for (Case caseInTrigger : Trigger.new) {
Date today = Date.today();
Decimal noOfCases = [SELECT count() FROM Case WHERE CreatedById = :UserInfo.getUserId()
AND CreatedDate >= :today.toStartofMonth()
AND CreatedDate maxNoOfCases) {
caseInTrigger.addError(‘Too many cases created this month for user ‘+ UserInfo.getName() +
‘ (‘ + UserInfo.getUserId() + ‘): ‘ + maxNoOfCases);
}
}
}
While this will work, you might want to look at making it bulk ready. You are doing a query for each case being inserted which can quickly exhaust your SOQL limits. To make this bulk ready you’ll want move your SOQL query out of your for loop.
Yes..Thanks for the input…I had actually realized that later, but didnt update it here in the comments, so this is my final code (and yes…this works too :) ):
trigger limitCases on Case (before insert) {
Max_Cases__c caseSettings = Max_Cases__c.getInstance(‘Max Cases’);
Decimal maxNoOfCases = caseSettings.Max_no_of_cases__c;
Date today = Date.today();
Decimal noOfCases = [SELECT count() FROM Case WHERE CreatedById = :UserInfo.getUserId()
AND CreatedDate >= :today.toStartofMonth()
AND CreatedDate maxNoOfCases) {
caseInTrigger.addError(‘Too many cases created this month for user ‘+ UserInfo.getName() +
‘ (‘ + UserInfo.getUserId() + ‘): ‘ + maxNoOfCases);
}
}
}
trigger CaseLimit on Case (before insert) {
List u = new List();
List cas = new List();
Set ids = new Set();
Map usertoCase = new Map();
datetime myDateTime = datetime.now();
Integer month = myDateTime.month();
for(Case c: Trigger.new){
ids.add(c.CreatedById);
}
u=[select Id,name from User where Id in :ids];
for(User uvar: u){
usertoCase.put(uvar.id,[select COUNT() from case where CreatedById =:uvar.id and CALENDAR_MONTH(CreatedDate) = :month]);
}
for(Case c: Trigger.new){
if(usertoCase.containsKey(c.CreatedById)){
Integer numofCases = usertoCase.get(c.CreatedById);
if(numofCases > 99)
c.addError(‘Too many cases created this month for user’+ c.createdBy +c.createdByid +’:99′);
}
}
}
Hi David,
After reading all chapters, now I realized y everyone is fan of urs and even I am also included in the same club.
Just request to u and if any other person like to help me on this.
I have mentioned the code i wrote and please let me know the feedback and improvement on my code.
Thanks a lot for your help David .
I finally made this work after 1 whole day of digging out new things and experimenting with them. This is the most advanced code I have written so far and I am so proud of myself today =). Thanks yet again David, for putting up this brain teaser exercise! My code:
https://gist.github.com/anonymous/3c85a87dddf1fa89f7f7
And here’s my test class:
https://gist.github.com/miragedeb/c758bce9f4200519dd33
And here’s my test class (100% coverage yay!):
https://gist.github.com/miragedeb/c758bce9f4200519dd33
Hi David,
I got solution for this.
trigger caselimit on Case (before insert) {
if(trigger.isInsert)
{
List casecount=new List();
for(Case c:trigger.new)
{
User u=[select id from User where Id = : UserInfo.getUserId()];
Date d = system.today().addDays(-30);
casecount=[select id from case where CreatedByid=:u.id and CreatedDate > :d ];
if(casecount.size()>99)
{
c.adderror(‘Too many cases created this month for user’+ userinfo.getName() + ‘(‘+ userinfo.getuserid() +’)’ + ‘: ‘+ ‘ 99’ );
}
}
}
}
Testclass for the above trigger:
@istest
public class test_limitcase {
static Testmethod void testcase()
{
try{
User u=new user();
u.firstname=’Ms’;
u.LastName=’Dhoni’;
u.Email=’ms@jnj.com’;
u.username=’msd@cric.com’;
u.ProfileId=’00e90000001xLRS’;
u.alias = ‘standt’;
u.emailencodingkey=’UTF-8′;
u.languagelocalekey=’en_US’;
u.localesidkey=’en_US’;
u.timezonesidkey=’America/Los_Angeles’;
insert u;
case firstcase=new case(status=’new’,Origin=’web’);
insert firstcase;
date d=system.today().adddays(-30);
List lic=[select id from case where createdbyid=:’u.id’ and createddate>:d];
integer i;
for( i=0;i<99;i++)
{
case seccase =new case(subject='log+i',status='closed',origin='phone');
insert seccase;
}
}
catch(exception e)
{}
}
}
@David
Hie there… every time i go to sdfc99 i feel like oh ! wat a life saver .
I have some doubt abt the test class for this
@isTest
private class caseLimit{
static testMethod void TestcaseLimit()
{
case_settings__c settings= new case_settings__c();
settings.Name=’max’;
settings.Max_Number__c=99;
insert settings;
list addcase = new list();
for(Integer i = 0; i < 110; i++){
Case a = new Case(Origin='Phone',Status='New',Ownerid =' YOUR OWNERD ID HERE',CreatedDate= System.Today());
addcase.add(a);
}
test.startTest();
try{
insert addcase;
}
catch(Exception e)
{
System.debug('An error happened, as predicted!');
}
test.stopTest();
}
}
i get error created date is not writable
Error: Compile Error: Field is not writeable: Case.CreatedDate at line 13 column 95
any work around
Chitral,
You cannot set the CreatedDate. It will default to Today anyway when you insert it.
Thanks dear,
But then again how do i check it in test class that in one month there shud be no more than 99 records creation
would this work
i read ur code below, awesome work …fr dat same code u wrote, have built this test class but i dnt know how to check for month part
any update?
You can do this by using Test.loadData [1] but that would get out of date pretty fast once you get past the current month. The other option is to just create n number of cases. So for the use case of no more than 99 records, just create 99 in your setup of your test (insert them as a list to avoid DML problems) and the inside your Test.startTest/stopTest insert test case 100.
[1] https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_load_data.htm
// its working perfectly
trigger CasesLimit on Case (before insert) {
List lstUser;
List lstCase;
integer limit1 = 99;
for(Case c : Trigger.new){
lstUser = [select id, name from user ];
System.debug(‘—lstUser —‘+lstUser);
System.debug(‘—Case Owner Name—‘+C.owner.FirstName);
System.debug(‘—Case Owner ID—‘+C.ownerID);
User us = [select id, name from user where id =: C.ownerID];
System.debug(‘—User us—‘+us);
lstCase = [select id, caseNumber, CreatedDate, tryme__Max_Case_Month__c from case where ownerID =: C.ownerID AND CALENDAR_MONTH(CreatedDate) = : system.today().month()];
System.debug(‘-lstCase User –‘+us.name+’ ‘+’Case Size–‘+lstcase.size());
System.debug(‘–All lstCase–‘+lstCase);
if(lstCase.size()<99){
//insert c;
}
else{
c.addError('Too many cases created this month for user '+us.name+' ('+C.ownerID +') '+'Case Limit '+limit1);
}
}
}
This solution might work perfectly for a few records but is not bulkified, would hit SOQL limit for many because of query in a FOR loop
Put down my thinking this way for my 1st trigger, am i meeting the requirement ?
trigger restrictCases on Case (before insert) {
integer i=[select count() from case
where CALENDAR_MONTH(CreatedDate)=:Date.today().month()];
if(Trigger.isInsert){
for(Case c:trigger.new){
if(i==99){
c.addError(‘Too many cases created this month for user ‘+
UserInfo.getName()+’ ( ‘+(UserInfo.getUserId())+’ ) ‘+’ : ‘+ i);
}
}
}
}
modifying the query,
integer i=[select count() from case
where CALENDAR_MONTH(CreatedDate)=:Date.today().month()
and ownerid=:UserInfo.getUserId()];
To complete this, I created a List custom setting called CaseSettings__c with a Number field named MaxCases__c. If the setting ‘default’ exists then the number entered will be the max number of cases any given User can create. Otherwise, they can create as many as they want.
trigger MaxCases on Case (before insert) {
Integer maxCases = null;
CaseSettings__c settings = CaseSettings__c.getValues('default');
if (settings != null) {
maxCases = Integer.valueOf(settings.MaxCases__c);
}
if (maxCases != null) {
Set userIds = new Set();
Map caseCountMap = new Map();
for (Case c: trigger.new) {
userIds.add(c.OwnerId);
caseCountMap.put(c.OwnerId, 0);
}
Map userMap = new Map([
select Name
from User
where Id in :userIds
]);
for (AggregateResult result: [
select count(Id),
OwnerId
from Case
where CreatedDate = THIS_MONTH and
OwnerId in :userIds
group by OwnerId
]) {
caseCountMap.put((Id) result.get('OwnerId'), (Integer) result.get('expr0'));
}
for (Case c: trigger.new) {
caseCountMap.put(c.OwnerId, caseCountMap.get(c.OwnerId) + 1);
if (caseCountMap.get(c.OwnerId) > maxCases) {
c.addError('Too many cases created this month for user ' + userMap.get(c.OwnerId).Name + '(' + c.OwnerId + '): ' + maxCases);
}
}
}
}
Gist version of code https://gist.github.com/pcon/8afe91eee8fde2d0fd15
PCON you ain’t playing around, LOL!! NICE!
Very impressive! Short and efficient!
pcon :D :D Mocking kids here