timesheet source code
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

808 lines
29KB

  1. <?php
  2. /**
  3. * Plugin Name: Acare Advanced Office
  4. * Plugin URI: http://biukop.com.au/acaresydney/timesheets
  5. * Description: Advanced Office system, timesheet, Payroll for AcareSydney
  6. * Version: 2.1
  7. * Author: Biukop Intelligence
  8. * Author URI: http://biukop.com.au/
  9. */
  10. namespace Biukop;
  11. use XeroPHP\Models\Accounting\Address;
  12. require_once(dirname(__FILE__) . '/autoload.php');
  13. require_once (ABSPATH . 'wp-includes/pluggable.php');
  14. class AcareOffice{
  15. private $nonce; //for ajax verification
  16. private $pages = array('time-sheets', 'user-list');
  17. private $bts_user_id = 0;
  18. private $bts_week_id = 1; //week 1, we will try to calculate current week;
  19. private $xero ;
  20. private $db;
  21. private $table_name;
  22. private $addr_table;
  23. public function __construct() {
  24. add_option( "acare_ts_db_version", "1.0" );
  25. register_activation_hook( __FILE__, array($this, 'db_install') );
  26. add_action('init', array($this, 'class_loader'));
  27. add_action('wp', array($this, 'check_auth'));
  28. add_action('wp_enqueue_scripts', array($this, 'register_js_css'), 99);
  29. add_filter('show_admin_bar', '__return_false');
  30. //ts-xx for sync single user
  31. add_shortcode( 'ts-sync-users', array($this, 'sync_users'));
  32. //bts-xx for webpage
  33. add_shortcode( 'bts_staff_item', array($this, 'bts_staff_item'));
  34. add_shortcode( 'bts_client_item', array($this, 'bts_client_item'));
  35. add_shortcode( 'bts_job_item', array($this, 'bts_job_item'));
  36. add_shortcode( 'bts_rate_options', array($this, 'bts_rate_options'));
  37. add_shortcode( 'bts_select_staff', array($this, 'bts_select_staff'));
  38. add_shortcode( 'bts_select_client', array($this, 'bts_select_client'));
  39. add_shortcode( 'bts_type_of_service', array($this, 'bts_type_of_service'));
  40. add_shortcode( 'bts_staff_job_summary', array($this, 'bts_staff_job_summary'));
  41. //user profile page
  42. add_shortcode( 'bts_user_name', array($this,'bts_user_name'));
  43. add_action('wp_ajax_list_staff', array($this,'list_staff' ));
  44. add_action('wp_ajax_list_client', array($this,'list_client' ));
  45. add_action('wp_ajax_save_job', array($this,'save_job' ));
  46. add_action('wp_ajax_list_job', array($this,'list_job' ));
  47. add_action('wp_ajax_delete_job', array($this,'delete_job' ));
  48. add_action('wp_ajax_email_job', array($this,'email_job' ));
  49. add_action('wp_ajax_earnings_rate', array($this,'get_payitem_earnings_rate' ));
  50. add_action('wp_ajax_nopriv_earnings_rate', array($this,'get_payitem_earnings_rate' ));
  51. add_action('wp_ajax_list_job_by_staff', array($this,'list_job_by_staff' ));
  52. add_action('wp_ajax_nopriv_list_job_by_staff', array($this,'list_job_by_staff' ));
  53. add_action('wp_ajax_staff_ack_job', array($this,'staff_ack_job' ));
  54. add_action('wp_ajax_nopriv_staff_ack_job', array($this,'staff_ack_job' ));
  55. // hook add_rewrite_rules function into rewrite_rules_array
  56. add_filter('rewrite_rules_array', array($this,'my_add_rewrite_rules'));
  57. // hook add_query_vars function into query_vars
  58. add_filter('query_vars', array($this,'add_query_vars'));
  59. global $wpdb;
  60. $this->db = $wpdb;
  61. $this->table_name = $wpdb->prefix . 'acare_ts';
  62. $this->addr_table = $wpdb->prefix . 'acare_addr_distance';
  63. $this->ndis_table = $wpdb->prefix . 'acare_ndis_price';
  64. }
  65. /**
  66. * Autoload the custom theme classes
  67. */
  68. public function class_loader()
  69. {
  70. // Create a new instance of the autoloader
  71. $loader = new \Psr4AutoloaderClass();
  72. // Register this instance
  73. $loader->register();
  74. // Add our namespace and the folder it maps to
  75. $loader->addNamespace('\XeroPHP', dirname(__FILE__) . '/xero-php-master/src/XeroPHP');
  76. $loader->addNamespace('\Biukop', dirname(__FILE__) . '/' );
  77. $this->xero = new Xero();
  78. $this->xero->init_wp();
  79. //$abc = new AddrMap("01515b52-6936-46b2-a000-9ad4cd7a5b50", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c");
  80. $abc = new AddrMap("122eb1d0-d8c4-4fc3-8bf8-b7825bee1a01", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c");
  81. }
  82. //init database
  83. public function db_install () {
  84. global $wpdb;
  85. $charset_collate = $wpdb->get_charset_collate();
  86. //table name: timesheets jobs
  87. $table_name = $this->table_name;
  88. $sql = "CREATE TABLE $table_name (
  89. id INT NOT NULL AUTO_INCREMENT,
  90. tos VARCHAR(45) NULL,
  91. start DATETIME NULL,
  92. finish DATETIME NULL,
  93. rate VARCHAR(45) NULL,
  94. staff VARCHAR(45) NULL,
  95. client VARCHAR(45) NULL,
  96. ack TINYINT(4) NULL,
  97. rating INT(4) NULL DEFAULT 0,
  98. PRIMARY KEY (id)
  99. ) $charset_collate;";
  100. //addr distance
  101. $addr_table = $this->addr_table;
  102. $sql_addr = "CREATE TABLE $addr_table (
  103. id INT NOT NULL AUTO_INCREMENT,
  104. origin VARCHAR(1024) NULL,
  105. destination VARCHAR(1024) NULL,
  106. response VARCHAR(40960) NULL,
  107. distance INT NULL,
  108. PRIMARY KEY (id)
  109. ) $charset_collate;";
  110. $ndis_table = $this->ndis_table;
  111. $sql_ndis_price = "
  112. CREATE TABLE $ndis_table (
  113. code VARCHAR(45) NOT NULL,
  114. name VARCHAR(45) NULL,
  115. level INT NULL,
  116. unit VARCHAR(45) NULL,
  117. price FLOAT NULL,
  118. year INT NOT NULL,
  119. PRIMARY KEY (code, year)
  120. )$charset_collate;";
  121. //create database
  122. require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
  123. dbDelta( $sql );
  124. dbDelta( $sql_addr);
  125. dbDelta( $sql_ndis_price);
  126. }
  127. //
  128. //query var
  129. public function add_query_vars($aVars) {
  130. $aVars[] = "bts_user_id"; // represents the name of the product category as shown in the URL
  131. $aVars[] = "bts_week_id"; // represents the name of the product category as shown in the URL
  132. $aVars[] = "bts_job_start"; // represents the name of the product category as shown in the URL
  133. $aVars[] = "bts_job_finish"; // represents the name of the product category as shown in the URL
  134. return $aVars;
  135. }
  136. //for customer profile and broker trans
  137. public function my_add_rewrite_rules($aRules) {
  138. $aNewRules = array(
  139. 'user/([^/]+)/?$' => 'index.php?pagename=user&bts_user_id=$matches[1]',
  140. 'task/week-([^/]+)/?$' => 'index.php?pagename=task&bts_week_id=$matches[1]',
  141. 'task/start-([^/]+)/finish-([^/]+)/?$' => 'index.php?pagename=task&bts_job_start=$matches[1]&bts_job_finish=$matches[2]',
  142. 'task/([^/]+)/?$' => 'index.php?pagename=task&bts_user_id=$matches[1]',
  143. 'task/([^/]+)/week-([^/]+)/?$' => 'index.php?pagename=task&bts_user_id=$matches[1]&bts_week_id=$matches[2]',
  144. 'task/([^/]+)/start-([^/]+)/finish-([^/]+)/?$' => 'index.php?pagename=task&bts_user_id=$matches[1]&bts_job_start=$matches[2]&bts_job_finish=$matches[3]',
  145. );
  146. $aRules = $aNewRules + $aRules;
  147. return $aRules;
  148. }
  149. //
  150. //
  151. ///check auth
  152. public function check_auth(){
  153. global $pagename;
  154. switch($pagename){
  155. case 'task':
  156. $this->cauth_task();
  157. break;
  158. case 'time-sheets':
  159. $this->cauth_time_sheet();
  160. }
  161. }
  162. private function cauth_task(){
  163. $login = get_query_var( 'bts_user_id' );
  164. $this->bts_job_start = get_query_var( 'bts_job_start' );
  165. $this->bts_job_finish = get_query_var( 'bts_job_finish' );
  166. $this->bts_week_id = get_query_var('bts_week_id');
  167. $redirect_url = $this->get_redirect_url_for_task();
  168. // wp_send_json(array(
  169. // 'week'=> $week,
  170. // 'userid'=>$login,
  171. // 'job_start' => $this->bts_job_start,
  172. // 'job_finish' => $this->bts_job_finish,
  173. // 'redirect' => $redirect_url,
  174. // ));
  175. if ($login != "")//perform autologin, and redirect
  176. {
  177. $staff = get_user_by('login', $login);
  178. if ($this->is_staff($staff)){//is valid staff;
  179. $current = wp_get_current_user();
  180. if($current->ID != $staff->ID){
  181. wp_logout();
  182. wp_set_current_user($staff->ID, $staff->display_name); //this is a must
  183. wp_set_auth_cookie($staff->ID, true);//only with this, wordpress calls login + redirect and lost week-%d
  184. }
  185. }
  186. wp_redirect($redirect_url);
  187. return;
  188. }
  189. //no auto login is required if reach here.
  190. $current = wp_get_current_user();
  191. if ($this->is_admin($current)){
  192. wp_redirect("/time-sheets/");
  193. return;
  194. }
  195. if (!$this->is_staff($current) && ! $this->is_admin($current))
  196. {
  197. wp_logout();
  198. wp_redirect("/login/");
  199. return;
  200. }
  201. }
  202. private function get_week_id()
  203. {
  204. $week = get_query_var( 'bts_week_id' );
  205. $week_id = intval($week);
  206. if ($week_id == 0 || $week_id >53 ||$week_id < 1)
  207. return $this->get_current_week_id();
  208. else
  209. return $week;
  210. }
  211. private function get_current_week_id()
  212. {
  213. $now = new \DateTime();
  214. $week = $now->format("W");
  215. return $week;
  216. }
  217. private function get_redirect_url_for_task()
  218. {
  219. if ($this->bts_week_id != "")
  220. return "/task/week-" . $this->bts_week_id . "/";
  221. if ($this->bts_job_start!="" && $this->bts_job_finish !="")
  222. return "/task/start-" . $this->bts_job_start . "/finish-" .$this->bts_job_finish . "/";
  223. return '/task/';
  224. }
  225. private function cauth_time_sheet()
  226. {
  227. $current = wp_get_current_user();
  228. if ($current->ID == 0 ) { //visitor not logged in
  229. wp_redirect("/wp-login.php?");
  230. return;
  231. }
  232. if ($this->is_staff($current)){
  233. wp_redirect("/task");
  234. return;
  235. }
  236. if ($this->is_admin($current)){
  237. //proceed
  238. return;
  239. }
  240. if ($this->is_client($current)){
  241. wp_redirect("/service");
  242. return;
  243. }
  244. //everything else
  245. wp_redirect("/?invalid-access");
  246. }
  247. ///
  248. // enqueue / register css /js
  249. //
  250. public function register_js_css() {
  251. $this->nonce = wp_create_nonce('acaresydney');
  252. $this->bts_user_id = get_query_var( 'bts_user_id' ) ;
  253. $this->register_bts_js();
  254. $this->register_timesheet_js_css();
  255. $this->register_task_js_css();
  256. }
  257. private function register_bts_js()
  258. {
  259. wp_enqueue_style( 'bts', plugins_url('css/ts.css', __FILE__));
  260. wp_enqueue_script('bts', plugins_url('js/ts.js', __FILE__), array('jquery', 'jquery-ui-core'));
  261. wp_localize_script( 'bts', 'bts1', array(
  262. 'ajax_url' => admin_url( 'admin-ajax.php' ),
  263. 'nonce' => $this->nonce, // It is common practice to comma after
  264. 'display_name' => wp_get_current_user()->display_name,
  265. 'anonymous' => !is_user_logged_in(),
  266. 'me'=> get_current_user_id(),
  267. 'userid'=> $this->bts_user_id,
  268. 'load_user_img'=> plugins_url('img/loading_user.gif', __FILE__),
  269. 'load_job_img'=> plugins_url('img/loading_job.gif', __FILE__),
  270. 'earnings_rate'=> get_option('bts_payitem_earnings_rate'),
  271. 'high_pay_keywords' => ['sat ', 'sun ', 'high ', 'public holiday'], //space is important
  272. ) );
  273. }
  274. private function register_timesheet_js_css(){
  275. global $pagename;
  276. if ($pagename != 'time-sheets'){
  277. return;
  278. }
  279. wp_enqueue_style( 'bts_ts', plugins_url('css/bts_timesheet.css', __FILE__));
  280. wp_enqueue_script( 'bts_ts', plugins_url('js/bts_timesheet.js', __FILE__), array( 'jquery' , 'bts' ));
  281. wp_enqueue_script('mustache', plugins_url('js/mustache.min.js', __FILE__), array('jquery'));
  282. }
  283. private function register_task_js_css(){
  284. global $pagename;
  285. if ($pagename != 'task'){
  286. return;
  287. }
  288. $this->bts_job_start = get_query_var( 'bts_job_start' );
  289. $this->bts_job_finish = get_query_var( 'bts_job_finish' );
  290. $this->bts_week_id = get_query_var('bts_week_id');
  291. wp_enqueue_style( 'bts_task', plugins_url('css/bts_task.css', __FILE__));
  292. wp_enqueue_script( 'bts_task', plugins_url('js/bts_task.js', __FILE__), array( 'jquery' , 'bts' ));
  293. wp_enqueue_script('mustache', plugins_url('js/mustache.min.js', __FILE__), array('jquery'));
  294. wp_localize_script('bts_task','bts_task1',array(
  295. 'ajax_url' => admin_url( 'admin-ajax.php' ),
  296. 'nonce' => wp_create_nonce('bts_task'),
  297. 'week_id' => $this->bts_week_id,
  298. 'bts_job_start' => $this->bts_job_start,
  299. 'bts_job_finish' => $this->bts_job_finish,
  300. ) );
  301. }
  302. public function sync_users()
  303. {
  304. //dummy sync
  305. return;
  306. }
  307. // Usage: `wp sync_users --mininterval=123
  308. public function sync_user_cli($args = array(), $assoc_args = array()){
  309. $arguments = wp_parse_args( $assoc_args, array(
  310. 'mininterval' => 600,
  311. 'employeeonly' => false,
  312. 'clientsonly' => false,
  313. ) );
  314. $this->xero->sync_users($arguments['mininterval'], $arguments['employeeonly'], $arguments['clientsonly']);
  315. return;
  316. }
  317. public function email_jobs($args = array(), $assoc_args = array()){
  318. $users = get_users(array('role' => 'staff'));
  319. foreach ($users as $u){
  320. $n = new UserJob($u->user_login);
  321. $resp = $n->list_jobs("2019-07-22 00:00:00", "2019-07-28 23:59:59");
  322. if ($resp['status']=='success' && $resp['job_count'] >0 ){
  323. if( $u->user_login != "9aa3308e-cc19-4c21-a110-f2c6abec4337" )
  324. continue;
  325. $msg = sprintf("Staff = %s, Login=%s, email=%s Job=%d\n", $u->display_name, $u->user_login, $u->user_email, $resp['job_count']);
  326. echo $msg;
  327. $this->send_email_with_job_link($u, "2019-07-22", "2019-07-28");
  328. }
  329. }
  330. return;
  331. }
  332. private function send_email_with_job_link($staff, $start, $finish)
  333. {
  334. $message = file_get_contents(plugin_dir_path(__FILE__) . "/html/email_job.html");
  335. $message = str_ireplace("{{display_name}}", $staff->display_name, $message);
  336. $message = str_ireplace("{{user_login}}", $staff->user_login, $message);
  337. $message = str_ireplace("{{job_start}}", $start, $message);
  338. $message = str_ireplace("{{job_finish}}", $finish, $message);
  339. $headers = ['Bcc: patrick@biukop.com.au, timesheet@acaresydney.com.au'];
  340. $subject = $staff->display_name . " Job arrangement $start ~ $finish";
  341. //wp_mail("sp@lawipac.com", $subject, $message, $headers);
  342. //wp_mail("timesheet@acaresydney.com.au", $subject, $message, $headers);
  343. wp_mail($staff->user_email, $subject, $message, $headers);
  344. }
  345. public function bts_staff_item($attr){
  346. return $this->template('staff_item', 'staff.html');
  347. }
  348. public function bts_client_item($attr){
  349. return $this->template('client_item', 'client.html');
  350. }
  351. public function bts_job_item($attr){
  352. $html =$this->template('job_item', 'job.html');
  353. //$html = str_replace('[bts-tos-options]', $this->bts_tos_options([]), $html);
  354. $html = do_shortcode($html);
  355. return $html;
  356. }
  357. public function bts_rate_options($attr){
  358. $result = "<select> \n";
  359. $options = get_option('bts_payitem_earnings_rate');
  360. foreach($options as $o){
  361. $result.=sprintf("<option value='%s'> $%3.2f-%s</option>",
  362. $o['EarningsRateID'], $o['RatePerUnit'], $o['Name']);
  363. }
  364. $result .="</select>";
  365. return $result;
  366. }
  367. public function bts_select_staff($attr){
  368. $result = "<select> \n";
  369. $staff = $this->get_people_by_role('staff');
  370. foreach ($staff as $u){
  371. $result .= sprintf("<option value=%s> %s</option>", $u->user_login, $u->first_name . " " . $u->last_name);
  372. }
  373. $result .="</select>";
  374. return $result;
  375. }
  376. public function bts_select_client($attr){
  377. $result = "<select> \n";
  378. $staff = $this->get_people_by_role('client');
  379. foreach ($staff as $u){
  380. $result .= sprintf("<option value=%s> %s</option>", $u->user_login, $u->display_name);
  381. }
  382. $result .="</select>";
  383. return $result;
  384. }
  385. public function bts_type_of_service($attr){
  386. $n = new NdisPrice(2019);
  387. return $n->get_html();
  388. }
  389. public function bts_user_name($attr)
  390. {
  391. $user = wp_get_current_user();
  392. return $user->display_name;
  393. }
  394. public function bts_staff_job_summary($attr)
  395. {
  396. $result ="<span>
  397. If there is more than one job, please click on 'confirm' to make sure it is included in your payment.
  398. </span>";
  399. return $result;
  400. }
  401. //generate template based on html file
  402. private function template($id, $file)
  403. {
  404. $text = '<script id="' . $id .'" type="text/x-biukop-template">';
  405. $text .= file_get_contents(plugin_dir_path(__FILE__) . "/html/$file");
  406. $text .= '</script>';
  407. return $text;
  408. }
  409. function list_staff(){
  410. check_ajax_referer('acaresydney');
  411. // Handle the ajax request
  412. $response = array(
  413. 'status' =>'error',
  414. 'users' => [],
  415. );
  416. //search all users that are staff
  417. $staffq = new \WP_User_Query(array('role'=>'staff','meta_key'=>'first_name', 'orderby'=>'meta_value', 'order'=>'ASC'));
  418. $staff = $staffq->get_results();
  419. if (! empty($staff)){
  420. $response['status'] = 'success';
  421. foreach( $staff as $s){
  422. $response['users'][] = array(
  423. 'login' => $s->user_login,
  424. 'firstname'=> $s->first_name,
  425. 'lastname'=> $s->last_name,
  426. 'mobile'=> get_user_meta($s->ID, 'mobile', true),
  427. 'email'=> $s->user_email,
  428. 'wages'=> 0,
  429. 'hour' => 0 ,
  430. 'OT' => 0 ,
  431. 'petrol'=> 0 ,
  432. 'rating'=> 0,
  433. 'unconfirmedjob'=> 0,
  434. );
  435. }
  436. }
  437. wp_send_json($response);
  438. wp_die();
  439. }
  440. function list_client(){
  441. check_ajax_referer('acaresydney');
  442. // Handle the ajax request
  443. $response = array(
  444. 'status' =>'error',
  445. 'users' => [],
  446. );
  447. //search all users that are staff
  448. $clientq = new \WP_User_Query(array('role'=>'client', 'meta_key'=>'first_name', 'orderby'=>'meta_value', 'order'=>'ASC'));
  449. $client = $clientq->get_results();
  450. if (! empty($client)){
  451. $response['status'] = 'success';
  452. foreach( $client as $s){
  453. $response['users'][] = array(
  454. 'login' => $s->user_login,
  455. 'firstname'=> $s->first_name,
  456. 'lastname'=> $s->last_name,
  457. 'display_name'=> $s->display_name,
  458. 'mobile'=> get_user_meta($s->ID, 'mobile', true),
  459. 'email'=> $s->user_email,
  460. 'account'=> get_user_meta($s->ID, 'account', true),
  461. 'address' => get_user_meta($s->ID, 'address', true),
  462. 'rating'=> 0,
  463. 'unconfirmedjob'=> 0,
  464. );
  465. }
  466. }
  467. wp_send_json($response);
  468. wp_die();
  469. }
  470. private function get_people_by_role($role){
  471. //search all users that are staff
  472. $staffq = new \WP_User_Query(array('role'=>$role, 'meta_key'=>'first_name', 'orderby'=>'meta_value', 'order'=>'ASC'));
  473. $staff = $staffq->get_results();
  474. return $staff;
  475. }
  476. //ajax get earnings rates
  477. function get_payitem_earnings_rate()
  478. {
  479. $response= array(
  480. 'status' => 'success',
  481. 'options'=> get_option('bts_payitem_earnings_rate'),
  482. );
  483. wp_send_json($response);
  484. }
  485. //ajax job CRUD
  486. function save_job()
  487. {
  488. check_ajax_referer('acaresydney');
  489. $r = $_POST['record'];
  490. $response = array();
  491. $d = array(
  492. 'tos' => $r['tos'],
  493. 'start' => $r['start'],
  494. 'finish' => $r['finish'],
  495. 'rate' => $r['rate'],
  496. 'staff' => $r['staff'],
  497. 'client' => $r['client'],
  498. 'ack' => $r['ack']=='true'?1:0,
  499. 'rating'=>$r['rating'],
  500. );
  501. //this is an update
  502. if ( isset($r['id']) && trim($r['id']) !='' && is_numeric($r['id'])){
  503. $response['isNew'] = false; //add or update?
  504. $result = $this->db->update($this->table_name, $d, array('id' =>$r['id']));
  505. if ($result !== false && $this->db->last_error == ''){
  506. $d['id'] = $r['id'];
  507. $response['status'] = 'success';
  508. //do data type conversion, string to int
  509. $response['newdata'] = $this->get_ts_record($r['id']);
  510. $response['errors'] = array(); //empty array
  511. }else{
  512. $response['status'] = 'error';
  513. $repsonse['errors'] = array(
  514. 'db' => "network database error" . $this->db->last_error,
  515. );
  516. }
  517. }else{
  518. $response['isNew'] = true;
  519. $result = $this->db->insert($this->table_name, $d);
  520. $lastid = $this->db->insert_id;
  521. if ($result != false && $this->db->last_error == ''){
  522. $response['status'] = 'success';
  523. $response['newdata'] = $this->get_ts_record($lastid);
  524. }else{
  525. $response['status'] = 'error';
  526. $response['errors'] = array(
  527. 'db' => 'network database error ' . $this->db->last_error,
  528. );
  529. }
  530. }
  531. wp_send_json($response);
  532. wp_die();
  533. }
  534. private function get_ts_record($id){
  535. $sql = "SELECT * FROM $this->table_name WHERE id=%d";
  536. $row = $this->db->get_row($this->db->prepare ($sql, array($id)));
  537. $response = [];
  538. if ($row != null){
  539. $response = array(
  540. 'id' => (int)$row->id,
  541. 'tos' => $row->tos,
  542. 'start' => $row->start,
  543. 'finish' => $row->finish,
  544. 'rate' => $row->rate,
  545. 'staff' => $row->staff,
  546. 'client' => $row->client,
  547. 'ack' => (int)$row->ack,
  548. 'rating' =>(int) $row->rating,
  549. );
  550. }
  551. return $response;
  552. }
  553. //ajax delete job
  554. function delete_job(){
  555. check_ajax_referer('acaresydney');
  556. $id = $_POST['jobid'];
  557. $result = $this->db->delete($this->table_name, array('id'=> $id));
  558. $response=array(
  559. 'status' => 'success',
  560. 'id' => $id,
  561. 'action'=> 'delete',
  562. 'error' => '',
  563. );
  564. if ($result == 1){
  565. wp_send_json($response);
  566. }else{
  567. $response['status'] = 'error';
  568. $response['error'] = $this->db->last_error;
  569. wp_send_json($response);
  570. }
  571. wp_die();
  572. }
  573. //ajax email staff their job arrangement
  574. function email_job()
  575. {
  576. check_ajax_referer('acaresydney');
  577. $staff = $_POST['staff'];
  578. $start = $_POST['start'];
  579. $finish = $_POST['finish'];
  580. $response=array(
  581. 'status' => 'success',
  582. 'staff' => $staff,
  583. 'start' => $start,
  584. 'finish' => $finish,
  585. 'error' => '',
  586. 'sent' => false,
  587. 'emailstatus'=>"Bypass (no job)",
  588. );
  589. $u = get_user_by('login', $staff);
  590. if ($this->is_staff($u)){
  591. $n = new UserJob($staff);
  592. $resp = $n->list_jobs("$start 00:00:00", "$finish 23:59:59");
  593. if ($resp['status']=='success' && $resp['job_count'] >0 ){
  594. $msg = sprintf("Email to <strong>%s</strong> (with job=%d) \n", $u->user_email, $resp['job_count']);
  595. $this->send_email_with_job_link($u, $start, $finish);
  596. $response['sent'] = true;
  597. $response['emailstatus'] = $msg;
  598. }
  599. }
  600. wp_send_json($response);
  601. }
  602. //ajax browse job with different filters
  603. function list_job(){
  604. check_ajax_referer('acaresydney');
  605. $start = $_POST['start'] . " 00:00:00";
  606. $finish = $_POST['finish']. " 23:59:59";
  607. $response = array(
  608. 'status'=>'success',
  609. 'jobs' => [],
  610. );
  611. $sql = "SELECT * FROM $this->table_name WHERE start>='%s' and start <='%s' order by start ASC ,staff ASC";
  612. $query = $this->db->prepare ($sql, array($start, $finish));
  613. $response['sql'] = $query;
  614. $jobs = $this->db->get_results($query);
  615. if (! empty($jobs)){
  616. $response['status'] = 'success';
  617. foreach( $jobs as $s){
  618. $response['jobs'][] = array(
  619. 'id' => $s->id,
  620. 'tos' => $s->tos,
  621. 'start'=> $s->start,
  622. 'finish'=> $s->finish,
  623. 'rate'=> $s->rate,
  624. 'staff'=> $s->staff,
  625. 'client'=> $s->client,
  626. 'ack' => $s->ack,
  627. 'rating' =>$s->rating,
  628. );
  629. }
  630. }
  631. wp_send_json($response);
  632. wp_die();
  633. }
  634. public function list_job_by_staff()
  635. {
  636. //check_ajax_referer('acaresydney');
  637. $start = $_POST['start'];
  638. $finish = $_POST['finish'];
  639. //$start="2019-07-01 00:00:00";
  640. //$finish="2019-07-14 23:59:59";
  641. $user = wp_get_current_user();// should be staff;
  642. if ( $this->is_staff($user) ){
  643. $n = new UserJob($user->user_login);
  644. $response = $n->list_jobs($start, $finish);
  645. wp_send_json($response);
  646. }else{
  647. $response = array(
  648. 'status' => 'error',
  649. 'errmsg' => 'invalid access',
  650. 'user' => $user,
  651. );
  652. wp_send_json($response);
  653. }
  654. wp_die();
  655. }
  656. private function is_staff($user)
  657. {
  658. return ($user->ID !=0 && in_array('staff', $user->roles));
  659. }
  660. private function is_admin($user)
  661. {
  662. $allowed_roles = array('administrator', 'acare_owner');
  663. if( array_intersect($allowed_roles, $user->roles ) ) {
  664. return true;
  665. }
  666. }
  667. public function staff_ack_job()
  668. {
  669. check_ajax_referer('acaresydney');
  670. $jobs = $_POST['jobs'];
  671. $response = array(
  672. 'status'=>'success',
  673. 'jobs'=>$jobs,
  674. );
  675. $yes=[];
  676. $no=[];
  677. foreach($jobs as $job){
  678. if ( $job['ack'] == "true")
  679. $yes[] =(int) $job['id'];
  680. else
  681. $no[] = (int) $job['id'];
  682. }
  683. $err = $this->ack_multiple_job($yes, $no);
  684. if ($this->db->last_error !='')
  685. {
  686. $response['status']= 'error';
  687. $response['err_msg']= $err;
  688. }
  689. $response['yes'] = $yes;
  690. $response['no'] = $no;
  691. wp_send_json($response);
  692. wp_die();
  693. }
  694. public function ack_multiple_job($yes, $no)
  695. {
  696. $str_yes_ids = implode(",", $yes);
  697. $str_no_ids = implode(",", $no);
  698. $err = "";
  699. if (count($yes) >0 ){
  700. $sql = "UPDATE $this->table_name SET ack=1 WHERE id IN ( $str_yes_ids) ; ";
  701. $r = $this->db->get_results($sql);
  702. $err = $this->db->last_error;
  703. }
  704. if (count($no) >0 ){
  705. $sql = "UPDATE $this->table_name SET ack=0 WHERE id IN ( $str_no_ids) ; ";
  706. $r = $this->db->get_results($sql);
  707. $err .= $this->db->last_error;
  708. }
  709. return $err;
  710. }
  711. }
  712. $bb = new AcareOffice();
  713. if ( defined( 'WP_CLI' ) && WP_CLI ) {
  714. \WP_CLI::add_command( 'sync_users', array($bb, 'sync_user_cli'));
  715. \WP_CLI::add_command( 'email_jobs', array($bb, 'email_jobs'));
  716. }
  717. //$bb->class_loader();
  718. //$bb->list_job_by_staff();