File Coverage

blib/lib/App/bif/new/project.pm
Criterion Covered Total %
statement 18 103 17.4
branch 0 20 0.0
condition 0 35 0.0
subroutine 6 10 60.0
pod 1 3 33.3
total 25 171 14.6


line stmt bran cond sub pod time code
1             package App::bif::new::project;
2 1     1   2618 use strict;
  1         2  
  1         38  
3 1     1   4 use warnings;
  1         1  
  1         32  
4 1     1   4 use Bif::Mo;
  1         1  
  1         9  
5 1     1   633 use IO::Prompt::Tiny qw/prompt/;
  1         415  
  1         88  
6 1     1   612 use DBIx::ThinSQL qw/ qv sq/;
  1         24720  
  1         9  
7              
8             our $VERSION = '0.1.5_5';
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             },
50 0         0 );
51              
52             $dbw->xdo(
53             update => 'projects',
54             set => { local => 1, },
55             where => { id => $opts->{id} },
56 0         0 );
57              
58             # TODO: unecessary?
59 0 0       0 if ( $dup_pinfo->{default_hub_id} ) {
60             $dbw->xdo(
61             insert_into => 'func_update_project',
62             values => {
63             id => $opts->{id},
64             change_id => $opts->{change_id},
65             hub_id => $dup_pinfo->{default_hub_id},
66             },
67 0         0 );
68             }
69              
70             my @status = $dbw->xhashrefs(
71             select => [ 'ps.status', 'ps.rank', 'p.id AS current_id' ],
72             from => 'project_status ps',
73             left_join => 'projects p',
74             on => 'p.project_status_id = ps.id',
75             where => { 'ps.project_id' => $dup_pinfo->{id} },
76 0         0 order_by => 'ps.rank',
77             );
78              
79 0         0 my $status_id;
80 0         0 foreach my $status (@status) {
81 0         0 my $sid = $dbw->nextval('nodes');
82 0 0       0 $status_id = $sid if $status->{current_id};
83              
84             $dbw->xdo(
85             insert_into => 'func_new_project_status',
86             values => {
87             change_id => $opts->{change_id},
88             id => $sid,
89             project_id => $opts->{id},
90             status => $status->{status},
91             rank => $status->{rank},
92             }
93 0         0 );
94             }
95              
96             $dbw->xdo(
97             insert_into => 'func_update_project',
98             values => {
99             id => $opts->{id},
100             change_id => $opts->{change_id},
101 0         0 project_status_id => $status_id,
102             },
103             );
104              
105             @status = $dbw->xhashrefs(
106             select => [ 'ist.status', 'ist.rank', 'ist.def' ],
107             from => 'issue_status ist',
108             where => { 'ist.project_id' => $dup_pinfo->{id} },
109 0         0 order_by => 'ist.rank',
110             );
111              
112 0         0 foreach my $status (@status) {
113 0         0 my $sid = $dbw->nextval('nodes');
114              
115             $dbw->xdo(
116             insert_into => 'func_new_issue_status',
117             values => {
118             change_id => $opts->{change_id},
119             id => $sid,
120             project_id => $opts->{id},
121             status => $status->{status},
122             rank => $status->{rank},
123             def => $status->{def},
124             }
125 0         0 );
126             }
127              
128             @status = $dbw->xhashrefs(
129             select => [ 'ts.status', 'ts.rank', 'ts.def' ],
130             from => 'task_status ts',
131             where => { 'ts.project_id' => $dup_pinfo->{id} },
132 0         0 order_by => 'ts.rank',
133             );
134              
135 0         0 foreach my $status (@status) {
136 0         0 my $sid = $dbw->nextval('nodes');
137              
138             $dbw->xdo(
139             insert_into => 'func_new_task_status',
140             values => {
141             change_id => $opts->{change_id},
142             id => $sid,
143             project_id => $opts->{id},
144             status => $status->{status},
145             rank => $status->{rank},
146             def => $status->{def},
147             }
148 0         0 );
149             }
150              
151             $self->end_change(
152             id => $opts->{change_id},
153             action_format =>
154             "new project $opts->{path} (%s) --dup $dup_pinfo->{path} (%s)]",
155             action_node_id_1 => $opts->{id},
156             action_node_id_1 => $dup_pinfo->{id},
157             message => $opts->{message},
158 0         0 );
159              
160             }
161 0         0 );
162              
163 0         0 return $self->ok('NewProject');
164             }
165              
166             sub new_project {
167 0     0 0 0 my $self = shift;
168 0   0     0 my $kind = shift || 'project';
169 0         0 my $dbw = $self->dbw;
170 0         0 my $opts = $self->opts;
171              
172             $dbw->xdo(
173             insert_into => 'func_new_project',
174             values => {
175             change_id => $opts->{change_id},
176             id => $opts->{id},
177             parent_id => $opts->{parent_id},
178             name => $opts->{name},
179             title => $opts->{title},
180             },
181 0         0 );
182              
183             $dbw->xdo(
184             update => 'projects',
185             set => {
186             local => 1,
187             },
188             where => { id => $opts->{id} },
189 0         0 );
190              
191 0         0 my @status = $dbw->xhashrefs(
192             select => [ qw/status rank/, ],
193             from => 'default_status',
194             where => { kind => $kind },
195             order_by => 'rank',
196             );
197              
198 0         0 foreach my $status (@status) {
199 0         0 my $sid = $dbw->nextval('nodes');
200              
201             $dbw->xdo(
202             insert_into => 'func_new_project_status',
203             values => {
204             change_id => $opts->{change_id},
205             id => $sid,
206             project_id => $opts->{id},
207             status => $status->{status},
208             rank => $status->{rank},
209             }
210 0         0 );
211             }
212              
213             $dbw->xdo(
214             insert_into =>
215             [ 'func_update_project', 'id', 'change_id', 'project_status_id', ],
216             select =>
217             [ qv( $opts->{id} ), qv( $opts->{change_id} ), 'project_status.id', ],
218             from => 'default_status',
219             inner_join => 'project_status',
220             on => {
221             project_id => $opts->{id},
222             'default_status.status' => \'project_status.status',
223             },
224 0         0 where => do {
225              
226 0 0       0 if ( $opts->{status} ) {
227             {
228             'default_status.kind' => 'project',
229             'default_status.status' => $opts->{status},
230 0         0 };
231             }
232             else {
233             {
234 0         0 'default_status.kind' => 'project',
235             'default_status.def' => 1,
236             };
237             }
238             },
239             );
240              
241 0         0 @status = $dbw->xhashrefs(
242             select => [ qw/status rank def/, ],
243             from => 'default_status',
244             where => { kind => 'issue' },
245             order_by => 'rank',
246             );
247              
248 0         0 foreach my $status (@status) {
249 0         0 my $sid = $dbw->nextval('nodes');
250             $dbw->xdo(
251             insert_into => 'func_new_issue_status',
252             values => {
253             change_id => $opts->{change_id},
254             id => $sid,
255             project_id => $opts->{id},
256             status => $status->{status},
257             rank => $status->{rank},
258             def => $status->{def},
259             }
260 0         0 );
261             }
262              
263 0         0 @status = $dbw->xhashrefs(
264             select => [ qw/status rank def/, ],
265             from => 'default_status',
266             where => { kind => 'task' },
267             order_by => 'rank',
268             );
269              
270 0         0 foreach my $status (@status) {
271 0         0 my $sid = $dbw->nextval('nodes');
272             $dbw->xdo(
273             insert_into => 'func_new_task_status',
274             values => {
275             change_id => $opts->{change_id},
276             id => $sid,
277             project_id => $opts->{id},
278             status => $status->{status},
279             rank => $status->{rank},
280             def => $status->{def},
281             }
282 0         0 );
283             }
284              
285             }
286              
287             sub run {
288 1     1 1 2 my $self = shift;
289 1         4 my $opts = $self->opts;
290 1         6 my $dbw = $self->dbw;
291              
292             $dbw->txn(
293             sub {
294 0     0     my $start = time;
295 0           $self->stop_work(
296             stop => $start,
297             save => 1,
298             );
299              
300 0   0       $opts->{path} ||= prompt( 'Path:', '' )
      0        
301             || return $self->err( 'ProjectPathRequired',
302             'project path is required' );
303              
304 0           my @parts = split( '/', $opts->{path} );
305 0           $opts->{name} = pop @parts;
306              
307 0           my $parent = join( '/', @parts );
308 0           my @parents = $dbw->get_projects($parent);
309              
310 0 0         if ( @parents > 1 ) {
    0          
    0          
311             return $self->err( 'ParentProjectAmbiguous',
312             "parent path is ambiguous:\n "
313 0           . join( "\n ", map { $_->{path} } @parents ) );
  0            
314             }
315             elsif (@parents) {
316 0           $opts->{parent_id} = $parents[0]->{id};
317 0           @parts = split( '/', $parents[0]->{path} );
318             }
319             elsif (@parts) {
320 0           return $self->err( 'HubNotFound',
321             "hub or parent project not found: " . join( '/', @parts ) );
322             }
323              
324 0           my @x = $dbw->get_projects( $opts->{path} );
325 0 0         return $self->err( 'ProjectExists',
326             "project exists: $opts->{path}" )
327             if @x;
328              
329 0           my $where;
330 0 0         if ( $opts->{status} ) {
331             return $self->err( 'InvalidStatus',
332             'unknown status: ' . $opts->{status} )
333             unless $dbw->xarrayref(
334             select => 'count(*)',
335             from => 'default_status',
336             where => {
337             kind => 'project',
338             status => $opts->{status},
339             }
340 0 0         );
341             }
342              
343 0 0         return dup($self) if $opts->{dup};
344              
345 0   0       $opts->{title} ||= prompt( 'Title:', '' )
      0        
346             || return $self->err( 'ProjectTitleequired',
347             'project title is required' );
348              
349 0   0       $opts->{message} ||= $self->prompt_edit( opts => $self );
350 0   0       $opts->{lang} ||= 'en';
351 0   0       $opts->{id} ||= $dbw->nextval('nodes');
352 0   0       $opts->{change_id} ||= $self->new_change;
353              
354 0           $self->new_project;
355              
356             $self->start_work(
357             node_id => $opts->{id},
358 0           start => $start,
359             start_comment => "new project",
360             billable => 1,
361             );
362              
363 0           $self->stop_work(
364             stop => time,
365             restore => 1,
366             );
367              
368             $self->save_work(
369             node_id => $opts->{id},
370             change_id => $opts->{change_id}
371 0           );
372              
373             $self->end_change(
374             id => $opts->{change_id},
375             message => $opts->{message},
376             action_format => "new project $opts->{path} (%s)",
377             action_node_id_1 => $opts->{id},
378 0           );
379              
380             }
381 0           );
382              
383 0           return $self->ok('NewProject');
384             }
385              
386             1;
387             __END__