\r\nShipping", * "billing_city": "Thangadh", * "billing_state": "Gujarat", * "billing_zip": "363630", * "billing_country": "102", * "shipping_street": "Thangadh, Gujarat, India
\r\nShipping", * "shipping_city": "Thangadh", * "shipping_state": "Gujarat", * "shipping_zip": "363630", * "shipping_country": "102", * "include_shipping": "1", * "show_shipping_on_estimate": "1", * "show_quantity_as": "1", * "pipeline_order": "0", * "is_expiry_notified": "0", * "acceptance_firstname": null, * "acceptance_lastname": null, * "acceptance_email": null, * "acceptance_date": null, * "acceptance_ip": null, * "signature": null, * "short_link": null, * "symbol": "$", * "name": "USD", * "decimal_separator": ".", * "thousand_separator": ",", * "placement": "before", * "isdefault": "1", * "currencyid": "1", * "currency_name": "USD", * "attachments": [], * "visible_attachments_to_customer_found": false, * "items": [ * { * "id": "2", * "rel_id": "1", * "rel_type": "estimate", * "description": "test", * "long_description": "test", * "qty": "1.00", * "rate": "1200.00", * "unit": "1", * "item_order": "1" * } * ], * "client": { * "userid": "1", * "company": "test", * "vat": "", * "phonenumber": "01324568903", * "country": "102", * "city": "test", * "zip": "3000", * "state": "Test", * "address": "Test", * "website": "", * "datecreated": "2021-07-30 16:29:46", * "active": "1", * "leadid": null, * "billing_street": "Test", * "billing_city": "Test", * "billing_state": "Test", * "billing_zip": "3000", * "billing_country": "102", * "shipping_street": "Test", * "shipping_city": "Test", * "shipping_state": "Test", * "shipping_zip": "3000", * "shipping_country": "102", * "longitude": null, * "latitude": null, * "default_language": "", * "default_currency": "0", * "show_primary_contact": "0", * "stripe_id": null, * "registration_confirmed": "1", * "addedfrom": "1" * }, * "scheduled_email": null, * "customfields": [] * } * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "No data were found" * } */ public function data_get($id = '') { // If the id parameter doesn't exist return all the $data = $this->Api_model->get_table('estimates', $id); // Check if the data store contains if ($data) { $data = $this->Api_model->get_api_custom_data($data, "estimate", $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/estimates/search/:keysearch Search Estimate information * @apiVersion 0.3.0 * @apiName GetEstimateSearch * @apiGroup Estimates * * @apiHeader {String} authtoken Authentication token, generated from admin area * * @apiParam {String} keysearch Search Keywords. * * @apiSuccess {Object} Estimate Information. * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "id": "2", * "sent": "0", * "datesend": null, * "clientid": "1", * "deleted_customer_name": null, * "project_id": "0", * "number": "2", * "prefix": "EST-", * "number_format": "1", * "hash": "ac754972999f948ade369c70bb44d696", * "datecreated": "2021-07-30 16:29:46", * "date": "2021-08-01", * "expirydate": "2021-08-08", * "currency": "1", * "subtotal": "1200.00", * "total_tax": "0.00", * "total": "1200.00", * "adjustment": "0.00", * "addedfrom": "1", * "status": "1", * "clientnote": "", * "adminnote": "adminnote", * "discount_percent": "0.00", * "discount_total": "0.00", * "discount_type": "", * "invoiceid": null, * "invoiced_date": null, * "terms": "", * "reference_no": "", * "sale_agent": "0", * "billing_street": "Test", * "billing_city": "Test", * "billing_state": "Test", * "billing_zip": "3000", * "billing_country": "102", * "shipping_street": "Test", * "shipping_city": "Test", * "shipping_state": "Test", * "shipping_zip": "3000", * "shipping_country": "102", * "include_shipping": "1", * "show_shipping_on_estimate": "1", * "show_quantity_as": "1", * "pipeline_order": "0", * "is_expiry_notified": "0", * "acceptance_firstname": null, * "acceptance_lastname": null, * "acceptance_email": null, * "acceptance_date": null, * "acceptance_ip": null, * "signature": null, * "short_link": null, * "userid": "1", * "company": "test", * "vat": "", * "phonenumber": "01324568903", * "country": "102", * "city": "Test", * "zip": "3000", * "state": "Test", * "address": "Test", * "website": "", * "active": "1", * "leadid": null, * "longitude": null, * "latitude": null, * "default_language": "", * "default_currency": "0", * "show_primary_contact": "0", * "stripe_id": null, * "registration_confirmed": "1", * "estimateid": "2", * "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('estimates', $key); // Check if the data store contains if ($data) { $data = $this->Api_model->get_api_custom_data($data, "estimate"); // 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/estimates/:id Delete Estimate * @apiVersion 0.3.0 * @apiName DeleteEstimate * @apiGroup Estimates * * @apiHeader {String} authtoken Authentication token, generated from admin area * @apiSuccess {Boolean} status Request status. * @apiSuccess {String} message Estimates Deleted Successfully * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "status": true, * "message": "Estimate Deleted Successfully" * } * * @apiError {Boolean} status Request status. * @apiError {String} message Estimate Delete Fail * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "Estimate 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 Estimate ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } else { $this->load->model('estimates_model'); $is_exist = $this->estimates_model->get($id); if (is_object($is_exist)) { $output = $this->estimates_model->delete($id); if ($output === TRUE) { // success $message = array('status' => TRUE, 'message' => 'Estimate Deleted Successfully'); $this->response($message, REST_Controller::HTTP_OK); } else { // error $message = array('status' => FALSE, 'message' => 'Estimate Delete Fail'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } else { $message = array('status' => FALSE, 'message' => 'Invalid Estimate ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } } /** * @api {post} api/estimates Add New Estimates * @apiVersion 0.3.0 * @apiName PostEstimates * @apiGroup Estimates * * @apiHeader {String} authtoken Authentication token, generated from admin area * * @apiParam {Number} clientid Mandatory. Customer id * @apiParam {Number} number Mandatory. Estimates Number * @apiParam {Date} date Mandatory. Estimates Date * @apiParam {Date} [duedate] Optional. Expiry Date of Estimates * @apiParam {Number} currency Mandatory. currency field * @apiParam {Array} newitems Mandatory. New Items to be added * @apiParam {Decimal} subtotal Mandatory. calculation based on item Qty, Rate and Tax * @apiParam {Decimal} total Mandatory. calculation based on subtotal, Discount and Adjustment * @apiParam {String} billing_street Optional. Street Address * @apiParam {String} [billing_city] Optional. City Name for billing * @apiParam {String} [billing_state] Optional. Name of state for billing * @apiParam {Number} [billing_zip] Optional. Zip code * @apiParam {Number} [billing_country] Optional. Country code * @apiParam {String} [shipping_street] Optional. Address of shipping * @apiParam {String} [shipping_city] Optional. City name for shipping * @apiParam {String} [shipping_state] Optional. Name of state for shipping * @apiParam {Number} [shipping_zip] Optional. Zip code for shipping * @apiParam {Number} [shipping_country] Optional. Country code * @apiParam {String} [tags] Optional. TAGS comma separated * @apiParam {Number} [status] Optional. Status id (default status is Accepted) * @apiParam {String} [Reference] Optional. Reference name * @apiParam {Number} [sale_agent] Optional. Sale Agent name * @apiParam {String} [adminnote] Optional. notes by admin * @apiParam {String} [clientnote] Optional. client notes * @apiParam {String} [terms] Optional. Terms * * @apiParamExample {Multipart Form} Request-Example: * [ * "clientid"=>1, * "number"=>"00001", * "date"=>"2020-09-07", * "currency"=>1, * "newitems[0][description]"=>"item 1 description", * "newitems[0][long_description]"=>"item 1 long description", * "newitems[0][qty]"=>1, * "newitems[0][rate]"=>100, * "newitems[0][order]"=>1, * "newitems[0][taxname][]"=>CGST|9.00, * "newitems[0][taxname][]"=>SGST|9.00, * "newitems[0][unit]"=>"", * "newitems[1][description]"=>"item 2 description", * "newitems[1][long_description]"=>"item 2 long description", * "newitems[1][qty]"=>1, * "newitems[1][rate]"=>100, * "newitems[1][order]"=>1, * "newitems[1][taxname][]"=>CGST|9.00, * "newitems[1][taxname][]"=>SGST|9.00, * "newitems[1][unit]"=>"", * "subtotal"=>236.00, * "total"=>236.00, * "status"=>1, * .... * ] * * * @apiSuccess {Boolean} status Request status. * @apiSuccess {String} message Estimates Added Successfully * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "status": true, * "message": "Estimates Added Successfully" * } * * @apiError {Boolean} status Request status. * @apiError {String} message Estimates add fail * @apiError {String} newitems[] The Items field is required * @apiError {String} number The Estimates number is already in use * @apiError {String} subtotal The Sub Total field is required * @apiError {String} total The Total field is required * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "Estimates Add Fail" * } * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "number":"The Estimates number is already in use" * }, * "message": "The Estimates number is already in use" * } * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "error": { * "newitems[]": "The Items field is required" * }, * "message": "

