source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/Employment.pm @ 2133

Last change on this file since 2133 was 2116, checked in by nanardon, 7 years ago

Typo

File size: 12.8 KB
RevLine 
[1489]1package LATMOS::Accounts::Bases::Sql::Employment;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use base qw(LATMOS::Accounts::Bases::Sql::objects);
[1500]8use LATMOS::Accounts::Log;
[1551]9use LATMOS::Accounts::I18N;
[1500]10use Date::Parse;
11use DateTime;
[1623]12use Date::Calc;
[1489]13
14our $VERSION = (q$Rev: 594 $ =~ /^Rev: (\d+) /)[0];
15
16=head1 NAME
17
18LATMOS::Accounts::Bases::Sql::Address - Physical office Adress Support
19
20=head1 DESCRIPTION
21
22C<Address> objects allow to store user's several office addresses.
23
24Notice most of other bases (Ldap, ...) support only one address.
25
26=cut
27
28sub stringify {
29    my ($self) = @_;
30
31    my $user = $self->base->get_object('user', $self->_get_c_field('user'))
32        or return $self->id;
33
34    return join(', ', grep { $_ }
35        (
36            $user,
[1500]37            $self->get_c_field('firstday'),
[1489]38        )
39    );
40}
41
42sub _object_table { 'employment' }
43
44sub _key_field { 'name' }
45
46sub _has_extended_attributes { 1 }
47
48sub _get_attr_schema {
49    my ($class, $base) = @_;
50
[1516]51    my $attrs = {
52        name =>         { inline => 1, },
53        exported =>     { inline => 1, },
54        user =>         { inline => 1,
55            reference => 'user',
[1550]56            label => l('User'),
[1516]57        },
[1550]58        description => {
59            label => l('Description'),
60        },
[1516]61        firstday => {
62            inline => 1,
63            formtype => 'DATE',
64            monitored => 1,
[1620]65            label => l('Contract start'),
[1516]66        },
67        lastday => {
68            inline => 1,
69            formtype => 'DATE',
70            monitored => 1,
[1620]71            label => l('Contract end'),
[1516]72        },
[1623]73        length => {
74            ro => 1,
75            managed => 1,
76            get => sub {
77                my ($self) = @_;
78                my $lastday = $self->object->get_attributes('lastday') || DateTime->now->ymd('-');
79                my $firstday = $self->object->get_attributes('firstday');
80
81                my @fd = split('-', $firstday);
82                my @ld = split('-', $lastday);
83
84                return Date::Calc::Delta_Days(@fd, @ld) +1;
85            },
86            label => l('Length'),
87        },
88        lengthText => {
89            ro => 1,
90            managed => 1,
91            get => sub {
92                my ($self) = @_;
93                my $lastday = $self->object->get_attributes('lastday')|| DateTime->now->ymd('-');
94                {
95                    my $dtlast = DateTime->from_epoch(epoch => str2time($lastday));
96                    $dtlast->add(days => 1);
97                    $lastday = $dtlast->ymd('-');
98                }
99                my $firstday = $self->object->get_attributes('firstday');
100
[1647]101                return if ($firstday gt $lastday);
102
[1646]103                my @fd = split('-', $firstday) or return;
104                my @ld = split('-', $lastday)  or return;
[1623]105
106                my ($Dy,$Dm,$Dd) = Date::Calc::N_Delta_YMD(@fd, @ld);
107                return join(', ',
108                    ($Dy ? l('%d years', $Dy)  : ()),
109                    ($Dm ? l('%d months', $Dm) : ()),
110                    ($Dd ? l('%d days', $Dd)   : ()),
111                );
112            },
113            label => l('Length'),
114        },
[1516]115        'state' => {
116            managed => 1,
117            ro => 1,
118            get => sub {
119                my ($self) = @_;
120                my $now = DateTime->now;
121                if ($now->epoch < str2time($self->object->get_attributes('firstday'))) {
122                    return 1;
123                } elsif ( my $end = $self->object->get_attributes('lastday') ) {
124                    my $eend = str2time($end) + 86400;
125                    if ($now->epoch > $eend) {
126                        return -1;
[1832]127                    } else {
128                        return 0;
[1500]129                    }
[1516]130                } else {
131                    return 0;
132                }
[1500]133            },
[1550]134            label => l('State'),
[1516]135        },
136        contratType => {
137            reference => 'group',
138            can_values => sub {
139                $base->search_objects('group', 'sutype=contrattype')
[1489]140            },
[1516]141            monitored => 1,
[1550]142            label => l('Type of contract'),
[1516]143        },
144        managerContact => {
145            delayed => 1,
146            can_values => sub {
147                my %uniq = map { $_ => 1 } grep { $_ }
148                ($_[1] ? $_[1]->get_attributes('managerContact') : ()),
149                $base->search_objects('user', 'active=*');
150                sort keys %uniq;
[1500]151            },
[1516]152            reference => 'user',
[1621]153            label => l('Direct manager'),
[1516]154        },
155        department => {
156            reference => 'group',
157            can_values => sub {
158                $base->search_objects('group', 'sutype=dpmt')
[1500]159            },
[1516]160            monitored => 1,
[1550]161            label => l('Department'),
[1516]162        },
[1550]163        company => {
164            label => l('Company'),
165        },
[1860]166        employer => {
167            label => l('Employer'),
168        },
[1550]169        endcircuit    => {
170            formtype => 'DATE',
171            monitored => 1,
[1620]172            label => l('End of entrance circuit'),
[1550]173        },
[1589]174        hosted => {
175            formtype => 'CHECKBOX',
176            label => l('Hosted'),
177        },
[2114]178        requestId => {
179            label => l('Request id')
[2116]180        },
[1516]181        previous => {
182            ro => 1,
183            managed => 1,
184            get => sub {
185                my ($self) = @_;
186                my $find = $self->object->base->db->prepare_cached(q{
187                    SELECT name from employment where "user" = ?
188                        and (lastday is not null and lastday < ?)
189                        order by lastday desc
190                });
191                $find->execute(
192                    $self->object->get_field('user'),
193                    $self->object->get_field('firstday')
194                );
195                my $res = $find->fetchrow_hashref;
196                $find->finish;
197                return $res->{name};
[1511]198            },
[1550]199            label => l('Previous'),
[1516]200        },
[2116]201        'next' => {
[1516]202            ro => 1,
203            managed => 1,
204            get => sub {
205                my ($self) = @_;
206                my $find = $self->object->base->db->prepare_cached(q{
207                    SELECT name from employment where "user" = ?
208                        and firstday > ?
209                        order by firstday asc
210                });
211                $find->execute(
212                    $self->object->get_field('user'),
213                    $self->object->get_field('lastday')
214                );
215                my $res = $find->fetchrow_hashref;
216                $find->finish;
217                return $res->{name};
[1511]218            },
[1550]219            label => l('Next'),
[1516]220        },
[1537]221        minFirstDay => {
222            ro => 1,
223            hidden => 1,
224            managed => 1,
225            formtype => 'DATE',
226            get => sub {
227                my ($attr) = @_;
228                my $self = $attr->object;
229
230                my $find = $self->base->db->prepare_cached(q{
231                    SELECT max(lastday) as lastday FROM employment where "user" = ?
232                        and lastday is not NULL and lastday < ?
233                    });
234
235                my $first = $self->get_field('firstday');
236
237                $find->execute(
238                    $self->get_field('user'),
239                    $first
240                );
241                my $res = $find->fetchrow_hashref;
242                $find->finish;
243
244                if ($res && $res->{lastday}) {
245                    my $dt = DateTime->from_epoch( epoch => str2time($res->{lastday}));
246                    $dt->set_time_zone( DateTime::TimeZone->new( name => 'local' ) );
247                    $dt->add(days => 1);
248                    if ($first eq $dt->ymd('-')) {
[1540]249                        return $first;
[1537]250                    } else {
251                        return $dt->ymd('-');
252                    }
253                } else {
[1540]254                    return;
[1537]255                }
256            },
[1550]257            label => l('Minimal first day'),
[1537]258        },
259        maxLastDay => {
260            ro => 1,
261            hidden => 1,
262            managed => 1,
263            formtype => 'DATE',
264            get => sub {
265                my ($attr) = @_;
266                my $self = $attr->object;
267
268                my $find = $self->base->db->prepare_cached(q{
269                    SELECT min(firstday) as firstday FROM employment where "user" = ?
270                        and firstday > ?
271                    });
272
273                my $last = $self->get_field('lastday') or do {
274                    # This contract is last then...
[1540]275                    return;
[1537]276                };
277
278                $find->execute(
279                    $self->get_field('user'),
280                    $last
281                );
282                my $res = $find->fetchrow_hashref;
283                $find->finish;
284
285                if ($res && $res->{firstday}) {
286                    my $dt = DateTime->from_epoch( epoch => str2time($res->{firstday}));
287                    $dt->set_time_zone( DateTime::TimeZone->new( name => 'local' ) );
288                    $dt->subtract(days => 1);
289                    if ($last eq $dt->ymd('-')) {
[1540]290                        return $last;
[1537]291                    } else {
292                        return $dt->ymd('-');
293                    }
294                } else {
[1540]295                    return;
[1537]296                }
297            },
[1550]298            label => l('Maximal last day'),
[1537]299        },
[1516]300    };
301
[1834]302    if (! $base->config("allow_pasted_employment")) {
[1516]303    # Completed contract are RO, we allow to still set lastday
[1860]304        foreach (qw(endcircuit firstday contratType department managerContact company employer)) {
[1834]305            $attrs->{$_}{ro} = sub {
306                my ($self) = $_[0];
307                $self or return 0;
308                my $st = $self->get_attributes('state') || '0';
309                return $st < 0 ? 1 : 0;
310            };
311        }
[1516]312    }
313    $class->SUPER::_get_attr_schema($base, $attrs);
[1489]314}
315
316sub _create {
317    my ($class, $base, $id, %data) = @_;
318    $data{user} or return;
319    my $user = $base->get_object('user', $data{user});
320    $user or return;
[1945]321    my $res = $class->SUPER::_create($base, $id, %data);
[1949]322    $user->applyCurrentEmployment;
[1945]323    $res;
[1489]324}
325
[1636]326sub _delete {
327    my ($class, $base, $id) = @_;
328
329    my $obj = $base->get_object($class->type, $id)
330        or return;
331
332    my $user = $obj->_get_attributes('user');
333
334    my $res = $class->SUPER::_delete($base, $id);
335    if ($res) {
336        my $ouser = $base->get_object('user', $user);
[1949]337        $ouser->applyCurrentEmployment;
[1636]338    }
339
340    $res
341}
342
[2075]343sub _set_c_fields {
[1945]344    my ($self, %data) = @_;
345
[2075]346    my $res = $self->SUPER::_set_c_fields(%data);
[1945]347
[2075]348    if ($res) {
349        my $user = $self->base->get_object('user', $self->get_attributes('user')) or do {
350            $self->base->log(LA_ERR, "Cannot fetch user %s to apply employment", $self->get_attributes('user'));
351            return;
352        };
[2076]353
354        $user->applyCurrentEmployment;
[2075]355    }
[1500]356
[1950]357    return $res;
[1500]358}
359
360sub checkValues {
361    my ($class, $base, $obj, %changes) = @_;
362
363    my $user = $changes{user} || $obj->get_attributes('user');
364    my $id = ref $obj ? $obj->id : $obj;
365
[1994]366    my $firstday = exists($changes{firstday}) 
367        ? $changes{firstday} : 
[2007]368            ref $obj ? $obj->get_attributes('firstday') : undef;
[1994]369    my $lastday  = exists($changes{lastday})
370        ?  $changes{lastday} :
[2007]371            ref $obj ? $obj->get_attributes('lastday') : undef;
[1787]372
373    if ($lastday) {
[1500]374        my $sth = $base->db->prepare_cached(q{
[1787]375            select name, firstday, lastday from employment where "user" = ? and name != ?
376                and
377            (
378            (firstday <= ? and (lastday is NULL or lastday >= ?))
379                or
380            ((lastday is NOT NULL and lastday <= ?) and firstday >= ?)
381            )
[1500]382        });
[1787]383        $sth->execute($user, $id, $lastday, $firstday, $lastday, $firstday);
[1500]384        my $res = $sth->fetchrow_hashref;
385        $sth->finish;
[1787]386
[1500]387        if ($res) {
[1787]388            $base->log(LA_ERR, "The change will overlap contrat %s (%s - %s)", $res->{name}, $res->{firstday}, $res->{lastday} || '');
[1500]389            return;
390        }
[1994]391    } elsif (!$firstday) {
392        $base->log(LA_ERR, "No firstday given");
393        return;
[1787]394    } else {
[1500]395        my $sth = $base->db->prepare_cached(q{
[1787]396            select * from employment where "user" = ? and name != ?
[1811]397            and (lastday is NULL OR lastday >= ?)
[1500]398            limit 1
399        });
[1787]400        $sth->execute($user, $id, $firstday);
[1500]401        my $res = $sth->fetchrow_hashref;
402        if ($res && $res->{name}) {
403            if ($id ne $res->{name}) {
404                $base->log(LA_ERR, "Another contract has no ending (%s)", $res->{name} || '');
405                return;
406            }
407        }
408    }
409
410    return 1;
411}
412
[1489]4131;
414
415__END__
416
417=head1 SEE ALSO
418
419L<LATMOS::Accounts::Bases::Sql>
420
421=head1 AUTHOR
422
423Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
424
425=head1 COPYRIGHT AND LICENSE
426
427Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
428
429This library is free software; you can redistribute it and/or modify
430it under the same terms as Perl itself, either Perl version 5.10.0 or,
431at your option, any later version of Perl 5 you may have available.
432
433
434=cut
Note: See TracBrowser for help on using the repository browser.