PluginProbe
Tiered Pricing Table for WooCommerce / 6.5.0
Tiered Pricing Table for WooCommerce v6.5.0
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
tier-pricing-table / src / Addons / ManualOrders / ManualOrdersAddon.php

ManualOrdersAddon.php in Tiered Pricing Table for WooCommerce 6.5.0, at src/Addons/ManualOrders/ManualOrdersAddon.php

200 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php namespace TierPricingTable\Addons\ManualOrders;
2
3 use TierPricingTable\Addons\AbstractAddon;
4 use TierPricingTable\CalculationLogic;
5 use TierPricingTable\PriceManager;
6 use WC_Order;
7 use WC_Order_Item;
8 use WC_Order_Item_Product;
9
10 class ManualOrdersAddon extends AbstractAddon {
11
12 protected $items = array();
13
14 public function getName(): string {
15 return __( 'Tiered pricing for manual orders', 'tier-pricing-table' );
16 }
17
18 public function getDescription(): string {
19 return __( 'Apply tiered pricing to orders created manually in the admin area.', 'tier-pricing-table' );
20 }
21
22 public function getIcon(): string {
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 }
25
26 public function getSlug(): string {
27 return 'manual-orders';
28 }
29
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
34 // Item has no tiered pricing rule. Return regular price (which also can be adjusted by pricing rule, but on the get_price hook)
35 if ( ! $tieredPricingRule->getRules() ) {
36 return $productPrice;
37 }
38
39 $tieredPrice = $tieredPricingRule->getTierPrice( $this->getTotalItemQuantity( $item ), false );
40
41 return $tieredPrice ? $tieredPrice : $productPrice;
42 }
43
44 public function getTotalItemQuantity( WC_Order_Item_Product $baseItem ): int {
45
46 $quantity = $baseItem->get_quantity();
47
48 $orderItems = $baseItem->get_order()->get_items();
49
50 if ( empty( $orderItems ) || count( $orderItems ) < 2 ) {
51 return $quantity;
52 }
53
54 $calculatedItems = [ $baseItem->get_id() ];
55
56 // Consider different variations
57 if ( CalculationLogic::considerProductVariationAsOneProduct() ) {
58 foreach ( $orderItems as $item ) {
59
60 /**
61 * Item type
62 *
63 * @var WC_Order_Item_Product $item
64 */
65
66 // Item quantity is already calculated
67 if ( in_array( $item->get_id(), $calculatedItems ) ) {
68 continue;
69 }
70
71 if ( $item->get_product_id() === $baseItem->get_product_id() ) {
72 $quantity += $item->get_quantity();
73 $calculatedItems[] = $item->get_id();
74 }
75 }
76 }
77
78 $baseItemPricingRule = PriceManager::getPricingRule( $baseItem->get_product_id() );
79
80 if ( 'global-rules' !== $baseItemPricingRule->provider ) {
81 return $quantity;
82 }
83
84 if ( empty( $baseItemPricingRule->providerData['applying_type'] ) || 'cross' !== $baseItemPricingRule->providerData['applying_type'] ) {
85 return $baseItem->get_quantity();
86 }
87
88 foreach ( $orderItems as $item ) {
89
90 // Item quantity is already calculated
91 if ( in_array( $item->get_id(), $calculatedItems ) ) {
92 continue;
93 }
94
95 $pricingRule = PriceManager::getPricingRule( $item->get_product_id() );
96
97 if ( 'global-rules' !== $pricingRule->provider ) {
98 continue;
99 }
100
101 if ( empty( $pricingRule->providerData['rule_id'] ) || $pricingRule->providerData['rule_id'] !== $baseItemPricingRule->providerData['rule_id'] ) {
102 continue;
103 }
104
105 $quantity += $item->get_quantity();
106 }
107
108 return $quantity;
109 }
110
111 public function run() {
112
113 // Store items before calculating
114 add_action( 'woocommerce_before_save_order_items', function ( $orderId, $items ) {
115 $this->items[ $orderId ] = $items;
116 }, 10, 2 );
117
118 add_action( 'woocommerce_before_save_order_item', function ( WC_Order_Item $item ) {
119
120 if ( ! ( $item instanceof WC_Order_Item_Product ) ) {
121 return;
122 }
123
124 // Need to be calculated with tiered pricing
125 if ( ! empty( $this->items[ $item->get_order_id() ]['calculate_tiered_pricing'] ) ) {
126
127 $GLOBALS['tpt_current_user_id'] = $item->get_order()->get_customer_id();
128
129 $itemPrice = $this->getItemPrice( $item );
130
131 $product = $item->get_product() ? $item->get_product() : false;
132
133 if ( ! $product ) {
134 return;
135 }
136
137 $itemTotal = wc_get_price_excluding_tax( $product, array(
138 'price' => $itemPrice,
139 'qty' => $item->get_quantity(),
140 ) );
141
142 // Nothing to change
143 if ( ( float ) $item->get_total() === $itemTotal ) {
144 return;
145 }
146
147 // translators: %1$s: item name, %2$s: original price, %3$s: new price
148 $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
151 $item->set_subtotal( $itemTotal );
152 $item->set_total( $itemTotal );
153
154 $item->calculate_taxes();
155
156 $item->get_order()->add_order_note( $note );
157 }
158
159 }, 10, 2 );
160
161 add_action( 'woocommerce_admin_order_items_after_line_items', function () {
162 ?>
163 <tr style="display: none;">
164 <td>
165 <input type="checkbox" name="calculate_tiered_pricing">
166 </td>
167 </tr>
168 <?php
169 } );
170
171 add_action( 'admin_head', function () {
172 ?>
173 <script>
174 jQuery(document).ready(function ($) {
175 $('#woocommerce-order-items').on('click', '.calculate-tiered-pricing', function () {
176 jQuery('[name=calculate_tiered_pricing]').prop('checked', true);
177
178 jQuery('#woocommerce-order-items button.calculate-action').trigger('click');
179 });
180 });
181
182 jQuery(document.body).on('order-totals-recalculate-complete', function () {
183 jQuery('[name=calculate_tiered_pricing]').prop('checked', false);
184 });
185 </script>
186 <?php
187 } );
188
189 add_action( 'woocommerce_order_item_add_action_buttons', function ( WC_Order $order ) {
190 if ( $order->is_editable() ) {
191 ?>
192 <button type="button" class="button button-primary calculate-tiered-pricing">
193 <?php esc_html_e( 'Re-calculate with tiered pricing', 'tier-pricing-table' ); ?>
194 </button>
195 <?php
196 }
197 } );
198 }
199 }
200