The Items field is required

\n" * } * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "error": { * "subtotal": "The Sub Total field is required" * }, * "message": "

The Sub Total field is required

\n" * } * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "error": { * "total": "The Total field is required" * }, * "message": "

The Total field is required

\n" * } * */ public function data_post() { \modules\api\core\Apiinit::the_da_vinci_code('api'); error_reporting(0); $data = $this->input->post(); $this->form_validation->set_rules('clientid', 'Customer', 'trim|required|numeric|greater_than[0]'); $this->form_validation->set_rules('project_id', 'Project', 'trim|numeric|greater_than[0]'); $this->form_validation->set_rules('include_shipping', 'Include Shipping', 'trim|numeric|greater_than_equal_to[0]|less_than_equal_to[1]'); $this->form_validation->set_rules('show_shipping_on_estimate', 'Show shipping on estimate', 'trim|numeric|greater_than_equal_to[0]|less_than_equal_to[1]'); $this->form_validation->set_rules('currency', 'Currency', 'trim|required|numeric|greater_than[0]'); $this->form_validation->set_rules('status', 'Status', 'trim|required|numeric|greater_than[0]'); $this->form_validation->set_rules('date', 'Estimate date', 'trim|required|max_length[255]'); $this->form_validation->set_rules('quantity', 'Quantity', 'trim|numeric|greater_than[0]'); $this->form_validation->set_rules('newitems[]', 'Items', 'required'); $this->form_validation->set_rules('subtotal', 'Sub Total', 'trim|required|decimal|greater_than[0]'); $this->form_validation->set_rules('total', 'Total', 'trim|required|decimal|greater_than[0]'); $this->form_validation->set_rules('billing_street', 'Street', 'trim|required|max_length[200]'); $this->form_validation->set_rules('number', 'Estimate Number', 'trim|required|numeric|callback_validate_estimate_number[0]'); 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_NOT_FOUND); } else { $this->load->model('estimates_model'); $data['expirydate'] = _d(date('Y-m-d', strtotime('+' . get_option('estimate_due_after') . ' DAY', strtotime(date('Y-m-d'))))); $id = $this->estimates_model->add($data); if ($id > 0 && !empty($id)) { $message = array( 'status' => TRUE, 'message' => 'Estimate Added Successfully', 'record_id' => $id ); $this->response($message, REST_Controller::HTTP_OK); } else { // error $message = array('status' => FALSE, 'message' => 'Estimate Add Fail'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } } public function validate_estimate_number($number, $estimateid) { $isedit = 'false'; if (!empty($estimateid)) { $isedit = 'true'; } $this->form_validation->set_message('validate_estimate_number', 'The {field} is already in use'); $original_number = null; $date = $this->input->post('date'); if (!empty($estimateid)) { $data = $this->Api_model->get_table('estimates', $estimateid); $original_number = $data->number; if (empty($date)) { $date = $data->date; } } $number = trim($number); $number = ltrim($number, '0'); if ($isedit == 'true') { if ($number == $original_number) { return TRUE; } } if (total_rows(db_prefix() . 'estimates', ['YEAR(date)' => date('Y', strtotime(to_sql_date($date))), 'number' => $number, ]) > 0) { return FALSE; } else { return TRUE; } } /** * @api {put} api/estimates/:id Update a estimate * @apiVersion 0.3.0 * @apiName PutEstimate * @apiGroup Estimates * * @apiHeader {String} authtoken Authentication token, generated from admin area * * @apiParam {String} clientid Mandatory. Customer. * @apiParam {String} billing_street Mandatory. Street Address * @apiParam {String} [billing_city] Optional. City Name for billing * @apiParam {String} [billing_state] Optional. Name of state for billing * @apiParam {Number} [billing_zip] Optional. Zip code * @apiParam {Number} [billing_country] Optional. Country code * @apiParam {boolean} [include_shipping="no"] Optional. set yes if you want add Shipping Address * @apiParam {boolean} [show_shipping_on_estimate] Optional. Shows shipping details in estimate. * @apiParam {String} [shipping_street] Optional. Address of shipping * @apiParam {String} [shipping_city] Optional. City name for shipping * @apiParam {String} [shipping_state] Optional. Name of state for shipping * @apiParam {Number} [shipping_zip] Optional. Zip code for shipping * @apiParam {Number} [shipping_country] Optional. Country code * @apiParam {Number} number Mandatory. Estimate Number * @apiParam {Date} date Mandatory. Estimate Date * @apiParam {Date} [expirydate] Optional. Expiry Date of Estimate * @apiParam {String} [tags] Optional. TAGS comma separated * @apiParam {Number} currency Mandatory. currency field * @apiParam {Number} status Mandatory. Estimate Status(eg. Draft, Sent) * @apiParam {String} [reference_no] Optional. Reference # * @apiParam {Number} [sale_agent] Optional. Sale Agent name * @apiParam {String} [discount_type] Optional. before_tax / after_tax discount type * @apiParam {String} [adminnote] Optional. notes by admin * @apiParam {Array} [items] Mandatory. Existing items with Id * @apiParam {Array} [removed_items] Optional. Items to be removed * @apiParam {Array} [newitems] Optional. New Items to be added * @apiParam {Decimal} subtotal Mandatory. calculation based on item Qty, Rate and Tax * @apiParam {Decimal} total Mandatory. calculation based on subtotal, Discount and Adjustment * @apiParam {String} [clientnote] Optional. client notes * @apiParam {String} [terms] Optional. Terms * * @apiParamExample {json} Request-Example: * { * "clientid": 1, * "billing_street": "new 1 update", * "number": 2, * "status": 2, * "date": "2021-08-19", * "currency": 1, * "items": { * "1": { * "itemid": "24", * "order": "1", * "description": "item description", * "long_description": "item long description", * "qty": "1", * "unit": "1", * "rate": "10.00", * "custom_fields":{ * "items":{ * "31":"test 12 item 1", * "32":"10", * "33":"Lorem Ipsum is simply dummy text of the printing and typesetting industry", * "34":"Option 1", * "35":["Option 1","Option 2"], * "36":["Option 1","Option 3"], * "37":"2021-05-06", * "38":"2021-05-06 00:23:25", * "39":"#ffffff", * "40":"Link" * } * } * } * }, * "newitems": { * "2": { * "order": "2", * "description": "updated item 2 description", * "long_description": "updated item 2 logn description", * "qty": "1", * "unit": "", * "rate": "100.00", * "custom_fields":{ * "items":{ * "31":"test 12 item 2", * "32":"10", * "33":"Lorem Ipsum is simply dummy text of the printing and typesetting industry", * "34":"Option 1", * "35":["Option 1","Option 2"], * "36":["Option 1","Option 3"], * "37":"2021-05-06", * "38":"2021-05-06 00:23:25", * "39":"#ffffff", * "40":"Link" * } * } * } * }, * "custom_fields":{ * "estimate":{ * "92":"test 1254" * } * }, * "subtotal":"110.00", * "total":"110.00" * } * * @apiSuccessExample Success-Response: * HTTP/1.1 200 OK * { * "status": false, * "message": "Estimate Updated Successfully" * } * * @apiErrorExample Error-Response: * HTTP/1.1 404 Not Found * { * "status": false, * "message": "Estimate Update Fail" * } * * @apiError {String} number The Estimate number is already in use * * @apiErrorExample Error-Response: * HTTP/1.1 409 Conflict * { * "status": false, * "error": { * "number":"The Estimate number is already in use" * }, * "message": "The Estimate number is already in use" * } * * */ public function data_put($id = "") { // JSON data is now automatically parsed in REST_Controller 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 Estimate ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } else { $this->form_validation->set_rules('clientid', 'Customer', 'trim|required|numeric|greater_than[0]'); $this->form_validation->set_rules('project_id', 'Project', 'trim|numeric|greater_than[0]'); $this->form_validation->set_rules('include_shipping', 'Include Shipping', 'trim|numeric|greater_than_equal_to[0]|less_than_equal_to[1]'); $this->form_validation->set_rules('show_shipping_on_estimate', 'Show shipping on estimate', 'trim|numeric|greater_than_equal_to[0]|less_than_equal_to[1]'); $this->form_validation->set_rules('currency', 'Currency', 'trim|required|numeric|greater_than[0]'); $this->form_validation->set_rules('status', 'Status', 'trim|required|numeric|greater_than[0]'); $this->form_validation->set_rules('date', 'Estimate date', 'trim|required|max_length[255]'); $this->form_validation->set_rules('quantity', 'Quantity', 'trim|numeric|greater_than[0]'); $this->form_validation->set_rules('items[]', 'Items', 'required'); $this->form_validation->set_rules('subtotal', 'Sub Total', 'trim|required|decimal|greater_than[0]'); $this->form_validation->set_rules('total', 'Total', 'trim|required|decimal|greater_than[0]'); $this->form_validation->set_rules('billing_street', 'Street', 'trim|required|max_length[200]'); $this->form_validation->set_rules('number', 'Estimate Number', 'trim|required|numeric|callback_validate_estimate_number[' . $id . ']'); $_POST['shipping_street'] = $_POST['shipping_street']??""; 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('estimates_model'); $is_exist = $this->estimates_model->get($id); if (!is_object($is_exist)) { $message = array('status' => FALSE, 'message' => 'Estimate ID Doesn\'t Not Exist.'); $this->response($message, REST_Controller::HTTP_CONFLICT); } if (is_object($is_exist)) { $data = $this->input->post(); $data['isedit'] = ""; $success = $this->estimates_model->update($data, $id); if ($success == true) { $message = array('status' => TRUE, 'message' => "Estimate Updated Successfully",); $this->response($message, REST_Controller::HTTP_OK); } else { // error $message = array('status' => FALSE, 'message' => 'Estimate Update Fail'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } else { $message = array('status' => FALSE, 'message' => 'Invalid Estimate ID'); $this->response($message, REST_Controller::HTTP_NOT_FOUND); } } } } }