<?php
/**
 * phpaga
 *
 * Expenses functionality.
 *
 * This file contains the necessary routines to manage expenses.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @version $Id$
 *
 * Copyright (c) 2003, Florian Lanthaler <florian@phpaga.net>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in
 *      the documentation and/or other materials provided with the
 *      distribution.
 *
 *    * Neither the name of Florian Lanthaler nor the names of his
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Checks if all fields of an expense contain valid values.
 *
 *
 * @param  array  $expInfo  Array containing the expense's information.
 *
 * @return bool   $errors  True. A PhPagaError object on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.2
 */

function phpaga_expenses_validdata($expInfo)
{

    $errors = array();

    if (!is_array($expInfo))
        $expInfo = array($expInfo);

    if (!phpaga_checkdate($expInfo['exp_date']))
        $errors[] = PHPAGA_ERR_INVALID_DATEFORMAT;

    if (!isset($expInfo['exp_desc']) || !strlen(trim($expInfo['exp_desc'])))
        $errors[] = PHPAGA_ERR_EXP_DESC;

    if (!isset($expInfo['prj_id']) || !is_numeric($expInfo['prj_id']))
        $errors[] = PHPAGA_ERR_PROJECT_INVALIDID;

    if (!isset($expInfo['pe_id']) || !is_numeric($expInfo['pe_id']))
        $errors[] = PHPAGA_ERR_PERSON_INVALIDID;

    if (!isset($expInfo['curr_id']) || !is_numeric($expInfo['curr_id']))
        $errors[] = PHPAGA_ERR_CURRENCY_INVALIDID;

    if (isset($expInfo['curr_id_foreign']) && strlen($expInfo['curr_id_foreign']) && !is_numeric($expInfo['curr_id_foreign']))
        $errors[] = PHPAGA_ERR_CURRENCY_INVALIDID;

    if (!isset($expInfo['exp_sum']) || !is_numeric($expInfo['exp_sum']))
        $errors[] = PHPAGA_ERR_EXP_INVALIDSUM;

    if (isset($expInfo['exp_sum_foreign']) && strlen($expInfo['exp_sum_foreign']) && !is_numeric($expInfo['exp_sum_foreign']))
        $errors[] = PHPAGA_ERR_EXP_INVALIDSUM;

    if (isset($expInfo['exp_exchange_rate']) && strlen($expInfo['exp_exchange_rate']) && !is_numeric($expInfo['exp_exchange_rate']))
        $errors[] = PHPAGA_ERR_EXP_INVALIDEXCHANGERATE;

    if (count($errors))
        return PhPagaError::raiseErrorByCode($errors);

    return true;
}


/**
 * Adds an expense to the database
 *
 * @param array   $expInfo    Array containing the expense information
 *
 * @return int    $result     ID of the freshly inserted expense. A PhPagaError object on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.2
 */

function phpaga_expenses_add($expInfo)
{

    $result = phpaga_expenses_validdata($expInfo);

    if (PhPagaError::isError($result))
        return $result;

    if (!isset($expInfo['exp_sum_foreign']) || !strlen($expInfo['exp_sum_foreign']))
        $expInfo['exp_sum_foreign'] = null;

    if (!isset($expInfo['curr_id_foreign']) || !strlen($expInfo['curr_id_foreign']))
        $expInfo['curr_id_foreign'] = null;

    if (!isset($expInfo['exp_exchange_rate']) || !strlen($expInfo['exp_exchange_rate']))
        $expInfo['exp_exchange_rate'] = null;

    $d = new PhPagaDbData;
    $exp_id = $d->nextId('expenses_exp_id');

    $fields = array('exp_id' => $exp_id,
                    'exp_date' => $expInfo['exp_date'],
                    'pe_id' => $expInfo['pe_id'],
                    'prj_id' => $expInfo['prj_id'],
                    'exp_desc' => $expInfo['exp_desc'],
                    'exp_sum' => $expInfo['exp_sum'],
                    'curr_id' => $expInfo['curr_id'],
                    'exp_sum_foreign' => $expInfo['exp_sum_foreign'],
                    'curr_id_foreign' => $expInfo['curr_id_foreign'],
                    'exp_exchange_rate' =>$expInfo['exp_exchange_rate']);

    $r = $d->insert('expenses', $fields);

    if (PhPagaError::isError($r))
        return $r;

    return $exp_id;
}


