Assets with 'dynamic' titles


#1

Hey,

I’m wanting to use Assets to track, well, our assets. But I’ll be
tracking hard drives and a few other components as well which don’t
have a specific name . Is it possible to have the subject dynamically
generated using a combination of Custom Fields and even potentially
relationships?

Ideally I’d have something like:

HDD $manufacturer $serial_number

Where $manufacturer $serial_number both come from Custom Fields.

Cheers,
Andrew

Andrew Ruthven, Wellington, New Zealand
andrew@etc.gen.nz | linux.conf.au 2017, Hobart, AU
New Zealand’s only Cloud: | The Future of Open Source
https://catalyst.net.nz/cloud | http://linux.conf.au


#2

Probably?

If you copy Asset.pm from its home to $RT4/local/lib/RT/Asset_Local.pm, you can modify the Create subroutine (and then probably delete all the routines that you don’t override). I’d aim for someplace around lines 222-231 (of the original file):

222 my $catalog = RT::Catalog->new( $self->CurrentUser );
223 $catalog->Load($args{‘Catalog’});
224
225 $args{‘Catalog’} = $catalog->id;
226
227 return (0, $self->loc(“Permission Denied”))
228 unless $catalog->CurrentUserHasRight(‘CreateAsset’);
229
230 return (0, $self->loc(‘Invalid Name (names may not be all digits)’))
231 unless $self->ValidateName( $args{‘Name’} );

If you create a Catalog for “Things that don’t have a specific name”, you can search for its $catalog->id, then generate the name for assets that are in that catalog. Something like:

227 return (0, $self->loc(“Permission Denied”))
228 unless $catalog->CurrentUserHasRight(‘CreateAsset’);
229
230 # This code snippet is not tested. Please hack at it in a test environment before relying on it.
231 # let’s make some assumptions
232 # - “Things that don’t have a specific name” is Catalog #2
233 # - Type of Thing (‘HDD’, for example) is Custom Field #12
234 # - Manufacturer is Custom Field #23
235 # - Serial Number is Custom Field #48
236 if ($catalog->id==2) {
237 $args{‘Name’} = $args{‘CustomField-12’} . ’ ’ . $args{‘CustomField-23’} . ’ '. $args{‘CustomField-48’};
238 }
239
240 return (0, $self->loc(‘Invalid Name (names may not be all digits)’))
241 unless $self->ValidateName( $args{‘Name’} );

(Offhand, I don’t know for certain that $catalog->id will be numeric, and not a string. You might need to use a string comparison in the if statement.)

Good luck,
Kyle
Kyle Dippery
Engineering Computing Services
219 RMB
859-257-1346From: rt-users rt-users-bounces@lists.bestpractical.com on behalf of Andrew Ruthven andrew@etc.gen.nz
Sent: Tuesday, February 21, 2017 3:03 PM
To: rt-users
Subject: [rt-users] Assets with ‘dynamic’ titles

Hey,

I’m wanting to use Assets to track, well, our assets. But I’ll be
tracking hard drives and a few other components as well which don’t
have a specific name . Is it possible to have the subject dynamically
generated using a combination of Custom Fields and even potentially
relationships?

Ideally I’d have something like:

HDD $manufacturer $serial_number

Where $manufacturer $serial_number both come from Custom Fields.

Cheers,
Andrew

Andrew Ruthven, Wellington, New Zealand
andrew@etc.gen.nz | linux.conf.au 2017, Hobart, AU
New Zealand’s only Cloud: | The Future of Open Source
https://catalyst.net.nz/cloud | http://linux.conf.au


#3

Thanks Kyle.

I’ve finally come back to look at this again now that I’m wanting to use Assets for real. The downside with over riding the Create method is that it’s a one-shot wonder. If the Custom Fields are updated later, you don’t get that change in the name.

What I’ve managed to get to work though, and I’m interested in comments, is to over ride the Name method on RT::Asset. Here’s a basic example:

{
    package RT::Asset;
    no warnings 'redefine';

    *Name = sub {
        my $self = shift;
        my $name = $self->_Value('Name', @_);

        if (! defined $name || $name eq '') {
            if ($self->CatalogObj->id == 2) {
                my $cf = $self->FirstCustomFieldValue(28);
                $name = "Card: $cf";
            }
        }

        return $name;
    };
}

Why do I need to use _Value? Name is created when the data is loaded from the DB, so I can’t just useHook::LexWrap or symbol table hacks as described here: https://rt-wiki.bestpractical.com/wiki/CustomizingWithOverlays to modify it at compile time.

Is this a sane way to do this? (Other than hard-coding the catalog and example name setting.) Is there a better way?

This works nicely for when displaying an asset, if you edit the asset and put in a name, then the new name is used and my modification is skipped. You can then delete the name you created and it goes back to being dynamic. Only issue I’ve noticed is that when you edit “Basics” then the dynamic name is inserted into the text edit box, so if you just hit save the dynamic name will be saved to the database and it is no longer dynamic.

Cheers,
Andrew


#4

No feed back for a couple of weeks…

I’ve extended my code so now you can have templates, and they’re per category.

Code is here: https://github.com/catalyst-cloud/rt-extension-assetautoname