| @@ -0,0 +1,174 @@ | |||
| <?php | |||
| namespace Biukop; | |||
| require_once(ABSPATH . "wp-config.php"); | |||
| require_once(ABSPATH . "wp-includes/wp-db.php"); | |||
| class AddrMap{ | |||
| private $user1; //wp-user | |||
| private $user2; //wp-user | |||
| private $origin;//addr | |||
| private $destination; //addr | |||
| private $json;//google response | |||
| private $dist;//distance in meter | |||
| private $error;//bool error | |||
| public function __construct(String $user1_login, String $user2_login) { | |||
| $this->error = false; | |||
| $this->user1 = get_user_by('login', $user1_login); | |||
| $this->user2 = get_user_by('login', $user2_login); | |||
| //convert user to their address | |||
| $this->origin = $this->get_user_address($user1_login); | |||
| $this->destination = $this->get_user_address($user2_login); | |||
| //get distance from db | |||
| $this->dist = $this->get_distance_from_db(); | |||
| if ($this->dist == false){ | |||
| //get distance from google map | |||
| $response = $this->get_google_direction($this->origin, $this->destination); | |||
| if ($response == false){ | |||
| //mark error | |||
| $this->error == true; | |||
| }else{ | |||
| $this->json = $response; | |||
| $this->dist = $this->convert_response_to_dist_in_meter($response); | |||
| } | |||
| //store it in db for future use | |||
| $this->update_db(); | |||
| } | |||
| } | |||
| public function has_error(){ | |||
| return $this->error; | |||
| } | |||
| public function get_error_msg(){ | |||
| if($this->error) | |||
| return "Cannot get distance getween $this->user1->display_name and $this->user2->display_name"; | |||
| else | |||
| return ""; | |||
| } | |||
| public function get_dist(){ | |||
| if ($this->error) | |||
| return 0; | |||
| return $this->dist; | |||
| } | |||
| public function get_dist_in_km(){ | |||
| if ($this->error) | |||
| return 0; | |||
| return $this->dist/1000; | |||
| } | |||
| private function update_db() | |||
| { | |||
| global $wpdb; | |||
| $table_name= $this->get_table_name(); | |||
| $sql = "INSERT INTO $table_name (origin,destination,response,distance) VALUES ('%s', '%s', '%s', %d) ;"; | |||
| $query = $wpdb->prepare($sql, array( | |||
| $this->origin, | |||
| $this->destination, | |||
| json_encode($this->json), | |||
| $this->dist, | |||
| )); | |||
| $results = $wpdb->get_results($query); | |||
| if ( $results == false) { | |||
| //failed | |||
| $lastid = $wpdb->insert_id; | |||
| $msg = sprintf("Insert into address distance db error: date=%s, user1_id=%s, user2_id=%s, orign=%s, dest=%s, resp=%s, dist=%d, db_error=%s", | |||
| date('Y-m-d, H:i:s'), | |||
| $this->user1->ID, | |||
| $this->user2->ID, | |||
| $this->origin, | |||
| $this->destination, | |||
| json_encode($this->json), | |||
| $this->dist, | |||
| $wpdb->last_error | |||
| ); | |||
| $error_log = plugin_dir_path(__FILE__) . "/logs/addr.log"; | |||
| file_put_contents($error_log, $msg, FILE_APPEND); | |||
| } | |||
| } | |||
| private function get_user_address($login){ | |||
| $user = get_user_by('login', $login); | |||
| $addr = get_user_meta($user->ID, 'address', true); | |||
| return $addr; | |||
| } | |||
| private function get_table_name() | |||
| { | |||
| global $wpdb; | |||
| $table_name = $wpdb->prefix . 'acare_addr_distance'; | |||
| return $table_name; | |||
| } | |||
| private function get_distance_from_db(){ | |||
| global $wpdb; | |||
| $table_name = $this->get_table_name(); | |||
| $sql = "SELECT * FROM $table_name WHERE origin='%s' and destination='%s' "; | |||
| $query = $wpdb->prepare($sql, array( | |||
| $this->origin, | |||
| $this->destination, | |||
| )); | |||
| $row = $wpdb->get_row($query); | |||
| if ( $row == null ) | |||
| return false; | |||
| return (int) $row->distance; //in meters; | |||
| } | |||
| private function super_json_decode($json, &$value, $assoc = false, $depth = 512, $options = 0) { | |||
| $pValue = false; | |||
| $result = json_decode($json, $assoc, $depth); | |||
| if(json_last_error() == JSON_ERROR_NONE) { | |||
| $value = $result; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| private function convert_response_to_dist_in_meter($resp){ | |||
| $distance = -1; | |||
| if (count($resp->routes) >0) | |||
| { | |||
| $legs = $resp->routes[0]->legs; | |||
| foreach ($legs as $l){ | |||
| $distance += $l->distance->value; | |||
| } | |||
| } | |||
| return $distance; | |||
| } | |||
| private function get_google_direction($origin, $destination) { | |||
| $data = ""; | |||
| $arg = array( | |||
| 'origin' => $origin, | |||
| 'destination' => $destination, | |||
| 'key'=>'AIzaSyDMRjRh3wu0zTQneYboTk5VgQio3XABz_o', | |||
| ); | |||
| $ch = curl_init("https://maps.googleapis.com/maps/api/directions/json?". http_build_query($arg)); | |||
| curl_setopt_array($ch, array( | |||
| CURLOPT_CONNECTTIMEOUT => 10, | |||
| CURLOPT_RETURNTRANSFER => true, | |||
| CURLOPT_TIMEOUT => 60, | |||
| )); | |||
| $response = false; | |||
| if($this->super_json_decode(curl_exec($ch), $data)) { | |||
| $response = $data; | |||
| } | |||
| $info = curl_getinfo($ch); | |||
| if($info['http_code'] !== 200) { | |||
| return false; | |||
| } | |||
| return $response; | |||
| //var_dump($response); | |||
| } | |||
| } | |||
| @@ -80,7 +80,7 @@ class Xero { | |||
| try{ | |||
| $this->sync_clients(); | |||
| //$this->sync_employees(); | |||
| $this->sync_employees(); | |||
| }catch(RateLimitExceededException $e){ | |||
| $msg= "Xero API rate limit exceeded, please try again later, existing sync within 600 seconds will by passed automatically\n"; | |||
| $this->logConsole($msg); | |||
| @@ -198,6 +198,7 @@ class Xero { | |||
| $id = wp_insert_user($args); | |||
| $user = get_user_by('ID', $id); | |||
| update_user_meta($user->ID, 'mobile', $args['mobile']); | |||
| update_user_meta($user->ID, 'address', $args['address']); | |||
| }else{ | |||
| if ($this->is_too_close_to_sync($user)){ | |||
| return; | |||
| @@ -208,6 +209,7 @@ class Xero { | |||
| unset($args['user_pass']); | |||
| wp_update_user($args); | |||
| update_user_meta($user->ID, 'mobile', $args['mobile']); | |||
| update_user_meta($user->ID, 'address', $args['address']); | |||
| } | |||
| $this->mark_updated($user->ID); | |||
| } | |||
| @@ -222,11 +224,31 @@ class Xero { | |||
| 'last_name' => $e->getLastName(), | |||
| 'nickname' => $e->getFirstName(), | |||
| 'mobile' => $e->getMobile(), | |||
| 'address'=> $this->get_employee_address($e), | |||
| 'role' => 'staff', | |||
| ]; | |||
| return $args; | |||
| } | |||
| private function get_employee_address($e){ | |||
| // "HomeAddress": { | |||
| // "AddressLine1": "16 Quist Avenue", | |||
| // "City": "Lurnea", | |||
| // "Region": "NSW", | |||
| // "PostalCode": "2170", | |||
| // "Country": "AUSTRALIA" | |||
| // }, | |||
| $addr = ""; | |||
| $home = $e->getHomeAddress(); | |||
| $addr .= $home->getAddressLine1() .","; | |||
| $addr .= $home->getAddressLine2() .","; | |||
| $addr .= $home->getCity() . ","; | |||
| $addr .= $home->getRegion() . " "; | |||
| $addr .= $home->getCountry() ." "; | |||
| $addr .= $home->getPostalCode(); | |||
| return $addr; | |||
| } | |||
| private function mark_updated($userid){ | |||
| update_user_meta($userid, 'lastsync', time()); | |||
| } | |||
| @@ -151,7 +151,7 @@ | |||
| new People("#p" + u.login,'#staff_item', u); | |||
| }); | |||
| hide_loading_staff(); | |||
| calculate_total_working_hour(); | |||
| calculate_total_hour_and_money(); | |||
| }else{ | |||
| alert('error getting staff list'); | |||
| } | |||
| @@ -324,7 +324,6 @@ | |||
| } | |||
| load_data(data) | |||
| { | |||
| this.set_job_id(data.id); | |||
| @@ -340,16 +339,9 @@ | |||
| this.data = data; | |||
| this.el.data({job:this, data:data}); | |||
| if (typeof(data.id) === 'undefined' || data.id == ''){ | |||
| this.mark_dirty(); | |||
| this.mark_new(); | |||
| } | |||
| else{ | |||
| this.mark_saved(); | |||
| } | |||
| this.mark_dirty_on_new_record(data); | |||
| this.mark_week_color(); | |||
| console.log('this job money = %o', this.get_payment_summary()); | |||
| this.validate(); | |||
| this.validate(); //also triggers mark errors | |||
| } | |||
| get_job_id(){ | |||
| @@ -479,6 +471,16 @@ | |||
| }); | |||
| } | |||
| mark_dirty_on_new_record(data){ | |||
| if (typeof(data.id) === 'undefined' || data.id == ''){ | |||
| this.mark_dirty(); | |||
| this.mark_new(); | |||
| } | |||
| else{ | |||
| this.mark_saved(); | |||
| } | |||
| } | |||
| mark_dirty() //need save | |||
| { | |||
| var d = this.el.find('.bsave'); | |||
| @@ -563,7 +565,7 @@ | |||
| { | |||
| var str = this.get_finish(); | |||
| if (! is_valid_date_str(str)){ | |||
| this.set_err_msg_finish('wront date'); | |||
| this.set_err_msg_finish('wrong date'); | |||
| this.mark_finish_invalid(); | |||
| return false; | |||
| } | |||
| @@ -836,8 +838,8 @@ | |||
| $('div.prevweek.left').click(function(){ | |||
| if (number_of_unsaved_job() > 0){ | |||
| alert ("you have unsaved jobs,please save it before proceed"); | |||
| return; | |||
| if(!confirm("you have unsaved jobs, proceed will lost them")) | |||
| return; | |||
| } | |||
| $('div.weekdays span.weekday').each(function(i, e){ | |||
| var date = $(e).data().date; | |||
| @@ -850,8 +852,8 @@ | |||
| }); | |||
| $('div.nextweek.right').click(function(){ | |||
| if (number_of_unsaved_job() > 0){ | |||
| alert ("you have unsaved jobs,please save it before proceed"); | |||
| return; | |||
| if(!confirm("you have unsaved jobs,proceed will lost them")) | |||
| return; | |||
| } | |||
| $('div.weekdays span.weekday').each(function(i, e){ | |||
| @@ -1055,7 +1057,7 @@ | |||
| }); | |||
| filter_workspace(staffs, clients); | |||
| calculate_total_working_hour(); | |||
| calculate_total_hour_and_money(); | |||
| } | |||
| function filter_workspace(staffs, clients){ | |||
| @@ -1081,10 +1083,15 @@ | |||
| }); | |||
| } | |||
| function calculate_total_working_hour() | |||
| var debounced_calculate = debounce(calculate_total_hour_and_money, 2000); | |||
| function calculate_total_hour_and_money() | |||
| { | |||
| //init pays for all staff; | |||
| var pays=[]; | |||
| var pays={ | |||
| total: 0, | |||
| hours: 0, | |||
| }; | |||
| $('.stafflist > div.peopleitem').each(function(i,e){ | |||
| var people = $(this).data().obj; | |||
| people.reset_summary(); | |||
| @@ -1092,12 +1099,20 @@ | |||
| $('div.workspace > .divTable').each(function(i,e){ | |||
| var job = $(e).data().job; //class Job | |||
| if (typeof job === 'undefined') | |||
| return; | |||
| var ps = job.get_payment_summary(); | |||
| pays.total += ps.money; | |||
| pays.hours += ps.hour; | |||
| var staff = job.get_staff(); | |||
| var people = find_staff(staff); //class People | |||
| if (people !=false) | |||
| people.add_payment_summary(ps); | |||
| }); | |||
| set_wages(pays.total.toFixed(2)); | |||
| set_working_hours(pays.hours.toFixed(2)); | |||
| } | |||
| function find_staff(login) | |||
| @@ -1108,15 +1123,11 @@ | |||
| return $('#p'+login).data().obj; | |||
| } | |||
| function calculate_total_money() | |||
| { | |||
| } | |||
| $(document).on('change', '.divTableRow select, .divTableRow input', function() { | |||
| var job = $(this).closest('.divTable').data().job; | |||
| job.validate(); | |||
| job.mark_dirty(); | |||
| debounced_calculate(); | |||
| }); | |||
| function init_ts(){ | |||
| @@ -9,18 +9,20 @@ | |||
| */ | |||
| namespace Biukop; | |||
| use XeroPHP\Models\Accounting\Address; | |||
| require_once(dirname(__FILE__) . '/autoload.php'); | |||
| require_once (ABSPATH . 'wp-includes/pluggable.php'); | |||
| class AcareOffice{ | |||
| private $nonce; //for ajax verification | |||
| private $pages = array('time-sheets', 'user-list'); | |||
| private $acaresydney_userid = 0; | |||
| private $xero ; | |||
| private $db; | |||
| private $table_name; | |||
| private $addr_table; | |||
| public function __construct() { | |||
| add_option( "acare_ts_db_version", "1.0" ); | |||
| @@ -42,6 +44,8 @@ class AcareOffice{ | |||
| add_shortcode( 'bts_select_staff', array($this, 'bts_select_staff')); | |||
| add_shortcode( 'bts_select_client', array($this, 'bts_select_client')); | |||
| add_shortcode( 'bts_type_of_service', array($this, 'bts_type_of_service')); | |||
| //user profile page | |||
| add_shortcode( 'bts_user_name', array($this,'bts_user_name')); | |||
| add_action('wp_ajax_list_staff', array($this,'list_staff' )); | |||
| @@ -53,10 +57,16 @@ class AcareOffice{ | |||
| add_action('wp_ajax_earnings_rate', array($this,'get_payitem_earnings_rate' )); | |||
| add_action('wp_ajax_nopriv_earnings_rate', array($this,'get_payitem_earnings_rate' )); | |||
| // hook add_rewrite_rules function into rewrite_rules_array | |||
| add_filter('rewrite_rules_array', array($this,'my_add_rewrite_rules')); | |||
| // hook add_query_vars function into query_vars | |||
| add_filter('query_vars', array($this,'add_query_vars')); | |||
| global $wpdb; | |||
| $this->db = $wpdb; | |||
| $this->table_name = $wpdb->prefix . 'acare_ts'; | |||
| $this->addr_table = $wpdb->prefix . 'acare_addr_distance'; | |||
| } | |||
| @@ -77,6 +87,8 @@ class AcareOffice{ | |||
| $this->xero = new Xero(); | |||
| $this->xero->init_wp(); | |||
| $abc = new AddrMap("01515b52-6936-46b2-a000-9ad4cd7a5b50", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c"); | |||
| } | |||
| //init database | |||
| @@ -84,9 +96,8 @@ class AcareOffice{ | |||
| global $wpdb; | |||
| $charset_collate = $wpdb->get_charset_collate(); | |||
| //table name: broker transactions | |||
| //table name: timesheets jobs | |||
| $table_name = $this->table_name; | |||
| $sql = "CREATE TABLE $table_name ( | |||
| id INT NOT NULL AUTO_INCREMENT, | |||
| tos VARCHAR(45) NULL, | |||
| @@ -99,12 +110,40 @@ class AcareOffice{ | |||
| rating INT(4) NULL DEFAULT 0, | |||
| PRIMARY KEY (id) | |||
| ) $charset_collate;"; | |||
| //addr distance | |||
| $addr_table = $this->addr_table; | |||
| $sql_addr = "CREATE TABLE $addr_table ( | |||
| id INT NOT NULL AUTO_INCREMENT, | |||
| origin VARCHAR(1024) NULL, | |||
| destination VARCHAR(1024) NULL, | |||
| response VARCHAR(40960) NULL, | |||
| distance INT NULL, | |||
| PRIMARY KEY (id) | |||
| ) $charset_collate;"; | |||
| //create database | |||
| require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); | |||
| dbDelta( $sql ); | |||
| dbDelta( $sql_addr); | |||
| } | |||
| // | |||
| //query var | |||
| public function add_query_vars($aVars) { | |||
| $aVars[] = "bts_user_id"; // represents the name of the product category as shown in the URL | |||
| return $aVars; | |||
| } | |||
| //for customer profile and broker trans | |||
| public function my_add_rewrite_rules($aRules) { | |||
| $aNewRules = array('user/([^/]+)/?$' => 'index.php?pagename=user&bts_user_id=$matches[1]'); | |||
| $aRules = $aNewRules + $aRules; | |||
| return $aRules; | |||
| } | |||
| // | |||
| // | |||
| @@ -228,6 +267,13 @@ class AcareOffice{ | |||
| return $result; | |||
| } | |||
| public function bts_user_name($attr) | |||
| { | |||
| //echo '<div class="vcex-module vcex-heading vcex-heading-bottom-border-w-color wpb_animate_when_almost_visible wpb_bounceInUp bounceInUp bts_user_name aligncenter wpb_start_animation animated" style="width:100%;"><span class="vcex-heading-inner clr">A hahah</span></div>;'; | |||
| $content = '[vc_row wpex_bg_overlay="color" wpex_bg_overlay_color="#ffffff"][vc_column][vcex_heading text="Heading13331" style="bottom-border-w-color" css_animation="flipInY" icon="fa fa-handshake-o" inner_bottom_border_color="#000000" width="100%;"][/vc_column][/vc_row][vc_row][vc_column][/vc_column][/vc_row][vc_row][vc_column][/vc_column][/vc_row]'; | |||
| echo do_shortcode($content); | |||
| } | |||
| //generate template based on html file | |||
| private function template($id, $file) | |||
| { | |||
| @@ -246,8 +292,8 @@ class AcareOffice{ | |||
| 'users' => [], | |||
| ); | |||
| //search all users that are staff | |||
| $staffq = new \WP_User_Query(array('role'=>'staff','meta_key'=>'first_name', 'orderby'=>'meta_value', order=>'ASC')); | |||
| $staff = $staffq->get_results(); | |||
| $staffq = new \WP_User_Query(array('role'=>'staff','meta_key'=>'first_name', 'orderby'=>'meta_value', 'order'=>'ASC')); | |||
| $staff = $staffq->get_results(); | |||
| if (! empty($staff)){ | |||
| $response['status'] = 'success'; | |||
| foreach( $staff as $s){ | |||
| @@ -449,3 +495,5 @@ $bb = new AcareOffice(); | |||
| if ( defined( 'WP_CLI' ) && WP_CLI ) { | |||
| \WP_CLI::add_command( 'sync_users', array($bb, 'sync_user_cli')); | |||
| } | |||