From 0018227d88e0174c7fc4b55613019e781a799e69 Mon Sep 17 00:00:00 2001 From: dinamiko Date: Mon, 29 Aug 2022 15:18:40 +0200 Subject: [PATCH] Ensure item taxes for pui payment (WIP) --- .../Endpoint/PayUponInvoiceOrderEndpoint.php | 75 ++++++++++++++++++- .../PayUponInvoice/PayUponInvoiceGateway.php | 2 +- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/modules/ppcp-api-client/src/Endpoint/PayUponInvoiceOrderEndpoint.php b/modules/ppcp-api-client/src/Endpoint/PayUponInvoiceOrderEndpoint.php index 41e5563ec..77d23b636 100644 --- a/modules/ppcp-api-client/src/Endpoint/PayUponInvoiceOrderEndpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/PayUponInvoiceOrderEndpoint.php @@ -12,8 +12,14 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint; use Psr\Log\LoggerInterface; use RuntimeException; use stdClass; +use WC_Order; +use WC_Order_Item_Product; +use WC_Product; +use WC_Tax; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\RequestTrait; +use WooCommerce\PayPalCommerce\ApiClient\Entity\Item; +use WooCommerce\PayPalCommerce\ApiClient\Entity\Money; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; @@ -96,7 +102,7 @@ class PayUponInvoiceOrderEndpoint { * @throws RuntimeException When there is a problem with the payment source. * @throws PayPalApiException When there is a problem creating the order. */ - public function create( array $items, PaymentSource $payment_source ): Order { + public function create( array $items, PaymentSource $payment_source, WC_Order $wc_order): Order { $data = array( 'intent' => 'CAPTURE', @@ -112,8 +118,7 @@ class PayUponInvoiceOrderEndpoint { ), ); - $data = $this->ensure_tax( $data ); - $data = $this->ensure_tax_rate( $data ); + $data = $this->ensure_taxes($wc_order, $data, $items); $data = $this->ensure_shipping( $data, $payment_source->to_array() ); $bearer = $this->bearer->bearer(); @@ -255,4 +260,68 @@ class PayUponInvoiceOrderEndpoint { return $data; } + + /** + * @param WC_Order $wc_order + * @param array $data + * @param array $items + * @return array + */ + private function ensure_taxes(WC_Order $wc_order, array $data, array $items): array + { + $items = array_map( + function (WC_Order_Item_Product $item) use ($wc_order): Item { + $product = $item->get_product(); + $currency = $wc_order->get_currency(); + $quantity = (int)$item->get_quantity(); + $unit_amount = $wc_order->get_item_subtotal($item, false, false); + + $tax_rates = WC_Tax::get_rates($product->get_tax_class()); + $tax_rate = reset($tax_rates)['rate'] ?? 0; + + $tax = $unit_amount * ($tax_rate / 100); + $tax = new Money($tax, $currency); + + return new Item( + mb_substr($item->get_name(), 0, 127), + new Money($wc_order->get_item_subtotal($item, false, false), $currency), + $quantity, + substr(wp_strip_all_tags($product instanceof WC_Product ? $product->get_description() : ''), + 0, 127) ?: '', + $tax, + $product instanceof WC_Product ? $product->get_sku() : '', + ($product instanceof WC_Product && $product->is_virtual()) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS, + reset($tax_rates)['rate'] ?? 0 + ); + }, + $wc_order->get_items(), + array_keys($wc_order->get_items()) + ); + + $items_count = count($data['purchase_units'][0]['items']); + for ($i = 0; $i < $items_count; $i++) { + if (!isset($data['purchase_units'][0]['items'][$i]['tax'])) { + $data['purchase_units'][0]['items'][$i] = $items[$i]->to_array(); + } + } + + $shipping = (float)$wc_order->calculate_shipping(); + $total = 0; + $tax_total = 0; + + foreach ($items as $item) { + $unit_amount = (float)$item->unit_amount()->value(); + $tax = (float)$item->tax()->value(); + $qt = $item->quantity(); + + $total += (($unit_amount + $tax) * $qt); + $tax_total += $tax * $qt; + } + + $data['purchase_units'][0]['amount']['value'] = number_format($total + $shipping, 2, '.', + ''); + $data['purchase_units'][0]['amount']['breakdown']['tax_total']['value'] = number_format($tax_total, + 2, '.', ''); + return $data; + } } diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index 68d4a19a7..7cff41b36 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -226,7 +226,7 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { $payment_source = $this->payment_source_factory->from_wc_order( $wc_order, $birth_date ); try { - $order = $this->order_endpoint->create( array( $purchase_unit ), $payment_source ); + $order = $this->order_endpoint->create( array( $purchase_unit ), $payment_source, $wc_order ); $this->add_paypal_meta( $wc_order, $order, $this->environment ); as_schedule_single_action(