function build_test_invoice($total = 0)
 {
     $user_args = array('user_login' => '*****@*****.**', 'display_name' => 'Unit Tester', 'user_pass' => wp_generate_password(), 'user_email' => '*****@*****.**');
     $user_id = SI_Clients::create_user($user_args);
     $args = array('company_name' => 'Test Client', 'user_id' => $user_id);
     $client_id = SI_Client::new_client($args);
     $args = array('subject' => 'TESTING Payments');
     $id = SI_Invoice::create_invoice($args, SI_Invoice::STATUS_TEMP);
     $this->invoice_ids[] = $id;
     $invoice = SI_Invoice::get_instance($id);
     $invoice->set_client_id($client_id);
     // No total set make them random
     if (!$total) {
         $line_items = array();
         for ($i = 0; $i < 10; $i++) {
             $rate = rand(1000, 4000);
             $qty = rand(1, 10);
             $line_items[] = array('rate' => $rate, 'qty' => $qty, 'desc' => 'This is a test line item for a test invoice.', 'type' => '', 'total' => $rate * $qty, 'tax' => 0);
         }
     } else {
         $line_items = array(array('rate' => $total, 'qty' => 1, 'desc' => 'This is a test line item for a test invoice.', 'type' => '', 'total' => $total, 'tax' => 0));
     }
     $invoice->set_line_items($line_items);
     $this->assertTrue(in_array($id, $this->invoice_ids));
     return $id;
 }
 public static function user_creation_notification($user_id, $args = array())
 {
     $client_ids = SI_Client::get_clients_by_user($user_id);
     $client = !empty($client_ids) ? SI_Client::get_instance($client_ids[0]) : 0;
     $to = self::get_user_email($user_id);
     $data = array('user_id' => $user_id, 'client' => $client, 'user_args' => $args, 'to' => $to);
     self::send_notification('user_notification', $data, $to);
 }
Esempio n. 3
0
 /**
  * Create a project select list that are grouped by client.
  * @param  integer $selected_id
  * @return string
  */
 function si_projects_select($selected_id = 0, $client_id = 0, $blank = true, $el_id = 'doc_project')
 {
     $selections = array();
     if ($client_id) {
         $client = SI_Client::get_instance($client_id);
         if (is_a($client, 'SI_Client')) {
             $projects = SI_Project::get_projects_by_client($client_id);
             $selections[$client->get_title()] = $projects;
         }
     }
     if (empty($selections)) {
         $args = array('post_type' => SI_Project::POST_TYPE, 'post_status' => 'any', 'posts_per_page' => -1, 'fields' => 'ids');
         $projects = get_posts($args);
         foreach ($projects as $project_id) {
             $project = SI_Project::get_instance($project_id);
             $clients = $project->get_associated_clients();
             foreach ($clients as $client_id) {
                 $client = SI_Client::get_instance($client_id);
                 if (is_a($client, 'SI_Client')) {
                     if (!isset($selections[$client->get_title()])) {
                         $selections[$client->get_title()] = array();
                     }
                     $selections[$client->get_title()][] = $project_id;
                 } else {
                     // no client assigned
                     $selections[si__('Client N/A')][] = $project_id;
                 }
             }
         }
     }
     if (!empty($selections)) {
         $out = '<select name="' . $el_id . '" class="select2">';
         if ($blank) {
             $out .= sprintf('<option value="0">%s</option>', si__('Select Project'));
         }
         foreach ($selections as $client => $projects) {
             $out .= sprintf('<optgroup label="%s">', $client);
             foreach ($projects as $project_id) {
                 $out .= sprintf('<option value="%s" %s>%s</option>', $project_id, selected($project_id, $selected_id, false), get_the_title($project_id));
             }
             $out .= '</optgroup>';
         }
         $out .= '</select>';
     } else {
         $out = '<span>' . sprintf(si__('No <a href="%s" target="_blank">projects</a> found'), admin_url('post-new.php?post_type=' . SI_Project::POST_TYPE)) . '</span>';
     }
     echo $out;
 }
