PluginProbe
Tiered Pricing Table for WooCommerce / 8.0.2
Tiered Pricing Table for WooCommerce v8.0.2
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
← All changes | src/Addons/ManualOrders/ManualOrdersAddon.php +67 -53 6.4.0 → 8.0.2 View file →
@@ -7,68 +7,77 @@
7 7 use WC_Order_Item;
8 8 use WC_Order_Item_Product;
9 9
10 10 class ManualOrdersAddon extends AbstractAddon {
11 -
11 +
12 12 protected $items = array();
13 -
13 +
14 14 public function getName(): string {
15 15 return __( 'Tiered pricing for manual orders', 'tier-pricing-table' );
16 16 }
17 -
17 +
18 18 public function getDescription(): string {
19 19 return __( 'Apply tiered pricing to orders created manually in the admin area.', 'tier-pricing-table' );
20 20 }
21 -
21 +
22 22 public function getIcon(): string {
23 23 return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 14H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></svg>';
24 24 }
25 -
25 +
26 26 public function getSlug(): string {
27 27 return 'manual-orders';
28 28 }
29 -
29 +
30 30 public function getItemPrice( WC_Order_Item_Product $item ) {
31 - $productPrice = $item->get_product()->get_price();
32 - $tieredPricingRule = PriceManager::getPricingRule( $item->get_product()->get_id() );
33 -
31 + $product = $item->get_product();
32 +
33 + // Product (or its variation) may have been deleted after the order was created.
34 + if ( ! $product ) {
35 + $quantity = $item->get_quantity();
36 +
37 + return $quantity ? ( (float) $item->get_total() / $quantity ) : (float) $item->get_total();
38 + }
39 +
40 + $productPrice = $product->get_price();
41 + $tieredPricingRule = PriceManager::getPricingRule( $product->get_id() );
42 +
34 43 // Item has no tiered pricing rule. Return regular price (which also can be adjusted by pricing rule, but on the get_price hook)
35 44 if ( ! $tieredPricingRule->getRules() ) {
36 45 return $productPrice;
37 46 }
38 -
47 +
39 48 $tieredPrice = $tieredPricingRule->getTierPrice( $this->getTotalItemQuantity( $item ), false );
40 -
41 - return $tieredPrice ? $tieredPrice : $productPrice;
49 +
50 + return false !== $tieredPrice ? $tieredPrice : $productPrice;
42 51 }
43 -
52 +
44 53 public function getTotalItemQuantity( WC_Order_Item_Product $baseItem ): int {
45 -
54 +
46 55 $quantity = $baseItem->get_quantity();
47 -
56 +
48 57 $orderItems = $baseItem->get_order()->get_items();
49 -
58 +
50 59 if ( empty( $orderItems ) || count( $orderItems ) < 2 ) {
51 60 return $quantity;
52 61 }
53 -
62 +
54 63 $calculatedItems = [ $baseItem->get_id() ];
55 -
64 +
56 65 // Consider different variations
57 66 if ( CalculationLogic::considerProductVariationAsOneProduct() ) {
58 67 foreach ( $orderItems as $item ) {
59 -
68 +
60 69 /**
61 70 * Item type
62 71 *
63 72 * @var WC_Order_Item_Product $item
64 73 */
65 -
74 +
66 75 // Item quantity is already calculated
67 76 if ( in_array( $item->get_id(), $calculatedItems ) ) {
68 77 continue;
69 78 }
70 -
79 +
71 80 if ( $item->get_product_id() === $baseItem->get_product_id() ) {
72 81 $quantity += $item->get_quantity();
73 82 $calculatedItems[] = $item->get_id();
74 83 }
@@ -73,92 +82,97 @@
73 82 $calculatedItems[] = $item->get_id();
74 83 }
75 84 }
76 85 }
77 -
86 +
78 87 $baseItemPricingRule = PriceManager::getPricingRule( $baseItem->get_product_id() );
79 -
88 +
80 89 if ( 'global-rules' !== $baseItemPricingRule->provider ) {
81 90 return $quantity;
82 91 }
83 -
92 +
84 93 if ( empty( $baseItemPricingRule->providerData['applying_type'] ) || 'cross' !== $baseItemPricingRule->providerData['applying_type'] ) {
85 94 return $baseItem->get_quantity();
86 95 }
87 -
96 +
88 97 foreach ( $orderItems as $item ) {
89 -
98 +
90 99 // Item quantity is already calculated
91 100 if ( in_array( $item->get_id(), $calculatedItems ) ) {
92 101 continue;
93 102 }
94 -
103 +
95 104 $pricingRule = PriceManager::getPricingRule( $item->get_product_id() );
96 -
105 +
97 106 if ( 'global-rules' !== $pricingRule->provider ) {
98 107 continue;
99 108 }
100 -
109 +
101 110 if ( empty( $pricingRule->providerData['rule_id'] ) || $pricingRule->providerData['rule_id'] !== $baseItemPricingRule->providerData['rule_id'] ) {
102 111 continue;
103 112 }
104 -
113 +
105 114 $quantity += $item->get_quantity();
106 115 }
107 -
116 +
108 117 return $quantity;
109 118 }
110 -
119 +
111 120 public function run() {
112 -
121 +
113 122 // Store items before calculating
114 123 add_action( 'woocommerce_before_save_order_items', function ( $orderId, $items ) {
115 124 $this->items[ $orderId ] = $items;
116 125 }, 10, 2 );
117 -
126 +
118 127 add_action( 'woocommerce_before_save_order_item', function ( WC_Order_Item $item ) {
119 -
128 +
120 129 if ( ! ( $item instanceof WC_Order_Item_Product ) ) {
121 130 return;
122 131 }
123 -
132 +
133 + if ( ! apply_filters( 'tiered_pricing_table/manual_created_orders/modify_item_price', true, $item ) ) {
134 + return;
135 + }
136 +
124 137 // Need to be calculated with tiered pricing
125 138 if ( ! empty( $this->items[ $item->get_order_id() ]['calculate_tiered_pricing'] ) ) {
126 -
139 +
127 140 $GLOBALS['tpt_current_user_id'] = $item->get_order()->get_customer_id();
128 -
141 +
129 142 $itemPrice = $this->getItemPrice( $item );
130 -
143 +
131 144 $product = $item->get_product() ? $item->get_product() : false;
132 -
145 +
133 146 if ( ! $product ) {
134 147 return;
135 148 }
136 -
149 +
137 150 $itemTotal = wc_get_price_excluding_tax( $product, array(
138 - 'price' => $itemPrice,
139 - 'qty' => $item->get_quantity(),
151 + 'price' => $itemPrice,
152 + 'qty' => $item->get_quantity(),
140 153 ) );
141 -
154 +
142 155 // Nothing to change
143 156 if ( ( float ) $item->get_total() === $itemTotal ) {
144 157 return;
145 158 }
146 -
159 +
147 160 // translators: %1$s: item name, %2$s: original price, %3$s: new price
148 161 $note = sprintf( __( 'Tiered pricing recalculations for %1$s: %2$s → %3$s', 'tier-pricing-table' ),
149 - $item->get_name(), wc_price( $item->get_total() / $item->get_quantity() ), wc_price( $itemPrice ) );
150 -
162 + $item->get_name(), wc_price( $item->get_total() / $item->get_quantity() ),
163 + wc_price( $itemPrice ) );
164 +
151 165 $item->set_subtotal( $itemTotal );
152 166 $item->set_total( $itemTotal );
153 -
167 +
154 168 $item->calculate_taxes();
155 -
169 +
156 170 $item->get_order()->add_order_note( $note );
157 171 }
158 -
172 +
159 173 }, 10, 2 );
160 -
174 +
161 175 add_action( 'woocommerce_admin_order_items_after_line_items', function () {
162 176 ?>
163 177 <tr style="display: none;">
164 178 <td>
@@ -166,9 +180,9 @@
166 180 </td>
167 181 </tr>
168 182 <?php
169 183 } );
170 -
184 +
171 185 add_action( 'admin_head', function () {
172 186 ?>
173 187 <script>
174 188 jQuery(document).ready(function ($) {
@@ -184,9 +198,9 @@
184 198 });
185 199 </script>
186 200 <?php
187 201 } );
188 -
202 +
189 203 add_action( 'woocommerce_order_item_add_action_buttons', function ( WC_Order $order ) {
190 204 if ( $order->is_editable() ) {
191 205 ?>
192 206 <button type="button" class="button button-primary calculate-tiered-pricing">