Create Default User Xero Invoice for Guest OpenPOS WooCommerce
Previously, I discussed how to fix the error "creating Xero invoice openPOS WooCommerce". That approach might not be entirely accurate in some cases because, in my example, payments made using PayNow QR from the OpenPOS app always require login to confirm the payment, even though there is a better approach, which is to set a default contact based on a specific contact ID registered in the WordPress system.
First, I need to explain that every time an order is created through the OpenPOS app, the Xero plugin in WooCommerce cannot create an invoice and shows an error like the following:
ERROR creating Xero invoice: ErrorNumber: 10 ErrorType: ValidationException Message: A validation exception occurred Detail: The Contact must contain at least 1 of the following elements to identify the contact: Name, ContactID, ContactNumber
This happens because orders created through the OpenPOS app are identified as guest users, which are not directly connected to WordPress users, so the invoice might not be sent to Xero.
We can debug from the admin side by editing the order and sending the invoice to Xero. The debugging results will display the following parameter:
<invoice>
<type>ACCREC</type>
<contact>
<name></name>
<firstname></firstname>
<lastname></lastname>
<emailaddress></emailaddress>
<addresses>
<address>
<addresstype>POBOX</addresstype>
<addressline1></addressline1>
<city></city>
<region></region>
<postalcode></postalcode>
<country></country>
</address>
</addresses>
<phones>
<phone>
<phonetype>DEFAULT</phonetype>
<phonenumber></phonenumber>
</phone>
</phones>
</contact>
<date>2024-09-05</date>
<duedate>2024-09-05</duedate>
<invoicenumber>EX-201</invoicenumber>
<reference>Cash Order 201</reference>
<url>https://mywpppppp.com/wp-admin/post.php?post=201&action=edit</url>
<lineamounttypes>Exclusive</lineamounttypes>
<lineitems>
<lineitem>
<description>My Product Name</description>
<accountcode>200</accountcode>
<itemcode>Myprd-SUB-000</itemcode>
<unitamount>213</unitamount>
<quantity>1</quantity>
<taxtype>NONE</taxtype>
<taxamount>0</taxamount>
</lineitem>
</lineitems>
<currencycode>SGD</currencycode>
<status>AUTHORISED</status>
</invoice>
code x1
DEBUGGING TO GET CONTACT ID
To resolve the issue above, we first need to debug to obtain the contact ID of the WordPress user. The process involves changing the guest user to another registered user and then sending the invoice to Xero. Before the invoice is sent to Xero, we need to intercept or debug to get the contact ID parameter of the assigned user.
Open the plugin editor and navigate to Xero, then edit the following file:
woocommerce-xero/includes/class-wc-xr-invoice.php
Pay attention to the entire code of the public function to_xml() below:
public function to_xml() {
// Start Invoice
$xml = '<Invoice>';
// Type
$xml .= '<Type>' . $this->get_type() . '</Type>';
// Add Contact
if ( $this->get_contact()->get_id() ) {
$xml .= $this->get_contact()->id_to_xml();
} else {
$xml .= $this->get_contact()->to_xml();
}
// Date
$xml .= '<Date>' . $this->get_date() . '</Date>';
// Due Date
$xml .= '<DueDate>' . $this->get_due_date() . '</DueDate>';
// Invoice Number
$invoice_number = $this->get_invoice_number();
if ( null !== $invoice_number ) {
$xml .= '<InvoiceNumber>' . $invoice_number . '</InvoiceNumber>';
}
// Reference
$order = $this->get_order();
$reference_pieces = array();
$payment_method = esc_xml( $order->get_payment_method_title() );
if ( ! empty( $payment_method ) ) {
$reference_pieces[] = $payment_method;
}
$transaction_id = $order->get_transaction_id();
if ( ! empty( $transaction_id ) ) {
$reference_pieces[] = $transaction_id;
}
if ( $order ) {
$reference_pieces[] = sprintf(
/* translators: %d: order id */
__( 'Order %d', 'woocommerce-xero' ),
(int) $order->get_id()
);
}
if ( 0 < count( $reference_pieces ) ) {
$xml .= '<Reference>' . implode( ' ', $reference_pieces ) . '</Reference>';
}
// URL
$order_id = $order->get_id();
$path = '/post.php?post=' . esc_attr( intval( $order_id ) ) . '&action=edit';
$url = admin_url( $path );
// Check for port number (port numbers in URLs are not allowed by Xero)
$port = parse_url( $url, PHP_URL_PORT );
// Only add the Url to the XML if a port number is NOT present
if ( empty( $port ) ) {
$xml .= '<Url>' . esc_url( $url ) . '</Url>';
}
// Line Amount Types. Always send prices exclusive VAT.
$line_amount_type = ( $this->settings->send_tax_inclusive_prices() ) ? 'Inclusive' : 'Exclusive';
$xml .= '<LineAmountTypes>' . $line_amount_type . '</LineAmountTypes>';
// Get Line Items
$line_items = $this->get_line_items();
// Check line items
if ( count( $line_items ) ) {
// Line Items wrapper open
$xml .= '<LineItems>';
// Loop
foreach ( $line_items as $line_item ) {
// Add
$xml .= $line_item->to_xml();
}
// Line Items wrapper close
$xml .= '</LineItems>';
}
// Currency Code
$xml .= '<CurrencyCode>' . $this->get_currency_code() . '</CurrencyCode>';
// Status
$xml .= '<Status>AUTHORISED</Status>';
// Get branding theme template ID.
$branding_theme = $this->settings->get_option( 'branding_theme' );
/**
* Filter to change the branding theme template ID.
*
* @since 1.7.45
*
* `woocommerce_xero_branding_theme` is a filter hook.
* @var string $branding_theme is a branding theme ID.
* @var object $order Order object.
*/
$branding_theme = apply_filters( 'woocommerce_xero_branding_theme', $branding_theme, $this );
if ( $branding_theme ) {
// Only send branding theme if it is valid/exists.
try {
$org_request = new WC_XR_Request_Branding_Themes( $this->settings, $branding_theme );
$org_request->do_request();
$xml_response = $org_request->get_response_body_xml();
if ( 'OK' === (string) $xml_response->Status ) {
$xml .= '<BrandingThemeID>' . esc_html( $branding_theme ) . '</BrandingThemeID>';
}
} catch ( Exception $e ) {
// Add Exception as order note.
$order->add_order_note( 'BrandingThemeID is invalid, using the default template. ' . $e->getMessage() );
}
}
// Total Tax
$xml .= '<TotalTax>' . $this->get_total_tax() . '</TotalTax>';
// Total
$xml .= '<Total>' . $this->get_total() . '</Total>';
// End Invoice
$xml .= '</Invoice>';
/**
* Filter the xml data returned by WC_XR_Invoice::to_xml()
* value is returned.
*
* @since 1.7.4 introduced
*
* @param string $xml
* @param WC_XR_Invoice $invoice_object
*/
return apply_filters( 'woocommerce_xero_invoice_to_xml', $xml, $this );
}
code x2
Insert the following code to perform debugging, then save:
// Currency Code
$xml .= '<CurrencyCode>' . $this->get_currency_code() . '</CurrencyCode>';
// Status
$xml .= '<Status>AUTHORISED</Status>';
//start debuging from here
echo var_dump($xml);
exit();
code x3
Return to the order that failed to send the invoice, then change the guest user identification to another user in the system. Next, update and choose "Send invoice to Xero". You should now see the contact ID of the user identified in the <contactid> tag. Save the value of this parameter.
SAVING DEFAULT USER TO SEND INVOICE XERO
Since the reason invoices cannot be created and sent to Xero automatically is that the user is identified as a guest with an empty contact ID, we can set it in the following line:
// Add Contact
if ( $this->get_contact()->get_id() ) {
$xml .= $this->get_contact()->id_to_xml();
} else {
// Place default user contact id from here
//$xml .= $this->get_contact()->to_xml();
$xml.='<Contact>';
$xml .='<ContactID>your-hah-contact-id</ContactID>';
$xml.='</Contact>';
}
code x4
Finally, please test again. The invoice should now be created automatically and sent to Xero.
============
CARA MEMBUAT USER DEFAULT XERO UNTUK GUES DARI openPOS WOOCOMMERCE
Sebelumnya saya pernah membahas tentang bagaimana Fix ERROR creating Xero invoice openPOS Woocommerce . Cara tersebut dalam beberapa kasus kurang tepat, sebab dalam contoh kasus saya pembayaran yang dilakukan menggunakan PayNow QR dari aplikasi openPOS selalu meminta login untuk mengkonfirmasi pembayaran padahal sebenarnya ada pendekatan yang lebih baik yaitu dengan menetapkan default contact berdasarkan contact id tertentu yang terdaftar dalam sistem wordpress
Pertama perlu saya jelaskan bahwa setiap kali order dibuat melalui aplikasi openPOS, plugins xero yang terdapat pada woocommerce tidak dapat membuat invoice dengan catatan error seperti berikut :
“ERROR creating Xero invoice: ErrorNumber: 10 ErrorType: ValidationException Message: A validation exception occurred Detail: The Contact must contain at least 1 of the following elements to identify the contact: Name, ContactID, ContactNumber”
Sebab proses order yang dibuat melalui aplikasi openPOS di identifikasi sebagai user guest yang tidak secara langsung terhubung ke user wordpress sehingga mungkin invoice tidak dapat dikirimkan ke xero
Kita dapat melakukan debuging dari admin dengan cara mengedit order dan mengirim invoice ke xero dan hasil debuging akan menampilkan parameter berikut:
lihat kode x1
DEBUGING UNTUK MENDAPATKAN CONTACT ID
Untuk mengatasi masalah diatas, pertama kita harus melakukan debuging untuk mendapatkan contact id dari user wordpress. Caranya adalah dengan mengubah user guest ke user lain yang terdaftar kemudian baru mengirimkan invoice ke xero, sebelum invoice diteruskan ke xero, maka kita perlu mencegatnya atau mendebug untuk mendapatkan parameter contact id dari user yang ditetapkan.
Buka editor plugin lalau arahkan ke xero selanjutnya edit file berikut:
woocommerce-xero/includes/class-wc-xr-invoice.php
Perhartikan keseluruhan kode dari fungsi public function to_xml() berikut :
lihat kode x2
Tempat kode berikut untuk melakukan debuging, selanjutnya simpan.
lihat kode x3
Kembali ke order yang gagal mengirim invoice, selanjutnya rubah identifikasi user guest ke user lain yang terdapat pada sistem. Kemudian update pilih send invoice to xero, maka nanti mungkin anda akan melihat contact id usernya yang di identifikasi dalam tag <contactid>, simpan nilai pada parameter tersebut.
MENYIMPAN DEFAULT USER UNTUK MENGIRIM INVOICE ke XERO
Karena yang menyebabkan invoice tidak dapat dibuat secara otomatis dan dikirim ke xero adalah karena user teridentifikasi sebagai guest yang nilai contact id nya kosong maka kita bisa mengesetnya pada baris berikut :
lihat kode x4
Terkahir silahkan test kembali, harusnya sekarang invoice dapat dibuat secara otomatis dan dikirim ke xero
senang datang disini, pulang bawa tambahan ilmu
ReplyDelete