WooCommerceDeposits.php
4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php
/**
* Class WooCommerceDeposits
*
* @package WCPay\MultiCurrency\Compatibility
*/
namespace WCPay\MultiCurrency\Compatibility;
use WC_Product;
use WCPay\MultiCurrency\MultiCurrency;
/**
* Class that controls Multi Currency Compatibility with WooCommerce Deposits Plugin.
*/
class WooCommerceDeposits extends BaseCompatibility {
/**
* Init the class.
*
* @return void
*/
protected function init() {
if ( class_exists( 'WC_Deposits' ) ) {
// Add compatibility filters here.
add_action( 'woocommerce_deposits_create_order', [ $this, 'modify_order_currency' ] );
add_filter( 'woocommerce_get_cart_contents', [ $this, 'modify_cart_item_deposit_amounts' ] );
add_filter( 'woocommerce_product_get__wc_deposit_amount', [ $this, 'modify_cart_item_deposit_amount_meta' ], 10, 2 );
add_filter( MultiCurrency::FILTER_PREFIX . 'should_convert_product_price', [ $this, 'maybe_convert_product_prices_for_deposits' ], 10, 2 );
}
}
/**
* Converts the currency for deposit amounts of each cart item, only applies if deposits are enabled on the product.
*
* @param array $cart_contents The items on the cart.
*
* @return array
*/
public function modify_cart_item_deposit_amounts( $cart_contents ) {
foreach ( $cart_contents as $cart_item_key => $cart_item ) {
if ( ! empty( $cart_item['is_deposit'] ) && isset( $cart_item['deposit_amount'] ) ) {
$deposit_amount = (float) $cart_item['deposit_amount'];
$cart_contents[ $cart_item_key ]['deposit_amount'] = $this->multi_currency->get_price( $deposit_amount, 'product' );
}
}
return $cart_contents;
}
/**
* Converts the currency for deposit amounts of each cart item, only applies if deposits are enabled on the product.
*
* @param float $amount The amount to convert.
* @param \WC_Product $product The product to check for.
*
* @return float
*/
public function modify_cart_item_deposit_amount_meta( $amount, $product ) {
if ( 'percent' === $this->get_product_deposit_type( $product ) && $this->utils->is_call_in_backtrace( [ 'WC_Deposits_Cart_Manager->deposits_form_output' ] ) ) {
return $this->multi_currency->get_price( $amount, 'product' );
}
return $amount;
}
/**
* Defines if the product prices need to be converted when calculating totals,
* if the product's deposit type is a payment plan, then it shouldn't convert it.
*
* @param bool $result The previous flag for converting the price.
* @param \WC_Product $product The product to check for.
*
* @return bool Whether the price should be converted or not.
*/
public function maybe_convert_product_prices_for_deposits( $result, $product ) {
if ( 'plan' === $this->get_product_deposit_type( $product ) && $this->utils->is_call_in_backtrace( [ 'WC_Cart->calculate_totals' ] ) ) {
return false;
}
return $result;
}
/**
* When creating a new order for the remaining amount, forces the new order currency
* to be the same with the deposited order currency.
*
* @param integer $order_id The created order ID.
*
* @return void
*/
public function modify_order_currency( $order_id ) {
// We need to get the original order from the first item meta.
$order = wc_get_order( $order_id );
$order_items = $order->get_items();
$first_order_item = 0 < count( $order_items ) ? reset( $order_items ) : null;
if ( ! $first_order_item ) {
return;
}
// Check if the original order ID is attached to the order item.
$original_order_id = wc_get_order_item_meta( $first_order_item->get_id(), '_original_order_id', true );
if ( ! $original_order_id ) {
return;
}
// Check if the original order still exists.
$original_order = wc_get_order( $original_order_id );
if ( ! $original_order ) {
return;
}
// Get the new and old order currencies, and match them if unmatched.
$saved_currency = $order->get_currency( 'view' );
$original_currency = $original_order->get_currency( 'view' );
if ( $saved_currency !== $original_currency ) {
$order->set_currency( $original_currency );
$order->save();
}
}
/**
* Gets the deposit type of a product if deposits are enabled for the product.
*
* @param \WC_Product $product The product to check.
*
* @return string|false The product deposit type if deposits are enabled on it, or false.
*/
private function get_product_deposit_type( $product ) {
$product_has_deposit = class_exists( 'WC_Deposits_Product_Manager' ) && call_user_func( [ 'WC_Deposits_Product_Manager', 'deposits_enabled' ], $product );
if ( $product_has_deposit ) {
return call_user_func( [ 'WC_Deposits_Product_Manager', 'get_deposit_type' ], $product );
}
return false;
}
}