| $this->shortcodes = new XeroOauth2ShortCode($this); | $this->shortcodes = new XeroOauth2ShortCode($this); | ||||
| $this->storage = new StorageClass(); | $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( 'plugins_loaded', array( '\\Carbon_Fields\\Carbon_Fields', 'boot' ) ); | ||||
| add_action('carbon_fields_register_fields', array($this, 'build_settings_page')); | add_action('carbon_fields_register_fields', array($this, 'build_settings_page')); | ||||
| add_action('carbon_fields_container_activated', array($this, 'field_activated')); | add_action('carbon_fields_container_activated', array($this, 'field_activated')); | ||||
| add_action('parse_request', array($this, 'xero_callback')); | 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) { | public function __call($method, $args) { | ||||
| } | } | ||||
| } | } | ||||
| public function xero_init() | |||||
| public function init() | |||||
| { | { | ||||
| $this->provider = $this->create_provider(); | $this->provider = $this->create_provider(); | ||||
| $this->init_wp(); | |||||
| } | } | ||||
| public function getTenantId() { | |||||
| return $this->xeroTenantId; | |||||
| } | |||||
| private function create_provider() { | private function create_provider() { | ||||
| $provider = new \League\OAuth2\Client\Provider\GenericProvider([ | $provider = new \League\OAuth2\Client\Provider\GenericProvider([ | ||||
| 'clientId' => $this->clientID, | 'clientId' => $this->clientID, | ||||
| /* sync xero to wp options */ | /* sync xero to wp options */ | ||||
| public function init_wp(){ | public function init_wp(){ | ||||
| try{ | try{ | ||||
| error_log("init_wp is empty"); | |||||
| $this->sync_pay_item(); | $this->sync_pay_item(); | ||||
| // $this->add_new_client(); | // $this->add_new_client(); | ||||
| // $this->add_new_employee(); | // $this->add_new_employee(); | ||||
| // $this->sync_payroll_calendar(); | |||||
| $this->sync_payroll_calendar(); | |||||
| }catch(\Exception $e){ | }catch(\Exception $e){ | ||||
| $this->office->log("XeroAuth2\\init_wp() has exception", $e->getMessage()); | |||||
| } | } | ||||
| } | } | ||||
| private function sync_pay_item() { | private function sync_pay_item() { | ||||
| if ($this->too_close_to_sync_payitem()){ | if ($this->too_close_to_sync_payitem()){ | ||||
| //return; | |||||
| return; | |||||
| } | } | ||||
| $api = $this->get_payroll_au_instance(); | $api = $this->get_payroll_au_instance(); | ||||
| try { | try { | ||||
| $result = $api->getPayItems($xeroTenantId, null, null, null, $page); | $result = $api->getPayItems($xeroTenantId, null, null, null, $page); | ||||
| foreach ($result->getPayItems()->getEarningsRates() as $e){ | foreach ($result->getPayItems()->getEarningsRates() as $e){ | ||||
| // "EarningsRateID": "34e17d08-237a-4ae2-8115-375d1ff8a9ed", | // "EarningsRateID": "34e17d08-237a-4ae2-8115-375d1ff8a9ed", | ||||
| // "Name": "Overtime Hours (exempt from super)", | // "Name": "Overtime Hours (exempt from super)", | ||||
| } | } | ||||
| public function sync_payroll_calendar() { | 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(){ | private function too_close_to_sync_payitem(){ | ||||
| return $diff < $this->minimum_sync_interval_in_seconds; //default 10 minutes | return $diff < $this->minimum_sync_interval_in_seconds; //default 10 minutes | ||||
| } | } | ||||
| private function sync_payitem(){ | |||||
| } | |||||
| private function too_close_to_add_employee(){ | private function too_close_to_add_employee(){ | ||||
| $lastsync = get_option('bts_add_employee_last_sync', 0); | $lastsync = get_option('bts_add_employee_last_sync', 0); | ||||
| $now = time(); | $now = time(); | ||||
| } | } | ||||
| public function getClients($contact_group_id = null) { | public function getClients($contact_group_id = null) { | ||||
| if ( $contact_group_id == null ){ | if ( $contact_group_id == null ){ | ||||
| $contact_group_id = $this->clientContactGroupID; | $contact_group_id = $this->clientContactGroupID; | ||||
| return $ret; | return $ret; | ||||
| } | } | ||||
| /* | |||||
| * operation get_payroll_calendar | |||||
| * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response | |||||
| * @throws \InvalidArgumentException | |||||
| */ | |||||
| public function get_payroll_calendar() | public function get_payroll_calendar() | ||||
| { | { | ||||
| $id = "33dc7df5-3060-4d76-b4da-57c20685d77d"; //fortnightly | $id = "33dc7df5-3060-4d76-b4da-57c20685d77d"; //fortnightly | ||||
| $api = $this->get_payroll_au_instance(); | $api = $this->get_payroll_au_instance(); | ||||
| $pc = $api->getPayrollCalendar($this->xeroTenantId, $id); | |||||
| return $pc; | |||||
| $calendars = $api->getPayrollCalendar($this->xeroTenantId, $id); | |||||
| return $calendars[0]; | |||||
| } | } | ||||
| } | } |
| { | { | ||||
| update_option('bts_pay_roll_calendar_last_sync', time()); | update_option('bts_pay_roll_calendar_last_sync', time()); | ||||
| try { | try { | ||||
| $result = $this->oauth2->get_payroll_calendar(); | |||||
| $pc = $result->getPayrollCalendars()[0]; | |||||
| $pc = $this->oauth2->get_payroll_calendar(); | |||||
| $start = $pc->getStartDateAsDate()->format('Y-m-d'); | $start = $pc->getStartDateAsDate()->format('Y-m-d'); | ||||
| $finish = new \DateTime($start); | $finish = new \DateTime($start); | ||||
| $finish = $finish->modify("+13 days")->format('Y-m-d'); | $finish = $finish->modify("+13 days")->format('Y-m-d'); | ||||
| $calendar["finish"] = $finish; | $calendar["finish"] = $finish; | ||||
| $calendar["paydate"] = $paydate; | $calendar["paydate"] = $paydate; | ||||
| return print_r ($calendar); | |||||
| return "start = $start, finish=$finish, paydate=$paydate"; | |||||
| }catch (\Exception $e) { | }catch (\Exception $e) { | ||||
| echo 'Exception when calling PayrollAuApi->getPayrollCalendar: ', $e->getMessage(), PHP_EOL; | echo 'Exception when calling PayrollAuApi->getPayrollCalendar: ', $e->getMessage(), PHP_EOL; | ||||
| } | } |
| <?php | |||||
| namespace Biukop; | |||||
| class XeroOauth2Timesheet | |||||
| { | |||||
| private $oauth2 ; | |||||
| private $apiPayrollAu ; | |||||
| private $start_date; | |||||
| private $end_date; | |||||
| private $remote_timesheets; | |||||
| private $local_timesheets =[]; | |||||
| private $buddy_timesheets =[]; | |||||
| private $warning_timesheets =[]; | |||||
| public function __construct($oauth2, $end_date){ | |||||
| $this->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; | |||||
| } | |||||
| } |
| //private $pages = array('time-sheets', 'user-list'); | //private $pages = array('time-sheets', 'user-list'); | ||||
| private $bts_user_id = 0; | private $bts_user_id = 0; | ||||
| private $bts_week_id = 1; //week 1, we will try to calculate current week; | private $bts_week_id = 1; //week 1, we will try to calculate current week; | ||||
| private $xero ; | |||||
| // private $xero ; | |||||
| private $db; | private $db; | ||||
| private $table_name; //default to job_table | private $table_name; //default to job_table | ||||
| private $job_table; | private $job_table; | ||||
| $loader->addNamespace('\XeroPHP', dirname(__FILE__) . '/xero-php-master/src/XeroPHP'); | $loader->addNamespace('\XeroPHP', dirname(__FILE__) . '/xero-php-master/src/XeroPHP'); | ||||
| $loader->addNamespace('\Biukop', dirname(__FILE__) . '/' ); | $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("01515b52-6936-46b2-a000-9ad4cd7a5b50", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c"); | ||||
| //$abc = new AddrMap("122eb1d0-d8c4-4fc3-8bf8-b7825bee1a01", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c"); | //$abc = new AddrMap("122eb1d0-d8c4-4fc3-8bf8-b7825bee1a01", "0768db6d-e5f4-4b45-89a2-29f7e8d2953c"); | ||||
| } | } | ||||
| exit(); | exit(); | ||||
| } | } | ||||
| public function init_xero_with_wp() { | |||||
| $this->xero->init_wp(); | |||||
| } | |||||
| private function get_ndis_price() | private function get_ndis_price() | ||||
| {//help to ensure ndis_price is only build once per call | {//help to ensure ndis_price is only build once per call | ||||
| if ( ! $this->ndis_price instanceof NdisPrice ) | if ( ! $this->ndis_price instanceof NdisPrice ) | ||||
| 'employeeonly' => false, | 'employeeonly' => false, | ||||
| 'clientsonly' => 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; | return; | ||||
| } | } | ||||
| $sync = true; | $sync = true; | ||||
| //set up payroll calendar | //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 = new \DateTime($start); | ||||
| $finish = $finish->modify("+13 days")->format('Y-m-d'); | $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 | //prepare response | ||||
| $response = array( | $response = array( | ||||
| 'paydate'=> $paydate, | '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); | $local_ts = $this->create_timesheet_from_db($start, $finish); | ||||
| if ($sync){ | if ($sync){ | ||||
| { | { | ||||
| check_ajax_referer('acaresydney'); | check_ajax_referer('acaresydney'); | ||||
| //set up payroll calendar | //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->getStartDate()->format('Y-m-d'); | ||||
| $finish = new \DateTime($start); | $finish = new \DateTime($start); | ||||
| 'paydate'=> $paydate, | 'paydate'=> $paydate, | ||||
| ), | ), | ||||
| ); | ); | ||||
| $xx = new \Biukop\TimeSheet($this->xero->get_xero_handle(), $finish); | |||||
| $xx = new \Biukop\TimeSheet($this->XeroOauth2, $finish); | |||||
| $xx->approve_all(); | $xx->approve_all(); | ||||
| wp_send_json($response); | wp_send_json($response); | ||||
| } | } |