File Coverage

blib/lib/App/Dochazka/REST/Model/Schedhistory.pm
Criterion Covered Total %
statement 26 52 50.0
branch 0 4 0.0
condition n/a
subroutine 9 16 56.2
pod 7 7 100.0
total 42 79 53.1


line stmt bran cond sub pod time code
1             # *************************************************************************
2             # Copyright (c) 2014-2017, SUSE LLC
3             #
4             # All rights reserved.
5             #
6             # Redistribution and use in source and binary forms, with or without
7             # modification, are permitted provided that the following conditions are met:
8             #
9             # 1. Redistributions of source code must retain the above copyright notice,
10             # this list of conditions and the following disclaimer.
11             #
12             # 2. Redistributions in binary form must reproduce the above copyright
13             # notice, this list of conditions and the following disclaimer in the
14             # documentation and/or other materials provided with the distribution.
15             #
16             # 3. Neither the name of SUSE LLC nor the names of its contributors may be
17             # used to endorse or promote products derived from this software without
18             # specific prior written permission.
19             #
20             # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21             # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22             # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23             # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24             # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25             # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26             # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27             # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28             # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29             # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30             # POSSIBILITY OF SUCH DAMAGE.
31             # *************************************************************************
32              
33             package App::Dochazka::REST::Model::Schedhistory;
34              
35 41     41   3002 use 5.012;
  41         133  
36 41     41   193 use strict;
  41         87  
  41         726  
37 41     41   222 use warnings;
  41         88  
  41         1130  
38 41     41   202 use App::CELL qw( $CELL $log $meta $site );
  41         84  
  41         3676  
39 41     41   884 use App::Dochazka::REST::Model::Shared qw( cud get_history load );
  41         92  
  41         1860  
40 41     41   226 use Data::Dumper;
  41         83  
  41         1513  
41 41     41   241 use Params::Validate qw( :all );
  41         80  
  41         5163  
42              
43             # we get 'spawn', 'reset', and accessors from parent
44 41     41   252 use parent 'App::Dochazka::Common::Model::Schedhistory';
  41         80  
  41         225  
45              
46              
47              
48              
49             =head1 NAME
50              
51             App::Dochazka::REST::Model::Schedhistory - schedule history functions
52              
53              
54              
55              
56             =head1 SYNOPSIS
57              
58             use App::Dochazka::REST::Model::Schedhistory;
59              
60             ...
61              
62              
63              
64             =head1 DESCRIPTION
65              
66             A description of the schedhistory data model follows.
67              
68              
69             =head2 Schedhistory in the database
70              
71             =head3 Table
72              
73             Once we know the SID of the schedule we would like to assign to a given
74             employee, it is time to insert a record into the C<schedhistory> table:
75              
76             CREATE TABLE IF NOT EXISTS schedhistory (
77             shid serial PRIMARY KEY,
78             eid integer REFERENCES employees (eid) NOT NULL,
79             sid integer REFERENCES schedules (sid) NOT NULL,
80             effective timestamp NOT NULL,
81             remark text,
82             stamp json
83             );
84              
85             =head3 Stored procedures
86              
87             This table also includes two stored procedures -- C<sid_at_timestamp> and
88             C<current_schedule> -- which will return an employee's schedule as of a given
89             date/time and as of 'now', respectively. For the procedure definitions, see
90             C<dbinit_Config.pm>
91              
92             See also L<When history changes take effect>.
93              
94              
95             =head2 Schedhistory in the Perl API
96              
97             =over
98              
99             =item * constructor (L<spawn>)
100              
101             =item * L<reset> method (recycles an existing object)
102              
103             =item * basic accessors (L<shid>, L<eid>, L<sid>, L<effective>, L<remark>)
104              
105             =item * L<load_by_eid> method (load schedhistory record from EID and optional timestamp)
106              
107             =item * L<load_by_shid> method (wrapper for load_by_id)
108              
109             =item * L<load_by_id> (load schedhistory record by its SHID)
110              
111             =item * L<insert> method (straightforward)
112              
113             =item * L<delete> method (straightforward) -- not tested yet # FIXME
114              
115             =back
116              
117             For basic workflow, see C<t/model/schedule.t>.
118              
119              
120              
121              
122             =head1 EXPORTS
123              
124             This module provides the following exports:
125              
126             =over
127              
128             =item L<get_schedhistory>
129              
130             =back
131              
132             =cut
133              
134 41     41   55189 use Exporter qw( import );
  41         93  
  41         21098  
