PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.4
WooCommerce v10.9.4
10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / assets / js / admin / meta-boxes-order.js
woocommerce / assets / js / admin Last commit date
api-keys.js 5 years ago api-keys.min.js 2 years ago backbone-modal.js 2 years ago backbone-modal.min.js 2 years ago marketplace-suggestions.js 10 months ago marketplace-suggestions.min.js 10 months ago meta-boxes-coupon.js 1 year ago meta-boxes-coupon.min.js 1 year ago meta-boxes-order.js 1 month ago meta-boxes-order.min.js 1 month ago meta-boxes-product-variation.js 1 year ago meta-boxes-product-variation.min.js 1 year ago meta-boxes-product.js 1 month ago meta-boxes-product.min.js 1 month ago meta-boxes.js 4 months ago meta-boxes.min.js 4 months ago network-orders.js 8 years ago network-orders.min.js 2 years ago order-attribution-admin.js 2 years ago order-attribution-admin.min.js 2 years ago product-editor.js 11 months ago product-editor.min.js 11 months ago product-ordering.js 3 months ago product-ordering.min.js 3 months ago quick-edit.js 1 year ago quick-edit.min.js 1 year ago reports.js 1 year ago reports.min.js 1 year ago settings-views-html-settings-tax.js 1 year ago settings-views-html-settings-tax.min.js 1 year ago settings.js 1 year ago settings.min.js 1 year ago system-status.js 3 months ago system-status.min.js 3 months ago term-ordering.js 3 months ago term-ordering.min.js 3 months ago users.js 5 years ago users.min.js 2 years ago variation-gallery.js 1 month ago variation-gallery.min.js 1 month ago wc-brands-enhanced-select.js 1 year ago wc-brands-enhanced-select.min.js 1 year ago wc-clipboard.js 5 years ago wc-clipboard.min.js 5 years ago wc-customer-stock-notifications.js 10 months ago wc-customer-stock-notifications.min.js 10 months ago wc-enhanced-select.js 2 years ago wc-enhanced-select.min.js 2 years ago wc-orders.js 3 years ago wc-orders.min.js 2 years ago wc-product-export.js 1 year ago wc-product-export.min.js 1 year ago wc-product-import.js 3 years ago wc-product-import.min.js 2 years ago wc-recent-reviews-widget-async.js 4 months ago wc-recent-reviews-widget-async.min.js 4 months ago wc-setup.js 5 years ago wc-setup.min.js 2 years ago wc-shipping-classes.js 1 year ago wc-shipping-classes.min.js 1 year ago wc-shipping-providers.js 3 months ago wc-shipping-providers.min.js 3 months ago wc-shipping-zone-methods.js 5 months ago wc-shipping-zone-methods.min.js 5 months ago wc-shipping-zones.js 1 year ago wc-shipping-zones.min.js 1 year ago wc-status-widget-async.js 4 months ago wc-status-widget-async.min.js 4 months ago wc-status-widget.js 1 year ago wc-status-widget.min.js 1 year ago woocommerce_admin.js 1 month ago woocommerce_admin.min.js 1 month ago
meta-boxes-order.js
1789 lines
1 // eslint-disable-next-line max-len
2 /*global woocommerce_admin_meta_boxes, woocommerce_admin, accounting, woocommerce_admin_meta_boxes_order, wcSetClipboard, wcClearClipboard, wc_enhanced_select_params */
3 jQuery( function ( $ ) {
4
5 // Stand-in wcTracks.recordEvent in case tracks is not available (for any reason).
6 window.wcTracks = window.wcTracks || {};
7 window.wcTracks.recordEvent = window.wcTracks.recordEvent || function() { };
8
9 /**
10 * Order Data Panel
11 */
12 var wc_meta_boxes_order = {
13 states: null,
14 init: function() {
15 if (
16 ! (
17 typeof woocommerce_admin_meta_boxes_order === 'undefined' ||
18 typeof woocommerce_admin_meta_boxes_order.countries === 'undefined'
19 )
20 ) {
21 /* State/Country select boxes */
22 this.states = JSON.parse( woocommerce_admin_meta_boxes_order.countries.replace( /"/g, '"' ) );
23 }
24
25 $( '.js_field-country' ).selectWoo().on( 'change', this.change_country );
26 $( '.js_field-country' ).trigger( 'change', [ true ] );
27 $( document.body ).on( 'change', 'select.js_field-state', this.change_state );
28 $( '#woocommerce-order-actions input, #woocommerce-order-actions a' ).on( 'click', function() {
29 window.onbeforeunload = '';
30 });
31 $( 'a.edit_address' ).on( 'click', this.edit_address );
32 $( 'a.billing-same-as-shipping' ).on( 'click', this.copy_billing_to_shipping );
33 $( 'a.load_customer_billing' ).on( 'click', this.load_billing );
34 $( 'a.load_customer_shipping' ).on( 'click', this.load_shipping );
35 $( '#customer_user' ).on( 'change', this.change_customer_user );
36 },
37
38 change_country: function( e, stickValue ) {
39 // Check for stickValue before using it
40 if ( typeof stickValue === 'undefined' ){
41 stickValue = false;
42 }
43
44 // Prevent if we don't have the metabox data
45 if ( wc_meta_boxes_order.states === null ){
46 return;
47 }
48
49 var $this = $( this ),
50 country = $this.val(),
51 $state = $this.parents( 'div.edit_address' ).find( ':input.js_field-state' ),
52 $parent = $state.parent(),
53 stateValue = $state.val(),
54 input_name = $state.attr( 'name' ),
55 input_id = $state.attr( 'id' ),
56 value = $this.data( 'woocommerce.stickState-' + country ) ? $this.data( 'woocommerce.stickState-' + country ) : stateValue,
57 placeholder = $state.attr( 'placeholder' ),
58 $newstate;
59
60 if ( stickValue ){
61 $this.data( 'woocommerce.stickState-' + country, value );
62 }
63
64 // Remove the previous DOM element
65 $parent.show().find( '.select2-container' ).remove();
66
67 if ( ! $.isEmptyObject( wc_meta_boxes_order.states[ country ] ) ) {
68 var state = wc_meta_boxes_order.states[ country ],
69 $defaultOption = $( '<option value=""></option>' )
70 .text( woocommerce_admin_meta_boxes_order.i18n_select_state_text );
71
72 $newstate = $( '<select></select>' )
73 .prop( 'id', input_id )
74 .prop( 'name', input_name )
75 .prop( 'placeholder', placeholder )
76 .addClass( 'js_field-state select short' )
77 .append( $defaultOption );
78
79 $.each( state, function( index ) {
80 var $option = $( '<option></option>' )
81 .prop( 'value', index )
82 .text( state[ index ] );
83 if ( index === stateValue ) {
84 $option.prop( 'selected' );
85 }
86 $newstate.append( $option );
87 } );
88
89 $newstate.val( value );
90
91 $state.replaceWith( $newstate );
92
93 $newstate.show().selectWoo().hide().trigger( 'change' );
94 } else {
95 $newstate = $( '<input type="text" />' )
96 .prop( 'id', input_id )
97 .prop( 'name', input_name )
98 .prop( 'placeholder', placeholder )
99 .addClass( 'js_field-state' )
100 .val( stateValue );
101 $state.replaceWith( $newstate );
102 }
103
104 // This event has a typo - deprecated in 2.5.0
105 $( document.body ).trigger( 'contry-change.woocommerce', [country, $( this ).closest( 'div' )] );
106 $( document.body ).trigger( 'country-change.woocommerce', [country, $( this ).closest( 'div' )] );
107 },
108
109 change_state: function() {
110 // Here we will find if state value on a select has changed and stick it to the country data
111 var $this = $( this ),
112 state = $this.val(),
113 $country = $this.parents( 'div.edit_address' ).find( ':input.js_field-country' ),
114 country = $country.val();
115
116 $country.data( 'woocommerce.stickState-' + country, state );
117 },
118
119 init_tiptip: function() {
120 $( '#tiptip_holder' ).removeAttr( 'style' );
121 $( '#tiptip_arrow' ).removeAttr( 'style' );
122 $( '.tips' ).tipTip({
123 'attribute': 'data-tip',
124 'fadeIn': 50,
125 'fadeOut': 50,
126 'delay': 200,
127 'keepAlive': true
128 });
129 },
130
131 edit_address: function( e ) {
132 e.preventDefault();
133
134 var $this = $( this ),
135 $wrapper = $this.closest( '.order_data_column' ),
136 $edit_address = $wrapper.find( 'div.edit_address' ),
137 $address = $wrapper.find( 'div.address' ),
138 $country_input = $edit_address.find( '.js_field-country' ),
139 $state_input = $edit_address.find( '.js_field-state' ),
140 is_billing = Boolean( $edit_address.find( 'input[name^="_billing_"]' ).length );
141
142 $address.hide();
143 $this.parent().find( 'a' ).toggle();
144
145 if ( ! $country_input.val() ) {
146 $country_input.val( woocommerce_admin_meta_boxes_order.default_country ).trigger( 'change' );
147 $state_input.val( woocommerce_admin_meta_boxes_order.default_state ).trigger( 'change' );
148 }
149
150 $edit_address.show();
151
152 var event_name = is_billing ? 'order_edit_billing_address_click' : 'order_edit_shipping_address_click';
153 window.wcTracks.recordEvent( event_name, {
154 order_id: woocommerce_admin_meta_boxes.post_id,
155 status: $( '#order_status' ).val()
156 } );
157 },
158
159 change_customer_user: function() {
160 if ( ! $( '#_billing_country' ).val() ) {
161 $( 'a.edit_address' ).trigger( 'click' );
162 wc_meta_boxes_order.load_billing( true );
163 wc_meta_boxes_order.load_shipping( true );
164 }
165 },
166
167 load_billing: function( force ) {
168 if ( true === force || window.confirm( woocommerce_admin_meta_boxes.load_billing ) ) {
169
170 // Get user ID to load data for
171 var user_id = $( '#customer_user' ).val();
172
173 if ( ! user_id ) {
174 window.alert( woocommerce_admin_meta_boxes.no_customer_selected );
175 return false;
176 }
177
178 var data = {
179 user_id : user_id,
180 action : 'woocommerce_get_customer_details',
181 security: woocommerce_admin_meta_boxes.get_customer_details_nonce
182 };
183
184 $( this ).closest( 'div.edit_address' ).block({
185 message: null,
186 overlayCSS: {
187 background: '#fff',
188 opacity: 0.6
189 }
190 });
191
192 $.ajax({
193 url: woocommerce_admin_meta_boxes.ajax_url,
194 data: data,
195 type: 'POST',
196 success: function( response ) {
197 if ( response && response.billing ) {
198 $.each( response.billing, function( key, data ) {
199 $( ':input#_billing_' + key ).val( data ).trigger( 'change' );
200 });
201 }
202 $( 'div.edit_address' ).unblock();
203 }
204 });
205 }
206 return false;
207 },
208
209 load_shipping: function( force ) {
210 if ( true === force || window.confirm( woocommerce_admin_meta_boxes.load_shipping ) ) {
211
212 // Get user ID to load data for
213 var user_id = $( '#customer_user' ).val();
214
215 if ( ! user_id ) {
216 window.alert( woocommerce_admin_meta_boxes.no_customer_selected );
217 return false;
218 }
219
220 var data = {
221 user_id: user_id,
222 action: 'woocommerce_get_customer_details',
223 security: woocommerce_admin_meta_boxes.get_customer_details_nonce
224 };
225
226 $( this ).closest( 'div.edit_address' ).block({
227 message: null,
228 overlayCSS: {
229 background: '#fff',
230 opacity: 0.6
231 }
232 });
233
234 $.ajax({
235 url: woocommerce_admin_meta_boxes.ajax_url,
236 data: data,
237 type: 'POST',
238 success: function( response ) {
239 if ( response && response.billing ) {
240 $.each( response.shipping, function( key, data ) {
241 $( ':input#_shipping_' + key ).val( data ).trigger( 'change' );
242 });
243 }
244 $( 'div.edit_address' ).unblock();
245 }
246 });
247 }
248 return false;
249 },
250
251 copy_billing_to_shipping: function() {
252 if ( window.confirm( woocommerce_admin_meta_boxes.copy_billing ) ) {
253 $('.order_data_column :input[name^="_billing_"]').each( function() {
254 var input_name = $(this).attr('name');
255 input_name = input_name.replace( '_billing_', '_shipping_' );
256 $( ':input#' + input_name ).val( $(this).val() ).trigger( 'change' );
257 });
258 }
259 return false;
260 }
261 };
262
263 /**
264 * Order Items Panel
265 */
266 var wc_meta_boxes_order_items = {
267 init: function() {
268 this.stupidtable.init();
269
270 $( '#woocommerce-order-items' )
271 .on( 'click', 'button.add-line-item', this.add_line_item )
272 .on( 'click', 'button.add-coupon', this.add_coupon )
273 .on( 'click', 'a.remove-coupon', this.remove_coupon )
274 .on( 'click', 'button.refund-items', this.refund_items )
275 .on( 'click', '.cancel-action', this.cancel )
276 .on( 'click', '.refund-actions .cancel-action', this.track_cancel )
277 .on( 'click', 'button.add-order-item', this.add_item )
278 .on( 'click', 'button.add-order-fee', this.add_fee )
279 .on( 'click', 'button.add-order-shipping', this.add_shipping )
280 .on( 'click', 'button.add-order-tax', this.add_tax )
281 .on( 'click', 'button.save-action', this.save_line_items )
282 .on( 'click', 'a.delete-order-tax', this.delete_tax )
283 .on( 'click', 'button.calculate-action', this.recalculate )
284 .on( 'click', 'a.edit-order-item', this.edit_item )
285 .on( 'click', 'a.delete-order-item', this.delete_item )
286
287 // Refunds
288 .on( 'click', '.delete_refund', this.refunds.delete_refund )
289 .on( 'click', 'button.do-api-refund, button.do-manual-refund', this.refunds.do_refund )
290 .on( 'change', '.refund input.refund_line_total, .refund input.refund_line_tax', this.refunds.input_changed )
291 .on( 'change keyup', '.wc-order-refund-items #refund_amount', this.refunds.amount_changed )
292 .on( 'change', 'input.refund_order_item_qty', this.refunds.refund_quantity_changed )
293
294 // Qty
295 .on( 'change', 'input.quantity', this.quantity_changed )
296
297 // Subtotal/total
298 .on( 'keyup change', '.split-input :input', function() {
299 var $subtotal = $( this ).parent().prev().find(':input');
300 if ( $subtotal && ( $subtotal.val() === '' || $subtotal.is( '.match-total' ) ) ) {
301 $subtotal.val( $( this ).val() ).addClass( 'match-total' );
302 }
303 })
304
305 .on( 'keyup', '.split-input :input', function() {
306 $( this ).removeClass( 'match-total' );
307 })
308
309 // Meta
310 .on( 'click', 'button.add_order_item_meta', this.item_meta.add )
311 .on( 'click', 'button.remove_order_item_meta', this.item_meta.remove )
312
313 // Reload items
314 .on( 'wc_order_items_reload', this.reload_items )
315 .on( 'wc_order_items_reloaded', this.reloaded_items );
316
317 $( document.body )
318 .on( 'wc_backbone_modal_loaded', this.backbone.init )
319 .on( 'wc_backbone_modal_response', this.backbone.response );
320 },
321
322 block: function() {
323 $( '#woocommerce-order-items' ).block({
324 message: null,
325 overlayCSS: {
326 background: '#fff',
327 opacity: 0.6
328 }
329 });
330 },
331
332 unblock: function() {
333 $( '#woocommerce-order-items' ).unblock();
334 },
335
336 filter_data: function( handle, data ) {
337 const filteredData = $( '#woocommerce-order-items' )
338 .triggerHandler(
339 `woocommerce_order_meta_box_${handle}_ajax_data`,
340 [ data ]
341 );
342
343 if ( filteredData ) {
344 return filteredData;
345 }
346
347 return data;
348 },
349
350 reload_items: function() {
351 var data = {
352 order_id: woocommerce_admin_meta_boxes.post_id,
353 action: 'woocommerce_load_order_items',
354 security: woocommerce_admin_meta_boxes.order_item_nonce
355 };
356
357 data = wc_meta_boxes_order_items.filter_data( 'reload_items', data );
358
359 wc_meta_boxes_order_items.block();
360
361 $.ajax({
362 url: woocommerce_admin_meta_boxes.ajax_url,
363 data: data,
364 type: 'POST',
365 success: function( response ) {
366 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
367 $( '#woocommerce-order-items' ).find( '.inside' ).append( response );
368 wc_meta_boxes_order_items.reloaded_items();
369 wc_meta_boxes_order_items.unblock();
370 }
371 });
372 },
373
374 reloaded_items: function() {
375 wc_meta_boxes_order.init_tiptip();
376 wc_meta_boxes_order_items.stupidtable.init();
377 },
378
379 // When the qty is changed, increase or decrease costs
380 quantity_changed: function() {
381 var $row = $( this ).closest( 'tr.item' );
382 var qty = $( this ).val();
383 var o_qty = $( this ).attr( 'data-qty' );
384 var line_total = $( 'input.line_total', $row );
385 var line_subtotal = $( 'input.line_subtotal', $row );
386
387 // Totals
388 var unit_total = accounting.unformat( line_total.attr( 'data-total' ), woocommerce_admin.mon_decimal_point ) / o_qty;
389 line_total.val(
390 parseFloat( accounting.formatNumber( unit_total * qty, woocommerce_admin_meta_boxes.rounding_precision, '' ) )
391 .toString()
392 .replace( '.', woocommerce_admin.mon_decimal_point )
393 );
394
395 var unit_subtotal = accounting.unformat( line_subtotal.attr( 'data-subtotal' ), woocommerce_admin.mon_decimal_point ) / o_qty;
396 line_subtotal.val(
397 parseFloat( accounting.formatNumber( unit_subtotal * qty, woocommerce_admin_meta_boxes.rounding_precision, '' ) )
398 .toString()
399 .replace( '.', woocommerce_admin.mon_decimal_point )
400 );
401
402 // Taxes
403 $( 'input.line_tax', $row ).each( function() {
404 var $line_total_tax = $( this );
405 var tax_id = $line_total_tax.data( 'tax_id' );
406 var unit_total_tax = accounting.unformat(
407 $line_total_tax.attr( 'data-total_tax' ),
408 woocommerce_admin.mon_decimal_point
409 ) / o_qty;
410 var $line_subtotal_tax = $( 'input.line_subtotal_tax[data-tax_id="' + tax_id + '"]', $row );
411 var unit_subtotal_tax = accounting.unformat(
412 $line_subtotal_tax.attr( 'data-subtotal_tax' ),
413 woocommerce_admin.mon_decimal_point
414 ) / o_qty;
415
416 if ( 0 < unit_total_tax ) {
417 $line_total_tax.val(
418 parseFloat( accounting.formatNumber( unit_total_tax * qty, woocommerce_admin_meta_boxes.rounding_precision, '' ) )
419 .toString()
420 .replace( '.', woocommerce_admin.mon_decimal_point )
421 );
422 }
423
424 if ( 0 < unit_subtotal_tax ) {
425 $line_subtotal_tax.val(
426 parseFloat( accounting.formatNumber(
427 unit_subtotal_tax * qty,
428 woocommerce_admin_meta_boxes.rounding_precision,
429 ''
430 ) )
431 .toString()
432 .replace( '.', woocommerce_admin.mon_decimal_point )
433 );
434 }
435 });
436
437 $( this ).trigger( 'quantity_changed' );
438 },
439
440 add_line_item: function() {
441 $( 'div.wc-order-add-item' ).slideDown();
442 $( 'div.wc-order-data-row-toggle' ).not( 'div.wc-order-add-item' ).slideUp();
443
444 window.wcTracks.recordEvent( 'order_edit_add_items_click', {
445 order_id: woocommerce_admin_meta_boxes.post_id,
446 status: $( '#order_status' ).val()
447 } );
448
449 return false;
450 },
451
452 add_coupon: function() {
453 window.wcTracks.recordEvent( 'order_edit_add_coupon_click', {
454 order_id: woocommerce_admin_meta_boxes.post_id,
455 status: $( '#order_status' ).val()
456 } );
457
458 var value = window.prompt( woocommerce_admin_meta_boxes.i18n_apply_coupon );
459
460 if ( null == value ) {
461 window.wcTracks.recordEvent( 'order_edit_add_coupon_cancel', {
462 order_id: woocommerce_admin_meta_boxes.post_id,
463 status: $( '#order_status' ).val()
464 } );
465 } else {
466 wc_meta_boxes_order_items.block();
467
468 var user_id = $( '#customer_user' ).val();
469 var user_email = $( '#_billing_email' ).val();
470
471 var data = $.extend( {}, wc_meta_boxes_order_items.get_taxable_address(), {
472 action : 'woocommerce_add_coupon_discount',
473 dataType : 'json',
474 order_id : woocommerce_admin_meta_boxes.post_id,
475 security : woocommerce_admin_meta_boxes.order_item_nonce,
476 coupon : value,
477 user_id : user_id,
478 user_email : user_email
479 } );
480
481 data = wc_meta_boxes_order_items.filter_data( 'add_coupon', data );
482
483 $.ajax( {
484 url: woocommerce_admin_meta_boxes.ajax_url,
485 data: data,
486 type: 'POST',
487 success: function( response ) {
488 if ( response.success ) {
489 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
490 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
491
492 // Update notes.
493 const notesEl = document.querySelector( '#woocommerce-order-notes ul.order_notes' );
494 if ( notesEl && response.data && typeof response.data.notes_html === 'string' ) {
495 notesEl.outerHTML = response.data.notes_html;
496 }
497
498 wc_meta_boxes_order_items.reloaded_items();
499 wc_meta_boxes_order_items.unblock();
500 } else {
501 window.alert( response.data.error );
502 }
503 wc_meta_boxes_order_items.unblock();
504 },
505 complete: function() {
506 window.wcTracks.recordEvent( 'order_edit_added_coupon', {
507 order_id: data.order_id,
508 status: $( '#order_status' ).val()
509 } );
510 }
511 } );
512 }
513 return false;
514 },
515
516 remove_coupon: function() {
517 var $this = $( this );
518 wc_meta_boxes_order_items.block();
519
520 var data = $.extend( {}, wc_meta_boxes_order_items.get_taxable_address(), {
521 action : 'woocommerce_remove_order_coupon',
522 dataType : 'json',
523 order_id : woocommerce_admin_meta_boxes.post_id,
524 security : woocommerce_admin_meta_boxes.order_item_nonce,
525 coupon : $this.data( 'code' )
526 } );
527
528 data = wc_meta_boxes_order_items.filter_data( 'remove_coupon', data );
529
530 $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {
531 if ( response.success ) {
532 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
533 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
534
535 // Update notes.
536 if ( response.data.notes_html ) {
537 $( 'ul.order_notes' ).empty();
538 $( 'ul.order_notes' ).append( $( response.data.notes_html ).find( 'li' ) );
539 }
540
541 wc_meta_boxes_order_items.reloaded_items();
542 wc_meta_boxes_order_items.unblock();
543 } else {
544 window.alert( response.data.error );
545 }
546 wc_meta_boxes_order_items.unblock();
547 });
548 },
549
550 refund_items: function() {
551 $( 'div.wc-order-refund-items' ).slideDown();
552 $( 'div.wc-order-data-row-toggle' ).not( 'div.wc-order-refund-items' ).slideUp();
553 $( 'div.wc-order-totals-items' ).slideUp();
554 $( '#woocommerce-order-items' ).find( 'div.refund' ).show();
555 $( '.wc-order-edit-line-item .wc-order-edit-line-item-actions' ).hide();
556
557 window.wcTracks.recordEvent( 'order_edit_refund_button_click', {
558 order_id: woocommerce_admin_meta_boxes.post_id,
559 status: $( '#order_status' ).val()
560 } );
561
562 return false;
563 },
564
565 cancel: function() {
566 $( 'div.wc-order-data-row-toggle' ).not( 'div.wc-order-bulk-actions' ).slideUp();
567 $( 'div.wc-order-bulk-actions' ).slideDown();
568 $( 'div.wc-order-totals-items' ).slideDown();
569 $( '#woocommerce-order-items' ).find( 'div.refund' ).hide();
570 $( '.wc-order-edit-line-item .wc-order-edit-line-item-actions' ).show();
571
572 // Reload the items
573 if ( 'true' === $( this ).attr( 'data-reload' ) ) {
574 wc_meta_boxes_order_items.reload_items();
575 }
576
577 window.wcTracks.recordEvent( 'order_edit_add_items_cancelled', {
578 order_id: woocommerce_admin_meta_boxes.post_id,
579 status: $( '#order_status' ).val()
580 } );
581
582 return false;
583 },
584
585 track_cancel: function() {
586 window.wcTracks.recordEvent( 'order_edit_refund_cancel', {
587 order_id: woocommerce_admin_meta_boxes.post_id,
588 status: $( '#order_status' ).val()
589 } );
590 },
591
592 add_item: function() {
593 $( this ).WCBackboneModal({
594 template: 'wc-modal-add-products'
595 });
596
597 return false;
598 },
599
600 add_fee: function() {
601 window.wcTracks.recordEvent( 'order_edit_add_fee_click', {
602 order_id: woocommerce_admin_meta_boxes.post_id,
603 status: $( '#order_status' ).val()
604 } );
605
606 var value = window.prompt( woocommerce_admin_meta_boxes.i18n_add_fee );
607
608 if ( null == value ) {
609 window.wcTracks.recordEvent( 'order_edit_add_fee_cancel', {
610 order_id: woocommerce_admin_meta_boxes.post_id,
611 status: $( '#order_status' ).val()
612 } );
613 } else {
614 wc_meta_boxes_order_items.block();
615
616 var data = $.extend( {}, wc_meta_boxes_order_items.get_taxable_address(), {
617 action : 'woocommerce_add_order_fee',
618 dataType: 'json',
619 order_id: woocommerce_admin_meta_boxes.post_id,
620 security: woocommerce_admin_meta_boxes.order_item_nonce,
621 amount : value
622 } );
623
624 data = wc_meta_boxes_order_items.filter_data( 'add_fee', data );
625
626 $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {
627 if ( response.success ) {
628 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
629 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
630 wc_meta_boxes_order_items.reloaded_items();
631 wc_meta_boxes_order_items.unblock();
632 window.wcTracks.recordEvent( 'order_edit_added_fee', {
633 order_id: woocommerce_admin_meta_boxes.post_id,
634 status: $( '#order_status' ).val()
635 } );
636 } else {
637 window.alert( response.data.error );
638 }
639 wc_meta_boxes_order.init_tiptip();
640 wc_meta_boxes_order_items.unblock();
641 });
642 }
643 return false;
644 },
645
646 add_shipping: function() {
647 wc_meta_boxes_order_items.block();
648
649 var data = {
650 action : 'woocommerce_add_order_shipping',
651 order_id : woocommerce_admin_meta_boxes.post_id,
652 security : woocommerce_admin_meta_boxes.order_item_nonce,
653 dataType : 'json'
654 };
655
656 data = wc_meta_boxes_order_items.filter_data( 'add_shipping', data );
657
658 $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {
659 if ( response.success ) {
660 $( 'table.woocommerce_order_items tbody#order_shipping_line_items' ).append( response.data.html );
661 window.wcTracks.recordEvent( 'order_edit_add_shipping', {
662 order_id: woocommerce_admin_meta_boxes.post_id,
663 status: $( '#order_status' ).val()
664 } );
665 } else {
666 window.alert( response.data.error );
667 }
668 wc_meta_boxes_order.init_tiptip();
669 wc_meta_boxes_order_items.unblock();
670 });
671
672 return false;
673 },
674
675 add_tax: function() {
676 $( this ).WCBackboneModal({
677 template: 'wc-modal-add-tax'
678 });
679 return false;
680 },
681
682 edit_item: function() {
683 $( this ).closest( 'tr' ).find( '.view' ).hide();
684 $( this ).closest( 'tr' ).find( '.edit' ).show();
685 $( this ).hide();
686 $( 'button.add-line-item' ).trigger( 'click' );
687 $( 'button.cancel-action' ).attr( 'data-reload', true );
688 window.wcTracks.recordEvent( 'order_edit_edit_item_click', {
689 order_id: woocommerce_admin_meta_boxes.post_id,
690 status: $( '#order_status' ).val()
691 } );
692 return false;
693 },
694
695 delete_item: function() {
696 var notice = woocommerce_admin_meta_boxes.remove_item_notice;
697
698 if ( $( this ).parents( 'tbody#order_fee_line_items' ).length ) {
699 notice = woocommerce_admin_meta_boxes.remove_fee_notice;
700 }
701
702 if ( $( this ).parents( 'tbody#order_shipping_line_items' ).length ) {
703 notice = woocommerce_admin_meta_boxes.remove_shipping_notice;
704 }
705
706 var answer = window.confirm( notice );
707
708 if ( answer ) {
709 var $item = $( this ).closest( 'tr.item, tr.fee, tr.shipping' );
710 var order_item_id = $item.attr( 'data-order_item_id' );
711
712 wc_meta_boxes_order_items.block();
713
714 var data = $.extend( {}, wc_meta_boxes_order_items.get_taxable_address(), {
715 order_id : woocommerce_admin_meta_boxes.post_id,
716 order_item_ids: order_item_id,
717 action : 'woocommerce_remove_order_item',
718 security : woocommerce_admin_meta_boxes.order_item_nonce
719 } );
720
721 // Check if items have changed, if so pass them through so we can save them before deleting.
722 if ( 'true' === $( 'button.cancel-action' ).attr( 'data-reload' ) ) {
723 data.items = $( 'table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]' ).serialize();
724 }
725
726 data = wc_meta_boxes_order_items.filter_data( 'delete_item', data );
727
728 $.ajax({
729 url: woocommerce_admin_meta_boxes.ajax_url,
730 data: data,
731 type: 'POST',
732 success: function( response ) {
733 if ( response.success ) {
734 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
735 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
736
737 // Update notes.
738 const notesEl = document.querySelector( '#woocommerce-order-notes ul.order_notes' );
739 if ( notesEl && response.data && typeof response.data.notes_html === 'string' ) {
740 notesEl.outerHTML = response.data.notes_html;
741 }
742
743 wc_meta_boxes_order_items.reloaded_items();
744 wc_meta_boxes_order_items.unblock();
745 } else {
746 window.alert( response.data.error );
747 }
748 wc_meta_boxes_order_items.unblock();
749 },
750 complete: function() {
751 window.wcTracks.recordEvent( 'order_edit_remove_item', {
752 order_id: woocommerce_admin_meta_boxes.post_id,
753 status: $( '#order_status' ).val()
754 } );
755 }
756 });
757 }
758 return false;
759 },
760
761 delete_tax: function() {
762 if ( window.confirm( woocommerce_admin_meta_boxes.i18n_delete_tax ) ) {
763 wc_meta_boxes_order_items.block();
764
765 var data = {
766 action: 'woocommerce_remove_order_tax',
767 rate_id: $( this ).attr( 'data-rate_id' ),
768 order_id: woocommerce_admin_meta_boxes.post_id,
769 security: woocommerce_admin_meta_boxes.order_item_nonce
770 };
771
772 data = wc_meta_boxes_order_items.filter_data( 'delete_tax', data );
773
774 $.ajax({
775 url: woocommerce_admin_meta_boxes.ajax_url,
776 data: data,
777 type: 'POST',
778 success: function( response ) {
779 if ( response.success ) {
780 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
781 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
782 wc_meta_boxes_order_items.reloaded_items();
783 wc_meta_boxes_order_items.unblock();
784 } else {
785 window.alert( response.data.error );
786 }
787 wc_meta_boxes_order_items.unblock();
788 },
789 complete: function() {
790 window.wcTracks.recordEvent( 'order_edit_delete_tax', {
791 order_id: data.order_id,
792 status: $( '#order_status' ).val()
793 } );
794 }
795 });
796 } else {
797 window.wcTracks.recordEvent( 'order_edit_delete_tax_cancel', {
798 order_id: woocommerce_admin_meta_boxes.post_id,
799 status: $( '#order_status' ).val()
800 } );
801 }
802 return false;
803 },
804
805 get_taxable_address: function() {
806 var country = '';
807 var state = '';
808 var postcode = '';
809 var city = '';
810
811 if ( 'shipping' === woocommerce_admin_meta_boxes.tax_based_on ) {
812 country = $( '#_shipping_country' ).val();
813 state = $( '#_shipping_state' ).val();
814 postcode = $( '#_shipping_postcode' ).val();
815 city = $( '#_shipping_city' ).val();
816 }
817
818 if ( 'billing' === woocommerce_admin_meta_boxes.tax_based_on || ! country ) {
819 country = $( '#_billing_country' ).val();
820 state = $( '#_billing_state' ).val();
821 postcode = $( '#_billing_postcode' ).val();
822 city = $( '#_billing_city' ).val();
823 }
824
825 return {
826 country: country,
827 state: state,
828 postcode: postcode,
829 city: city
830 };
831 },
832
833 recalculate: function() {
834 if ( window.confirm( woocommerce_admin_meta_boxes.calc_totals ) ) {
835 wc_meta_boxes_order_items.block();
836
837 var data = $.extend( {}, wc_meta_boxes_order_items.get_taxable_address(), {
838 action: 'woocommerce_calc_line_taxes',
839 order_id: woocommerce_admin_meta_boxes.post_id,
840 items: $( 'table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]' ).serialize(),
841 security: woocommerce_admin_meta_boxes.calc_totals_nonce
842 } );
843
844 data = wc_meta_boxes_order_items.filter_data( 'recalculate', data );
845
846 $( document.body ).trigger( 'order-totals-recalculate-before', data );
847
848 $.ajax({
849 url: woocommerce_admin_meta_boxes.ajax_url,
850 data: data,
851 type: 'POST',
852 success: function( response ) {
853 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
854 $( '#woocommerce-order-items' ).find( '.inside' ).append( response );
855 wc_meta_boxes_order_items.reloaded_items();
856 wc_meta_boxes_order_items.unblock();
857
858 $( document.body ).trigger( 'order-totals-recalculate-success', response );
859 },
860 complete: function( response ) {
861 $( document.body ).trigger( 'order-totals-recalculate-complete', response );
862
863 window.wcTracks.recordEvent( 'order_edit_recalc_totals', {
864 order_id: woocommerce_admin_meta_boxes.post_id,
865 ok_cancel: 'OK',
866 status: $( '#order_status' ).val()
867 } );
868 }
869 });
870 } else {
871 window.wcTracks.recordEvent( 'order_edit_recalc_totals', {
872 order_id: woocommerce_admin_meta_boxes.post_id,
873 ok_cancel: 'cancel',
874 status: $( '#order_status' ).val()
875 } );
876 }
877
878 return false;
879 },
880
881 save_line_items: function() {
882 var data = {
883 order_id: woocommerce_admin_meta_boxes.post_id,
884 items: $( 'table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]' ).serialize(),
885 action: 'woocommerce_save_order_items',
886 security: woocommerce_admin_meta_boxes.order_item_nonce
887 };
888
889 data = wc_meta_boxes_order_items.filter_data( 'save_line_items', data );
890
891 wc_meta_boxes_order_items.block();
892
893 $.ajax({
894 url: woocommerce_admin_meta_boxes.ajax_url,
895 data: data,
896 type: 'POST',
897 success: function( response ) {
898 if ( response.success ) {
899 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
900 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
901
902 // Update notes.
903 if ( response.data.notes_html ) {
904 $( 'ul.order_notes' ).empty();
905 $( 'ul.order_notes' ).append( $( response.data.notes_html ).find( 'li' ) );
906 }
907
908 wc_meta_boxes_order_items.reloaded_items();
909 wc_meta_boxes_order_items.unblock();
910 } else {
911 wc_meta_boxes_order_items.unblock();
912 window.alert( response.data.error );
913 }
914 },
915 complete: function() {
916 window.wcTracks.recordEvent( 'order_edit_save_line_items', {
917 order_id: woocommerce_admin_meta_boxes.post_id,
918 status: $( '#order_status' ).val()
919 } );
920 }
921 });
922
923 $( this ).trigger( 'items_saved' );
924
925 return false;
926 },
927
928 refunds: {
929
930 do_refund: function() {
931 wc_meta_boxes_order_items.block();
932
933 if ( window.confirm( woocommerce_admin_meta_boxes.i18n_do_refund ) ) {
934 var refund_amount = $( 'input#refund_amount' ).val();
935 var refund_reason = $( 'input#refund_reason' ).val();
936 var refunded_amount = $( 'input#refunded_amount' ).val();
937
938 // Get line item refunds
939 var line_item_qtys = {};
940 var line_item_totals = {};
941 var line_item_tax_totals = {};
942
943 $( '.refund input.refund_order_item_qty' ).each(function( index, item ) {
944 if ( $( item ).closest( 'tr' ).data( 'order_item_id' ) ) {
945 if ( item.value ) {
946 line_item_qtys[ $( item ).closest( 'tr' ).data( 'order_item_id' ) ] = item.value;
947 }
948 }
949 });
950
951 $( '.refund input.refund_line_total' ).each(function( index, item ) {
952 if ( $( item ).closest( 'tr' ).data( 'order_item_id' ) ) {
953 line_item_totals[ $( item ).closest( 'tr' ).data( 'order_item_id' ) ] = accounting.unformat(
954 item.value,
955 woocommerce_admin.mon_decimal_point
956 );
957 }
958 });
959
960 $( '.refund input.refund_line_tax' ).each(function( index, item ) {
961 if ( $( item ).closest( 'tr' ).data( 'order_item_id' ) ) {
962 var tax_id = $( item ).data( 'tax_id' );
963
964 if ( ! line_item_tax_totals[ $( item ).closest( 'tr' ).data( 'order_item_id' ) ] ) {
965 line_item_tax_totals[ $( item ).closest( 'tr' ).data( 'order_item_id' ) ] = {};
966 }
967
968 line_item_tax_totals[ $( item ).closest( 'tr' ).data( 'order_item_id' ) ][ tax_id ] = accounting.unformat(
969 item.value,
970 woocommerce_admin.mon_decimal_point
971 );
972 }
973 });
974
975 var data = {
976 action : 'woocommerce_refund_line_items',
977 order_id : woocommerce_admin_meta_boxes.post_id,
978 refund_amount : refund_amount,
979 refunded_amount : refunded_amount,
980 refund_reason : refund_reason,
981 line_item_qtys : JSON.stringify( line_item_qtys, null, '' ),
982 line_item_totals : JSON.stringify( line_item_totals, null, '' ),
983 line_item_tax_totals : JSON.stringify( line_item_tax_totals, null, '' ),
984 api_refund : $( this ).is( '.do-api-refund' ),
985 restock_refunded_items: $( '#restock_refunded_items:checked' ).length ? 'true': 'false',
986 security : woocommerce_admin_meta_boxes.order_item_nonce
987 };
988
989 data = wc_meta_boxes_order_items.filter_data( 'do_refund', data );
990
991 $.ajax( {
992 url: woocommerce_admin_meta_boxes.ajax_url,
993 data: data,
994 type: 'POST',
995 success: function( response ) {
996 if ( true === response.success ) {
997 // Redirect to same page for show the refunded status
998 window.location.reload();
999 } else {
1000 window.alert( response.data.error );
1001 wc_meta_boxes_order_items.reload_items();
1002 wc_meta_boxes_order_items.unblock();
1003 }
1004 },
1005 complete: function() {
1006 window.wcTracks.recordEvent( 'order_edit_refunded', {
1007 order_id: data.order_id,
1008 status: $( '#order_status' ).val(),
1009 api_refund: data.api_refund,
1010 has_reason: Boolean( data.refund_reason.length ),
1011 restock: 'true' === data.restock_refunded_items
1012 } );
1013 }
1014 } );
1015 } else {
1016 wc_meta_boxes_order_items.unblock();
1017 }
1018 },
1019
1020 delete_refund: function() {
1021 if ( window.confirm( woocommerce_admin_meta_boxes.i18n_delete_refund ) ) {
1022 var $refund = $( this ).closest( 'tr.refund' );
1023 var refund_id = $refund.attr( 'data-order_refund_id' );
1024
1025 wc_meta_boxes_order_items.block();
1026
1027 var data = {
1028 action: 'woocommerce_delete_refund',
1029 refund_id: refund_id,
1030 security: woocommerce_admin_meta_boxes.order_item_nonce
1031 };
1032
1033 data = wc_meta_boxes_order_items.filter_data( 'delete_refund', data );
1034
1035 $.ajax({
1036 url: woocommerce_admin_meta_boxes.ajax_url,
1037 data: data,
1038 type: 'POST',
1039 success: function() {
1040 wc_meta_boxes_order_items.reload_items();
1041 }
1042 });
1043 }
1044 return false;
1045 },
1046
1047 input_changed: function() {
1048 var refund_amount = 0;
1049 var $items = $( '.woocommerce_order_items' ).find( 'tr.item, tr.fee, tr.shipping' );
1050 var round_at_subtotal = 'yes' === woocommerce_admin_meta_boxes.round_at_subtotal;
1051
1052 $items.each(function() {
1053 var $row = $( this );
1054 var refund_cost_fields = $row.find( '.refund input:not(.refund_order_item_qty)' );
1055
1056 refund_cost_fields.each(function( index, el ) {
1057 var field_amount = accounting.unformat( $( el ).val() || 0, woocommerce_admin.mon_decimal_point );
1058 refund_amount += parseFloat( round_at_subtotal ?
1059 field_amount :
1060 accounting.formatNumber( field_amount, woocommerce_admin_meta_boxes.currency_format_num_decimals, '' ) );
1061 });
1062 });
1063
1064 $( '#refund_amount' )
1065 .val( accounting.formatNumber(
1066 refund_amount,
1067 woocommerce_admin_meta_boxes.currency_format_num_decimals,
1068 '',
1069 woocommerce_admin.mon_decimal_point
1070 ) )
1071 .trigger( 'change' );
1072 },
1073
1074 amount_changed: function() {
1075 var total = accounting.unformat( $( this ).val(), woocommerce_admin.mon_decimal_point );
1076
1077 $( 'button .wc-order-refund-amount .amount' ).text( accounting.formatMoney( total, {
1078 symbol: woocommerce_admin_meta_boxes.currency_format_symbol,
1079 decimal: woocommerce_admin_meta_boxes.currency_format_decimal_sep,
1080 thousand: woocommerce_admin_meta_boxes.currency_format_thousand_sep,
1081 precision: woocommerce_admin_meta_boxes.currency_format_num_decimals,
1082 format: woocommerce_admin_meta_boxes.currency_format
1083 } ) );
1084 },
1085
1086 // When the refund qty is changed, increase or decrease costs
1087 refund_quantity_changed: function() {
1088 var $row = $( this ).closest( 'tr.item' );
1089 var qty = $row.find( 'input.quantity' ).val();
1090 var refund_qty = $( this ).val();
1091 var line_total = $( 'input.line_total', $row );
1092 var refund_line_total = $( 'input.refund_line_total', $row );
1093
1094 // Totals
1095 var unit_total = accounting.unformat( line_total.attr( 'data-total' ), woocommerce_admin.mon_decimal_point ) / qty;
1096
1097 refund_line_total.val(
1098 parseFloat( accounting.formatNumber( unit_total * refund_qty, woocommerce_admin_meta_boxes.rounding_precision, '' ) )
1099 .toString()
1100 .replace( '.', woocommerce_admin.mon_decimal_point )
1101 ).trigger( 'change' );
1102
1103 // Taxes
1104 $( '.refund_line_tax', $row ).each( function() {
1105 var $refund_line_total_tax = $( this );
1106 var tax_id = $refund_line_total_tax.data( 'tax_id' );
1107 var line_total_tax = $( 'input.line_tax[data-tax_id="' + tax_id + '"]', $row );
1108 var unit_total_tax = accounting.unformat(
1109 line_total_tax.data( 'total_tax' ),
1110 woocommerce_admin.mon_decimal_point
1111 ) / qty;
1112
1113 if ( 0 < unit_total_tax ) {
1114
1115 $refund_line_total_tax.val(
1116 parseFloat( accounting.formatNumber(
1117 unit_total_tax * refund_qty,
1118 woocommerce_admin_meta_boxes.rounding_precision,
1119 ''
1120 ) )
1121 .toString()
1122 .replace( '.', woocommerce_admin.mon_decimal_point )
1123 ).trigger( 'change' );
1124 } else {
1125 $refund_line_total_tax.val( 0 ).trigger( 'change' );
1126 }
1127 });
1128
1129 // Restock checkbox
1130 if ( refund_qty > 0 ) {
1131 $( '#restock_refunded_items' ).closest( 'tr' ).show();
1132 } else {
1133 $( '#restock_refunded_items' ).closest( 'tr' ).hide();
1134 $( '.woocommerce_order_items input.refund_order_item_qty' ).each( function() {
1135 if ( $( this ).val() > 0 ) {
1136 $( '#restock_refunded_items' ).closest( 'tr' ).show();
1137 }
1138 });
1139 }
1140
1141 $( this ).trigger( 'refund_quantity_changed' );
1142 }
1143 },
1144
1145 item_meta: {
1146
1147 add: function() {
1148 var $button = $( this );
1149 var $item = $button.closest( 'tr.item, tr.shipping' );
1150 var $items = $item.find('tbody.meta_items');
1151 var index = $items.find('tr').length + 1;
1152 var $row = '<tr data-meta_id="0">' +
1153 '<td>' +
1154 '<input type="text" maxlength="255" placeholder="' +
1155 woocommerce_admin_meta_boxes_order.placeholder_name +
1156 '" name="meta_key[' + $item.attr( 'data-order_item_id' ) +
1157 '][new-' + index + ']" />' +
1158 '<textarea placeholder="' +
1159 woocommerce_admin_meta_boxes_order.placeholder_value +
1160 '" name="meta_value[' +
1161 $item.attr( 'data-order_item_id' ) +
1162 '][new-' +
1163 index +
1164 ']"></textarea>' +
1165 '</td>' +
1166 '<td width="1%"><button class="remove_order_item_meta button">&times;</button></td>' +
1167 '</tr>';
1168 $items.append( $row );
1169
1170 return false;
1171 },
1172
1173 remove: function() {
1174 if ( window.confirm( woocommerce_admin_meta_boxes.remove_item_meta ) ) {
1175 var $row = $( this ).closest( 'tr' );
1176 $row.find( ':input' ).val( '' );
1177 $row.hide();
1178 }
1179 return false;
1180 }
1181 },
1182
1183 backbone: {
1184
1185 init: function( e, target ) {
1186 if ( 'wc-modal-add-products' === target ) {
1187 $( document.body ).trigger( 'wc-enhanced-select-init' );
1188
1189 $( this ).on( 'change', '.wc-product-search', function() {
1190 if ( ! $( this ).closest( 'tr' ).is( ':last-child' ) ) {
1191 return;
1192 }
1193 var item_table = $( this ).closest( 'table.widefat' ),
1194 item_table_body = item_table.find( 'tbody' ),
1195 index = item_table_body.find( 'tr' ).length,
1196 row = item_table_body.data( 'row' ).replace( /\[0\]/g, '[' + index + ']' );
1197
1198 item_table_body.append( '<tr>' + row + '</tr>' );
1199 $( document.body ).trigger( 'wc-enhanced-select-init' );
1200 } );
1201 }
1202 },
1203
1204 response: function( e, target, data ) {
1205 if ( 'wc-modal-add-tax' === target ) {
1206 var rate_id = data.add_order_tax;
1207 var manual_rate_id = '';
1208
1209 if ( data.manual_tax_rate_id ) {
1210 manual_rate_id = data.manual_tax_rate_id;
1211 }
1212
1213 wc_meta_boxes_order_items.backbone.add_tax( rate_id, manual_rate_id );
1214 }
1215 if ( 'wc-modal-add-products' === target ) {
1216 // Build array of data.
1217 var item_table = $( this ).find( 'table.widefat' ),
1218 item_table_body = item_table.find( 'tbody' ),
1219 rows = item_table_body.find( 'tr' ),
1220 add_items = [];
1221
1222 $( rows ).each( function() {
1223 var item_id = $( this ).find( ':input[name="item_id"]' ).val(),
1224 item_qty = $( this ).find( ':input[name="item_qty"]' ).val();
1225
1226 add_items.push( {
1227 'id' : item_id,
1228 'qty': item_qty ? item_qty: 1
1229 } );
1230 } );
1231
1232 return wc_meta_boxes_order_items.backbone.add_items( add_items );
1233 }
1234 },
1235
1236 add_items: function( add_items ) {
1237 wc_meta_boxes_order_items.block();
1238
1239 var data = {
1240 action : 'woocommerce_add_order_item',
1241 order_id : woocommerce_admin_meta_boxes.post_id,
1242 security : woocommerce_admin_meta_boxes.order_item_nonce,
1243 data : add_items
1244 };
1245
1246 // Check if items have changed, if so pass them through so we can save them before adding a new item.
1247 if ( 'true' === $( 'button.cancel-action' ).attr( 'data-reload' ) ) {
1248 data.items = $( 'table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]' ).serialize();
1249 }
1250
1251 data = wc_meta_boxes_order_items.filter_data( 'add_items', data );
1252
1253 $.ajax({
1254 type: 'POST',
1255 url: woocommerce_admin_meta_boxes.ajax_url,
1256 data: data,
1257 success: function( response ) {
1258 if ( response.success ) {
1259 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
1260 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
1261
1262 // Update notes.
1263 const notesEl = document.querySelector( '#woocommerce-order-notes ul.order_notes' );
1264 if ( notesEl && response.data && typeof response.data.notes_html === 'string' ) {
1265 notesEl.outerHTML = response.data.notes_html;
1266 }
1267
1268 wc_meta_boxes_order_items.reloaded_items();
1269 wc_meta_boxes_order_items.unblock();
1270 } else {
1271 wc_meta_boxes_order_items.unblock();
1272 window.alert( response.data.error );
1273 }
1274 },
1275 complete: function() {
1276 window.wcTracks.recordEvent( 'order_edit_add_products', {
1277 order_id: woocommerce_admin_meta_boxes.post_id,
1278 status: $( '#order_status' ).val()
1279 } );
1280 },
1281 dataType: 'json'
1282 });
1283 },
1284
1285 add_tax: function( rate_id, manual_rate_id ) {
1286 if ( manual_rate_id ) {
1287 rate_id = manual_rate_id;
1288 }
1289
1290 if ( ! rate_id ) {
1291 return false;
1292 }
1293
1294 var rates = $( '.order-tax-id' ).map( function() {
1295 return $( this ).val();
1296 }).get();
1297
1298 // Test if already exists
1299 if ( -1 === $.inArray( rate_id, rates ) ) {
1300 wc_meta_boxes_order_items.block();
1301
1302 var data = {
1303 action: 'woocommerce_add_order_tax',
1304 rate_id: rate_id,
1305 order_id: woocommerce_admin_meta_boxes.post_id,
1306 security: woocommerce_admin_meta_boxes.order_item_nonce
1307 };
1308
1309 data = wc_meta_boxes_order_items.filter_data( 'add_tax', data );
1310
1311 $.ajax({
1312 url : woocommerce_admin_meta_boxes.ajax_url,
1313 data : data,
1314 dataType : 'json',
1315 type : 'POST',
1316 success : function( response ) {
1317 if ( response.success ) {
1318 $( '#woocommerce-order-items' ).find( '.inside' ).empty();
1319 $( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
1320 wc_meta_boxes_order_items.reloaded_items();
1321 } else {
1322 window.alert( response.data.error );
1323 }
1324 wc_meta_boxes_order_items.unblock();
1325 },
1326 complete: function() {
1327 window.wcTracks.recordEvent( 'order_edit_add_tax', {
1328 order_id: woocommerce_admin_meta_boxes.post_id,
1329 status: $( '#order_status' ).val()
1330 } );
1331 }
1332 });
1333 } else {
1334 window.alert( woocommerce_admin_meta_boxes.i18n_tax_rate_already_exists );
1335 }
1336 }
1337 },
1338
1339 stupidtable: {
1340 init: function() {
1341 $( '.woocommerce_order_items' ).stupidtable();
1342 $( '.woocommerce_order_items' ).on( 'aftertablesort', this.add_arrows );
1343 },
1344
1345 add_arrows: function( event, data ) {
1346 var th = $( this ).find( 'th' );
1347 var arrow = data.direction === 'asc' ? '&uarr;' : '&darr;';
1348 var index = data.column;
1349 th.find( '.wc-arrow' ).remove();
1350 th.eq( index ).append( '<span class="wc-arrow">' + arrow + '</span>' );
1351 }
1352 }
1353 };
1354
1355 /**
1356 * Order Notes Panel
1357 */
1358 var wc_meta_boxes_order_notes = {
1359 init: function() {
1360 $( '#woocommerce-order-notes' )
1361 .on( 'click', 'button.add_note', this.add_order_note )
1362 .on( 'click', 'a.delete_note', this.delete_order_note )
1363 .on( 'change', 'select#order_note_type', this.update_note_type_ui );
1364
1365 // Sync the CTA + helper link to reflect the current select state on load.
1366 $( 'select#order_note_type' ).trigger( 'change' );
1367 },
1368
1369 update_note_type_ui: function() {
1370 var $option = $( this ).find( ':selected' );
1371 // Fallback: extension-injected options may lack data-button-label.
1372 // Default to the first option's label so the button never shows stale text.
1373 var defaultLabel = $( this ).find( 'option:first' ).data( 'button-label' );
1374 var label = $option.data( 'button-label' ) || defaultLabel;
1375 var isCustomer = 'customer' === $( this ).val();
1376 if ( label ) {
1377 $( '#woocommerce-order-notes button.add_note' ).text( label );
1378 }
1379 $( '#woocommerce-order-notes .add_note_email_settings' ).prop( 'hidden', ! isCustomer );
1380 },
1381
1382 add_order_note: function() {
1383 if ( ! $( 'textarea#add_order_note' ).val() ) {
1384 return;
1385 }
1386
1387 $( '#woocommerce-order-notes' ).block({
1388 message: null,
1389 overlayCSS: {
1390 background: '#fff',
1391 opacity: 0.6
1392 }
1393 });
1394
1395 var data = {
1396 action: 'woocommerce_add_order_note',
1397 post_id: woocommerce_admin_meta_boxes.post_id,
1398 note: $( 'textarea#add_order_note' ).val(),
1399 note_type: $( 'select#order_note_type' ).val(),
1400 security: woocommerce_admin_meta_boxes.add_order_note_nonce
1401 };
1402
1403 $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {
1404 $( 'ul.order_notes .no-items' ).remove();
1405 $( 'ul.order_notes' ).prepend( response );
1406 $( '#woocommerce-order-notes' ).unblock();
1407 $( '#add_order_note' ).val( '' );
1408
1409 // Announce the result to screen readers (WCAG 4.1.3).
1410 if ( window.wp && window.wp.a11y && 'function' === typeof window.wp.a11y.speak ) {
1411 var message = 'customer' === data.note_type
1412 ? woocommerce_admin_meta_boxes.i18n_customer_order_note_added
1413 : woocommerce_admin_meta_boxes.i18n_order_note_added;
1414 if ( message ) {
1415 window.wp.a11y.speak( message, 'polite' );
1416 }
1417 }
1418
1419 window.wcTracks.recordEvent( 'order_edit_add_order_note', {
1420 order_id: woocommerce_admin_meta_boxes.post_id,
1421 note_type: data.note_type || 'private',
1422 status: $( '#order_status' ).val()
1423 } );
1424 });
1425
1426 return false;
1427 },
1428
1429 delete_order_note: function() {
1430 var note = $( this ).closest( 'li.note' );
1431 var message = note.hasClass( 'customer-note' )
1432 ? woocommerce_admin_meta_boxes.i18n_delete_customer_note
1433 : woocommerce_admin_meta_boxes.i18n_delete_note;
1434
1435 if ( window.confirm( message ) ) {
1436
1437 $( note ).block({
1438 message: null,
1439 overlayCSS: {
1440 background: '#fff',
1441 opacity: 0.6
1442 }
1443 });
1444
1445 var data = {
1446 action: 'woocommerce_delete_order_note',
1447 note_id: $( note ).attr( 'rel' ),
1448 security: woocommerce_admin_meta_boxes.delete_order_note_nonce
1449 };
1450
1451 $.post( woocommerce_admin_meta_boxes.ajax_url, data, function() {
1452 if ( window.wcTracks && window.wcTracks.recordEvent ) {
1453 var noteType = note.hasClass( 'customer-note' ) ? 'customer' : 'private';
1454 var dateStr = note.find( '.exact-date' ).attr( 'title' );
1455 var addedAt = dateStr ? new Date( dateStr.replace( ' ', 'T' ) ) : null;
1456 var seconds = ( addedAt && ! isNaN( addedAt.valueOf() ) )
1457 ? Math.round( ( Date.now() - addedAt.getTime() ) / 1000 )
1458 : null;
1459 window.wcTracks.recordEvent( 'order_edit_delete_order_note', {
1460 order_id: woocommerce_admin_meta_boxes.post_id,
1461 note_type: noteType,
1462 status: $( '#order_status' ).val(),
1463 seconds_since_added: seconds
1464 } );
1465 }
1466 $( note ).remove();
1467 var $list = $( 'ul.order_notes' );
1468 if ( 0 === $list.find( 'li.note' ).length ) {
1469 $list.append( $( '<li class="no-items"></li>' ).text( woocommerce_admin_meta_boxes.i18n_no_notes_yet ) );
1470 }
1471 });
1472 }
1473
1474 return false;
1475 }
1476 };
1477
1478 /**
1479 * Order Downloads Panel
1480 */
1481 var wc_meta_boxes_order_downloads = {
1482 init: function() {
1483 $( '.order_download_permissions' )
1484 .on( 'click', 'button.grant_access', this.grant_access )
1485 .on( 'click', 'button.revoke_access', this.revoke_access )
1486 .on( 'click', '#copy-download-link', this.copy_link )
1487 .on( 'aftercopy', '#copy-download-link', this.copy_success )
1488 .on( 'aftercopyfailure', '#copy-download-link', this.copy_fail );
1489
1490 // Work around WP's callback for '.handlediv' hiding the containing WP metabox instead of just the WC one.
1491 $( '.order_download_permissions .wc-metabox .handlediv' ).on( 'click', function( e ) {
1492 e.stopImmediatePropagation();
1493 $( this ).closest( 'h3' ).trigger( 'click' );
1494 } );
1495 },
1496
1497 grant_access: function() {
1498 var products = $( '#grant_access_id' ).val();
1499
1500 if ( ! products || 0 === products.length ) {
1501 return;
1502 }
1503
1504 $( '.order_download_permissions' ).block({
1505 message: null,
1506 overlayCSS: {
1507 background: '#fff',
1508 opacity: 0.6
1509 }
1510 });
1511
1512 var data = {
1513 action: 'woocommerce_grant_access_to_download',
1514 product_ids: products,
1515 loop: $('.order_download_permissions .wc-metabox').length,
1516 order_id: woocommerce_admin_meta_boxes.post_id,
1517 security: woocommerce_admin_meta_boxes.grant_access_nonce
1518 };
1519
1520 $.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {
1521
1522 if ( response && -1 !== parseInt( response ) ) {
1523 $( '.order_download_permissions .wc-metaboxes' ).append( response );
1524 } else {
1525 window.alert( woocommerce_admin_meta_boxes.i18n_download_permission_fail );
1526 }
1527
1528 $( document.body ).trigger( 'wc-init-datepickers' );
1529 $( '#grant_access_id' ).val( '' ).trigger( 'change' );
1530 $( '.order_download_permissions' ).unblock();
1531 });
1532
1533 return false;
1534 },
1535
1536 revoke_access: function () {
1537 if ( window.confirm( woocommerce_admin_meta_boxes.i18n_permission_revoke ) ) {
1538 var el = $( this ).parent().parent();
1539 var product = $( this ).attr( 'rel' ).split( ',' )[0];
1540 var file = $( this ).attr( 'rel' ).split( ',' )[1];
1541 var permission_id = $( this ).data( 'permission_id' );
1542
1543 if ( product > 0 ) {
1544 $( el ).block({
1545 message: null,
1546 overlayCSS: {
1547 background: '#fff',
1548 opacity: 0.6
1549 }
1550 });
1551
1552 var data = {
1553 action: 'woocommerce_revoke_access_to_download',
1554 product_id: product,
1555 download_id: file,
1556 permission_id: permission_id,
1557 order_id: woocommerce_admin_meta_boxes.post_id,
1558 security: woocommerce_admin_meta_boxes.revoke_access_nonce
1559 };
1560
1561 $.post( woocommerce_admin_meta_boxes.ajax_url, data, function() {
1562 // Success
1563 $( el ).fadeOut( '300', function () {
1564 $( el ).remove();
1565 });
1566 });
1567
1568 } else {
1569 $( el ).fadeOut( '300', function () {
1570 $( el ).remove();
1571 });
1572 }
1573 }
1574 return false;
1575 },
1576
1577 /**
1578 * Copy download link.
1579 *
1580 * @param {Object} evt Copy event.
1581 */
1582 copy_link: function( evt ) {
1583 wcClearClipboard();
1584 wcSetClipboard( $( this ).attr( 'href' ), $( this ) );
1585 evt.preventDefault();
1586 },
1587
1588 /**
1589 * Display a "Copied!" tip when success copying
1590 */
1591 copy_success: function() {
1592 $( this ).tipTip({
1593 'attribute': 'data-tip',
1594 'activation': 'focus',
1595 'fadeIn': 50,
1596 'fadeOut': 50,
1597 'delay': 0
1598 }).trigger( 'focus' );
1599 },
1600
1601 /**
1602 * Displays the copy error message when failure copying.
1603 */
1604 copy_fail: function() {
1605 $( this ).tipTip({
1606 'attribute': 'data-tip-failed',
1607 'activation': 'focus',
1608 'fadeIn': 50,
1609 'fadeOut': 50,
1610 'delay': 0
1611 }).trigger( 'focus' );
1612 }
1613 };
1614
1615 /**
1616 * Configures ajax request for custom metadata box in order edit screen.
1617 */
1618 var wc_meta_boxes_order_custom_meta = {
1619 init: function() {
1620 let select2_args;
1621 let metakey_select;
1622
1623 if ( ! $('#order_custom').length ) {
1624 return;
1625 }
1626
1627 $( '#order_custom #the-list' ).wpList( {
1628 /**
1629 * Add order id and action to the request.
1630 */
1631 addBefore: function( settings ) {
1632 settings.data += "&order_id=" + woocommerce_admin_meta_boxes.post_id + "&action=woocommerce_order_add_meta";
1633 return settings;
1634 },
1635
1636 addAfter: function() {
1637 $('table#list-table').show();
1638 },
1639
1640 delBefore: function( settings, el ) {
1641 if (typeof select2_args.ajax == 'undefined') {
1642 // If the list of meta keys have already loaded, prepend the deleted key to the list if it isn't already present.
1643 let meta_key = $(el).find('#meta-' + settings.data.id + '-key').val();
1644 if (metakey_select.find('option[value=\'' + meta_key + '\']').length === 0) {
1645 let newOption = new Option(meta_key, meta_key, false, false);
1646 metakey_select.prepend(newOption);
1647 }
1648 }
1649 settings.data.order_id = woocommerce_admin_meta_boxes.post_id;
1650 settings.data.action = 'woocommerce_order_delete_meta';
1651 return settings;
1652 },
1653
1654 });
1655
1656 $( '#order_custom #metakeyselect').filter( function() {
1657 metakey_select = $(this);
1658 if(metakey_select.hasClass('enhanced)')) {
1659 return;
1660 }
1661
1662 select2_args = {
1663 allowClear: !!metakey_select.data('allow_clear'),
1664 placeholder: metakey_select.data('placeholder'),
1665 ajax: {
1666 url: wc_enhanced_select_params.ajax_url,
1667 dataType: 'json',
1668 delay: 500,
1669 data: function (params) {
1670 return {
1671 order_id: metakey_select.data('order_id'),
1672 action: 'woocommerce_json_search_order_metakeys',
1673 security: wc_enhanced_select_params.search_order_metakeys_nonce
1674 };
1675 },
1676 success: function (data) {
1677 let terms = [];
1678 if (data) {
1679 $.each(data, function (id, term) {
1680 terms.push({
1681 id: term,
1682 text: term,
1683 });
1684 });
1685 }
1686 // Reinitialize with the loaded data to avoid continued ajax requests when searching since
1687 // we are not using the search term to filter the list on the backend.
1688 select2_args.data = terms;
1689 delete select2_args.ajax;
1690 metakey_select.selectWoo(select2_args).select2('open');
1691 return false;
1692 },
1693 cache: true
1694 },
1695 language: {
1696 errorLoading: function () {
1697 // Workaround for https://github.com/select2/select2/issues/4355 instead of i18n_ajax_error.
1698 return wc_enhanced_select_params.i18n_searching;
1699 },
1700 inputTooLong: function (args) {
1701 var overChars = args.input.length - args.maximum;
1702
1703 if (1 === overChars) {
1704 return wc_enhanced_select_params.i18n_input_too_long_1;
1705 }
1706
1707 return wc_enhanced_select_params.i18n_input_too_long_n.replace('%qty%', overChars);
1708 },
1709 inputTooShort: function (args) {
1710 var remainingChars = args.minimum - args.input.length;
1711
1712 if (1 === remainingChars) {
1713 return wc_enhanced_select_params.i18n_input_too_short_1;
1714 }
1715
1716 return wc_enhanced_select_params.i18n_input_too_short_n.replace('%qty%', remainingChars);
1717 },
1718 loadingMore: function () {
1719 return wc_enhanced_select_params.i18n_load_more;
1720 },
1721 maximumSelected: function (args) {
1722 if (args.maximum === 1) {
1723 return wc_enhanced_select_params.i18n_selection_too_long_1;
1724 }
1725
1726 return wc_enhanced_select_params.i18n_selection_too_long_n.replace('%qty%', args.maximum);
1727 },
1728 noResults: function () {
1729 return wc_enhanced_select_params.i18n_no_matches;
1730 },
1731 searching: function () {
1732 return wc_enhanced_select_params.i18n_searching;
1733 }
1734 }
1735
1736 };
1737
1738 // Work around to deal with the lack of responsive support from Select2 until a better replacement can be integrated.
1739 let resizeTimer;
1740 $( window ).on( 'resize', function () {
1741 cancelAnimationFrame( resizeTimer );
1742 resizeTimer = requestAnimationFrame( function () {
1743 metakey_select.selectWoo( select2_args );
1744 } );
1745 });
1746
1747 metakey_select.selectWoo(select2_args).addClass('enhanced');
1748 });
1749 }
1750 };
1751
1752 wc_meta_boxes_order.init();
1753 wc_meta_boxes_order_items.init();
1754 wc_meta_boxes_order_notes.init();
1755 wc_meta_boxes_order_downloads.init();
1756 wc_meta_boxes_order_custom_meta.init();
1757
1758 /**
1759 * Event listeners to allow third-party plugins to reinitialize WooCommerce order meta boxes
1760 * after dynamically modifying their content.
1761 *
1762 * Usage Example:
1763 *
1764 * // Reinitialize the Order Data Panel:
1765 * window.dispatchEvent(new CustomEvent("wc_meta_boxes_order_init"));
1766 *
1767 * // Reinitialize Order Items Panel:
1768 * window.dispatchEvent(new CustomEvent("wc_meta_boxes_order_items_init"));
1769 *
1770 * These events ensure that order meta boxes can be dynamically updated
1771 * and properly reinitialized as needed.
1772 */
1773 window.addEventListener('wc_meta_boxes_order_init', (e) => {
1774 wc_meta_boxes_order.init()
1775 });
1776 window.addEventListener('wc_meta_boxes_order_items_init', (e) => {
1777 wc_meta_boxes_order_items.init()
1778 });
1779 window.addEventListener('wc_meta_boxes_order_notes_init', (e) => {
1780 wc_meta_boxes_order_notes.init()
1781 });
1782 window.addEventListener('wc_meta_boxes_order_downloads_init', (e) => {
1783 wc_meta_boxes_order_downloads.init()
1784 });
1785 window.addEventListener('wc_meta_boxes_order_custom_meta_init', (e) => {
1786 wc_meta_boxes_order_custom_meta.init()
1787 });
1788 });
1789