1 package SL::DB::Helper::RecordLink;
4 use parent qw(Exporter);
8 use SL::MoreCommon qw(listify);
10 use constant RECORD_ID => 'converted_from_record_id';
11 use constant RECORD_TYPE_REF => 'converted_from_record_type_ref';
12 use constant RECORD_ITEM_ID => 'converted_from_record_item_id';
13 use constant RECORD_ITEM_TYPE_REF => 'converted_from_record_item_type_ref';
15 our @EXPORT_OK = qw(RECORD_ID RECORD_TYPE_REF RECORD_ITEM_ID RECORD_ITEM_TYPE_REF set_record_link_conversions);
18 my ($self, $allowed_linked_records, $allowed_linked_record_items) = @_;
20 my %allowed_linked_records = map {$_ => 1} @$allowed_linked_records;
21 my %allowed_linked_record_items = map {$_ => 1} @$allowed_linked_record_items;
23 return 1 unless my $from_record_ids = $self->{RECORD_ID()};
24 my @from_record_ids = split / /, $from_record_ids;
26 my $from_record_type = $self->{RECORD_TYPE_REF()};
27 unless ($allowed_linked_records{$from_record_type}) {
28 croak("Not allowed @{[ RECORD_TYPE_REF ]}: $from_record_type");
31 for my $id (@from_record_ids) {
32 my $from_record = $from_record_type->new(id => $id)->load;
33 $from_record->link_to_record($self);
36 #clear converted_from;
37 delete $self->{$_} for RECORD_ID, RECORD_TYPE_REF;
39 for my $item (@{ $self->items_sorted }) {
40 link_record_item($self, $item, \%allowed_linked_record_items);
46 sub link_record_item {
47 my ($self, $record_item, $allowed_linked_record_items) = @_;
49 return 1 unless my $from_item_id = $record_item->{RECORD_ITEM_ID()};
51 my $from_item_type = $record_item->{RECORD_ITEM_TYPE_REF()};
52 unless ($allowed_linked_record_items->{$from_item_type}) {
53 croak("Not allowed @{[ RECORD_ITEM_TYPE_REF() ]}: $from_item_type");
56 $from_item_type->new(id => $from_item_id)->load
57 ->link_to_record($record_item);
59 #clear converted_from;
60 delete $record_item->{$_} for RECORD_ITEM_ID, RECORD_ITEM_TYPE_REF;
64 sub set_record_link_conversions {
65 my ($record, $from_type, $from_ids, $item_types, $item_ids) = @_;
67 return unless listify($from_ids);
69 $record->{ RECORD_TYPE_REF() } = $from_type;
70 $record->{ RECORD_ID() } = $from_ids;
73 my $items = $record->items_sorted;
76 croak "more item ids than items in record" if @$item_ids > @$items;
78 for my $idx (0..$#$item_ids) {
79 my $item = $items->[$idx];
81 $item->{ RECORD_ITEM_TYPE_REF() } = $item_types->[$idx];
82 $item->{ RECORD_ITEM_ID() } = $item_ids->[$idx];
95 SL::DB::Helper::RecordLink - creates record links that are stored in the gived objects
99 # in the consuming class
100 __PACKAGE__->after_save_hook("link_records_hook");
102 sub link_records_hook {
104 SL::DB::Helper::RecordLink::link_records(
106 [ qw(SL::DB::Order) ], # list of allowed record sources
107 [ qw(SL::DB::OrderItem) ], # list of allowed record item sources
111 # set conversion data in record
112 sub prepare_linked_records {
113 my @converted_from_ids = @{ $::form->{converted_from_oe_ids} };
114 my @converted_from_item_ids = @{ $::form->{converted_from_orderitem_ids} };
116 set_record_link_conversion(
117 $self->order, # the record to modify
118 'SL::DB::Order' => \@converted_from_ids, # singular or multiple source record ids
119 'SL::DB::OrderItem' => \@converted_from_item_ids # ids of items, each item will get one id
125 This module implements reusable after save hooks for dealing with record links for records created from other records.
127 It reacts to non-rose attributes set in the underlying hashes of the given record:
131 =item * C<converted_from_record_id>
133 =item * C<converted_from_record_type_ref>
135 =item * C<converted_from_record_item_id>
137 =item * C<converted_from_record_item_type_ref>
141 If a typeref is given that is not explicitely whitelisted, an error will be thrown.
143 The older C<converted_from_oe_ids> etc forms can be converted with TODO
149 =item * C<set_record_link_conversions> $record, $record_type => \@ids, $item_type => \@item_ids
151 Register the given ids in the object to be linked after saving.
153 Item ids will be assigned one by one to sorted_items.
155 This function can be exported on demand to the calling package.
157 =item * C<link_records> $record, \@allowed_record_types, \@allowed_item_types
159 Intended as a post-save hook.
160 Evaluates the stored ids from L </set_record_link_conversions>
161 and links the creating objects to the given one.
167 Aöll of these can be exported on demand if the calling code wants to set or read the markers in a record manually.
171 =item * C<RECORD_ID> = C<converted_from_record_id>
173 =item * C<RECORD_TYPE_REF> = C<converted_from_record_type_ref>
175 =item * C<RECORD_ITEM_ID> = C<converted_from_record_item_id>
177 =item * C<RECORD_ITEM_TYPE_REF> = C<converted_from_record_item_type_ref>
187 Sven Schöling $<lt>s.schoeling@googlemail.comE<gt>