From 91099e6d0d0445f5dace7e2155effd36569ce0a3 Mon Sep 17 00:00:00 2001 From: davisonpro Date: Thu, 9 May 2024 01:23:00 +0300 Subject: [PATCH 1/2] Variable pricing option for items --- .gitignore | 1 + assets/css/admin.css | 140 + assets/js/admin.js | 2993 +++++++++-------- includes/admin/class-getpaid-installer.php | 4 +- .../class-getpaid-meta-box-item-details.php | 634 +++- includes/class-wpinv-ajax.php | 7 +- includes/class-wpinv-invoice.php | 12 +- includes/class-wpinv-item.php | 168 +- includes/data-stores/class-getpaid-data.php | 4 +- .../class-getpaid-invoice-data-store.php | 44 +- .../class-getpaid-item-data-store.php | 12 +- includes/invoice-functions.php | 8 +- includes/payments/class-getpaid-checkout.php | 6 +- includes/payments/class-getpaid-form-item.php | 53 +- ...-getpaid-payment-form-submission-items.php | 128 +- ...payment-form-submission-refresh-prices.php | 24 +- .../class-getpaid-payment-form-submission.php | 11 - .../payments/class-getpaid-payment-form.php | 16 +- includes/wpinv-item-functions.php | 6 - readme.txt | 3 + templates/payment-forms/cart-item.php | 273 +- templates/payment-forms/cart.php | 10 +- 22 files changed, 2751 insertions(+), 1806 deletions(-) diff --git a/.gitignore b/.gitignore index e57b0098..97a44ffc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea/ +.vscode # Composer composer.phar diff --git a/assets/css/admin.css b/assets/css/admin.css index 95db5cd6..f611f21f 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -1604,6 +1604,14 @@ textarea.wpi-email_overdue_content { /* Subscription items */ /* We use classes to toggle so that the initial "display value e.g flex|blog" is maintained*/ +.getpaid_is_not_variable_pricing_item .wpinv_show_if_variable_pricing { + display: none !important; +} + +.getpaid_is_variable_pricing_item .wpinv_hide_if_variable_pricing { + display: none !important; +} + .getpaid_is_not_subscription_item .wpinv_show_if_recurring { display: none !important; } @@ -1822,4 +1830,136 @@ textarea.wpi-email_overdue_content { .getpaid-settings-editor-input { width: 620px; +} + + +.getpaid-add-repeatable-row { + margin: 10px 0 +} + +.getpaid-add-repeatable-row .submit { + padding: 0!important +} + +.getpaid-repeatable-row-actions { + color: #777; + font-size: 12px +} + +.getpaid-repeatable-row-actions a { + text-decoration: none; + width: auto; + cursor: pointer; + vertical-align: middle +} + +.getpaid-repeatable-row-header { + clear: both; + background: #f1f1f1; + border: 1px solid #e5e5e5; + cursor: move; +} + +.getpaid-repeatable-row-header:after, +.getpaid-repeatable-row-header:before { + content: ''; + display: table +} + +.getpaid-repeatable-row-header:after { + clear: both +} + +.getpaid-repeatable-row-title { + float: left; + font-weight: 600 +} + +.getpaid-repeatable-row-actions, +.getpaid-repeatable-row-title { + padding: 8px; + box-sizing: border-box +} + +.getpaid-repeatable-row-actions { + float: right; + text-align: right; + padding: 8px +} + +.getpaid-repeatable-row-actions .getpaid-remove-row { + font-size: 12px; + width: auto; + cursor: pointer +} + +.getpaid-repeatable-row-standard-fields { + background: #f9f9f9; + padding: 8px; + border-width: 0 1px 1px; + border-style: solid; + border-color: #e5e5e5 +} + +.getpaid-option-name, +.getpaid-option-price, +.getpaid_repeatable_default { + display: inline-block; + vertical-align: top +} + +.getpaid-option-name { + width: 38%; + margin-right: 5% +} + +.getpaid-option-price { + min-width: 100px +} + +.getpaid_repeatable_default { + text-align: center; + min-width: 80px +} + +.wpinv_variable_prices_wrapper:not(:first-child) { + margin-top: 12px +} + +.wpinv-custom-price-option-settings-wrap { + display: none; + border-width: 0 1px 1px; + border-style: solid; + border-color: #e5e5e5; + box-sizing: border-box; + width: 100% +} + +.wpinv-custom-price-option-setting { + display: block; + padding: 10px 8px; + border-bottom: 1px solid rgba(222,222,222,.3) +} + +.wpinv-custom-price-option-setting:last-child { + border-bottom: none +} + +.wpinv-custom-price-option-setting-title { + display: block; + font-size: 14px; + font-weight: 600; + padding: 0 0 10px +} + +.wpinv-custom-price-option-setting>:not(.wpinv-custom-price-option-setting-title) { + display: inline-block; + padding-right: 20px; + vertical-align: top; + margin-bottom: 4px +} + +.wpinv-custom-price-option-setting>:not(.wpinv-custom-price-option-setting-title) label { + display: block; + margin-bottom: 2px } \ No newline at end of file diff --git a/assets/js/admin.js b/assets/js/admin.js index 9c5c1288..05a38e28 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -3,1589 +3,1672 @@ window.getpaid = window.getpaid || {} // Init the select2 items container. getpaid.init_select2_item_search = function (select, parent) { - if (!parent) { - parent = jQuery('#getpaid-add-items-to-invoice') - } - - var ignore = jQuery(select).data( 'ignore' ); - - jQuery(select).select2({ - minimumInputLength: 3, - allowClear: false, - dropdownParent: parent, - ajax: { - url: WPInv_Admin.ajax_url, - delay: 250, - data: function (params) { - - var data = { - action: 'wpinv_get_invoicing_items', - search: params.term, - _ajax_nonce: WPInv_Admin.wpinv_nonce, - ignore: ignore, - post_id: WPInv_Admin.post_ID - } - - // Query parameters will be ?search=[term]&type=public - return data; - }, - processResults: function (res) { - - if (res.success) { - return { - results: res.data - }; - } - - return { - results: [] - }; - } - }, - templateResult: function (item) { - - if (item.loading) { - return WPInv_Admin.searching; - } - - if (!item.id) { - return item.text; - } - - return jQuery('' + item.text + '') - }, - language: { - inputTooShort: function() { - return WPInv_Admin.search_items; - } - } - }); + if (!parent) { + parent = jQuery('#getpaid-add-items-to-invoice') + } + + var ignore = jQuery(select).data('ignore'); + + jQuery(select).select2({ + minimumInputLength: 3, + allowClear: false, + dropdownParent: parent, + ajax: { + url: WPInv_Admin.ajax_url, + delay: 250, + data: function (params) { + + var data = { + action: 'wpinv_get_invoicing_items', + search: params.term, + _ajax_nonce: WPInv_Admin.wpinv_nonce, + ignore: ignore, + post_id: WPInv_Admin.post_ID + } + + // Query parameters will be ?search=[term]&type=public + return data; + }, + processResults: function (res) { + + if (res.success) { + return { + results: res.data + }; + } + + return { + results: [] + }; + } + }, + templateResult: function (item) { + + if (item.loading) { + return WPInv_Admin.searching; + } + + if (!item.id) { + return item.text; + } + + return jQuery('' + item.text + '') + }, + language: { + inputTooShort: function () { + return WPInv_Admin.search_items; + } + } + }); } // Init the select2 customer container. getpaid.init_select2_customer_search = function (select, parent) { - if ( ! parent ) { - parent = jQuery(select).parent() - } - - jQuery(select).select2({ - minimumInputLength: 3, - allowClear: false, - dropdownParent: parent, - ajax: { - url: WPInv_Admin.ajax_url, - delay: 250, - data: function (params) { - - var data = { - action: 'wpinv_get_customers', - search: params.term, - _ajax_nonce: WPInv_Admin.wpinv_nonce, - post_id: WPInv_Admin.post_ID - } - - // Query parameters will be ?search=[term]&type=public - return data; - }, - processResults: function (res) { - - if (res.success) { - return { - results: res.data - }; - } - - return { - results: [] - }; - } - }, - templateResult: function (item) { - - if (item.loading) { - return WPInv_Admin.searching; - } - - if (!item.id) { - return item.text; - } - - return jQuery('' + item.text + '') - }, - language: { - inputTooShort: function() { - return WPInv_Admin.search_customers; - } - } - }); + if (!parent) { + parent = jQuery(select).parent() + } + + jQuery(select).select2({ + minimumInputLength: 3, + allowClear: false, + dropdownParent: parent, + ajax: { + url: WPInv_Admin.ajax_url, + delay: 250, + data: function (params) { + + var data = { + action: 'wpinv_get_customers', + search: params.term, + _ajax_nonce: WPInv_Admin.wpinv_nonce, + post_id: WPInv_Admin.post_ID + } + + // Query parameters will be ?search=[term]&type=public + return data; + }, + processResults: function (res) { + + if (res.success) { + return { + results: res.data + }; + } + + return { + results: [] + }; + } + }, + templateResult: function (item) { + + if (item.loading) { + return WPInv_Admin.searching; + } + + if (!item.id) { + return item.text; + } + + return jQuery('' + item.text + '') + }, + language: { + inputTooShort: function () { + return WPInv_Admin.search_customers; + } + } + }); } // Currency formatter. getpaid.currency = new Intl.NumberFormat(undefined, { - style: 'currency', - currency: WPInv_Admin.currency, + style: 'currency', + currency: WPInv_Admin.currency, }) jQuery(function ($) { - //'use strict'; - - // Tooltips. - if( jQuery().tooltip ) { - - $('.wpi-help-tip').tooltip({ - content: function () { - return $(this).prop('title'); - }, - tooltipClass: 'wpi-ui-tooltip', - position: { - my: 'center top', - at: 'center bottom+10', - collision: 'flipfit' - }, - hide: { - duration: 200 - }, - show: { - duration: 200 - } - }); - - } - - // Init select 2. - wpi_select2(); - function wpi_select2() { - if (jQuery("select.wpi_select2").length > 0) { - jQuery("select.wpi_select2").select2(); - jQuery("select.wpi_select2_nostd").select2({ - allow_single_deselect: 'true' - }); - } - } - - // Init item selector. - $('.getpaid-ajax-item-selector').each(function () { - var el = $(this); - getpaid.init_select2_item_search(el, $(el).parent()) - }); - - // Init customer selector. - $('.getpaid-customer-search').each(function () { - var el = $(this); - getpaid.init_select2_customer_search(el, $(el).parent()) - }); - - $('.getpaid-install-plugin-siwtch-div').on('click', function (e) { - e.preventDefault() - - var _input = $( this ).find('input') - _input.prop( 'checked', ! _input.prop( 'checked' ) ); - - }); - - $('.getpaid-merge-tags').click(function() { - const tags = $(this).parent().find('.getpaid-merge-tags-content'); - // fix css d-none !important rule - if(tags.hasClass('d-none')) { - tags.css({ 'display' : 'none' }) && tags.removeClass('d-none'); - } - tags.slideToggle('fast'); - }); - - // returns a random string - function random_string() { - return (Date.now().toString(36) + Math.random().toString(36).substr(2)) - } - - // Subscription items. - if ($('#wpinv_is_recurring').length) { - - // Toggles the 'getpaid_is_subscription_item' class on the body. - var watch_subscription_change = function () { - $('body').toggleClass('getpaid_is_subscription_item', $('#wpinv_is_recurring').is(':checked')) - $('body').toggleClass('getpaid_is_not_subscription_item', !$('#wpinv_is_recurring').is(':checked')) - - $('.getpaid-price-input').toggleClass('col-sm-4', $('#wpinv_is_recurring').is(':checked')) - $('.getpaid-price-input').toggleClass('col-sm-12', !$('#wpinv_is_recurring').is(':checked')) - - } - - // Toggle the class when the document is loaded... - watch_subscription_change(); - - // ... and whenever the checkbox changes. - $(document).on('change', '#wpinv_is_recurring', watch_subscription_change); - - } - - // Dynamic items. - if ($('#wpinv_name_your_price').length) { - - // Toggles the 'getpaid_is_dynamic_item' class on the body. - var watch_dynamic_change = function () { - $('body').toggleClass('getpaid_is_dynamic_item', $('#wpinv_name_your_price').is(':checked')) - $('body').toggleClass('getpaid_is_not_dynamic_item', !$('#wpinv_name_your_price').is(':checked')) - } - - // Toggle the class when the document is loaded... - watch_dynamic_change(); - - // ... and whenever the checkbox changes. - $(document).on('change', '#wpinv_name_your_price', watch_dynamic_change); - - } - - // Rename excerpt to 'description' - $('body.post-type-wpi_item #postexcerpt h2.hndle').text(WPInv_Admin.item_description) - $('body.post-type-wpi_discount #postexcerpt h2.hndle').text(WPInv_Admin.discount_description) - $('body.getpaid-is-invoice-cpt #postexcerpt h2.hndle').text(WPInv_Admin.invoice_description) - $('body.getpaid-is-invoice-cpt #postexcerpt p, body.post-type-wpi_item #postexcerpt p, body.post-type-wpi_discount #postexcerpt p').hide() + //'use strict'; + + // Tooltips. + if (jQuery().tooltip) { + + $('.wpi-help-tip').tooltip({ + content: function () { + return $(this).prop('title'); + }, + tooltipClass: 'wpi-ui-tooltip', + position: { + my: 'center top', + at: 'center bottom+10', + collision: 'flipfit' + }, + hide: { + duration: 200 + }, + show: { + duration: 200 + } + }); - // Discount types. - $(document).on('change', '#wpinv_discount_type', function () { - $('#wpinv_discount_amount_wrap').removeClass('flat percent') - $('#wpinv_discount_amount_wrap').addClass($(this).val()) - }); + } - // Fill in user information. - $('#getpaid-invoice-fill-user-details').on('click', function (e) { - e.preventDefault() + // Init select 2. + wpi_select2(); + function wpi_select2() { + if (jQuery("select.wpi_select2").length > 0) { + jQuery("select.wpi_select2").select2(); + jQuery("select.wpi_select2_nostd").select2({ + allow_single_deselect: 'true' + }); + } + } - var metabox = $(this).closest('.bsui'); - var user_id = metabox.find('#wpinv_post_author_override').val(); + // Init item selector. + $('.getpaid-ajax-item-selector').each(function () { + var el = $(this); + getpaid.init_select2_item_search(el, $(el).parent()) + }); + + // Init customer selector. + $('.getpaid-customer-search').each(function () { + var el = $(this); + getpaid.init_select2_customer_search(el, $(el).parent()) + }); + + // check int input to not accept -ve numbers or strings. + $(document).on('input', 'input.wpinv-force-integer', function (e) { + var $input = $(this); + $input.val(function (_, currentValue) { + return currentValue.replace(/[^\d.]+/g, ''); + }); + }); + + $('.getpaid-install-plugin-siwtch-div').on('click', function (e) { + e.preventDefault() + + var _input = $(this).find('input') + _input.prop('checked', !_input.prop('checked')); + + }); + + $('.getpaid-merge-tags').click(function () { + const tags = $(this).parent().find('.getpaid-merge-tags-content'); + // fix css d-none !important rule + if (tags.hasClass('d-none')) { + tags.css({ 'display': 'none' }) && tags.removeClass('d-none'); + } + tags.slideToggle('fast'); + }); - // Ensure that we have a user id and that we are not adding a new user. - if (!user_id || $(this).attr('disabled')) { - return; - } + // returns a random string + function random_string() { + return (Date.now().toString(36) + Math.random().toString(36).substr(2)) + } - // Clear existing data. - $('#wpinv_first_name, #wpinv_last_name, #wpinv_address, #wpinv_city, #wpinv_zip, #wpinv_company, #wpinv_company_id, #wpinv_phone, #wpinv_vat_number').val(''); + $("#wpinv_price_fields").on("keyup input keydown", ".wpinv_variable_price_name", function() { + var key = parseInt($(this).parents(".getpaid_repeatable_row").data("key")), + name = $(this).val(), + field_select = $(".getpaid_repeatable_condition_field"); + + field_select.each(function() { + var field_option = $(this).find("option[value='" + key + "']"); + + if (field_option.length > 0) { + field_option.text(name); + } else { + field_select.append(new Option(name, key)); + } + + $(this).select2(); + }); + + }); + + // Toggle custom price option settings section + $(document).on('click', '.wpinv-toggle-custom-price-option-settings', function (e) { + e.preventDefault(); + + var _this = $(this); + var show = _this.html() === _this.data('show'); + var row_header = $(this).parents('.getpaid-repeatable-row-header'); + var standard_fields_wrap = row_header.siblings('.getpaid-repeatable-row-standard-fields'); + var custom_settings_wrap = row_header.siblings('.wpinv-custom-price-option-settings-wrap'); + + _this.html(show ? _this.data('hide') : _this.data('show')); + + custom_settings_wrap.slideToggle(); + + let first_input; + if (show) { + first_input = $(":input:not(input[type=button],input[type=submit],button):visible:first", custom_settings_wrap); + } else { + first_input = $(":input:not(input[type=button],input[type=submit],button):visible:first", standard_fields_wrap); + } - // Block the metabox. - wpinvBlock(metabox) + first_input.focus(); + }); + + $(document).on('change', '.wpinv-recurring-enabled select', function () { + const _this = $(this); + + if (!_this.is(':visible')) return; + + const price_option_setting = _this.closest('.wpinv-custom-price-option-setting'); + const fields = price_option_setting.find('input, select'); + const val = _this.find('option:selected').val(); + + fields.prop('disabled', val === 'no' ? true : false); + + _this.prop('disabled', false); + }); + + $( '.wpinv-recurring-enabled select' ).change(); + + // Variable pricing items. + if ($('#wpinv_variable_pricing').length) { + // Toggles the 'getpaid_is_variable_pricing_item' class on the body. + var watch_variable_pricing_change = function () { + $('body').toggleClass('getpaid_is_variable_pricing_item', $('#wpinv_variable_pricing').is(':checked')) + $('body').toggleClass('getpaid_is_not_variable_pricing_item', !$('#wpinv_variable_pricing').is(':checked')) + } + + // Toggle the class when the document is loaded... + watch_variable_pricing_change(); + + // ... and whenever the checkbox changes. + $(document).on('change', '#wpinv_variable_pricing', watch_variable_pricing_change); + + } - // Retrieve the user's billing address. - var data = { - action: 'wpinv_get_billing_details', - user_id: user_id, - post_id: WPInv_Admin.post_ID, - _ajax_nonce: WPInv_Admin.wpinv_nonce - } + // Subscription items. + if ($('#wpinv_is_recurring').length) { - $.get(WPInv_Admin.ajax_url, data) + // Toggles the 'getpaid_is_subscription_item' class on the body. + var watch_subscription_change = function () { + $('body').toggleClass('getpaid_is_subscription_item', $('#wpinv_is_recurring').is(':checked')) + $('body').toggleClass('getpaid_is_not_subscription_item', !$('#wpinv_is_recurring').is(':checked')) + + $('.getpaid-price-input').toggleClass('col-sm-4', $('#wpinv_is_recurring').is(':checked')) + $('.getpaid-price-input').toggleClass('col-sm-12', !$('#wpinv_is_recurring').is(':checked')) + + } + + // Toggle the class when the document is loaded... + watch_subscription_change(); + + // ... and whenever the checkbox changes. + $(document).on('change', '#wpinv_is_recurring', watch_subscription_change); + + } + + // Dynamic items. + if ($('#wpinv_name_your_price').length) { + + // Toggles the 'getpaid_is_dynamic_item' class on the body. + var watch_dynamic_change = function () { + $('body').toggleClass('getpaid_is_dynamic_item', $('#wpinv_name_your_price').is(':checked')) + $('body').toggleClass('getpaid_is_not_dynamic_item', !$('#wpinv_name_your_price').is(':checked')) + } + + // Toggle the class when the document is loaded... + watch_dynamic_change(); + + // ... and whenever the checkbox changes. + $(document).on('change', '#wpinv_name_your_price', watch_dynamic_change); + + } + + // Rename excerpt to 'description' + $('body.post-type-wpi_item #postexcerpt h2.hndle').text(WPInv_Admin.item_description) + $('body.post-type-wpi_discount #postexcerpt h2.hndle').text(WPInv_Admin.discount_description) + $('body.getpaid-is-invoice-cpt #postexcerpt h2.hndle').text(WPInv_Admin.invoice_description) + $('body.getpaid-is-invoice-cpt #postexcerpt p, body.post-type-wpi_item #postexcerpt p, body.post-type-wpi_discount #postexcerpt p').hide() + + // Discount types. + $(document).on('change', '#wpinv_discount_type', function () { + $('#wpinv_discount_amount_wrap').removeClass('flat percent') + $('#wpinv_discount_amount_wrap').addClass($(this).val()) + }); + + // Fill in user information. + $('#getpaid-invoice-fill-user-details').on('click', function (e) { + e.preventDefault() + + var metabox = $(this).closest('.bsui'); + var user_id = metabox.find('#wpinv_post_author_override').val(); + + // Ensure that we have a user id and that we are not adding a new user. + if (!user_id || $(this).attr('disabled')) { + return; + } + + // Clear existing data. + $('#wpinv_first_name, #wpinv_last_name, #wpinv_address, #wpinv_city, #wpinv_zip, #wpinv_company, #wpinv_company_id, #wpinv_phone, #wpinv_vat_number').val(''); + + // Block the metabox. + wpinvBlock(metabox) + + // Retrieve the user's billing address. + var data = { + action: 'wpinv_get_billing_details', + user_id: user_id, + post_id: WPInv_Admin.post_ID, + _ajax_nonce: WPInv_Admin.wpinv_nonce + } - .done(function (response) { + $.get(WPInv_Admin.ajax_url, data) - if (response.success) { + .done(function (response) { - $.each(response.data, function (key, value) { + if (response.success) { - // Retrieve the associated input. - var el = $('#wpinv_' + key) + $.each(response.data, function (key, value) { - // If it exists... - if (el.length) { - el.val(value); - } + // Retrieve the associated input. + var el = $('#wpinv_' + key) - }); + // If it exists... + if (el.length) { + el.val(value); + } - recalculateTotals(); - } - }) + }); - .always(function (response) { - wpinvUnblock(metabox); - }) + recalculateTotals(); + } + }) - }) + .always(function (response) { + wpinvUnblock(metabox); + }) - $( '#wpinv_post_author_override' ).on( 'change', function() { - $( '.getpaid-is-invoice-cpt #post_author_override' ).val( $( '#wpinv_post_author_override' ).val() ) - $('#getpaid-invoice-fill-user-details').trigger( 'click' ) - } ) + }) - $( '.getpaid-is-invoice-cpt #post_author_override' ).replaceWith( '' ) - $( '.getpaid-is-invoice-cpt #post_author_override' ).val( $( '#wpinv_post_author_override' ).val() ) + $('#wpinv_post_author_override').on('change', function () { + $('.getpaid-is-invoice-cpt #post_author_override').val($('#wpinv_post_author_override').val()) + $('#getpaid-invoice-fill-user-details').trigger('click') + }) - // When clicking the create a new user button... - $('#getpaid-invoice-create-new-user-button').on('click', function (e) { - e.preventDefault() + $('.getpaid-is-invoice-cpt #post_author_override').replaceWith('') + $('.getpaid-is-invoice-cpt #post_author_override').val($('#wpinv_post_author_override').val()) - // Hide the button and the customer select div. - $('#getpaid-invoice-user-id-wrapper, #getpaid-invoice-create-new-user-button').addClass('d-none') + // When clicking the create a new user button... + $('#getpaid-invoice-create-new-user-button').on('click', function (e) { + e.preventDefault() - // Display the email input and the cancel button. - $('#getpaid-invoice-cancel-create-new-user, #getpaid-invoice-email-wrapper').removeClass('d-none') + // Hide the button and the customer select div. + $('#getpaid-invoice-user-id-wrapper, #getpaid-invoice-create-new-user-button').addClass('d-none') - // Disable the fill user details button. - $('#getpaid-invoice-fill-user-details').attr('disabled', true); + // Display the email input and the cancel button. + $('#getpaid-invoice-cancel-create-new-user, #getpaid-invoice-email-wrapper').removeClass('d-none') - // Indicate that we will be creating a new user. - $('#getpaid-invoice-create-new-user').val(1); + // Disable the fill user details button. + $('#getpaid-invoice-fill-user-details').attr('disabled', true); - // The email field is now required. - $('#getpaid-invoice-new-user-email').prop('required', 'required'); + // Indicate that we will be creating a new user. + $('#getpaid-invoice-create-new-user').val(1); - // Delete existing values. - $('#wpinv_first_name, #wpinv_last_name, #wpinv_company, #wpinv_vat_number, #wpinv_address, #wpinv_city, #wpinv_zip, #wpinv_phone').val('') - }); + // The email field is now required. + $('#getpaid-invoice-new-user-email').prop('required', 'required'); - // When clicking the "cancel new user" button... - $('#getpaid-invoice-cancel-create-new-user').on('click', function (e) { - e.preventDefault(); + // Delete existing values. + $('#wpinv_first_name, #wpinv_last_name, #wpinv_company, #wpinv_vat_number, #wpinv_address, #wpinv_city, #wpinv_zip, #wpinv_phone').val('') + }); - // Hide the button and the email input divs. - $('#getpaid-invoice-cancel-create-new-user, #getpaid-invoice-email-wrapper').addClass('d-none') + // When clicking the "cancel new user" button... + $('#getpaid-invoice-cancel-create-new-user').on('click', function (e) { + e.preventDefault(); - // Display the add new user button and select customer divs. - $('#getpaid-invoice-user-id-wrapper, #getpaid-invoice-create-new-user-button').removeClass('d-none') + // Hide the button and the email input divs. + $('#getpaid-invoice-cancel-create-new-user, #getpaid-invoice-email-wrapper').addClass('d-none') + + // Display the add new user button and select customer divs. + $('#getpaid-invoice-user-id-wrapper, #getpaid-invoice-create-new-user-button').removeClass('d-none') + + // Enable the fill user details button. + $('#getpaid-invoice-fill-user-details').attr('disabled', false); + + // We are no longer creating a new user. + $('#getpaid-invoice-create-new-user').val(0); + $('#getpaid-invoice-new-user-email').val('').prop('required', false); + + }); + + // When the new user's email changes... + $('#getpaid-invoice-new-user-email').on('change', function (e) { + e.preventDefault(); + + // Hide any error messages. + $(this) + .removeClass('is-invalid') + .parent() + .find('.invalid-feedback') + .remove() + + var metabox = $(this).closest('.bsui'); + var email = $(this).val() + + // Block the metabox. + wpinvBlock(metabox) + + // Ensure the email is unique. + var data = { + action: 'wpinv_check_new_user_email', + email: email, + post_id: WPInv_Admin.post_ID, + _ajax_nonce: WPInv_Admin.wpinv_nonce + } + + $.get(WPInv_Admin.ajax_url, data) + + .done(function (response) { + if (!response.success) { + // Show error messages. + $('#getpaid-invoice-new-user-email') + .addClass('is-invalid') + .parent() + .append('
' + response + '
') + } else if (response.data.id) { + + var val = response.data.id; + + // Set the value, creating a new option if necessary + $('#getpaid-invoice-cancel-create-new-user').trigger('click') + if ($('#wpinv_post_author_override').find('option[value=' + val + ']').length) { + $('#wpinv_post_author_override').val(val).trigger('change') + } else { + $('#wpinv_post_author_override').append(new Option(email, val, true, true)).trigger('change') + } + + } + + }) + + .always(function (response) { + wpinvUnblock(metabox); + }) + + }); + + // When the country changes, load the states field. + $('.getpaid-is-invoice-cpt').on('change', '#wpinv_country', function (e) { + + // Ensure that we have the states field. + if (!$('#wpinv_state').length) { + return + } + + var row = $(this).closest('.row'); + + // Block the row. + wpinvBlock(row) + + // Fetch the states field. + var data = { + action: 'wpinv_get_aui_states_field', + country: $('#wpinv_country').val(), + state: $('#wpinv_state').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce + } + + // Fetch new states field. + $.get(WPInv_Admin.ajax_url, data) + + .done(function (response) { + if (response.success) { + $('#wpinv_state').closest('.form-group').replaceWith(response.data.html) + + if (response.data.select) { + $('#wpinv_state').select2() + } + } + }) + + .always(function (response) { + wpinvUnblock(row); + }) + }) + + // Update template when it changes. + $('#wpinv_template').on('change', function (e) { + $(this) + .closest('#poststuff') + .removeClass('amount quantity hours') + .addClass($(this).val()) + }) + $('#wpinv_template').trigger('change') + + // Adding items to an invoice. + function getpaid_add_invoice_item_modal() { + + // Contains an array of empty selections. + var empty_select = [] + + // Save a cache of the default row. + $('#getpaid-add-items-to-invoice tbody') + .data( + 'row', + $('#getpaid-add-items-to-invoice tbody').html() + ) + + $('.getpaid-add-invoice-item-select').select2( + { + dropdownParent: $('#getpaid-add-items-to-invoice .modal-body') + } + ) + + // Add a unique id. + $('.getpaid-add-invoice-item-select').data('key', random_string()) + + // (Maybe) add another select box. + $('#getpaid-add-items-to-invoice').on('change', '.getpaid-add-invoice-item-select', function (e) { + + var el = $(this) + var key = el.data('key') + + // If no value is selected, add it to empty selects. + if (!el.val()) { + if (-1 == $.inArray(key, empty_select)) { + empty_select.push(key) + } + return; + } + + // Maybe remove it from the list of empty selects. + var index = $.inArray(key, empty_select) + if (-1 != index) { + empty_select.splice(index, 1); + } + + // If we no longer have an empty select, add one. + if (empty_select.length) { + return; + } + + var key = random_string() + var row = $('#getpaid-add-items-to-invoice tbody').data('row') + row = $(row).appendTo('#getpaid-add-items-to-invoice tbody') + var select = row.find('.getpaid-add-invoice-item-select') + select.data('key', key).select2( + { + dropdownParent: $('#getpaid-add-items-to-invoice .modal-body') + } + ) + empty_select.push(key) + + $('#getpaid-add-items-to-invoice').modal('handleUpdate') + + }) + + // Reverts the modal. + var revert = function () { + empty_select = [] + + $('#getpaid-add-items-to-invoice tbody') + .html( + $('#getpaid-add-items-to-invoice tbody').data('row') + ) + + $('.getpaid-add-invoice-item-select').select2( + { + dropdownParent: $('#getpaid-add-items-to-invoice .modal-body') + } + ) + + // Add a unique id. + $('.getpaid-add-invoice-item-select').data('key', random_string()) + } + + // Cancel addition. + $('#getpaid-add-items-to-invoice .getpaid-cancel').on('click', revert) + + // Save addition. + $('#getpaid-add-items-to-invoice .getpaid-add').on('click', function () { + + // Retrieve selected items. + var items = $('#getpaid-add-items-to-invoice tbody tr') + .map(function () { + if ($(this).find('select').val()) { + return { + id: $(this).find('select').val(), + qty: $(this).find('input').val() + } + } + }) + .get() + + // Revert the modal. + revert() + + // If no items were selected, abort + if (!items.length) { + return; + } + + // Block the metabox. + wpinvBlock('.getpaid-invoice-items-inner') + + // Add the items to the invoice. + var data = { + action: 'wpinv_add_invoice_items', + post_id: $('#post_ID').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce, + items: items, + } + + $.post(WPInv_Admin.ajax_url, data) + + .done(function (response) { + + if (response.success) { + getpaid_replace_invoice_items(response.data.items) + + if (response.data.alert) { + alert(response.data.alert) + } + + recalculateTotals() + } + + }) + + .always(function (response) { + wpinvUnblock('.getpaid-invoice-items-inner'); + }) + }) + } + getpaid_add_invoice_item_modal() + + function recalculate_full_prices(e) { + if (e) { + e.preventDefault() + } + + var data = $('.getpaid-recalculate-prices-on-change').serialize() + data += '&action=wpinv_recalculate_full_prices' + '&post_id=' + $('#post_ID').val() + '&_ajax_nonce=' + WPInv_Admin.wpinv_nonce + + // Block the metabox. + wpinvBlock('#wpinv_items_wrap') + + $.post(WPInv_Admin.ajax_url, data) + .done(function (response) { + if (response.success) { + if (response.data.alert) { + alert(response.data.alert) + } else { + $('#wpinv_items_wrap').replaceWith(response.data.table); + // Trigger on recalculate full prices done. + $("body").trigger("getpaid_on_recalculate_full_prices", response.data); + } + } + }) + + .always(function (response) { + wpinvUnblock('#wpinv_items_wrap'); + }) + } + + $('.getpaid-is-invoice-cpt').on('change', '.getpaid-recalculate-prices-on-change', recalculate_full_prices) + $('.getpaid-is-invoice-cpt #wpinv-items').on('click', '.wpinv-item-remove', function () { + $(this).closest('tr').remove() + recalculate_full_prices() + }) + $('.getpaid-is-invoice-cpt').on('click', '#wpinv-recalc-totals', recalculate_full_prices) + $('.getpaid-is-invoice-cpt').on('click', '#wpinv-add-item', function (e) { + e.preventDefault() + + var data = { + action: 'wpinv_admin_add_invoice_item', + post_id: $('#post_ID').val(), + item_id: $('#wpinv_invoice_item').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce + } - // Enable the fill user details button. - $('#getpaid-invoice-fill-user-details').attr('disabled', false); + // Block the metabox. + wpinvBlock('#wpinv_items_wrap') + + $.post(WPInv_Admin.ajax_url, data) + + .done(function (response) { + + if (response.success) { + if (response.data.alert) { + alert(response.data.alert) + } else { + $('.wpinv-line-items').append(response.data.row) + recalculate_full_prices() + } + } + + }) + + .always(function (response) { + wpinvUnblock('#wpinv_items_wrap'); + }) + + }) + + $('.getpaid-is-invoice-cpt').on('click', '#wpinv-new-item', function (e) { + e.preventDefault(); + $('#wpinv-quick-add').slideToggle('fast'); + }); + + $('.getpaid-is-invoice-cpt').on('click', '#wpinv-cancel-item', function (e) { + e.preventDefault(); + $('#wpinv-quick-add').slideToggle('fast'); + $('#_wpinv_quick_vat_rule, #_wpinv_quick_vat_class, #_wpinv_quick_type').prop('selectedIndex', 0); + $('.wpinv-quick-item-name, .wpinv-quick-item-price, .wpinv-quick-item-qty, .wpinv-quick-item-price, .wpinv-quick-item-description').val(''); + return false; + }); + + $('.getpaid-is-invoice-cpt').on('click', '#wpinv-save-item', function (e) { + e.preventDefault() + + var data = { + action: 'wpinv_create_invoice_item', + invoice_id: $('#post_ID').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce, + _wpinv_quick: { + 'name': $('.wpinv-quick-item-name').val(), + 'price': $('.wpinv-quick-item-price').val(), + 'qty': $('.wpinv-quick-item-qty').val(), + 'description': $('.wpinv-quick-item-description').val(), + 'type': $('.wpinv-quick-type').val(), + 'vat_rule': $('.wpinv-quick-vat-rule').val(), + 'vat_class': $('.wpinv-quick-vat-class').val(), + 'one-time': $('#_wpinv_quick-one-time').is(':checked') ? 1 : 0, + } + } - // We are no longer creating a new user. - $('#getpaid-invoice-create-new-user').val(0); - $('#getpaid-invoice-new-user-email').val('').prop('required', false); + if (!data._wpinv_quick.name) { + $('.wpinv-quick-item-name').focus(); + return; + } - }); + if (!data._wpinv_quick.price) { + $('.wpinv-quick-item-price').focus(); + return; + } - // When the new user's email changes... - $('#getpaid-invoice-new-user-email').on('change', function (e) { - e.preventDefault(); + // Block the metabox. + wpinvBlock('#wpinv_items_wrap') - // Hide any error messages. - $(this) - .removeClass('is-invalid') - .parent() - .find('.invalid-feedback') - .remove() + $.post(WPInv_Admin.ajax_url, data) - var metabox = $(this).closest('.bsui'); - var email = $(this).val() + .done(function (response) { - // Block the metabox. - wpinvBlock(metabox) + if (response.success) { + if (response.data.alert) { + alert(response.data.alert) + } else { + $('.wpinv-line-items').append(response.data.row) + recalculate_full_prices() + } + } - // Ensure the email is unique. - var data = { - action: 'wpinv_check_new_user_email', - email: email, - post_id: WPInv_Admin.post_ID, - _ajax_nonce: WPInv_Admin.wpinv_nonce - } + }) - $.get(WPInv_Admin.ajax_url, data) + .always(function (response) { + wpinvUnblock('#wpinv_items_wrap'); + }) - .done(function (response) { - if (!response.success) { - // Show error messages. - $('#getpaid-invoice-new-user-email') - .addClass('is-invalid') - .parent() - .append('
' + response + '
') - } else if ( response.data.id ) { + }); - var val = response.data.id; + // Refresh invoice items. + if ($('#wpinv-items .getpaid-invoice-items-inner').hasClass('has-items')) { - // Set the value, creating a new option if necessary - $('#getpaid-invoice-cancel-create-new-user').trigger( 'click' ) - if ( $('#wpinv_post_author_override').find( 'option[value=' + val + ']').length ) { - $('#wpinv_post_author_override').val(val).trigger( 'change' ) - } else { - $('#wpinv_post_author_override').append( new Option( email, val, true, true ) ).trigger( 'change' ) - } - - } - - }) - - .always(function (response) { - wpinvUnblock(metabox); - }) - - }); - - // When the country changes, load the states field. - $('.getpaid-is-invoice-cpt').on('change', '#wpinv_country', function (e) { - - // Ensure that we have the states field. - if (!$('#wpinv_state').length) { - return - } - - var row = $(this).closest('.row'); - - // Block the row. - wpinvBlock(row) - - // Fetch the states field. - var data = { - action: 'wpinv_get_aui_states_field', - country: $('#wpinv_country').val(), - state: $('#wpinv_state').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce - } - - // Fetch new states field. - $.get(WPInv_Admin.ajax_url, data) - - .done(function (response) { - if (response.success) { - $('#wpinv_state').closest('.form-group').replaceWith(response.data.html) - - if (response.data.select) { - $('#wpinv_state').select2() - } - } - }) - - .always(function (response) { - wpinvUnblock(row); - }) - }) - - // Update template when it changes. - $('#wpinv_template').on('change', function (e) { - $(this) - .closest('#poststuff') - .removeClass('amount quantity hours') - .addClass($(this).val()) - }) - $('#wpinv_template').trigger('change') - - // Adding items to an invoice. - function getpaid_add_invoice_item_modal() { - - // Contains an array of empty selections. - var empty_select = [] - - // Save a cache of the default row. - $('#getpaid-add-items-to-invoice tbody') - .data( - 'row', - $('#getpaid-add-items-to-invoice tbody').html() - ) - - $('.getpaid-add-invoice-item-select').select2( - { - dropdownParent: $('#getpaid-add-items-to-invoice .modal-body') - } - ) - - // Add a unique id. - $('.getpaid-add-invoice-item-select').data('key', random_string()) - - // (Maybe) add another select box. - $('#getpaid-add-items-to-invoice').on('change', '.getpaid-add-invoice-item-select', function (e) { - - var el = $(this) - var key = el.data('key') - - // If no value is selected, add it to empty selects. - if (!el.val()) { - if (-1 == $.inArray(key, empty_select)) { - empty_select.push(key) - } - return; - } - - // Maybe remove it from the list of empty selects. - var index = $.inArray(key, empty_select) - if (-1 != index) { - empty_select.splice(index, 1); - } - - // If we no longer have an empty select, add one. - if (empty_select.length) { - return; - } - - var key = random_string() - var row = $('#getpaid-add-items-to-invoice tbody').data('row') - row = $(row).appendTo('#getpaid-add-items-to-invoice tbody') - var select = row.find('.getpaid-add-invoice-item-select') - select.data('key', key).select2( - { - dropdownParent: $('#getpaid-add-items-to-invoice .modal-body') - } - ) - empty_select.push(key) - - $('#getpaid-add-items-to-invoice').modal('handleUpdate') - - }) - - // Reverts the modal. - var revert = function () { - empty_select = [] - - $('#getpaid-add-items-to-invoice tbody') - .html( - $('#getpaid-add-items-to-invoice tbody').data('row') - ) - - $('.getpaid-add-invoice-item-select').select2( - { - dropdownParent: $('#getpaid-add-items-to-invoice .modal-body') - } - ) - - // Add a unique id. - $('.getpaid-add-invoice-item-select').data('key', random_string()) - } - - // Cancel addition. - $('#getpaid-add-items-to-invoice .getpaid-cancel').on('click', revert) - - // Save addition. - $('#getpaid-add-items-to-invoice .getpaid-add').on('click', function () { - - // Retrieve selected items. - var items = $('#getpaid-add-items-to-invoice tbody tr') - .map(function () { - if ($(this).find('select').val()) { - return { - id: $(this).find('select').val(), - qty: $(this).find('input').val() - } - } - }) - .get() - - // Revert the modal. - revert() - - // If no items were selected, abort - if (!items.length) { - return; - } - - // Block the metabox. - wpinvBlock('.getpaid-invoice-items-inner') - - // Add the items to the invoice. - var data = { - action: 'wpinv_add_invoice_items', - post_id: $('#post_ID').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce, - items: items, - } - - $.post(WPInv_Admin.ajax_url, data) - - .done(function (response) { - - if (response.success) { - getpaid_replace_invoice_items(response.data.items) - - if (response.data.alert) { - alert(response.data.alert) - } - - recalculateTotals() - } - - }) - - .always(function (response) { - wpinvUnblock('.getpaid-invoice-items-inner'); - }) - }) - } - getpaid_add_invoice_item_modal() - - function recalculate_full_prices( e ) { - if ( e ) { - e.preventDefault() - } - - var data = $('.getpaid-recalculate-prices-on-change').serialize() - data += '&action=wpinv_recalculate_full_prices' + '&post_id=' + $('#post_ID').val() + '&_ajax_nonce=' + WPInv_Admin.wpinv_nonce - - // Block the metabox. - wpinvBlock('#wpinv_items_wrap') - - $.post(WPInv_Admin.ajax_url, data) - .done(function (response) { - if (response.success) { - if (response.data.alert) { - alert(response.data.alert) - }else{ - $('#wpinv_items_wrap').replaceWith(response.data.table); - // Trigger on recalculate full prices done. - $("body").trigger("getpaid_on_recalculate_full_prices", response.data); - } - } - }) - - .always(function (response) { - wpinvUnblock('#wpinv_items_wrap'); - }) - } - - $('.getpaid-is-invoice-cpt').on('change', '.getpaid-recalculate-prices-on-change', recalculate_full_prices ) - $('.getpaid-is-invoice-cpt #wpinv-items').on('click', '.wpinv-item-remove', function() { - $(this).closest('tr').remove() - recalculate_full_prices() - } ) - $('.getpaid-is-invoice-cpt').on('click', '#wpinv-recalc-totals', recalculate_full_prices ) - $('.getpaid-is-invoice-cpt').on('click', '#wpinv-add-item', function( e ) { - e.preventDefault() - - var data = { - action: 'wpinv_admin_add_invoice_item', - post_id: $('#post_ID').val(), - item_id: $('#wpinv_invoice_item').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce - } - - // Block the metabox. - wpinvBlock('#wpinv_items_wrap') - - $.post(WPInv_Admin.ajax_url, data) - - .done(function (response) { - - if (response.success) { - if (response.data.alert) { - alert(response.data.alert) - }else{ - $('.wpinv-line-items').append(response.data.row) - recalculate_full_prices() - } - } - - }) - - .always(function (response) { - wpinvUnblock('#wpinv_items_wrap'); - }) - - }) - - $('.getpaid-is-invoice-cpt').on('click', '#wpinv-new-item', function(e) { - e.preventDefault(); - $('#wpinv-quick-add').slideToggle('fast'); - }); - - $('.getpaid-is-invoice-cpt').on('click', '#wpinv-cancel-item', function(e) { - e.preventDefault(); - $('#wpinv-quick-add').slideToggle('fast'); - $('#_wpinv_quick_vat_rule, #_wpinv_quick_vat_class, #_wpinv_quick_type').prop('selectedIndex',0); - $('.wpinv-quick-item-name, .wpinv-quick-item-price, .wpinv-quick-item-qty, .wpinv-quick-item-price, .wpinv-quick-item-description').val(''); - return false; - }); - - $('.getpaid-is-invoice-cpt').on('click', '#wpinv-save-item', function(e) { - e.preventDefault() - - var data = { - action: 'wpinv_create_invoice_item', - invoice_id: $('#post_ID').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce, - _wpinv_quick: { - 'name': $('.wpinv-quick-item-name').val(), - 'price': $('.wpinv-quick-item-price').val(), - 'qty': $('.wpinv-quick-item-qty').val(), - 'description': $('.wpinv-quick-item-description').val(), - 'type': $('.wpinv-quick-type').val(), - 'vat_rule': $('.wpinv-quick-vat-rule').val(), - 'vat_class': $('.wpinv-quick-vat-class').val(), - 'one-time': $('#_wpinv_quick-one-time').is(':checked') ? 1 : 0, - } - } - - if ( ! data._wpinv_quick.name ) { - $('.wpinv-quick-item-name').focus(); - return; - } - - if ( ! data._wpinv_quick.price ) { - $('.wpinv-quick-item-price').focus(); - return; - } - - // Block the metabox. - wpinvBlock('#wpinv_items_wrap') - - $.post(WPInv_Admin.ajax_url, data) - - .done(function (response) { - - if (response.success) { - if (response.data.alert) { - alert(response.data.alert) - }else{ - $('.wpinv-line-items').append(response.data.row) - recalculate_full_prices() - } - } - - }) - - .always(function (response) { - wpinvUnblock('#wpinv_items_wrap'); - }) - - }); - - // Refresh invoice items. - if ($('#wpinv-items .getpaid-invoice-items-inner').hasClass('has-items')) { + // Refresh the items. + var data = { + action: 'wpinv_get_invoice_items', + post_id: $('#post_ID').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce + } - // Refresh the items. - var data = { - action: 'wpinv_get_invoice_items', - post_id: $('#post_ID').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce - } + // Block the metabox. + wpinvBlock('.getpaid-invoice-items-inner') - // Block the metabox. - wpinvBlock('.getpaid-invoice-items-inner') + $.post(WPInv_Admin.ajax_url, data) - $.post(WPInv_Admin.ajax_url, data) + .done(function (response) { - .done(function (response) { + if (response.success) { + getpaid_replace_invoice_items(response.data.items) + } - if (response.success) { - getpaid_replace_invoice_items(response.data.items) - } + }) - }) + .always(function (response) { + wpinvUnblock('.getpaid-invoice-items-inner'); + }) + } - .always(function (response) { - wpinvUnblock('.getpaid-invoice-items-inner'); - }) - } + /** + * Replaces all items with the provided items. + * + * @param {Array} items New invoice items. + */ + function getpaid_replace_invoice_items(items) { - /** - * Replaces all items with the provided items. - * - * @param {Array} items New invoice items. - */ - function getpaid_replace_invoice_items(items) { - - // Remove all existing items. - $('tr.getpaid-invoice-item').remove() - var _class = "no-items" + // Remove all existing items. + $('tr.getpaid-invoice-item').remove() + var _class = "no-items" - $.each(items, function (index, item) { + $.each(items, function (index, item) { - _class = 'has-items' - var row = $('tr.getpaid-invoice-item-template').clone() - row - .removeClass('getpaid-invoice-item-template d-none') - .addClass('getpaid-invoice-item item-' + item.id) + _class = 'has-items' + var row = $('tr.getpaid-invoice-item-template').clone() + row + .removeClass('getpaid-invoice-item-template d-none') + .addClass('getpaid-invoice-item item-' + item.id) - $.each(item.texts, function (key, value) { - row.find('.' + key).html(value) - }) + $.each(item.texts, function (key, value) { + row.find('.' + key).html(value) + }) - row - .data('inputs', item.inputs) - .appendTo('#wpinv-items .getpaid_invoice_line_items') + row + .data('inputs', item.inputs) + .appendTo('#wpinv-items .getpaid_invoice_line_items') - }) + }) - $('.getpaid-invoice-items-inner') - .removeClass('no-items has-items') - .addClass(_class) - } + $('.getpaid-invoice-items-inner') + .removeClass('no-items has-items') + .addClass(_class) + } - // Delete invoice items. - $('.getpaid-is-invoice-cpt').on('click', '.getpaid-item-actions .dashicons-trash', function (e) { - e.preventDefault(); + // Delete invoice items. + $('.getpaid-is-invoice-cpt').on('click', '.getpaid-item-actions .dashicons-trash', function (e) { + e.preventDefault(); - // Block the metabox. - wpinvBlock('.getpaid-invoice-items-inner') + // Block the metabox. + wpinvBlock('.getpaid-invoice-items-inner') - // Item details. - var inputs = $(this).closest('.getpaid-invoice-item').data('inputs') - var that = this + // Item details. + var inputs = $(this).closest('.getpaid-invoice-item').data('inputs') + var that = this - // Remove the item from the invoice. - var data = { - action: 'wpinv_remove_invoice_item', - post_id: $('#post_ID').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce, - item_id: inputs['item-id'], - } + // Remove the item from the invoice. + var data = { + action: 'wpinv_remove_invoice_item', + post_id: $('#post_ID').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce, + item_id: inputs['item-id'], + } - $.post(WPInv_Admin.ajax_url, data) + $.post(WPInv_Admin.ajax_url, data) - .done(function (response) { + .done(function (response) { - if (response.success) { + if (response.success) { - $(that).closest('.getpaid-invoice-item').remove() + $(that).closest('.getpaid-invoice-item').remove() - $('.getpaid-invoice-items-inner').removeClass('no-items has-items') + $('.getpaid-invoice-items-inner').removeClass('no-items has-items') - if ($('tr.getpaid-invoice-item').length) { - $('.getpaid-invoice-items-inner').addClass('has-items') - } else { - $('.getpaid-invoice-items-inner').addClass('no-items') - } + if ($('tr.getpaid-invoice-item').length) { + $('.getpaid-invoice-items-inner').addClass('has-items') + } else { + $('.getpaid-invoice-items-inner').addClass('no-items') + } - recalculateTotals() - } + recalculateTotals() + } - }) + }) - .always(function (response) { - wpinvUnblock('.getpaid-invoice-items-inner'); - }) + .always(function (response) { + wpinvUnblock('.getpaid-invoice-items-inner'); + }) - }) + }) - // Edit invoice items. - $('.getpaid-is-invoice-cpt').on('click', '.getpaid-item-actions .dashicons-edit', function (e) { - e.preventDefault(); + // Edit invoice items. + $('.getpaid-is-invoice-cpt').on('click', '.getpaid-item-actions .dashicons-edit', function (e) { + e.preventDefault(); - var inputs = $(this).closest('.getpaid-invoice-item').data('inputs') + var inputs = $(this).closest('.getpaid-invoice-item').data('inputs') - // Enter value getpaid-edit-item-div - $.each(inputs, function (key, value) { - $('#getpaid-edit-invoice-item .getpaid-edit-item-div .' + key).val(value) - }) + // Enter value getpaid-edit-item-div + $.each(inputs, function (key, value) { + $('#getpaid-edit-invoice-item .getpaid-edit-item-div .' + key).val(value) + }) - // Display the modal. - if ( window.bootstrap && window.bootstrap.Modal ) { - var invoiceModal = new window.bootstrap.Modal(document.getElementById('getpaid-edit-invoice-item') ); + // Display the modal. + if (window.bootstrap && window.bootstrap.Modal) { + var invoiceModal = new window.bootstrap.Modal(document.getElementById('getpaid-edit-invoice-item')); invoiceModal.show(); } else { $('#getpaid-edit-invoice-item').modal() } - }) + }) + + // Cancel item edit. + $('#getpaid-edit-invoice-item .getpaid-cancel').on('click', function () { + $('#getpaid-edit-invoice-item .getpaid-edit-item-div :input').val('') + }) + + // Cancel item creation. + $('#getpaid-create-invoice-item .getpaid-cancel').on('click', function () { + $('#getpaid-create-invoice-item .getpaid-create-item-div :input').val('') + }) + + // Save edited invoice item. + $('#getpaid-edit-invoice-item .getpaid-save').on('click', function () { + + // Retrieve item data. + var data = $('#getpaid-edit-invoice-item .getpaid-edit-item-div :input') + .map(function () { + return { + 'field': $(this).attr('name'), + 'value': $(this).val(), + } + }) + .get() + + $('#getpaid-edit-invoice-item .getpaid-edit-item-div :input').val('') + + // Block the metabox. + wpinvBlock('.getpaid-invoice-items-inner') + + // Save the edit. + var post_data = { + action: 'wpinv_edit_invoice_item', + post_id: $('#post_ID').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce, + data: data, + } + + $.post(WPInv_Admin.ajax_url, post_data) + + .done(function (response) { - // Cancel item edit. - $('#getpaid-edit-invoice-item .getpaid-cancel').on('click', function () { - $('#getpaid-edit-invoice-item .getpaid-edit-item-div :input').val('') - }) + if (response.success) { + getpaid_replace_invoice_items(response.data.items) - // Cancel item creation. - $('#getpaid-create-invoice-item .getpaid-cancel').on('click', function () { - $('#getpaid-create-invoice-item .getpaid-create-item-div :input').val('') - }) + if (response.data.alert) { + alert(response.data.alert) + } - // Save edited invoice item. - $('#getpaid-edit-invoice-item .getpaid-save').on('click', function () { + recalculateTotals() + } - // Retrieve item data. - var data = $('#getpaid-edit-invoice-item .getpaid-edit-item-div :input') - .map(function () { - return { - 'field': $(this).attr('name'), - 'value': $(this).val(), - } - }) - .get() + }) - $('#getpaid-edit-invoice-item .getpaid-edit-item-div :input').val('') - - // Block the metabox. - wpinvBlock('.getpaid-invoice-items-inner') + .always(function (response) { + wpinvUnblock('.getpaid-invoice-items-inner'); + }) + }) - // Save the edit. - var post_data = { - action: 'wpinv_edit_invoice_item', - post_id: $('#post_ID').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce, - data: data, - } + // Save created invoice item. + $('#getpaid-create-invoice-item .getpaid-save').on('click', function () { - $.post(WPInv_Admin.ajax_url, post_data) + // Retrieve item data. + var data = $('#getpaid-create-invoice-item .getpaid-create-item-div :input') + .map(function () { + return { + 'field': $(this).attr('name'), + 'value': $(this).val(), + } + }) + .get() - .done(function (response) { + $('#getpaid-create-invoice-item .getpaid-create-item-div :input').val('') + + // Block the metabox. + wpinvBlock('.getpaid-invoice-items-inner') + + // Save the edit. + var post_data = { + action: 'wpinv_create_invoice_item', + post_id: $('#post_ID').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce, + data: data, + } + + $.post(WPInv_Admin.ajax_url, post_data) + + .done(function (response) { + + if (response.success) { + getpaid_replace_invoice_items(response.data.items) + + if (response.data.alert) { + alert(response.data.alert) + } + + recalculateTotals() + } + + }) + + .always(function (response) { + wpinvUnblock('.getpaid-invoice-items-inner'); + }) + }) + + // Recalculate invoice totals. + function recalculateTotals() { + + // Prepare arguments. + var data = { + country: $('#wpinv_country').val(), + state: $('#wpinv_state').val(), + currency: $('#wpinv_currency').val(), + taxes: $('#wpinv_taxable:checked').length, + action: 'wpinv_recalculate_invoice_totals', + post_id: $('#post_ID').val(), + discount_code: $('#wpinv_discount_code').val(), + _ajax_nonce: WPInv_Admin.wpinv_nonce, + } + + if ($('#wpinv_vat_number').length) { + data.vat_number = $('#wpinv_vat_number').val() + } - if (response.success) { - getpaid_replace_invoice_items(response.data.items) + // Block the metabox. + wpinvBlock('.getpaid-invoice-items-inner') - if (response.data.alert) { - alert(response.data.alert) - } + $.post(WPInv_Admin.ajax_url, data) - recalculateTotals() - } + .done(function (response) { - }) + if (response.success) { - .always(function (response) { - wpinvUnblock('.getpaid-invoice-items-inner'); - }) - }) + var totals = response.data.totals - // Save created invoice item. - $('#getpaid-create-invoice-item .getpaid-save').on('click', function () { + $.each(totals, function (key, value) { + $('tr.getpaid-totals-' + key).find('.value').html(value) + }) - // Retrieve item data. - var data = $('#getpaid-create-invoice-item .getpaid-create-item-div :input') - .map(function () { - return { - 'field': $(this).attr('name'), - 'value': $(this).val(), - } - }) - .get() + if (response.data.alert) { + alert(response.data.alert) + } + } - $('#getpaid-create-invoice-item .getpaid-create-item-div :input').val('') + }) - // Block the metabox. - wpinvBlock('.getpaid-invoice-items-inner') + .always(function (response) { + wpinvUnblock('.getpaid-invoice-items-inner'); + }) + + } + $('#wpinv-items .recalculate-totals-button').on('click', function (e) { + e.preventDefault() + recalculateTotals() + }) + + $('.getpaid-is-invoice-cpt #wpinv_vat_number, .getpaid-is-invoice-cpt #wpinv_discount_code, .getpaid-is-invoice-cpt #wpinv_taxable').on('change', function (e) { + e.preventDefault() + //recalculateTotals() + }) + + $('.getpaid-is-invoice-cpt').on('change', '#wpinv_country, #wpinv_state', function (e) { + recalculateTotals() + }) + + // Hide status entry. + $('.getpaid-is-invoice-cpt form#post [name="post_status"]').attr('type', 'hidden'); + + /** + * Invoice Notes Panel + */ + var wpinv_meta_boxes_notes = { + init: function () { + $('#wpinv-notes') + .on('click', 'a.add_note', this.add_invoice_note) + .on('click', 'a.delete_note', this.delete_invoice_note); + if ($('ul.invoice_notes')[0]) { + $('ul.invoice_notes')[0].scrollTop = $('ul.invoice_notes')[0].scrollHeight; + } + }, + add_invoice_note: function () { + if (!$('textarea#add_invoice_note').val()) { + return; + } + + wpinvBlock('#wpinv-notes'); + + var data = { + action: 'wpinv_add_note', + post_id: WPInv_Admin.post_ID, + note: $('textarea#add_invoice_note').val(), + note_type: $('select#invoice_note_type').val(), + _nonce: WPInv_Admin.add_invoice_note_nonce + }; + $.post(WPInv_Admin.ajax_url, data, function (response) { + $('ul.invoice_notes').append(response); + $('ul.invoice_notes')[0].scrollTop = $('ul.invoice_notes')[0].scrollHeight; + wpinvUnblock('#wpinv-notes'); + $('#add_invoice_note').val(''); + }); + return false; + }, + delete_invoice_note: function (e) { + e.preventDefault(); + + // Fetch the note id. + var note_id = $(this).data('id'); + + // Remove the note from the DOM. + $(this).closest('li.note').remove(); + + // Delete remotely. + $.post(WPInv_Admin.ajax_url, { + action: 'wpinv_delete_note', + note_id: note_id, + _nonce: WPInv_Admin.delete_invoice_note_nonce + }); + } + }; + wpinv_meta_boxes_notes.init(); + var invDetails = jQuery('#wpinv-details .inside').html(); + + if (invDetails) { + jQuery('#submitpost', jQuery('.wpinv')).detach().appendTo(jQuery('#wpinv-details')); + jQuery('#submitdiv', jQuery('.wpinv')).remove(); + jQuery('#publishing-action', '#wpinv-details').find('input[type=submit]').attr('name', 'save_invoice').val(WPInv_Admin.save_invoice); + } + var invBilling = jQuery('#wpinv-address.postbox').html(); + if (invBilling) { + jQuery('#wpinv_post_author_override', '#authordiv').remove(); + jQuery('#authordiv', jQuery('.wpinv')).hide(); + } + var wpinvNumber; + if (!jQuery('#post input[name="post_title"]').val() && (wpinvNumber = jQuery('#wpinv-details input[name="wpinv_number"]').val())) { + jQuery('#post input[name="post_title"]').val(wpinvNumber); + } + var wpi_stat_links = jQuery('.getpaid-is-invoice-cpt .subsubsub'); + if (wpi_stat_links.is(':visible')) { + var publish_count = jQuery('.publish', wpi_stat_links).find('.count').text(); + jQuery('.publish', wpi_stat_links).find('a').html(WPInv_Admin.status_publish + ' ' + publish_count + ''); + var pending_count = jQuery('.wpi-pending', wpi_stat_links).find('.count').text(); + jQuery('.pending', wpi_stat_links).find('a').html(WPInv_Admin.status_pending + ' ' + pending_count + ''); + } + + // Update state field based on selected country + var getpaid_user_edit_sync_state_and_country = function () { + + // Ensure that we have both fields. + if (!$('.getpaid_js_field-country').length || !$('.getpaid_js_field-state').length) { + return + } + + // fade the state field. + $('.getpaid_js_field-state').fadeTo(1000, 0.4); + + var is_aui = $('.getpaid_js_field-state').is('.custom-select, .form-control') + var _class = $('.getpaid_js_field-state').attr('class') + + // Prepare data. + var data = { + action: 'wpinv_get_states_field', + country: $('.getpaid_js_field-country').val(), + field_name: $('.getpaid_js_field-country').attr('name').replace('country', 'state'), + class: $('.getpaid_js_field-state').attr('class'), + }; + + // Fetch new states field. + $.post(WPInv_Admin.ajax_url, data) + + .done(function (response) { + + var value = $('.getpaid_js_field-state').val() + + if ('nostates' == response) { + if (is_aui) { + var text_field = ''; + } else { + var text_field = ''; + } + $('.getpaid_js_field-state').removeClass('custom-select').addClass(_class) + $('.getpaid_js_field-state').replaceWith(text_field); + } else { + var response = $(response) + response.attr('id', data.field_name) + $('.getpaid_js_field-state').replaceWith(response) + $('.getpaid_js_field-state').removeClass('form-control').addClass(_class).addClass('custom-select') + } + + $('.getpaid_js_field-state').val(value) + + }) + + .fail(function () { + var text_field = ''; + $('.getpaid_js_field-state').replaceWith(text_field); + }) + + .always(function () { + // unfade the state field. + $('.getpaid_js_field-state').fadeTo(1000, 1); + }) + + + } - // Save the edit. - var post_data = { - action: 'wpinv_create_invoice_item', - post_id: $('#post_ID').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce, - data: data, - } - - $.post(WPInv_Admin.ajax_url, post_data) - - .done(function (response) { - - if (response.success) { - getpaid_replace_invoice_items(response.data.items) - - if (response.data.alert) { - alert(response.data.alert) - } - - recalculateTotals() - } - - }) - - .always(function (response) { - wpinvUnblock('.getpaid-invoice-items-inner'); - }) - }) - - // Recalculate invoice totals. - function recalculateTotals() { - - // Prepare arguments. - var data = { - country: $('#wpinv_country').val(), - state: $('#wpinv_state').val(), - currency: $('#wpinv_currency').val(), - taxes: $('#wpinv_taxable:checked').length, - action: 'wpinv_recalculate_invoice_totals', - post_id: $('#post_ID').val(), - discount_code: $('#wpinv_discount_code').val(), - _ajax_nonce: WPInv_Admin.wpinv_nonce, - } - - if ( $('#wpinv_vat_number').length ) { - data.vat_number = $('#wpinv_vat_number').val() - } - - // Block the metabox. - wpinvBlock('.getpaid-invoice-items-inner') - - $.post(WPInv_Admin.ajax_url, data) - - .done(function (response) { - - if (response.success) { - - var totals = response.data.totals - - $.each(totals, function (key, value) { - $('tr.getpaid-totals-' + key).find('.value').html(value) - }) - - if (response.data.alert) { - alert(response.data.alert) - } - } - - }) - - .always(function (response) { - wpinvUnblock('.getpaid-invoice-items-inner'); - }) - - } - $('#wpinv-items .recalculate-totals-button').on('click', function (e) { - e.preventDefault() - recalculateTotals() - }) - - $('.getpaid-is-invoice-cpt #wpinv_vat_number, .getpaid-is-invoice-cpt #wpinv_discount_code, .getpaid-is-invoice-cpt #wpinv_taxable').on('change', function (e) { - e.preventDefault() - //recalculateTotals() - }) - - $('.getpaid-is-invoice-cpt').on('change', '#wpinv_country, #wpinv_state', function (e) { - recalculateTotals() - }) - - // Hide status entry. - $('.getpaid-is-invoice-cpt form#post [name="post_status"]').attr( 'type', 'hidden' ); - - /** - * Invoice Notes Panel - */ - var wpinv_meta_boxes_notes = { - init: function () { - $('#wpinv-notes') - .on('click', 'a.add_note', this.add_invoice_note) - .on('click', 'a.delete_note', this.delete_invoice_note); - if ($('ul.invoice_notes')[0]) { - $('ul.invoice_notes')[0].scrollTop = $('ul.invoice_notes')[0].scrollHeight; - } - }, - add_invoice_note: function () { - if (!$('textarea#add_invoice_note').val()) { - return; - } - - wpinvBlock('#wpinv-notes'); - - var data = { - action: 'wpinv_add_note', - post_id: WPInv_Admin.post_ID, - note: $('textarea#add_invoice_note').val(), - note_type: $('select#invoice_note_type').val(), - _nonce: WPInv_Admin.add_invoice_note_nonce - }; - $.post(WPInv_Admin.ajax_url, data, function (response) { - $('ul.invoice_notes').append(response); - $('ul.invoice_notes')[0].scrollTop = $('ul.invoice_notes')[0].scrollHeight; - wpinvUnblock( '#wpinv-notes' ); - $('#add_invoice_note').val(''); - }); - return false; - }, - delete_invoice_note: function ( e ) { - e.preventDefault(); - - // Fetch the note id. - var note_id = $(this).data('id'); - - // Remove the note from the DOM. - $(this).closest('li.note').remove(); - - // Delete remotely. - $.post( WPInv_Admin.ajax_url, { - action: 'wpinv_delete_note', - note_id: note_id, - _nonce: WPInv_Admin.delete_invoice_note_nonce - }); - } - }; - wpinv_meta_boxes_notes.init(); - var invDetails = jQuery('#wpinv-details .inside').html(); - - if (invDetails) { - jQuery('#submitpost', jQuery('.wpinv')).detach().appendTo(jQuery('#wpinv-details')); - jQuery('#submitdiv', jQuery('.wpinv')).remove(); - jQuery('#publishing-action', '#wpinv-details').find('input[type=submit]').attr('name', 'save_invoice').val(WPInv_Admin.save_invoice); - } - var invBilling = jQuery('#wpinv-address.postbox').html(); - if (invBilling) { - jQuery('#wpinv_post_author_override', '#authordiv').remove(); - jQuery('#authordiv', jQuery('.wpinv')).hide(); - } - var wpinvNumber; - if (!jQuery('#post input[name="post_title"]').val() && (wpinvNumber = jQuery('#wpinv-details input[name="wpinv_number"]').val())) { - jQuery('#post input[name="post_title"]').val(wpinvNumber); - } - var wpi_stat_links = jQuery('.getpaid-is-invoice-cpt .subsubsub'); - if (wpi_stat_links.is(':visible')) { - var publish_count = jQuery('.publish', wpi_stat_links).find('.count').text(); - jQuery('.publish', wpi_stat_links).find('a').html(WPInv_Admin.status_publish + ' ' + publish_count + ''); - var pending_count = jQuery('.wpi-pending', wpi_stat_links).find('.count').text(); - jQuery('.pending', wpi_stat_links).find('a').html(WPInv_Admin.status_pending + ' ' + pending_count + ''); - } - - // Update state field based on selected country - var getpaid_user_edit_sync_state_and_country = function () { - - // Ensure that we have both fields. - if (!$('.getpaid_js_field-country').length || !$('.getpaid_js_field-state').length) { - return - } - - // fade the state field. - $('.getpaid_js_field-state').fadeTo(1000, 0.4); - - var is_aui = $('.getpaid_js_field-state').is( '.custom-select, .form-control' ) - var _class = $('.getpaid_js_field-state').attr('class') - - // Prepare data. - var data = { - action: 'wpinv_get_states_field', - country: $('.getpaid_js_field-country').val(), - field_name: $('.getpaid_js_field-country').attr('name').replace('country', 'state'), - class: $('.getpaid_js_field-state').attr('class'), - }; - - // Fetch new states field. - $.post(WPInv_Admin.ajax_url, data) - - .done(function (response) { - - var value = $('.getpaid_js_field-state').val() - - if ('nostates' == response) { - if ( is_aui ) { - var text_field = ''; - } else { - var text_field = ''; - } - $('.getpaid_js_field-state').removeClass('custom-select').addClass(_class) - $('.getpaid_js_field-state').replaceWith(text_field); - } else { - var response = $(response) - response.attr('id', data.field_name) - $('.getpaid_js_field-state').replaceWith(response) - $('.getpaid_js_field-state').removeClass('form-control').addClass(_class).addClass('custom-select') - } - - $('.getpaid_js_field-state').val(value) - - }) - - .fail(function () { - var text_field = ''; - $('.getpaid_js_field-state').replaceWith(text_field); - }) - - .always(function () { - // unfade the state field. - $('.getpaid_js_field-state').fadeTo(1000, 1); - }) - - - } - - // Sync on load. - getpaid_user_edit_sync_state_and_country(); - - // Sync on changes. - $(document.body).on('change', '.getpaid_js_field-country', getpaid_user_edit_sync_state_and_country); - - /** - * Reindexes the tax table. - */ - function wpinv_reindex_tax_table() { - - $('#wpinv_tax_rates tbody tr').each(function (rowIndex) { - - $(this).find(":input[name^='tax_rates']").each(function () { - var name = $(this).attr('name'); - name = name.replace(/\[(\d+)\]/, '[' + (rowIndex) + ']'); - $(this).attr('name', name).attr('id', name); - }); - - }); - - } - - // Inserts a new tax rate row - $('.wpinv_add_tax_rate').on('click', function (e) { - - e.preventDefault() - var html = $('#tmpl-wpinv-tax-rate-row').html() - $('#wpinv_tax_rates tbody').append(html) - wpinv_reindex_tax_table(); - - }); - - $('.wpinv_add_tax_rule').on('click', function (e) { - - e.preventDefault(); - var html = $('#tmpl-wpinv-tax-rule-row').html(); - html = html.replace(/TAX_RULE_KEY/g, random_string() ); - $('#wpinv-tax-rules tbody').append(html) - - }); - - // Remove tax row. - $(document).on('click', '#wpinv_tax_rates .wpinv_remove_tax_rate', function (e) { - - e.preventDefault() - $(this).closest('tr').remove(); - wpinv_reindex_tax_table(); - - }); - - $(document).on('click', '#wpinv-tax-rules .wpinv_remove_tax_rule', function (e) { - - e.preventDefault(); - $(this).closest('tr').remove(); - - }); - - var WPInv = { - init: function () { - this.preSetup(); - }, - preSetup: function () { - - var wpinvColorPicker = $('.wpinv-color-picker'); - if (wpinvColorPicker.length) { - wpinvColorPicker.wpColorPicker(); - } - var no_states = $('select.wpinv-no-states'); - if (no_states.length) { - no_states.closest('tr').hide(); - } - // Update base state field based on selected base country - $('select[name="wpinv_settings[default_country]"]:not(.getpaid_js_field-country)').change(function () { - var $this = $(this), - $tr = $this.closest('tr'); - data = { - action: 'wpinv_get_states_field', - country: $(this).val(), - field_name: 'wpinv_settings[default_state]' - }; - $.post(WPInv_Admin.ajax_url, data, function (response) { - if ('nostates' == response) { - $tr.next().hide(); - } else { - $tr.next().show(); - $tr.next().find('select').replaceWith(response); - } - }); - return false; - }); - - // Toggle recaptcha settings. - function toggleRecaptchaSettings() { - - var show = $( '#wpinv-settings-enable_recaptcha' ).is ( ':checked' ); - - $( '#wpinv-settings-recaptcha_version' ).closest( 'tr' ).toggle( show ); - $( '#wpinv-settings-recaptcha_site_key' ).closest( 'tr' ).toggle( show ); - $( '#wpinv-settings-recaptcha_secret_key' ).closest( 'tr' ).toggle( show ); - } - - $( '#wpinv-settings-enable_recaptcha' ).on( 'change', toggleRecaptchaSettings ); - toggleRecaptchaSettings(); - }, - - }; - $('.getpaid-is-invoice-cpt form#post #titlediv [name="post_title"]').attr('readonly', true); - - WPInv.init(); - - /** - * Retrieves a report. - * @param {string} report - * @param {object} args - */ - function getStats(report, args) { - - // Reports. - return $.ajax( - { - url: WPInv_Admin.rest_root + 'getpaid/v1/reports/' + report, - method: 'GET', - data: args, - beforeSend: function (xhr) { - xhr.setRequestHeader('X-WP-Nonce', WPInv_Admin.rest_nonce); - } - } - ); - - } - - /** - * Feeds a stat onto the page. - * @param {string} stat - * @param {string} current - * @param {string} previous - */ - function feedStat(stat, current, previous) { - - // Abort if it is not supported. - var $el = $('.getpaid-report-cards .card.' + stat); - if ($el.length == 0) { - return - } - - // Fill in card revenue. - if (!window.Intl || ['total_invoices', 'total_items', 'refunded_items', 'period_ticket_sales'].indexOf(stat) > -1) { - $el.find('.getpaid-report-card-value').text(current) - $el.find('.getpaid-report-card-previous-value').text(previous) - } else { - - $el.find('.getpaid-report-card-value').text(getpaid.currency.format(current)) - $el.find('.getpaid-report-card-previous-value').text(getpaid.currency.format(previous)) - - } - - // Fill in growth. - var percentage = (current == 0 || previous == 0) ? '' : '%'; - if (current > previous) { - var growth = (current - previous) * 100 / previous; - $el.find('.getpaid-report-card-growth') - .addClass('text-success') - .html('' + parseFloat(growth).toFixed(2) + percentage) - - } else if (current < previous) { - var loss = (current - previous) * 100 / previous; - $el.find('.getpaid-report-card-growth') - .addClass('text-danger') - .html('' + parseFloat(loss).toFixed(2) + percentage) - - } - } - - /** - * Draws a graph. - * @param {string} stat - * @param {object} current - * @param {object} previous - */ - function drawGraph(stat, current, previous) { - - // Abort if it is not supported. - if ($('#getpaid-chartjs-' + stat).length == 0) { - return - } - - var labels = [] - var previous_dataset = [] - var current_dataset = [] - var ctx = document.getElementById('getpaid-chartjs-' + stat).getContext('2d'); - - for (var date in current[0]['totals']) { - if (current[0]['totals'].hasOwnProperty(date)) { - labels.push(date) - current_dataset.push(current[0]['totals'][date][stat]) - } - } - - for (var date in previous[0]['totals']) { - if (previous[0]['totals'].hasOwnProperty(date)) { - previous_dataset.push(previous[0]['totals'][date][stat]) - } - } - - var _radius = current[0].interval > 30 ? 0 : 3 - _radius = current[0].interval < 5 ? 10 : _radius - - new Chart( - ctx, - { - type: 'line', - data: { - 'labels': labels, - 'datasets': [ - { - label: $('#getpaid-chartjs-' + stat).closest('.card').find('.card-header strong').text(), - data: current_dataset, - backgroundColor: current[0].interval > 30 ? 'rgba(255, 255, 255, 0)' : 'rgba(54, 162, 235, 0.1)', - borderColor: 'rgb(54, 162, 235)', - pointBackgroundColor: 'rgb(54, 162, 235)', - pointHoverBackgroundColor: 'rgba(54, 162, 235, 0.4 )', - pointRadius: _radius, - pointHoverRadius: 15, - lineTension: current[0].interval > 30 ? 0.1 : 0.4, - borderWidth: current[0].interval > 30 ? 2 : 4, - }, - { - label: 'Previous Period', - data: previous_dataset, - backgroundColor: 'rgba(255, 255, 255, 0)', - borderColor: 'rgb(77, 201, 246 )', - pointBackgroundColor: 'rgb(77, 201, 246 )', - pointHoverBackgroundColor: 'rgba(77, 201, 246, 0.4 )', - pointRadius: _radius, - pointHoverRadius: 15, - lineTension: current[0].interval > 30 ? 0.1 : 0.4, - borderWidth: current[0].interval > 30 ? 2 : 4, - } - ] - }, - options: { - tooltips: { - mode: 'index', - intersect: true, - callbacks: { - label: function (tooltipItem, data) { - var label = data.datasets[tooltipItem.datasetIndex].label || ''; - var value = tooltipItem.yLabel - - if (label) { - label += ': '; - } - - if (window.Intl && ['invoices', 'items', 'tickets_sold'].indexOf(stat) == -1) { - value = getpaid.currency.format(value); - } - - label += value; - return label; - } - } - }, - scales: { - y: { - beginAtZero: true, - - ticks: { - // Include a dollar sign in the ticks - callback: function(value, index, ticks) { - - if (!window.Intl || ['invoices', 'items', 'tickets_sold'].indexOf(stat) > -1) { - return value - } else { - return getpaid.currency.format(value) - } - - } - } - }, - x: { - ticks: { - maxTicksLimit: 12, - - } - } - }, - legend: { - display: true, - position: 'bottom', - labels: { - generateLabels: function (chart) { - - var datasets = chart.data.datasets; - var labels = chart.legend.options.labels; - var usePointStyle = labels.usePointStyle; - - return chart._getSortedDatasetMetas().map(function (meta) { - - var style = meta.controller.getStyle(usePointStyle ? 0 : undefined); - var total = datasets[meta.index].data.reduce(function (total, num) { return total + num }, 0); - - if (window.Intl && ['invoices', 'items', 'tickets_sold'].indexOf(stat) == -1) { - total = getpaid.currency.format(total) - } - - return { - text: datasets[meta.index].label + " : " + total, - fillStyle: style.backgroundColor, - hidden: false, - lineCap: style.borderCapStyle, - lineDash: style.borderDash, - lineDashOffset: style.borderDashOffset, - lineJoin: style.borderJoinStyle, - lineWidth: style.borderWidth, - strokeStyle: style.borderColor, - pointStyle: style.pointStyle, - rotation: style.rotation, - datasetIndex: meta.index - }; - - }, this); - }, - - }, - } - } - - } - ); - } - - // Handle reports. - if ($('.row.getpaid-report-cards').length) { - - // Period selects. - $('.getpaid-filter-earnings select').on( - 'change', function () { - - if ('custom' == $(this).val()) { - $('.getpaid-date-range-picker').removeClass('d-none') - $('.getpaid-date-range-viewer').addClass('d-none') - } else { - $('.getpaid-date-range-picker').addClass('d-none') - $('.getpaid-date-range-viewer').removeClass('d-none') - } - - } - ); - - $('.getpaid-filter-earnings select').trigger('change'); - - wpinvBlock('.single-report-card'); - - getStats('sales', WPInv_Admin.date_range) - .done(function (response) { - - // Fill in date ranges. - $('.getpaid-date-range-picker .getpaid-from').val(response[0].start_date) - $('.getpaid-date-range-picker .getpaid-to').val(response[0].end_date) - - getStats('sales', response[0].previous_range) - .done(function (second_response) { - - wpinvUnblock('.single-report-card'); - - // Fill in report cards. - for (var stat in response[0]) { - if (response[0].hasOwnProperty(stat)) { - feedStat(stat, response[0][stat], second_response[0][stat]) - } - } - - // Draw graphs. - var graphs = WPInv_Admin.graphs; - for (var i = 0; i < graphs.length; i++) { - drawGraph(graphs[i], response, second_response) - } - - }); - }); - - } + // Sync on load. + getpaid_user_edit_sync_state_and_country(); + + // Sync on changes. + $(document.body).on('change', '.getpaid_js_field-country', getpaid_user_edit_sync_state_and_country); + + /** + * Reindexes the tax table. + */ + function wpinv_reindex_tax_table() { + + $('#wpinv_tax_rates tbody tr').each(function (rowIndex) { + + $(this).find(":input[name^='tax_rates']").each(function () { + var name = $(this).attr('name'); + name = name.replace(/\[(\d+)\]/, '[' + (rowIndex) + ']'); + $(this).attr('name', name).attr('id', name); + }); + + }); + + } + + // Inserts a new tax rate row + $('.wpinv_add_tax_rate').on('click', function (e) { + + e.preventDefault() + var html = $('#tmpl-wpinv-tax-rate-row').html() + $('#wpinv_tax_rates tbody').append(html) + wpinv_reindex_tax_table(); + + }); + + $('.wpinv_add_tax_rule').on('click', function (e) { + + e.preventDefault(); + var html = $('#tmpl-wpinv-tax-rule-row').html(); + html = html.replace(/TAX_RULE_KEY/g, random_string()); + $('#wpinv-tax-rules tbody').append(html) + + }); + + // Remove tax row. + $(document).on('click', '#wpinv_tax_rates .wpinv_remove_tax_rate', function (e) { + + e.preventDefault() + $(this).closest('tr').remove(); + wpinv_reindex_tax_table(); + + }); + + $(document).on('click', '#wpinv-tax-rules .wpinv_remove_tax_rule', function (e) { + + e.preventDefault(); + $(this).closest('tr').remove(); + + }); + + var WPInv = { + init: function () { + this.preSetup(); + }, + preSetup: function () { + + var wpinvColorPicker = $('.wpinv-color-picker'); + if (wpinvColorPicker.length) { + wpinvColorPicker.wpColorPicker(); + } + var no_states = $('select.wpinv-no-states'); + if (no_states.length) { + no_states.closest('tr').hide(); + } + // Update base state field based on selected base country + $('select[name="wpinv_settings[default_country]"]:not(.getpaid_js_field-country)').change(function () { + var $this = $(this), + $tr = $this.closest('tr'); + data = { + action: 'wpinv_get_states_field', + country: $(this).val(), + field_name: 'wpinv_settings[default_state]' + }; + $.post(WPInv_Admin.ajax_url, data, function (response) { + if ('nostates' == response) { + $tr.next().hide(); + } else { + $tr.next().show(); + $tr.next().find('select').replaceWith(response); + } + }); + return false; + }); + + // Toggle recaptcha settings. + function toggleRecaptchaSettings() { + + var show = $('#wpinv-settings-enable_recaptcha').is(':checked'); + + $('#wpinv-settings-recaptcha_version').closest('tr').toggle(show); + $('#wpinv-settings-recaptcha_site_key').closest('tr').toggle(show); + $('#wpinv-settings-recaptcha_secret_key').closest('tr').toggle(show); + } + + $('#wpinv-settings-enable_recaptcha').on('change', toggleRecaptchaSettings); + toggleRecaptchaSettings(); + }, + + }; + $('.getpaid-is-invoice-cpt form#post #titlediv [name="post_title"]').attr('readonly', true); + + WPInv.init(); + + /** + * Retrieves a report. + * @param {string} report + * @param {object} args + */ + function getStats(report, args) { + + // Reports. + return $.ajax( + { + url: WPInv_Admin.rest_root + 'getpaid/v1/reports/' + report, + method: 'GET', + data: args, + beforeSend: function (xhr) { + xhr.setRequestHeader('X-WP-Nonce', WPInv_Admin.rest_nonce); + } + } + ); + + } + + /** + * Feeds a stat onto the page. + * @param {string} stat + * @param {string} current + * @param {string} previous + */ + function feedStat(stat, current, previous) { + + // Abort if it is not supported. + var $el = $('.getpaid-report-cards .card.' + stat); + if ($el.length == 0) { + return + } + + // Fill in card revenue. + if (!window.Intl || ['total_invoices', 'total_items', 'refunded_items', 'period_ticket_sales'].indexOf(stat) > -1) { + $el.find('.getpaid-report-card-value').text(current) + $el.find('.getpaid-report-card-previous-value').text(previous) + } else { + + $el.find('.getpaid-report-card-value').text(getpaid.currency.format(current)) + $el.find('.getpaid-report-card-previous-value').text(getpaid.currency.format(previous)) + + } + + // Fill in growth. + var percentage = (current == 0 || previous == 0) ? '' : '%'; + if (current > previous) { + var growth = (current - previous) * 100 / previous; + $el.find('.getpaid-report-card-growth') + .addClass('text-success') + .html('' + parseFloat(growth).toFixed(2) + percentage) + + } else if (current < previous) { + var loss = (current - previous) * 100 / previous; + $el.find('.getpaid-report-card-growth') + .addClass('text-danger') + .html('' + parseFloat(loss).toFixed(2) + percentage) + + } + } + + /** + * Draws a graph. + * @param {string} stat + * @param {object} current + * @param {object} previous + */ + function drawGraph(stat, current, previous) { + + // Abort if it is not supported. + if ($('#getpaid-chartjs-' + stat).length == 0) { + return + } + + var labels = [] + var previous_dataset = [] + var current_dataset = [] + var ctx = document.getElementById('getpaid-chartjs-' + stat).getContext('2d'); + + for (var date in current[0]['totals']) { + if (current[0]['totals'].hasOwnProperty(date)) { + labels.push(date) + current_dataset.push(current[0]['totals'][date][stat]) + } + } + + for (var date in previous[0]['totals']) { + if (previous[0]['totals'].hasOwnProperty(date)) { + previous_dataset.push(previous[0]['totals'][date][stat]) + } + } + + var _radius = current[0].interval > 30 ? 0 : 3 + _radius = current[0].interval < 5 ? 10 : _radius + + new Chart( + ctx, + { + type: 'line', + data: { + 'labels': labels, + 'datasets': [ + { + label: $('#getpaid-chartjs-' + stat).closest('.card').find('.card-header strong').text(), + data: current_dataset, + backgroundColor: current[0].interval > 30 ? 'rgba(255, 255, 255, 0)' : 'rgba(54, 162, 235, 0.1)', + borderColor: 'rgb(54, 162, 235)', + pointBackgroundColor: 'rgb(54, 162, 235)', + pointHoverBackgroundColor: 'rgba(54, 162, 235, 0.4 )', + pointRadius: _radius, + pointHoverRadius: 15, + lineTension: current[0].interval > 30 ? 0.1 : 0.4, + borderWidth: current[0].interval > 30 ? 2 : 4, + }, + { + label: 'Previous Period', + data: previous_dataset, + backgroundColor: 'rgba(255, 255, 255, 0)', + borderColor: 'rgb(77, 201, 246 )', + pointBackgroundColor: 'rgb(77, 201, 246 )', + pointHoverBackgroundColor: 'rgba(77, 201, 246, 0.4 )', + pointRadius: _radius, + pointHoverRadius: 15, + lineTension: current[0].interval > 30 ? 0.1 : 0.4, + borderWidth: current[0].interval > 30 ? 2 : 4, + } + ] + }, + options: { + tooltips: { + mode: 'index', + intersect: true, + callbacks: { + label: function (tooltipItem, data) { + var label = data.datasets[tooltipItem.datasetIndex].label || ''; + var value = tooltipItem.yLabel + + if (label) { + label += ': '; + } + + if (window.Intl && ['invoices', 'items', 'tickets_sold'].indexOf(stat) == -1) { + value = getpaid.currency.format(value); + } + + label += value; + return label; + } + } + }, + scales: { + y: { + beginAtZero: true, + + ticks: { + // Include a dollar sign in the ticks + callback: function (value, index, ticks) { + + if (!window.Intl || ['invoices', 'items', 'tickets_sold'].indexOf(stat) > -1) { + return value + } else { + return getpaid.currency.format(value) + } + + } + } + }, + x: { + ticks: { + maxTicksLimit: 12, + + } + } + }, + legend: { + display: true, + position: 'bottom', + labels: { + generateLabels: function (chart) { + + var datasets = chart.data.datasets; + var labels = chart.legend.options.labels; + var usePointStyle = labels.usePointStyle; + + return chart._getSortwpinvatasetMetas().map(function (meta) { + + var style = meta.controller.getStyle(usePointStyle ? 0 : undefined); + var total = datasets[meta.index].data.reduce(function (total, num) { return total + num }, 0); + + if (window.Intl && ['invoices', 'items', 'tickets_sold'].indexOf(stat) == -1) { + total = getpaid.currency.format(total) + } + + return { + text: datasets[meta.index].label + " : " + total, + fillStyle: style.backgroundColor, + hidden: false, + lineCap: style.borderCapStyle, + lineDash: style.borderDash, + lineDashOffset: style.borderDashOffset, + lineJoin: style.borderJoinStyle, + lineWidth: style.borderWidth, + strokeStyle: style.borderColor, + pointStyle: style.pointStyle, + rotation: style.rotation, + datasetIndex: meta.index + }; + + }, this); + }, + + }, + } + } + + } + ); + } + + // Handle reports. + if ($('.row.getpaid-report-cards').length) { + + // Period selects. + $('.getpaid-filter-earnings select').on( + 'change', function () { + + if ('custom' == $(this).val()) { + $('.getpaid-date-range-picker').removeClass('d-none') + $('.getpaid-date-range-viewer').addClass('d-none') + } else { + $('.getpaid-date-range-picker').addClass('d-none') + $('.getpaid-date-range-viewer').removeClass('d-none') + } + + } + ); + + $('.getpaid-filter-earnings select').trigger('change'); + + wpinvBlock('.single-report-card'); + + getStats('sales', WPInv_Admin.date_range) + .done(function (response) { + + // Fill in date ranges. + $('.getpaid-date-range-picker .getpaid-from').val(response[0].start_date) + $('.getpaid-date-range-picker .getpaid-to').val(response[0].end_date) + + getStats('sales', response[0].previous_range) + .done(function (second_response) { + + wpinvUnblock('.single-report-card'); + + // Fill in report cards. + for (var stat in response[0]) { + if (response[0].hasOwnProperty(stat)) { + feedStat(stat, response[0][stat], second_response[0][stat]) + } + } + + // Draw graphs. + var graphs = WPInv_Admin.graphs; + for (var i = 0; i < graphs.length; i++) { + drawGraph(graphs[i], response, second_response) + } + + }); + }); + + } }); function wpinvBlock(el, message) { message = typeof message != 'undefined' && message !== '' ? message : WPInv_Admin.loading; - var $el = jQuery( el ) + var $el = jQuery(el) // Do not block twice. - if ( ! $el.data( 'GetPaidIsBlocked' ) ) { - $el.data( 'GetPaidIsBlocked', 1 ) - $el.data( 'GetPaidWasRelative', $el.hasClass( 'position-relative' ) ) - $el.addClass( 'position-relative' ) - $el.append( '
' + message +'
' ) + if (!$el.data('GetPaidIsBlocked')) { + $el.data('GetPaidIsBlocked', 1) + $el.data('GetPaidWasRelative', $el.hasClass('position-relative')) + $el.addClass('position-relative') + $el.append('
' + message + '
') } else { - $el.data( 'GetPaidIsBlocked', $el.data( 'GetPaidIsBlocked' ) + 1 ) - } + $el.data('GetPaidIsBlocked', $el.data('GetPaidIsBlocked') + 1) + } } function wpinvUnblock(el) { - var $el = jQuery( el ) + var $el = jQuery(el) - if ( $el.data( 'GetPaidIsBlocked' ) ) { + if ($el.data('GetPaidIsBlocked')) { - if ( $el.data( 'GetPaidIsBlocked' ) - 1 > 0 ) { - $el.data( 'GetPaidIsBlocked', $el.data( 'GetPaidIsBlocked' ) - 1 ) - return - } + if ($el.data('GetPaidIsBlocked') - 1 > 0) { + $el.data('GetPaidIsBlocked', $el.data('GetPaidIsBlocked') - 1) + return + } - $el.data( 'GetPaidIsBlocked', 0 ) + $el.data('GetPaidIsBlocked', 0) - if ( ! $el.data( 'GetPaidWasRelative') ) { - $el.removeClass( 'position-relative' ) + if (!$el.data('GetPaidWasRelative')) { + $el.removeClass('position-relative') } - $el.children( '.getpaid-block-ui' ).remove() + $el.children('.getpaid-block-ui').remove() } diff --git a/includes/admin/class-getpaid-installer.php b/includes/admin/class-getpaid-installer.php index cd21b413..ce033978 100644 --- a/includes/admin/class-getpaid-installer.php +++ b/includes/admin/class-getpaid-installer.php @@ -501,11 +501,13 @@ public static function get_db_schema() { discount DECIMAL(16,4) NOT NULL DEFAULT 0, subtotal DECIMAL(16,4) NOT NULL DEFAULT 0, price DECIMAL(16,4) NOT NULL DEFAULT 0, + price_id INT(11) NOT NULL DEFAULT 0, meta TEXT, fees TEXT, PRIMARY KEY (ID), KEY item_id (item_id), - KEY post_id (post_id) + KEY post_id (post_id), + KEY price_id (price_id) ) $charset_collate;"; // Customers. diff --git a/includes/admin/meta-boxes/class-getpaid-meta-box-item-details.php b/includes/admin/meta-boxes/class-getpaid-meta-box-item-details.php index 5a80ef03..fecb4c01 100644 --- a/includes/admin/meta-boxes/class-getpaid-meta-box-item-details.php +++ b/includes/admin/meta-boxes/class-getpaid-meta-box-item-details.php @@ -8,7 +8,7 @@ */ if ( ! defined( 'ABSPATH' ) ) { - exit; // Exit if accessed directly + exit; // Exit if accessed directly } /** @@ -17,18 +17,20 @@ class GetPaid_Meta_Box_Item_Details { /** - * Output the metabox. - * - * @param WP_Post $post - */ + * Output the metabox. + * + * @param WP_Post $post + */ public static function output( $post ) { - // Prepare the item. $item = new WPInv_Item( $post ); // Nonce field. wp_nonce_field( 'getpaid_meta_nonce', 'getpaid_meta_nonce' ); + // Variable prices. + $variable_prices = $item->get_variable_prices(); + // Set the currency position. $position = wpinv_currency_position(); @@ -51,16 +53,16 @@ public static function output( $post ) { .bsui label.col-sm-3.col-form-label { font-weight: 600; } - -
+
+
-
-
+
+
@@ -75,7 +77,7 @@ public static function output( $post ) { - + @@ -89,80 +91,104 @@ public static function output( $post ) {
-
select( - array( - 'id' => 'wpinv_recurring_period', - 'name' => 'wpinv_recurring_period', - 'label' => __( 'Period', 'invoicing' ), - 'placeholder' => __( 'Select Period', 'invoicing' ), - 'value' => $item->get_recurring_period( 'edit' ), - 'select2' => true, - 'data-allow-clear' => 'false', - 'options' => array( - 'D' => __( 'day(s)', 'invoicing' ), - 'W' => __( 'week(s)', 'invoicing' ), - 'M' => __( 'month(s)', 'invoicing' ), - 'Y' => __( 'year(s)', 'invoicing' ), - ), + aui()->select( + array( + 'id' => 'wpinv_recurring_period', + 'name' => 'wpinv_recurring_period', + 'label' => __( 'Period', 'invoicing' ), + 'placeholder' => __( 'Select Period', 'invoicing' ), + 'value' => $item->get_recurring_period( 'edit' ), + 'select2' => true, + 'data-allow-clear' => 'false', + 'options' => array( + 'D' => __( 'day(s)', 'invoicing' ), + 'W' => __( 'week(s)', 'invoicing' ), + 'M' => __( 'month(s)', 'invoicing' ), + 'Y' => __( 'year(s)', 'invoicing' ), ), - true - ); + ), + true + ); ?>
+
input( + array( + 'id' => 'wpinv_variable_pricing', + 'name' => 'wpinv_variable_pricing', + 'type' => 'checkbox', + 'label' => apply_filters( 'wpinv_variable_pricing_toggle_text', __( 'Enable variable pricing', 'invoicing' ) ), + 'value' => '1', + 'checked' => $item->has_variable_pricing(), + 'no_wrap' => true, + ), + true + ); + + do_action( 'wpinv_item_details_metabox_variable_pricing_checkbox', $item ); + ?> +
+
- // Dynamic pricing. - if ( $item->supports_dynamic_pricing() ) { - - do_action( 'wpinv_item_details_metabox_before_dynamic_pricing_checkbox', $item ); - - // NYP toggle. - aui()->input( - array( - 'id' => 'wpinv_name_your_price', - 'name' => 'wpinv_name_your_price', - 'type' => 'checkbox', - 'label' => apply_filters( 'wpinv_name_your_price_toggle_text', __( 'Let customers name their price', 'invoicing' ) ), - 'value' => '1', - 'checked' => $item->user_can_set_their_price(), - 'no_wrap' => true, - ), - true - ); +
+
+ supports_dynamic_pricing() ) { - } + do_action( 'wpinv_item_details_metabox_before_dynamic_pricing_checkbox', $item ); - // Subscriptions. - do_action( 'wpinv_item_details_metabox_before_subscription_checkbox', $item ); + // NYP toggle. aui()->input( array( - 'id' => 'wpinv_is_recurring', - 'name' => 'wpinv_is_recurring', + 'id' => 'wpinv_name_your_price', + 'name' => 'wpinv_name_your_price', 'type' => 'checkbox', - 'label' => apply_filters( 'wpinv_is_recurring_toggle_text', __( 'Charge customers a recurring amount for this item', 'invoicing' ) ), + 'label' => apply_filters( 'wpinv_name_your_price_toggle_text', __( 'Let customers name their price', 'invoicing' ) ), 'value' => '1', - 'checked' => $item->is_recurring(), + 'checked' => $item->user_can_set_their_price(), 'no_wrap' => true, ), true ); - do_action( 'wpinv_item_details_metabox_subscription_checkbox', $item ); + + do_action( 'wpinv_item_details_metabox_dynamic_pricing_checkbox', $item ); + } + + // Subscriptions. + do_action( 'wpinv_item_details_metabox_before_subscription_checkbox', $item ); + + aui()->input( + array( + 'id' => 'wpinv_is_recurring', + 'name' => 'wpinv_is_recurring', + 'type' => 'checkbox', + 'label' => apply_filters( 'wpinv_is_recurring_toggle_text', __( 'Charge customers a recurring amount for this item', 'invoicing' ) ), + 'value' => '1', + 'checked' => $item->is_recurring(), + 'no_wrap' => true, + ), + true + ); + do_action( 'wpinv_item_details_metabox_subscription_checkbox', $item ); ?>
@@ -171,15 +197,16 @@ public static function output( $post ) {
-
+
+ supports_dynamic_pricing() ) : ?> -
+