Merge branch 'master' of github.com:kivitendo/kivitendo-erp
[kivitendo-erp.git] / SL / DB / Helper / Mappings.pm
1 package SL::DB::Helper::Mappings;
2
3 use utf8;
4 use strict;
5
6 require Exporter;
7 our @ISA       = qw(Exporter);
8 our @EXPORT_OK = qw(get_table_for_package get_package_for_table get_package_names);
9
10 # these will not be managed as Rose::DB models, because they are not normalized,
11 # significant changes are needed to get them done, or they were done by CRM.
12 my @lxoffice_blacklist_permanent = qw(
13   leads
14 );
15
16 # these are not managed _yet_, but will hopefully at some point.
17 # if you are confident that one of these works, remove it here.
18 my @lxoffice_blacklist_temp = qw(
19 );
20
21 # tables created by crm module
22 my @crm_blacklist = qw(
23 );
24
25 # tables created by cash register
26 my @cash_register_blacklist = qw(
27 ekartikel ekbon ekkunde ektext erptasten
28 );
29
30 my @lxoffice_blacklist = (@lxoffice_blacklist_permanent, @lxoffice_blacklist_temp, @crm_blacklist, @cash_register_blacklist);
31
32 # map table names to their models.
33 # unlike rails we have no singular<->plural magic.
34 # remeber: tables should be named as the plural of the model name.
35 my %lxoffice_package_names = (
36   acc_trans                      => 'acc_transaction',
37   audittrail                     => 'audit_trail',
38   auth_group                     => 'auth_groups',
39   auth_group_right               => 'auth_group_rights',
40   auth_user                      => 'auth_users',
41   auth_user_config               => 'auth_user_configs',
42   auth_user_group                => 'auth_user_groups',
43   ar                             => 'invoice',
44   ap                             => 'purchase_invoice',
45   background_jobs                => 'background_job',
46   background_job_histories       => 'background_job_history',
47   ap                             => 'purchase_invoice',
48   bank_accounts                  => 'bank_account',
49   buchungsgruppen                => 'buchungsgruppe',
50   contacts                       => 'contact',
51   csv_import_profiles            => 'csv_import_profile',
52   csv_import_profile_settings    => 'csv_import_profile_setting',
53   csv_import_reports             => 'csv_import_report',
54   csv_import_report_rows         => 'csv_import_report_row',
55   csv_import_report_status       => 'csv_import_report_status',
56   custom_variable_configs        => 'custom_variable_config',
57   custom_variables               => 'custom_variable',
58   custom_variables_validity      => 'custom_variable_validity',
59   datev                          => 'datev',
60   defaults                       => 'default',
61   delivery_orders                => 'delivery_order',
62   delivery_order_items           => 'delivery_order_item',
63   department                     => 'department',
64   dpt_trans                      => 'dpt_trans',
65   drafts                         => 'draft',
66   dunning                        => 'dunning',
67   dunning_config                 => 'dunning_config',
68   employee                       => 'employee',
69   exchangerate                   => 'exchangerate',
70   finanzamt                      => 'finanzamt',
71   follow_up_access               => 'follow_up_access',
72   follow_up_links                => 'follow_up_link',
73   follow_ups                     => 'follow_up',
74   generic_translations           => 'generic_translation',
75   gl                             => 'GLTransaction',
76   history_erp                    => 'history',
77   inventory                      => 'inventory',
78   invoice                        => 'invoice_item',
79   language                       => 'language',
80   makemodel                      => 'make_model',
81   notes                          => 'note',
82   orderitems                     => 'order_item',
83   oe                             => 'order',
84   parts                          => 'part',
85   partsgroup                     => 'parts_group',
86   payment_terms                  => 'payment_term',
87   periodic_invoices              => 'periodic_invoice',
88   periodic_invoices_configs      => 'periodic_invoices_config',
89   prices                         => 'price',
90   price_factors                  => 'price_factor',
91   pricegroup                     => 'pricegroup',
92   printers                       => 'Printer',
93   record_links                   => 'record_link',
94   sepa_export                    => 'sepa_export',
95   sepa_export_items              => 'sepa_export_item',
96   schema_info                    => 'schema_info',
97   status                         => 'status',
98   tax                            => 'tax',
99   taxkeys                        => 'tax_key',
100   tax_zones                      => 'tax_zone',
101   todo_user_config               => 'todo_user_config',
102   translation                    => 'translation',
103   translation_payment_terms      => 'translation_payment_term',
104   units                          => 'unit',
105   units_language                 => 'units_language',
106   vendor                         => 'vendor',
107 );
108
109 my (%lxoffice_tables_to_packages, %lxoffice_tables_to_manager_packages, %lxoffice_packages_to_tables);
110
111 sub get_blacklist {
112   return LXOFFICE => \@lxoffice_blacklist;
113 }
114
115 sub get_package_names {
116   return LXOFFICE => \%lxoffice_package_names;
117 }
118
119 sub get_package_for_table {
120   %lxoffice_tables_to_packages = map { ($_ => "SL::DB::" . camelify($lxoffice_package_names{$_})) } keys %lxoffice_package_names
121     unless %lxoffice_tables_to_packages;
122
123   return $lxoffice_tables_to_packages{ $_[0] };
124 }
125
126 sub get_manager_package_for_table {
127   %lxoffice_tables_to_manager_packages = map { ($_ => "SL::DB::Manager::" . camelify($lxoffice_package_names{$_})) } keys %lxoffice_package_names
128     unless %lxoffice_tables_to_manager_packages;
129
130   return $lxoffice_tables_to_manager_packages{ $_[0] };
131 }
132
133 sub get_table_for_package {
134   get_package_for_table('dummy') if !%lxoffice_tables_to_packages;
135   %lxoffice_packages_to_tables = reverse %lxoffice_tables_to_packages unless %lxoffice_packages_to_tables;
136
137   my $package = $_[0] =~ m/^SL::DB::/ ? $_[0] : "SL::DB::" . $_[0];
138   return $lxoffice_packages_to_tables{ $package };
139 }
140
141 sub db {
142   my $string = $_[0];
143   my $lookup = $lxoffice_package_names{$_[0]} ||
144       plurify($lxoffice_package_names{singlify($_[0])});
145
146   for my $thing ($string, $lookup) {
147
148     # best guess? its already the name. like part. camelize it first
149     my $class = "SL::DB::" . camelify($thing);
150     return $class if defined *{ $class. '::' };
151
152     # next, someone wants a manager and pluralized.
153     my $manager = "SL::DB::Manager::" . singlify(camelify($thing));
154     return $manager if defined *{ $manager . '::' };
155   }
156
157   die "Can't resolve '$string' as a database model, sorry. Did you perhaps forgot to load it?";
158 }
159
160 sub camelify {
161   my ($str) = @_;
162   $str =~ s/_+(.)/uc($1)/ge;
163   ucfirst $str;
164 }
165
166 sub snakify {
167   my ($str) = @_;
168   $str =~ s/(?<!^)\u(.)/'_' . lc($1)/ge;
169   lcfirst $str;
170 }
171
172 sub plurify {
173   my ($str) = @_;
174   $str . 's';
175 }
176
177 sub singlify {
178   my ($str) = @_;
179   local $/ = 's';
180   chomp $str;
181   $str;
182 }
183
184 1;
185
186 __END__
187
188 =encoding utf8
189
190 =head1 NAME
191
192 SL::DB::Helper::Mappings - Rose Table <-> Model mapping information
193
194 =head1 SYNOPSIS
195
196   use SL::DB::Helper::Mappings qw(@blacklist %table2model);
197
198 =head1 DESCRIPTION
199
200 This modul stores table <-> model mappings used by the
201 L<scripts/rose_auto_create_model.pl> script.  If you add a new table that has
202 custom mappings, add it here.
203
204 =head1 FUNCTIONS
205
206 =over 4
207
208 =item C<db $name>
209
210 A special function provided here is C<db>. Without it you'd have to write:
211
212   my $part = SL::DB::Part->new(id => 1234);
213   my @all_parts = SL::DB::Manager::Part->get_all;
214
215 with them it becomes:
216
217   my $part = db('part')->new(id => 123);
218   my @all_parts = db('parts')->get_all;
219
220 You don't have to care about add that SL::DB:: incantation anymore. Also, a
221 simple s at the end will get you the associated Manager class.
222
223 db is written to try to make sense of what you give it, but if all fails, it
224 will die with an error.
225
226 =item C<get_package_for_table $table_name>
227
228 Returns the package name for a table name:
229
230   SL::DB::Helper::Mappings::get_package_for_table('oe')
231   # SL::DB::Order
232
233 =item C<get_manager_package_for_table $table_name>
234
235 Returns the manager package name for a table name:
236
237   SL::DB::Helper::Mappings::get_manager_package_for_table('oe')
238   # SL::DB::Manager::Order
239
240 =item C<get_table_for_package $package_name>
241
242 Returns the table name for a package name:
243
244   SL::DB::Helper::Mappings::get_table_for_package('SL::DB::Order')
245   # oe
246   SL::DB::Helper::Mappings::get_table_for_package('Order')
247   # oe
248
249 =back
250
251 =head1 BUGS
252
253 nothing yet
254
255 =head1 SEE ALSO
256
257 L<scripts/rose_auto_create_model.pl>
258
259 =head1 AUTHOR
260
261 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>,
262 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
263
264 =cut