stub für einen generische attrhelper.
[kivitendo-erp.git] / SL / DB / Object.pm
1 package SL::DB::Object;
2
3 use strict;
4
5 use Readonly;
6 use Rose::DB::Object;
7 use List::MoreUtils qw(any);
8
9 use SL::DB;
10 use SL::DB::Helpers::AttrNumber;
11 use SL::DB::Helpers::AttrDate;
12 use SL::DB::Helpers::AttrPercent;
13 use SL::DB::Helpers::Metadata;
14 use SL::DB::Helpers::Manager;
15
16 use base qw(Rose::DB::Object);
17
18 sub new {
19   my $class = shift;
20   my $self  = $class->SUPER::new();
21
22   $self->_assign_attributes(@_) if $self;
23
24   return $self;
25 }
26
27 sub init_db {
28   my $class_or_self = shift;
29   my $class         = ref($class_or_self) || $class_or_self;
30   my $type          = 'LXOFFICE';
31
32   return SL::DB::create(undef, $type);
33 }
34
35 sub meta_class {
36   return 'SL::DB::Helpers::Metadata';
37 }
38
39 sub _get_manager_class {
40   my $class_or_self = shift;
41   my $class         = ref($class_or_self) || $class_or_self;
42
43   return $class->meta->convention_manager->auto_manager_class_name($class);
44 }
45
46 Readonly my %text_column_types => (text => 1, char => 1, varchar => 1);
47
48 sub assign_attributes {
49   my $self       = shift;
50   my %attributes = @_;
51
52   my $pk         = ref($self)->meta->primary_key;
53   delete @attributes{$pk->column_names} if $pk;
54
55   return $self->_assign_attributes(%attributes);
56 }
57
58 sub _assign_attributes {
59   my $self       = shift;
60   my %attributes = @_;
61
62   my %types      = map { $_->name => $_->type } ref($self)->meta->columns;
63
64   while (my ($attribute, $value) = each %attributes) {
65     my $type = lc($types{$attribute} || 'text');
66     $value   = $type eq 'boolean'        ? ($value ? 't' : 'f')
67              : $text_column_types{$type} ? $value
68              :                             ($value || undef);
69     $self->$attribute($value);
70   }
71
72   return $self;
73 }
74
75 sub update_attributes {
76   my $self = shift;
77
78   $self->assign_attributes(@_)->save;
79
80   return $self;
81 }
82
83 sub make_attr_helper {
84   my ($self) = @_;
85   my $package = ref $self || $self;
86
87   for my $col ($package->meta->columns) {
88     next if $col->primary_key_position; # don't make attr helper for primary keys
89
90     attr_number ($package, $col->name, -2) if $col->type =~ /numeric | real | float/xi;
91     attr_percent($package, $col->name, -2) if $col->type =~ /numeric | real | float/xi;
92     attr_number ($package, $col->name,  0) if $col->type =~ /int/xi;
93     attr_date   ($package, $col->name)     if $col->type =~ /date | timestamp/xi;
94   }
95
96   return $self;
97 }
98
99 sub attr_number {
100   SL::DB::Helpers::AttrNumber::define(@_);
101 }
102
103 sub attr_date {
104   SL::DB::Helpers::AttrDate::define(@_);
105 }
106
107 sub attr_percent {
108   SL::DB::Helpers::AttrPercent::define(@_);
109 }
110
111 1;
112
113 __END__
114
115 =pod
116
117 =head1 NAME
118
119 SL::DB::Object: Base class for all of our model classes
120
121 =head1 DESCRIPTION
122
123 This is the base class from which all other model classes are
124 derived. It contains functionality and settings required for all model
125 classes.
126
127 Several functions (e.g. C<make_manager_class>, C<init_db>) in this
128 class are used for setting up the classes / base classes used for all
129 model instances. They overwrite the functions from
130 L<Rose::DB::Object>.
131
132 =head1 FUNCTIONS
133
134 =over 4
135
136 =item assign_attributes %attributes
137
138 =item _assign_attributes %attributes
139
140 Assigns all elements from C<%attributes> to the columns by calling
141 their setter functions. The difference between the two functions is
142 that C<assign_attributes> protects primary key columns while
143 C<_assign_attributes> doesn't.
144
145 Both functions handle values that are empty strings by replacing them
146 with C<undef> for non-text columns. This allows the calling functions
147 to use data from HTML forms as the input for C<assign_attributes>
148 without having to remove empty strings themselves (think of
149 e.g. select boxes with an empty option which should be turned into
150 C<NULL> in the database).
151
152 =item update_attributes %attributes
153
154 Assigns the attributes from C<%attributes> by calling the
155 C<assign_attributes> function and saves the object afterwards. Returns
156 the object itself.
157
158 =item _get_manager_class
159
160 Returns the manager package for the object or class that it is called
161 on. Can be used from methods in this package for getting the actual
162 object's manager.
163
164 =back
165
166 =head1 AUTHOR
167
168 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
169
170 =cut