# $Id: academic_committee.pm,v 1.20 2004/11/12 05:45:23 gwolf Exp $
######################################
# Comas - Conference Management System
######################################
# Copyright 2003 CONSOL
# Congreso Nacional de Software Libre (http://www.consol.org.mx/)
#   Gunnar Wolf <gwolf@gwolf.cx>
#   Manuel Rabade <mig@mig-29.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
######################################

######################################
# Module: Comas::HTML::committee::academic_committee
# Front End for the academic committe tasks
######################################
# Depends on:

# Comas::Person - Handles the interaction with a person for Comas
# Comas::HTML::common - Common functions for the HTML FrontEnd
# Comas::Proposal - Handles the interaction with a person for Comas
# Comas::Admin - Manage administrative tasks for a Comas database 
# Comas::Conf - Comas' configuration management routines
# Data::FormValidator - Validates user input based on input profile
# HTML::FromText - Marks up plain text as HTML
# Net::SMTP - Simple Mail Transfer Protocol Client

# This module is not meant to be called on its own, it should be called from
# Comas::HTML.

package Comas::HTML::committee::academic_committee;

use strict;
use warnings;
use Carp;

use Comas::Admin;
use Comas::Conf qw(:read);
use Comas::Person;
use Comas::Proposal;
use Comas::HTML::common qw(:all);

use Data::FormValidator;
use HTML::FromText;
use Net::SMTP;

use Exporter;

our @ISA = qw(Exporter);
our @EXPORT_OK = qw( academic_committee_prop_revision
                     academic_committee_prop_list );
our %EXPORT_TAGS = (all => [@EXPORT_OK]);

=head1 NAME
    
Comas::HTML::committee::academic_committee - Front End for the academic
committe tasks

=head1 SYNOPSIS

This module is not meant to be used by itself, but as an auxiliary to
L<Comas::HTML|Comas::HTML>. Please check L<Comas::HTML|Comas::HTML>'s
documentation, in the B<Front End Tasks> section, for further details on the
usage for this functions.

=head1 INTERNALS

=head2 METHODS

=head3 $res = $html->academic_committee_prop_list($message);

Main list of proposals to be evaluated by the academic committee. Can receive an
optional explanatory message that will be passed to the template in case there
was an error in some other method.

=cut

sub academic_committee_prop_list {
    my ($template, @prop_loop, @sorted_loop);
    my $h = shift;
    my $message = shift;

    unless($h->_ck_committee_task) {
        return $h->committee_menu('NOT_AUTHORIZED');
    }
    
    $template = $h->new_template('committee/academic_committee/proposals_list.tmpl');

    if (defined $message) {
        $template->param($message => 1);
    }

    $template->param(-track_list => 
                     _catalog2html_opts($h->{-db},'track',
                                        $h->{-params}->{-filter_track_id}),
                     -prop_type_list =>
                     _catalog2html_opts($h->{-db},'prop_type',
                                        $h->{-params}->{-filter_prop_type_id}),
                     -prop_status_list =>
                     _catalog2html_opts($h->{-db},'prop_status',
                                        $h->{-params}->{-filter_prop_status_id}));

    @prop_loop = $h->_proposals_list;
    @sorted_loop = _sort_proposals('author', @prop_loop);
    $template->param(PROPOSALS => \@sorted_loop);
    $template->param(NUMBER_OF_PROPOSALS => scalar @prop_loop);
    return $template->output;
}

=pod

=head3 $res = $html->academic_committee_prop_revision;

Evaluate selected proposal, also the academic committee members can modify the
proposal. A notification email is sent to the authors if the proposal is
modified.

=cut

