db = $wpdb;
$this->table_name = $wpdb->prefix . 'acare_ts';
$this->addr_table = $wpdb->prefix . 'acare_addr_distance';
$this->ndis_table = $wpdb->prefix . 'acare_ndis_price';
}
/**
* Autoload the custom theme classes
*/
public function class_loader()
{
// Create a new instance of the autoloader
$loader = new \Psr4AutoloaderClass();
// Register this instance
$loader->register();
// Add our namespace and the folder it maps to
$loader->addNamespace('\XeroPHP', dirname(__FILE__) . '/xero-php-master/src/XeroPHP');
$loader->addNamespace('\Biukop', dirname(__FILE__) . '/' );
$this->xero = new Xero();
$this->xero->init_wp();
//$abc = new AddrMap("01515b52-6936-46b2-a000-9ad4cd7a5b50", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c");
$abc = new AddrMap("122eb1d0-d8c4-4fc3-8bf8-b7825bee1a01", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c");
}
//init database
public function db_install () {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
//table name: timesheets jobs
$table_name = $this->table_name;
$sql = "CREATE TABLE $table_name (
id INT NOT NULL AUTO_INCREMENT,
tos VARCHAR(45) NULL,
start DATETIME NULL,
finish DATETIME NULL,
rate VARCHAR(45) NULL,
staff VARCHAR(45) NULL,
client VARCHAR(45) NULL,
ack TINYINT(4) NULL,
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;";
$ndis_table = $this->ndis_table;
$sql_ndis_price = "
CREATE TABLE $ndis_table (
code VARCHAR(45) NOT NULL,
name VARCHAR(45) NULL,
level INT NULL,
unit VARCHAR(45) NULL,
price FLOAT NULL,
year INT NOT NULL,
PRIMARY KEY (code, year)
)$charset_collate;";
//create database
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
dbDelta( $sql_addr);
dbDelta( $sql_ndis_price);
}
//
//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;
}
//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]',
'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;
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;
}
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");
}
///
// enqueue / register css /js
//
public function register_js_css() {
$this->nonce = wp_create_nonce('acaresydney');
$this->bts_user_id = get_query_var( 'bts_user_id' ) ;
$this->register_bts_js();
$this->register_timesheet_js_css();
$this->register_task_js_css();
}
private function register_bts_js()
{
wp_enqueue_style( 'bts', plugins_url('css/ts.css', __FILE__));
wp_enqueue_script('bts', plugins_url('js/ts.js', __FILE__), array('jquery', 'jquery-ui-core'));
wp_localize_script( 'bts', 'bts1', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $this->nonce, // It is common practice to comma after
'display_name' => wp_get_current_user()->display_name,
'anonymous' => !is_user_logged_in(),
'me'=> get_current_user_id(),
'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'),
'high_pay_keywords' => ['sat ', 'sun ', 'high ', 'public holiday'], //space is important
) );
}
private function register_timesheet_js_css(){
global $pagename;
if ($pagename != 'time-sheets'){
return;
}
wp_enqueue_style( 'bts_ts', plugins_url('css/bts_timesheet.css', __FILE__));
wp_enqueue_script( 'bts_ts', plugins_url('js/bts_timesheet.js', __FILE__), array( 'jquery' , 'bts' ));
wp_enqueue_script('mustache', plugins_url('js/mustache.min.js', __FILE__), array('jquery'));
}
private function register_task_js_css(){
global $pagename;
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'));
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,
) );
}
public function sync_users()
{
//dummy sync
return;
}
// Usage: `wp sync_users --mininterval=123
public function sync_user_cli($args = array(), $assoc_args = array()){
$arguments = wp_parse_args( $assoc_args, array(
'mininterval' => 600,
'employeeonly' => false,
'clientsonly' => false,
) );
$this->xero->sync_users($arguments['mininterval'], $arguments['employeeonly'], $arguments['clientsonly']);
return;
}
public function email_jobs($args = array(), $assoc_args = array()){
$users = get_users(array('role' => 'staff'));
foreach ($users as $u){
$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 != "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, "2019-07-22", "2019-07-28");
}
}
return;
}
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 $start ~ $finish", $message, $headers);
}
public function bts_staff_item($attr){
return $this->template('staff_item', 'staff.html');
}
public function bts_client_item($attr){
return $this->template('client_item', 'client.html');
}
public function bts_job_item($attr){
$html =$this->template('job_item', 'job.html');
//$html = str_replace('[bts-tos-options]', $this->bts_tos_options([]), $html);
$html = do_shortcode($html);
return $html;
}
public function bts_rate_options($attr){
$result = "";
return $result;
}
public function bts_select_staff($attr){
$result = "";
return $result;
}
public function bts_select_client($attr){
$result = "";
return $result;
}
public function bts_type_of_service($attr){
$n = new NdisPrice(2019);
return $n->get_html();
}
public function bts_user_name($attr)
{
$user = wp_get_current_user();
return $user->display_name;
}
public function bts_staff_job_summary($attr)
{
$result ="
If there is more than one job, please click on 'confirm' to make sure it is included in your payment.
";
return $result;
}
//generate template based on html file
private function template($id, $file)
{
$text = '';
return $text;
}
function list_staff(){
check_ajax_referer('acaresydney');
// Handle the ajax request
$response = array(
'status' =>'error',
'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();
if (! empty($staff)){
$response['status'] = 'success';
foreach( $staff as $s){
$response['users'][] = array(
'login' => $s->user_login,
'firstname'=> $s->first_name,
'lastname'=> $s->last_name,
'mobile'=> get_user_meta($s->ID, 'mobile', true),
'email'=> $s->user_email,
'wages'=> 0,
'hour' => 0 ,
'OT' => 0 ,
'petrol'=> 0 ,
'rating'=> 0,
'unconfirmedjob'=> 0,
);
}
}
wp_send_json($response);
wp_die();
}
function list_client(){
check_ajax_referer('acaresydney');
// Handle the ajax request
$response = array(
'status' =>'error',
'users' => [],
);
//search all users that are staff
$clientq = new \WP_User_Query(array('role'=>'client', 'meta_key'=>'first_name', 'orderby'=>'meta_value', 'order'=>'ASC'));
$client = $clientq->get_results();
if (! empty($client)){
$response['status'] = 'success';
foreach( $client as $s){
$response['users'][] = array(
'login' => $s->user_login,
'firstname'=> $s->first_name,
'lastname'=> $s->last_name,
'display_name'=> $s->display_name,
'mobile'=> get_user_meta($s->ID, 'mobile', true),
'email'=> $s->user_email,
'account'=> get_user_meta($s->ID, 'account', true),
'address' => get_user_meta($s->ID, 'address', true),
'rating'=> 0,
'unconfirmedjob'=> 0,
);
}
}
wp_send_json($response);
wp_die();
}
private function get_people_by_role($role){
//search all users that are staff
$staffq = new \WP_User_Query(array('role'=>$role, 'meta_key'=>'first_name', 'orderby'=>'meta_value', 'order'=>'ASC'));
$staff = $staffq->get_results();
return $staff;
}
//ajax get earnings rates
function get_payitem_earnings_rate()
{
$response= array(
'status' => 'success',
'options'=> get_option('bts_payitem_earnings_rate'),
);
wp_send_json($response);
}
//ajax job CRUD
function save_job()
{
check_ajax_referer('acaresydney');
$r = $_POST['record'];
$response = array();
$d = array(
'tos' => $r['tos'],
'start' => $r['start'],
'finish' => $r['finish'],
'rate' => $r['rate'],
'staff' => $r['staff'],
'client' => $r['client'],
'ack' => $r['ack']=='true'?1:0,
'rating'=>$r['rating'],
);
//this is an update
if ( isset($r['id']) && trim($r['id']) !='' && is_numeric($r['id'])){
$response['isNew'] = false; //add or update?
$result = $this->db->update($this->table_name, $d, array('id' =>$r['id']));
if ($result !== false && $this->db->last_error == ''){
$d['id'] = $r['id'];
$response['status'] = 'success';
//do data type conversion, string to int
$response['newdata'] = $this->get_ts_record($r['id']);
$response['errors'] = array(); //empty array
}else{
$response['status'] = 'error';
$repsonse['errors'] = array(
'db' => "network database error" . $this->db->last_error,
);
}
}else{
$response['isNew'] = true;
$result = $this->db->insert($this->table_name, $d);
$lastid = $this->db->insert_id;
if ($result != false && $this->db->last_error == ''){
$response['status'] = 'success';
$response['newdata'] = $this->get_ts_record($lastid);
}else{
$response['status'] = 'error';
$response['errors'] = array(
'db' => 'network database error ' . $this->db->last_error,
);
}
}
wp_send_json($response);
wp_die();
}
private function get_ts_record($id){
$sql = "SELECT * FROM $this->table_name WHERE id=%d";
$row = $this->db->get_row($this->db->prepare ($sql, array($id)));
$response = [];
if ($row != null){
$response = array(
'id' => (int)$row->id,
'tos' => $row->tos,
'start' => $row->start,
'finish' => $row->finish,
'rate' => $row->rate,
'staff' => $row->staff,
'client' => $row->client,
'ack' => (int)$row->ack,
'rating' =>(int) $row->rating,
);
}
return $response;
}
//ajax delete job
function delete_job(){
check_ajax_referer('acaresydney');
$id = $_POST['jobid'];
$result = $this->db->delete($this->table_name, array('id'=> $id));
$response=array(
'status' => 'success',
'id' => $id,
'action'=> 'delete',
'error' => '',
);
if ($result == 1){
wp_send_json($response);
}else{
$response['status'] = 'error';
$response['error'] = $this->db->last_error;
wp_send_json($response);
}
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');
$start = $_POST['start'];
$finish = $_POST['finish'];
$response = array(
'status'=>'success',
'jobs' => [],
);
$sql = "SELECT * FROM $this->table_name WHERE start>='%s' and start <='%s' order by start ASC ,staff ASC";
$jobs = $this->db->get_results($this->db->prepare ($sql, array($start, $finish)));
if (! empty($jobs)){
$response['status'] = 'success';
foreach( $jobs as $s){
$response['jobs'][] = array(
'id' => $s->id,
'tos' => $s->tos,
'start'=> $s->start,
'finish'=> $s->finish,
'rate'=> $s->rate,
'staff'=> $s->staff,
'client'=> $s->client,
'ack' => $s->ack,
'rating' =>$s->rating,
);
}
}
wp_send_json($response);
wp_die();
}
public function list_job_by_staff()
{
//check_ajax_referer('acaresydney');
$start = $_POST['start'];
$finish = $_POST['finish'];
//$start="2019-07-01 00:00:00";
//$finish="2019-07-14 23:59:59";
$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);
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');
$jobs = $_POST['jobs'];
$response = array(
'status'=>'success',
'jobs'=>$jobs,
);
$yes=[];
$no=[];
foreach($jobs as $job){
if ( $job['ack'] == "true")
$yes[] =(int) $job['id'];
else
$no[] = (int) $job['id'];
}
$err = $this->ack_multiple_job($yes, $no);
if ($this->db->last_error !='')
{
$response['status']= 'error';
$response['err_msg']= $err;
}
$response['yes'] = $yes;
$response['no'] = $no;
wp_send_json($response);
wp_die();
}
public function ack_multiple_job($yes, $no)
{
$str_yes_ids = implode(",", $yes);
$str_no_ids = implode(",", $no);
$err = "";
if (count($yes) >0 ){
$sql = "UPDATE $this->table_name SET ack=1 WHERE id IN ( $str_yes_ids) ; ";
$r = $this->db->get_results($sql);
$err = $this->db->last_error;
}
if (count($no) >0 ){
$sql = "UPDATE $this->table_name SET ack=0 WHERE id IN ( $str_no_ids) ; ";
$r = $this->db->get_results($sql);
$err .= $this->db->last_error;
}
return $err;
}
}
$bb = new AcareOffice();
if ( defined( 'WP_CLI' ) && WP_CLI ) {
\WP_CLI::add_command( 'sync_users', array($bb, 'sync_user_cli'));
\WP_CLI::add_command( 'email_jobs', array($bb, 'email_jobs'));
}
//$bb->class_loader();
//$bb->list_job_by_staff();