Example #1
0
 /**
  * update an entry
  *
  * <code>
  * $entry = new DayEntry();
  * $entry->set("id" 11111);
  * $entry->set("notes", "Test Support");
  * $entry->set("hours", 3);
  * $entry->set("project_id", 3);
  * $entry->set("task_id", 14);
  * $entry->set("spent_at", "Tue, 17 Oct 2006");
  *
  * $api = new HarvestApi();
  *
  * $result = $api->updateEntry($entry);
  * if ($result->isSuccess()) {
  *     // success logic
  * }
  * </code>
  *
  * @param DayEntry $entry Day Entry
  * @return Result
  */
 public function updateEntry(DayEntry $entry)
 {
     $url = "daily/update/{$entry->id}";
     return $this->performPost($url, $entry->toXML());
 }
Example #2
0
 /**
  * update an entry
  *
  * <code>
  * $entry = new DayEntry();
  * $entry->set("id" 11111);
  * $entry->set("notes", "Test Support");
  * $entry->set("hours", 3);
  * $entry->set("project_id", 3);
  * $entry->set("task_id", 14);
  * $entry->set("spent_at", "Tue, 17 Oct 2006");
  *
  * $api = new HarvestApi();
  *
  * $result = $api->try($entry);
  * if ($result->isSuccess()) {
  *     // success logic
  * }
  * </code>
  *
  * @param DayEntry $entry
  * @param bool $other_user
  * @return Result
  *
  * @see http://www.getharvest.com/api/time-tracking#other-users
  */
 public function updateEntry(DayEntry $entry, $other_user = true)
 {
     $url = "daily/update/{$entry->id}";
     if ($other_user) {
         $url .= "?of_user="******"user-id");
     }
     return $this->performPost($url, $entry->toXML());
 }
Example #3
0
 /**
  * Sync a single harvest time entry.
  *
  * @param \Harvest\Model\DayEntry $harvest_entry
  *
  * @return bool
  */
 protected function syncEntry(DayEntry $harvest_entry)
 {
     // Check spelling.
     $words = explode(' ', preg_replace('/[^a-z]+/i', ' ', $harvest_entry->get('notes')));
     $spelling_errors = array();
     foreach ($words as $word) {
         if (!pspell_check($this->pspellLink, $word)) {
             $spelling_errors[] = $word;
         }
     }
     if ($spelling_errors) {
         $this->userTimeEntryErrors[$harvest_entry->get('user-id')]['spelling'][] = ['entry' => $harvest_entry, 'spelling-errors' => $spelling_errors];
     }
     $redmine_issue = $this->getRedmineIssue($harvest_entry);
     if (!$redmine_issue) {
         return false;
     }
     $existing_redmine_time_entries = $this->getExistingRedmineIssueTimeEntries($redmine_issue, $harvest_entry);
     // If there are existing Redmine time entries matching this harvest entry and we are not updating, skip.
     if (count($existing_redmine_time_entries) > 0 && !$this->input->getOption('update')) {
         return false;
     }
     // Or if there is more than one matching redmine time entry, throw an error and continue.
     if (count($existing_redmine_time_entries) > 1) {
         $this->output->writeln(sprintf('<error>Multiple Redmine time entries matching harvest time entry %d. See entries %s</error>', $harvest_entry->get('id'), json_encode($existing_redmine_time_entries)));
         $this->errors = true;
         return false;
     }
     // If Harvest user is not mapped to a redmine user, throw an error and continue.
     if (!isset($this->userMap[$harvest_entry->get('user-id')])) {
         $this->output->writeln(sprintf('<error>No mapping is defined for user %d</error>', $harvest_entry->get('user-id')));
         $this->errors = true;
         return false;
     }
     // Log the entry.
     $redmine_entry_params = $this->populateRedmineTimeEntry($redmine_issue, $harvest_entry);
     // Check rounding.
     if ($redmine_entry_params['hours'] != $harvest_entry->get('hours')) {
         $this->userTimeEntryErrors[$harvest_entry->get('user-id')]['rounding'][] = ['entry' => $harvest_entry, 'rounded-hours' => $redmine_entry_params['hours']];
     }
     $save_entry_result = false;
     $this->setRedmineClient();
     if (!$this->input->getOption('dry-run')) {
         try {
             $this->redmineClient->setImpersonateUser($this->userMap[$harvest_entry->get('user-id')]);
             $save_entry_result = $this->saveHarvestTimeEntryToRedmine($redmine_entry_params, $existing_redmine_time_entries);
         } catch (\Exception $e) {
             $this->output->writeln(sprintf('<error>Failed to create time entry for redmine issue #%d, harvest id %d, exception %s</error>', $redmine_issue['issue']['id'], $harvest_entry->get('id'), $e->getMessage()));
         } finally {
             $this->redmineClient->setImpersonateUser(null);
         }
     }
     if ($save_entry_result || $this->input->getOption('dry-run')) {
         $this->output->writeln(sprintf('<comment>%s time entry for issue #%d with %s hours (Harvest hours: %s)</comment>', count($existing_redmine_time_entries) > 0 ? 'Updated' : 'Created', $redmine_issue['issue']['id'], $redmine_entry_params['hours'], $harvest_entry->get('hours')));
     }
     return $save_entry_result;
 }