/**
  * Send the payment to the XERO API
  *
  * @param int $order_id
  *
  * @return bool
  */
 public function send_payment($order_id)
 {
     // Get the order
     $order = wc_get_order($order_id);
     // Payment Request
     $payment_request = new WC_XR_Request_Payment($this->get_payment_by_order($order));
     // Write exception message to log
     $logger = new WC_XR_Logger();
     // Logging start
     $logger->write('START XERO NEW PAYMENT. order_id=' . $order->id);
     // Try to do the request
     try {
         // Do the request
         $payment_request->do_request();
         // Parse XML Response
         $xml_response = $payment_request->get_response_body_xml();
         // Check response status
         if ('OK' == $xml_response->Status) {
             // Add post meta
             add_post_meta($order->id, '_xero_payment_id', (string) $xml_response->Payments->Payment[0]->PaymentID);
             // Write logger
             $logger->write('XERO RESPONSE:' . "\n" . $payment_request->get_response_body());
             // Add order note
             $order->add_order_note(__('Xero Payment created.  ', 'wc-xero') . ' Payment ID: ' . (string) $xml_response->Payments->Payment[0]->PaymentID);
         } else {
             // XML reponse is not OK
             // Logger write
             $logger->write('XERO ERROR RESPONSE:' . "\n" . $payment_request->get_response_body());
             // Error order note
             $error_num = (string) $xml_response->ErrorNumber;
             $error_msg = (string) $xml_response->Elements->DataContractBase->ValidationErrors->ValidationError->Message;
             $order->add_order_note(__('ERROR creating Xero payment. ErrorNumber:' . $error_num . '| Error Message:' . $error_msg, 'wc-xero'));
         }
     } catch (Exception $e) {
         // Add Exception as order note
         $order->add_order_note($e->getMessage());
         $logger->write($e->getMessage());
         return false;
     }
     // Logging end
     $logger->write('END XERO NEW PAYMENT');
     return true;
 }
 /**
  * Send invoice to XERO API
  *
  * @param int $order_id
  *
  * @return bool
  */
 public function send_invoice($order_id)
 {
     // Get the order
     $order = wc_get_order($order_id);
     // Get the invoice
     $invoice = $this->get_invoice_by_order($order);
     // Settings object
     $settings = new WC_XR_Settings();
     // Write exception message to log
     $logger = new WC_XR_Logger();
     // Check if the order total is 0 and if we need to send 0 total invoices to Xero
     if (0 == $invoice->get_total() && 'on' !== $settings->get_option('export_zero_amount')) {
         $logger->write('INVOICE HAS TOTAL OF 0, NOT SENDING ORDER WITH ID ' . $order->id);
         $order->add_order_note(__("XERO: Didn't create invoice because total is 0 and send order with zero total is set to off.", 'wc-xero'));
         return false;
     }
     // Invoice Request
     $invoice_request = new WC_XR_Request_Invoice($this->get_invoice_by_order($order));
     // Logging
     $logger->write('START XERO NEW INVOICE. order_id=' . $order->id);
     // Try to do the request
     try {
         // Do the request
         $invoice_request->do_request();
         // Parse XML Response
         $xml_response = $invoice_request->get_response_body_xml();
         // Check response status
         if ('OK' == $xml_response->Status) {
             // Add order meta data
             add_post_meta($order->id, '_xero_invoice_id', (string) $xml_response->Invoices->Invoice[0]->InvoiceID);
             add_post_meta($order->id, '_xero_currencyrate', (string) $xml_response->Invoices->Invoice[0]->CurrencyRate);
             // Log response
             $logger->write('XERO RESPONSE:' . "\n" . $invoice_request->get_response_body());
             // Add Order Note
             $order->add_order_note(__('Xero Invoice created.  ', 'wc-xero') . ' Invoice ID: ' . (string) $xml_response->Invoices->Invoice[0]->InvoiceID);
             // Settings object
             $settings = new WC_XR_Settings();
             // Check if sending payment is on
             if ('on' === $settings->get_option('send_payments') && $invoice->get_total() > 0) {
                 // Payment Manager
                 $payment_manager = new WC_XR_Payment_Manager();
                 // Send payment
                 $payment_manager->send_payment($order->id);
             }
         } else {
             // XML reponse is not OK
             // Log reponse
             $logger->write('XERO ERROR RESPONSE:' . "\n" . $invoice_request->get_response_body());
             // Format error message
             $error_message = $xml_response->Elements->DataContractBase->ValidationErrors->ValidationError->Message ? $xml_response->Elements->DataContractBase->ValidationErrors->ValidationError->Message : __('None', 'wc-xero');
             // Add order note
             $order->add_order_note(__('ERROR creating Xero invoice: ', 'wc-xero') . __(' ErrorNumber: ', 'wc-xero') . $xml_response->ErrorNumber . __(' ErrorType: ', 'wc-xero') . $xml_response->Type . __(' Message: ', 'wc-xero') . $xml_response->Message . __(' Detail: ', 'wc-xero') . $error_message);
         }
     } catch (Exception $e) {
         // Add Exception as order note
         $order->add_order_note($e->getMessage());
         $logger->write($e->getMessage());
         return false;
     }
     $logger->write('END XERO NEW INVOICE');
     return true;
 }
 /**
  * Build a correction line if needed
  *
  * @param WC_Order $order
  * @param array <WC_XR_Line_Item>
  *
  * @return WC_XR_Line_Item
  */
 public function build_correction($order, $line_items)
 {
     // Line Item
     $correction_line = null;
     // The line item total in cents
     $line_item_total_cents = 0;
     // Get a sum of the amount and tax of all line items
     if (count($line_items) > 0) {
         foreach ($line_items as $line_item) {
             // Check if line amount is set
             if (null !== $line_item->get_line_amount()) {
                 // Use line amount if set
                 $line_item_total_cents += $line_item->get_line_amount() * 100;
             } else {
                 // Use unit amount if line amount is not set
                 $line_item_total_cents += $line_item->get_unit_amount() * 100;
             }
             $line_item_total_cents += $line_item->get_tax_amount() * 100;
         }
     }
     // Order total in cents
     $order_total_cents = intval(floatval($order->order_total) * 100);
     // We want an integer
     $line_item_total_cents = intval($line_item_total_cents);
     // Check if there's a difference
     if ($line_item_total_cents !== $order_total_cents) {
         // Calculate difference
         $diff = round($order_total_cents - $line_item_total_cents) / 100;
         // Settings object
         $settings = new WC_XR_Settings();
         // Get rounding account code
         $account_code = $settings->get_option('rounding_account');
         // Check rounding account code
         if ('' !== $account_code) {
             // Create correction line item
             $correction_line = new WC_XR_Line_Item();
             // Correction description
             $correction_line->set_description('Rounding adjustment');
             // Correction quantity
             $correction_line->set_quantity(1);
             // Correction amount
             $correction_line->set_unit_amount($diff);
             $correction_line->set_account_code($account_code);
         } else {
             // There's a rounding difference but no rounding account
             $logger = new WC_XR_Logger();
             $logger->write("There's a rounding difference but no rounding account set in XERO settings.");
         }
     }
     return $correction_line;
 }