Esempio n. 4
0
 /**
  * Return the user object for the person responsible paying at the time of purchase.
  * @param  SI_Invoice $invoice
  * @return object/false
  */
 function si_default_client_user($client_id = 0)
 {
     if (!$client_id) {
         $client_id = get_the_id();
     }
     $user = false;
     $client = SI_Client::get_instance($client_id);
     if (!is_wp_error($client)) {
         $client_users = $client->get_associated_users();
         $client_user_id = array_shift($client_users);
         if ($client_user_id) {
             $user = get_userdata($client_user_id);
         }
     }
     return apply_filters('si_default_client_user', $user, $invoice);
 }
 /**
  * Query sa_client posts with assigned user ID
  *
  * @param 	(int) $user_id 	wp_user ID
  * @return 	(array) 		sa_client post ID's
  **/
 public static function get_client_si_projects($user_id = 0)
 {
     $project_ids = array();
     if (!$user_id) {
         $user_id = get_current_user_id();
     }
     if (!$user_id) {
         return $project_ids;
     }
     $client_ids = SI_Client::get_clients_by_user($user_id);
     if (empty($client_ids)) {
         return $project_ids;
     }
     foreach ($client_ids as $client_id) {
         $project_ids[] = SI_Project::get_projects_by_client($client_id);
     }
     return $project_ids;
 }
 function setUp()
 {
     parent::setUp();
     $user_args = array('user_login' => '*****@*****.**', 'display_name' => 'Unit Tester', 'user_pass' => wp_generate_password(), 'user_email' => '*****@*****.**');
     $user_id = SI_Clients::create_user($user_args);
     $args = array('company_name' => 'Test Client', 'user_id' => $user_id);
     $client_id = SI_Client::new_client($args);
     $args = array('subject' => 'TEST Payment');
     $this->invoice_id = SI_Invoice::create_invoice($args, SI_Invoice::STATUS_TEMP);
     $this->invoice = SI_Invoice::get_instance($this->invoice_id);
     $this->invoice->set_client_id($client_id);
     $line_items = array();
     for ($i = 0; $i < 10; $i++) {
         $rate = rand(100, 1000);
         $qty = rand(1, 10);
         $line_items[] = array('rate' => $rate, 'qty' => $qty, 'desc' => 'This is a test line item for a test invoice.', 'type' => '', 'total' => $rate * $qty, 'tax' => 0);
     }
     $this->invoice->set_line_items($line_items);
 }
 /**
  * Checks to see if the user is accessing a post they have access to as part of an sa_client
  * @param  boolean $result Current pass/fail of access
  * @param  integer $psp_id The project id of the current viewed psp project
  * @return boolean         Access or not.
  */
 public static function check_access_on_post($result = false, $psp_id = 0)
 {
     $current_user_id = get_current_user_id();
     $user_associated_clients = SI_Client::get_clients_by_user($current_user_id);
     // If the result is true, then nothing will override it below
     // Plus if there are not associated clients than tough luck.
     if ($result || empty($user_associated_clients)) {
         return $result;
     }
     $si_project_id = get_field(self::META_KEY, $psp_id);
     // what si_project is assigned to this project access
     if (!$si_project_id || '' === $si_project_id) {
         return false;
     }
     $si_project = SI_Project::get_instance($si_project_id);
     $project_associated_clients = $si_project->get_associated_clients();
     $matches = array_intersect($project_associated_clients, $user_associated_clients);
     // If there are no matches
     if (empty($matches)) {
         return false;
     }
     // there were matches
     return true;
 }
 /**
  * Prep data.
  *
  * @uses $this->_column_headers
  * @uses $this->items
  * @uses $this->get_columns()
  * @uses $this->get_sortable_columns()
  * @uses $this->get_pagenum()
  * @uses $this->set_pagination_args()
  * */
 function prepare_items()
 {
     /**
      * First, lets decide how many records per page to show
      */
     $per_page = 25;
     /**
      * Define our column headers.
      */
     $columns = $this->get_columns();
     $hidden = array();
     $sortable = $this->get_sortable_columns();
     /**
      * REQUIRED. Build an array to be used by the class for column
      * headers.
      */
     $this->_column_headers = array($columns, $hidden, $sortable);
     $filter = isset($_REQUEST['post_status']) ? $_REQUEST['post_status'] : array(SI_Payment::STATUS_PENDING, SI_Payment::STATUS_AUTHORIZED, SI_Payment::STATUS_COMPLETE, SI_Payment::STATUS_PARTIAL, SI_Payment::STATUS_RECURRING, SI_Payment::STATUS_CANCELLED);
     $args = array('post_type' => SI_Payment::POST_TYPE, 'post_status' => $filter, 'posts_per_page' => $per_page, 'paged' => $this->get_pagenum());
     // Check based on post_type id
     if (isset($_REQUEST['s']) && is_numeric($_REQUEST['s'])) {
         $post_id = $_REQUEST['s'];
         switch (get_post_type($post_id)) {
             case SI_Payment::POST_TYPE:
                 $payment_ids = array($post_id);
                 break;
             case SI_Invoice::POST_TYPE:
                 $invoice = SI_Invoice::get_instance($post_id);
                 $payment_ids = $invoice->get_payments();
                 break;
             case SI_Client::POST_TYPE:
                 $client = SI_Client::get_instance($post_id);
                 $payment_ids = $client->get_payments();
                 break;
             default:
                 $payment_ids = false;
                 break;
         }
         if ($payment_ids) {
             $meta_query = array('post__in' => $payment_ids);
             $args = array_merge($args, $meta_query);
         }
     } elseif (isset($_GET['s']) && $_GET['s'] != '') {
         $args = array_merge($args, array('s' => sanitize_text_field($_GET['s'])));
     }
     // Filter by date
     if (isset($_GET['m']) && $_GET['m'] != '') {
         $args = array_merge($args, array('m' => sanitize_text_field($_GET['m'])));
     }
     $payments = new WP_Query($args);
     /**
      * REQUIRED. *Sorted* data to the items property, where
      * it can be used by the rest of the class.
      */
     $this->items = apply_filters('si_mngt_payments_items', $payments->posts);
     /**
      * REQUIRED. Register our pagination options & calculations.
      */
     $this->set_pagination_args(array('total_items' => $payments->found_posts, 'per_page' => $per_page, 'total_pages' => $payments->max_num_pages));
 }
Esempio n. 9
0
 /**
  * Meta box view
  * Abstracted to be called via AJAX
  * @param int $client_id
  *
  */
 public static function submit_meta_box_view($client_id = 0)
 {
     if (!current_user_can('edit_sprout_invoices')) {
         self::ajax_fail('User cannot create new posts!');
     }
     if (!$client_id && isset($_REQUEST['client_id'])) {
         $client_id = $_REQUEST['client_id'];
     }
     $client = SI_Client::get_instance($client_id);
     if (!is_a($client, 'SI_Client')) {
         self::ajax_fail('Client not found.');
     }
     global $post;
     $post = $client->get_post();
     print self::show_submit_meta_box($client->get_post(), array());
     exit;
 }
Esempio n. 10
0
 public static function form_fields($project = 0, $required = false)
 {
     $fields = array();
     $associated_client = $project ? $project->get_associated_clients() : array(0);
     $client_id = array_pop($associated_client);
     $fields['name'] = array('weight' => 1, 'label' => self::__('Project Name'), 'type' => 'text', 'required' => true, 'default' => $project ? $project->get_title() : '');
     $client_options = array();
     $client_options[0] = '';
     $client_options += SI_Client::get_all_clients();
     $description = $client_id ? sprintf(self::__('Edit <a href="%s">%s</a>, select another client or <a href="%s">create a new client</a>.'), get_edit_post_link($client_id), get_the_title($client_id), '#TB_inline?width=600&height=450&inlineId=client_creation_modal" id="client_creation_modal_link" class="thickbox') : sprintf(self::__('Select an existing client or <a href="%s">create a new client</a>.'), '#TB_inline?width=600&height=420&inlineId=client_creation_modal" id="client_creation_modal_link" class="thickbox');
     $fields['client'] = array('weight' => 3, 'label' => self::__('Client'), 'type' => 'select', 'options' => $client_options, 'required' => true, 'default' => $client_id, 'attributes' => array('class' => 'select2'), 'description' => $description);
     $fields['start_date'] = array('weight' => 100, 'label' => self::__('Start Date'), 'type' => 'date', 'required' => $required, 'default' => $project && $project->get_start_date() ? date('Y-m-d', $project->get_start_date()) : '', 'placeholder' => '');
     $fields['end_date'] = array('weight' => 100, 'label' => self::__('End Date'), 'type' => 'date', 'required' => $required, 'default' => $project && $project->get_end_date() ? date('Y-m-d', $project->get_end_date()) : '', 'placeholder' => '');
     $fields['website'] = array('weight' => 120, 'label' => self::__('Website'), 'type' => 'text', 'required' => $required, 'default' => $project ? $project->get_website() : '', 'placeholder' => 'http://');
     $fields['nonce'] = array('type' => 'hidden', 'value' => wp_create_nonce(self::SUBMISSION_NONCE), 'weight' => 10000);
     $fields = apply_filters('si_project_form_fields', $fields);
     uasort($fields, array(__CLASS__, 'sort_by_weight'));
     return $fields;
 }
 public static function client_data(SI_Client $client)
 {
     $emails = array();
     $associated_users = $client->get_associated_users();
     if (!empty($associated_users)) {
         foreach ($associated_users as $user_id) {
             $user = get_userdata($user_id);
             if ($user) {
                 $emails[] = $user->user_email;
             }
         }
     }
     $client_data = array('company_name' => $client->get_title(), 'address' => $client->get_address(), 'user_ids' => $associated_users, 'user_emails' => $emails, 'phone' => $client->get_phone(), 'website' => $client->get_website(), 'estimate_ids' => $client->get_invoices(), 'invoice_ids' => $client->get_estimates(), 'payment_ids' => $client->get_payments());
     return $client_data;
 }
