<?php
/**
 * phpaga
 *
 * finances functionality.
 *
 * This file contains the necessary routines for displaying some financial information.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @version $Id: finances.php 856 2007-09-15 20:54:05Z florian $
 *
 * Copyright (c) 2002, 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.
 */

/**
 * Returns an array containing the amount of money billed per month.
 *
 * @param int    $curr_id          Currency ID
 * @param int    $year             Fiscal year
 *
 * @return array $billedPerMonth  Array containing amount of money
 *                                billed per month for the currency selected
 *                                A PhPagaError on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_finances_billedPerMonth($curr_id, $year = null)
{
    $r = array();

    if (!isset($year) || !is_numeric($year))
        $year = phpaga_finances_getfiscalyear(date('Y-m-d'));

    $fy_dates = phpaga_finances_getfiscalyeardates($year);

    $d = new PhPagaDbData;

    $r = $d->queryAll('SELECT SUM(bill_endsum) AS amount, MONTH(bill_date) AS month, curr_name, bills.curr_id
        FROM bills
        LEFT JOIN currencies ON currencies.curr_id = bills.curr_id
        WHERE ((bill_date >= ?)
        AND (bill_date <= ?))
        AND (bills.curr_id = ?)
        GROUP BY MONTH(bill_date), curr_name, bills.curr_id
        ORDER BY month(bill_date)',
                      array($fy_dates['start'], $fy_dates['end'], (int)$curr_id));

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

    return $r;
}


/**
 * Returns an array containing the amount of money received through paid bills
 * per month.
 *
 * @param int    $curr_id          Currency ID
 * @param int    $year             Fiscal year
 *
 * @return array $paidPerMonth     Array containing amount of money
 *                                 billed per month for the currency selected.
 *                                 A PhPagaError on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_finances_paidPerMonth($curr_id, $year = null)
{
    $r = array();

    if (!isset($year) || !is_numeric($year))
        $year = phpaga_finances_getfiscalyear(date('Y-m-d'));

    $fy_dates = phpaga_finances_getfiscalyeardates($year);

    $d = new PhPagaDbData;

    $r = $d->queryAll('SELECT SUM(bill_endsum) AS amount,
        MONTH(bill_paydate) AS month,
        curr_name, bills.curr_id
        FROM bills
        LEFT JOIN currencies ON currencies.curr_id = bills.curr_id
        WHERE  ((bill_paydate >= ?)
        AND (bill_paydate <= ?))
        AND (bills.curr_id = ?)
        GROUP BY MONTH(bill_paydate), curr_name, bills.curr_id
        ORDER BY month(bill_paydate)',
                      array($fy_dates['start'], $fy_dates['end'], (int)$curr_id));

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

    return $r;
}


/**
 * Returns an array containing the amount of money billed per company. Should
 * help you find out who is your biggest client. :)
 *
 * @param int    $curr_id            Currency ID
 * @param int    $year               Fiscal year
 *
 * @return array $billedPerCompany   Array containing amount of money
 *                                   billed per company for the currency selected.
 *                                   A PhPagaError on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.1
 */

function phpaga_finances_billedPerCompany ($curr_id, $year = null)
{
    $r = array ();
    $billedPerCompany = array();

    if (!isset($year) || !is_numeric($year))
        $year = phpaga_finances_getfiscalyear(date('Y-m-d'));

    $fy_dates = phpaga_finances_getfiscalyeardates($year);

    $d = new PhPagaDbData;

    $r = $d->queryAll('SELECT companies.cpn_name, bills.cpn_id, SUM(bill_endsum) AS amount,
        curr_name, curr_decimals
        FROM bills
        LEFT JOIN companies ON companies.cpn_id = bills.cpn_id
        LEFT JOIN currencies ON currencies.curr_id = bills.curr_id
        WHERE ((bill_date >= ?)
        AND (bill_date <= ?))
        AND (bills.curr_id = ?)
        GROUP BY bills.cpn_id, companies.cpn_name, curr_name, curr_decimals
        ORDER BY amount DESC',
                      array($fy_dates['start'], $fy_dates['end'], (int)$curr_id));

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

    foreach ($r as $qrow) {

        $qrow['amount_src'] = $qrow['amount'];
        $qrow['amount'] =
            trim (number_format(
                      $qrow['amount'], $qrow['curr_decimals'],
                      PHPAGA_SEPARATOR_DECIMALS,
                      PHPAGA_SEPARATOR_THOUSANDS));
        $billedPerCompany[] = $qrow;
    }

    return $billedPerCompany;
}


