Api_model->get_table('expenses', $id); // Check if the data store contains if ($data) { $data = $this->Api_model->get_api_custom_data($data, "expenses", $id); // Set the response and exit $this->response($data, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code } else { // Set the response and exit $this->response(['status' => FALSE, 'message' => 'No data were found'], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code } } /** * @api {get} api/expenses/search/:keysearch Search Expenses information * @apiVersion 0.3.0 * @apiName GetExpenseSearch * @apiGroup Expenses * * @apiHeader {String} authtoken Authentication token, generated from admin area * * @apiParam {String} keysearch Search Keywords * * @apiSuccess {Array} Expenses Expenses Information * * @apiSuccessExample Success-Response: * [ * { * "id": "1", * "category": "1", * "currency": "1", * "amount": "50.00", * "tax": "0", * "tax2": "0", * "reference_no": "012457893", * "note": "AWS server hosting charges", * "expense_name": "Cloud Hosting", * "clientid": "1", * "project_id": "0", * "billable": "0", * "invoiceid": null, * "paymentmode": "2", * "date": "2021-09-01", * "recurring_type": "month", * "repeat_every": "1", * "recurring": "1", * "cycles": "12", * "total_cycles": "0", * "custom_recurring": "0", * "last_recurring_date": null, * "create_invoice_billable": "0", * "send_invoice_to_customer": "0", * "recurring_from": null, * "dateadded": "2021-09-01 12:26:34", * "addedfrom": "1", * "is_expense_created_in_xero": "0", * "userid": "1", * "company": "Company A", * "vat": "", * "phonenumber": "", * "country": "0", * "city": "", * "zip": "", * "state": "", * "address": "", * "website": "", * "datecreated": "2020-05-25 22:55:49", * "active": "1", * "leadid": null, * "billing_street": "", * "billing_city": "", * "billing_state": "", * "billing_zip": "", * "billing_country": "0", * "shipping_street": "", * "shipping_city": "", * "shipping_state": "", * "shipping_zip": "", * "shipping_country": "0", * "longitude": null, * "latitude": null, * "default_language": "", * "default_currency": "0", * "show_primary_contact": "0", * "stripe_id": null, * "registration_confirmed": "1", * "name": "Hosting Management", * "description": "server space and other settings", * "show_on_pdf": "0", * "invoices_only": "0", * "expenses_only": "0", * "selected_by_default": "0", * "taxrate": null, * "category_name": "Hosting Management", * "payment_mode_name": "Paypal", * "tax_name": null, * "tax_name2": null, * "taxrate2": null, * "expenseid": "1", * "customfields": [] * } * ] * * @apiError {Boolean} status Request status * @apiError {String} message No data were found * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "No data were found" * } */ public function data_search_get($key = '') { $data = $this->Api_model->search('expenses', $key); // Check if the data store contains if ($data) { $data = $this->Api_model->get_api_custom_data($data, "expenses"); // Set the response and exit $this->response($data, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code } else { // Set the response and exit $this->response(['status' => FALSE, 'message' => 'No data were found'], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code } } /** * @api {delete} api/expenses/:id Delete Expense * @apiVersion 0.3.0 * @apiName DeleteExpenses * @apiGroup Expenses * * @apiHeader {String} authtoken Authentication token, generated from admin area * @apiSuccess {Boolean} status Request status. * @apiSuccess {String} message Expense Deleted Successfully * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "status": true, * "message": "Expense Deleted Successfully" * } * * @apiError {Boolean} status Request status. * @apiError {String} message Expense Delete Fail * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "Expense Delete Fail" * } */ public function data_delete($id = '') { $id = $this->security->xss_clean($id); if (empty($id) && !is_numeric($id)) { $message = array('status' => FALSE, 'message' => 'Invalid Expense ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } else { $this->load->model('expenses_model'); $is_exist = $this->expenses_model->get($id); if (is_object($is_exist)) { $output = $this->expenses_model->delete($id); if ($output === TRUE) { // success $message = array('status' => TRUE, 'message' => 'Expense Deleted Successfully'); $this->response($message, REST_Controller::HTTP_OK); } else { // error $message = array('status' => FALSE, 'message' => 'Expense Delete Fail'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } else { $message = array('status' => FALSE, 'message' => 'Invalid Expense ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } } /** * @api {post} api/expenses Add Expense * @apiVersion 0.3.0 * @apiName AddExpense * @apiGroup Expenses * * @apiHeader {String} authtoken Authentication token, generated from admin area * * @apiParam {String} [expense_name] Optional. Expanse Name * @apiParam {String} [note] Optional. Expanse Note * @apiParam {Number} category Mandatory. Expense Category * @apiParam {Decimal} amount Mandatory. Expense Amount * @apiParam {Date} date Mandatory. Expense Date * @apiParam {Number} clientid Optional. Customer id * @apiParam {Number} currency Mandatory. Currency Field * @apiParam {Number} tax Optional. Tax 1 * @apiParam {Number} tax2 Optional. Tax 2 * @apiParam {Number} paymentmode Optional. Payment mode * @apiParam {String} [reference_no] Optional. Reference # * @apiParam {String} [recurring] Optional. recurring 1 to 12 or custom * @apiParam {Number} [repeat_every_custom] Optional. if recurring is custom set number gap * @apiParam {String} [repeat_type_custom] Optional. if recurring is custom set gap option day/week/month/year * * @apiParamExample {json} Request-Example: * { * "expense_name": "Test51", * "note": "Expanse note", * "category": 300, * "date": "2021-08-20", * "amount": "1200.00", * "billable": 1, * "clientid": 1, * "currency": 1, * "tax": 1, * "tax2": 1, * "paymentmode": 2, * "reference_no": 5874, * "repeat_every": "6-month", * "cycles": 5, * "create_invoice_billable": 0, * "send_invoice_to_customer": 1, * "custom_fields": * { * "expenses": * { * "94": "test 1254" * } * } * } * * @apiSuccess {Boolean} status Request status. * @apiSuccess {String} message Expense Added Successfully * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "status": true, * "message": "Expense Added Successfully" * } * * @apiError {Boolean} status Request status. * @apiError {String} message Expense Update Fail * @apiError {String} category The Expense Category is not found. * @apiError {String} date The Expense date field is required. * @apiError {String} amount The Amount field is required. * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "Expense Add Fail" * } * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "category":"The Expense Category is not found" * }, * "message": "The Expense Category is not found" * } * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "date":"The Expense date field is required." * }, * "message": "The Expense date field is required." * } * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "amount":"The Amount field is required." * }, * "message": "The Amount field is required." * } * */ public function data_post() { $data = $this->input->post(); $this->form_validation->set_rules('category', 'Expense Category', 'trim|required|max_length[255]|callback_validate_category'); $this->form_validation->set_rules('date', 'Expense date', 'trim|required|max_length[255]'); $this->form_validation->set_rules('category', 'Expense Category', 'trim|required|max_length[255]'); $this->form_validation->set_rules('date', 'Invoice date', 'trim|required|max_length[255]'); $this->form_validation->set_rules('currency', 'Currency', 'trim|required|max_length[255]'); $this->form_validation->set_rules('amount', 'Amount', 'trim|required|decimal|greater_than[0]'); $data['note'] = $data['note'] ?? ""; if ($this->form_validation->run() == FALSE) { $message = array('status' => FALSE, 'error' => $this->form_validation->error_array(), 'message' => validation_errors()); $this->response($message, REST_Controller::HTTP_CONFLICT); } else { $this->load->model('expenses_model'); $id = $this->expenses_model->add($data); if ($id > 0 && !empty($id)) { $this->handle_expense_attachments_array($id); $message = array( 'status' => TRUE, 'message' => 'Expense added successfully.', 'record_id' => $id ); $this->response($message, REST_Controller::HTTP_OK); } else { // error $message = array('status' => FALSE, 'message' => 'Expense add fail.'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } } /** * @api {put} api/expenses Update a Expense * @apiVersion 0.3.0 * @apiName PutExpense * @apiGroup Expenses * * @apiHeader {String} authtoken Authentication token, generated from admin area * * @apiParam {String} [expense_name] Optional. Name * @apiParam {String} [note] Optional. Note * @apiParam {Number} category Mandatory. Expense Category * @apiParam {Decimal} amount Mandatory. Expense Amount * @apiParam {Date} date Mandatory. Expense Date * @apiParam {Number} clientid Optional. Customer id * @apiParam {Number} currency Mandatory. currency field * @apiParam {Number} tax Optional. Tax 1 * @apiParam {Number} tax2 Optional. Tax 2 * @apiParam {Number} paymentmode Optional. Payment mode * @apiParam {String} [reference_no] Optional. Reference # * @apiParam {String} [recurring] Optional. recurring 1 to 12 or custom * @apiParam {Number} [repeat_every_custom] Optional. if recurring is custom set number gap * @apiParam {String} [repeat_type_custom] Optional. if recurring is custom set gap option day/week/month/year * * @apiParamExample {json} Request-Example: * { * "expense_name": "Test51", * "note": "exp note", * "category": 300, * "date": "2021-08-20", * "amount": "1200.00", * "billable": 1, * "clientid": 1, * "currency": 1, * "tax": 1, * "tax2": 1, * "paymentmode": 2, * "reference_no": 5874, * "repeat_every": "6-month", * "cycles": 5, * "create_invoice_billable": 0, * "send_invoice_to_customer": 1, * "custom_fields": * { * "expenses": * { * "94": "test 1254" * } * } * } * * @apiSuccess {Boolean} status Request status. * @apiSuccess {String} message Expense Updated Successfully * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "status": true, * "message": "Expense Updated Successfully" * } * * @apiError {Boolean} status Request status. * @apiError {String} message Expense Update Fail * @apiError {String} category The Expense Category is not found. * @apiError {String} date The Expense date field is required. * @apiError {String} amount The Amount field is required. * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "Expense Update Fail" * } * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "category":"The Expense Category is not found" * }, * "message": "The Expense Category is not found" * } * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "date":"The Expense date field is required." * }, * "message": "The Expense date field is required." * } * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "amount":"The Amount field is required." * }, * "message": "The Amount field is required." * } * */ public function data_put($id = "") { // JSON data is now automatically parsed in REST_Controller if (empty($_POST) || !isset($_POST)) { $this->load->library('parse_input_stream'); $_POST = $this->parse_input_stream->parse_parameters(); $_FILES = $this->parse_input_stream->parse_files(); if (empty($_POST) || !isset($_POST)) { $message = array('status' => FALSE, 'message' => 'Data Not Acceptable OR Not Provided'); $this->response($message, REST_Controller::HTTP_NOT_ACCEPTABLE); } } if (empty($id) && !is_numeric($id)) { $message = array('status' => FALSE, 'message' => 'Invalid Lead ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } else { $this->load->model('expenses_model'); $is_exist = $this->expenses_model->get($id); if (!is_object($is_exist)) { $message = array('status' => FALSE, 'message' => 'Expense ID Doesn\'t Not Exist.'); $this->response($message, REST_Controller::HTTP_CONFLICT); } if (is_object($is_exist)) { $update_data = $this->input->post(); $update_file = isset($update_data['file']) ? $update_data['file'] : null; unset($update_data['file']); $output = $this->expenses_model->update($update_data, $id); if (!empty($update_file) && count($update_file)) { if ($output <= 0 || empty($output)) { $output = $id; } } if ($output > 0 && !empty($output)) { $this->expenses_model->delete_expense_attachment($output); $this->handle_expense_attachments_array($output); $message = array('status' => TRUE, 'message' => "Expense Updated Successfully",); $this->response($message, REST_Controller::HTTP_OK); } else { // error $message = array('status' => FALSE, 'message' => 'Expense Update Fail'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } else { $message = array('status' => FALSE, 'message' => 'Invalid Expense ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } } public function validate_category($value) { $this->form_validation->set_message('validate_category', 'The {field} is not found.'); $this->load->model('expenses_model'); $is_exist = $this->expenses_model->get_category($value); if ($is_exist) { return TRUE; } return FALSE; } function handle_expense_attachments_array($expense_id, $index_name = 'file') { $path = get_upload_path_by_type('expense') . $expense_id . '/'; $CI = & get_instance(); if (isset($_FILES[$index_name]['name']) && ($_FILES[$index_name]['name'] != '' || is_array($_FILES[$index_name]['name']) && count($_FILES[$index_name]['name']) > 0)) { if (!is_array($_FILES[$index_name]['name'])) { $_FILES[$index_name]['name'] = [$_FILES[$index_name]['name']]; $_FILES[$index_name]['type'] = [$_FILES[$index_name]['type']]; $_FILES[$index_name]['tmp_name'] = [$_FILES[$index_name]['tmp_name']]; $_FILES[$index_name]['error'] = [$_FILES[$index_name]['error']]; $_FILES[$index_name]['size'] = [$_FILES[$index_name]['size']]; } _file_attachments_index_fix($index_name); for ($i = 0; $i < count($_FILES[$index_name]['name']); $i++) { // Get the temp file path $tmpFilePath = $_FILES[$index_name]['tmp_name'][$i]; // Make sure we have a filepath if (!empty($tmpFilePath) && $tmpFilePath != '') { if (_perfex_upload_error($_FILES[$index_name]['error'][$i]) || !_upload_extension_allowed($_FILES[$index_name]['name'][$i])) { continue; } _maybe_create_upload_path($path); $filename = unique_filename($path, $_FILES[$index_name]['name'][$i]); $newFilePath = $path . $filename; // Upload the file into the temp dir if (move_uploaded_file($tmpFilePath, $newFilePath)) { $CI = & get_instance(); $CI->load->model('expenses_model'); $data = []; $data[] = ['file_name' => $filename, 'filetype' => $_FILES[$index_name]['type'][$i], ]; $this->add_attachment_to_database($expense_id, $data, false); } } } } return true; } function add_attachment_to_database($expense_id, $attachment, $external = false, $form_activity = false) { $this->misc_model->add_attachment_to_database($expense_id, 'expense', $attachment, $external); // No notification when attachment is imported from web to lead form if ($form_activity == false) { $this->load->model('expenses_model'); $expense = $this->expenses_model->get($expense_id); $not_user_ids = []; if ($expense->addedfrom != get_staff_user_id()) { array_push($not_user_ids, $expense->addedfrom); } $notifiedUsers = []; foreach ($not_user_ids as $uid) { $notified = add_notification([ 'description' => 'not_expense_added_attachment', 'touserid' => $uid, 'link' => '#expenseid=' . $expense_id, 'additional_data' => serialize([ $expense->expense_name, ]), ]); if ($notified) { array_push($notifiedUsers, $uid); } } pusher_trigger_notification($notifiedUsers); } } } /* End of file Expenses.php */