Esempio n. 12
0
// Add a progress bar to show table record collection.
echo '<tr class="odd" id="progress_row"><td valign="top" colspan="8" class="dataTables_empty"><div id="rows_progress" style="width:100%;border:1px solid #ccc;"></div> <div id="table_progress">' . __('Preparing rows...', 'sprout-invoices') . '</div></td></tr>';
$records = new WP_Query($args);
$i = 0;
while ($records->have_posts()) {
    $records->the_post();
    // Calculate the percentage
    $i++;
    $percent = intval($i / $records->found_posts * 100) . "%";
    // Javascript for updating the progress bar and information
    echo '<script language="javascript" id="progress_js">
						document.getElementById("rows_progress").innerHTML="<div style=\\"width:' . $percent . ';background-color:#ddd;\\">&nbsp;</div>";
						document.getElementById("table_progress").innerHTML="' . sprintf(__('%o records(s) of %o added.', 'sprout-invoices'), $i, $records->found_posts) . '";
						document.getElementById("progress_js").remove();
						</script>';
    $client = SI_Client::get_instance(get_the_ID());
    $estimates = $client->get_estimates();
    $invoices = $client->get_invoices();
    $number_estimate = count($estimates);
    $number_invoices = count($invoices);
    $number_estimate_complete = 0;
    if (!empty($estimates)) {
        foreach ($estimates as $estimate_id) {
            if (get_post_status($estimate_id) == SI_Estimate::STATUS_APPROVED) {
                $number_estimate_complete += 1;
            }
        }
    }
    $number_invoices_complete = 0;
    $total_invoiced = 0;
    $total_payments = 0;
Esempio n. 13
0
 /**
  * Client
  */
 public function get_client()
 {
     if (!$this->get_client_id()) {
         return new WP_Error('no_client', __('No client associated with this invoice.', 'sprout-invoices'));
     }
     return SI_Client::get_instance($this->get_client_id());
 }
 public static function client($data = array())
 {
     if (!isset($data['id'])) {
         $data['id'] = $_GET['id'];
     }
     $client = SI_Client::get_instance($data['id']);
     if (!is_a($client, 'SI_Client')) {
         return;
     }
     return self::client_data($client);
 }
Esempio n. 15
0
/**
 * Load the SI application
 * (function called at the bottom of this page)
 *
 * @package Sprout_Invoices
 * @return void
 */
function sprout_invoices_load()
{
    if (class_exists('Sprout_Invoices')) {
        error_log('** Sprout_Invoices Already Loaded **');
        return;
        // already loaded, or a name collision
    }
    do_action('sprout_invoices_preload');
    //////////
    // Load //
    //////////
    // Master class
    require_once SI_PATH . '/Sprout_Invoices.class.php';
    // base classes
    require_once SI_PATH . '/models/_Model.php';
    require_once SI_PATH . '/controllers/_Controller.php';
    do_action('si_require_base_classes');
    // models
    require_once SI_PATH . '/models/Client.php';
    require_once SI_PATH . '/models/Estimate.php';
    require_once SI_PATH . '/models/Invoice.php';
    require_once SI_PATH . '/models/Notification.php';
    require_once SI_PATH . '/models/Payment.php';
    require_once SI_PATH . '/models/Record.php';
    // Premium models
    require_once SI_PATH . '/models/Project.php';
    // i18n
    require_once SI_PATH . '/controllers/i18n/Countries_States.php';
    require_once SI_PATH . '/controllers/i18n/Locales.php';
    do_action('si_require_model_classes');
    /////////////////
    // Controllers //
    /////////////////
    // settings
    require_once SI_PATH . '/controllers/admin/Settings.php';
    if (!class_exists('SA_Settings_API')) {
        require_once SI_PATH . '/controllers/admin/Settings_API.php';
    }
    require_once SI_PATH . '/controllers/admin/Capabilities.php';
    require_once SI_PATH . '/controllers/admin/Help.php';
    // json api
    require_once SI_PATH . '/controllers/api/JSON_API.php';
    // checkouts
    require_once SI_PATH . '/controllers/checkout/Checkouts.php';
    // clients
    require_once SI_PATH . '/controllers/clients/Clients.php';
    // developer logs
    require_once SI_PATH . '/controllers/developer/Logs.php';
    // Estimates
    require_once SI_PATH . '/controllers/estimates/Estimate_Submission.php';
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/estimates/Estimate_Submission_Premium.php')) {
        require_once SI_PATH . '/controllers/estimates/Estimate_Submission_Premium.php';
    }
    require_once SI_PATH . '/controllers/estimates/Estimates.php';
    require_once SI_PATH . '/controllers/estimates/Estimates_Admin.php';
    require_once SI_PATH . '/controllers/estimates/Estimates_Edit.php';
    require_once SI_PATH . '/controllers/estimates/Estimates_Records.php';
    require_once SI_PATH . '/controllers/estimates/Estimates_Template.php';
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/estimates/Estimates_Premium.php')) {
        require_once SI_PATH . '/controllers/estimates/Estimates_Premium.php';
    }
    // invoices
    require_once SI_PATH . '/controllers/invoices/Invoices.php';
    require_once SI_PATH . '/controllers/invoices/Invoices_Admin.php';
    require_once SI_PATH . '/controllers/invoices/Invoices_Edit.php';
    require_once SI_PATH . '/controllers/invoices/Invoices_Records.php';
    require_once SI_PATH . '/controllers/invoices/Invoices_Template.php';
    require_once SI_PATH . '/controllers/invoices/Invoices_Deposit.php';
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/invoices/Invoices_Premium.php')) {
        require_once SI_PATH . '/controllers/invoices/Invoices_Premium.php';
    }
    // Line Items
    require_once SI_PATH . '/controllers/line-items/Line_Items.php';
    // notifications
    require_once SI_PATH . '/controllers/notifications/Notifications_Control.php';
    require_once SI_PATH . '/controllers/notifications/Notifications.php';
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/notifications/Notifications_Premium.php')) {
        require_once SI_PATH . '/controllers/notifications/Notifications_Premium.php';
    }
    require_once SI_PATH . '/controllers/notifications/Notifications_Admin_Table.php';
    // payment processing
    require_once SI_PATH . '/controllers/payment-processing/Payment_Processors.php';
    require_once SI_PATH . '/controllers/payment-processing/Credit_Card_Processors.php';
    require_once SI_PATH . '/controllers/payment-processing/Offsite_Processors.php';
    // payment processors
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/payment-processing/processors/SI_Paypal_EC.php')) {
        require_once SI_PATH . '/controllers/payment-processing/processors/SI_Paypal_EC.php';
    }
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/payment-processing/processors/SI_Paypal_Pro.php')) {
        require_once SI_PATH . '/controllers/payment-processing/processors/SI_Paypal_Pro.php';
    }
    require_once SI_PATH . '/controllers/payment-processing/processors/SI_Checks.php';
    require_once SI_PATH . '/controllers/payment-processing/processors/SI_Admin_Payment.php';
    do_action('si_payment_processors_loaded');
    // payments
    require_once SI_PATH . '/controllers/payments/Payments.php';
    require_once SI_PATH . '/controllers/payments/Payments_Admin_Table.php';
    // Projects
    require_once SI_PATH . '/controllers/projects/Projects.php';
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/projects/Projects_Premium.php')) {
        require_once SI_PATH . '/controllers/projects/Projects_Premium.php';
    }
    // internal records
    require_once SI_PATH . '/controllers/records/Internal_Records.php';
    require_once SI_PATH . '/controllers/records/Records_Admin_Table.php';
    // reporting
    require_once SI_PATH . '/controllers/reporting/Dashboard.php';
    require_once SI_PATH . '/controllers/reporting/Reporting.php';
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/reporting/Reporting_Premium.php')) {
        require_once SI_PATH . '/controllers/reporting/Reporting_Premium.php';
    }
    require_once SI_PATH . '/controllers/templating/Templating.php';
    require_once SI_PATH . '/controllers/templating/Customizer.php';
    // updates
    if (!SI_FREE_TEST && file_exists(SI_PATH . '/controllers/updates/Updates.php')) {
        require_once SI_PATH . '/controllers/updates/Updates.php';
    }
    if (file_exists(SI_PATH . '/controllers/updates/Free_License.php')) {
        require_once SI_PATH . '/controllers/updates/Free_License.php';
    }
    // importers
    require_once SI_PATH . '/importers/Importer.php';
    require_once SI_PATH . '/importers/Freshbooks.php';
    require_once SI_PATH . '/importers/Harvest.php';
    require_once SI_PATH . '/importers/WP-Invoice.php';
    require_once SI_PATH . '/importers/CSV.php';
    do_action('si_importers_loaded');
    // Fix others problems
    require_once SI_PATH . '/controllers/compat/Compatibility.php';
    // all done
    do_action('si_require_controller_classes');
    // Template tags
    require_once SI_PATH . '/template-tags/estimates.php';
    require_once SI_PATH . '/template-tags/clients.php';
    require_once SI_PATH . '/template-tags/forms.php';
    require_once SI_PATH . '/template-tags/invoices.php';
    require_once SI_PATH . '/template-tags/line-items.php';
    require_once SI_PATH . '/template-tags/projects.php';
    require_once SI_PATH . '/template-tags/ui.php';
    require_once SI_PATH . '/template-tags/utility.php';
    require_once SI_PATH . '/template-tags/docs.php';
    // l18n
    require_once SI_PATH . '/languages/SI_l10n.php';
    require_once SI_PATH . '/languages/SI_Strings.php';
    // i18n & l10n
    SI_l10n::init();
    SI_Strings::load_additional_strings();
    SI_Locales::init();
    SI_Countries_States::init();
    ///////////////////
    // init() models //
    ///////////////////
    do_action('si_models_init');
    SI_Post_Type::init();
    // _Model
    SI_Record::init();
    SI_Notification::init();
    SI_Invoice::init();
    SI_Estimate::init();
    SI_Client::init();
    SI_Payment::init();
    SI_Project::init();
    /////////////////////////
    // init() controllers //
    /////////////////////////
    do_action('si_controllers_init');
    SI_Controller::init();
    SA_Settings_API::init();
    SI_Templating_API::init();
    SI_Customizer::init();
    SI_Admin_Capabilities::init();
    // updates
    if (!SI_FREE_TEST && class_exists('SI_Updates')) {
        SI_Updates::init();
    }
    if (class_exists('SI_Free_License')) {
        SI_Free_License::init();
    }
    // api
    SI_JSON_API::init();
    // reports
    SI_Dashboard::init();
    SI_Reporting::init();
    if (!SI_FREE_TEST && class_exists('SI_Reporting_Premium')) {
        SI_Reporting_Premium::init();
    }
    // records and logs
    SI_Internal_Records::init();
    SI_Dev_Logs::init();
    // settings
    SI_Admin_Settings::init();
    // payments and processing
    SI_Payment_Processors::init();
    SI_Payments::init();
    // notifications
    SI_Notifications::init();
    // Hooks come before parent class.
    if (!SI_FREE_TEST && class_exists('SI_Notifications_Premium')) {
        SI_Notifications_Premium::init();
    }
    SI_Notifications_Control::init();
    // clients
    SI_Clients::init();
    // estimates
    SI_Estimates::init();
    if (!SI_FREE_TEST && class_exists('SI_Estimates_Premium')) {
        SI_Estimates_Premium::init();
    }
    if (!SI_FREE_TEST && class_exists('SI_Estimates_Submission_Premium')) {
        SI_Estimates_Submission_Premium::init();
    }
    SI_Estimate_Submissions::init();
    SI_Estimates_Admin::init();
    SI_Estimates_Edit::init();
    SI_Estimates_Template::init();
    SI_Estimates_Records::init();
    // checkouts
    SI_Checkouts::init();
    // invoices
    SI_Invoices::init();
    SI_Invoices_Admin::init();
    SI_Invoices_Edit::init();
    SI_Invoices_Template::init();
    SI_Invoices_Records::init();
    SI_Invoices_Deposit::init();
    if (!SI_FREE_TEST && class_exists('SI_Invoices_Premium')) {
        SI_Invoices_Premium::init();
    }
    // Line items
    SI_Line_Items::init();
    // projects
    SI_Projects::init();
    if (!SI_FREE_TEST && class_exists('SI_Projects_Premium')) {
        SI_Projects_Premium::init();
    }
    // importer
    SI_Importer::init();
    // help
    SI_Help::init();
    // Compat
    SI_Compatibility::init();
    // addons
    require_once SI_PATH . '/add-ons/Addons.php';
    require_once SI_PATH . '/add-ons/updates/edd_plugin_updater.class.php';
    SA_Addons::init();
    do_action('sprout_invoices_loaded');
}
Esempio n. 16
0
 public static function create_invoice($invoice = array())
 {
     if (isset($invoice['Description']) && $invoice['Description'] != '') {
         $subject = $invoice['Description'];
     } elseif (isset($invoice['Client']) && $invoice['Client'] != '') {
         $subject = $invoice['Client'] . ' #' . $invoice['Invoice ID'];
     } else {
         $subject = '#' . $invoice['Invoice ID'];
     }
     $args = array('subject' => $subject);
     // Attempt to find matching client
     if (isset($invoice['Company'])) {
         global $wpdb;
         $client_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type = %s", esc_sql($invoice['Company']), SI_Client::POST_TYPE));
         // Get client and confirm it's validity
         if (is_array($client_ids) && !empty($client_ids)) {
             $client = SI_Client::get_instance($client_ids[0]);
             $args['client_id'] = $client->get_id();
         }
     }
     if (isset($invoice['Invoice ID'])) {
         $args['invoice_id'] = $invoice['Invoice ID'];
     }
     if (isset($invoice['Total'])) {
         $args['total'] = $invoice['Total'];
     }
     if (isset($invoice['Currency Code'])) {
         $args['currency'] = $invoice['Currency Code'];
     }
     if (isset($invoice['PO Number'])) {
         $args['po_number'] = $invoice['PO Number'];
     }
     if (isset($invoice['Discount %'])) {
         $args['discount'] = $invoice['Discount %'];
     }
     if (isset($invoice['Tax 1 %'])) {
         $args['tax'] = $invoice['Tax 1 %'];
     }
     if (isset($invoice['Tax 2 %'])) {
         $args['tax2'] = $invoice['Tax 2 %'];
     }
     if (isset($invoice['Notes'])) {
         $args['notes'] = $invoice['Notes'];
     }
     if (isset($invoice['Terms'])) {
         $args['terms'] = $invoice['Terms'];
     }
     if (isset($invoice['Invoice Date'])) {
         $args['issue_date'] = strtotime($invoice['Invoice Date']);
     }
     if (isset($invoice['Due Date'])) {
         $args['due_date'] = strtotime($invoice['Due Date']);
     }
     $line_items = self::build_line_items($invoice);
     $args['line_items'] = $line_items;
     $new_invoice_id = SI_Invoice::create_invoice($args, SI_Invoice::STATUS_PENDING);
     update_post_meta($new_invoice_id, self::CSV_ID, $invoice['Invoice ID']);
     $inv = SI_Invoice::get_instance($new_invoice_id);
     // post date
     if (isset($invoice['Invoice Date'])) {
         $inv->set_post_date(date('Y-m-d H:i:s', strtotime($invoice['Invoice Date'])));
     }
     return $inv;
 }
