PluginProbe
Tiered Pricing Table for WooCommerce / 6.1.0
Tiered Pricing Table for WooCommerce v6.1.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.1.0, at src/Addons/ManualOrders/ManualOrdersAddon.php

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