Need to auto-generate uniqueness name

We need to auto-generate a name in a custom module we create, and have no clue on where to start :pleading_face:

The name of the module will represent a CODE:

2021.06.XXXXXXXX

where XXXXXXXX would be random chars, but must be unique (not already taken by another name)

We know how to auto-fill the name with a custom content (we are using a workflow), but have no idea on validate the uniqueness of it.

thank you in advance

1 Like

@fraxx

Maybe the formula for WorkFlow will have enough unique:
{now(Y.m.dHis)}

1 Like

Check this post:

1 Like

thank you so much, https://community.suitecrm.com/u/p.konetskiy, for giving us the great tip of using time: we are going this way.

Only one issue: we need milliseconds, too, to avoid having duplicates (this will sure happens if we generate those codes automatically), and I see i do not have access to milliseconds in workflow, so I guess I need the php solution cited by https://community.suitecrm.com/u/BrozTechnologies

Another tip: we need a final code of max 10 chars, so we will replace some numbers (for example: hours 0…23, with their ascii code, so to save 1 chars in total length)

We’ll give it a try and let you know

https://community.suitecrm.com/u/BrozTechnologies this is great, it works: not I add the milliseconds

(I wrote there a not, to fix a couple of parentesis)

with the code from https://community.suitecrm.com/u/BrozTechnologies we ended up generating a unique 10 chars long code with the followings

file custom/modules/bwadd_workcode/hooks/WorkCodeCreateNameHook.php

 <?php
/****************************************************
 * https://community.suitecrm.com/t/adding-autoincremental-number-date-unique-number-to-name/75561 *
 * LogicHook Sample created By BrozTechnologies     *
 * to demostrate a simple way to add YYYMMDDHHmmss  *
 * to record's names (or were ever it's needed)     *
 * 20201006 - www.broztechnologies.com              *
 */
//prevents directly accessing this file from a web browser
if (!defined('sugarEntry') ||!sugarEntry) die('Not A Valid Entry Point');

class WorkCodeCreateNameHook
{
        // function called in the before_save hook
    function customName($bean, $event, $arguments)
    {
                global $db; // These allows us access to the DB connection 

                if ($bean->id !=  $bean->fetched_row['id']) {  // Making sure it's called on creation only                      
                       
                        $d = new DateTime(); // this will return current date
                        //$mystring =  $d->format("Y-m-d H:i:s.v");
                        // https://www.php.net/manual/en/datetime.format.php
                        // https://www.man7.org/linux/man-pages/man7/ascii.7.html
                        // YEAR
                        $YY = $d->format("y"); // 21 or 99 or 03 ... 
                        // MONTH
                        $MM = intval($d->format("n")); // n: 1 through 12  
                        if ($MM < 10) { $ascii_MM = strval($MM); }
                        else          { $ascii_MM = chr($MM + 55); } // 1..9,A,B,C  since chr(65=55+10)=>"A" chr(67=55+12)=>"C"
                        // DAY
                        $DD = intval($d->format("j")); // j: 1 to 31
                        if ($DD < 10) { $ascii_DD = strval($DD); }
                        else          { $ascii_DD = chr($DD + 55); } // 1..9,A...V chr(86=55+31)=>"V"
                        // HOUR
                        $HH = intval(strval(intval($d->format("H"))+1)); // H: 00 through 23, so here we have 1..24,  chr(79=55+24)=>"O"
                        if ($HH < 10) { $ascii_HH = strval($HH); }
                        else          { $ascii_HH = chr($HH + 55); } // 1..9,A...O
                        // MINUTE
                        $mm = $d->format("i"); // i: 00 to 59
                        // SECOND
                        $ss = $d->format("s"); // s: 00 through 59
                        // MILLISECOND
                        $N  = $d->format("v")[0]; // first digit of milliseconds
                        // $code = $d->format("y").$ascii_MM.$ascii_DD.$ascii_HH.$d->format("i").".".$d->format("s").$first_digit_of_milliseconds;
                        $code = $YY.$ascii_MM.$ascii_DD.$ascii_HH.$mm.$ss.$N;
                        # replacements
                        $code = str_replace("I","X",$code);
                        $code = str_replace("O","Y",$code);
                        $bean->name = $code;
                }
        }
}

and custom/modules/bwadd_workcode/logic_hooks.php

<?php
// Do not store anything in this file that is not part of the array or the hook version.  This file will        
// be automatically rebuilt in the future. 
$hook_version = 1;
$hook_array = Array();
// position, file, function 
$hook_array['before_save'] = Array();
$hook_array['before_save'][] = Array(1, 'customName', 'custom/modules/bwadd_workcode/hooks/WorkCodeCreateNameHook.php','WorkCodeCreateNameHook', 'customName');

?>

As you can see we replace the letter “I” and “O” (they can be mixed up with “1” and “0”, aka zero)

Ok, so problem solved, but we found out the so called “Global Counters” https://docs.suitecrm.com/user/advanced-modules/workflow-calculated-fields/#_globalcounterpermodule which we missed completely.

We are thinking that this way could solve our issue much easier, and will try to implement it: do you see any issue which this?

mmmh, se see that GlobalCounter are not written in DN but in config_override.php

$sugar_config['SweeterCalc']['GlobalCounter']['MyName'] = 1;

which is something we would not expect, but the negative point is that we cannot use Parameter on the name of the counter, so we cannot automatically reset the counter at the beginning of the year: anyhow we can do it by hand.

@fraxx
I think I got the best and automated solution for you.

Check out the: SuiteCRM Unique ID Generator Plugin

There is a :free:3-days free of cost try as well, so it won’t hurt to just try.

1 Like

ok, we can try it out, but how does the code arrive to us? since is PHP I imagine we can read the source code, how then do you assure people will not use your plugin if they do not purchase it?

I ask you this since, due to the extreme privacy of the content of our CRM, we have to be very careful with any code we add: so we are sure unable to add obscured/compiled code of any sort: we may miss how plugins are distributed, but to us this is a pretty big drawback that limit the purchase of plugins

You can use standard PHP function - microtime in logichook.