function process_ajax_on_project_change()
{
    $has_admin = array();
    //@TODO ADD NONCE CHECK
    $post_id = $_POST['post_id'];
    if ($post_id <= 0) {
        return;
    }
    $SI_Project = SI_Project::get_instance($post_id);
    $invoice_ids = $SI_Project->get_invoices();
    $estimate_ids = $SI_Project->get_estimates();
    $client_ids = $SI_Project->get_associated_clients();
    $clients = array();
    $estimates = array();
    $invoices = array();
    $asscoiativeTasks = array();
    foreach ($client_ids as $clients_id) {
        $SI_Client = SI_Client::get_instance($clients_id);
        $user_ids = $SI_Client->get_associated_users();
        foreach ($user_ids as $user_id) {
            if (user_can($user_id, 'update_core')) {
                $has_admin[] = $user_id;
            }
            $user = get_user_by('ID', $user_id);
            $display_name = $user->data->display_name;
            $clients[] = array('user_id' => (int) $user_id, 'display_name' => $display_name);
        }
    }
    if (empty($has_admin) && current_user_can('update_core')) {
        $args = array('role' => 'administrator');
        $users = get_users($args);
        foreach ($users as $user) {
            $clients[] = array('user_id' => (int) $user->ID, 'display_name' => $user->data->display_name);
        }
    }
    $blank_option = array('user_id' => '', 'display_name' => '');
    array_unshift($clients, $blank_option);
    foreach ($estimate_ids as $estimate_id) {
        $title = get_the_title($estimate_id);
        $estimates[] = array('est_id' => (int) $estimate_id, 'est_title' => $title);
    }
    foreach ($invoice_ids as $invoice_id) {
        $title = get_the_title($invoice_id);
        $invoices[] = array('inv_id' => (int) $invoice_id, 'inv_title' => $title);
    }
    $args = array('post_type' => 'mg_task', 'meta_key' => 'project', 'meta_value' => $post_id, 'post_status' => array('complete', 'in-progress', 'not-started', 'publish', 'published'));
    $the_query = new WP_Query($args);
    while ($the_query->have_posts()) {
        $the_query->the_post();
        $asscoiativeTasks[] = array('task_title' => get_the_title(), 'task_id' => get_the_ID());
    }
    $data = array('clients' => $clients, 'estimates' => $estimates, 'invoices' => $invoices, 'tasks' => $asscoiativeTasks);
    $output = json_encode($data);
    exit($output);
}
 /**
  * Maybe create a client from submission
  * @param  SI_Estimate $estimate 
  * @param  array       $args     * email - required
  *                               * client_id - if client_id is passed than just assign estimate
  *                               * client_name - required
  *                               * full_name - 
  *                               * website
  *                               * contact_street
  *                               * contact_city
  *                               * contact_zone
  *                               * contact_postal_code
  *                               * contact_country
  *                               
  */
 public static function maybe_create_client(SI_Estimate $estimate, $args = array())
 {
     $args = apply_filters('si_afi_maybe_create_client', $args);
     $client_id = isset($args['client_id']) && get_post_type($args['client_id']) == SI_Client::POST_TYPE ? $args['client_id'] : 0;
     $user_id = get_current_user_id();
     // check to see if the user exists by email
     if (isset($args['email']) && $args['email'] != '') {
         if ($user = get_user_by('email', $args['email'])) {
             $user_id = $user->ID;
         }
     }
     // Check to see if the user is assigned to a client already
     if (!$client_id) {
         $client_ids = SI_Client::get_clients_by_user($user_id);
         if (!empty($client_ids)) {
             $client_id = array_pop($client_ids);
         }
     }
     // Create a user for the submission if an email is provided.
     if (!$user_id) {
         // email is critical
         if (isset($args['email']) && $args['email'] != '') {
             $user_args = array('user_login' => self::esc__($args['email']), 'display_name' => isset($args['client_name']) ? self::esc__($args['client_name']) : self::esc__($args['email']), 'user_pass' => wp_generate_password(), 'user_email' => isset($args['email']) ? self::esc__($args['email']) : '', 'first_name' => si_split_full_name(self::esc__($args['full_name']), 'first'), 'last_name' => si_split_full_name(self::esc__($args['full_name']), 'last'), 'user_url' => isset($args['website']) ? self::esc__($args['website']) : '');
             $user_id = SI_Clients::create_user($user_args);
         }
     }
     // create the client based on what's submitted.
     if (!$client_id) {
         $address = array('street' => isset($args['contact_street']) ? self::esc__($args['contact_street']) : '', 'city' => isset($args['contact_city']) ? self::esc__($args['contact_city']) : '', 'zone' => isset($args['contact_zone']) ? self::esc__($args['contact_zone']) : '', 'postal_code' => isset($args['contact_postal_code']) ? self::esc__($args['contact_postal_code']) : '', 'country' => isset($args['contact_country']) ? self::esc__($args['contact_country']) : '');
         $args = array('company_name' => isset($args['client_name']) ? self::esc__($args['client_name']) : '', 'website' => isset($args['website']) ? self::esc__($args['website']) : '', 'address' => $address, 'user_id' => $user_id);
         $client_id = SI_Client::new_client($args);
         // History
         do_action('si_new_record', sprintf('Client Created & Assigned: %s', get_the_title($client_id)), self::SUBMISSION_UPDATE, $estimate->get_id(), sprintf('Client Created & Assigned: %s', get_the_title($client_id)), 0, false);
     }
     // Set the estimates client
     $estimate->set_client_id($client_id);
 }
