From 9e13da8b7d02049c271b87d902d246e134611899 Mon Sep 17 00:00:00 2001 From: sp Date: Mon, 27 Sep 2021 04:23:07 +1000 Subject: [PATCH] timesheets seems working wow --- XeroOauth2.php | 61 +++++++------ XeroOauth2ShortCode.php | 5 +- XeroOauth2Timesheet.php | 194 ++++++++++++++++++++++++++++++++++++++++ ts.php | 26 +++--- 4 files changed, 239 insertions(+), 47 deletions(-) create mode 100644 XeroOauth2Timesheet.php diff --git a/XeroOauth2.php b/XeroOauth2.php index f5007bd..21be939 100644 --- a/XeroOauth2.php +++ b/XeroOauth2.php @@ -59,18 +59,13 @@ class XeroOAuth2 $this->shortcodes = new XeroOauth2ShortCode($this); $this->storage = new StorageClass(); - add_action('init', array($this, 'init_wp')); - add_action('after_setup_theme', array($this, 'boot_carbon')); - // add_action('init', array('Carbon_Fields\\Carbon_Fields', 'boot')); + add_action('init', array($this, 'init')); + add_action( 'plugins_loaded', array( '\\Carbon_Fields\\Carbon_Fields', 'boot' ) ); add_action('carbon_fields_register_fields', array($this, 'build_settings_page')); add_action('carbon_fields_container_activated', array($this, 'field_activated')); add_action('parse_request', array($this, 'xero_callback')); - - add_action('init', array($this, "xero_init")); - add_action('plugins_loaded', array($this, "load_storage")); - } public function __call($method, $args) { @@ -82,12 +77,15 @@ class XeroOAuth2 } } - public function xero_init() + public function init() { $this->provider = $this->create_provider(); - + $this->init_wp(); } + public function getTenantId() { + return $this->xeroTenantId; + } private function create_provider() { $provider = new \League\OAuth2\Client\Provider\GenericProvider([ 'clientId' => $this->clientID, @@ -303,19 +301,18 @@ class XeroOAuth2 /* sync xero to wp options */ public function init_wp(){ try{ - error_log("init_wp is empty"); $this->sync_pay_item(); // $this->add_new_client(); // $this->add_new_employee(); -// $this->sync_payroll_calendar(); + $this->sync_payroll_calendar(); }catch(\Exception $e){ - + $this->office->log("XeroAuth2\\init_wp() has exception", $e->getMessage()); } } private function sync_pay_item() { if ($this->too_close_to_sync_payitem()){ - //return; + return; } $api = $this->get_payroll_au_instance(); @@ -324,8 +321,6 @@ class XeroOAuth2 try { $result = $api->getPayItems($xeroTenantId, null, null, null, $page); - - foreach ($result->getPayItems()->getEarningsRates() as $e){ // "EarningsRateID": "34e17d08-237a-4ae2-8115-375d1ff8a9ed", // "Name": "Overtime Hours (exempt from super)", @@ -370,7 +365,21 @@ class XeroOAuth2 } public function sync_payroll_calendar() { - + if ($this->too_close_to_sync_payroll_calendar()){ + // return; + } + update_option('bts_pay_roll_calendar_last_sync', time()); + + $pc = $this->get_payroll_calendar(); + $start = $pc->getStartDateAsDate()->format('Y-m-d'); + $finish = new \DateTime($start); + $finish = $finish->modify("+13 days")->format('Y-m-d'); + $paydate = $pc->getPaymentDateAsDate()->format('Y-m-d'); + $calendar["start"] = $start; + $calendar["finish"] = $finish; + $calendar["paydate"] = $paydate; + + update_option('bts_pay_roll_calendar', $calendar); } private function too_close_to_sync_payitem(){ @@ -380,12 +389,6 @@ class XeroOAuth2 return $diff < $this->minimum_sync_interval_in_seconds; //default 10 minutes } - private function sync_payitem(){ - - - } - - private function too_close_to_add_employee(){ $lastsync = get_option('bts_add_employee_last_sync', 0); $now = time(); @@ -406,10 +409,6 @@ class XeroOAuth2 } - - - - public function getClients($contact_group_id = null) { if ( $contact_group_id == null ){ $contact_group_id = $this->clientContactGroupID; @@ -446,13 +445,17 @@ class XeroOAuth2 return $ret; } + /* + * operation get_payroll_calendar + * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response + * @throws \InvalidArgumentException + */ public function get_payroll_calendar() { $id = "33dc7df5-3060-4d76-b4da-57c20685d77d"; //fortnightly $api = $this->get_payroll_au_instance(); - - $pc = $api->getPayrollCalendar($this->xeroTenantId, $id); - return $pc; + $calendars = $api->getPayrollCalendar($this->xeroTenantId, $id); + return $calendars[0]; } } \ No newline at end of file diff --git a/XeroOauth2ShortCode.php b/XeroOauth2ShortCode.php index 18601c9..1e27527 100644 --- a/XeroOauth2ShortCode.php +++ b/XeroOauth2ShortCode.php @@ -251,8 +251,7 @@ class XeroOauth2ShortCode { update_option('bts_pay_roll_calendar_last_sync', time()); try { - $result = $this->oauth2->get_payroll_calendar(); - $pc = $result->getPayrollCalendars()[0]; + $pc = $this->oauth2->get_payroll_calendar(); $start = $pc->getStartDateAsDate()->format('Y-m-d'); $finish = new \DateTime($start); $finish = $finish->modify("+13 days")->format('Y-m-d'); @@ -261,7 +260,7 @@ class XeroOauth2ShortCode $calendar["finish"] = $finish; $calendar["paydate"] = $paydate; - return print_r ($calendar); + return "start = $start, finish=$finish, paydate=$paydate"; }catch (\Exception $e) { echo 'Exception when calling PayrollAuApi->getPayrollCalendar: ', $e->getMessage(), PHP_EOL; } diff --git a/XeroOauth2Timesheet.php b/XeroOauth2Timesheet.php new file mode 100644 index 0000000..c35b379 --- /dev/null +++ b/XeroOauth2Timesheet.php @@ -0,0 +1,194 @@ +oauth2 = $oauth2; + $this->apiPayrollAu = $this->oauth2->get_payroll_au_instance(); + $this->end_date = $end_date; + $this->start_date = $this->cal_start(); //set start_date; + $this->get_remote_timesheets(); + } + + + private function cal_start(){ + $d = new \DateTime($this->end_date); + $d->modify("-13 days"); + return $d->format("Y-m-d"); + } + + public function refresh_remote(){ + $this->get_remote_timesheets(); + } + + private function get_remote_timesheets() + { + $api = $this->oauth2->get_payroll_au_instance(); + $where = 'EndDate==DateTime.Parse("'. $this->end_date .'")'; + $result = $api->getTimeSheets($this->oauth2->getTenantId(), null, $where, null, null); + $this->remote_timesheets =$result->getTimeSheets(); + } + + public function get_xero_timesheet() + { + return $this->remote_timesheets; + } + + public function get_local_timesheet() + { + return $this->local_timesheets; + } + + public function set_local_timesheet($lines) + { + + $this->local_timesheets = []; + //convert $val to Timesheet format; + foreach ($lines as $staff_login => $rateshours){ + $ts = ""; + if (array_key_exists($staff_login, $this->local_timesheets)){ + $ts = $this->local_timesheets[$staff_login]; + }else{ + $ts = new \XeroAPI\XeroPHP\Models\PayrollAu\Timesheet; + $ts->setEmployeeID($staff_login); + $ts->setTimeSheetID($this->get_timesheet_id_by_employee_id($staff_login)); + $ts->setStartDate($this->start_date); + $ts->setEndDate($this->end_date); + $ts->setStatus(\XeroAPI\XeroPHP\Models\PayrollAu\TimesheetStatus::DRAFT); + } + //adding lines + foreach ($rateshours as $rateId => $hours) + { + $ts_line = new \XeroAPI\XeroPHP\Models\PayrollAu\TimesheetLine; + $ts_line->setEarningsRateID($rateId); + $numOfUnits =[]; + for ($i=0; $i<14; $i++){ + $numOfUnits[]=$hours[$i]; + } + $ts_line->setNumberOfUnits($numOfUnits); + $tsLines[] = $ts_line; + $ts->setTimesheetLines($tsLines); + } + //update this timesheet; + $this->local_timesheets[$staff_login] = $ts; + } + } + private function get_timesheet_id_by_employee_id($id) + { + foreach ($this->remote_timesheets as $ts) + { + $staff_login = $ts->getEmployeeID(); + if($staff_login == $id){ + return $ts->getTimesheetID(); + } + } + return NULL; + } + + public function save_to_xero() + { + $to_create=[]; + $to_save=[]; + foreach ( $this->local_timesheets as $t){ + $buddy = $this->get_buddy_timesheet_by_ts($t); + if ($buddy != NULL && $buddy->getStatus() != "DRAFT"){ + continue;//we encountered approved timesheet; + } + if ( trim($t->getTimeSheetId() ) != "" ){ + $to_save[]=$t; + }else{ + $to_save[] = $t; // TODO: maybe update will work for new timesheet + // $to_create[]= $t; + } + } + //empty remote timesheet which are not available in local + // + //some of buddy timesheets might be removed from local already + //we cannot delete it but we can set it to 0 hours + // + foreach ($this->remote_timesheets as $ts) + { + $staff_login = $ts->getEmployeeID(); + if (!array_key_exists($staff_login, $this->local_timesheets)){//not found + //we create empty timesheets for him/her + $empty = new \XeroAPI\XeroPHP\Models\PayrollAu\Timesheet; + $empty->setEmployeeID($staff_login); + $empty->setTimeSheetID($ts->getTimesheetID()); + $empty->setStartDate($this->start_date); + $empty->setEndDate($this->end_date); + $empty->setStatus(\XeroAPI\XeroPHP\Models\PayrollAu\TimesheetStatus::DRAFT); + + foreach($ts->getTimesheetLines() as $line){ + $eid = $line->getEarningsRateID(); + $zeroline= $this->create_empty_timesheet_lines($eid); + $zerolines[] = $zeroline; + $empty->setTimesheetLines($zerolines); + } + + if ( $ts->getStatus() == "DRAFT" ){//good, we can save it; + $to_save[] = $empty;//add it to save + }else{ + $staff_name = \Biukop\AcareOffice::get_user_name_by_login($staff_login); + $msg = sprintf("%s : %s is APPROVED, but needs to be empty it", + $staff_name, + $ts->getTimeSheetID()); + \Biukop\AcareOffice::log($msg); + } + } + } + $this->apiPayrollAu->createTimesheet($this->oauth2->getTenantId(),$to_save); + } + + public function approve_all(){ + $to_save=[]; + foreach ( $this->remote_timesheets as $t){ + if($t->getStatus() == 'DRAFT'){ + $to_save[]=$t; + } + } + $this->apiPayrollAu->createTimesheet($this->oauth2->getTenantId(), false); + } + + private function get_buddy_timesheet_by_ts($t) + { + $employee_id = $t->getEmployeeID(); + $start = $t->getStartDate(); + $end = $t->getEndDate(); + return $this->get_buddy_timesheets($employee_id, $start, $end); + } + + public function get_buddy_timesheets($employee_id, $start, $end) + { + foreach ($this->remote_timesheets as $t){ + if ( $t->getEmployeeID() == $employee_id && + $t->getStartDateAsDate()->format('Y-m-d') == $start->format('Y-m-d') && + $t->getEndDateAsDate()->format('Y-m-d') == $end->format('Y-m-d') ) + { + return $t; + } + } + return NULL; //not found; + } + + private function create_empty_timesheet_lines($EarningsRateID) + { + $unit = []; + for ($i=0; $i<14; $i++) + $unit[] = 0; + + $line = new \XeroAPI\XeroPHP\Models\PayrollAu\TimesheetLine; + $line->setEarningsRateID($EarningsRateID); + $line->setNumberOfUnits($unit); + return $line; + } +} \ No newline at end of file diff --git a/ts.php b/ts.php index 33d5fb7..b3d53b8 100644 --- a/ts.php +++ b/ts.php @@ -22,7 +22,7 @@ class AcareOffice{ //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 $xero ; private $db; private $table_name; //default to job_table private $job_table; @@ -131,9 +131,7 @@ class AcareOffice{ $loader->addNamespace('\XeroPHP', dirname(__FILE__) . '/xero-php-master/src/XeroPHP'); $loader->addNamespace('\Biukop', dirname(__FILE__) . '/' ); - //$this->xero = new XeroOauth2($this); - //$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"); } @@ -178,10 +176,7 @@ class AcareOffice{ exit(); } - public function init_xero_with_wp() { - $this->xero->init_wp(); - } - + private function get_ndis_price() {//help to ensure ndis_price is only build once per call if ( ! $this->ndis_price instanceof NdisPrice ) @@ -647,7 +642,8 @@ class AcareOffice{ 'employeeonly' => false, 'clientsonly' => false, ) ); - $this->xero->sync_users($arguments['mininterval'], $arguments['employeeonly'], $arguments['clientsonly']); + //TODO: SYNC USER + //$this->xero->sync_users($arguments['mininterval'], $arguments['employeeonly'], $arguments['clientsonly']); return; } @@ -1317,12 +1313,12 @@ ZOT; $sync = true; //set up payroll calendar - $pc = $this->xero->get_payroll_calendar(); + $pc = $this->XeroOauth2->get_payroll_calendar(); - $start = $pc->getStartDate()->format('Y-m-d'); + $start = $pc->getStartDateAsDate()->format('Y-m-d'); $finish = new \DateTime($start); $finish = $finish->modify("+13 days")->format('Y-m-d'); - $paydate = $pc->getPaymentDate()->format('Y-m-d'); + $paydate = $pc->getPaymentDateAsDate()->format('Y-m-d'); //prepare response $response = array( @@ -1333,7 +1329,7 @@ ZOT; 'paydate'=> $paydate, ), ); - $xx = new \Biukop\TimeSheet($this->xero->get_xero_handle(), $finish); + $xx = new \Biukop\XeroOauth2Timesheet($this->XeroOauth2, $finish); $local_ts = $this->create_timesheet_from_db($start, $finish); if ($sync){ @@ -1421,7 +1417,7 @@ ZOT; { check_ajax_referer('acaresydney'); //set up payroll calendar - $pc = $this->xero->get_payroll_calendar(); + $pc = $this->XeroOauth2->get_payroll_calendar(); $start = $pc->getStartDate()->format('Y-m-d'); $finish = new \DateTime($start); @@ -1437,7 +1433,7 @@ ZOT; 'paydate'=> $paydate, ), ); - $xx = new \Biukop\TimeSheet($this->xero->get_xero_handle(), $finish); + $xx = new \Biukop\TimeSheet($this->XeroOauth2, $finish); $xx->approve_all(); wp_send_json($response); }