/**
 * Returns the fiscal year for a given date.
 *
 * @param  string $date      Date
 *
 * @return int    $year      Fiscal year for the given date or false on error.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_finances_getfiscalyear($date)
{

    if (!strlen($date))
        return false;

    $fy_dates = phpaga_finances_getfiscalyeardates(date('Y', strtotime($date)));

    $tstamp = strtotime($date);
    $tstamp_end = strtotime($fy_dates['end']);

    if ($tstamp < $tstamp_end)
        return((int)date('Y', $tstamp_end));
    else
        return((int)date('Y', $tstamp_end) + 1);
}


/**
 * Returns the start end end date for a given fiscal year. (Each
 * fiscal year is identified by the calendar year in which it ends.)
 *
 * @param  int    $year      Fiscal year
 *
 * @return array  $dates     Start end end dates for the fiscal year
 *                           ($date['start'] and $date['end'])
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_finances_getfiscalyeardates($fy)
{

    $dates = array('start' => false,
                   'end' => false);

    if (!strlen($fy) || !is_numeric($fy))
        return $dates;

    $t = strtotime(sprintf("%s-%s-%s",
                           $fy,
                           PHPAGA_FIN_FISCYEAR_MONTH,
                           PHPAGA_FIN_FISCYEAR_DAY));

    $md = date('m-d', strtotime("-1 day", $t));

    $dates['end'] = sprintf("%s-%s", $fy, $md);
    $dates['start'] = date('Y-m-d',
                         strtotime("-1 year +1 day",
                                   strtotime($dates['end'])));

    return $dates;
}


/**
 * Returns an array containing the amount of money billed, received,
 * and missing per customer.
 *
 * @param int    $curr_id            Currency ID
 * @param int    $year               Fiscal year
 *
 * @return array $details            Array containing amount of money
 *                                   billed, received, and missing per
 *                                   company for the selected curreny
 *                                   and year. A PhaPagaError on failure.
 *
 * @author Florian Lanthaler <florian@phpaga.net>
 * @since phpaga 0.3
 */

