diff --git a/Xero.php b/Xero.php index a1933e3..7e09f84 100644 --- a/Xero.php +++ b/Xero.php @@ -110,8 +110,8 @@ class Xero { foreach ( $employees as $e){ $msg = sprintf("SYNC employee name=[%s %s] {%s} \n", $e->getFirstName(), $e->getLastName(), $e->getEmployeeID()); $this->logConsole($msg); - if ($e->getEmployeeID() != '3e8c2e62-8e28-4b68-ae98-9ef1d76188c4') - continue; +// if ($e->getEmployeeID() != '3e8c2e62-8e28-4b68-ae98-9ef1d76188c4') +// continue; $this->ensure_staff_exists($e); } } @@ -212,12 +212,10 @@ class Xero { if ($this->is_too_close_to_sync($user)){ return; } - echo "i update existing $user->user_login $user->display_name\n"; $xero_employee = $this->getEmployee($login); $args = $this->xero_employee_profile($xero_employee); $args['ID'] = $user->ID; unset($args['user_pass']); - var_dump($args); wp_update_user($args); update_user_meta($user->ID, 'mobile', $args['mobile']); update_user_meta($user->ID, 'address', $args['address']); diff --git a/css/bts_timesheet.css b/css/bts_timesheet.css index 2f6c9e1..51169a9 100644 --- a/css/bts_timesheet.css +++ b/css/bts_timesheet.css @@ -872,4 +872,22 @@ div.divTable.invalidjob{ div.divTable .invalid{ background-color:yellow; } -/* end of div table */ \ No newline at end of file +/* end of div table */ + +/* pop up message box */ +.bts_message .ult_modal-body{ + height:50vh; + overflow:scroll; +} +.bts_message .ult_modal-body .sent{ + color: green; +} +.bts_message .ult_modal-body .nojob{ + color: dimgrey; +} +.bts_message .ult_modal-body .error{ + color : red; +} +.bts_message .ult_modal-body .span{ + font-weight:900; +} \ No newline at end of file diff --git a/html/email_job.html b/html/email_job.html index af72779..2dda8dd 100644 --- a/html/email_job.html +++ b/html/email_job.html @@ -2,7 +2,7 @@ Dear {{display_name}}, Below is your job arrangement for the current week, please click the link to view your jobs -https://acaresydney.com.au/task/{{user_login}}/ +https://acaresydney.com.au/task/{{user_login}}/start-{{job_start}}/finish-{{job_finish}}/ If you have any questions, please call Helen directly or email diff --git a/js/bts_task.js b/js/bts_task.js index 3ec2789..9049105 100644 --- a/js/bts_task.js +++ b/js/bts_task.js @@ -29,9 +29,8 @@ function on_confirm_all(){} $.post(bts().ajax_url, { // POST request _ajax_nonce: bts().nonce, // nonce action: "list_job_by_staff", // action - start: get_this_week_start(), - finish: get_this_week_end(), - login: get_staff_login(), + start: get_start_date(), + finish: get_finish_date(), }, function(response, status, xhr){ if (response.status == "success"){ pre_process(response); @@ -43,15 +42,18 @@ function on_confirm_all(){} }); } - function get_staff_login() - { - //pathname: "/task/a6536a3b-ef22-4a28-8d55-e2a26d4ae227/" - var path = window.location.pathname; - var p = path.substr(6);//remove /task/ - var s = p.substring(0, p.length - 1); //remove last / - //console.log(s); - return s; - } +// function get_staff_login() +// { +// //pathname: "/task/a6536a3b-ef22-4a28-8d55-e2a26d4ae227/" +// var path = window.location.pathname; +// var p = path.substr(6);//remove /task/ +// var s = p.substring(0, p.length - 1); //remove last / +// //console.log(s); +// return s; +// } + + + //add extra info to response.jobs function pre_process(response) { @@ -132,6 +134,20 @@ function on_confirm_all(){} } return yyyy + '-' + mm + '-' +dd + " " +hh +":" + ii + ":" + ss; } + + function format_date_only(date){ + var dd = date.getDate(); + var mm = date.getMonth() + 1; //January is 0! + var yyyy = date.getFullYear(); + + if (dd < 10) { + dd = '0' + dd; + } + if (mm < 10) { + mm = '0' + mm; + } + return yyyy + '-' + mm + '-' +dd; + } function get_this_week_start(){ var curr = new Date; // get current date @@ -154,6 +170,24 @@ function on_confirm_all(){} return format_date(lastday); } + function get_start_date() + { + var b=bts_task1; + if (b.bts_job_start != '') + return b.bts_job_start + " 00:00:00"; + else + return get_this_week_start(); + } + function get_finish_date() + { + var b=bts_task1; + if (b.bts_job_finish != '') + return b.bts_job_finish +" 23:59:59"; + else + return get_this_week_end(); + } + + function do_on_confirm_all() { var job_ids=[]; @@ -220,7 +254,67 @@ function on_confirm_all(){} } }); } + + function set_prev_next_week_link() + { + var link = get_previous_week_link(); + $('#previousweek a').attr('href', link); + var link = get_next_week_link(); + $('#nextweek a').attr('href', link); + + } + function get_previous_week_link() + { + return get_link_by_move_date(-7); + } + + function get_next_week_link() + { + return get_link_by_move_date(+7); + } + + function get_link_by_move_date(val) + { + var link = '/task/start-'; + //start date; + var start = new Date(get_start_from_url()); + var date = start.getDate(); + start.setDate(date + val); + link += format_date_only(start) + "/finish-"; + //finish date + var finish = new Date(get_finish_from_url()); + var date = finish.getDate(); + finish.setDate(date + val); + link += format_date_only(finish) + "/"; + return link; + } + + + function get_start_from_url() + { + //pathname: "/task/start-2017-07-01/finish-2018-09-02/" + var path = window.location.pathname; + var regex = /start-(.*)\/f/g; + var match = regex.exec(path); + if ( match != null && match.length ==2) + return match[1]; + else + return get_this_week_start(); + } + function get_finish_from_url() + { + //pathname: "/task/start-2017-07-01/finish-2018-09-02/" + var path = window.location.pathname; + var regex = /finish-(.*)\//g; + var match = regex.exec(path); + if ( match != null && match.length ==2) + return match[1]; + else + return get_this_week_end(); + } + + //register events $(document).on('change', 'div.confirmfield input', function(){ var ack = $(this).is(':checked'); @@ -247,6 +341,7 @@ function on_confirm_all(){} //init set_user_name_at_summary(); get_my_jobs(); + set_prev_next_week_link(); //get_staff_login(); on_confirm_all = do_on_confirm_all; /*_____________________________________________*/ diff --git a/js/bts_timesheet.js b/js/bts_timesheet.js index bc1e505..d60a599 100644 --- a/js/bts_timesheet.js +++ b/js/bts_timesheet.js @@ -143,8 +143,9 @@ $.post(bts().ajax_url, { // POST request _ajax_nonce: bts().nonce, // nonce action: "list_staff", // action - }, function(response, status, xhr){ + }).done(function(response, status, xhr){ if (response.status =='success'){ + bts().staff = response.users; response.users.forEach(function(u){ var html = bts_staff_html(u); jQuery('div.stafflist').append(html); @@ -166,6 +167,7 @@ action: "list_client", // action }, function(response, status, xhr){ if (response.status =='success'){ + bts().client = response.users; response.users.forEach(function(u){ hide_loading_client(); var html = bts_client_html(u); @@ -733,7 +735,6 @@ var w2_end = new Date($('span[name="w2d7"]').data().date); w2_begin.setHours(0,0,0,0); w2_end.setHours(23,59,59); - console.log("week2 begin %o, end %o", w2_begin, w2_end); var me = new Date(this.data.start); return (w2_begin <= me && me <= w2_end ); } @@ -869,6 +870,7 @@ { var now = new Date; var d1 = new Date(now.setDate(i)); + now = new Date; var d2 = new Date(now.setDate(i+7)); set_day_number(1,pos, d1); //week 1 set_day_number(2,pos, d2); //week 2 @@ -880,6 +882,7 @@ var selector = 'span[name="w'+week+'d'+index+'"]'; $(selector).html(date.getDate()); $(selector).data({date:date}); + console.log('set w%d-d%d %o', week,index,date); } function set_today(){ @@ -1151,10 +1154,19 @@ } $('button[name="confirmschedule"]').click(function(){ - //$('div.workspace span.ticon.ticon-save').trigger('click'); - + if (!confirm('sending email to each staff for their job arrangement?')) + return; + $('div.bts_message .ult-overlay-close-inside').hide(); + $('div.bts_message_button').trigger('click'); + setTimeout(do_email_jobs, 2000);//2 seconds for dialog to popup }); + $('button[name="confirmschedule"]').mouseenter(function(){ + $('div.week2').addClass('blink_me'); + }) + $('button[name="confirmschedule"]').mouseleave(function(){ + $('div.week2').removeClass('blink_me'); + }) var debounced_filter_workspace = debounce(do_filter_workspace, 1000); $(document).on('click','div.userlist', debounced_filter_workspace); @@ -1327,7 +1339,59 @@ init_user_search(); //ajax_earning_rate(); reset_title_to_today(); - load_timesheet(); + //load_timesheet(); + } + + function do_email_jobs() + { + var selector = 'div.bts_message div.ult_modal-body'; + $(selector).html('Analysis staff jobs ... ok'); + var staff = bts().staff.slice(0);//copy this array; + var s = staff.pop(); + + //week2 start + var w2_begin = new Date($('span[name="w2d1"]').data().date); + var w2_end = new Date($('span[name="w2d7"]').data().date); + var start = format_date(w2_begin); + var finish = format_date(w2_end); + + function do_staff(){ + var el = $('

Checking ' + s.firstname + "....

"); + $(selector).append(el); + el[0].scrollIntoView(); + + $.post(bts().ajax_url, { // POST request + _ajax_nonce: bts().nonce, // nonce + action: "email_job", // action + staff : s.login, + start : start, + finish: finish, + }, function(response, status, xhr){ + if (response.status == 'success'){ + if (response.sent){ + el.append('' + response.emailstatus + ''); + }else{ + el.append('' + response.emailstatus + ''); + } + }else{ + el.append(' Error[' + response.error + ' ...]'); + } + }).fail(function(){ + el.append('' + 'Network Error occured' + ''); + }).always(function(){//next staff + if (staff.length >0){ + s = staff.pop(); + setTimeout(do_staff, 100); //a short delay makes it looks nice + }else{ + $('div.bts_message .ult-overlay-close-inside').show(); + $('div.bts_message .ult-overlay-close-inside').addClass('blink_me'); + $('div.week2').removeClass('blink_me'); + $(selector).append('All staff done! '); + } + }); + } + //execute + do_staff(); } // function ajax_earning_rate(){ diff --git a/ts.php b/ts.php index daf6df4..f98858f 100644 --- a/ts.php +++ b/ts.php @@ -18,7 +18,8 @@ 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 $bts_user_id = 0; + private $bts_week_id = 1; //week 1, we will try to calculate current week; private $xero ; private $db; private $table_name; @@ -55,6 +56,7 @@ class AcareOffice{ add_action('wp_ajax_save_job', array($this,'save_job' )); add_action('wp_ajax_list_job', array($this,'list_job' )); add_action('wp_ajax_delete_job', array($this,'delete_job' )); + add_action('wp_ajax_email_job', array($this,'email_job' )); 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' )); @@ -155,6 +157,9 @@ class AcareOffice{ //query var public function add_query_vars($aVars) { $aVars[] = "bts_user_id"; // represents the name of the product category as shown in the URL + $aVars[] = "bts_week_id"; // represents the name of the product category as shown in the URL + $aVars[] = "bts_job_start"; // represents the name of the product category as shown in the URL + $aVars[] = "bts_job_finish"; // represents the name of the product category as shown in the URL return $aVars; } @@ -162,34 +167,124 @@ class AcareOffice{ public function my_add_rewrite_rules($aRules) { $aNewRules = array( 'user/([^/]+)/?$' => 'index.php?pagename=user&bts_user_id=$matches[1]', - 'task/([^/]+)/?$' => 'index.php?pagename=task&bts_user_id=$matches[1]' + 'task/week-([^/]+)/?$' => 'index.php?pagename=task&bts_week_id=$matches[1]', + 'task/start-([^/]+)/finish-([^/]+)/?$' => 'index.php?pagename=task&bts_job_start=$matches[1]&bts_job_finish=$matches[2]', + 'task/([^/]+)/?$' => 'index.php?pagename=task&bts_user_id=$matches[1]', + 'task/([^/]+)/week-([^/]+)/?$' => 'index.php?pagename=task&bts_user_id=$matches[1]&bts_week_id=$matches[2]', + 'task/([^/]+)/start-([^/]+)/finish-([^/]+)/?$' => 'index.php?pagename=task&bts_user_id=$matches[1]&bts_job_start=$matches[2]&bts_job_finish=$matches[3]', + ); $aRules = $aNewRules + $aRules; - return $aRules; } - - // // ///check auth public function check_auth(){ global $pagename; - if ( $pagename == 'task'){ - $login = get_query_var( 'bts_user_id' ); - if ($login != "")//perform autologin - { - $staff = get_user_by('login', $login); - if ($staff->ID !=0 && in_array('staff', $staff->roles)){//is valid staff; - //wp_set_current_user($staff->ID); - $current = wp_get_current_user(); - if( $current->ID != $staff->ID) - wp_redirect("/task"); + + switch($pagename){ + case 'task': + $this->cauth_task(); + break; + case 'time-sheets': + $this->cauth_time_sheet(); + } + } + + private function cauth_task(){ + $login = get_query_var( 'bts_user_id' ); + $this->bts_job_start = get_query_var( 'bts_job_start' ); + $this->bts_job_finish = get_query_var( 'bts_job_finish' ); + $this->bts_week_id = get_query_var('bts_week_id'); + + $redirect_url = $this->get_redirect_url_for_task(); +// wp_send_json(array( +// 'week'=> $week, +// 'userid'=>$login, +// 'job_start' => $this->bts_job_start, +// 'job_finish' => $this->bts_job_finish, +// 'redirect' => $redirect_url, +// )); + + if ($login != "")//perform autologin, and redirect + { + $staff = get_user_by('login', $login); + if ($this->is_staff($staff)){//is valid staff; + $current = wp_get_current_user(); + if($current->ID != $staff->ID){ + wp_logout(); + wp_set_current_user($staff->ID, $staff->display_name); //this is a must + wp_set_auth_cookie($staff->ID, true);//only with this, wordpress calls login + redirect and lost week-%d } } + wp_redirect($redirect_url); + return; + } + + //no auto login is required if reach here. + $current = wp_get_current_user(); + if ($this->is_admin($current)){ + wp_redirect("/time-sheets/"); + return; } - //echo $pagename; + if (!$this->is_staff($current) && ! $this->is_admin($current)) + { + wp_logout(); + wp_redirect("/login/"); + return; + } + } + + private function get_week_id() + { + $week = get_query_var( 'bts_week_id' ); + $week_id = intval($week); + if ($week_id == 0 || $week_id >53 ||$week_id < 1) + return $this->get_current_week_id(); + else + return $week; + } + + private function get_current_week_id() + { + $now = new \DateTime(); + $week = $now->format("W"); + return $week; + } + + private function get_redirect_url_for_task() + { + if ($this->bts_week_id != "") + return "/task/week-" . $this->bts_week_id . "/"; + if ($this->bts_job_start!="" && $this->bts_job_finish !="") + return "/task/start-" . $this->bts_job_start . "/finish-" .$this->bts_job_finish . "/"; + return '/task/'; + } + + + private function cauth_time_sheet() + { + $current = wp_get_current_user(); + if ($current->ID == 0 ) { //visitor not logged in + wp_redirect("/wp-login.php?"); + return; + } + if ($this->is_staff($current)){ + wp_redirect("/task"); + return; + } + if ($this->is_admin($current)){ + //proceed + return; + } + if ($this->is_client($current)){ + wp_redirect("/service"); + return; + } + //everything else + wp_redirect("/?invalid-access"); } /// @@ -197,7 +292,7 @@ class AcareOffice{ // public function register_js_css() { $this->nonce = wp_create_nonce('acaresydney'); - $this->acaresydney_userid = get_query_var( 'bts_user_id' ) ; + $this->bts_user_id = get_query_var( 'bts_user_id' ) ; $this->register_bts_js(); $this->register_timesheet_js_css(); $this->register_task_js_css(); @@ -212,7 +307,7 @@ class AcareOffice{ 'display_name' => wp_get_current_user()->display_name, 'anonymous' => !is_user_logged_in(), 'me'=> get_current_user_id(), - 'userid'=> $this->acaresydney_userid, + 'userid'=> $this->bts_user_id, 'load_user_img'=> plugins_url('img/loading_user.gif', __FILE__), 'load_job_img'=> plugins_url('img/loading_job.gif', __FILE__), 'earnings_rate'=> get_option('bts_payitem_earnings_rate'), @@ -235,6 +330,11 @@ class AcareOffice{ if ($pagename != 'task'){ return; } + + $this->bts_job_start = get_query_var( 'bts_job_start' ); + $this->bts_job_finish = get_query_var( 'bts_job_finish' ); + $this->bts_week_id = get_query_var('bts_week_id'); + wp_enqueue_style( 'bts_task', plugins_url('css/bts_task.css', __FILE__)); wp_enqueue_script( 'bts_task', plugins_url('js/bts_task.js', __FILE__), array( 'jquery' , 'bts' )); wp_enqueue_script('mustache', plugins_url('js/mustache.min.js', __FILE__), array('jquery')); @@ -242,6 +342,9 @@ class AcareOffice{ wp_localize_script('bts_task','bts_task1',array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce('bts_task'), + 'week_id' => $this->bts_week_id, + 'bts_job_start' => $this->bts_job_start, + 'bts_job_finish' => $this->bts_job_finish, ) ); } @@ -269,24 +372,26 @@ class AcareOffice{ $n = new UserJob($u->user_login); $resp = $n->list_jobs("2019-07-22 00:00:00", "2019-07-28 23:59:59"); if ($resp['status']=='success' && $resp['job_count'] >0 ){ -// if( $u->user_login != "3e8c2e62-8e28-4b68-ae98-9ef1d76188c4" ) -// continue; + if( $u->user_login != "9aa3308e-cc19-4c21-a110-f2c6abec4337" ) + continue; $msg = sprintf("Staff = %s, Login=%s, email=%s Job=%d\n", $u->display_name, $u->user_login, $u->user_email, $resp['job_count']); echo $msg; - $this->send_email_with_job_link($u); + $this->send_email_with_job_link($u, "2019-07-22", "2019-07-28"); } } return; } - private function send_email_with_job_link($staff) + private function send_email_with_job_link($staff, $start, $finish) { $message = file_get_contents(plugin_dir_path(__FILE__) . "/html/email_job.html"); $message = str_ireplace("{{display_name}}", $staff->display_name, $message); $message = str_ireplace("{{user_login}}", $staff->user_login, $message); + $message = str_ireplace("{{job_start}}", $start, $message); + $message = str_ireplace("{{job_finish}}", $finish, $message); $headers = ['Bcc: patrick@biukop.com.au']; //wp_mail("sp@lawipac.com", "Your Job arrangement 22 July ~ 28 July", $message, $headers); - wp_mail($staff->user_email, "Your Job arrangement 22 July ~ 28 July", $message, $headers); + wp_mail($staff->user_email, "Your Job arrangement $start ~ $finish", $message, $headers); } public function bts_staff_item($attr){ @@ -536,6 +641,37 @@ class AcareOffice{ wp_die(); } + //ajax email staff their job arrangement + function email_job() + { + check_ajax_referer('acaresydney'); + $staff = $_POST['staff']; + $start = $_POST['start']; + $finish = $_POST['finish']; + $response=array( + 'status' => 'success', + 'staff' => $staff, + 'start' => $start, + 'finish' => $finish, + 'error' => '', + 'sent' => false, + 'emailstatus'=>"Bypass (no job)", + ); + + $u = get_user_by('login', $staff); + if ($this->is_staff($u)){ + $n = new UserJob($staff); + $resp = $n->list_jobs("$start 00:00:00", "$finish 23:59:59"); + if ($resp['status']=='success' && $resp['job_count'] >0 ){ + $msg = sprintf("Email to %s (with job=%d) \n", $u->user_email, $resp['job_count']); + $this->send_email_with_job_link($u, $start, $finish); + $response['sent'] = true; + $response['emailstatus'] = $msg; + } + } + wp_send_json($response); + } + //ajax browse job with different filters function list_job(){ check_ajax_referer('acaresydney'); @@ -570,33 +706,42 @@ class AcareOffice{ } public function list_job_by_staff() { - check_ajax_referer('acaresydney'); + //check_ajax_referer('acaresydney'); $start = $_POST['start']; $finish = $_POST['finish']; - $login = $_POST['login']; - $response= array( - 'status' => 'error', - 'current_user' => wp_get_current_user(), - ); - wp_send_json($response); - //$user = wp_get_current_user();// should be staff; - //$user = get_user_by('login', 'a6536a3b-ef22-4a28-8d55-e2a26d4ae227'); - //$login = get_query_var( 'bts_user_id' ); - //if ($user->ID ==0){ - $user = get_user_by('login', $login); - //} + //$start="2019-07-01 00:00:00"; + //$finish="2019-07-14 23:59:59"; - if (in_array('staff', $user->roles)){ - //require_once (dirname(__FILE__) . "/UserJob.php"); + $user = wp_get_current_user();// should be staff; + if ( $this->is_staff($user) ){ $n = new UserJob($user->user_login); $response = $n->list_jobs($start, $finish); - $response['current_user'] = wp_get_current_user(); + wp_send_json($response); + }else{ + $response = array( + 'status' => 'error', + 'errmsg' => 'invalid access', + 'user' => $user, + ); wp_send_json($response); } wp_die(); } + private function is_staff($user) + { + return ($user->ID !=0 && in_array('staff', $user->roles)); + } + + private function is_admin($user) + { + $allowed_roles = array('administrator', 'acare_owner'); + if( array_intersect($allowed_roles, $user->roles ) ) { + return true; + } + } + public function staff_ack_job() { check_ajax_referer('acaresydney'); @@ -653,4 +798,5 @@ if ( defined( 'WP_CLI' ) && WP_CLI ) { \WP_CLI::add_command( 'email_jobs', array($bb, 'email_jobs')); } - +//$bb->class_loader(); +//$bb->list_job_by_staff();