sub academic_committee_prop_revision {
    my $h = shift;
    my ($template, $proposal, %authors);

    unless($h->_ck_committee_task) {
        return $h->committee_menu('NOT_AUTHORIZED');
    }
        
    $proposal = Comas::Proposal->new(-db => $h->{-db},
                                     -id => $h->{-path}[2]);

    if(defined $h->{-params}->{-posted}) {
        my $adm = Comas::Admin->new(-db => $h->{-db_adm},
                                    %{$h->{-session}->{-admin}});
        $adm->set_title($proposal->{-id}, $h->{-params}->{-title});
        $adm->set_status($proposal->{-id}, $h->{-params}->{-prop_status_id});
        $adm->set_track_id($proposal->{-id}, $h->{-params}->{-track_id});
        $adm->set_prop_type_id($proposal->{-id},$h->{-params}->{-prop_type_id});
        $adm->set_comments($proposal->{-id}, $h->{-params}->{-comments});
	$adm->set_abstract($proposal->{-id}, $h->{-params}->{-abstract});
        
        if ($h->{-params}->{-notification}) {
            _send_author_mail($proposal, 
                              $h->{-config}->{-tmpl_path} .
                              'mail/proposal_revision.txt');
            return $h->academic_committee_prop_list('REVISED_PROPOSAL_WITH_MAIL');
        } else {
            return $h->academic_committee_prop_list('REVISED_PROPOSAL');
        }
    }

    $template = $h->new_template('committee/academic_committee/proposals_revision.tmpl');

    unless($proposal) {
        return $h->academic_committee_prop_list;
    }

    $template->param(-id => $proposal->get_id,
		     -title => $proposal->get_title,
		     -abstract => $proposal->get_abstract,
		     -track_list => 
                         _catalog2html_opts($h->{-db},"track",
					    $proposal->get_track_id,undef,1),
                     -prop_type_list =>
                         _catalog2html_opts($h->{-db},"prop_type",
					  $proposal->get_prop_type_id,undef,1));

    if (my @files = $proposal->get_files) {
	my (@file_data);

	for my $file (@files) {
	    push @file_data, {-FILE_ID => $file->get_id,
			      -FILENAME => $file->get_filename, 
			      -SIZE => $file->get_filesize,
			      -DESCR => $file->get_descr};
	}

	$template->param(FILES => \@file_data);
	
    }

    $template->param(-prop_status_list => 
                     _catalog2html_opts($h->{-db}, 
                                        'prop_status',
                                        $proposal->get_prop_status_id,
                                        undef, 1));
    $template->param(-comments => $proposal->get_comments);

    %authors = $proposal->get_authors(-result=>'hash');

    my ($author_temp, @loop);
    foreach my $author_id (sort { $authors{$a} <=> $authors{$b} }
                           keys %authors) {
        my %row;
        $author_temp = Comas::Person->new(-db => $h->{-db},
                                          -id => $author_id);
        $row{-firstname} = $author_temp->get_firstname;
        $row{-famname} = $author_temp->get_famname;
        $row{-resume} = text2html($author_temp->get_resume, lines => 1);
        push (@loop, \%row);
    }
    $template->param(AUTHORS => \@loop);
    return $template->output;
}

=pod

=head2 FUNCTIONS

=head3 $res = _send_author_mail($proposal, $mail_tmpl);

Send a notification via email to the authors of a modified proposal.

The arguments are:

=over 2

=item - $proposal

L<Comas::Proposal|Comas::Proposal> object of the current proposal.

=item - $mail_tmpl

Filename of the email template with full path.

=back

This function also needs the following configuration values: smtp_host (if isn't
defined 127.0.0.1 is used) and proposal_revision_mail_from (sender of
notifications).

The C<$res> retrun value is undef in case of an error or true if successful.

=cut

sub _send_author_mail {
    my ($proposal, $mail_tmpl, $mail_orig, %mail_subst, @authors, $smtp_host,
        $mail_from);
    $proposal = shift;
    $mail_tmpl = shift;
    
    unless (-r $mail_tmpl and open(TMPL, '<', $mail_tmpl)) {
	warn "Could not open mail template ($mail_tmpl): $!\n";
	warn 'Mail will not be sent to the authors.';
	return undef;
    }
    while (<TMPL>) {
        $mail_orig .= $_;
    }
    close(TMPL);

    $mail_subst{FROM}=get_conf($proposal->{-db},'proposal_revision_mail_from');
    $mail_subst{PROP_ID} = $proposal->{-id};
    $mail_subst{TITLE} = $proposal->get_title;
    $mail_subst{COMMENTS} = $proposal->get_comments;
    $mail_subst{STATUS} = $proposal->{-db}->getCatDescr('prop_status',
				    $proposal->get_prop_status_id);
    
    @authors = map {_get_author_name_mail($proposal->{-db}, $_)}
    $proposal->get_authors;

    $smtp_host = get_conf($proposal->{-db}, 'smtp_host') || '127.0.0.1';
    unless($mail_from = get_conf($proposal->{-db}, 
				 'proposal_revision_mail_from')) {
        warn "Couldn't get sender address, please check your configuration.\n";
	warn "Mail will not be sent to the authors.\n";
	return undef;
    }    
    
    for my $author (@authors) {
	my $mail = $mail_orig;
	$mail_subst{NAME} = $author->[0];
	$mail_subst{MAIL} = $author->[1];
	# Here goes my mail-processing mini-template-engine!
	for my $key (keys %mail_subst) {
	    $mail =~ s/__${key}__/$mail_subst{$key}/gs;
	}
        my $smtp;
        unless ($smtp = Net::SMTP->new($smtp_host)) {
            warn "Couldn't contact SMTP server\n";
            warn "Mail will not be sent to the authors.\n";
            return undef;
        }
        
        $smtp->mail($mail_from);
        $smtp->to($author->[1]);
        $smtp->data();
        $smtp->datasend($mail);
        $smtp->dataend();
        $smtp->quit();
    }
    return 1;
}