Esempio n. 19
0
 public static function create_invoice($wp_invoice = array(), $client_id = 0)
 {
     // Don't create a duplicate if this was already imported.
     $possible_dups = SI_Post_Type::find_by_meta(SI_Invoice::POST_TYPE, array(self::WPINVOICE_ID => $wp_invoice['ID']));
     if (!empty($possible_dups)) {
         do_action('si_error', 'Invoice imported already', $wp_invoice['ID']);
         return;
     }
     // Get client
     if (!$client_id) {
         $clients = SI_Post_Type::find_by_meta(SI_Client::POST_TYPE, array(self::WPINVOICE_ID => $wp_invoice['ID']));
         // Get client and confirm it's validity
         $client = SI_Client::get_instance($clients[0]);
         $client_id = is_a($client, 'SI_Client') ? $client->get_id() : 0;
     }
     $args = array('subject' => $wp_invoice['post_title'] ? $wp_invoice['post_title'] : 'WPInvoice Import #' . $wp_invoice['ID']);
     $new_invoice_id = SI_Invoice::create_invoice($args, SI_Invoice::STATUS_TEMP);
     update_post_meta($new_invoice_id, self::WPINVOICE_ID, $wp_invoice['invoice_id']);
     $invoice = SI_Invoice::get_instance($new_invoice_id);
     $invoice->set_client_id($client_id);
     if (isset($wp_invoice['invoice_id'])) {
         $invoice->set_invoice_id($wp_invoice['invoice_id']);
     }
     if (isset($wp_invoice['subtotal'])) {
         $invoice->set_total($wp_invoice['subtotal']);
     }
     if (isset($wp_invoice['deposit_amount'])) {
         $invoice->set_deposit($wp_invoice['deposit_amount']);
     }
     if (isset($wp_invoice['default_currency_code'])) {
         $invoice->set_currency($wp_invoice['default_currency_code']);
     }
     if (isset($wp_invoice['custom_id'])) {
         $invoice->set_po_number($wp_invoice['custom_id']);
     }
     if (isset($wp_invoice['total_discount'])) {
         $invoice->set_discount($wp_invoice['total_discount']);
     }
     if (isset($wp_invoice['post_content'])) {
         $invoice->set_notes($wp_invoice['post_content']);
     }
     if (isset($wp_invoice['post_status'])) {
         switch ($wp_invoice['post_status']) {
             case 'paid':
                 $invoice->set_as_paid();
                 break;
             case 'active':
             case 'pending':
                 $invoice->set_pending();
                 break;
             case 'refund':
                 $invoice->set_as_written_off();
                 break;
             default:
                 $invoice->set_as_temp();
                 break;
         }
     }
     $invoice->set_issue_date(strtotime($wp_invoice['due_date_day'] . '-' . $wp_invoice['due_date_month'] . '-' . $wp_invoice['due_date_year']));
     // post date
     $invoice->set_post_date(date('Y-m-d H:i:s', strtotime($wp_invoice['post_date'])));
     // line items
     $line_items = array();
     if (isset($wp_invoice['itemized_list']) && !empty($wp_invoice['itemized_list'])) {
         foreach ($wp_invoice['itemized_list'] as $key => $item) {
             $line_items[] = array('rate' => isset($item['price']) ? $item['price'] : '', 'qty' => isset($item['quantity']) ? $item['quantity'] : '', 'desc' => $item['description'] == '' ? $item['name'] : '<strong>' . $item['name'] . '</strong><br/>' . $item['description'], 'type' => '', 'total' => isset($item['line_total_after_tax']) ? $item['line_total_after_tax'] : '', 'tax' => isset($item['tax_rate']) ? $item['tax_rate'] : '');
         }
     }
     // I don't know what itemized charges could possibly be used for but they can be items.
     if (isset($wp_invoice['itemized_charges']) && !empty($wp_invoice['itemized_charges'])) {
         foreach ($wp_invoice['itemized_charges'] as $key => $item) {
             $line_items[] = array('rate' => isset($item['amount']) ? $item['amount'] : '', 'qty' => 1, 'desc' => isset($item['name']) ? $item['name'] : '', 'type' => '', 'total' => isset($item['after_tax']) ? $item['after_tax'] : '', 'tax' => isset($item['tax']) ? $item['tax'] : '');
         }
     }
     $invoice->set_line_items($line_items);
     // Records
     if (!empty($wp_invoice['log'])) {
         foreach ($wp_invoice['log'] as $key => $event) {
             if ($event['attribute'] == 'notification') {
                 // payments are added separately
                 do_action('si_new_record', self::__('Notification content was not stored by WP-Invoice.'), SI_Notifications::RECORD, $new_invoice_id, $event['text'], 0, false);
             }
         }
     }
     do_action('si_new_record', $wp_invoice, self::RECORD, $new_invoice_id, self::__('Invoice Imported'), 0);
     return $invoice;
 }
 public static function validate_token()
 {
     $user_id = 0;
     if (!isset($_REQUEST[self::USER_QUERY_ARG]) || $_REQUEST[self::USER_QUERY_ARG] == '') {
         return false;
     }
     if (!isset($_REQUEST[self::CLIENT_TOKEN_QUERY_ARG]) || $_REQUEST[self::CLIENT_TOKEN_QUERY_ARG] == '') {
         return false;
     }
     $user_id = $_REQUEST[self::USER_QUERY_ARG];
     $token = $_REQUEST[self::CLIENT_TOKEN_QUERY_ARG];
     // Search for client with token.
     $clients = SI_Post_Type::find_by_meta(SI_Client::POST_TYPE, array(self::CLIENT_TOKEN_META => $token));
     if (empty($clients)) {
         return false;
     }
     foreach ($clients as $client_id) {
         $client = SI_Client::get_instance($client_id);
         // confirm user id is associated still.
         if (!in_array($user_id, $client->get_associated_users())) {
             return false;
         }
     }
     return $clients;
 }