135             our @EXPORT_OK = qw( get_schedhistory );
136              
137              
138              
139             =head1 METHODS
140              
141              
142             =head2 load_by_eid
143              
144             Class method. Given an EID, and, optionally, a timestamp, attempt to
145             look it up in the database. Generate a status object: if a schedhistory
146             record is found, it will be in the payload and the code will be
147             'DISPATCH_RECORDS_FOUND'.
148              
149             =cut
150              
151             sub load_by_eid {
152 0     0 1   my $self = shift;
153 0           my ( $conn, $eid, $ts ) = validate_pos( @_,
154             { isa => 'DBIx::Connector' },
155             { type => SCALAR }, # EID
156             { type => SCALAR|UNDEF, optional => 1 }, # optional timestamp
157             );
158              
159 0 0         if ( $ts ) {
160 0           return load(
161             conn => $conn,
162             class => __PACKAGE__,
163             sql => $site->SQL_SCHEDHISTORY_SELECT_ARBITRARY,
164             keys => [ $eid, $ts ],
165             );
166             }
167              
168 0           return load(
169             conn => $conn,
170             class => __PACKAGE__,
171             sql => $site->SQL_SCHEDHISTORY_SELECT_CURRENT,
172             keys => [ $eid ],
173             );
174             }
175            
176              
177              
178             =head2 load_by_id
179              
180             Given a shid, load a single schedhistory record.
181              
182             =cut
183              
184             sub load_by_id {
185 0     0 1   my $self = shift;
186 0           my ( $conn, $shid ) = validate_pos( @_,
187             { isa => 'DBIx::Connector' },
188             { type => SCALAR }
189             );
190              
191 0           return load(
192             conn => $conn,
193             class => __PACKAGE__,
194             sql => $site->SQL_SCHEDHISTORY_SELECT_BY_SHID,
195             keys => [ $shid ],
196             );
197             }
198              
199              
200             =head2 load_by_shid
201              
202             Wrapper for load_by_id
203              
204             =cut
205              
206             sub load_by_shid {
207 0     0 1   my $self = shift;
208 0           my ( $conn, $shid ) = validate_pos( @_,
209             { isa => 'DBIx::Connector' },
210             { type => SCALAR }
211             );
212              
213 0           return $self->load_by_id( $conn, $shid );
214             }
215              
216              
217             =head2 insert
218              
219             Instance method. Attempts to INSERT a record into the 'Schedhistory' table.
220             Field values are taken from the object. Returns a status object.
221              
222             =cut
223              
224             sub insert {
225 0     0 1   my $self = shift;
226 0           my ( $context ) = validate_pos( @_, { type => HASHREF } );
227              
228             my $status = cud(
229             conn => $context->{'dbix_conn'},
230 0           eid => $context->{'current'}->{'eid'},
231             object => $self,
232             sql => $site->SQL_SCHEDHISTORY_INSERT,
233             attrs => [ 'eid', 'sid', 'effective', 'remark' ],
234             );
235              
236 0           return $status;
237             }
238              
239              
240             =head2 update
241              
242             Instance method. Updates the record. Returns status object.
243              
244             =cut
245              
246             sub update {
247 0     0 1   my $self = shift;
248 0           my ( $context ) = validate_pos( @_, { type => HASHREF } );
249              
250             my $status = cud(
251             conn => $context->{'dbix_conn'},
252 0           eid => $context->{'current'}->{'eid'},
253             object => $self,
254             sql => $site->SQL_SCHEDHISTORY_UPDATE,
255             attrs => [ 'sid', 'effective', 'remark', 'shid' ],
256             );
257              
258 0           return $status;
259             }
260              
261              
262             =head2 delete
263              
264             Instance method. Deletes the record. Returns status object.
265              
266             =cut
267              
268             sub delete {
269 0     0 1   my $self = shift;
270 0           my ( $context ) = validate_pos( @_, { type => HASHREF } );
271              
272             my $status = cud(
273             conn => $context->{'dbix_conn'},
274 0           eid => $context->{'current'}->{'eid'},
275             object => $self,
276             sql => $site->SQL_SCHEDHISTORY_DELETE,
277             attrs => [ 'shid' ],
278             );
279 0 0         $self->reset( 'shid' => $self->{shid} ) if $status->ok;
280              
281 0           return $status;
282             }
283              
284              
285             =head2 get_schedhistory
286              
287             Takes a PARAMHASH which can have one or more of the properties 'eid', 'nick',
288             and 'tsrange'.
289              
290             At least one of { 'eid', 'nick' } must be specified. If both are specified,
291             the employee is determined according to 'eid'.
292              
293             The function returns the history of schedule changes for that employee
294             over the given tsrange, or the entire history if no tsrange is supplied.
295              
296             The return value will always be an L<App::CELL::Status|status> object.
297              
298             Upon success, the payload will be a reference to an array of C<schedhistory>
299             objects. If nothing is found, the array will be empty. If there is a DBI error,
300             the payload will be undefined.
301              
302             =cut
303              
304             sub get_schedhistory {
305 0     0 1   my $context = shift;
306 0           return get_history( 'sched', $context->{'dbix_conn'}, @_ );
307             }
308              
309              
310              
311             =head1 EXAMPLES
312              
313             In this section, some examples are presented to give an idea of how this
314             module is used.
315              
316              
317             =head2 Sam Wallace joins the firm
318              
319             Let's say Sam's initial schedule is 09:00-17:00, Monday to Friday. To
320             reflect that, the C<schedintvls> table might contain the following intervals
321             for C<< sid = 9 >>
322              
323             '[2014-06-02 09:00, 2014-06-02 17:00)'
324             '[2014-06-03 09:00, 2014-06-03 17:00)'
325             '[2014-06-04 09:00, 2014-06-04 17:00)'
326             '[2014-06-05 09:00, 2014-06-05 17:00)'
327             '[2014-06-06 09:00, 2014-06-06 17:00)'
328              
329             and the C<schedhistory> table would contain a record like this:
330              
331             shid 848 (automatically assigned by PostgreSQL)
332             eid 39 (Sam's Dochazka EID)
333             sid 9
334             effective '2014-06-04 00:00'
335              
336             (This is a straightfoward example.)
337              
338              
339             =head2 Sam goes on night shift
340              
341             A few months later, Sam gets assigned to the night shift. A new
342             C<schedhistory> record is added:
343              
344             shid 1215 (automatically assigned by PostgreSQL)
345             eid 39 (Sam's Dochazka EID)
346             sid 17 (link to Sam's new weekly work schedule)
347             effective '2014-11-17 12:00'
348              
349             And the schedule intervals for C<< sid = 17 >> could be:
350              
351             '[2014-06-02 23:00, 2014-06-03 07:00)'
352             '[2014-06-03 23:00, 2014-06-04 07:00)'
353             '[2014-06-04 23:00, 2014-06-05 07:00)'
354             '[2014-06-05 23:00, 2014-06-06 07:00)'
355             '[2014-06-06 23:00, 2014-06-07 07:00)'
356            
357             (Remember: the date part in this case designates the day of the week)
358              
359              
360              
361              
362             =head1 AUTHOR
363              
364             Nathan Cutler, C<< <presnypreklad@gmail.com> >>
365              
366             =cut
367              
368             1;
369              
370              
371