Annotation of loncom/interface/lonrequestcourse.pm, revision 1.10
1.1 raeburn 1: # The LearningOnline Network
2: # Request a course
3: #
1.10 ! raeburn 4: # $Id: lonrequestcourse.pm,v 1.9 2009/08/12 02:04:38 raeburn Exp $
1.1 raeburn 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: ###
29:
30: =head1 NAME
31:
32: Apache::lonrequestcourse.pm
33:
34: =head1 SYNOPSIS
35:
36: Allows users to request creation of new courses.
37:
38: This is part of the LearningOnline Network with CAPA project
39: described at http://www.lon-capa.org.
40:
41: =head1 SUBROUTINES
42:
43: =over
44:
45: =item handler()
46:
47: =back
48:
49: =cut
50:
51: package Apache::lonrequestcourse;
52:
53: use strict;
54: use Apache::Constants qw(:common :http);
55: use Apache::lonnet;
56: use Apache::loncommon;
57: use Apache::lonlocal;
1.8 raeburn 58: use Apache::loncoursequeueadmin;
1.4 raeburn 59: use LONCAPA qw(:DEFAULT :match);
1.1 raeburn 60:
61: sub handler {
62: my ($r) = @_;
63: if ($r->header_only) {
64: &Apache::loncommon::content_type($r,'text/html');
65: $r->send_http_header;
66: return OK;
67: }
68: &Apache::loncommon::content_type($r,'text/html');
69: $r->send_http_header;
70:
1.2 raeburn 71: &Apache::lonhtmlcommon::clear_breadcrumbs();
72: my $dom = &get_course_dom();
1.1 raeburn 73: my $action = $env{'form.action'};
74: my $state = $env{'form.state'};
1.2 raeburn 75:
76: my %stored;
77: my $jscript;
78: if ((defined($state)) && (defined($action))) {
79: my %elements = &form_elements($dom);
80: if (($action eq 'view') && ($state ne 'crstype')) {
81: if (defined($env{'form.request_id'})) {
82: %stored = &retrieve_settings($dom,$env{'form.request_id'});
83: }
84: }
85: my $elementsref = {};
86: if (ref($elements{$action}) eq 'HASH') {
87: if (ref($elements{$action}{$state}) eq 'HASH') {
88: $elementsref = $elements{$action}{$state};
89: }
90: }
91: $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored);
92: }
93:
94: if ($state eq 'personnel') {
95: $jscript .= "\n".&Apache::loncommon::userbrowser_javascript();
96: }
97:
98: my $loaditems = &onload_action($action,$state);
99:
100: my %states;
101: $states{'view'} = ['pick_request','details','review','process'];
102: $states{'log'} = ['filter','display'];
103: $states{'new'} = ['courseinfo','enrollment','personnel','review','process'];
104: if (($action eq 'new') && ($env{'form.crstype'} eq 'official')) {
105: unless ($env{'form.state'} eq 'crstype') {
106: unshift (@{$states{'new'}},'codepick');
107: }
108: }
109:
110: foreach my $key (keys(%states)) {
111: if (ref($states{$key}) eq 'ARRAY') {
112: unshift (@{$states{$key}},'crstype');
113: }
114: }
115:
1.3 raeburn 116: my %trail = (
1.10 ! raeburn 117: crstype => 'Course Request Action',
! 118: codepick => 'Category',
! 119: courseinfo => 'Description',
! 120: enrollment => 'Enrollment',
! 121: personnel => 'Personnel',
! 122: review => 'Review',
! 123: process => 'Result',
! 124: pick_request => 'Display Summary',
1.3 raeburn 125: );
126:
1.2 raeburn 127: my $page = 0;
1.3 raeburn 128: my $crumb;
1.2 raeburn 129: if (defined($action)) {
130: my $done = 0;
131: my $i=0;
132: if (ref($states{$action}) eq 'ARRAY') {
133: while ($i<@{$states{$action}} && !$done) {
134: if ($states{$action}[$i] eq $state) {
135: $page = $i;
136: $done = 1;
137: }
138: $i++;
139: }
140: }
1.3 raeburn 141: for (my $i=0; $i<@{$states{$action}}; $i++) {
142: if ($state eq $states{$action}[$i]) {
143: &Apache::lonhtmlcommon::add_breadcrumb(
144: {text=>"$trail{$state}"});
145: $crumb = &Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests');
146: last;
147: } else {
148: if (($state eq 'process') && ($i > 0)) {
149: &Apache::lonhtmlcommon::add_breadcrumb(
150: {href=>"javascript:backPage(document.requestcrs,'$states{$action}[0]')",
151: text=>"$trail{$states{$action}[$i]}"});
152: } else {
153: &Apache::lonhtmlcommon::add_breadcrumb(
154: {href=>"javascript:backPage(document.requestcrs,'$states{$action}[$i]')",
155: text=>"$trail{$states{$action}[$i]}"});
156: }
157: }
158: }
159: } else {
160: &Apache::lonhtmlcommon::add_breadcrumb(
161: {text=>'Pick Action'});
162: $crumb = &Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests');
1.2 raeburn 163: }
164:
1.1 raeburn 165: my %can_request;
166: my $canreq = &check_can_request($dom,\%can_request);
167: if ($action eq 'new') {
168: if ($canreq) {
169: if ($state eq 'crstype') {
1.3 raeburn 170: &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems,
171: $crumb);
1.1 raeburn 172: } else {
1.2 raeburn 173: &request_administration($r,$action,$state,$page,\%states,$dom,$jscript,
1.3 raeburn 174: $loaditems,$crumb);
1.1 raeburn 175: }
176: } else {
1.3 raeburn 177: $r->print(&header('Course Requests').$crumb.
1.1 raeburn 178: '<div class="LC_warning">'.
179: &mt('You do not have privileges to request creation of courses.').
1.2 raeburn 180: '</div>'.&Apache::loncommon::end_page());
1.1 raeburn 181: }
182: } elsif ($action eq 'view') {
1.10 ! raeburn 183: if ($state eq 'crstype') {
! 184: &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb);
! 185: } elsif ($state eq 'pick_request') {
! 186: $r->print(&print_request_status($dom,$crumb));
! 187: }
1.1 raeburn 188: } elsif ($action eq 'log') {
1.3 raeburn 189: &print_request_logs($jscript,$loaditems,$crumb);
1.1 raeburn 190: } else {
1.3 raeburn 191: &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb);
1.1 raeburn 192: }
193: return OK;
194: }
195:
1.2 raeburn 196: sub header {
197: my ($bodytitle,$jscript,$loaditems,$jsextra) = @_;
198: if ($jscript) {
1.6 raeburn 199: $jscript = '<script type="text/javascript">'."\n".
200: '// <![CDATA['."\n".
201: $jscript."\n".'// ]]>'."\n".'</script>'."\n";
1.2 raeburn 202: }
203: if ($loaditems) {
1.3 raeburn 204: $loaditems = {'add_entries' => $loaditems,};
205: return &Apache::loncommon::start_page($bodytitle,$jscript.$jsextra,$loaditems);
206: } else {
207: return &Apache::loncommon::start_page($bodytitle,$jscript.$jsextra);
208: }
1.2 raeburn 209: }
210:
211: sub form_elements {
212: my ($dom) = @_;
213: my %elements =
214: (
215: new => {
216: crstype => {
217: crstype => 'selectbox',
218: action => 'selectbox',
219: },
220: courseinfo => {
221: cdescr => 'text',
222: clonecourse => 'text',
223: clonedomain => 'selectbox',
224: datemode => 'radio',
225: dateshift => 'text',
226: },
227: enrollment => {
228: startaccess_month => 'selectbox',
229: startaccess_hour => 'selectbox',
230: endaccess_month => 'selectbox',
231: endaccess_hour => 'selectbox',
232: startaccess_day => 'text',
233: startaccess_year => 'text',
234: startaccess_minute => 'text',
235: startaccess_second => 'text',
236: endaccess_day => 'text',
237: endaccess_year => 'text',
238: endaccess_minute => 'text',
239: endaccess_second => 'text',
240: no_end_date => 'checkbox',
241: },
242: personnel => {
243: persontotal => 'hidden',
244: addperson => 'checkbox',
245: },
246: },
247: view => {
248: crstype => {
249: crstype => 'selectbox',
250: action => 'selectbox',
251: },
252: },
253: );
254: my (@codetitles,%cat_titles,%cat_order,@code_order,$lastitem);
255: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
256: \%cat_order,\@code_order);
257: my $numtitles = scalar(@codetitles);
258: if ($numtitles) {
259: my %extras;
260: $lastitem = pop(@codetitles);
261: $extras{'instcode_'.$lastitem} = 'text';
262: foreach my $item (@codetitles) {
263: $extras{'instcode_'.$item} = 'selectbox';
264: }
265: $elements{'new'}{'codepick'} = \%extras;
266: }
267: if (&Apache::lonnet::auto_run('',$dom)) {
268: my %extras = (
269: sectotal => 'hidden',
270: startenroll_month => 'selectbox',
271: startenroll_hour => 'selectbox',
272: endenroll_month => 'selectbox',
273: endenroll_hour => 'selectbox',
274: startenroll_day => 'text',
275: startenroll_year => 'text',
276: startenroll_minute => 'text',
277: startenroll_second => 'text',
278: endenroll_day => 'text',
279: endenroll_year => 'text',
280: endenroll_minute => 'text',
281: endenroll_second => 'text',
282: crosslisttotal => 'hidden',
283: addcrosslist => 'checkbox',
284: autoadds => 'radio',
285: autodrops => 'radio',
286: );
287: if ($env{'form.sectotal'} > 0) {
288: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
289: $extras{'sec_'.$i} = 'checkbox',
290: $extras{'secnum_'.$i} = 'text',
291: $extras{'loncapasec_'.$i} = 'checkbox',
292: }
293: }
294: my $crosslisttotal = $env{'form.crosslisttotal'};
295: if (!defined($crosslisttotal)) {
296: $crosslisttotal = 1;
297: }
298: if ($crosslisttotal > 0) {
299: for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) {
300: if ($numtitles) {
301: $extras{'crosslist_'.$i.'_'.$lastitem} = 'text';
302: }
303: if (@codetitles > 0) {
304: foreach my $item (@codetitles) {
305: $extras{'crosslist_'.$i.'_'.$item} = 'selectbox';
306: }
307: }
308: $extras{'crosslist_'.$i} = 'checkbox';
309: $extras{'crosslist_'.$i.'_instsec'} = 'text',
310: $extras{'crosslist_'.$i.'_lcsec'} = 'text',
311: }
312: }
313: my %mergedhash = (%{$elements{'new'}{'enrollment'}},%extras);
314: %{$elements{'new'}{'enrollment'}} = %mergedhash;
315: }
316: my %people;
317: my $persontotal = $env{'form.persontotal'};
318: if (!defined($persontotal)) {
319: $persontotal = 1;
320: }
321: for (my $i=0; $i<$persontotal; $i++) {
322: $people{'person_'.$i.'_uname'} = 'text',
323: $people{'person_'.$i.'_dom'} = 'selectbox',
324: $people{'person_'.$i.'_hidedom'} = 'hidden',
325: $people{'person_'.$i.'_first'} = 'text',
326: $people{'person_'.$i.'_last'} = 'text',
327: $people{'person_'.$i.'_email'} = 'text',
328: $people{'person_'.$i.'_role'} = 'selectbox',
329: $people{'person_'.$i.'_sec'} = 'selectbox',
330: $people{'person_'.$i.'_newsec'} = 'text',
331: $people{'person_'.$i.'_sections'} = 'hidden',
332: }
333: my %personnelhash = (%{$elements{'new'}{'personnel'}},%people);
334: %{$elements{'new'}{'personnel'}} = %personnelhash;
335: return %elements;
336: }
337:
338: sub onload_action {
339: my ($action,$state) = @_;
340: my %loaditems;
341: if (($action eq 'new') || ($action eq 'view')) {
342: $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)';
343: }
344: return \%loaditems;
345: }
346:
1.1 raeburn 347: sub check_can_request {
348: my ($dom,$can_request) = @_;
349: my $canreq = 0;
1.4 raeburn 350: my ($types,$typename) = &course_types();
351: if ((ref($can_request) eq 'HASH') && (ref($types) eq 'ARRAY')) {
352: foreach my $type (@{$types}) {
1.1 raeburn 353: if (&Apache::lonnet::usertools_access($env{'user.name'},
354: $env{'user.domain'},
355: $type,undef,'requestcourses')) {
356: $canreq ++;
357: if ($dom eq $env{'user.domain'}) {
358: $can_request->{$type} = 1;
359: }
360: }
361: if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
362: my @curr = split(',',$env{'environment.reqcrsotherdom.'.$type});
363: if (@curr > 0) {
364: $canreq ++;
365: unless ($dom eq $env{'user.domain'}) {
366: if (grep(/^\Q$dom\E$/,@curr)) {
367: $can_request->{$type} = 1;
368: }
369: }
370: }
371: }
372: }
373: }
374: return $canreq;
375: }
376:
1.4 raeburn 377: sub course_types {
378: my @types = ('official','unofficial','community');
379: my %typename = (
380: official => 'Official course',
381: unofficial => 'Unofficial course',
382: community => 'Community',
383: );
384: return (\@types,\%typename);
385: }
386:
387:
1.1 raeburn 388: sub print_main_menu {
1.3 raeburn 389: my ($r,$can_request,$states,$dom,$jscript,$loaditems,$crumb) = @_;
1.4 raeburn 390: my ($types,$typename) = &course_types();
1.1 raeburn 391: my $onchange;
392: unless ($env{'form.interface'} eq 'textual') {
393: $onchange = 1;
394: }
395:
1.2 raeburn 396: my $nextstate_setter = "\n";
397: if (ref($states) eq 'HASH') {
398: foreach my $key (keys(%{$states})) {
399: if (ref($states->{$key}) eq 'ARRAY') {
400: $nextstate_setter .=
401: " if (actionchoice == '$key') {
402: nextstate = '".$states->{$key}[1]."';
403: }
404: ";
405: }
406: }
407: }
1.1 raeburn 408:
1.2 raeburn 409: my $js = <<"END";
1.1 raeburn 410:
1.2 raeburn 411: function nextPage(formname) {
412: var crschoice = document.requestcrs.crstype.value;
413: var actionchoice = document.requestcrs.action.value;
414: if (check_can_request(crschoice,actionchoice) == true) {
415: if ((actionchoice == 'new') && (crschoice == 'official')) {
416: nextstate = 'codepick';
417: } else {
418: $nextstate_setter
419: }
1.1 raeburn 420: formname.state.value= nextstate;
421: formname.submit();
422: }
423: return;
424: }
425:
1.2 raeburn 426: function check_can_request(crschoice,actionchoice) {
1.1 raeburn 427: var official = '';
428: var unofficial = '';
429: var community = '';
430: END
431:
432: foreach my $item (keys(%{$can_request})) {
433: $js .= "
434: $item = 1;
435: ";
436: }
437: my %lt = &Apache::lonlocal::texthash(
438: official => 'You are not permitted to request creation of an official course in this domain.',
439: unofficial => 'You are not permitted to request creation of an unofficial course in this domain.',
440: community => 'You are not permitted to request creation of a community this domain.',
441: all => 'You must choose a specific course type when making a new course request.\\nAll types is not allowed.',
442: );
443: $js .= <<END;
444: if (crschoice == 'official') {
445: if (official != 1) {
446: alert("$lt{'official'}");
447: return false;
448: }
449: } else {
450: if (crschoice == 'unofficial') {
451: if (unofficial != 1) {
452: alert("$lt{'unofficial'}");
453: return false;
454: }
455: } else {
456: if (crschoice == 'community') {
457: if (community != 1) {
458: alert("$lt{'community'}");
459: return false;
460: }
461: } else {
462: if (actionchoice == 'new') {
463: alert("$lt{'all'}");
464: return false;
465: }
466: }
467: }
468: }
469: return true;
470: }
471:
472: END
473:
1.3 raeburn 474: $r->print(&header('Course Requests',$js.$jscript,$loaditems).$crumb.
475: '<div>'.
1.1 raeburn 476: '<form name="domforcourse" method="post" action="/adm/requestcourse">'.
477: &Apache::lonhtmlcommon::start_pick_box().
1.8 raeburn 478: &Apache::lonhtmlcommon::row_title('Course Domain').
1.1 raeburn 479: &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange));
480: if (!$onchange) {
481: $r->print(' <input type="submit" name="godom" value="'.
482: &mt('Change').'" />');
483: }
484: $r->print(&Apache::lonhtmlcommon::row_closure(1).
485: &Apache::lonhtmlcommon::end_pick_box().'</form></div>');
486:
1.2 raeburn 487: my $formname = 'requestcrs';
1.1 raeburn 488: my $nexttext = &mt('Next');
489: $r->print('<div><form name="'.$formname.'" method="post" action="/adm/requestcourse">'.
490: &Apache::lonhtmlcommon::start_pick_box().
491: &Apache::lonhtmlcommon::row_title('Action').'
492: <input type="hidden" name="showdom" value="'.$dom.'" />
493: <select size="1" name="action" >
1.2 raeburn 494: <option value="new">'.&mt('New request').'</option>
1.1 raeburn 495: <option value="view">'.&mt('View/Modify/Cancel pending requests').'</option>
496: <option value="log">'.&mt('View request history').'</option>
497: </select>'.
498: &Apache::lonhtmlcommon::row_closure().
499: &Apache::lonhtmlcommon::row_title('Course Type').'
500: <select size="1" name="crstype">
1.4 raeburn 501: <option value="any">'.&mt('All types').'</option>');
502: if ((ref($types) eq 'ARRAY') && (ref($typename) eq 'HASH')) {
503: foreach my $type (@{$types}) {
504: my $selected = '';
505: if ($type eq 'official') {
506: $selected = ' selected="selected"';
507: }
508: $r->print('<option value="'.$type.'"'.$selected.'>'.$typename->{$type}.
509: '</option>'."\n");
510: }
511: }
512: $r->print('</select>
1.1 raeburn 513: <input type="hidden" name="state" value="crstype" />'.
514: &Apache::lonhtmlcommon::row_closure(1).
515: &Apache::lonhtmlcommon::end_pick_box().'<br />
1.2 raeburn 516: <input type="button" name="next" value="'.$nexttext.'" onclick="javascript:nextPage(document.'.$formname.')" />
1.1 raeburn 517: </form></div>');
518: $r->print(&Apache::loncommon::end_page());
519: return;
520: }
521:
522: sub request_administration {
1.3 raeburn 523: my ($r,$action,$state,$page,$states,$dom,$jscript,$loaditems,$crumb) = @_;
1.2 raeburn 524: my $js;
525: if (($action eq 'new') || ($action eq 'view')) {
526: $js = <<END;
1.1 raeburn 527:
528: function nextPage(formname,nextstate) {
529: formname.state.value= nextstate;
530: formname.submit();
531: }
532: function backPage(formname,prevstate) {
533: formname.state.value = prevstate;
534: formname.submit();
535: }
536:
537: END
1.2 raeburn 538: }
539: if ($action eq 'new') {
540: my $jsextra;
1.1 raeburn 541: unless (($state eq 'review') || ($state eq 'process')) {
1.2 raeburn 542: $jsextra = "\n".&Apache::loncommon::coursebrowser_javascript($dom);
1.1 raeburn 543: }
1.3 raeburn 544: $r->print(&header('Request a course',$js.$jscript,$loaditems,$jsextra).$crumb);
1.8 raeburn 545: &print_request_form($r,$action,$state,$page,$states,$dom);
1.2 raeburn 546: } elsif ($action eq 'view') {
1.3 raeburn 547: $r->print(&header('Manage course requests',$js.$jscript,$loaditems).$crumb);
1.1 raeburn 548: } elsif ($action eq 'log') {
1.3 raeburn 549: $r->print(&coursereq_log('View request log',$jscript,$loaditems).$crumb);
1.1 raeburn 550: }
1.2 raeburn 551: $r->print(&Apache::loncommon::end_page());
1.1 raeburn 552: return;
553: }
554:
555: sub print_request_form {
1.2 raeburn 556: my ($r,$action,$state,$page,$states,$dom) = @_;
1.1 raeburn 557: my $formname = 'requestcrs';
1.2 raeburn 558: my ($next,$prev,$message,$output,$codepicker,$crstype);
559: $prev = $states->{$action}[$page-1];
560: $next = $states->{$action}[$page+1];
1.4 raeburn 561: my %navtxt = &Apache::lonlocal::texthash (
1.10 ! raeburn 562: prev => 'Back',
1.4 raeburn 563: next => 'Next',
564: );
1.2 raeburn 565: $crstype = $env{'form.crstype'};
1.1 raeburn 566: $r->print('<form name="'.$formname.'" method="post" action="/adm/requestcourse">');
1.2 raeburn 567: my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk);
1.1 raeburn 568: if ($crstype eq 'official') {
1.2 raeburn 569: if ($env{'form.instcode'} ne '') {
570: $instcode = $env{'form.instcode'};
571: }
572: }
573: if ($prev eq 'codepick') {
1.4 raeburn 574: if ($crstype eq 'official') {
575: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
576: \%cat_order,\@code_order);
577: }
1.2 raeburn 578: if (@code_order > 0) {
579: my $message;
580: if ($instcode eq '') {
1.1 raeburn 581: foreach my $item (@code_order) {
1.2 raeburn 582: $instcode .= $env{'form.instcode_'.$item};
1.1 raeburn 583: }
1.2 raeburn 584: $r->print('<input type="hidden" name="instcode" value="'.$instcode.'" />'."\n");
1.1 raeburn 585: }
586: if ($instcode ne '') {
1.2 raeburn 587: $code_chk = &Apache::lonnet::auto_validate_instcode('',$dom,$instcode);
1.1 raeburn 588: if ($code_chk eq 'ok') {
589: $message = '<div class="LC_info">'.
590: &mt('The chosen course category [_1] is valid.','<b>'.
1.2 raeburn 591: $instcode.'</b>').'</div>';
1.1 raeburn 592: } else {
593: $message = '<div class="LC_warning">'.
594: &mt('No course was found matching your choice of institutional course category.');
595: if ($code_chk ne '') {
596: $message .= '<br />'.$code_chk;
597: }
598: $message .= '</div>';
599: }
1.2 raeburn 600: } else {
601: $message = '<div class="LC_warning">'.
602: &mt('No course was found matching your choice of institutional course category.');
1.1 raeburn 603: }
1.2 raeburn 604: unless ($code_chk eq 'ok') {
605: $prev = 'crstype';
606: }
607: $r->print($message);
1.1 raeburn 608: }
1.2 raeburn 609: }
610: if ($prev eq 'crstype') {
1.4 raeburn 611: if ($crstype eq 'official') {
612: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
613: \%cat_order,\@code_order);
614: }
1.2 raeburn 615: if (@code_order > 0) {
1.1 raeburn 616: $codepicker = &coursecode_form($dom,'instcode',\@codetitles,
617: \%cat_titles,\%cat_order);
1.2 raeburn 618: if ($codepicker) {
619: $r->print('<div>'.&Apache::lonhtmlcommon::start_pick_box().$codepicker.
620: &Apache::lonhtmlcommon::end_pick_box().'</div>');
621: } else {
622: $r->print(&courseinfo_form($dom,$formname,$crstype));
623: }
624: } else {
625: $r->print(&courseinfo_form($dom,$formname,$crstype));
1.1 raeburn 626: }
1.2 raeburn 627: } elsif ($prev eq 'codepick') {
628: $r->print(&courseinfo_form($dom,$formname,$crstype));
629: } elsif ($state eq 'enrollment') {
1.4 raeburn 630: if ($crstype eq 'official') {
631: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
632: \%cat_order,\@code_order);
633: }
1.2 raeburn 634: $r->print(&print_enrollment_menu($formname,$instcode,$dom,\@codetitles,
635: \%cat_titles,\%cat_order,\@code_order));
636: } elsif ($state eq 'personnel') {
1.8 raeburn 637: $r->print(&print_personnel_menu($dom,$formname,$crstype));
1.4 raeburn 638: } elsif ($state eq 'review') {
639: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
640: \%cat_order,\@code_order);
641: $r->print(&print_review($formname,$dom,\@codetitles,\%cat_titles,\%cat_order,
642: \@code_order));
643: $navtxt{'next'} = &mt('Submit course request');
1.10 ! raeburn 644: } elsif ($state eq 'process') {
! 645: if ($crstype eq 'official') {
! 646: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
! 647: \%cat_order,\@code_order);
! 648: }
! 649: my $result = &print_request_outcome($dom,\@codetitles,\@code_order);
1.1 raeburn 650: }
1.2 raeburn 651: my @excluded = ('counter');
652: my %elements = &form_elements($dom);
653: if (ref($states) eq 'HASH') {
654: if (ref($states->{$action}) eq 'ARRAY') {
655: my @items = @{$states->{$action}};
656: my $numitems = scalar(@items);
657: if ($numitems) {
658: for (my $i=$numitems-1; $i>=0; $i--) {
659: if (ref($elements{$action}) eq 'HASH') {
660: if (ref($elements{$action}{$items[$i]}) eq 'HASH') {
661: foreach my $key (keys(%{$elements{$action}{$items[$i]}})) {
662: push(@excluded,$key);
663: }
664: }
665: }
666: last if ($items[$i] eq $state);
667: }
668: }
669: }
670: }
671: if (grep(/^instcode_/,@excluded)) {
672: push(@excluded,'instcode');
1.1 raeburn 673: }
1.2 raeburn 674: $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).'</form>');
1.4 raeburn 675: &display_navbuttons($r,$formname,$prev,$navtxt{'prev'},$next,$navtxt{'next'});
1.1 raeburn 676: return;
677: }
678:
1.2 raeburn 679: sub print_enrollment_menu {
680: my ($formname,$instcode,$dom,$codetitles,$cat_titles,$cat_order,$code_order) =@_;
681: my ($sections,$autoenroll,$access_dates);
682: my $starttime = time;
683: my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
684:
685: my %accesstitles = (
686: 'start' => 'Default start access',
687: 'end' => 'Default end accss',
688: );
689: my %enrolltitles = (
690: 'start' => 'Start auto-enrollment',
691: 'end' => 'End auto-enrollment',
692: );
693: if ($env{'form.crstype'} eq 'official') {
694: if (&Apache::lonnet::auto_run('',$dom)) {
695: my ($section_form,$crosslist_form,$autoenroll_form);
696: $section_form = &inst_section_selector($dom,$instcode);
697: my $crosslisttotal = $env{'form.crosslisttotal'};
698: if (!defined($crosslisttotal)) {
699: $crosslisttotal = 1;
700: }
701: if ($env{'form.addcrosslist'}) {
702: $crosslisttotal ++;
703: }
704: for (my $i=0; $i<$crosslisttotal; $i++) {
705: $crosslist_form .= &coursecode_form($dom,'crosslist',$codetitles,
706: $cat_titles,$cat_order,$i);
707: }
708: if ($crosslist_form) {
709: $crosslist_form .=
710: &Apache::lonhtmlcommon::row_title(&mt('Add another?')).
711: '<input name="crosslisttotal" type="hidden" value="'.$crosslisttotal.'" />'.
712: '<input name="addcrosslist" type="checkbox" value="'.$crosslisttotal.'"'.
713: ' onclick="javascript:nextPage(document.'.$formname.",'".$env{'form.state'}.
714: "'".');" />'.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1);
715: }
716: if ($section_form || $crosslist_form) {
717: $sections = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
718: $section_form.$crosslist_form.
719: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
720: }
721: $autoenroll_form =
722: &Apache::lonhtmlcommon::row_title(&mt('Add registered students automatically')).
723: '<span class="LC_nobreak"><label>'.
724: '<input type="radio" name="autoadds" value="1">'.
725: &mt('Yes').'</label>'.(' 'x3).'<label>'.
726: '<input type="radio" name="autoadds" value="0" checked="checked">'.
727: &mt('No').'</label></span>'.
728: &Apache::lonhtmlcommon::row_closure().
729: &Apache::lonhtmlcommon::row_title(&mt('Drop unregistered students automatically')).
730: '<span class="LC_nobreak"><label>'.
731: '<input type="radio" name="autodrops" value="1">'.
732: &mt('Yes').'</label>'.(' 'x3).'<label>'.
733: '<input type="radio" name="autodrops" value="0" checked="checked">'.
734: &mt('No').'</label></span>'.
735: &Apache::lonhtmlcommon::row_closure().
736: &date_setting_table($starttime,$endtime,$formname,'enroll',%enrolltitles);
737: if ($autoenroll_form) {
738: $autoenroll = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
739: $autoenroll_form.
740: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
741: }
742: }
743: }
744: my $access_dates_form =
745: &date_setting_table($starttime,$endtime,$formname,'access',%accesstitles);
746: if ($access_dates_form) {
747: $access_dates = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
748: $access_dates_form.
749: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
750: }
751: return $sections.$autoenroll.$access_dates;
752: }
753:
1.1 raeburn 754: sub inst_section_selector {
1.2 raeburn 755: my ($dom,$instcode) = @_;
756: my @sections = &Apache::lonnet::auto_get_sections(undef,$dom,$instcode);
757: my $sectotal = scalar(@sections);
1.1 raeburn 758: my $output;
1.2 raeburn 759: if ($sectotal) {
760: $output .= &Apache::lonhtmlcommon::row_title('Sections').
761: &Apache::loncommon::start_data_table().
762: &Apache::loncommon::start_data_table_row().
763: '<th>'.&mt('Include?').'<input type="hidden" name="sectotal" '.
764: 'value="'.$sectotal.'"</th>'.
765: '<th>'.&mt('Institutional Section').'</th>'.
766: '<th>'.&mt('LON-CAPA section').'</th>'.
767: &Apache::loncommon::end_data_table_row();
768: for (my $i=0; $i<@sections; $i++) {
1.1 raeburn 769: my $colflag = $i%2;
770: $output .= &Apache::loncommon::start_data_table_row().
1.2 raeburn 771: '<td><input type="checkbox" name="sec_'.$i.
772: '" checked="checked" /></td>'.
773: '<td>'.$sections[$i].
1.1 raeburn 774: '<input type="hidden" name="secnum_'.$i.'" value="'.
1.2 raeburn 775: $sections[$i].'" /></td>'.
1.1 raeburn 776: '<td><input type="text" size="10" name="loncapasec_'.$i.
1.2 raeburn 777: '" value="'.$sections[$i].'" /></td>'.
1.1 raeburn 778: &Apache::loncommon::end_data_table_row();
779: }
1.2 raeburn 780: $output .= &Apache::loncommon::end_data_table().
781: &Apache::lonhtmlcommon::row_closure();
1.1 raeburn 782: }
783: return $output;
784: }
785:
1.2 raeburn 786: sub date_setting_table {
787: my ($starttime,$endtime,$formname,$suffix,%datetitles) = @_;
788: my ($perpetual,$table);
789: my $startform = &Apache::lonhtmlcommon::date_setter($formname,'start'.$suffix,
790: $starttime,'','','',1,'','','',1);
791: my $endform = &Apache::lonhtmlcommon::date_setter($formname,'end'.$suffix,
792: $endtime,'','','',1,'','','',1);
793: if ($suffix eq 'access') {
794: $perpetual = ' <span class="LC_nobreak"><label>'.
795: '<input type="checkbox" name="no_end_date" />'.
796: &mt('No end date').'</label></span>';
797: }
798: $table = &Apache::lonhtmlcommon::row_title($datetitles{'start'}).
799: $startform.
800: &Apache::lonhtmlcommon::row_closure().
801: &Apache::lonhtmlcommon::row_title($datetitles{'end'}).
802: $endform.$perpetual.
803: &Apache::lonhtmlcommon::row_closure(1);
804: return $table;
805: }
806:
807: sub print_personnel_menu {
1.8 raeburn 808: my ($dom,$formname,$crstype) = @_;
1.2 raeburn 809: my $output = '<div>'.&Apache::lonhtmlcommon::start_pick_box();
810: my $persontotal = $env{'form.persontotal'};
811: if (!defined($persontotal)) {
812: $persontotal = 1;
813: }
814: if ($env{'form.addperson'}) {
815: $persontotal ++;
816: }
817: my $userlinktxt = &mt('Set User');
818: my @items = ('uname','dom','last','first','email','hidedom');
819:
820: my $roleoptions;
821: my @roles = &Apache::lonuserutils::roles_by_context('course');
1.8 raeburn 822: my $type = 'Course';
823: if ($crstype eq 'community') {
824: $type = 'Community';
825: }
1.2 raeburn 826: foreach my $role (@roles) {
1.8 raeburn 827: my $plrole=&Apache::lonnet::plaintext($role,$type);
1.2 raeburn 828: $roleoptions .= ' <option value="'.$role.'">'.$plrole.'</option>'."\n";
829: }
830: my %customroles=&Apache::lonuserutils::my_custom_roles();
831: if (keys(%customroles) > 0) {
832: foreach my $cust (sort(keys(%customroles))) {
833: my $custrole='cr_cr_'.$env{'user.domain'}.
834: '_'.$env{'user.name'}.'_'.$cust;
835: $roleoptions .= ' <option value="'.$custrole.'">'.$cust.'</option>'."\n";
836: }
837: }
838:
839: my @currsecs;
840: if ($env{'form.sectotal'}) {
841: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
842: if (defined($env{'form.loncapasec_'.$i})) {
843: my $lcsec = $env{'form.loncapasec_'.$i};
844: unless (grep(/^\Q$lcsec\E$/,@currsecs)) {
845: push(@currsecs,$lcsec);
846: }
847: }
848: }
849: }
850:
851: my ($existtitle,$existops,$existmult,$newtitle,$seccolspan);
852: if (@currsecs) {
853: my $existsize = scalar(@currsecs);
854: if ($existsize > 3) {
855: $existsize = 3;
856: }
857: if ($existsize > 1) {
858: $existmult = ' multiple="multiple" size="'.$existsize.'" ';
859: }
860: @currsecs = sort { $a <=> $b } (@currsecs);
861: $existtitle = &mt('Official').': ';
862: $existops = '<option value="">'.&mt('None').'</option>';
863: foreach my $sec (@currsecs) {
864: $existops .= '<option value="'.$sec.'">'.$sec.'</option>'."\n";
865: }
866: $seccolspan = ' colspan="2"';
867: $newtitle = &mt('Other').': ';
868: }
869:
870: for (my $i=0; $i<$persontotal; $i++) {
871: my @linkargs = map { 'person_'.$i.'_'.$_ } (@items);
872: my $linkargstr = join("','",@linkargs);
1.7 raeburn 873: my $userlink = &Apache::loncommon::selectuser_link($formname,@linkargs,$dom,$userlinktxt);
1.2 raeburn 874: my $uname_form = '<input type="text" name="person_'.$i.'_uname" value=""'.
875: ' onFocus="this.blur();'.
1.7 raeburn 876: 'openuserbrowser('."'$formname','$linkargstr','$dom'".');" />';
1.2 raeburn 877: my $onchange = 'javascript:fix_domain('."'$formname','person_".$i."_dom',".
878: "'person_".$i."_hidedom'".');'.
1.7 raeburn 879: 'openuserbrowser('."'$formname','$linkargstr','$dom'".');';
1.2 raeburn 880: my $udom_form = &Apache::loncommon::select_dom_form($dom,'person_'.$i.'_dom','',
881: 1,$onchange).
882: '<input type="hidden" name="person_'.$i.'_hidedom" value="'.$dom.'" />';
883: my %form_elems;
884: foreach my $item (@items) {
885: next if (($item eq 'dom') || ($item eq 'uname') || ($item eq 'hidedom'));
886: $form_elems{$item} = '<input type="text" name="person_'.$i.'_'.$item.'" '.
887: 'value="" readonly="readonly" />';
888: }
889: my $roleselector = '<select name="person_'.$i.'_role">'."\n".
890: $roleoptions.'</select>';
891: my $sectionselector;
892: if (@currsecs) {
893: $sectionselector = $existtitle.'<select name="person_'.$i.'_sec"'.
894: $existmult.'>'."\n".$existops.'</select>'.(' ' x3);
895: }
896: $sectionselector .= $newtitle.
897: '<input type="text" name="person_'.$i.'_newsec" size="15" value="" />'.
898: '<input type="hidden" name="person_'.$i.'_sections" value="" />'."\n";
899:
900: $output .=
901: &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel').'<br />'.
902: '<span class="LC_nobreak">'.$userlink.
903: '</span>').
904: '<table><tr><td align="center" valign="top">'.&mt('Username').'<br />'.$uname_form.'</td>'."\n".
905: '<td align="center" valign="top" colspan="2">'.&mt('Domain').'<br />'.$udom_form.'</td></tr><tr>'."\n".
906: '<td align="center" valign="top">'.&mt('First Name').'<br />'.$form_elems{'first'}.'</td>'."\n".
907: '<td align="center" valign="top">'.&mt('Last Name').'<br />'.$form_elems{'last'}.'</td>'."\n".
908: '<td align="center" valign="top">'.&mt('E-mail').'<br />'.$form_elems{email}.'</td></tr>'."\n".
909: '<tr><td align="center" valign="top">'.&mt('Role').'<br />'.$roleselector.'</td>'."\n".
910: '<td'.$seccolspan.' align="center" valign="top">'.&mt('Section(s)').'<br />'.$sectionselector.'</td>'."\n".
911: '</tr></table>'.&Apache::lonhtmlcommon::row_closure();
912: }
913: $output .= &Apache::lonhtmlcommon::row_title(&mt('Add another?')).
914: '<input name="persontotal" type="hidden" value="'.$persontotal.'" />'.
915: '<input name="addperson" type="checkbox" value="'.$persontotal.'"'.
916: ' onclick="javascript:nextPage(document.'.$formname.",'".$env{'form.state'}.
917: "'".');" />'.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1).
918: &Apache::lonhtmlcommon::end_pick_box().'</div>';
919: return $output;
920: }
921:
1.1 raeburn 922: sub print_request_status {
1.10 ! raeburn 923: my ($dom,$crumb) = @_;
! 924: my $js = <<END;
! 925:
! 926: function backPage(formname,prevstate) {
! 927: formname.state.value = prevstate;
! 928: formname.submit();
! 929: }
! 930:
! 931: END
! 932: my $output = &header('Course Requests',$js).$crumb;
! 933: my %requests = &Apache::lonnet::dumpstore('courserequests',$env{'user.domain'},
! 934: $env{'user.name'});
! 935: my %queue_by_date;
! 936: foreach my $key (keys(%requests)) {
! 937: if (ref($requests{$key}) eq 'HASH') {
! 938: my ($cdom,$cnum) = split('_',$key);
! 939: next if ($cdom ne $dom);
! 940: my $entry;
! 941: my $timestamp = $requests{$key}{'timestamp'};
! 942: my $crstype = $requests{$key}{'crstype'};
! 943: my $status = $requests{$key}{'status'};
! 944: next unless (($env{'form.crstype'} eq 'all') ||
! 945: ($env{'form.crstype'} eq $crstype));
! 946: next unless (($status eq 'approval') || ($status eq 'pending'));
! 947: if (ref($requests{$key}{'details'}) eq 'HASH') {
! 948: $entry = $key.':'.$crstype.':'.$requests{$key}{'details'}{'cdesc'};
! 949: if ($crstype eq 'official') {
! 950: $entry .= ':'.$requests{$key}{'details'}{'instcode'};
! 951: }
! 952: }
! 953: if ($entry ne '') {
! 954: if (exists($queue_by_date{$timestamp})) {
! 955: if (ref($queue_by_date{$timestamp}) eq 'ARRAY') {
! 956: push(@{$queue_by_date{$timestamp}},$entry);
! 957: }
! 958: } else {
! 959: @{$queue_by_date{$timestamp}} = ($entry);
! 960: }
! 961: }
! 962: }
! 963: }
! 964: my $formname = 'requestcrs';
! 965: my @sortedtimes = sort {$a <=> $b} (keys(%queue_by_date));
! 966: $output .= '<form method="post" name="'.$formname.'" action="/adm/requestcourse" />'."\n".
! 967: '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
! 968: '<input type="hidden" name="state" value="'.$env{'form.state'}.'" />'."\n".
! 969: '<input type="hidden" name="crstype" value="'.$env{'form.crstype'}.'" />'."\n";
! 970: if (@sortedtimes > 0) {
! 971: $output .= &Apache::loncommon::start_data_table().
! 972: &Apache::loncommon::start_data_table_header_row().
! 973: '<th>'.&mt('Action').'</th>'.
! 974: '<th>'.&mt('Description').'</th>';
! 975: if ($env{'form.crstype'} eq 'all') {
! 976: $output .= '<th>'.&mt('Type').'</th>';
! 977: }
! 978: if (($env{'form.crstype'} eq 'all') || ($env{'form.crstype'} eq 'official')) {
! 979: $output .= '<th>'.&mt('Institutional Code').'</th>';
! 980: }
! 981: $output .= '<th>'.&mt('Date requested').'</th>'.
! 982: &Apache::loncommon::end_data_table_header_row();
! 983: my $count = 0;
! 984: foreach my $item (@sortedtimes) {
! 985: my $showtime = &Apache::lonlocal::locallocaltime($item);
! 986: if (ref($queue_by_date{$item}) eq 'ARRAY') {
! 987: foreach my $request (sort(@{$queue_by_date{$item}})) {
! 988: my ($key,$type,$desc,$instcode) = split(':',$request);
! 989: my ($cdom,$cnum) = split('_',$key);
! 990: $output .= &Apache::loncommon::start_data_table_row().
! 991: '<td><input type="button" value="'.&mt('Select').'" onclick="javascript:viewrequest('."'$cdom','$cnum'".')" /></td>'.
! 992: '<td>'.$desc.'</td>';
! 993: if ($env{'form.crstype'} eq 'all') {
! 994: $output .= '<td>'.&course_types($type).'</td>';
! 995: }
! 996: if (($env{'form.crstype'} eq 'all') ||
! 997: ($env{'form.crstype'} eq 'official')) {
! 998: $output .= '<td>'.$instcode.'</td>';
! 999: }
! 1000: $output .= '<td>'.$showtime.'</td>'.
! 1001: &Apache::loncommon::end_data_table_row();
! 1002: }
! 1003: }
! 1004: }
! 1005: $output .= &Apache::loncommon::end_data_table();
! 1006: } else {
! 1007: $output .= '<div class="LC_info">'.&mt('You have no course requests pending approval by a Domain Coordinator or held in a queue pending administrative action at your institution.').'</div>';
! 1008: }
! 1009: $output .= '
! 1010: <input type="button" name="prev" value="'.&mt('Back').'" onclick="javascript:backPage(document.'.$formname.",'crstype'".')" />
! 1011: </form>'.
! 1012: &Apache::loncommon::end_page();
! 1013: return $output;
1.1 raeburn 1014: }
1015:
1016: sub print_request_logs {
1.10 ! raeburn 1017: my ($jscript,$loaditems,$crumb) = @_;
1.1 raeburn 1018: return;
1019: }
1020:
1021: sub print_review {
1.4 raeburn 1022: my ($formname,$dom,$codetitles,$cat_titles,$cat_order,$code_order) = @_;
1023: my ($types,$typename) = &course_types();
1024: my ($owner,$ownername,$owneremail);
1025: $owner = $env{'user.name'}.':'.$env{'user.domain'};
1026: $ownername = &Apache::loncommon::plainname($env{'user.name'},
1027: $env{'user.domain'},'first');
1028: my %emails = &Apache::loncommon::getemails();
1029: foreach my $email ('permanentemail','critnotification','notification') {
1030: $owneremail = $emails{$email};
1031: last if ($owneremail ne '');
1032: }
1033: my ($inst_headers,$inst_values,$crstypename,$enroll_headers,$enroll_values,
1034: $section_headers,$section_values,$personnel_headers,$personnel_values);
1035:
1036: $crstypename = $env{'form.crstype'};
1037: if (ref($typename) eq 'HASH') {
1038: unless ($typename->{$env{'form.crstype'}} eq '') {
1039: $crstypename = $typename->{$env{'form.crstype'}};
1040: }
1041: }
1042:
1043: $inst_headers = '<th>'.&mt('Description').'</th><th>'.&mt('Type').'</th>';
1044: $inst_values = '<td>'.$env{'form.cdescr'}.'</td><td>'.$crstypename.'</td>';
1045:
1046: if ($env{'form.crstype'} eq 'official') {
1047: if ((ref($codetitles) eq 'ARRAY') && (ref($cat_titles) eq 'HASH')) {
1048: foreach my $title (@{$codetitles}) {
1049: if ($env{'form.instcode_'.$title} ne '') {
1050: $inst_headers .= '<th>'.$title.'</th>';
1051: my $longitem = $env{'form.instcode_'.$title};
1052: if (ref($cat_titles->{$title}) eq 'HASH') {
1053: if ($cat_titles->{$title}{$env{'form.instcode_'.$title}} ne '') {
1054: $longitem = $cat_titles->{$title}{$env{'form.instcode_'.$title}};
1055: }
1056: }
1057: $inst_values .= '<td>'.$longitem.'</td>';
1058: }
1059: }
1060: }
1061: if (&Apache::lonnet::auto_run('',$dom)) {
1062: $enroll_headers = '<th>'.&mt('Automatic Adds').'</th>'.
1063: '<th>'.&mt('Automatic Drops').'</th>'.
1064: '<th>'.&mt('Enrollment Starts').'</th>'.
1065: '<th>'.&mt('Enrollment Ends').'</th>';
1066: $section_headers = '<th>'.&mt('Sections').'</th>'.
1067: '<th>'.&mt('Crosslistings').'</th>';
1068:
1069: my ($startenroll,$endenroll) = &dates_from_form('startenroll','endenroll');
1070: my @autoroster = (&mt('No'),&mt('Yes'));
1071: $enroll_values = '<td>'.$autoroster[$env{'form.autoadds'}].'</td>'.
1072: '<td>'.$autoroster[$env{'form.autodrops'}].'</td>'.
1073: '<td>'.&Apache::lonlocal::locallocaltime($startenroll).'</td>'.
1074: '<td>'.&Apache::lonlocal::locallocaltime($endenroll).'</td>';
1.6 raeburn 1075: $section_values = '<td><table class="LC_innerpickbox"><tr><th>'.
1076: &mt('Institutional section').'</th>'.
1077: '<th>'.&mt('LON-CAPA section').'</th></tr>';
1.5 raeburn 1078: my $secinfo;
1.4 raeburn 1079: if ($env{'form.sectotal'} > 0) {
1080: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
1081: if ($env{'form.sec_'.$i}) {
1.5 raeburn 1082: $secinfo .= '<tr><td>'.$env{'form.secnum_'.$i}.'</td><td>';
1.4 raeburn 1083: if ($env{'form.loncapasec_'.$i} ne '') {
1.5 raeburn 1084: $secinfo .= $env{'form.loncapasec_'.$i};
1085: } else {
1086: $secinfo .= &mt('None');
1.4 raeburn 1087: }
1.5 raeburn 1088: $secinfo .= '</td></tr>';
1.4 raeburn 1089: }
1090: }
1091: }
1.6 raeburn 1092: if ($secinfo eq '') {
1093: $secinfo = '<tr><td colspan="2">'.&mt('None').'</td></tr>';
1.5 raeburn 1094: }
1.6 raeburn 1095: $section_values .= $secinfo.'</table></td><td>'.
1096: '<table class="LC_innerpickbox"><tr><th>'.
1097: &mt('Institutional course/section').'</th>'.
1098: '<th>'.&mt('LON-CAPA section').'</th></tr>';
1.5 raeburn 1099: my $xlistinfo;
1.4 raeburn 1100: if ($env{'form.crosslisttotal'}) {
1101: for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) {
1102: if ($env{'form.crosslist_'.$i}) {
1.5 raeburn 1103: $xlistinfo .= '<tr><td>';
1104: if (ref($code_order) eq 'ARRAY') {
1105: if (@{$code_order} > 0) {
1106: foreach my $item (@{$code_order}) {
1107: $xlistinfo .= $env{'form.crosslist_'.$i.'_'.$item};
1.4 raeburn 1108: }
1109: }
1110: }
1.5 raeburn 1111: $xlistinfo .= $env{'form.crosslist_'.$i.'_instsec'}.'</td><td>';
1.4 raeburn 1112: if ($env{'form.crosslist_'.$i.'_lcsec'}) {
1.5 raeburn 1113: $xlistinfo .= $env{'form.crosslist_'.$i.'_lcsec'};
1114: } else {
1115: $xlistinfo .= &mt('None');
1.4 raeburn 1116: }
1.5 raeburn 1117: $xlistinfo .= '</td></tr>';
1.4 raeburn 1118: }
1119: }
1120: }
1.6 raeburn 1121: if ($xlistinfo eq '') {
1122: $xlistinfo = '<tr><td colspan="2">'.&mt('None').'</td></tr>';
1.5 raeburn 1123: }
1.6 raeburn 1124: $section_values .= $xlistinfo.'</table></td>';
1.4 raeburn 1125: }
1126: }
1127:
1128: my %ctxt = &clone_text();
1129: $inst_headers .= '<th>'.&mt('Clone From').'</th>';
1130: if (($env{'form.clonecourse'} =~ /^$match_name$/) &&
1131: ($env{'form.clonedomain'} =~ /^$match_domain$/)) {
1132: my %coursehash =
1133: &Apache::lonnet::courseiddump($env{'form.clonedomain'},'.',1,'.','.',
1134: $env{'form.clonecourse'},undef,undef,'.');
1135: my $cloneid = $env{'form.clonedomain'}.'_'.$env{'form.clonecourse'};
1136: if (ref($coursehash{$cloneid}) eq 'HASH') {
1137: $inst_headers .= '<th>'.$ctxt{'dsh'}.'</th>';
1138: my $clonedesc = $coursehash{$cloneid}{'description'};
1139: my $cloneinst = $coursehash{$cloneid}{'inst_code'};
1140:
1141: $inst_values .= '<td>'.$clonedesc.' ';
1142: if ($cloneinst ne '') {
1143: $inst_values .= &mt('([_1] in [_2])',$cloneinst,$env{'form.clonedomain'});
1144: } else {
1145: $inst_values .= &mt('(from [_1])',$env{'form.clonedomain'});
1146: }
1147: $inst_values .= '</td><td>';
1148: if ($env{'form.datemode'} eq 'preserve') {
1149: $inst_values .= $ctxt{'pcd'};
1150: } elsif ($env{'form.datemode'} eq 'shift') {
1151: $inst_values .= &mt('Shift dates by [_1] days',$env{'form.dateshift'});
1152: } else {
1153: $inst_values .= $ctxt{'ncd'};
1154: }
1155: $inst_values .= '</td>';
1156: } else {
1157: $inst_values .= '<td>'.&mt('Unknown').'</td>';
1158: }
1159: } else {
1160: $inst_values .= '<td>'.&mt('None').'</td>';
1161: }
1162: $enroll_headers .= '<th>'.&mt('Access Starts').'</th>'.
1163: '<th>'.&mt('Access Ends').'</th>';
1164: my ($startaccess,$endaccess) = &dates_from_form('startaccess','endaccess');
1165: $enroll_values .= '<td>'.&Apache::lonlocal::locallocaltime($startaccess).'</td>';
1166: if ($endaccess == 0) {
1167: $enroll_values .= '<td>'.&mt('No end date').'</td>';
1168: } else {
1169: $enroll_values .= '<td>'.&Apache::lonlocal::locallocaltime($endaccess).'</td>';
1170: }
1171:
1172: my $container = 'Course';
1173: if ($env{'form.crstype'} eq 'community') {
1174: $container = 'Community';
1175: }
1176:
1177: $personnel_headers = '<th>'.&mt('Name').'</th><th>'.&mt('Username:Domain').
1178: '</th><th>'.&mt('Role').'</th><th>'.&mt('LON-CAPA Sections').
1179: '</th>';
1180: $personnel_values .= '<tr><td>'.$ownername.'</td><td>'.$owner.'</td>'.
1181: '<td>'.&Apache::lonnet::plaintext('cc',$container).'</td>'.
1182: '<td>'.&mt('None').'</td></tr>';
1183: for (my $i=0; $i<$env{'form.persontotal'}; $i++) {
1184: if ($env{'form.person_'.$i.'_uname'} ne '') {
1185: $personnel_values .=
1186: '<tr><td>'.$env{'form.person_'.$i.'_first'}.' '.
1187: $env{'form.person_'.$i.'_last'}.'</td>'.
1188: '<td>'.$env{'form.person_'.$i.'_uname'}.':'.
1189: $env{'form.person_'.$i.'_dom'}.'</td>'.
1190: '<td>'.&Apache::lonnet::plaintext($env{'form.person_'.$i.'_role'},
1191: $container).'</td>'.
1192: '<td>'.$env{'form.person_'.$i.'_sections'}.'</td></tr>';
1193: }
1194: }
1195: my $output = '<p>'.&mt('Review the details of the course request before submission.').'</p>'.
1196: '<div>'.&Apache::lonhtmlcommon::start_pick_box().
1197: &Apache::lonhtmlcommon::row_title(&mt('Owner')).
1.6 raeburn 1198: '<table class="LC_innerpickbox"><tr>'.
1.4 raeburn 1199: '<th>'.&mt('Name').'</th>'.
1200: '<th>'.&mt('Username:Domain').'</th>'.
1201: '<th>'.&mt('E-mail address').'</th>'.
1202: '</tr><tr>'."\n".
1203: '<td>'.$ownername.'</td><td>'.$owner.'</td>'.
1204: '<td>'.$owneremail.'</td>'.
1205: '</tr></table>'."\n".
1206: &Apache::lonhtmlcommon::row_closure().
1.5 raeburn 1207: &Apache::lonhtmlcommon::row_title(&mt('Description')).
1.4 raeburn 1208: '<table class="LC_innerpickbox"><tr>'.$inst_headers.'</tr>'."\n".
1209: '<tr>'.$inst_values.'</tr></table>'."\n".
1210: &Apache::lonhtmlcommon::row_closure().
1211: &Apache::lonhtmlcommon::row_title(&mt('Enrollment')).
1212: '<table class="LC_innerpickbox"><tr>'.$enroll_headers.'</tr>'."\n".
1213: '<tr>'.$enroll_values.'</tr></table>'."\n".
1214: &Apache::lonhtmlcommon::row_closure();
1215: if ($section_headers ne '') {
1216: $output .= &Apache::lonhtmlcommon::row_title(&mt('Sections')).
1217: '<table class="LC_innerpickbox"><tr>'.$section_headers.'</tr>'."\n".
1218: '<tr>'.$section_values.'</tr></table>'."\n".
1219: &Apache::lonhtmlcommon::row_closure();
1220: }
1221: $output .= &Apache::lonhtmlcommon::row_title(&mt('Personnel')).
1222: '<table class="LC_innerpickbox"><tr>'.$personnel_headers.'</tr>'."\n".
1223: $personnel_values.'</table>'."\n".
1224: &Apache::lonhtmlcommon::row_closure(1).
1225: &Apache::lonhtmlcommon::end_pick_box();
1.8 raeburn 1226: my $cnum = &Apache::lonnet::generate_coursenum($dom);
1227: $output .= '<input type="hidden" name="cnum" value="'.$cnum.'" />';
1.4 raeburn 1228: return $output;
1229: }
1230:
1231: sub dates_from_form {
1232: my ($startname,$endname) = @_;
1233: my $startdate = &Apache::lonhtmlcommon::get_date_from_form($startname);
1234: my $enddate = &Apache::lonhtmlcommon::get_date_from_form($endname);
1235: if ($endname eq 'endaccess') {
1236: if (exists($env{'form.no_end_date'}) ) {
1237: $enddate = 0;
1238: }
1239: }
1240: return ($startdate,$enddate);
1.1 raeburn 1241: }
1242:
1243: sub courseinfo_form {
1.2 raeburn 1244: my ($dom,$formname,$crstype) = @_;
1245: my $output = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
1246: &Apache::lonhtmlcommon::row_title('Course Description').
1247: '<input type="text" size="40" name="cdescr" />'.
1248: &Apache::lonhtmlcommon::row_closure(1).
1249: &Apache::lonhtmlcommon::end_pick_box().'</div>'.
1250: '<div>'.&clone_form($dom,$formname,$crstype).'</div>'."\n";
1.1 raeburn 1251: return $output;
1252: }
1253:
1254: sub clone_form {
1255: my ($dom,$formname,$crstype) = @_;
1256: my $type = 'Course';
1257: if ($crstype eq 'community') {
1258: $type = 'Community';
1259: }
1260: my $cloneform = &Apache::loncommon::select_dom_form($dom,'clonedomain').
1.2 raeburn 1261: &Apache::loncommon::selectcourse_link($formname,'clonecourse','clonedomain','','','',$type);
1.4 raeburn 1262: my %lt = &clone_text();
1.2 raeburn 1263: my $output .=
1264: &Apache::lonhtmlcommon::start_pick_box().
1265: &Apache::lonhtmlcommon::row_title($lt{'cid'}).'<label>'.
1266: '<input type="text" size="25" name="clonecourse" value="" onfocus="this.blur();'.
1267: 'opencrsbrowser('."'$formname','clonecourse','clonedomain','','','','$type'".');" />'.
1268: '</label>'.&Apache::lonhtmlcommon::row_closure(1).'<label>'.
1269: &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'</label>'.
1270: $cloneform.'</label>'.&Apache::lonhtmlcommon::row_closure().
1271: &Apache::lonhtmlcommon::row_title($lt{'dsh'}).'<label>'.
1272: '<input type="radio" name="datemode" value="delete" /> '.$lt{'ncd'}.
1273: '</label><br /><label>'.
1274: '<input type="radio" name="datemode" value="preserve" /> '.$lt{'prd'}.
1275: '</label><br /><label>'.
1276: '<input type="radio" name="datemode" value="shift" checked="checked" /> '.
1277: $lt{'shd'}.'</label>'.
1278: '<input type="text" size="5" name="dateshift" value="365" />'.
1279: &Apache::lonhtmlcommon::row_closure(1).
1280: &Apache::lonhtmlcommon::end_pick_box();
1.1 raeburn 1281: return $output;
1282: }
1283:
1.4 raeburn 1284: sub clone_text {
1285: return &Apache::lonlocal::texthash(
1286: 'cid' => 'Course ID',
1287: 'dmn' => 'Domain',
1288: 'dsh' => 'Date Shift',
1289: 'ncd' => 'Do not clone date parameters',
1290: 'prd' => 'Clone date parameters as-is',
1291: 'shd' => 'Shift date parameters by number of days',
1292: );
1293: }
1294:
1.1 raeburn 1295: sub coursecode_form {
1.2 raeburn 1296: my ($dom,$context,$codetitles,$cat_titles,$cat_order,$num) = @_;
1.1 raeburn 1297: my $output;
1.2 raeburn 1298: my %rowtitle = (
1299: instcode => 'Course Category',
1300: crosslist => 'Cross Listed Course',
1301: );
1.1 raeburn 1302: if ((ref($codetitles) eq 'ARRAY') && (ref($cat_titles) eq 'HASH') &&
1303: (ref($cat_order))) {
1.2 raeburn 1304: my ($sel,$instsec,$lcsec);
1305: $sel = $context;
1306: if ($context eq 'crosslist') {
1307: $sel .= '_'.$num;
1308: $instsec = &mt('Institutional section').'<br />'.
1309: '<input type="text" size="10" name="'.$sel.'_instsec" />';
1310: $lcsec = &mt('LON-CAPA section').'<br />'.
1311: '<input type="text" size="10" name="'.$sel.'_lcsec" />';
1312: }
1.1 raeburn 1313: if (@{$codetitles} > 0) {
1314: my $lastitem = pop(@{$codetitles});
1.2 raeburn 1315: my $lastinput = '<input type="text" size="5" name="'.$sel.'_'. $lastitem.'" />';
1.1 raeburn 1316: if (@{$codetitles} > 0) {
1.2 raeburn 1317: $output = &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
1318: '<table><tr>';
1.1 raeburn 1319: if ($context eq 'crosslist') {
1.2 raeburn 1320: $output .= '<td>'.&mt('Include?').'<br />'.
1321: '<input type="checkbox" name="'.$sel.'" value="1" /></td>';
1.1 raeburn 1322: }
1323: foreach my $title (@{$codetitles}) {
1324: if (ref($cat_order->{$title}) eq 'ARRAY') {
1325: if (@{$cat_order->{$title}} > 0) {
1326: $output .= '<td align="center">'.$title.'<br />'."\n".
1327: '<select name="'.$sel.'_'.$title.'">'."\n".
1328: ' <option value="" selected="selected">'.
1329: &mt('Select').'</option>'."\n";
1330: foreach my $item (@{$cat_order->{$title}}) {
1331: my $longitem = $item;
1332: if (ref($cat_titles->{$title}) eq 'HASH') {
1333: if ($cat_titles->{$title}{$item} ne '') {
1334: $longitem = $cat_titles->{$title}{$item};
1335: }
1336: }
1337: $output .= '<option value="'.$item.'">'.$longitem.
1338: '</option>'."\n";
1339: }
1340: }
1341: $output .= '</select></td>'."\n";
1342: }
1343: }
1344: if ($context eq 'crosslist') {
1345: $output .= '<td align="center">'.$lastitem.'<br />'."\n".
1.2 raeburn 1346: $lastinput.'</td><td align="center">'.$instsec.'</td>'.
1347: '<td align="center">'.$lcsec.'</td></tr></table>';
1.1 raeburn 1348: } else {
1349: $output .= '</tr></table>'.
1350: &Apache::lonhtmlcommon::row_closure().
1351: &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
1352: $lastinput;
1353: }
1354: } else {
1355: if ($context eq 'crosslist') {
1356: $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
1.2 raeburn 1357: '<table><tr>'.
1358: '<td align="center">'.$lastitem.'<br />'.$lastinput.'</td>'.
1359: '<td align="center">'.$instsec.'</td><td>'.$lcsec.'</td>'.
1360: '</tr></table>';
1.1 raeburn 1361: } else {
1362: $output .= &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
1363: $lastinput;
1364: }
1365: }
1.2 raeburn 1366: $output .= &Apache::lonhtmlcommon::row_closure(1);
1367: push(@$codetitles,$lastitem);
1368: } elsif ($context eq 'crosslist') {
1369: $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
1370: '<table><tr><td align="center">'.
1371: '<span class="LC_nobreak">'.&mt('Include?').
1372: '<input type="checkbox" name="'.$sel.'" value="1" /></span>'.
1373: '</td><td align="center">'.&mt('Institutional ID').'<br />'.
1374: '<input type="text" size="10" name="'.$sel.'_instsec" />'.
1375: '</td><td align="center">'.$lcsec.'</td></tr></table>'.
1376: &Apache::lonhtmlcommon::row_closure(1);
1.1 raeburn 1377: }
1378: }
1379: return $output;
1380: }
1381:
1382: sub get_course_dom {
1383: my $codedom = &Apache::lonnet::default_login_domain();
1384: if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
1385: $codedom = $env{'user.domain'};
1386: if ($env{'request.role.domain'} ne '') {
1387: $codedom = $env{'request.role.domain'};
1388: }
1389: }
1390: if ($env{'form.showdom'} ne '') {
1391: if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
1392: $codedom = $env{'form.showdom'};
1393: }
1394: }
1395: return $codedom;
1396: }
1397:
1398: sub display_navbuttons {
1399: my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
1400: $r->print('<div class="LC_navbuttons">');
1401: if ($prev) {
1402: $r->print('
1403: <input type="button" name="previous" value = "'.$prevtext.'"
1404: onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
1405: ');
1406: } elsif ($prevtext) {
1407: $r->print('
1408: <input type="button" name="previous" value = "'.$prevtext.'"
1409: onclick="javascript:history.back()"/>
1410: ');
1411: }
1412: if ($next) {
1413: $r->print('
1414: <input type="button" name="next" value="'.$nexttext.'"
1415: onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
1416: }
1417: $r->print('</div>');
1418: }
1419:
1420: sub print_request_outcome {
1.10 ! raeburn 1421: my ($dom,$codetitles,$code_order) = @_;
! 1422: my ($output,$cnum,$now,$req_notifylist,$crstype,$startenroll,$endenroll,
! 1423: %sections,%crosslistings,%personnel,@baduname,@missingdom,%domconfig,);
! 1424: $cnum = $env{'form.cnum'};
1.8 raeburn 1425: unless ($cnum =~ /^$match_courseid$/) {
1426: $output = &mt('Invalid LON-CAPA course number for the new course')."\n";
1427: return $output;
1428: }
1.10 ! raeburn 1429: %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom);
1.9 raeburn 1430: if (ref($domconfig{'requestcourses'}) eq 'HASH') {
1431: if (ref($domconfig{'requestcourses'}{'notify'}) eq 'HASH') {
1432: $req_notifylist = $domconfig{'requestcourses'}{'notify'}{'approval'};
1433: }
1434: }
1.10 ! raeburn 1435: $now = time;
! 1436: $crstype = $env{'form.crstype'};
1.8 raeburn 1437: if ($crstype eq 'official') {
1438: if (&Apache::lonnet::auto_run('',$dom)) {
1439: ($startenroll,$endenroll)=&dates_from_form('startenroll','endenroll');
1440: }
1.10 ! raeburn 1441: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
! 1442: if ($env{'form.sec_'.$i}) {
! 1443: if ($env{'form.secnum_'.$i} ne '') {
! 1444: $sections{$env{'form.secnum_'.$i}} = $env{'form.loncapasec_'.$i};
! 1445: }
! 1446: }
! 1447: }
! 1448: for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) {
! 1449: if ($env{'form.crosslist_'.$i}) {
! 1450: my $xlistinfo = '';
! 1451: if (ref($code_order) eq 'ARRAY') {
! 1452: if (@{$code_order} > 0) {
! 1453: foreach my $item (@{$code_order}) {
! 1454: $xlistinfo .= $env{'form.crosslist_'.$i.'_'.$item};
! 1455: }
! 1456: }
! 1457: }
! 1458: $xlistinfo .= $env{'form.crosslist_'.$i.'_instsec'};
! 1459: $crosslistings{$xlistinfo} = $env{'form.crosslist_'.$i.'_lcsec'};
! 1460: }
! 1461: }
! 1462: }
! 1463:
! 1464: for (my $i=0; $i<$env{'form.persontotal'}; $i++) {
! 1465: my $uname = $env{'form.person_'.$i.'_uname'};
! 1466: my $udom = $env{'form.person_'.$i.'_uname'};
! 1467: if (($uname =~ /^$match_username$/) && ($udom =~ /^$match_domain$/)) {
! 1468: if (&Apache::lonnet::domain($udom) ne '') {
! 1469: $personnel{$uname.':'.$udom} = {
! 1470: first => $env{'form.person_'.$i.'_first'},
! 1471: last => $env{'form.person_'.$i.'_last'},
! 1472: email => $env{'form.person_'.$i.'_email'},
! 1473: role => $env{'form.person_'.$i.'_role'},
! 1474: sections => $env{'form.person_'.$i.'_sections'},
! 1475: };
! 1476: } else {
! 1477: push(@missingdom,$uname.':'.$udom);
! 1478: }
! 1479: } else {
! 1480: push(@baduname,$uname.':'.$udom);
! 1481: }
1.8 raeburn 1482: }
1.10 ! raeburn 1483:
1.8 raeburn 1484: my ($startaccess,$endaccess) = &dates_from_form('startaccess','endacess');
1485: my $details = {
1.10 ! raeburn 1486: owner => $env{'user.name'},
! 1487: domain => $env{'user.domain'},
! 1488: cdom => $dom,
! 1489: cnum => $cnum,
! 1490: cdesc => $env{'form.cdesc'},
! 1491: crstype => $env{'form.crstype'},
! 1492: instcode => $env{'form.instcode'},
! 1493: clonedomain => $env{'form.clonedomain'},
! 1494: clonecourse => $env{'form.clonecourse'},
! 1495: datemode => $env{'form.datemode'},
! 1496: dateshift => $env{'form.datshift'},
! 1497: sectotal => $env{'form.sectotal'},
! 1498: sections => \%sections,
! 1499: crosslisttotal => $env{'form.crosslisttotal'},
! 1500: crosslistings => \%crosslistings,
! 1501: autoadds => $env{'form.autoadds'},
! 1502: autodrops => $env{'form.autodrops'},
! 1503: startenroll => $startenroll,
! 1504: endenroll => $endenroll,
! 1505: startaccess => $startaccess,
! 1506: endaccess => $endaccess,
! 1507: personnel => \%personnel,
1.8 raeburn 1508: };
1509: my @inststatuses;
1.9 raeburn 1510: my $val = &get_processtype($dom,$crstype,\@inststatuses,\%domconfig);
1.8 raeburn 1511: if ($val eq '') {
1512: if ($crstype eq 'official') {
1513: $output = &mt('You are not permitted to request creation of official courses');
1514: } elsif ($crstype eq 'unofficial') {
1515: $output = &mt('You are not permitted to request creation of unofficial courses');
1516: } elsif ($crstype eq 'community') {
1517: $output = &mt('You are not permitted to request creation of communities');
1518: } else {
1519: $output = &mt('Unrecognized course type: [_1]',$crstype);
1520: }
1521: } else {
1522: my ($disposition,$message);
1523: my %reqhash = (
1.10 ! raeburn 1524: timestamp => $now,
! 1525: crstype => $crstype,
! 1526: details => $details,
1.8 raeburn 1527: );
1528: my $requestkey = $dom.'_'.$cnum;
1.10 ! raeburn 1529: if ($val eq 'autolimit=') {
! 1530: $disposition = 'process';
! 1531: } elsif ($val =~ /^autolimit=(\d+)$/) {
! 1532: my $limit = $1;
1.8 raeburn 1533: $disposition = &check_autolimit($env{'user.name'},$env{'user.domain'},
1.10 ! raeburn 1534: $dom,$crstype,$limit,\$message);
1.8 raeburn 1535: } elsif ($val eq 'validate') {
1536: $disposition =
1537: &Apache::lonnet::auto_courserequest_validation($dom,$details,
1538: \@inststatuses,\$message);
1539: } else {
1540: $disposition = 'approval';
1541: }
1542: $reqhash{'status'} = $disposition;
1543: if ($disposition eq 'rejected') {
1544: $output = &mt('Your course request was rejected.');
1545: if ($message) {
1546: $output .= '<div class="LC_warning">'.$message.'</div>';
1547: }
1548: } elsif ($disposition eq 'process') {
1549: my $type = 'Course';
1550: if ($crstype eq 'community') {
1551: $type = 'Community';
1552: }
1553: my ($logmsg,$newusermsg,$addresult,$enrollcount,$output,$keysmsg,%longroles);
1554: my @roles = &Apache::lonuserutils::roles_by_context('course');
1555: foreach my $role (@roles) {
1556: $longroles{$role}=&Apache::lonnet::plaintext($role,$type);
1557: }
1558: my %reqdetails = &build_batchcreatehash($details);
1559: my $cid = &LONCAPA::batchcreatecourse::build_course($dom,$cnum,'request',\%reqdetails,\%longroles,\$logmsg,\$newusermsg,\$addresult,\$enrollcount,\$output,\$keysmsg,$env{'user.domain'},$env{'user.name'},$cnum);
1560: $disposition = 'created';
1561: if ($cid eq $cnum) {
1562: $disposition = 'created';
1563: $output = &mt('Your course request has been processed and the course has been created.').'<br />'.&mt('You will need to logout and log-in again to be able to select a role in the course.');
1564: } else {
1565: $output = &mt('An error occurred when processing your course request.').'<br />'.&mt('You may want to review the request details and submit the request again.');
1566: }
1567: } else {
1568: my $requestid = $cnum.'_'.$disposition;
1569: my $request = {
1570: $requestid => {
1571: timestamp => $now,
1572: crstype => $crstype,
1573: ownername => $env{'user.name'},
1574: ownerdom => $env{'user.domain'},
1575: description => $env{'form.cdesc'},
1576: },
1577: };
1578: my $putresult = &Apache::lonnet::newput_dom('courserequestqueue',$request,
1579: $dom);
1580: if ($putresult eq 'ok') {
1581: my %emails = &Apache::loncommon::getemails();
1582: my $address;
1583: if (($emails{'permanentemail'} ne '') || ($emails{'notification'} ne '')) {
1584: $address = $emails{'permanentemail'};
1585: if ($address eq '') {
1586: $address = $emails{'notification'};
1587: }
1588: }
1589: $output = &mt('Your course request has been recorded.').'<br />';
1590: if ($disposition eq 'approval') {
1591: $output .= &mt('Your course request has been recorded.').'<br />'.
1592: &mt('A message will be sent to your LON-CAPA account when a domain coordinator takes action on your request.').'<br />'.
1593: &mt('To access your LON-CAPA message, go to the Main Menu and click on "Send and Receive Messages".').'<br />';
1594: if ($address ne '') {
1595: $output.= &mt('An e-mail will also be sent to: [_1] when this occurs.',$address).'<br />';
1596: }
1597: if ($req_notifylist) {
1598: my $fullname = &Apache::loncommon::plainname($env{'user.name'},
1599: $env{'user.domain'});
1600: &Apache::loncoursequeueadmin::send_selfserve_notification($req_notifylist,$fullname,$now,$dom,$details);
1601: }
1602: } else {
1603: $output .= '<div class="LC_info">'.
1604: &mt('Your request has been placed in a queue pending administrative action.').'<br />'.
1605: &mt("Usually this means that your institution's information systems do not list you among the instructional personnel for this course.").'<br />'.
1606: &mt('The list of instructional personnel for the course will be automatically checked daily, and once you are listed the request will be processed.').
1607: '</div>';
1608: }
1609: } else {
1610: $reqhash{'status'} = 'domainerror';
1611: $reqhash{'disposition'} = $disposition;
1612: my $warning = &mt('An error occurred saving your request in the pending requests queue.');
1613: $output = '<span class"LC_warning">'.$warning.'</span><br />';
1614:
1615: }
1616: }
1.10 ! raeburn 1617: my $storeresult;
! 1618: if ($requestkey =~ /^($match_domain)_($match_courseid)$/) {
! 1619: $storeresult = &Apache::lonnet::store_userdata(\%reqhash,$requestkey,
! 1620: 'courserequests');
! 1621: } else {
! 1622: $storeresult = 'error: invalid requestkey format';
! 1623: }
1.8 raeburn 1624: if ($storeresult ne 'ok') {
1625: $output .= '<span class="LC_warning">'.&mt('An error occurred saving a record of the details of your request.').'</span><br />';
1626: &logthis("Error saving course request - $requestkey for $env{'user.name'}:$env{'user.domain'} - $storeresult");
1627: }
1628: }
1629: return $output;
1630: }
1631:
1632: sub get_processtype {
1.9 raeburn 1633: my ($dom,$crstype,$inststatuses,$domconfig) = @_;
1634: return unless ((ref($inststatuses) eq 'ARRAY') && (ref($domconfig) eq 'HASH'));
1.8 raeburn 1635: my (%userenv,%settings,$val);
1636: my @options = ('autolimit','validate','approve');
1637: if ($dom eq $env{'user.domain'}) {
1638: %userenv =
1639: &Apache::lonnet::userenvironment($env{'user.domain'},$env{'user.name'},
1640: 'requestcourses.'.$crstype,'inststatus');
1641: if ($userenv{'requestcourses.'.$crstype}) {
1642: $val = $userenv{'requestcourses.'.$crstype};
1643: @{$inststatuses} = ('_custom_');
1644: } else {
1645: my ($task,%alltasks);
1.9 raeburn 1646: if (ref($domconfig->{'requestcourses'}) eq 'HASH') {
1647: %settings = %{$domconfig->{'requestcourses'}};
1.8 raeburn 1648: if (ref($settings{$crstype}) eq 'HASH') {
1649: if (($env{'user.adv'}) && (exists($settings{$crstype}{'_LC_adv'}))) {
1650: $val = $settings{$crstype}{'_LC_adv'};
1651: @{$inststatuses} = ('_LC_adv_');
1652: } else {
1653: if ($userenv{'inststatus'} ne '') {
1654: @{$inststatuses} = split(',',$userenv{'inststatus'});
1655: } else {
1656: @{$inststatuses} = ('other');
1657: }
1658: foreach my $status (@{$inststatuses}) {
1659: if (exists($settings{$crstype}{$status})) {
1660: my $value = $settings{$crstype}{$status};
1661: next unless ($value);
1662: unless (exists($alltasks{$value})) {
1663: if (ref($alltasks{$value}) eq 'ARRAY') {
1664: unless(grep(/^\Q$status\E$/,@{$alltasks{$value}})) {
1665: push(@{$alltasks{$value}},$status);
1666: }
1667: } else {
1668: @{$alltasks{$value}} = ($status);
1669: }
1670: }
1671: }
1672: }
1673: my $maxlimit = 0;
1674: foreach my $key (sort(keys(%alltasks))) {
1675: if ($key =~ /^autolimit=(\d*)$/) {
1676: if ($1 eq '') {
1677: $val ='autolimit=';
1678: last;
1679: } elsif ($1 > $maxlimit) {
1680: $maxlimit = $1;
1681: }
1682: }
1683: }
1684: if ($maxlimit) {
1685: $val = 'autolimit='.$maxlimit;
1686: } else {
1687: foreach my $option (@options) {
1688: if ($alltasks{$option}) {
1689: $val = $option;
1690: last;
1691: }
1692: }
1693: }
1694: }
1695: }
1696: }
1697: }
1698: } else {
1699: %userenv = &Apache::lonnet::userenvironment($env{'user.domain'},
1700: $env{'user.name'},'reqcrsotherdom.'.$env{'form.crstype'});
1701: if ($userenv{'reqcrsotherdom'}) {
1702: my @doms = split(',',$userenv{'reqcrsotherdom'});
1703: my $optregex = join('|',@options);
1704: if (grep(/^\Q$dom\E:($optregex=?\d*)/,@doms)) {
1705: $val = $1;
1706: }
1707: @{$inststatuses} = ('_external_');
1708: }
1709: }
1710: return $val;
1711: }
1712:
1713: sub check_autolimit {
1.10 ! raeburn 1714: my ($uname,$udom,$dom,$crstype,$limit,$message) = @_;
! 1715: my %crsroles = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},
! 1716: 'userroles',['active','future'],['cc'],[$dom]);
! 1717: my ($types,$typename) = &course_types();
! 1718: my %requests = &Apache::lonnet::dumpstore('courserequests',$udom,$uname);
! 1719: my %count;
! 1720: if (ref($types) eq 'ARRAY') {
! 1721: foreach my $type (@{$types}) {
! 1722: $count{$type} = 0;
! 1723: }
! 1724: }
! 1725: foreach my $key (keys(%requests)) {
! 1726: my ($cdom,$cnum) = split('_',$key);
! 1727: if (exists($crsroles{$cnum.':'.$cdom.':cc'})) {
! 1728: if (ref($requests{$key}) eq 'HASH') {
! 1729: my $type = $requests{$key}{'crstype'};
! 1730: if ($type =~ /^official|unofficial|community$/) {
! 1731: $count{$type} ++;
! 1732: }
! 1733: }
! 1734: }
! 1735: }
! 1736: if ($count{$crstype} < $limit) {
! 1737: return 'process';
! 1738: } else {
! 1739: if (ref($typename) eq 'HASH') {
! 1740: $$message = &mt('Your request has not been processed because you have reached the limit for the number of courses of this type.').'<br />'.&mt("Your $typename->{$crstype} limit is [_1].",$limit);
! 1741: }
! 1742: return 'rejected';
! 1743: }
1.1 raeburn 1744: return;
1745: }
1746:
1.8 raeburn 1747: sub build_batchcreatehash {
1748: my ($details) = @_;
1749: my %batchhash;
1750: if (ref($details) eq 'HASH') {
1751:
1752: }
1753: return %batchhash;
1754: }
1755:
1.2 raeburn 1756: sub retrieve_settings {
1757: my ($dom,$request_id) = @_;
1758: my %reqinfo = &get_request_settings($request_id,$dom);
1759: my %stored;
1760: $stored{'cdescr'} = &unescape($reqinfo{'description'});
1761: $stored{'startaccess'} = $reqinfo{'startaccess'};
1762: $stored{'endaccess'} = $reqinfo{'endaccess'};
1763: if ($stored{'endaccess'} == 0) {
1764: $stored{'no_end_date'} = 1;
1765: }
1766: $stored{'startenroll'} = $reqinfo{'startenroll'};
1767: $stored{'endenroll'} = $reqinfo{'endenroll'};
1768: $stored{'crosslist'} = $reqinfo{'crosslist'};
1769: $stored{'clonecourse'} = $reqinfo{'clonecourse'};
1770: $stored{'clonedomain'} = $reqinfo{'clonedomain'};
1771: $stored{'sections'} = $reqinfo{'sections'};
1772: $stored{'personnel'} = $reqinfo{'personnel'};
1773:
1774: return %stored;
1775: }
1776:
1777: sub get_request_settings {
1778: my ($request_id,$dom);
1779: }
1780:
1.1 raeburn 1781: 1;
1782:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>