Esempio n. 21
0
 public static function create_invoice(Harvest_Invoice $invoice)
 {
     $possible_dups = SI_Post_Type::find_by_meta(SI_Invoice::POST_TYPE, array(self::HARVEST_ID => $invoice->id));
     // Don't create a duplicate if this was already imported.
     if (!empty($possible_dups)) {
         do_action('si_error', 'Invoice imported already', $invoice->id);
         return;
     }
     $clients = SI_Post_Type::find_by_meta(SI_Client::POST_TYPE, array(self::HARVEST_ID => $invoice->client_id));
     // Get client and confirm it's validity
     $client = SI_Client::get_instance($clients[0]);
     $client_id = is_a($client, 'SI_Client') ? $client->get_id() : 0;
     $args = array('subject' => $invoice->subject ? $invoice->subject : 'Harvest Import #' . $invoice->id);
     $inv_id = SI_Invoice::create_invoice($args, SI_Invoice::STATUS_TEMP);
     update_post_meta($inv_id, self::HARVEST_ID, $invoice->id);
     $inv = SI_Invoice::get_instance($inv_id);
     $inv->set_client_id($client_id);
     $inv->set_invoice_id($invoice->number);
     $inv->set_total($invoice->amount);
     $inv->set_tax($invoice->tax);
     $inv->set_discount($invoice->discount);
     $inv->set_notes($invoice->notes);
     $inv->set_due_date(strtotime($invoice->due_at));
     $inv->set_issue_date(strtotime($invoice->created_at));
     // post date
     $inv->set_post_date(date('Y-m-d H:i:s', strtotime($invoice->created_at)));
     // Record
     do_action('si_new_record', $invoice, self::RECORD, $inv_id, self::__('Invoice Imported'), 0);
     return $inv;
 }
 /**
  * Process the payment and return the result
  *
  * @param int $order_id
  * @return array
  */
 public function process_payment($order_id)
 {
     $order = wc_get_order($order_id);
     ///////////////////////////
     // Create Sprout Invoice //
     ///////////////////////////
     /**
      * Build line item array
      * @var array
      */
     $line_items = array();
     $tax = 0;
     foreach ($order->get_items() as $key => $item) {
         $_product = apply_filters('woocommerce_order_item_product', $order->get_product_from_item($item), $item);
         if ($_product && !$_product->is_visible()) {
             $desc = apply_filters('woocommerce_order_item_name', $item['name'], $item);
         } else {
             $desc = apply_filters('woocommerce_order_item_name', sprintf('<a href="%s">%s</a>', get_permalink($item['product_id']), $item['name']), $item);
         }
         $line_items[] = array('rate' => $item['line_subtotal'] / $item['qty'], 'qty' => (int) $item['qty'], 'desc' => $desc, 'total' => $item['line_subtotal'], 'tax' => -$tax);
     }
     if ($order->get_total_shipping() > 0.0) {
         $line_items[] = array('rate' => $order->get_total_shipping(), 'qty' => 1, 'desc' => __('Shipping', 'sprout-invoices'), 'total' => $order->get_total_shipping(), 'tax' => 0);
     }
     foreach ($order->get_tax_totals() as $code => $tax) {
         $line_items[] = array('rate' => $tax->amount - $order->get_total_tax_refunded_by_rate_id($tax->rate_id), 'qty' => 1, 'desc' => $tax->label, 'total' => $tax->amount - $order->get_total_tax_refunded_by_rate_id($tax->rate_id), 'tax' => 0);
     }
     if ('' !== $order->customer_note) {
         $line_items[] = array('rate' => 0, 'qty' => 0, 'desc' => $order->customer_note, 'total' => 0, 'tax' => 0);
     }
     $invoice_args = array('status' => SI_Invoice::STATUS_PENDING, 'subject' => sprintf(__('Order #%s', 'sprout-invoices'), $order_id), 'line_items' => $line_items);
     $invoice_id = SI_Invoice::create_invoice($invoice_args);
     $invoice = SI_Invoice::get_instance($invoice_id);
     $invoice->set_discount($order->get_total_discount());
     $invoice->set_total($order->get_total());
     if (method_exists($invoice, 'set_email')) {
         $invoice->set_email($order->billing_email);
     }
     if ($order->get_user_id()) {
         $client_ids = SI_Client::get_clients_by_user($order->get_user_id());
         if (!empty($client_ids)) {
             $client_id = array_pop($client_ids);
         }
         if (!$client_id) {
             $address = array('street' => $order->billing_address_1 . ' ' . $order->billing_address_2, 'city' => $order->billing_city, 'zone' => $order->billing_state, 'postal_code' => $order->billing_postcode, 'country' => $order->billing_country);
             $args = array('company_name' => '' !== $order->billing_company ? $order->billing_company : $order->billing_first_name . ' ' . $order->billing_last_name, 'website' => '', 'address' => $address, 'user_id' => $order->get_user_id());
             $client_id = SI_Client::new_client($args);
         }
         $invoice->set_client_id($client_id);
     }
     // History
     do_action('si_new_record', sprintf('<a href="%s">#%s</a>', add_query_arg(array('post' => $order_id, 'action' => 'edit'), admin_url('post.php')), $order_id), 'woocommerce_order', $invoice_id, sprintf('<a href="%s">#%s</a>', add_query_arg(array('post' => $order_id, 'action' => 'edit'), admin_url('post.php')), $order_id), 0, false);
     // store the order id within the invoice
     update_post_meta($invoice_id, Woo_Integration::ORDER_ID_META, $order_id);
     do_action('si_woocommerce_payment', $order_id, $invoice_id);
     ////////////
     // Return //
     ////////////
     // Mark as on-hold (we're awaiting the sprout_invoices)
     $order->update_status('on-hold', __('Awaiting invoice payment', 'sprout-invoices'));
     // Reduce stock levels
     $order->reduce_order_stock();
     // Remove cart
     WC()->cart->empty_cart();
     // Return thankyou redirect
     return array('result' => 'success', 'redirect' => $this->get_return_url($order));
 }