=pod

=head3 $res = _get_author_name_mail($db, $id)

Return the full name of a proposal's author (C<-firstname> and C<-famname>).

The arguments are:

=over 2

=item - $db

L<Comas::DB|Comas::DB> object.

=item - $id

Id of the proposal's author.

=back

The C<$res> retrun value is undef in case of an error.

=cut

sub _get_author_name_mail {
    my ($db, $person, $id, $name, $mail);
    $db = shift;
    $id = shift;
    
    unless ($person = Comas::Person->new(-db=>$db, -id=>$id)) {
	warn "Could not find information for person ID $id";
	return undef;
    }
    
    $name = $person->get_firstname . ' ' . $person->get_famname;
    $mail = $person->get_email;
    
    return [$name, $mail];
}

1;

=pod

=head1 SEE ALSO

L<Comas::HTML|Comas::HTML> module documentation

=head1 AUTHOR

Gunnar Wolf, gwolf@gwolf.cx

Manuel Rabade, mig@mig-29.net

Comas has been developed for CONSOL, Congreso Nacional de Software Libre,
http://www.consol.org.mx/

=head1 COPYRIGHT

Copyright 2003 Gunnar Wolf and Manuel Rabade

This library is free software, you can redistribute it and/or modify it
under the terms of the GPL version 2 or later.

=cut

# $Log: academic_committee.pm,v $
# Revision 1.20  2004/11/12 05:45:23  gwolf
# Added the functionality to be able to handle more than one file per proposal and store it in the DB, not in separate files.
#
# Revision 1.19  2004/07/18 08:05:23  mig
# POD finished
#
# Revision 1.18  2004/07/08 00:15:40  gwolf
# Handling Comas' and the conference's base URL in the configuration,
# not hard-coded in the HTML templates themselves
#
# Revision 1.17  2004/06/14 16:58:03  gwolf
# Minor modifications for consistency sake (all of them regarding field
# names in templates, or at least something terribly similar to it)
#
# Revision 1.16  2004/05/17 23:20:49  gwolf
# Allows the Academic Committee to change the title of an abstract
#
# Revision 1.15  2004/05/10 15:47:06  gwolf
# When reviewing proposals, the committee can now also modify the
# abstracts
#
# Revision 1.14  2004/04/16 23:56:14  gwolf
# Sorts differently (not yet able to specify a criteria)
#
# Revision 1.13  2004/04/07 21:32:40  gwolf
# Created Comas::DB methods getCatalog and getCatDescr, modified some of
# Comas::DB modules in order to use this interface instead of
# Comas::HTML::common::_id2descr (and removed that function, of course)
#
# Revision 1.12  2004/02/03 19:34:02  mig
# - Agrege un poquito de documentacion
#
# Revision 1.11  2004/01/11 23:41:36  mig
# - Los ordenamientos de las listas son independientes ahora
#
# Revision 1.10  2004/01/11 06:40:31  mig
# - Agrego el despliege del numero de ponencias.
#
# Revision 1.9  2004/01/11 04:59:48  mig
# - Muchos cambios :-P
# - Notificar a los autores es opcional (con un checkbox).
# - Se puede modificar el tipo y track de ponencia.
# - Reflejo cambios del prefijo 'filter' para los campos de filtrado.
#
# Revision 1.8  2003/12/24 07:20:37  mig
# - Agreo soporte para los filtros y le quito un cacho que ya esta
#   generalizado en _proposals_list :)
#
# Revision 1.7  2003/12/21 07:49:29  mig
# - Ouch .. faltaba el 'return 1;' de _send_author_mail
#
# Revision 1.6  2003/12/21 04:30:59  mig
# - Ya manda correos ! :)
#
# Revision 1.5  2003/12/20 04:14:51  mig
# - Agrego tags Id y Log que expanda el CVS
#
