4 use base 'OpenSRF::Application';
6 use OpenSRF::Utils::Logger;
7 my $log = 'OpenSRF::Utils::Logger';
9 use OpenILS::Application::Storage::CDBI;
10 use OpenILS::Application::Storage::CDBI::actor;
11 use OpenILS::Application::Storage::CDBI::action;
12 use OpenILS::Application::Storage::CDBI::asset;
13 use OpenILS::Application::Storage::CDBI::biblio;
14 use OpenILS::Application::Storage::CDBI::config;
15 use OpenILS::Application::Storage::CDBI::metabib;
16 use OpenILS::Application::Storage::CDBI::money;
17 use OpenILS::Application::Storage::CDBI::container;
18 use OpenILS::Application::Storage::CDBI::config;
20 use vars qw/$fieldmap $VERSION/;
24 sub publish_fieldmapper {
25 my ($self,$client,$class) = @_;
27 return $fieldmap unless (defined $class);
28 return undef unless (exists($$fieldmap{$class}));
29 return {$class => $$fieldmap{$class}};
31 __PACKAGE__->register_method(
32 api_name => 'opensrf.open-ils.system.fieldmapper',
34 method => 'publish_fieldmapper',
38 # To dump the Javascript version of the fieldmapper struct use the command:
40 # PERL5LIB=~/cvs/ILS/OpenSRF/src/perlmods/:~/cvs/ILS/Open-ILS/src/perlmods/ GEN_JS=1 perl -MOpenILS::Utils::Fieldmapper -e 'print "\n";'
42 # ... adjusted for your CVS sandbox, of course.
46 return () unless (defined $fieldmap);
47 return keys %$fieldmap;
51 return if (keys %$fieldmap);
55 'Fieldmapper::container::user_bucket' => { hint => 'cub',
56 proto_fields => { items => 1 } },
57 'Fieldmapper::container::copy_bucket' => { hint => 'ccb',
58 proto_fields => { items => 1 } },
59 'Fieldmapper::container::call_number_bucket' => { hint => 'ccnb',
60 proto_fields => { items => 1 } },
61 'Fieldmapper::container::biblio_record_entry_bucket' => { hint => 'cbreb',
62 proto_fields => { items => 1 } },
64 'Fieldmapper::container::user_bucket_item' => { hint => 'cubi' },
65 'Fieldmapper::container::copy_bucket_item' => { hint => 'ccbi' },
66 'Fieldmapper::container::call_number_bucket_item' => { hint => 'ccnbi' },
67 'Fieldmapper::container::biblio_record_entry_bucket_item' => { hint => 'cbrebi' },
69 'Fieldmapper::action::in_house_use' => { hint => 'aihu' },
70 'Fieldmapper::action::non_cataloged_circulation'=> { hint => 'ancc' },
72 'Fieldmapper::action::survey' => { hint => 'asv',
73 proto_fields => { questions => 1,
75 'Fieldmapper::action::survey_question' => { hint => 'asvq',
76 proto_fields => { answers => 1,
78 'Fieldmapper::action::survey_answer' => { hint => 'asva',
79 proto_fields => { responses => 1 } },
80 'Fieldmapper::action::survey_response' => { hint => 'asvr' },
81 'Fieldmapper::action::circulation' => { hint => 'circ',
84 'Fieldmapper::action::open_circulation' => { hint => 'aoc',
87 'Fieldmapper::actor::workstation' => { hint => 'aws' },
89 'Fieldmapper::actor::user' => { hint => 'au',
90 proto_fields => { cards => 1,
91 survey_responses => 1,
92 stat_cat_entries => 1,
99 standing_penalties => 1,
101 'Fieldmapper::actor::usr_note' => { hint => 'aun' },
102 'Fieldmapper::actor::user_setting' => { hint => 'aus' },
103 'Fieldmapper::actor::user_standing_penalty' => { hint => 'ausp' },
104 'Fieldmapper::actor::org_unit_setting' => { hint => 'aous' },
105 'Fieldmapper::actor::user_address' => { hint => 'aua' },
106 'Fieldmapper::actor::org_address' => { hint => 'aoa' },
107 'Fieldmapper::actor::profile' => { hint => 'ap' },
108 'Fieldmapper::actor::card' => { hint => 'ac' },
109 'Fieldmapper::actor::stat_cat' => { hint => 'actsc',
110 proto_fields => { entries => 1 } },
111 'Fieldmapper::actor::stat_cat_entry' => { hint => 'actsce' },
112 'Fieldmapper::actor::stat_cat_entry_user_map' => { hint => 'actscecm' },
113 'Fieldmapper::actor::org_unit' => { hint => 'aou',
114 proto_fields => { children => 1 } },
115 'Fieldmapper::actor::org_unit::closed_date' => { hint => 'aoucd' },
116 'Fieldmapper::actor::org_unit::hours_of_operation' => { hint => 'aouhoo' },
117 'Fieldmapper::actor::org_unit_type' => { hint => 'aout',
118 proto_fields => { children => 1 } },
120 'Fieldmapper::biblio::record_node' => { hint => 'brn',
122 proto_fields => { children => 1,
133 'Fieldmapper::metabib::virtual_record' => { hint => 'mvr',
135 proto_fields => { title => 1,
144 types_of_resource => 1,
149 physical_description => 1,
156 'Fieldmapper::authority::record_entry' => { hint => 'are', },
157 'Fieldmapper::authority::record_note' => { hint => 'arn', },
158 'Fieldmapper::biblio::record_note' => { hint => 'bren', },
159 'Fieldmapper::biblio::record_entry' => { hint => 'bre',
160 proto_fields => { call_numbers => 1,
161 fixed_fields => 1 } },
162 #'Fieldmapper::biblio::record_marc' => { hint => 'brx' }, # now it's inside record_entry
164 'Fieldmapper::money::payment' => { hint => 'mp',
167 'Fieldmapper::money::cash_payment' => { hint => 'mcp' },
168 'Fieldmapper::money::check_payment' => { hint => 'mckp' },
169 'Fieldmapper::money::credit_payment' => { hint => 'mcrp' },
170 'Fieldmapper::money::credit_card_payment' => { hint => 'mccp' },
171 'Fieldmapper::money::forgive_payment' => { hint => 'mfp' },
172 'Fieldmapper::money::work_payment' => { hint => 'mwp' },
173 'Fieldmapper::money::collections_tracker' => { hint => 'mct' },
175 'Fieldmapper::money::billing' => { hint => 'mb' },
176 'Fieldmapper::money::billable_transaction' => { hint => 'mbt' },
177 'Fieldmapper::money::grocery' => { hint => 'mg' },
179 'Fieldmapper::money::open_user_summary' => { hint => 'mous',
181 'Fieldmapper::money::user_summary' => { hint => 'mus',
184 'Fieldmapper::money::open_user_circulation_summary' => { hint => 'moucs',
186 'Fieldmapper::money::user_circulation_summary' => { hint => 'mucs',
189 'Fieldmapper::money::open_billable_transaction_summary' => { hint => 'mobts',
191 'Fieldmapper::money::billable_transaction_summary' => { hint => 'mbts',
194 'Fieldmapper::config::identification_type' => { hint => 'cit' },
195 'Fieldmapper::config::bib_source' => { hint => 'cbs' },
196 'Fieldmapper::config::metabib_field' => { hint => 'cmf' },
197 'Fieldmapper::config::rules::age_hold_protect' => { hint => 'crahp' },
198 'Fieldmapper::config::rules::recuring_fine' => { hint => 'crrf' },
199 'Fieldmapper::config::rules::circ_duration' => { hint => 'crcd' },
200 'Fieldmapper::config::rules::max_fine' => { hint => 'crmf' },
201 'Fieldmapper::config::non_cataloged_type' => { hint => 'cnct' },
202 'Fieldmapper::config::standing' => { hint => 'cst' },
203 'Fieldmapper::config::copy_status' => { hint => 'ccs' },
204 'Fieldmapper::config::net_access_level' => { hint => 'cnal' },
206 'Fieldmapper::config::audience_map' => { hint => 'cam',
208 'Fieldmapper::config::language_map' => { hint => 'clm',
210 'Fieldmapper::config::item_form_map' => { hint => 'cifm',
212 'Fieldmapper::config::item_type_map' => { hint => 'citm',
214 'Fieldmapper::config::lit_form_map' => { hint => 'clfm',
217 'Fieldmapper::authority::full_rec' => { hint => 'afr' },
218 'Fieldmapper::authority::record_descriptor' => { hint => 'ard' },
220 'Fieldmapper::metabib::metarecord' => { hint => 'mmr' },
221 'Fieldmapper::metabib::title_field_entry' => { hint => 'mtfe' },
222 'Fieldmapper::metabib::author_field_entry' => { hint => 'mafe' },
223 'Fieldmapper::metabib::subject_field_entry' => { hint => 'msfe' },
224 'Fieldmapper::metabib::keyword_field_entry' => { hint => 'mkfe' },
225 'Fieldmapper::metabib::series_field_entry' => { hint => 'msefe' },
226 'Fieldmapper::metabib::full_rec' => { hint => 'mfr' },
227 'Fieldmapper::metabib::record_descriptor' => { hint => 'mrd' },
228 'Fieldmapper::metabib::metarecord_source_map' => { hint => 'mmrsm'},
230 'Fieldmapper::asset::copy' => { hint => 'acp',
231 proto_fields => { stat_cat_entries => 1 } },
232 'Fieldmapper::asset::stat_cat' => { hint => 'asc',
233 proto_fields => { entries => 1 } },
234 'Fieldmapper::asset::stat_cat_entry' => { hint => 'asce' },
235 'Fieldmapper::asset::stat_cat_entry_copy_map' => { hint => 'ascecm' },
236 'Fieldmapper::asset::copy_note' => { hint => 'acpn' },
237 'Fieldmapper::asset::copy_location' => { hint => 'acpl' },
238 'Fieldmapper::asset::call_number' => { hint => 'acn',
239 proto_fields => { copies => 1 } },
240 'Fieldmapper::asset::call_number_note' => { hint => 'acnn' },
242 'Fieldmapper::permission::perm_list' => { hint => 'ppl' },
243 'Fieldmapper::permission::grp_tree' => { hint => 'pgt', proto_fields => { children => 1 } },
244 'Fieldmapper::permission::usr_grp_map' => { hint => 'pugm' },
245 'Fieldmapper::permission::usr_perm_map' => { hint => 'pupm' },
246 'Fieldmapper::permission::grp_perm_map' => { hint => 'pgpm' },
247 'Fieldmapper::action::hold_request' => { hint => 'ahr', proto_fields => { status => 1, transit => 1 } },
248 'Fieldmapper::action::hold_notification' => { hint => 'ahn' },
249 'Fieldmapper::action::hold_copy_map' => { hint => 'ahcm' },
250 'Fieldmapper::action::hold_transit_copy' => { hint => 'ahtc' },
251 'Fieldmapper::action::transit_copy' => { hint => 'atc' },
252 'Fieldmapper::action::unfulfilled_hold_list' => { hint => 'aufh' },
255 'Fieldmapper::ex' => { hint => 'ex',
263 'Fieldmapper::perm_ex' => { hint => 'perm_ex',
274 #-------------------------------------------------------------------------------
275 # Now comes the evil! Generate classes
277 for my $pkg ( __PACKAGE__->classes ) {
278 (my $cdbi = $pkg) =~ s/^Fieldmapper:://o;
282 use base 'Fieldmapper';
286 for my $vfield ( qw/isnew ischanged isdeleted/ ) {
287 $$fieldmap{$pkg}{fields}{$vfield} = { position => $pos, virtual => 1 };
291 if (exists $$fieldmap{$pkg}{proto_fields}) {
292 for my $pfield ( sort keys %{ $$fieldmap{$pkg}{proto_fields} } ) {
293 $$fieldmap{$pkg}{fields}{$pfield} = { position => $pos, virtual => $$fieldmap{$pkg}{proto_fields}{$pfield} };
298 unless ( $$fieldmap{$pkg}{virtual} ) {
299 $$fieldmap{$pkg}{cdbi} = $cdbi;
300 for my $col ( sort $cdbi->columns('Essential') ) {
301 $$fieldmap{$pkg}{fields}{$col} = { position => $pos, virtual => 0 };
306 JSON->register_class_hint(
307 hint => $pkg->json_hint,
318 $value = [] unless (defined $value);
319 return bless $value => $self->class_name;
332 (my $field = $AUTOLOAD) =~ s/^.*://o;
333 my $class_name = $obj->class_name;
336 $fpos =~ s/^clear_//og ;
338 my $pos = $$fieldmap{$class_name}{fields}{$fpos}{position};
340 if ($field =~ /^clear_/o) {
342 *{$obj->class_name."::$field"} = sub {
344 $self->[$pos] = undef;
348 return $obj->$field();
351 die "No field by the name $field in $class_name!"
352 unless (exists $$fieldmap{$class_name}{fields}{$field} && defined($pos));
356 *{$obj->class_name."::$field"} = sub {
359 $self->[$pos] = $new_val if (defined $new_val);
360 return $self->[$pos];
363 return $obj->$field($value);
367 my $class_name = shift;
368 return ref($class_name) || $class_name;
373 my $class_name = $self->class_name;
374 my $fields = $$fieldmap{$class_name}{fields};
377 !$$fields{$_}{virtual}
378 } sort {$$fields{$a}{position} <=> $$fields{$b}{position}} keys %$fields;
386 my $class_name = $self->class_name;
387 return 1 if grep { $_ eq $field } keys %{$$fieldmap{$class_name}{fields}};
393 my $class_name = $self->class_name;
394 return keys %{$$fieldmap{$class_name}{fields}};
399 return $self->new( [@$self] );
404 return $fieldmap->{$self->class_name}->{api_level};
409 return $fieldmap->{$self->class_name}->{cdbi};
415 return $fieldmap->{$self->class_name}->{proto_fields}->{$field} if ($field);
416 return $fieldmap->{$self->class_name}->{virtual};
422 return $fieldmap->{$self->class_name}->{readonly};
427 return $fieldmap->{$self->class_name}->{hint};