<?php
  /**
   * phpaga
   *
   * Return simple query results or execute actions.
   *
   * This page is called by xmlhttprequests/Ajax requests.
   *
   * @author Florian Lanthaler <florian@phpaga.net>
   * @version $Id$
   *
   * Copyright (c) 2005, 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.
   */

include_once("./config.php");

if (!isset($REQUEST_DATA["saction"]) || !is_numeric($REQUEST_DATA["saction"]))
    return '';

switch ($REQUEST_DATA["saction"]) {

    case ACTION_SERVICE_GETCURRTIME:
        /*
         * Get the current time.
         */
        $response = array('status' => 0, 'message' => '', 'data' => array('time' => phpaga_getCurrentDateTimeFormatted()));
        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;

    case ACTION_SERVICE_PAYTERM:
        /*
         * Get a company's default payment term.
         */
        $response = array('status' => 0, 'message' => '', 'data' => array());
        if (isset($REQUEST_DATA["id"]) && is_numeric($REQUEST_DATA["id"]))
            $response['data']['term'] = phpaga_companies_getdefaultpayterm($REQUEST_DATA["id"]);
        else {
            $response['status'] = 20;
            $response['message'] = _('Invalid company ID.');
        }
        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;

    case ACTION_SERVICE_MEMBERPARM:
        /*
         * Get a persons's job category and default hourly rate.
         * Used when adding a new member to a project.
         */
        $response = array('status' => 0, 'message' => '', 'data' => array());
        if (isset($REQUEST_DATA["id"]) && is_numeric($REQUEST_DATA["id"])) {
            $peInfo = phpaga_persons_getInfo($REQUEST_DATA["id"]);

            if (!PhPagaError::isError($peInfo))
            {
                if (isset($peInfo["jcat_id"]))
                    $response['data']['jcat_id'] = $peInfo["jcat_id"];

                if (isset($peInfo["pe_hourlyrate"]))
                    $response['data']['pe_hourlyrate'] = $peInfo["pe_hourlyrate"];
            }
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;

    case ACTION_SERVICE_OPDETAILS:
        /*
         * Fetch a task's details in html.
         */
        $html = '';

        if (isset($REQUEST_DATA['id']) && is_numeric($REQUEST_DATA['id']))
        {
            $opInfo = array();
            $prjInfo = array();

            $opInfo = phpaga_operations_getInfo($REQUEST_DATA['id']);

            if (!PhPagaError::isError($opInfo)) {

                $prjInfo = phpaga_projects_getInfo($opInfo['prj_id']);
                if (!PhPagaError::isError($prjInfo) && count($prjInfo)) {

                    $tpl = new psmarty;
                    $tpl->assign('prjInfo', $prjInfo);
                    $tpl->assign('opInfo', $opInfo);
                    $tpl->assign('isdiv', true);
                    $html = $tpl->fetch('view_operation.tpl.html');
                }
            }
        }

        print $html;
        break;


    case ACTION_SERVICE_GETADDTASK_HTML:
        /*
         * Fetch the "add task form" in html.
         */
        $err = false;
        $errtxt = null;
        $oid = null;
        $otxt = null;
        $ismember = false;
        $can_manage = false;
        $prjInfo = array();
        $select_user = array();

        $html = '';

        if (isset($REQUEST_DATA["id"]) && is_numeric($REQUEST_DATA["id"])) {

            $prj_id = $REQUEST_DATA["id"];

            $ismember = phpaga_project_is_member($prj_id, $_SESSION["auth_user"]["pe_id"]);
            $can_manage = phpaga_project_canmanage($prj_id);

            /* User can add tasks if she is a project member or if she has the right to manage this project */

            if (!$ismember && !$can_manage) {
                $err = true;
                $errtxt = _("You cannot file tasks for this project because you are not a member or manager.");
            } else {

                $prjInfo = phpaga_projects_getInfo($prj_id);
                $opInfo = array('pe_id' => $_SESSION['auth_user']['pe_id'], 'op_startdate' => date('Y-m-d'));

                if (!PhPagaError::isError($prjInfo) && count($prjInfo)) {

                    $select_opcat = phpaga_operations_getCategoryList();
                    phpaga_arrayAddOption($select_opcat, PHPAGA_OPTION_SELECT);

                    /* Only the project owner and overall project managers can set an operation's user */

                    if (!$can_manage) {
                        $peInfo = phpaga_persons_getInfo($_SESSION["auth_user"]["pe_id"]);
                        $select_user[$peInfo["pe_id"]] = sprintf("%s (%s)",
                                                                 $peInfo["pe_person"],
                                                                 $_SESSION["auth_user"]["usr_login"]);
                    } else {
                        $userInfo["prj_id"] = $prj_id;
                        $users = phpaga_user_search($userInfo);

                        foreach ($users as $u)
                            $select_user[$u["pe_id"]] = $u["pe_name"]." (".$u["usr_login"].")";
                    }
                
                    if (isset($prjInfo["prj_billabletype"]) && ($prjInfo["prj_billabletype"] != 10))
                        $opInfo["billable_checked"] = true;
                    else
                        $opInfo["billable_checked"] = false;

                    $tpl = new psmarty;
                    $tpl->assign('opInfo', $opInfo);
                    $tpl->assign('editprjInfo', $prjInfo);
                    $tpl->assign('select_person', $select_user);
                    $tpl->assign('select_opcat', $select_opcat);
                    $html = $tpl->fetch('add_operation_div.tpl.html');

                } else {
                    $err = true;
                    $errtxt = $prjInfo->getMessage();
                }
            }

        } else {
            $err = true;
            $errtxt = _("Invalid project");
        }

        if ($err && strlen($errtxt))
            $html = $errtxt;

        print $html;
        break;


    case ACTION_SERVICE_ADDTASK:
        /*
         * Add a task (operation) to a project.
         */
        $op_id = null;
        $err = false;
        $errtxt = null;
        $ismember = false;
        $can_manage = false;
        $values = null;
        $opInfo = array();

        $response = array('status' => -1, 'message' => _('An error has occurred.'), 'data' => array());

        if (isset($REQUEST_DATA['prj_id']) && is_numeric($REQUEST_DATA['prj_id'])) {

            $prj_id = $REQUEST_DATA['prj_id'];
            $opInfo['prj_id'] = $prj_id;

            $ismember = phpaga_project_is_member($prj_id, $_SESSION['auth_user']['pe_id']);
            $can_manage = phpaga_project_canmanage($prj_id);

            if (!$ismember && !$can_manage) {
                $err = true;
                $errtxt = _('You cannot file tasks for this project because you are not a member or manager.');
            } else {

                /* Only the project owner and overall project managers can set an operation's user */

                if (!$can_manage)
                    $opInfo['pe_id'] = $_SESSION['auth_user']['pe_id'];
                else
                    $opInfo['pe_id'] = $REQUEST_DATA['pe_id'];

                if (isset($REQUEST_DATA['op_billabletype']) && ($REQUEST_DATA['op_billabletype'] == '0')) {
                    $opInfo['op_billabletype'] = 0;
                    $opInfo['billable_checked'] = true;
                } else {
                    $opInfo['op_billabletype'] = 10;
                    $opInfo['billable_checked'] = false;
                }

                $opInfo['opcat_id'] = $_POST['opcat_id'];
                $opInfo['op_desc'] = $_POST['op_desc'];
                $opInfo['op_duration'] = $_POST['op_duration'];

                /* If the duration is numeric, convert it from fractional hours into hours:minutes */

                if (is_numeric($opInfo["op_duration"])) {
                    // Under 24 - assume the duration was given in hours
                    if ($opInfo["op_duration"] < 24)
                        $opInfo["op_duration"] = (int)$opInfo["op_duration"].':'.sprintf('%02d', 60 * ($opInfo["op_duration"] - (int)$opInfo["op_duration"]));
                    // More than 60 minutes, different calculation
                    elseif ($opInfo["op_duration"] >= 60)
                        $opInfo["op_duration"] = (int)($opInfo["op_duration"] / 60).':'.sprintf('%02d', $opInfo["op_duration"] % 60);
                    // Duration given in minutes
                    else
                        $opInfo["op_duration"] = '0:'.(int)$opInfo["op_duration"];
                }

                /* Convert valid start date and time to a timestamp */

                $opInfo['op_startdate']  = $_POST['op_startdate'];
                $opInfo['op_starthours'] = $_POST['op_starthours'];

                $start_tmp = '';

                if ($opInfo['op_startdate'] != '') {

                    $start_tmp = $opInfo['op_startdate'];

                    if ($opInfo['op_starthours'] != '')
                        $start_tmp .= ' '.$opInfo['op_starthours'];

                    $opInfo['op_start'] = $start_tmp;
                } else
                    $opInfo['op_start'] = null;

                /* Convert valid end date and time to a timestamp */

                $opInfo['op_enddate']  = $_POST['op_enddate'];
                $opInfo['op_endhours'] = $_POST['op_endhours'];

                $end_tmp = '';

                if ($opInfo['op_enddate'] != '') {

                    $end_tmp = $opInfo['op_enddate'];

                    if ($opInfo['op_endhours'] != '')
                        $end_tmp .= ' '.$opInfo['op_endhours'];

                    $opInfo['op_end'] = $end_tmp;
                } else
                    $opInfo['op_end'] = null;

                /* Check if operation data is valid and add the operation */

                $result = phpaga_operations_validdata($opInfo);

                if (PhPagaError::isError($result)) {
                    $err = true;
                    $errtxt = $result->getMessage();
                } else {
                    $op_id = phpaga_operations_add($opInfo);

                    if (PhPagaError::isError($op_id)) {
                        $err = true;
                        $errtxt = $op_id->getMessage();
                    } else {

                        $duration = phpaga_projects_getDuration($prj_id);
                        $opInfo = phpaga_operations_getInfo($op_id);

                        if (PhPagaError::isError($opInfo)) {
                            $err = true;
                            $errtxt = $opInfo->getMessage();
                        } else {

                            $taskdate = phpaga_strftime(PHPAGA_DATEFORMAT_SHORT, $opInfo["op_start"]);

                            if (strlen($opInfo['prj_title']) > PHPAGA_SHOWPRJTITLELENGHT)
                                $prj_title = phpaga_substr($opInfo['prj_title'], 0, PHPAGA_SHOWPRJTITLELENGHT).'...';
                            else
                                $prj_title = $opInfo['prj_title'];

                            if (strlen($opInfo['op_desc']) > PHPAGA_SHOWOPDESCLENGHT)
                                $op_desc = phpaga_substr($opInfo['op_desc'], 0, PHPAGA_SHOWOPDESCLENGHT).'...';
                            else
                                $op_desc = $opInfo['op_desc'];

                            $deltxt = phpaga_jsmessage_sanitizestr(sprintf("%s\n%s: %s\n%s: %s",
                                                                           $taskdate,
                                                                           _("Project"),
                                                                           $opInfo['prj_title'],
                                                                           _("Task"),
                                                                           $opInfo['op_desc']));

                            $response['status'] = 0;
                            $response['message'] = _('The task has been saved.');

                            $response['data'] = array('prjid' => $prj_id,
                                'prjduration' => $duration,
                                'prjtitle' => $prj_title,
                                'opcat' => $opInfo['opcat_title'],
                                'opid' => $op_id,
                                'opdesc' => $op_desc,
                                'opstart' => $taskdate,
                                'opduration' => $opInfo['op_duration'],
                                'deltxt' => $deltxt);
                        }
                    }
                }
            }
        }

        if ($err) {
            $response['status'] = 20;

            if (strlen($errtxt))
                $response['message'] = $errtxt;
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;


    case ACTION_SERVICE_MATDETAILS:
        /*
         * Get material details for a given material ID.
         */
        $html = '';

        if (isset($REQUEST_DATA["id"]) && is_numeric($REQUEST_DATA["id"]))
        {
            $matInfo = array();
            $prjInfo = array();

            $matInfo = phpaga_materials_getInfo($REQUEST_DATA["id"]);
            if (!PhPagaError::isError($matInfo))
            {
                $prjInfo = phpaga_projects_getInfo($matInfo["prj_id"]);
                if (!PhPagaError::isError($prjInfo) && count($prjInfo)) {

                    $tpl = new psmarty;
                    $tpl->assign("prjinfo", $prjInfo);
                    $tpl->assign("matinfo", $matInfo);
                    $html = $tpl->fetch("material.tpl.html");
                }
            }
        }

        print $html;
        break;


    case ACTION_SERVICE_PRODINFO:
        /*
         * Get product info for a given product code.
         */
        $h_status = null;
        $err = true;
        $response = array('status' => -1, 'message' => null, 'data' => array());
        $data = array();
        $errtxt = _('An error has occurred.');

        if (isset($REQUEST_DATA["prod_code"]) && strlen($REQUEST_DATA["prod_code"])) {
            $prodInfo = array();
            $prodInfo = phpaga_products_getInfo($REQUEST_DATA["prod_code"], true);

            if (!PhPagaError::isError($prodInfo)) {
                $err = false;
                if (is_array($prodInfo) && count($prodInfo)) {
                    $response['status'] = 0;
                    $response['data'] = array('prod_name' => $prodInfo['prod_name'],
                        'prod_price' => $prodInfo['prod_price'],
                        'prod_id' => $prodInfo['prod_id']);
                } else {
                    $response['status'] = 30;
                    $response['message'] = _('No matching products have been found.');
                }

            }
        }

        if ($err) {
            $response['status'] = 20;

            if (strlen($errtxt))
                $response['message'] = $errtxt;
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;


    case ACTION_SERVICE_GETEMPLOYEES:
        /*
         * Get an array with employees for a given company.
         */
        $response = array('status' => -1, 'message' => null, 'data' => array('persons' => array()));
        $persons = array();
        $persons_count = 0;
        $err = true;
        $errtxt = _('An error has occurred.');

        if (isset($REQUEST_DATA['id']) && strlen($REQUEST_DATA['id'])) {

            $persons = phpaga_persons_list($persons_count, null, $REQUEST_DATA['id']);

            if (!PhPagaError::isError($persons)) {
                $err = false;
                $response['status'] = 0;
                foreach ($persons as $p)
                    $response['data']['persons'][] = array('id' => (int)$p['pe_id'], 'name' => $p['pe_person']);

            } 
        }
        if ($err) {
            $response['status'] = 20;

            if (strlen($errtxt))
                $response['message'] = $errtxt;
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;



    case ACTION_SERVICE_LOGIN:
        /*
         * Perform a user's login.
         */

        $response = array('status' => -1, 'message' => null, 'data' => null);
        $err = false;
        $errtxt = _('An error has occurred.');

        $login = phpaga_fetch_POST('login');
        $passwd = phpaga_fetch_POST('passwd');

        if (!isset ($login) || !strlen($login)) {
            $err = true;
            $errtxt = _("Invalid login or password.");
        }

        if (!isset ($passwd) || !strlen($passwd)) {
            $err = true;
            $errtxt = _("Invalid login or password.");
        }

        if (!$err) {

            $userID = phpaga_auth_login($login, $passwd);

            if (PhPagaError::isError($userID)) {
                $err=true;
                if (($userID->getCode() == PHPAGA_ERR_USER_INVALIDID) || ($userID->getCode() == PHPAGA_ERR_DB_FETCHVALUE))
                    $errtxt = _("Invalid login or password.");
                else
                    $errtxt = $userID->getMessage();
            } else {

                $userInfo = phpaga_user_getUserInfo($userID);

                if (PhPagaError::isError($userInfo)) {
                    $err=true;
                    $errtxt = _("Invalid login or password.");
                } else {
                    session_destroy();
                    session_start();
                    $_SESSION["auth_session"] = 1;
                    $_SESSION["auth_user"] = $userInfo;
                    $response['status'] = 0;
                    $response['message'] = _('Login successful');
                }
            }
        }

        if ($err) {
            $response['status'] = 99;

            if (strlen($errtxt))
                $response['message'] = $errtxt;
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;

    case ACTION_SERVICE_DELETE_USER:
        /*
         * Delete a user.
         */

        $response = array('status' => -1, 'message' => null, 'data' => null);
        $err = false;
        $errtxt = _('An error has occurred.');

        $usr_id = phpaga_fetch_POST('usr_id');
        if (!isset ($usr_id) || !is_numeric($usr_id)) {
            $err = true;
            $errtxt = _("Invalid user.");
        } else {
            $result = phpaga_user_delete($usr_id);
            if (PhPagaError::isError($result)) {
                $err = true;
                $errtxt = $result->getMessage();
            } else
                $response['status'] = 0;
        }

        if ($err) {
            $response['status'] = 99;
            if (strlen($errtxt))
                $response['message'] = $errtxt;
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;


    case ACTION_SERVICE_DELETE_OP:
        /*
         * Delete a task. Note that only the task owner or the project manager can remove a task.
         */

        $response = array('status' => -1, 'message' => null, 'data' => null);
        $err = false;
        $errtxt = _('An error has occurred.');

        $op_id = phpaga_fetch_POST('op_id');
        if (!isset ($op_id) || !is_numeric($op_id)) {
            $err = true;
            $errtxt = _("Invalid task.");
        } else {

            $opInfo = array();
            $opInfo = phpaga_operations_getInfo($op_id);

            if (PhPagaError::isError($opInfo)) {
                $err = true;
                $errtxt = $opInfo->getMessage();
            } else {

                $prjmanage = phpaga_project_canmanage($opInfo['prj_id']);

                if (!$prjmanage && ($opInfo['pe_id'] != $_SESSION['auth_user']['pe_id'])) {
                    $err = true;
                    $errtxt = _('You do not have the required permission to delete this record.');
                } else {
                    $result = phpaga_operations_delete($op_id);
                    if (PhPagaError::isError($result)) {
                        $err = true;
                        $errtxt = $result->getMessage();
                    } else
                        $response['status'] = 0;
                }
            }
        }

        if ($err) {
            $response['status'] = 99;
            if (strlen($errtxt))
                $response['message'] = $errtxt;
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;


    case ACTION_SERVICE_PRJHOURS:
        /*
         * Fetch the number of hours tracked for a particular project.
         */

        $response = array('status' => -1, 'message' => null, 'data' => null);
        $err = false;
        $errtxt = _('An error has occurred.');

        $prj_id = phpaga_fetch_GET('id');
        if (!isset ($prj_id) || !is_numeric($prj_id)) {
            $err = true;
            $errtxt = _("Invalid project.");
        } else {
            $result = phpaga_projects_getDuration($prj_id);
            if (PhPagaError::isError($result)) {
                $err = true;
                $errtxt = $result->getMessage();
            } else {
                $response['status'] = 0;
                $response['data'] = $result;
            }
        }

        if ($err) {
            $response['status'] = 99;
            if (strlen($errtxt))
                $response['message'] = $errtxt;
        }

        header('Content-Type: text/javascript; charset=utf8');
        print json_encode($response);
        break;


    default:
        print '';
        break;
}

?>
