/** * Performs the fetch of the work request * * @param $params * Associative array of parameters * - $params->wr: Work Request ID or array of * - $params->user: User ID making the request * @return * - The request object on success * - Error message if access is denied, or wr was not filled. */ function run($params) { $access = access::getInstance(); if ($params['GET']['wr'] == null) { error_logging('WARNING', "No work request number (wr) provided."); return new error('No work request number (wr) provided.'); } if (!preg_match('/^(\\d+)(,\\d+)*$/', $params['GET']['wr'])) { error_logging('WARNING', 'Provided work request (wr) of; "' . $params['GET']['wr'] . '" argument does not match required format.'); return new error('Bad work request (wr) argument. Argument must be in the format of one or more integers seperated by commas.'); } $response = new response('Success'); $sql = 'SELECT * FROM request WHERE request_id IN (' . $params['GET']['wr'] . ')'; $result = db_query($sql); while ($row = db_fetch_object($result)) { if ($access->permitted('wr/view', $row->request_id)) { $object = new WrmsWorkRequest(); $object->populate($row); $object->populateChildren(); $response->data[] = $object; } else { $response->data[] = new error('You cannot access this work request.', 403); # EKM TODO add id not allowed option } } return $response; }
function run($params) { /* * I know this seems backwards, but we check access as one of the last steps * We really need the full WR so we can check if the person has enough access, * so we will build the WR first then check permissions, then write it to the DB */ // WR number - If present, this is an edit, if not it's a create $wr = $params['GET']['wr']; $brief = $params['GET']['brief']; $org = $params['GET']['org']; $person = $params['GET']['person']; $sys = $params['GET']['sys']; $type = $params['GET']['type']; $urgency = $params['GET']['urgency']; $importance = $params['GET']['importance']; $requested_by = $params['GET']['requested_by']; $agreed_due = $params['GET']['agreed_due']; $invoice_to = $params['GET']['invoice_to']; $details = $params['GET']['details']; /* * Other things you can do to a WR that will need implementing * Add files * Add Quotes * Link WRs * Subscribe people * Allocate to people * Assign a tag * Add a QA action * Add a Note - (preserve HTML) * Change the status * Select Quiet update */ if (isset($wr) && is_numeric($wr)) { // We are editing a WR } else { $wr = new WrmsWorkRequest(); //$urgency, $importance, $type, $person, $brief, $details, $sys) return $wr->create($urgency, $importance, $type, $person, $brief, $details, $sys); } $access = access::getInstance(); if ($access->permitted('wr/create', $wr)) { return new response('Access granted'); } else { return new error('You cannot add a WR for this system.', '403'); } }
/** * Performs the fetch of the current status * * @param $params * Associative array of parameters * - $params->wr: Work Request ID * - $params->user: User ID making the request * @return * A character corresponding to the current status on success * FALSE is permission denied * NULL if no work request */ function run($params) { $request_id = $params['GET']['wr']; $access = access::getInstance(); if ($access->permitted('wr/view', $request_id)) { $result = db_query('SELECT * FROM request_status WHERE request_id = %d ORDER BY status_on DESC LIMIT 1', $request_id); if (db_num_rows($result) > 0) { $response = new response('Success'); $object = new WrmsStatus(); $object->populate(db_fetch_object($result)); $response->set('status', $object); return $response; } return new error('No status records found for that Work Request. Please ensure the WR exists.', 400); } else { return new error('Access denied', 403); } }
/** * Performs the fetch of the timesheets by work request * * @param $params * Associative array of parameters * - $params->wr: Work Request ID * - $params->user: User ID making the request * - $params->start_date: Start date to search by * - $params->end_date: End date to search by * Start_date and End_date are inclusive, results will be returned for those days as well. * If one date is ommited a result set its returned for the one day specified by the other date * @return * An array of timesheets or an empty array if no results */ function run($params) { $access = access::getInstance(); $from = $params['GET']['start_date']; $to = $params['GET']['end_date']; $request_id = $params['GET']['wr']; if ($access->permitted('wr/timesheet/view', $request_id)) { $sql = 'SELECT * FROM request_timesheet WHERE request_id = %d '; /* * There may be a better way to do this, but it seems like a sensible validation and or injection stopper - any invalid date will be 1970-01-01 */ if ($from) { $from = date('Y-m-d', strtotime($from)); if ($from == "1970-01-01") { return new error('Invalid date format in start date. Required format: yyyy-mm-dd'); } else { $sql .= "AND work_on >= '{$from}' "; } } if ($to) { $to = date('Y-m-d', strtotime($to)); if ($to == "1970-01-01") { return new error('Invalid date format in end date. Required format: yyyy-mm-dd'); } else { $sql .= "AND work_on <= '{$to}' "; } } $sql .= 'ORDER BY timesheet_id DESC'; $result = db_query($sql, $request_id); $response = new response('Success'); $return = array(); if (db_num_rows($result) > 0) { while ($row = db_fetch_object($result)) { $obj = new WrmsTimeSheet(); $obj->populate($row); $return[] = $obj; } } $response->set('timesheetentries', $return); return $response; } else { return new error('Access denied', 403); } }
/** * Performs the fetch of attached notes * * @param $params * Associative array of parameters * - $params->wr: Work Request ID * - $params->user: User ID making the request * @return * An array of notes on success * An empty array on failure */ function run($params) { $request_id = $params['GET']['wr']; $access = access::getInstance(); if ($access->permitted('wr/view', $request_id)) { $result = db_query('SELECT * FROM request_note WHERE request_id = %d ORDER BY note_on', $request_id); $response = new response('Success'); $notes = array(); while ($row = db_fetch_object($result)) { $note = new WrmsRequestNote(); $note->populateNow($row); $notes[] = $note; } $response->set('notes', $notes); return $response; } else { return new error('Access denied', '403'); } }
/** * Performs the fetch of the subscribed users * * @param $params * Associative array of parameters * - $params->wr: Work Request ID * - $params->user: User ID making the request * @return * An array of users on success * Empty array of failure */ function run($params) { $request_id = $params['GET']['wr']; $access = access::getInstance(); if ($access->permitted('wr/view', $request_id)) { $result = db_query('SELECT user_no FROM request_interested WHERE request_id = %d', $request_id); if (db_num_rows($result) >= 1) { $users = array(); while ($row = db_fetch_object($result)) { $users[] = new user($row->user_no); } $response = new response('Success'); $response->set('users', $users); } return $response; } else { return new error('Access denied', '403'); } }
public function populateChildren() { $access = access::getInstance(); if ($access->permitted('wr/timesheet/view', $this->id)) { $result = db_query("SELECT * FROM request_timesheet WHERE request_id='%d'", $this->id); while ($row = db_fetch_assoc($result)) { $newsheet = new WrmsTimeSheet(); $newsheet->populate($row); $this->timesheets[] = $newsheet; } } # This possibly isn't the smallest implementation, but it will do for the moment. $result = db_query("SELECT * FROM request_note WHERE request_id='%d'", $this->id); while ($row = db_fetch_assoc($result)) { $newnote = new WrmsRequestNote(); $newnote->populate($row); $this->notes[] = $newnote; } }
/** * Performs the fetch list action * * @param $params * Associative array of parameters * - $params->wr: Work Request ID * - $params->user: User ID making the request * @return * An array of status changes ordered from most recent to oldest * An empty array if permission is denied */ function run($params) { $return = array(); $access = access::getInstance(); $request_id = $params['GET']['wr']; if ($access->permitted('wr/view', $request_id)) { $result = db_query('SELECT * FROM request_status WHERE request_id = %d ORDER BY status_on DESC', $request_id); $response = new response('Success'); if (db_num_rows($result) > 0) { while ($row = db_fetch_object($result)) { $obj = new WrmsStatus(); $obj->populate($row); $return[] = $obj; } } $response->set('history', $return); return $response; } else { return new error('Access denied', 403); } }
/** * Performs the fetch of allocated users * * @param $params * Associative array of parameters * - $params->wr: Work Request ID * @return * An array of users on success * An error reponses */ function run($params) { if ($params['GET']['wr'] == null) { error_logging('WARNING', "No work request number (wr) provided."); return new error('No work request number (wr) provided.'); } $request_id = $params['GET']['wr']; $access = access::getInstance(); if ($access->permitted('wr/view', $request_id)) { $result = db_query('SELECT allocated_to_id FROM request_allocated WHERE request_id = %d', $request_id); $users = array(); $response = new response('Success'); while ($row = db_fetch_object($result)) { $users[] = new user($row->allocated_to_id); } $response->set('allocated', $users); return $response; } else { return new error('Access denied', '403'); } }
/** * Performs the insert of the timesheet * * @param $params * Associative array of parameters * - $params->wr: Work Request ID * - $params->datetime: The date and time to record the timesheet for in ISO format * - $params->quantity: The quantity of units to add * - $params->units: The units to use (default: hours) * - $params->rate: Optional rate of charge - if not supplied we apply the WRMS logic. - Note: If units is 'amount' then rate is required * - $params->description: A description about what the time was spent on * @return * TRUE on success, FALSE on failure to add */ function run($params) { // All the things we might need to enter a timesheet $wr = $params['GET']['wr']; $datetime = $params['GET']['datetime']; $quantity = $params['GET']['quantity']; $units = $params['GET']['units']; $rate = $params['GET']['rate']; $description = $params['GET']['description']; $needsreview = (int) (bool) $params['GET']['needs_review']; // Who are we logged in as, and can we actually add timesheets? $user = currentuser::getInstance(); $access = access::getInstance(); if ($access->permitted('wr/timesheet/add', $wr)) { // Get the ID of the user $id = $user->getID(); if ($id == null) { return new error('You must be logged in to add a timesheet', '403'); } // Is this a real WR? $result = db_query("SELECT request_id FROM request WHERE request_id = %d", $wr); if (db_fetch_object($result) == null) { return new error("You cannot put time against a non-existant work request", '405'); } // Make sure the date and time are valid - convert to wrms-happy timestamp $timestamp = date('Y-m-d H:i:s', strtotime($datetime)); if ($timestamp == 0 || $timestamp == 43200) { # Change to proper UTC time at some point return new error('Unable to add timesheet: Invalid date', 400); } // Get the amount of time worked -- Can't be negative or zero if ($quantity <= 0) { return new error("Unable to add timesheet: You can't work 0 hours or less on a WR", '405'); } /* * So there's more than one way to log 'time' on a WR * The standard is hours, so this will be the default if you don't specify * Days is only here because of the few that use it - I personally would love to see it gone forever * Amount is for when you buy hardware or a fixed cost item as part of a WR - new server - travel expenses, etc. * All the others I've yet to find a reason to implement */ switch ($units) { case 'hours': // If we are in hours, then our job is very simple - we do nothing and the SQL figures itself out break; case 'days': // If we are in days, then our job is very simple - we do nothing and the SQL figures itself out break; case 'minutes': // If we don't handle minutes, we'll pass it in as hours, and that'll be bad. break; case 'amount': if (empty($rate)) { return new error('Unable to add timesheet: you must specify a rate when adding an amount to a WR', '400'); } else { if (!is_numeric($rate)) { return new error('Unable to add timesheet: rate must be a numeric value', '400'); } } // So long as we've got this far the below rate calculation logic won't be applied break; case 'dollars': return new error('dollars not implemented for this method - please use hours, days or amount', 406); break; case 'pounds': return new error('pounds not implemented for this method - please use hours, days or amount', 406); break; case 'euros': return new error('euros not implemented for this method - please use hours, days or amount', 406); break; case 'usd': return new error('usd not implemented for this method - please use hours, days or amount', 406); break; case 'aud': return new error('aud not implemented for this method - please use hours, days or amount', 406); break; default: $units = 'hours'; break; } /* * Okay, I'm not saying this logic is any good, but it's what WRMS 2.0 does (pick the first that applies) * 1. If the user has specified a rate in the call to this method, use that * 2. If the client has a rate set, use that rate * 3. If the user has a rate set, use that rate * 4. If the supplier has a rate set, use that rate * 5. Default to the config value (120 at time of coding, but configurable from lib/medusa/config/config.php) */ // If we haven't got a rate, set $rate to null so the default rate logic will kick in if (empty($rate)) { $rate = null; } else { if (!is_numeric($rate)) { return new error('Unable to add timesheet: rate must be numeric', '400'); } } // Check the rate for the client (requestor) if ($rate == null) { $result = db_query("SELECT work_rate FROM request \n INNER JOIN usr ON (request.requester_id = usr.user_no) \n INNER JOIN organisation_plus ON (usr.org_code = organisation_plus.org_code) \n WHERE request.request_id=%d LIMIT 1", $wr); while ($row = db_fetch_object($result)) { $rate = $row->work_rate; } } // If we didn't have any luck there, check the rate for the user if ($rate == null) { $result = db_query("SELECT base_rate FROM usr WHERE user_no=%d LIMIT 1", $id); while ($row = db_fetch_object($result)) { $rate = $row->base_rate; } } // Still no luck? Check the supplier rate if ($rate == null) { $result = db_query("SELECT work_rate FROM usr INNER JOIN organisation_plus ON (usr.org_code = organisation_plus.org_code) \n WHERE usr.user_no=%d LIMIT 1", $id); while ($row = db_fetch_object($result)) { $rate = $row->work_rate; } } // If all our options have failed us, set a default rate from config if ($rate == null) { $rate = DEFAULT_CHARGE_RATE; } // Description - URL Encoded $description = urldecode($description); // I know "$quantity $units" looks bad, postgres puts this into an 'interval' database field, so _it_ figures out how to make it nice, not us if ($units != 'amount') { $duration = "{$quantity} {$units}"; } else { $duration = "null"; } $result = db_query("INSERT INTO request_timesheet (request_id, work_on, work_quantity, work_duration, work_by_id, work_description, work_rate, work_units, review_needed)\n VALUES (%d, '%s', %d, '%s', %d, '%s', %d, '%s', %b)", $wr, $timestamp, $quantity, $duration, $id, $description, $rate, $units, $needsreview); if ($result == false) { return new error('Database query failed', '500'); } else { return new response('Success'); } } else { return new error('You are not authorised to add timesheets', 403); } }
} if (is_null($params['POST']['session_id'])) { # Problem, complain not logged in and boot out, unless doing a login if ($method == 'wrms_login' && class_exists($method)) { error_logging('DEBUG', "Creating class login::"); $class = new wrms_login(); $result = $class->run($params); } else { $result = new error("Session not set."); error_logging('WARNING', 'session_id not set'); } } else { currentuser::set(new user(login::check_session($params['POST']['session_id']))); if (currentuser::getInstance() != null) { if (substr($method, 0, 5) == 'wrms_' && class_exists($method)) { $access = access::getInstance(); $access->setUser(currentuser::getInstance()); error_logging('DEBUG', "method {$method} exists"); $class = new $method(); error_logging('DEBUG', "about to run {$method}"); $result = $class->run($params); } else { error_logging('WARNING', "Method {$method} does not exist"); $result = new error("The method you are trying to call does not exist"); } } else { error_logging('DEBUG', "Session is invalid, timed out, or no longer exists."); $result = new error("Session is invalid, timed out, or no longer exists."); } } echo $response_renderer->render($result);