|
- <?php
- /**
- * Plugin Name: Acare Advanced Office
- * Plugin URI: http://biukop.com.au/acaresydney/timesheets
- * Description: Advanced Office system, timesheet, Payroll for AcareSydney
- * Version: 2.1
- * Author: Biukop Intelligence
- * Author URI: http://biukop.com.au/
- */
-
- namespace Biukop;
- use XeroPHP\Models\Accounting\Address;
- use XeroPHP\Models\Accounting\Payment;
-
- require_once(dirname(__FILE__) . '/autoload.php');
- require_once (ABSPATH . 'wp-includes/pluggable.php');
-
-
- class AcareOffice{
- private $acare_ndis_registration = "4050024758";
- private $nonce; //for ajax verification
- private $pages = array('time-sheets', 'user-list');
- 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; //default to job_table
- private $job_table;
- private $allowance_table;
- private $addr_table;
- private $ndis_table;
- private $apiv1;
- private $ndis_price;
-
- public function __construct() {
- $this->setup_db_name();
- $this->class_loader();
- $this->apiv1 = new Apiv1($this, $this->job_table);
- //$this->check_csv_download();
-
- add_option( "acare_ts_db_version", "1.0" );
- register_activation_hook( __FILE__, array($this, 'db_install') );
-
- //add_action('init', array($this, 'class_loader'));
- add_action('init', array($this, 'check_csv_download'));
-
- add_action('wp', array($this, 'check_auth'));
- add_action('wp_enqueue_scripts', array($this, 'register_js_css'), 99);
-
- add_filter('show_admin_bar', '__return_false');
-
- //ts-xx for sync single user
- add_shortcode( 'ts-sync-users', array($this, 'sync_users'));
- //bts-xx for webpage
- add_shortcode( 'bts_staff_item', array($this, 'bts_staff_item'));
- add_shortcode( 'bts_client_item', array($this, 'bts_client_item'));
- add_shortcode( 'bts_job_item', array($this, 'bts_job_item'));
- add_shortcode( 'bts_rate_options', array($this, 'bts_rate_options'));
- 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'));
- add_shortcode( 'bts_staff_job_summary', array($this, 'bts_staff_job_summary'));
- add_shortcode( 'bts_feedback_card', array($this, 'bts_feedback_card'));
- add_shortcode( 'bb_timesheet_canvas', array($this, 'bb_timesheet_canvas'));
- add_shortcode( 'bts_staff_hours_template', array($this, 'bts_staff_hours_template'));
- add_shortcode( 'bts_client_invoice_template', array($this, 'bts_client_invoice_template'));
- add_shortcode( 'bts_csv_template', array($this, 'bts_csv_template'));
- add_shortcode( 'bts_invoiced_client', array($this, 'bts_invoiced_client'));
- //user profile page
- add_shortcode( 'bts_user_name', array($this,'bts_user_name'));
-
-
- add_action('wp_ajax_list_staff', array($this,'list_staff' ));
- add_action('wp_ajax_list_client', array($this,'list_client' ));
- add_action('wp_ajax_list_tos', array($this,'list_tos' ));
-
- 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_email_feedback_url', array($this,'email_feedback_url' ));
-
-
- 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' ));
-
- add_action('wp_ajax_list_job_by_staff', array($this,'list_job_by_staff' ));
- add_action('wp_ajax_nopriv_list_job_by_staff', array($this,'list_job_by_staff' ));
-
- add_action('wp_ajax_staff_ack_job', array($this,'staff_ack_job' ));
- add_action('wp_ajax_nopriv_staff_ack_job', array($this,'staff_ack_job' ));
-
- add_action('wp_ajax_list_job_by_client', array($this,'list_job_by_client' ));
- add_action('wp_ajax_nopriv_list_job_by_client', array($this,'list_job_by_client' ));
-
- add_action('wp_ajax_client_ack_job', array($this,'client_ack_job' ));
- add_action('wp_ajax_nopriv_client_ack_job', array($this,'client_ack_job' ));
-
- add_action('wp_ajax_get_timesheet_from_xero', array($this,'get_timesheet_from_xero' ));
- add_action('wp_ajax_approve_all_timesheet', array($this,'approve_all_timesheet' ));
- add_action('wp_ajax_get_invoice_item', array($this,'get_invoice_item' ));
- add_action('wp_ajax_create_invoice_in_xero', array($this,'create_invoice_in_xero' ));
-
-
- // 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'));
-
-
-
- }
-
- private function setup_db_name()
- {
- global $wpdb;
- $this->db = $wpdb;
- $this->table_name = $wpdb->prefix . 'acare_ts'; //for backward compatability;
- $this->job_table = $wpdb->prefix . 'acare_ts';
- $this->allowance_table = $wpdb->prefix . 'acare_allowance';
- $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");
- }
-
- public function check_csv_download()
- {
- $method = $_SERVER['REQUEST_METHOD'];
- if ( $method != "POST")
- return;
-
- global $wpdb;
- $url = $_SERVER['REQUEST_URI'];
- if ($url != "/ndiscsv/"){
- return;
- }
- $clients= $_POST['clients'];
- $start = $_POST['start'];;
- $finish = $_POST['finish'];;
- $filename="{$start}___{$finish}.csv";
-
- header("Expires: 0");
- header("Cache-Control: no-cache, no-store, must-revalidate");
- header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);
- header("Pragma: no-cache");
- header("Content-type: text/csv");
- header("Content-Disposition:attachment; filename=$filename");
- header("Content-Type: application/force-download");
-
-
- //readfile(dirname(__FILE__) . "/img/circle.png");
- $clients_in = "'" . implode("','", $clients) . "'";
- $sql = "SELECT * from $this->table_name WHERE client in ($clients_in) and start >='$start 00:00:00' and start<='$finish 23:59:59'";
- $results = $wpdb->get_results($sql);
-
- $csv_header = "RegistrationNumber,NDISNumber,SupportsDeliveredFrom,SupportsDeliveredTo,SupportNumber,ClaimReference,Quantity,Hours,UnitPrice,GSTCode,AuthorisedBy,ParticipantApproved,InKindFundingProgram,ClaimType,CancellationReason\n";
- echo $csv_header;
- foreach($results as $r)
- {
- echo $this->ndis_csv_line($r);
- }
- //echo $sql;
- exit();
- }
-
- private function get_ndis_price()
- {//help to ensure ndis_price is only build once per call
- if ( ! $this->ndis_price instanceof NdisPrice )
- $this->ndis_price = new NdisPrice();
- return $this->ndis_price;
- }
-
- private function ndis_csv_line($record)
- {
- $str = "";
- $price = $price = $this->get_ndis_price();
- $registration = $this->acare_ndis_registration;
- $ndisnumber = $this->get_client_ndis_account($record->client);
- $date = new \DateTime($record->start);
- $start = $date->format("Y-m-d");
- $date = new \Datetime($record->finish);
- $finish = $date->format("Y-m-d");
- $quantity = $this->get_job_hours($record->start, $record->finish);
- $hours = $quantity;
- $unitprice = $this->get_ndis_price()->get_tos_price($record->tos);
- $authorizedby="helen";
- $participant_approved = "";
- $GST = $this->get_client_GST($record->client);
- $in_kind_program = $this->get_client_in_kind_program($record->client);
- $ClaimType = "";// standard;
- $CancellationReason="";
- return "$registration,$ndisnumber,$start,$finish,$record->tos,REC_{$record->id},$quantity,$hours,$unitprice,$GST,$authorizedby,$participant_approved,$in_kind_program,$ClaimType,$CancellationReason\n";
- }
-
- private function get_client_ndis_account($client)
- {
- $user = get_user_by('login', $client);
- return get_user_meta($user->ID,'account',true);
- }
-
- private function get_client_in_kind_program($client)
- {
- $user = get_user_by('login', $client);
- return get_user_meta($user->ID,'in_kind_prog',true);
- }
- private function get_client_GST($client)
- {
- $user = get_user_by('login', $client);
- $str = get_user_meta($user->ID,'gst',true);
- if ($str == "")
- return "P2";
- return $str;
- }
-
- //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]',
-
- 'feedback_card/week-([^/]+)/?$' => 'index.php?pagename=feedback_card&bts_week_id=$matches[1]',
- 'feedback_card/start-([^/]+)/finish-([^/]+)/?$' => 'index.php?pagename=feedback_card&bts_job_start=$matches[1]&bts_job_finish=$matches[2]',
- 'feedback_card/([^/]+)/?$' => 'index.php?pagename=feedback_card&bts_user_id=$matches[1]',
- 'feedback_card/([^/]+)/week-([^/]+)/?$' => 'index.php?pagename=feedback_card&bts_user_id=$matches[1]&bts_week_id=$matches[2]',
- 'feedback_card/([^/]+)/start-([^/]+)/finish-([^/]+)/?$' => 'index.php?pagename=feedback_card&bts_user_id=$matches[1]&bts_job_start=$matches[2]&bts_job_finish=$matches[3]',
-
- 'ndiscsv/start-([^/]+)/finish-([^/]+)/?$' => 'index.php?pagename=ndiscsv&bts_job_start=$matches[1]&bts_job_finish=$matches[2]',
-
- );
- $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();
- break;
- case 'feedback_card':
- $this->cauth_feedback_card();
- break;
- }
- }
-
- 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 cauth_feedback_card(){
- $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_feedback_card();
-
- if ($login != "")//perform autologin, and redirect
- {
- $client = get_user_by('login', $login);
- if ($this->is_client($client)){//is valid client;
- $current = wp_get_current_user();
- if($current->ID != $client->ID){
- wp_logout();
- wp_set_current_user($client->ID, $client->display_name); //this is a must
- wp_set_auth_cookie($client->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_client($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 get_redirect_url_for_feedback_card()
- {
- if ($this->bts_week_id != "")
- return "/feedback_card/week-" . $this->bts_week_id . "/";
- if ($this->bts_job_start!="" && $this->bts_job_finish !="")
- return "/feedback_card/start-" . $this->bts_job_start . "/finish-" .$this->bts_job_finish . "/";
- return '/feedback_card/';
- }
-
-
- 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_office_js_css();
- $this->register_task_js_css();
- $this->register_feedback_card_js_css();
- $this->register_xeroc_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__),
- 'driving' => "259ee8e8-a1e5-42e4-9c14-517543ecdc4b",
- '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'));
-
- global $wp_scripts;
- wp_enqueue_script('jquery-ui-datepicker');
- // get registered script object for jquery-ui
- //$ui = $wp_scripts->query('jquery-ui-core');
- // tell WordPress to load the Smoothness theme from Google CDN
- //$protocol = is_ssl() ? 'https' : 'http';
- // $url = "$protocol://ajax.googleapis.com/ajax/libs/jqueryui/{$ui->ver}/themes/smoothness/jquery-ui.min.css";
- $url = plugins_url('jquery-ui-1.11.4.theme/jquery-ui.min.css', __FILE__);
- wp_enqueue_style('jquery-ui-smoothness', $url, false, null);
- }
-
- private function register_office_js_css(){
- global $pagename;
- if ($pagename != 'office'){
- return;
- }
- wp_enqueue_style( 'bts_office', plugins_url('css/bts_office.css', __FILE__));
- wp_enqueue_script( 'bts_office', plugins_url('js/bts_office.js', __FILE__), array( 'jquery' , 'bts' ));
- wp_enqueue_script('mustache', plugins_url('js/mustache.min.js', __FILE__), array('jquery'));
-
- global $wp_scripts;
- wp_enqueue_script('jquery-ui-datepicker');
- // get registered script object for jquery-ui
- //$ui = $wp_scripts->query('jquery-ui-core');
- // tell WordPress to load the Smoothness theme from Google CDN
- //$protocol = is_ssl() ? 'https' : 'http';
- // $url = "$protocol://ajax.googleapis.com/ajax/libs/jqueryui/{$ui->ver}/themes/smoothness/jquery-ui.min.css";
- $url = plugins_url('jquery-ui-1.11.4.theme/jquery-ui.min.css', __FILE__);
- wp_enqueue_style('jquery-ui-smoothness', $url, false, null);
- }
-
-
- 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,
- ) );
- }
-
- private function register_feedback_card_js_css()
- {
- global $pagename;
- if ($pagename != 'feedback_card'){
- 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( 'feedback_card', plugins_url('css/feedback_card.css', __FILE__));
- wp_enqueue_script( 'feedback_card', plugins_url('js/feedback_card.js', __FILE__), array( 'jquery' , 'bts' ));
- wp_enqueue_script('mustache', plugins_url('js/mustache.min.js', __FILE__), array('jquery'));
-
- wp_localize_script('feedback_card','feedback_card',array(
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
- 'nonce' => wp_create_nonce('feedback_card'),
- 'week_id' => $this->bts_week_id,
- 'bts_job_start' => $this->bts_job_start,
- 'bts_job_finish' => $this->bts_job_finish,
- ) );
- }
-
- private function register_xeroc_js_css(){
- global $pagename;
- if ($pagename != 'xeroc'){
- return;
- }
- wp_enqueue_style( 'bts_xeroc', plugins_url('css/xeroc.css', __FILE__));
- wp_enqueue_script( 'bts_xeroc', plugins_url('js/xeroc.js', __FILE__), array( 'jquery' , 'bts' ));
- wp_enqueue_script('mustache', plugins_url('js/mustache.min.js', __FILE__), array('jquery'));
- wp_enqueue_script('scrollintoview', plugins_url('js/scrollintoview.js', __FILE__), array('jquery'));
-
- global $wp_scripts;
- wp_enqueue_script('jquery-ui-datepicker');
- $url = plugins_url('jquery-ui-1.11.4.theme/jquery-ui.min.css', __FILE__);
- wp_enqueue_style('jquery-ui-smoothness', $url, false, null);
- }
-
- 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_by_staff("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;
- }
-
- public function produce_invoice($args = array(), $assoc_args = array())
- {
- $users = get_users(array('role' => 'client'));
- foreach ($users as $u)
- {
- $pay = get_user_meta($u->id, 'payment',true);
- echo sprintf("%s: %s\n", $u->display_name, $pay);
- }
- }
-
- 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, timesheet@acaresydney.com.au'];
- $subject = $staff->display_name . " Job arrangement $start ~ $finish";
- //wp_mail("sp@lawipac.com", $subject, $message, $headers);
- //wp_mail("timesheet@acaresydney.com.au", $subject, $message, $headers);
- wp_mail($staff->user_email, $subject, $message, $headers);
- }
-
- private function send_email_feedback_url($client)
- {
- $message = file_get_contents(plugin_dir_path(__FILE__) . "/html/email_feedback_url.html");
- $message = str_ireplace("{{display_name}}", $client->display_name, $message);
- $message = str_ireplace("{{user_login}}", $client->user_login, $message);
- $headers = ['Bcc: helenwang41@hotmail.com, timesheet@acaresydney.com.au'];
- $subject = $client->display_name . " Feedback Link";
- wp_mail( "helen@acaresydney.com.au", $subject, $message, $headers);
- //wp_mail( "patrick@biukop.com.au", $subject, $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 = "<select> \n";
- $options = get_option('bts_payitem_earnings_rate');
- foreach($options as $o){
- if ($o['CurrentRecord'] !='true')
- continue;
- if ($o['RateType'] != 'RATEPERUNIT')
- continue;
- if (stripos($o['TypeOfUnits'],'hour') != false) //unit contains hour Hour
- continue;
- $result.=sprintf("<option value='%s'> $%3.2f-%s</option>",
- $o['EarningsRateID'], $o['RatePerUnit'], $o['Name']);
- }
- $result .="</select>";
- return $result;
- }
-
- private function get_rate_name_by_id($id)
- {
- $options = get_option('bts_payitem_earnings_rate');
- foreach($options as $o){
- if ( $o['EarningsRateID'] == $id )
- return sprintf("$%3.2f-%s", $o['RatePerUnit'], $o['Name']);
- }
- }
-
- public function bts_select_staff($attr){
- $result = "<select> \n";
- $staff = $this->get_people_by_role('staff');
- foreach ($staff as $u){
- $result .= sprintf("<option value=%s> %s</option>", $u->user_login, $u->first_name . " " . $u->last_name);
- }
- $result .="</select>";
- return $result;
- }
-
- public function bts_select_client($attr){
- $result = "<select> \n";
- $staff = $this->get_people_by_role('client');
- foreach ($staff as $u){
- $result .= sprintf("<option value=%s> %s</option>", $u->user_login, $u->display_name);
- }
- $result .="</select>";
- 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 ="<span>
- If there is more than one job, please click on 'confirm' to make sure it is included in your payment.
- </span>";
- return $result;
- }
-
- public function bts_feedback_card($attr)
- {
- return $this->template('bts_feedback_card', 'feedback_card.html');
- }
- public function bb_timesheet_canvas($attr)
- {
- return file_get_contents(plugin_dir_path(__FILE__) . "/html/timesheet.html");
- }
-
- public function bts_staff_hours_template($attr){
- return $this->template('bts_staff_hours_template', 'bts_staff_hours_template.html');
- }
-
- public function bts_client_invoice_template($attr){
- return $this->template('bts_client_invoice_template', 'bts_client_invoice_template.html');
- }
-
- public function bts_csv_template($attr){
- return $this->template('bts_csv_template', 'bts_csv_template.html');
- }
-
- public function bts_invoiced_client($attr)
- {
- $attr = shortcode_atts([
- 'preferred' => 'true',
- ], $attr);
-
- $result = "";
- $users = $users = get_users(array('role' => 'client'));
- $row = <<<ZOT
- <tr id="nameonly_%s" data-client-id='%s' class="invoice_nameonly_row %s">
- <td class="client_nameonly" data-client-id='%s'>
- <i class="vc_tta-icon fa fa-plus-square"></i> %s
- </td>
- </tr>
- <tr id="dummyui_%s" data-client-id='%s' class="invoice_nameonly_row_dummy %s">
- <td class="client_nameonly" data-client-id='%s'>
- <i class="vc_tta-icon fa fa-plus-square"></i> %s is loading .... please wait...
- </td>
- </tr>
- ZOT;
- foreach ($users as $u)
- {
- $payment = get_user_meta($u->ID, 'payment', true);
-
- if ( $attr['preferred'] == 'true' ){
- if( $payment == 'invoice' ){
- $invoice_preferred = "invoice_preferred";
- $result .= sprintf($row,
- $u->user_login, $u->user_login, $invoice_preferred, $u->user_login, $u->display_name,
- $u->user_login, $u->user_login, $invoice_preferred, $u->user_login, $u->display_name);
- }
- }else{
- $invoice_preferred = "";
- if( $payment != 'invoice' ){
- $result .= sprintf($row,
- $u->user_login, $u->user_login, $invoice_preferred, $u->user_login, $u->display_name,
- $u->user_login, $u->user_login, $invoice_preferred, $u->user_login, $u->display_name);
- }
-
- }
- }
- return $result;
- }
-
- //generate template based on html file
- private function template($id, $file)
- {
- $text = '<script id="' . $id .'" type="text/x-biukop-template">';
- $text .= file_get_contents(plugin_dir_path(__FILE__) . "/html/$file");
- $text .= '</script>';
- 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,
- 'display_name' => $s->display_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){
- $data_item = 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),
- 'payment'=>get_user_meta($s->ID, 'payment', true),
- 'rating'=> 0,
- 'unconfirmedjob'=> 0,
- );
- $response['users'][] = $data_item;
- }
- }
- wp_send_json($response);
- wp_die();
- }
-
- //ajax
- function list_tos() {
- check_ajax_referer('acaresydney');
- // Handle the ajax request
- $response = array(
- 'status' =>'success',
- 'tos' => [],
- );
- $price = $this->get_ndis_price();
- $response['tos']= $price->get_tos_array();
- wp_send_json($response);
- }
-
- 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_by_staff("$start 00:00:00", "$finish 23:59:59");
- if ($resp['status']=='success' && $resp['job_count'] >0 ){
- $msg = sprintf("Email to <strong>%s</strong> (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 email feedback url
- function email_feedback_url()
- {
- check_ajax_referer('acaresydney');
- $client = $_POST['client'];
- $response=array(
- 'status' => 'success',
- 'error' => '',
- 'sent' => false,
- 'emailstatus' =>'not sent',
- );
- $u = get_user_by('login', $client);
- if ($this->is_client($u)){
- $status = $this->send_email_feedback_url($u);
- $response['emailstatus'] = $status;
- }
- wp_send_json($response);
-
- }
-
- //ajax browse job with different filters
- function list_job(){
- check_ajax_referer('acaresydney');
- $start = $_POST['start'] . " 00:00:00";
- $finish = $_POST['finish']. " 23:59:59";
-
- $response = array(
- 'status'=>'success',
- 'jobs' => [],
- );
-
- $sql = "SELECT * FROM $this->table_name WHERE start>='%s' and start <='%s' order by start ASC ,staff ASC";
- $query = $this->db->prepare ($sql, array($start, $finish));
- $response['sql'] = $query;
- $jobs = $this->db->get_results($query);
-
- 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) || $this->is_admin($user) ){
- $n = new UserJob($user->user_login);
- $response = $n->list_jobs_by_staff($start, $finish);
- wp_send_json($response);
- }else{
- $response = array(
- 'status' => 'error',
- 'errmsg' => 'invalid access',
- 'user' => $user,
- );
- wp_send_json($response);
- }
- wp_die();
- }
-
- public function list_job_by_client()
- {
- 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_client($user) || $this->is_admin($user) ){
- $n = new UserJob($user->user_login);
- $response = $n->list_jobs_by_client($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_client($user)
- {
- return ($user->ID !=0 && in_array('client', $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;
- }
- public function client_ack_job()
- {
- check_ajax_referer('acaresydney');
- $job_id = $_POST['job_id'];
- $rating = $_POST['rating'];
-
- $response = array(
- 'status'=>'success',
- );
- $sql= "UPDATE $this->table_name SET rating=%d WHERE id = %d ; ";
- $sql= $this->db->prepare($sql, array($rating, $job_id));
-
- $result = $this->db->get_results($sql);
- $response['rating'] = (int) $rating;
- if ($this->db->last_error !='')
- {
- $response['status']= 'error';
- $response['err_msg']= $this->db->last_error;
- $response['rating'] = 0;
- }
- wp_send_json($response);
- }
-
-
- public function get_timesheet_from_xero()
- {
- check_ajax_referer('acaresydney');
-
- //check if we need sync
- $sync = $_POST['sync'];
- if ($sync != "true")
- $sync = false;
- else
- $sync = true;
-
- //set up payroll calendar
- $pc = $this->xero->get_payroll_calendar();
-
- $start = $pc->getStartDate()->format('Y-m-d');
- $finish = new \DateTime($start);
- $finish = $finish->modify("+13 days")->format('Y-m-d');
- $paydate = $pc->getPaymentDate()->format('Y-m-d');
-
- //prepare response
- $response = array(
- 'status' => 'success',
- 'payroll_calendar' => array(
- 'start' => $start,
- 'finish' => $finish,
- 'paydate'=> $paydate,
- ),
- );
- $xx = new \Biukop\TimeSheet($this->xero->get_xero_handle(), $finish);
- $local_ts = $this->create_timesheet_from_db($start, $finish);
-
- if ($sync){
- $xx->set_local_timesheet($local_ts);
- $xx->save_to_xero();
- $xx->refresh_remote();
- }
-
-
- $days=[];
- $d = new \DateTime($start);
- for ($i=1; $i<=14; $i++){
- $days["days_$i"] = $d->format("d/M");
- $d->modify("+1 day");
- }
-
-
- $lines=[];
- foreach ($local_ts as $staff_login => $details)
- {
- $item = array(
- 'staff_name' => $this->get_user_name_by_login ($staff_login),
- 'staff_id' => $staff_login,
- 'Xero_Status' => 'Empty',
- 'rowspan' =>1,
- 'local_total' =>0,
- 'remote_total'=>0,
- 'ratetype' => [],
- );
-
- $buddy = $xx->get_buddy_timesheets($staff_login, new \DateTime($start), new \DateTime($finish));
- if ($buddy != NULL){
- $item['Xero_Status'] = $buddy->getStatus();
- }else{
- $item['Xero_Status'] = "Not Exist";
- }
-
-
- foreach($details as $rate => $hours){
- $item['rowspan'] ++;
-
- $ratetype_item=[];
- $ratetype_item['rate_name'] = $this->get_rate_name_by_id($rate);
- //for local
- for ($i=1; $i<=14; $i++)
- {
- $ratetype_item["local_$i"] = $hours[$i-1];
- $ratetype_item["local_$i"] = number_format($ratetype_item["local_$i"], 2);
- $item['local_total'] += $hours[$i-1];
- }
- $item['local_total'] = number_format($item['local_total'], 2);
- //for remote
- if ( $buddy != NULL )
- {
- $remote_lines = $buddy->getTimesheetLines();
- foreach($remote_lines as $rl)
- {
- if ( $rl->getEarningsRateID() == $rate){
- for ($i=1; $i<=14; $i++)
- {
- $ratetype_item["xero_$i"] = $rl->getNumberOfUnits()[$i-1];
- $item['remote_total'] += $rl->getNumberOfUnits()[$i-1];
- if ($ratetype_item["xero_$i"] != $ratetype_item["local_$i"]){
- $ratetype_item["xero_{$i}_mismatch"] = "mismatch";
- }
- }
- break;//we found it
- }
- }
- }
- $item['ratetype'][] = $ratetype_item;
- }
-
- $item = array_merge($item, $days);
- $lines[]=$item;
- }
-
- $ts = json_decode(file_get_contents(dirname(__FILE__) . "/sample/timesheets.json"));
- $response['ts'] = $ts;
- $response['lines'] = $lines;
- wp_send_json($response);
- }
-
- public function approve_all_timesheet()
- {
- check_ajax_referer('acaresydney');
- //set up payroll calendar
- $pc = $this->xero->get_payroll_calendar();
-
- $start = $pc->getStartDate()->format('Y-m-d');
- $finish = new \DateTime($start);
- $finish = $finish->modify("+13 days")->format('Y-m-d');
- $paydate = $pc->getPaymentDate()->format('Y-m-d');
-
- //prepare response
- $response = array(
- 'status' => 'success',
- 'payroll_calendar' => array(
- 'start' => $start,
- 'finish' => $finish,
- 'paydate'=> $paydate,
- ),
- );
- $xx = new \Biukop\TimeSheet($this->xero->get_xero_handle(), $finish);
- $xx->approve_all();
- wp_send_json($response);
- }
-
- static public function get_user_name_by_login($login)
- {
- $user = get_user_by('login', $login);
- if ($user->ID !=0 )
- return $user->display_name;
- else
- return "Invalid Name";
- }
-
-
- //ajax
- public function get_invoice_item()
- {
- check_ajax_referer('acaresydney');
- $client = $_POST['client'];
- //$client = "8cb3d205-6cdc-4187-ae39-9216923dd86d";
- $start = $_POST['start']; //2019-07-01';
- $finish= $_POST['finish'];//2019-07-31';
-
- $sql = "SELECT * from $this->table_name WHERE tos != '00_000_0000_0_0' and start>='$start 00:00:00' and start<='$finish 23:59:59' and client='$client' ORDER BY start";
- $rows = $this->db->get_results($sql);
-
- $response=[
- 'status' =>'success',
- 'client_login' => $client,
- 'client_name' => $this->get_user_name_by_login($client),
- 'jobs'=>[],
- 'err'=>''
- ];
- $price = $this->get_ndis_price();
- $summary=[];// by ndis code
- foreach($rows as $r){
- $quantity = $this->get_job_hours($r->start, $r->finish);
- $unit = $price->get_tos_unit($r->tos);
- if ($unit != "Hour")
- {
- $quantity = 1;
- }
- $unitprice = $price->get_tos_price($r->tos);
- $description = $this->get_job_description_for_invoice($price, $r);
-
- $data = [
- 'tos' => $price->get_tos_full_str($r->tos),
- 'start' => $r->start,
- 'finish' => $r->finish,
- 'hours' => $quantity,
- 'unitprice'=> $price->get_tos_price($r->tos),
- 'staff_name' => $this->get_user_name_by_login($r->staff),
- 'price' => sprintf("%.2f", $quantity * $unitprice),
- ];
- $response['jobs'][] = $data;
- $summary[$r->tos] += $quantity;
- }
-
- if (count($response['jobs']) ==0)
- {
- $response['nojob'] = true;
- }
-
- foreach ($summary as $key => $val)
- {
- $response['summary'][] = array(
- 'ndis' => $key,
- 'tos' => $price->get_tos_full_str($key),
- 'Hours'=> sprintf("%0.2f", $val),
- );
- }
- if (count($summary) > 0){
- $response['has_summary'] = true;
- }
-
-
- wp_send_json($response);
- }
-
- public function create_invoice_in_xero()
- {
- check_ajax_referer('acaresydney');
- $client = $_POST['client'];
- //$client = "8cb3d205-6cdc-4187-ae39-9216923dd86d";
- $start = $_POST['start']; //2019-07-01';
- $finish= $_POST['finish'];//2019-07-31';
- //
-
- $response=[
- 'status'=>success,
- 'invoice_number' => '',
- 'err'=> '',
- ];
-
- try{
- $invoice = $this->create_invoice_by_client($client, $start, $finish);
- $response['invoice_number'] = sprintf("<a href='https://go.xero.com/AccountsReceivable/Edit.aspx?InvoiceID=%s' target='_blank'>%s</a>",
- $invoice->getInvoiceID(), $invoice->getInvoiceNumber());
- }catch(\Exception $e){
- $response['status'] = 'error';
- $response['err'] = "XERO Invoice Error";
- }
-
- wp_send_json($response);
- }
-
-
- public function create_invoice_by_client($client_login, $start, $finish)
- {
- $user = get_user_by('login', $client_login);
- if ( !$this->is_client($user) )
- return NULL;
- // $payment = get_user_meta($user->ID, "payment", true);
- // if ($payment != "invoice")
- // return NULL;
-
- $sql = "SELECT * from $this->table_name WHERE tos != '00_000_0000_0_0' and start>='$start 00:00:00' and start<='$finish 23:59:59' and client='$client_login' ORDER BY start";
- $rows = $this->db->get_results($sql);
-
- $xero = $this->xero->get_xero_handle();
-
- //crate invoice
- $invoice = new \XeroPHP\Models\Accounting\Invoice($xero);
- $contact= $xero->loadByGUID('Accounting\\Contact', $client_login);
- $now = new \DateTime();
- $due = new \DateTime();
- $due->modify("+14 days");
- $invoice->setType("ACCREC")
- ->setStatus("DRAFT")
- ->setContact($contact)
- ->setDate($now)
- ->setDueDate($due);
- $to_save=[];//all invoices to save;
- $price = new NdisPrice($now->format("Y"));//current year;
-
- foreach($rows as $r){
- $quantity = $this->get_job_hours($r->start, $r->finish);
- $unit = $price->get_tos_unit($r->tos);
- if ($unit != "Hour")
- {
- $quantity = 1;
- }
- $unitprice = $price->get_tos_price($r->tos);
- $description = $this->get_job_description_for_invoice($price, $r);
- $lineItem = new \XeroPHP\Models\Accounting\Invoice\LineItem($xero);
- $lineItem->setDescription($description)
- ->setQuantity($quantity)
- ->setUnitAmount($unitprice)
- ->setAccountCode(220)
- ->setTaxType("EXEMPTOUTPUT");
- $invoice->addLineItem($lineItem);
- }
-
- //prevent zero lineitems
- if ( count($invoice->getLineItems()) >0 )
- $invoice->save();
- return $invoice;
- }
-
- public function get_job_description_for_invoice($price, $job)
- {
- $description = sprintf(
- '%s
- [NDIS code: %s]
- Time: %s - %s
- By Carer : %s',
- $price->get_tos_str($job->tos),
- $job->tos,
- $job->start,
- $job->finish,
- $this->get_user_name_by_login($job->staff)
- );
- return $description;
- }
-
- public function create_timesheet_from_db($start, $finish){
- $results = [];
-
- $sql = "SELECT * from $this->table_name WHERE start>='$start 00:00:00' and start<='$finish 23:59:59'";
- $rows = $this->db->get_results($sql);
- foreach ($rows as $r){
- if (!array_key_exists($r->staff, $results)){
- $results[$r->staff] = [];
- }
- if (!array_key_exists($r->rate, $results[$r->staff])){
- $results[$r->staff][$r->rate] = [];
- for ($i=0; $i<14; $i++){
- $results[$r->staff][$r->rate][$i] = 0; //14 days init to 0;
- }
- }
-
- $idx = $this->convert_date_to_idx($r->start, $start, $finish);
- if ($idx >=0 && $idx <=13){
- $hours = $this->get_job_hours($r->start, $r->finish);
- $results[$r->staff][$r->rate][$idx] += $hours;
- //$results[$r->staff][$r->id] = $hours;
- //$results[$r->staff][$r->id . '_index'] = $idx;
- }else{
- $msg = sprintf("ACARE_TS_ERR: found invalid job index for job id=%d, on %s, idx is %d, start=%s, finish=%s\n",
- $r->id, date('Y-m-d'), $idx, $start, $finish);
- $this->log($msg);
- }
- }
- //wp_send_json($results);
- return $results;
- }
- //convert date (no time) to index, 0 day is $start, 13day is finish, -1 is not found
- public function convert_date_to_idx($date, $start, $finish)
- {//start, finish format must be yyyy-mm-dd
- $idx = -1;
- $cur = new \DateTime($date);
- $cur->setTime(0,0,0);//clear time;
- $s = new \DateTime($start);
- $s->setTime(0,0,0);
- $f = new \DateTime($finish);
- $f->setTime(0,0,0);
- if ( $s <= $cur && $cur <=$f ){
- $datediff = date_diff($s,$cur);
- $idx = $datediff->days;
- }
- return $idx;
- }
-
- private function get_job_hours($start, $finish)
- {
- $hours = 0;
- $s = strtotime($start);
- $f = strtotime($finish);
- $diff = $f- $s;
- $hours = ($diff * 1.0 / 3600); //can be float;
- return sprintf('%0.2f', $hours);
- }
-
- public function feedback_url()
- {
- $users = get_users(array('role'=>'client'));
- foreach($users as $u){
- echo sprintf("Hi %s:\n\nPlease rate our service, https://acaresydney.com.au/feedback_card/%s/\n\nAcareSydney\n\n", $u->display_name, $u->user_login);
- }
- }
-
- static public function log($msg){
- openlog("ACARE_TS", LOG_PID | LOG_PERROR, LOG_SYSLOG);
- //something wrong, we dont touch it, but give some error here
- syslog(LOG_WARNING, $msg);
- closelog();
- }
- }
-
- $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'));
- \WP_CLI::add_command( 'feedback_url', array($bb, 'feedback_url'));
- \WP_CLI::add_command( 'produce_invoice', array($bb, 'produce_invoice'));
- }
-
- //$bb->class_loader();
- //$bb->create_invoice_by_client("8cb3d205-6cdc-4187-ae39-9216923dd86d", "2019-07-01", "2019-07-31");
- //$idx = $bb->convert_date_to_idx("2019-07-02 14:30:00", "2019-07-01", "2019-07-02");
- //wp_send_json($idx);
- //$bb->create_timesheet_from_db("2019-07-01", "2019-07-14");
|