File Coverage

blib/lib/App/bif/new/project.pm
Criterion Covered Total %
statement 18 88 20.4
branch 0 20 0.0
condition 0 49 0.0
subroutine 6 10 60.0
pod 1 3 33.3
total 25 170 14.7


line stmt bran cond sub pod time code
1             package App::bif::new::project;
2 1     1   3333 use strict;
  1         4  
  1         26  
3 1     1   4 use warnings;
  1         2  
  1         33  
4 1     1   5 use Bif::Mo;
  1         1  
  1         6  
5 1     1   685 use IO::Prompt::Tiny qw/prompt/;
  1         529  
  1         68  
6 1     1   794 use DBIx::ThinSQL qw/ case qv sq/;
  1         27151  
  1         7  
7              
8             our $VERSION = '0.1.5_7';
9             extends 'App::bif';
10              
11             sub dup {
12 0     0 0 0 my $self = shift;
13 0         0 my $opts = $self->opts;
14 0         0 my $dbw = $self->dbw;
15              
16 0         0 my $path = $opts->{path};
17 0         0 my $dup_pinfo = $self->get_project( $opts->{dup} );
18              
19             $opts->{title} ||= $dbw->xval(
20             select => 'p.title',
21             from => 'projects p',
22             where => { 'p.id' => $dup_pinfo->{id} },
23 0   0     0 );
24              
25             my $src = $dbw->xval(
26             select => 'n.path',
27             from => 'projects p',
28             inner_join => 'nodes n',
29             on => 'n.id = p.id',
30             where => { 'p.id' => $dup_pinfo->{id} },
31 0         0 );
32              
33             $opts->{message} ||=
34 0   0     0 $self->prompt_edit( txt => "[ dup: $src ]\n", opts => $self );
35              
36             $dbw->txn(
37             sub {
38 0   0 0   0 $opts->{id} ||= $dbw->nextval('nodes');
39 0   0     0 $opts->{change_id} ||= $self->new_change;
40              
41             $dbw->xdo(
42             insert_into => 'func_new_project',
43             values => {
44             change_id => $opts->{change_id},
45             id => $opts->{id},
46             parent_id => $opts->{parent_id},
47             name => $opts->{name},
48             title => $opts->{title},
49 0   0     0 bill => $opts->{bill} // 1,
50             },
51             );
52              
53             $dbw->xdo(
54             update => 'projects',
55             set => { local => 1, },
56             where => { id => $opts->{id} },
57 0         0 );
58              
59             # TODO: unecessary?
60 0 0       0 if ( $dup_pinfo->{default_hub_id} ) {
61             $dbw->xdo(
62             insert_into => 'func_update_project',
63             values => {
64             id => $opts->{id},
65             change_id => $opts->{change_id},
66             hub_id => $dup_pinfo->{default_hub_id},
67             },
68 0         0 );
69             }
70              
71             my @status = $dbw->xhashrefs(
72             select => [ 'ps.status', 'ps.rank', 'p.id AS current_id' ],
73             from => 'project_status ps',
74             left_join => 'projects p',
75             on => 'p.project_status_id = ps.id',
76             where => { 'ps.project_id' => $dup_pinfo->{id} },
77 0         0 order_by => 'ps.rank',
78             );
79              
80 0         0 my $status_id;
81 0         0 foreach my $status (@status) {
82 0         0 my $sid = $dbw->nextval('nodes');
83 0 0       0 $status_id = $sid if $status->{current_id};
84              
85             $dbw->xdo(
86             insert_into => 'func_new_project_status',
87             values => {
88             change_id => $opts->{change_id},
89             id => $sid,
90             project_id => $opts->{id},
91             status => $status->{status},
92             rank => $status->{rank},
93 0   0     0 bill => $opts->{bill} // 1,
94             }
95             );
96             }
97              
98             $dbw->xdo(
99             insert_into => 'func_update_project',
100             values => {
101             id => $opts->{id},
102             change_id => $opts->{change_id},
103 0         0 project_status_id => $status_id,
104             },
105             );
106              
107             $dbw->xdo(
108             insert_into => [
109             'func_new_topic_status',
110             qw/change_id id project_id tkind status rank def
111             bill/,
112             ],
113             select => [
114             qv( $opts->{change_id} ), 'nextval("nodes")',
115             qv( $opts->{id} ), 'ts.tkind',
116             'ts.status', 'ts.rank',
117             'ts.def', qv( $opts->{bill} // 1 ),
118             ],
119             from => 'topic_status ts',
120             where => { 'ts.project_id' => $dup_pinfo->{id} },
121 0   0     0 order_by => [qw/ts.tkind ts.rank/]
122             );
123              
124             $self->end_change(
125             id => $opts->{change_id},
126             action_format =>
127             "new project $opts->{path} (%s) --dup $dup_pinfo->{path} (%s)]",
128             action_node_id_1 => $opts->{id},
129             action_node_id_1 => $dup_pinfo->{id},
130             message => $opts->{message},
131 0         0 );
132              
133             }
134 0         0 );
135              
136 0         0 return $self->ok('NewProject');
137             }
138              
139             sub new_project {
140 0     0 0 0 my $self = shift;
141 0   0     0 my $kind = shift || 'project';
142 0         0 my $dbw = $self->dbw;
143 0         0 my $opts = $self->opts;
144              
145             $dbw->xdo(
146             insert_into => 'func_new_project',
147             values => {
148             change_id => $opts->{change_id},
149             id => $opts->{id},
150             parent_id => $opts->{parent_id},
151             name => $opts->{name},
152             title => $opts->{title},
153 0   0     0 bill => $opts->{bill} // 1,
154             },
155             );
156              
157             $dbw->xdo(
158             update => 'projects',
159             set => {
160             local => 1,
161             },
162             where => { id => $opts->{id} },
163 0         0 );
164              
165 0         0 my @status = $dbw->xhashrefs(
166             select => [ qw/status rank/, ],
167             from => 'default_status',
168             where => { kind => $kind },
169             order_by => 'rank',
170             );
171              
172 0         0 foreach my $status (@status) {
173 0         0 my $sid = $dbw->nextval('nodes');
174              
175             $dbw->xdo(
176             insert_into => 'func_new_project_status',
177             values => {
178             change_id => $opts->{change_id},
179             id => $sid,
180             project_id => $opts->{id},
181             status => $status->{status},
182             rank => $status->{rank},
183 0   0     0 bill => $opts->{bill} // 1,
184             }
185             );
186             }
187              
188             $dbw->xdo(
189             insert_into =>
190             [ 'func_update_project', 'id', 'change_id', 'project_status_id', ],
191             select =>
192             [ qv( $opts->{id} ), qv( $opts->{change_id} ), 'project_status.id', ],
193             from => 'default_status',
194             inner_join => 'project_status',
195             on => {
196             project_id => $opts->{id},
197             'default_status.status' => \'project_status.status',
198             },
199 0         0 where => do {
200              
201 0 0       0 if ( $opts->{status} ) {
202             {
203             'default_status.kind' => 'project',
204             'default_status.status' => $opts->{status},
205 0         0 };
206             }
207             else {
208             {
209 0         0 'default_status.kind' => 'project',
210             'default_status.def' => 1,
211             };
212             }
213             },
214             );
215              
216             $dbw->xdo(
217             insert_into => [
218             'func_new_topic_status',
219             qw/change_id id project_id tkind status rank def bill/,
220             ],
221             select => [
222             qv( $opts->{change_id} ),
223             'nextval("nodes")',
224             qv( $opts->{id} ),
225             'ds.kind',
226             'ds.status',
227             'ds.rank',
228             case (
229             when => 'ds.def',
230             then => 1,
231             else => 0,
232             )->as('def'),
233 0   0     0 qv( $opts->{bill} // 1 ),
234             ],
235             from => 'default_status ds',
236             where => { 'ds.kind !' => [ 'project', 'hub' ] },
237             order_by => [qw/ds.kind ds.rank/]
238             );
239             }
240              
241             sub run {
242 1     1 1 2 my $self = shift;
243 1         5 my $opts = $self->opts;
244 1         7 my $dbw = $self->dbw;
245              
246             $dbw->txn(
247             sub {
248 0     0     $self->pause_work;
249 0           my $start = time;
250              
251             # $self->stop_work(
252             # stop => $start,
253             # save => 1,
254             # );
255              
256 0   0       $opts->{path} ||= prompt( 'Path:', '' )
      0        
257             || return $self->err( 'ProjectPathRequired',
258             'project path is required' );
259              
260 0           my @parts = split( '/', $opts->{path} );
261 0           $opts->{name} = pop @parts;
262              
263 0           my $parent = join( '/', @parts );
264 0           my @parents = $dbw->get_projects($parent);
265              
266 0 0         if ( @parents > 1 ) {
    0          
    0          
267             return $self->err( 'ParentProjectAmbiguous',
268             "parent path is ambiguous:\n "
269 0           . join( "\n ", map { $_->{path} } @parents ) );
  0            
270             }
271             elsif (@parents) {
272 0           $opts->{parent_id} = $parents[0]->{id};
273 0           @parts = split( '/', $parents[0]->{path} );
274             }
275             elsif (@parts) {
276 0           return $self->err( 'HubNotFound',
277             "hub or parent project not found: " . join( '/', @parts ) );
278             }
279              
280 0           my @x = $dbw->get_projects( $opts->{path} );
281 0 0         return $self->err( 'ProjectExists',
282             "project exists: $opts->{path}" )
283             if @x;
284              
285 0           my $where;
286 0 0         if ( $opts->{status} ) {
287             return $self->err( 'InvalidStatus',
288             'unknown status: ' . $opts->{status} )
289             unless $dbw->xarrayref(
290             select => 'count(*)',
291             from => 'default_status',
292             where => {
293             kind => 'project',
294             status => $opts->{status},
295             }
296 0 0         );
297             }
298              
299 0 0         return dup($self) if $opts->{dup};
300              
301 0   0       $opts->{title} ||= prompt( 'Title:', '' )
      0        
302             || return $self->err( 'ProjectTitleequired',
303             'project title is required' );
304              
305 0   0       $opts->{message} ||= $self->prompt_edit( opts => $self );
306 0   0       $opts->{lang} ||= 'en';
307 0   0       $opts->{change_id} ||= $self->new_change;
308 0   0       $opts->{id} ||= $dbw->nextval('nodes');
309              
310 0           $self->new_project;
311              
312             $self->save_new_work(
313             bill => $opts->{bill} // 1,
314             change_id => $opts->{change_id},
315             node_id => $opts->{id},
316 0   0       start => $start,
317             stop => time,
318             );
319              
320             $self->end_change(
321             id => $opts->{change_id},
322             message => $opts->{message},
323 0           action_format => "new project $opts->{path}",
324             );
325              
326 0           $self->resume_work;
327             }
328 0           );
329              
330 0           return $self->ok('NewProject');
331             }
332              
333             1;
334             __END__