?>
</span><br/>
		<span class="history_date"><?php 
echo date_i18n(get_option('date_format') . ' @ ' . get_option('time_format'), strtotime($post->post_date));
?>
</span>
	</dt>
	<dd><p>
		&nbsp;
	</p></dd>

	<?php 
foreach ($historical_records as $record_id) {
    ?>
		<?php 
    $record = SI_Record::get_instance($record_id);
    // If no type is set than just keep on moving.
    if ($record->get_type() == SI_Record::DEFAULT_TYPE) {
        continue;
    }
    $r_post = $record->get_post();
    switch ($record->get_type()) {
        case SI_Controller::PRIVATE_NOTES_TYPE:
            $type = si__('Private Note');
            break;
        case SI_Notifications::RECORD:
            $type = si__('Notification');
            break;
        case SI_Projects::HISTORY_STATUS_UPDATE:
        default:
            $type = si__('Status Update');
 public static function get_zap_target_url($zap_id = 0)
 {
     $zap = SI_Record::get_instance($zap_id);
     if (!is_a($zap, 'SI_Record')) {
         return;
     }
     return $zap->get_excerpt();
 }
 /**
  * Remove single time to associated array
  * @param int $time_id 
  */
 public function remove_time_associated($time_id = 0)
 {
     // Delete time record
     $time = SI_Record::get_instance($time_id);
     if (is_a($time, 'SI_Record')) {
         $activity_id = $time->get_associate_id();
         $activity = SI_Time::get_instance($activity_id);
         $activity->delete_time($time_id);
     }
     // Remove from associated array
     $times = $this->get_associated_times();
     if (($key = array_search($time_id, $times)) !== false) {
         unset($times[$key]);
     }
     $this->set_associated_times($times);
 }
 public static function projects_time()
 {
     $nonce = $_REQUEST['nonce'];
     if (!wp_verify_nonce($nonce, self::SUBMISSION_NONCE)) {
         self::ajax_fail('Not going to fall for it!');
     }
     if (isset($_REQUEST['project_id'])) {
         $project_id = $_REQUEST['project_id'];
     }
     if (!$project_id) {
         self::ajax_fail('No project id');
     }
     $project = SI_Project::get_instance($project_id);
     if (!is_a($project, 'SI_Project')) {
         self::ajax_fail('Project not found');
     }
     $times = $project->get_associated_times();
     $time_data = array();
     if (!empty($times)) {
         foreach ($times as $time_id) {
             $time = SI_Record::get_instance($time_id);
             if (!is_a($time, 'SI_Record')) {
                 continue;
             }
             $activity = SI_Time::get_instance($time->get_associate_id());
             $data = $time->get_data();
             // If time is unbillable don't import
             // This includes not returning time that has already been invoiced.
             if (isset($_REQUEST['billable'])) {
                 if (is_a($activity, 'SI_Time') && !$activity->is_billable()) {
                     continue;
                 }
                 // Don't return the time that has already been invoiced
                 if (isset($data['invoice_id'])) {
                     continue;
                 }
             }
             $description = is_a($activity, 'SI_Time') ? '<b>' . get_the_title($activity->get_id()) . "</b>\n" . $time->get_title() . "\n<small>" . date_i18n(get_option('date_format'), $data['date']) . '</small>' : $time->get_title() . "\n<small>" . date_i18n(get_option('date_format'), $data['date']) . '</small>';
             $description = apply_filters('the_content', $description);
             $time_data[] = array('id' => $time_id, 'date' => date_i18n(get_option('date_format'), $data['date']), 'note' => apply_filters('the_content', $time->get_title()), 'qty' => si_get_number_format((double) $data['time_val']), 'description' => apply_filters('si_project_time_imported_description', $description), 'activity_id' => is_a($activity, 'SI_Time') ? $activity->get_id() : false, 'activity' => is_a($activity, 'SI_Time') ? $activity->get_title() : '', 'activity_rate' => is_a($activity, 'SI_Time') ? $activity->get_default_rate() : 0, 'activity_tax' => is_a($activity, 'SI_Time') ? $activity->get_default_percentage() : 0);
         }
     }
     if (empty($time_data)) {
         self::ajax_fail('Nothing to import');
     }
     header('Content-type: application/json');
     if (self::DEBUG) {
         header('Access-Control-Allow-Origin: *');
     }
     echo wp_json_encode($time_data);
     exit;
 }
function si_doc_history_records($doc_id = 0, $filtered = true)
{
    if (!$doc_id) {
        $doc_id = get_the_ID();
    }
    $returned_history = array();
    switch (get_post_type($doc_id)) {
        case SI_Estimate::POST_TYPE:
            $estimate = SI_Estimate::get_instance($doc_id);
            $history = $estimate->get_history();
            break;
        case SI_Invoice::POST_TYPE:
            $invoice = SI_Invoice::get_instance($doc_id);
            $history = array_merge($invoice->get_history(), $invoice->get_payments());
            break;
        default:
            # code...
            break;
    }
    $history = apply_filters('si_doc_history_records_pre_sort', $history, $doc_id, $filtered);
    // Sort in ascending order
    asort($history, SORT_NUMERIC);
    foreach ($history as $item_id) {
        if (get_post_type($item_id) == SI_Record::POST_TYPE) {
            $record = SI_Record::get_instance($item_id);
            // If no type is set than just keep on moving.
            if ($record->get_type() == SI_Record::DEFAULT_TYPE) {
                continue;
            }
            // filter these types of records out.
            if ($filtered) {
                if (in_array($record->get_type(), array(SI_Controller::PRIVATE_NOTES_TYPE, SI_Estimates::VIEWED_STATUS_UPDATE, SI_Notifications::RECORD))) {
                    continue;
                }
            }
            $r_post = $record->get_post();
            switch ($record->get_type()) {
                case SI_Controller::PRIVATE_NOTES_TYPE:
                    $returned_history[$item_id]['type'] = __('Private Note', 'sprout-invoices');
                    break;
                case SI_Estimates::HISTORY_UPDATE:
                    $returned_history[$item_id]['type'] = __('Updated', 'sprout-invoices');
                    break;
                case SI_Estimates::VIEWED_STATUS_UPDATE:
                    $returned_history[$item_id]['type'] = __('Viewed', 'sprout-invoices');
                    break;
                case SI_Notifications::RECORD:
                    $returned_history[$item_id]['type'] = __('Notification', 'sprout-invoices');
                    break;
                case SI_Estimates::HISTORY_INVOICE_CREATED:
                    $returned_history[$item_id]['type'] = __('Invoice Created', 'sprout-invoices');
                    break;
                case SI_Estimate_Submissions::SUBMISSION_UPDATE:
                    $returned_history[$item_id]['type'] = __('Submitted', 'sprout-invoices');
                    break;
                case SI_Importer::RECORD:
                    $returned_history[$item_id]['type'] = __('Imported', 'sprout-invoices');
                    break;
                case SI_Estimates::HISTORY_STATUS_UPDATE:
                default:
                    $returned_history[$item_id]['type'] = __('Status Update', 'sprout-invoices');
                    break;
            }
            $returned_history[$item_id]['status_type'] = $record->get_type();
            $returned_history[$item_id]['post_date'] = $r_post->post_date;
            $returned_history[$item_id]['update_title'] = $r_post->post_title;
            $returned_history[$item_id]['content'] = $r_post->post_content;
        } elseif (get_post_type($item_id) == SI_Payment::POST_TYPE) {
            $payment = SI_Payment::get_instance($item_id);
            $p_post = $payment->get_post();
            $returned_history[$item_id]['type'] = __('Payment', 'sprout-invoices');
            $returned_history[$item_id]['status_type'] = 'payment';
            $returned_history[$item_id]['post_date'] = $p_post->post_date;
            $returned_history[$item_id]['update_title'] = $p_post->post_title;
            $returned_history[$item_id]['content'] = '';
            $returned_history[$item_id]['content'] .= '<span>' . $payment->get_payment_method() . '</span><br/>';
            $returned_history[$item_id]['content'] .= '<b>' . __('Payment Total', 'sprout-invoices') . ':</b> ' . sa_get_formatted_money($payment->get_amount(), $item_id);
        } else {
            if ($filtered) {
                $comment = get_comment($item_id);
                if (!is_wp_error($comment)) {
                    $returned_history[$item_id]['type'] = $comment->comment_author;
                    $returned_history[$item_id]['status_type'] = 'comment';
                    $returned_history[$item_id]['post_date'] = $comment->comment_date;
                    $returned_history[$item_id]['content'] = get_comment_text($comment->comment_ID);
                    $returned_history[$item_id]['comment_id'] = intval($comment->comment_ID);
                }
            }
        }
    }
    return $returned_history;
}
    function column_data($item)
    {
        $record = SI_Record::get_instance($item->ID);
        $data = $record->get_data();
        if ($data != '') {
            ?>
				<a href="#TB_inline?width=900&height=600&inlineId=data_id_<?php 
            echo esc_attr($item->ID);
            ?>
" class="thickbox button" title="<?php 
            echo esc_attr($item->post_title);
            ?>
 <?php 
            _e('Data', 'sprout-invoices');
            ?>
"><?php 
            _e('View Data', 'sprout-invoices');
            ?>
</a>
				<?php 
            if (is_array($data)) {
                ?>
					<div id="data_id_<?php 
                echo esc_attr($item->ID);
                ?>
" style="display:none;"><pre style="white-space:pre-wrap; text-align: left; font: normal normal 11px/1.4 menlo, monaco, monospaced; padding: 5px;"><?php 
                print_r($data);
                ?>
</pre></div>
				<?php 
            } else {
                ?>
					<div id="data_id_<?php 
                echo esc_attr($item->ID);
                ?>
" style="display:none;"><?php 
                echo apply_filters('the_content', $data);
                ?>
</div>
				<?php 
            }
            ?>
			<?php 
        }
    }
 public static function maybe_update_private_note()
 {
     if (!isset($_REQUEST['nonce'])) {
         wp_die('Forget something?');
     }
     $nonce = $_REQUEST['nonce'];
     if (!wp_verify_nonce($nonce, SI_Controller::NONCE)) {
         wp_die('Not going to fall for it!');
     }
     if (!isset($_REQUEST['record_id'])) {
         self::ajax_fail('No id given!');
     }
     $record_id = $_REQUEST['record_id'];
     $private_note = $_REQUEST['private_note'];
     $record = SI_Record::get_instance($record_id);
     $record->set_data($private_note, false);
     exit;
 }
 public static function download_toggl_time($project_id = 0)
 {
     $toggl_id = self::get_projects_toggl_id($project_id);
     if (!$toggl_id) {
         return;
     }
     $entries = Toggl_API::get_workspace_time($toggl_id);
     if (!isset($entries->data)) {
         return;
     }
     $project = SI_Project::get_instance($project_id);
     if (!is_a($project, 'SI_Project')) {
         return;
     }
     // Don't import times already imported, duh.
     $time_records = $project->get_associated_times();
     $already_imported = array();
     foreach ($time_records as $time_id) {
         $time = SI_Record::get_instance($time_id);
         if (!is_a($time, 'SI_Record')) {
             continue;
         }
         $data = $time->get_data();
         if (isset($data['toggl_id'])) {
             $already_imported[] = $data['toggl_id'];
         }
     }
     $entries = apply_filters('si_toggl_import_entries', $entries->data);
     foreach ($entries as $key => $time_entry) {
         if (in_array($time_entry->id, $already_imported)) {
             continue;
             // already imported
         }
         $data = array('project_id' => (int) $project_id, 'activity_id' => (int) self::get_projects_default_time_import_activity($project_id), 'time_val' => $time_entry->dur / 3600000, 'note' => $time_entry->description, 'date' => strtotime($time_entry->start), 'toggl_id' => $time_entry->id);
         $project->create_associated_time($data);
     }
 }
 public static function add_invoice_id($time_id = 0, $invoice_id = 0)
 {
     $record = SI_Record::get_instance($time_id);
     if (!is_a($record, 'SI_Record')) {
         return 0;
     }
     $data = $record->get_data();
     $data['invoice_id'] = $invoice_id;
     $record->set_data($data);
     return $record;
 }