function phpaga_finances_getSumsPerCustomerYearly($curr_id, $year = null)
{
    $details = array('details' => array(),
                     'totals' => array('billed' => 0,
                                       'paid' => 0,
                                       'missing' => 0));
    $cpn = array();

    if (!isset($year) || !is_numeric($year))
        $year = phpaga_finances_getfiscalyear(date('Y-m-d'));

    $fy_dates = phpaga_finances_getfiscalyeardates($year);

    $d = new PhPagaDbData;

    $query = 'SELECT companies.cpn_name, bills.cpn_id, SUM(bill_endsum) AS amount
        FROM bills
        LEFT JOIN companies ON companies.cpn_id = bills.cpn_id
        WHERE ((bill_date >= ?)
        AND (bill_date <= ?))
        AND (bills.curr_id = ?)
        GROUP BY bills.cpn_id, companies.cpn_name
        ORDER BY companies.cpn_name';

    $r = $d->queryAll($query, array($fy_dates['start'], $fy_dates['end'], (int)$curr_id));

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

    foreach ($r as $qrow) {
        $cpn[$qrow['cpn_name'].'-'.$qrow['cpn_id']] = array('cpn_id' => $qrow['cpn_id'],
                                                            'cpn_name' => $qrow['cpn_name'],
                                                            'sum_billed' => $qrow['amount'],
                                                            'sum_paid' => 0,
                                                            'sum_missing' => 0);

        $details['totals']['billed'] += $qrow['amount'];
    }

    $query = 'SELECT companies.cpn_name, bills.cpn_id, SUM(bill_endsum) AS amount
        FROM bills
        LEFT JOIN companies ON companies.cpn_id = bills.cpn_id
        WHERE ((bill_paydate >= ?)
        AND (bill_paydate <= ?))
        AND (bills.curr_id = ?)
        GROUP BY bills.cpn_id, companies.cpn_name';

    $r = $d->queryAll($query, array($fy_dates['start'], $fy_dates['end'], (int)$curr_id));

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

    foreach ($r as $qrow) {

        if (isset($cpn[$qrow['cpn_name'].'-'.$qrow['cpn_id']]))
            $cpn[$qrow['cpn_name'].'-'.$qrow['cpn_id']]['sum_paid'] = $qrow['amount'];
        else
            $cpn[$qrow['cpn_name'].'-'.$qrow['cpn_id']] = array('cpn_id' => $qrow['cpn_id'],
                                                                'cpn_name' => $qrow['cpn_name'],
                                                                'sum_billed' => 0,
                                                                'sum_paid' => $qrow['amount'],
                                                                'sum_missing' => 0);

        $details['totals']['paid'] += $qrow['amount'];
    }

    $query = 'SELECT companies.cpn_name, bills.cpn_id, SUM(bill_endsum) AS amount
        FROM bills
        LEFT JOIN companies ON companies.cpn_id = bills.cpn_id
        WHERE ((bill_date >= ?)
        AND (bill_date <= ?))
        AND bill_paydate IS NULL
        AND (bills.curr_id = ?)
        GROUP BY bills.cpn_id, companies.cpn_name';

    $r = $d->queryAll($query, array($fy_dates['start'], $fy_dates['end'], (int)$curr_id));

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

    foreach ($r as $qrow) {

        if (isset($cpn[$qrow['cpn_name'].'-'.$qrow['cpn_id']]))
            $cpn[$qrow['cpn_name'].'-'.$qrow['cpn_id']]['sum_missing'] = $qrow['amount'];
        else
            $cpn[$qrow['cpn_name'].'-'.$qrow['cpn_id']] = array('cpn_id' => $qrow['cpn_id'],
                                                                'cpn_name' => $qrow['cpn_name'],
                                                                'sum_billed' => 0,
                                                                'sum_paid' => 0,
                                                                'sum_missing' => $qrow['amount']);

        $details['totals']['missing'] += $qrow['amount'];
    }

    foreach ($cpn as $c)
        $details['details'][] = $c;

    return $details;
}


/**
 * Returns an array containing the amount of money missing per month.
 *
 * @param int    $curr_id           Currency ID
 * @param int    $year              Year
 *
 * @return array $missingPerMonth   Array containing amount of money
 *                                  missing per month for the currency selected.
 *                                  A PhPagaError on failure.
 *
 * @author Jeremy Heslop <jeremy@jheslop.com>
 * @since phpaga 20050806
 */

function phpaga_finances_missingPerMonth($curr_id, $year = null)
{
    $r = array ();

    if (!isset($year) || !is_numeric($year))
        $year = date('Y');

    $d = new PhPagaDbData;

    $r = $d->queryAll('SELECT SUM(bill_startsum) AS amount,
        MONTH(bill_date) AS month,
        curr_name, bills.curr_id
        FROM bills
        LEFT JOIN currencies ON currencies.curr_id = bills.curr_id
        WHERE (YEAR(bill_date) = ?)
        AND (bill_paydate IS NULL)
        AND (bills.curr_id = ?)
        GROUP BY MONTH(bill_date), curr_name, bills.curr_id
        ORDER BY month(bill_date)',
                      array($year, $curr_id));

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

    return $r;
}

?>