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   gifi                           => 'gifi',
76   gl                             => 'GLTransaction',
77   history_erp                    => 'history',
78   inventory                      => 'inventory',
79   invoice                        => 'invoice_item',
80   language                       => 'language',
81   makemodel                      => 'make_model',
82   notes                          => 'note',
83   orderitems                     => 'order_item',
84   oe                             => 'order',
85   parts                          => 'part',
86   partsgroup                     => 'parts_group',
87   payment_terms                  => 'payment_term',
88   periodic_invoices              => 'periodic_invoice',
89   periodic_invoices_configs      => 'periodic_invoices_config',
90   prices                         => 'price',
91   price_factors                  => 'price_factor',
92   pricegroup                     => 'pricegroup',
93   printers                       => 'Printer',
94   record_links                   => 'record_link',
95   sepa_export                    => 'sepa_export',
96   sepa_export_items              => 'sepa_export_item',
97   schema_info                    => 'schema_info',
98   status                         => 'status',
99   tax                            => 'tax',
100   taxkeys                        => 'tax_key',
101   tax_zones                      => 'tax_zone',
102   todo_user_config               => 'todo_user_config',
103   translation                    => 'translation',
104   translation_payment_terms      => 'translation_payment_term',
105   units                          => 'unit',
106   units_language                 => 'units_language',
107   vendor                         => 'vendor',
108 );
109
110 my (%lxoffice_tables_to_packages, %lxoffice_tables_to_manager_packages, %lxoffice_packages_to_tables);
111
112 sub get_blacklist {
113   return LXOFFICE => \@lxoffice_blacklist;
114 }
115
116 sub get_package_names {
117   return LXOFFICE => \%lxoffice_package_names;
118 }
119
120 sub get_package_for_table {
121   %lxoffice_tables_to_packages = map { ($_ => "SL::DB::" . camelify($lxoffice_package_names{$_})) } keys %lxoffice_package_names
122     unless %lxoffice_tables_to_packages;
123
124   return $lxoffice_tables_to_packages{ $_[0] };
125 }
126
127 sub get_manager_package_for_table {
128   %lxoffice_tables_to_manager_packages = map { ($_ => "SL::DB::Manager::" . camelify($lxoffice_package_names{$_})) } keys %lxoffice_package_names
129     unless %lxoffice_tables_to_manager_packages;
130
131   return $lxoffice_tables_to_manager_packages{ $_[0] };
132 }
133
134 sub get_table_for_package {
135   get_package_for_table('dummy') if !%lxoffice_tables_to_packages;
136   %lxoffice_packages_to_tables = reverse %lxoffice_tables_to_packages unless %lxoffice_packages_to_tables;
137
138   my $package = $_[0] =~ m/^SL::DB::/ ? $_[0] : "SL::DB::" . $_[0];
139   return $lxoffice_packages_to_tables{ $package };
140 }
141
142 sub db {
143   my $string = $_[0];
144   my $lookup = $lxoffice_package_names{$_[0]} ||
145       plurify($lxoffice_package_names{singlify($_[0])});
146
147   for my $thing ($string, $lookup) {
148
149     # best guess? its already the name. like part. camelize it first
150     my $class = "SL::DB::" . camelify($thing);
151     return $class if defined *{ $class. '::' };
152
153     # next, someone wants a manager and pluralized.
154     my $manager = "SL::DB::Manager::" . singlify(camelify($thing));
155     return $manager if defined *{ $manager . '::' };
156   }
157
158   die "Can't resolve '$string' as a database model, sorry. Did you perhaps forgot to load it?";
159 }
160
161 sub camelify {
162   my ($str) = @_;
163   $str =~ s/_+(.)/uc($1)/ge;
164   ucfirst $str;
165 }
166
167 sub snakify {
168   my ($str) = @_;
169   $str =~ s/(?<!^)\u(.)/'_' . lc($1)/ge;
170   lcfirst $str;
171 }
172
173 sub plurify {
174   my ($str) = @_;
175   $str . 's';
176 }
177
178 sub singlify {
179   my ($str) = @_;
180   local $/ = 's';
181   chomp $str;
182   $str;
183 }
184
185 1;
186
187 __END__
188
189 =encoding utf8
190
191 =head1 NAME
192
193 SL::DB::Helper::Mappings - Rose Table <-> Model mapping information
194
195 =head1 SYNOPSIS
196
197   use SL::DB::Helper::Mappings qw(@blacklist %table2model);
198
199 =head1 DESCRIPTION
200
201 This modul stores table <-> model mappings used by the
202 L<scripts/rose_auto_create_model.pl> script.  If you add a new table that has
203 custom mappings, add it here.
204
205 =head1 FUNCTIONS
206
207 =over 4
208
209 =item C<db $name>
210
211 A special function provided here is C<db>. Without it you'd have to write:
212
213   my $part = SL::DB::Part->new(id => 1234);
214   my @all_parts = SL::DB::Manager::Part->get_all;
215
216 with them it becomes:
217
218   my $part = db('part')->new(id => 123);
219   my @all_parts = db('parts')->get_all;
220
221 You don't have to care about add that SL::DB:: incantation anymore. Also, a
222 simple s at the end will get you the associated Manager class.
223
224 db is written to try to make sense of what you give it, but if all fails, it
225 will die with an error.
226
227 =item C<get_package_for_table $table_name>
228
229 Returns the package name for a table name:
230
231   SL::DB::Helper::Mappings::get_package_for_table('oe')
232   # SL::DB::Order
233
234 =item C<get_manager_package_for_table $table_name>
235
236 Returns the manager package name for a table name:
237
238   SL::DB::Helper::Mappings::get_manager_package_for_table('oe')
239   # SL::DB::Manager::Order
240
241 =item C<get_table_for_package $package_name>
242
243 Returns the table name for a package name:
244
245   SL::DB::Helper::Mappings::get_table_for_package('SL::DB::Order')
246   # oe
247   SL::DB::Helper::Mappings::get_table_for_package('Order')
248   # oe
249
250 =back
251
252 =head1 BUGS
253
254 nothing yet
255
256 =head1 SEE ALSO
257
258 L<scripts/rose_auto_create_model.pl>
259
260 =head1 AUTHOR
261
262 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>,
263 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
264
265 =cut