diff --git a/html/AssetTracker/Asset/Clone.html b/html/AssetTracker/Asset/Clone.html new file mode 100644 index 000000000..2e8a12ae0 --- /dev/null +++ b/html/AssetTracker/Asset/Clone.html @@ -0,0 +1,70 @@ +<& /Elements/Header, + Title => $AssetObj->Name &> +<& /Elements/Tabs &> + +<& /Elements/ListActions, actions => \@Actions &> + +<& /Elements/TitleBoxStart, title => loc('New Asset'), color=> "#333399", contentbg => '#ffffff' &> +
+Cloned asset unique name: +
+(IP addresses and Links are not cloned.) + + +<& /Elements/Submit, Label => loc('Clone'), color => "#333399" &> +
+ +<& /Elements/TitleBoxEnd &> + +
+
+<& /Elements/TitleBoxStart, title => loc('Cloning Asset'), contentbg => '#bbbbbb' &> +<& /AssetTracker/Asset/Elements/ShowBasics, Asset => $AssetObj &> +<& /Elements/TitleBoxEnd &> + +<%ARGS> +$id => undef +$Create => undef +$AssetObj => undef +$Actions => undef +$Name => undef + + +<%INIT> + +$m->comp('/Elements/Callback', _CallbackName => 'Initial', AssetObj => $AssetObj, ARGSRef => \%ARGS); + +my ($linkid, $message, @Actions, $tid, $Assets); +push(@Actions, @$Actions) if $Actions; + +unless ($id || $AssetObj) { + Abort('No asset specified'); +} + +if (!$AssetObj) { + + $AssetObj = RTx::AssetTracker::Asset->new($session{'CurrentUser'}); + + $AssetObj = LoadAsset($ARGS{'id'}); + unless ($AssetObj->CurrentUserHasRight('ShowAsset')) { + Abort("No permission to view asset"); + } +} + +if ($ARGS{'new'} eq 'new') { + unless ($AssetObj->CurrentUserHasRight('CreateAsset')) { + Abort('You have no permission to create assets of that type.'); + } + my ($rv, $trans, $msg) = $AssetObj->Clone($Name); + if ($rv) { + $m->redirect("Display.html?id=$rv"); + } + else { + push (@Actions, $msg); + } +} + +$m->comp('/Elements/Callback', _CallbackName => 'BeforeDisplay', + AssetObj => \$AssetObj, Assets => \$Assets, ARGSRef => \%ARGS); + + diff --git a/html/AssetTracker/Asset/Create.html b/html/AssetTracker/Asset/Create.html index 64478d720..2a6bb206a 100644 --- a/html/AssetTracker/Asset/Create.html +++ b/html/AssetTracker/Asset/Create.html @@ -104,7 +104,6 @@ % $m->callback( CallbackName => 'AfterRoles', ARGSRef => \%ARGS ); <& /AssetTracker/Asset/Elements/EditCustomFields, %ARGS, TypeObj => $TypeObj, InTable => 1 &> -%# <& /AssetTracker/Asset/Elements/EditTransactionCustomFields, %ARGS, TypeObj => $TypeObj, InTable => 1 &> % $m->callback( CallbackName => 'AfterBasics', TypeObj => $TypeObj, ARGSRef => \%ARGS ); @@ -142,79 +141,6 @@ my %link_types = %{ RTx::AssetTracker::Asset::LINKTYPEMAP() }; my @link_order = RTx::AssetTracker::Asset::LINKORDER(); -if ($CloneAsset) { - my $CloneAssetObj = RTx::AssetTracker::Asset->new( $session{CurrentUser} ); - $CloneAssetObj->Load($CloneAsset) - or Abort( loc("Asset could not be loaded") ); - - my $clone = { }; - - foreach my $role ( $CloneAssetObj->TypeObj->RoleGroupTypes() ) { - my $role_method = $role . 'RoleGroup'; - $clone->{$role} = join( ',', $CloneAssetObj->$role_method->MemberEmailAddressesAsString ); - } - - $clone->{$_} = $CloneAssetObj->$_() - for qw/Name Description Status/; - - if (0) { # Temporarily disabled - my $members = $CloneAssetObj->Members; - my ( @members, @members_of, @refers, @refers_by, @depends, @depends_by ); - my $refers = $CloneAssetObj->RefersTo; - while ( my $refer = $refers->Next ) { - push @refers, $refer->LocalTarget; - } - $clone->{'new-RefersTo'} = join ' ', @refers; - - my $refers_by = $CloneAssetObj->ReferredToBy; - while ( my $refer_by = $refers_by->Next ) { - push @refers_by, $refer_by->LocalBase; - } - $clone->{'RefersTo-new'} = join ' ', @refers_by; - my $depends = $CloneAssetObj->DependsOn; - while ( my $depend = $depends->Next ) { - push @depends, $depend->LocalTarget; - } - $clone->{'new-DependsOn'} = join ' ', @depends; - - my $depends_by = $CloneAssetObj->DependedOnBy; - while ( my $depend_by = $depends_by->Next ) { - push @depends_by, $depend_by->LocalBase; - } - $clone->{'DependsOn-new'} = join ' ', @depends_by; - - while ( my $member = $members->Next ) { - push @members, $member->LocalBase; - } - $clone->{'MemberOf-new'} = join ' ', @members; - - my $members_of = $CloneAssetObj->MemberOf; - while ( my $member_of = $members_of->Next ) { - push @members_of, $member_of->LocalTarget; - } - $clone->{'new-MemberOf'} = join ' ', @members_of; - - } - - my $cfs = $CloneAssetObj->TypeObj->AssetCustomFields(); - while ( my $cf = $cfs->Next ) { - my $cf_id = $cf->id; - my $cf_values = $CloneAssetObj->CustomFieldValues( $cf->id ); - my @cf_values; - while ( my $cf_value = $cf_values->Next ) { - push @cf_values, $cf_value->Content; - } - $clone->{"Object-RTx::AssetTracker::Asset--CustomField-$cf_id-Value"} = join "\n", - @cf_values; - } - - $clone->{'ChangeComment'} = "Cloned from asset #$CloneAsset."; - - for ( keys %$clone ) { - $ARGS{$_} = $clone->{$_} if not defined $ARGS{$_}; - } -} - my @results; my $title = loc("Create a new asset"); @@ -256,5 +182,5 @@ <%ARGS> -$CloneAsset => undef + diff --git a/html/Callbacks/AssetTracker/Elements/Tabs/Privileged b/html/Callbacks/AssetTracker/Elements/Tabs/Privileged index 82480502d..84ae4c2de 100644 --- a/html/Callbacks/AssetTracker/Elements/Tabs/Privileged +++ b/html/Callbacks/AssetTracker/Elements/Tabs/Privileged @@ -67,6 +67,7 @@ if ( $request_path =~ m{^/AssetTracker/} ) { if ( $can->('ModifyAsset') ) { $tabs->child( fields => title => loc('Fields'), path => "/AssetTracker/Asset/ModifyFields.html?id=" . $id, ); $tabs->child( links => title => loc('Links'), path => "/AssetTracker/Asset/ModifyLinks.html?id=" . $id, ); + $tabs->child( clone => title => loc('Clone'), path => "/AssetTracker/Asset/Clone.html?id=" . $id, ); } #if ( $can->('ModifyAsset') || $can->('ModifyCustomField') || $can->('_ModifyOwner') ) { diff --git a/lib/RTx/AssetTracker/Asset.pm b/lib/RTx/AssetTracker/Asset.pm index 407f5cc93..7109d1c03 100644 --- a/lib/RTx/AssetTracker/Asset.pm +++ b/lib/RTx/AssetTracker/Asset.pm @@ -494,6 +494,36 @@ sub Create { } } +sub Clone { + + # still need to handle Links + my $self = shift; + my $name = shift or return ( 0, 0, "No name specified for cloned asset." ); + + # test name uniqueness + my ($rv, $msg) = $self->SatisfiesUniqueness($name, $self->TypeObj->Id, $self->Status); + return ($rv, 0, $msg) unless $rv; + + my @CustomFields; + my $cfs = $self->CustomFields; + while (my $cf = $cfs->Next) { + # may have to skip unique CFs some day + push @CustomFields, "CustomField-" . $cf->Id; + + my $cfvals = $self->CustomFieldValues($cf->Id); + push @CustomFields, [ map { $_->Content } @{$cfvals->ItemsArrayRef} ]; + } + + my $asset = RTx::AssetTracker::Asset->new($self->CurrentUser); + return $asset->Create( + Type => $self->TypeObj, + Name => $name, + Description => $self->Description, + Status => $self->Status, + TransactionData => "Cloned from " . $self->Name, + @CustomFields ); +} + sub _AddLinksOnCreateOrUpdate { my ($self, %args) = @_;