/**
 * Fetches the expenses according to the search parameters in expInfo.
 *
 * @param array   $expInfo        Array containing search parameters

 * @return array  $expenses       Array containing the results. A PhPagaError object on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.2
 */

function phpaga_expenses_getexpenses($expInfo)
{

    $expenses = array();
    $where = array();
    $qparam = array();

    if (!is_array($expInfo))
        $expInfo = array();

    $query = 'SELECT exp_id, e.pe_id, pe_firstname, pe_lastname, exp_date,
        e.prj_id, prj_title, exp_desc, exp_sum, e.curr_id, c.curr_name,
        exp_sum_foreign, e.curr_id_foreign, c2.curr_name AS curr_name_foreign,
        exp_exchange_rate, e.bill_id
        FROM expenses e
        LEFT JOIN persons p ON p.pe_id = e.pe_id
        LEFT JOIN currencies c ON c.curr_id = e.curr_id
        LEFT JOIN projects s ON s.prj_id = e.prj_id
        LEFT JOIN currencies c2 ON c2.curr_id = e.curr_id_foreign ';

    if (isset($expInfo['idlist']) && is_array($expInfo['idlist']) && count($expInfo['idlist']))
        $where[] = sprintf('exp_id IN (%s)', implode(', ', $expInfo['idlist']));

    if (isset($expInfo['bill_id']) && is_numeric($expInfo['bill_id'])) {
        $where[] = 'e.bill_id = ?';
        $qparam[] = $expInfo['bill_id'];
    }

    if (array_key_exists('bill_id', $expInfo) && is_null($expInfo['bill_id']))
        $where[] = 'e.bill_id IS NULL ';

    if (isset($expInfo['pe_id']) && is_numeric($expInfo['pe_id'])) {
        $where[] = 'e.pe_id = ?';
        $qparam[] = $expInfo['pe_id'];
    }

    if (isset($expInfo['prj_id']) && is_numeric($expInfo['prj_id'])) {
        $where[] = 'e.prj_id = ?';
        $qparam[] = $expInfo['prj_id'];
    }

    if (isset($expInfo['curr_id']) && is_numeric($expInfo['curr_id'])) {
        $where[] = 'e.curr_id = ?';
        $qparam[] = $expInfo['curr_id'];
    }

    if (isset($expInfo['curr_id_foreign']) && is_numeric($expInfo['curr_id_foreign'])) {
        $where[] = 'e.curr_id_foreign = ?';
        $qparam[] = $expInfo['curr_id_foreign'];
    }

    if (isset($expInfo['cpn_id']) && is_numeric($expInfo['cpn_id'])) {
        $where[] = 's.cpn_id = ?';
        $qparam[] = $expInfo['cpn_id'];
        }

    if (count($where) > 0)
        $query .=  sprintf('WHERE %s ', implode(' AND ', $where));

    $query .= ' ORDER BY e.exp_date ';

    $d = new PhPagaDbData;

    $r = $d->queryAll($query, $qparam);

    if (PhPagaError::isError($r))
        return $r;

    foreach ($r as $qrow) {

        phpaga_sanitizeArray($qrow);

        $qrow['exp_sum'] = (float) $qrow['exp_sum'];
        $qrow['exp_sum_foreign'] = (float) $qrow['exp_sum_foreign'];
        $qrow['exp_exchange_rate'] = (float) $qrow['exp_exchange_rate'];
        $qrow['pe_person'] = phpaga_persons_formatname ($qrow['pe_lastname'], $qrow['pe_firstname']);

        $expenses[] = $qrow;
    }

    return $expenses;
}


/**
 * Delete an expense if is has not been billed yet.
 *
 * @param  int     $exp_id      Expense Id
 *
 * @return bool    $result      True if successful. A PhPagaError object on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.4
 */

function phpaga_expenses_delete($exp_id)
{
    if (!isset($exp_id) || !is_numeric($exp_id))
        return PhPagaError::raiseErrorByCode(PHPAGA_ERR_INVALID_PARAMTYPE);

    $d = new PhPagaDbData;

    $n = $d->queryOneVal('SELECT bill_id FROM expenses WHERE exp_id = ?', (int)$exp_id);

    if (PhPagaError::isError($n))
        return $n;

    if (strlen($n))
        return PhPagaError::raiseErrorByCode(PHPAGA_ERR_DEL_DEPENDENCIES);

    $result = $d->execute('DELETE FROM expenses WHERE exp_id = ?', $exp_id);

    if (PhPagaError::isError($result))
        return $result;

    return true;
}

?>