Esempio n. 23
0
 public static function create_invoice($invoice = array())
 {
     $possible_dups = SI_Post_Type::find_by_meta(SI_Invoice::POST_TYPE, array(self::FRESHBOOKS_ID => $invoice['invoice_id']));
     // Don't create a duplicate if this was already imported.
     if (!empty($possible_dups)) {
         do_action('si_error', 'Invoice imported already', $invoice['invoice_id']);
         return;
     }
     $clients = SI_Post_Type::find_by_meta(SI_Client::POST_TYPE, array(self::FRESHBOOKS_ID => $invoice['client_id']));
     // Get client and confirm it's validity
     $client = SI_Client::get_instance($clients[0]);
     $client_id = is_a($client, 'SI_Client') ? $client->get_id() : 0;
     $args = array('subject' => isset($invoice['description']) ? $invoice['description'] : 'Freshbooks Import #' . $invoice['invoice_id']);
     $new_invoice_id = SI_Invoice::create_invoice($args, SI_Invoice::STATUS_TEMP);
     update_post_meta($new_invoice_id, self::FRESHBOOKS_ID, $invoice['invoice_id']);
     $inv = SI_Invoice::get_instance($new_invoice_id);
     $inv->set_client_id($client_id);
     if (!is_array($invoice['number'])) {
         $inv->set_invoice_id($invoice['number']);
     }
     if (!is_array($invoice['amount'])) {
         $inv->set_total($invoice['amount']);
     }
     if (!is_array($invoice['currency_code'])) {
         $inv->set_currency($invoice['currency_code']);
     }
     if (!is_array($invoice['po_number'])) {
         $inv->set_po_number($invoice['po_number']);
     }
     if (!is_array($invoice['discount'])) {
         $inv->set_discount($invoice['discount']);
     }
     if (!is_array($invoice['notes'])) {
         $inv->set_notes($invoice['notes']);
     }
     if (!is_array($invoice['terms'])) {
         $inv->set_terms($invoice['terms']);
     }
     $inv->set_issue_date(strtotime($invoice['date']));
     // post date
     $inv->set_post_date(date('Y-m-d H:i:s', strtotime($invoice['date'])));
     // line items
     $line_items = array();
     if (isset($invoice['lines']['line']) && !empty($invoice['lines']['line'])) {
         // for some reason FB
         if (isset($invoice['lines']['line'][0])) {
             foreach ($invoice['lines']['line'] as $key => $item) {
                 $line_items[] = array('rate' => !is_array($item['unit_cost']) ? $item['unit_cost'] : '', 'qty' => !is_array($item['quantity']) ? $item['quantity'] : '', 'desc' => !is_array($item['description']) ? $item['description'] : '', 'type' => !is_array($item['type']) ? $item['type'] : '', 'total' => !is_array($item['amount']) ? $item['amount'] : '', 'tax' => !is_array($item['tax1_percent']) ? $item['tax1_percent'] : '');
             }
         } else {
             $line_items[] = array('rate' => !is_array($invoice['lines']['line']['unit_cost']) ? $invoice['lines']['line']['unit_cost'] : '', 'qty' => !is_array($invoice['lines']['line']['quantity']) ? $invoice['lines']['line']['quantity'] : '', 'desc' => !is_array($invoice['lines']['line']['description']) ? $invoice['lines']['line']['description'] : '', 'type' => !is_array($invoice['lines']['line']['type']) ? $invoice['lines']['line']['type'] : '', 'total' => !is_array($invoice['lines']['line']['amount']) ? $invoice['lines']['line']['amount'] : '', 'tax' => !is_array($invoice['lines']['line']['tax1_percent']) ? $invoice['lines']['line']['tax1_percent'] : '');
         }
     }
     $inv->set_line_items($line_items);
     // Record
     do_action('si_new_record', $invoice, self::RECORD, $new_invoice_id, self::__('Invoice Imported'), 0);
     return $inv;
 }
 public static function client_name($atts = array())
 {
     $id = 0;
     if (si_get_doc_context() == 'estimate') {
         $id = si_get_estimate_id();
     } else {
         $id = si_get_invoice_id();
     }
     $doc = si_get_doc_object($id);
     if (!$doc->get_client_id()) {
         return '';
     }
     $client = SI_Client::get_instance($client_id);
     return $client->get_title();
 }