# $Id: monetary_adm.pm,v 1.5 2003/12/20 04:14:51 mig 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::Admin::monetary_adm
# Manage money-related issues
######################################
# Depends on:
#
# Comas::Common - Common functions for various Comas modules
# Comas::Admin - Manage administrative tasks for a Comas database

# This module is not meant to be called on its own, it should be called from
# Comas::Admin.
package Comas::Admin::monetary_adm;

use strict;
use warnings;
use Carp;
use Comas::Common qw(valid_hash);
use Comas::Admin;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(create_exp_status set_exp_status delete_exp_status
		    create_payment_type set_payment_type delete_payment_type
		    create_time_discount set_time_discount delete_time_discount
		    create_price set_price delete_price);
our %EXPORT_TAGS = (exp_status => [qw(create_exp_status set_exp_status 
				      delete_exp_status)],
		    payment_type => [qw(create_payment_type set_payment_type 
					delete_payment_type)],
		    time_discount => [qw(create_time_discount set_time_discount 
					 delete_time_discount)],
		    price => [qw(create_price set_price delete_price)],
		    );

=head1 NAME

Comas::Admin::monetary_adm - Manage money-related issues

=head1 SYNOPSIS

This module is not meant to be used by itself, but as an auxiliary to
L<Comas::Admin>. Please check L<Comas::Admin>'s documentation, in the
B<Money-related issues> section, for further details on the usage for this
functions.

=head1 SEE ALSO

L<Comas::Admin> 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

sub create_exp_status {
    my ($adm, $descr);
    $adm = shift;
    $descr = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }
    return Comas::Admin::_create_record($adm->{-db}, 'exp_status', $descr);
}

sub create_payment_type { 
    my ($adm, $descr);
    $adm = shift;
    $descr = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }
    return Comas::Admin::_create_record($adm->{-db}, 'payment_type', $descr);
}

sub create_time_discount { 
    my ($adm, $date, $disc, $id, $sth);
    $adm = shift;
    $date = shift;
    $disc = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }

    unless (defined $date and $disc =~ /(100|\d{1,2})/) {
	carp 'Invocation error';
	return undef;
    }

    $adm->{-db}->begin_work;
    unless ($sth = $adm->{-db}->prepare('INSERT INTO time_discount 
            (max_date, discount) VALUES (?, ?)') and 
	    $sth->execute($date, $disc)) {
	carp 'Could not insert record into time_discount';
	$adm->{-db}->rollback;
	return undef;
    }

    unless ($sth=$adm->{-db}->prepare("SELECT currval('time_discount_id_seq')")
	    and $sth->execute and ($id) = $sth->fetchrow_array) {
	carp 'Could not verify new record ID - Not inserting it';
	$sth->{-db}->rollback;
	return undef;
    }
    $adm->{-db}->commit;

    return $id;
}

sub create_price { 
    # Creating and setting a price are the same operation...
    my $adm = shift;
    return $adm->set_price(@_);
}

sub set_exp_status { 
    my ($adm, $id, $descr);
    $adm = shift;
    $id = shift;
    $descr = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }
    return Comas::Admin::_set_record($adm->{-db}, 'exp_status', $id, $descr);
}

sub set_payment_type { 
    my ($adm, $id, $descr);
    $adm = shift;
    $id = shift;
    $descr = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }
    return Comas::Admin::_set_record($adm->{-db}, 'payment_type', $id, $descr);
}

sub set_time_discount { 
    my ($adm, %par, @sql, $err, $sth);
    $adm = shift;
    $err = 0;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }

    $sql[0] = 'UPDATE time_discount SET';

    unless (%par = valid_hash(@_)) {
	carp 'Invocation error - Wrong number of parameters';
	return undef;
    }

    unless (exists $par{-id} and $par{-id} =~ /^\d+$/) {
	carp 'Invocation error - A numeric ID is mandatory';
	$err = 1;
    }
    for my $key (keys %par) {
	next if $key eq '-id';
	if ($key ne '-max_date' and $key ne '-discount') {
	    carp "Invalid key ($key) received";
	    $err = 1;
	}
	# In order to build the SQL and have the sorted array of elements, we
	# add to @sql the name of the field (removing the initial dash we were
	# called with) and the value.
	push(@sql, [substr($key, 1), $par{$key}]);
    }

    return undef if $err;

    # If we received only -id, there is nothing to do, return successfully.
    return 1 if scalar(keys %par) == 1;

    $sql[0] .= join(', ', map {" $_->[0] = ? "} @sql[1..$#sql]) . 
	'WHERE id = ?';
    # Now that the SQL sentence is formed, flatten the array discarding the
    # field names
    @sql = map {ref($_) ? $_->[1] : $_} @sql;

    unless ($sth = $adm->{-db}->prepare($sql[0]) and
	    $sth->execute(@sql[1..$#sql], $par{-id})) {
	carp 'Unable to update specified time_discount record';
	return undef;
    }

    return 1;
}

sub set_price {
    my ($adm, $person, $prop, $amount, $sql, $sth);
    $adm = shift;
    $person = shift;
    $prop = shift;
    $amount = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }

    unless (defined $person and defined $prop and defined $amount and
	    $person =~ /^\d+$/ and $prop =~ /^\d+$/ and $amount =~ /^\d+$/) {
	carp 'Invocation error';
	return undef;
    }

    # Has a price been set for this relation?
    unless ($sth = $adm->{-db}->prepare('SELECT amount FROM price WHERE
            person_type_id = ? AND prop_type_id = ?') and
	    $sth->execute($person, $prop)) {
	carp 'Could not verify if relation already exists';
	return undef;
    }
    $sql = $sth->rows ?
	# Yes, it does exist - Update it
	$sql = 'UPDATE price SET amount = ? WHERE person_type_id = ? AND
                prop_type_id = ?' : 
	# New one - Insert it
		'INSERT INTO price (amount, person_type_id, prop_type_id) 
                 VALUES (?, ?, ?)';

    unless ($sth = $adm->{-db}->prepare($sql) and 
	    $sth->execute($amount, $person, $prop)) {
	carp 'Could not set the requested price relation';
	return undef;
    }

    return 1;
}


sub delete_exp_status { 
    my ($adm, $id);
    $adm = shift;
    $id = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }
    return Comas::Admin::_delete_record($adm->{-db}, 'exp_status', $id);
}

sub delete_payment_type { 
    my ($adm, $id);
    $adm = shift;
    $id = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }
    return Comas::Admin::_delete_record($adm->{-db}, 'payment_type', $id);
}

sub delete_time_discount { 
    my ($adm, $id);
    $adm = shift;
    $id = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }
    return Comas::Admin::_delete_record($adm->{-db}, 'time_discount', $id);
}

sub delete_price { 
    my ($adm, $per_t, $prop_t, $sth);
    $adm = shift;
    $per_t = shift;
    $prop_t = shift;

    unless ($adm->ck_admin_task(-task=>'schedule_adm')) {
	carp 'Access denied';
	return undef;
    }

    unless (defined $per_t and defined $prop_t and
	    $per_t =~ /^\d+$/ and $prop_t =~ /\d+$/) {
	carp 'Invocation error';
	return undef;
    }

    unless ($sth = $adm->{-db}->prepare('DELETE FROM price WHERE person_type_id=?
            AND prop_type_id=?') and $sth->execute($per_t, $prop_t)) {
	carp 'Could not remove requested price relation';
	return undef;
    }

    return 1;
}

1;

# $Log: monetary_adm.pm,v $
# Revision 1.5  2003/12/20 04:14:51  mig
# - Agrego tags Id y Log que expanda el CVS
#
