Plugin Directory

Changeset 3259100


Ignore:
Timestamp:
03/20/2025 11:50:54 AM (13 months ago)
Author:
ceretax
Message:

CereTax Plugin 1.4.0

Location:
ceretax
Files:
25 added
5 edited

Legend:

Unmodified
Added
Removed
  • ceretax/trunk/ceretax.php

    r3248052 r3259100  
    44 * Plugin URI: https://wordpress.org/plugins/ceretax/
    55 * Description: Simplify sales tax complexity with CereTax for WooCommerce.
    6  * Version: 1.3.8
     6 * Version: 1.4.0
    77 * Author: CereTax, Inc.
    88 * Author URI: https://www.ceretax.com/
  • ceretax/trunk/changelog.txt

    r3248052 r3259100  
    3232
    33332025-02-19 - version 1.3.6
    34  * fix - * fix - If fee name changed from admin option, destroy order calculation issue
     34 * fix - If fee name changed from admin option, destroy order calculation issue
    3535
    36362025-02-24 - version 1.3.7
    3737* fix - If the tax showing zero in order calculation issue
    3838
    39 2025-02-27 - version 1.3.8
    40 * fix - Restore to 1.3.6 functionality
     392025-03-08 - version 1.3.9
     40* fix - Postcode in lower case causing tax calculation issue
    4141
     422025-03-19 - version 1.4.0
     43* add - Disable CereTax for refund orders
  • ceretax/trunk/inc/admin/class-cwafc-admin-action.php

    r3248052 r3259100  
    4242            add_action( 'created_product_cat', array( $this, 'action__cwafc_save_custom_field_in_product_category' ), 10, 2 );
    4343            add_action( 'edited_product_cat', array( $this, 'action__cwafc_save_custom_field_in_product_category' ), 10, 2 );
     44            // Add admin order line item column.
     45            add_action( 'woocommerce_admin_order_item_headers', array( $this, 'action__cwafc_woocommerce_admin_order_item_headers' ), 20 );
     46            // Populate the new column with custom data.
     47            add_action( 'woocommerce_admin_order_item_values', array( $this, 'action__cwafc_woocommerce_admin_order_item_values' ), 10, 3 );
     48            // Add admin order style and script.
    4449            add_action( 'admin_footer', array( $this, 'action__cwafc_admin_footer_function' ), 20 );
    4550        }
     
    152157
    153158                array(
     159                    'name'    => __( 'Disable CereTax For Refund Orders', 'ceretax' ),
     160                    'type'    => 'checkbox',
     161                    'id'      => CWAFC_PREFIX . '_cere_tax_refund_disable',
     162                    'class'   => 'cere_tax_checkbox',
     163                    'default' => 'no',
     164                ),
     165
     166                array(
    154167                    'name'    => __( 'Post finalized transactions to CereTax', 'ceretax' ),
    155168                    'type'    => 'checkbox',
     
    238251                    'autoload' => false,
    239252                    'default'  => 'Tax',
     253                ),
     254
     255                array(
     256                    'name'     => __( 'Line Item Tax Column Name', 'ceretax' ),
     257                    'type'     => 'text',
     258                    'desc'     => __( 'Enter the admin order line item tax column name. If you are using a multilingual plugin do not make any changes here.', 'ceretax' ),
     259                    'id'       => CWAFC_PREFIX . '_cere_tax_line_item_column_name',
     260                    'desc_tip' => true,
     261                    'autoload' => false,
     262                    'default'  => 'Tax Total',
    240263                ),
    241264
     
    384407
    385408        /**
    386          * Admin footer style
     409         * Admin footer script & style
    387410         *
    388411         * @return void
    389412         */
    390413        public function action__cwafc_admin_footer_function() {
    391 
     414            $order_id = null;
    392415            if ( ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) || ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) ) {
    393416                if ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) {
     
    412435            }
    413436            if ( ! empty( $order_id ) && ! empty( $ceretax_data ) && $fee_amount > 0 ) { ?>
    414             <style>
    415                 /* Hide the 3rd tr of .wc-order-totals if .wc-used-coupons is found */
    416                 .wc-order-data-row:has(.wc-used-coupons) .wc-order-totals:first-of-type tr:nth-of-type(3) {
    417                     display: none !important;
     437                <style>
     438                    /* Hide the 3rd tr of .wc-order-totals if .wc-used-coupons is found */
     439                    .wc-order-data-row:has(.wc-used-coupons) .wc-order-totals:first-of-type tr:nth-of-type(3) {
     440                        display: none !important;
     441                    }
     442
     443                    /* Hide the 2nd tr of .wc-order-totals if .wc-used-coupons is not found */
     444                    .wc-order-data-row:not(:has(.wc-used-coupons)) .wc-order-totals:first-of-type tr:nth-of-type(2) {
     445                        display: none !important;
     446                    }
     447
     448                </style>
     449            <?php } if ( ! empty( $order_id ) && ! empty( $ceretax_data ) ) { ?>
     450                <style>
     451                    /* Hide Tax column for ceretax order item list */
     452                    .woocommerce_order_items tr th.line_tax,
     453                    .woocommerce_order_items tr td.line_tax {
     454                        display: none !important;
     455                    }
     456
     457                </style>
     458            <?php
     459            }
     460
     461            // Refund order script.
     462            if ( ! empty( $order_id ) && ! empty( $ceretax_data ) ) { ?>
     463            <script>
     464                jQuery(function($) {
     465                    jQuery( '#woocommerce-order-items' ).on( 'change', 'input.refund_order_item_qty', function() {
     466                        var $row               = $( this ).closest( 'tr.item' );
     467                        var qty                = $row.find( 'input.quantity' ).val();
     468                        var refund_qty         = $( this ).val();
     469                        var ceretax_line_total = $( 'input.ceretax_line_total', $row );
     470                        var line_total         = $( 'input.line_total', $row );
     471                        var refund_line_total  = $( 'input.refund_line_total', $row );
     472
     473                        var unit_line_ceretax_total = accounting.unformat( ceretax_line_total.attr( 'data-line-tax' ), woocommerce_admin.mon_decimal_point ) / qty;
     474                        ceretax_line_total.val(
     475                            parseFloat( accounting.formatNumber( unit_line_ceretax_total * refund_qty, 2, '' ) )
     476                            .toString()
     477                            .replace( '.', woocommerce_admin.mon_decimal_point )
     478                        ).trigger( 'change' );
     479
     480                        // Totals
     481                        var unit_total = accounting.unformat( line_total.attr( 'data-total' ), woocommerce_admin.mon_decimal_point ) / qty;
     482
     483                        refund_line_total.val(
     484                            parseFloat( accounting.formatNumber( unit_total * refund_qty, woocommerce_admin_meta_boxes.rounding_precision, '' ) )
     485                                .toString()
     486                                .replace( '.', woocommerce_admin.mon_decimal_point )
     487                        ).trigger( 'change' );
     488
     489                        $( this ).trigger( 'refund_quantity_changed' );
     490
     491                    });
     492                    $( '#woocommerce-order-items' ).on( 'change', '.refund input.ceretax_line_total', function() {
     493
     494                        var refund_amount     = 0;
     495                        var $items            = $( '.woocommerce_order_items' ).find( 'tr.item, tr.fee, tr.shipping' );
     496                        var round_at_subtotal = 'yes' === woocommerce_admin_meta_boxes.round_at_subtotal;
     497
     498                        // Restrict value based on data-line-tax
     499                        var maxValue   = parseFloat( $( this ).data('line-tax') ) || 0;
     500                        var inputValue = parseFloat( $( this ).val() ) || 0;
     501
     502                        if ( inputValue > maxValue ) {
     503                            alert( 'You cannot refund the line item tax exceeding the allowed limit of ' + maxValue + '.' );
     504                            $( this ).val( maxValue );
     505                        }
     506
     507                        $items.each(function() {
     508                            var $row               = $( this );
     509                            var refund_cost_fields = $row.find( '.refund input:not(.refund_order_item_qty)' );
     510
     511                            refund_cost_fields.each(function( index, el ) {
     512                                var field_amount = accounting.unformat( $( el ).val() || 0, woocommerce_admin.mon_decimal_point );
     513                                refund_amount += parseFloat( round_at_subtotal ?
     514                                    field_amount :
     515                                    accounting.formatNumber( field_amount, woocommerce_admin_meta_boxes.currency_format_num_decimals, '' ) );
     516                            });
     517                        });
     518
     519                        $( '#refund_amount' ).val(
     520                            accounting.formatNumber(
     521                                refund_amount,
     522                                woocommerce_admin_meta_boxes.currency_format_num_decimals,
     523                                '',
     524                                woocommerce_admin.mon_decimal_point
     525                        ) ).trigger( 'change' );
     526
     527                    });
     528                });
     529            </script>
     530            <?php }
     531
     532        }
     533
     534        /**
     535         * Add admin order line item column header.
     536         *
     537         * @param object $order Order object.
     538         * @return void
     539         */
     540        public function action__cwafc_woocommerce_admin_order_item_headers( $order ) {
     541            $ceretax_data_lineitem = get_post_meta( $order->get_id(), 'ceretax_data_lineitem', true );
     542            if ( ! empty( $ceretax_data_lineitem ) ) {
     543                $cere_tax_line_item_column_name = get_option( CWAFC_PREFIX . '_cere_tax_line_item_column_name', 'Tax Total' );
     544                echo '<th class="ceretax_line_heading" width="7%">' . esc_html( $cere_tax_line_item_column_name ) . '</th>';
     545            }
     546        }
     547
     548        /**
     549         * Add admin order line item column header.
     550         *
     551         * @param object $product Product object.
     552         * @param object $item Product item object.
     553         * @param string $item_id Order object.
     554         * @return void
     555         */
     556        public function action__cwafc_woocommerce_admin_order_item_values( $product, $item, $item_id ) {
     557
     558            $order_id = null;
     559            if ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) {
     560                $order_id = $_GET['post'];
     561            } else if ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) {
     562                $order_id = $_GET['id'];
     563            } else {
     564                $order_id = null;
     565            }
     566
     567            $cere_tax_name         = get_option( CWAFC_PREFIX . '_cere_tax_name', 'Tax' );
     568            $order                 = wc_get_order( $order_id );
     569            $ceretax_data_lineitem = json_decode( get_post_meta( $order_id, 'ceretax_data_lineitem', true ) );
     570            $ceretax_data          = json_decode( get_post_meta( $order_id, 'ceretax_data', true ) );
     571
     572            if ( ! empty( $ceretax_data_lineitem ) && ! empty( $ceretax_data ) && ! empty( $order ) ) {
     573
     574                if ( ! empty( $product ) ) {
     575
     576                    // $refunded_qty = -1 * $order->get_total_refunded_for_item( $item_id );
     577
     578                    echo '<td class="ceretax_line_value" width="7%">';
     579                    if ( is_object( $ceretax_data_lineitem ) && is_object( $ceretax_data ) ) {
     580                        $ceretax_items_data = $ceretax_data_lineitem->invoice->lineItems;
     581                        $ceretax_data       = $ceretax_data->invoice->lineItems;
     582                        if ( ! empty( $ceretax_items_data ) && ! empty( $ceretax_data ) ) {
     583                            $product_id = $product->get_id();
     584                            $filtered   = array_filter( $ceretax_items_data, function ( $item ) use ( $product_id ) {
     585                                return isset( $item->itemNumber ) && $item->itemNumber == $product_id;
     586                            });
     587
     588                            $refunded_filtered = array_filter( $ceretax_data, function ( $refunded_item ) use ( $product_id ) {
     589                                return isset( $refunded_item->itemNumber ) && $refunded_item->itemNumber == $product_id;
     590                            });
     591                            $total_line_tax          = ! empty( $filtered ) ? reset( $filtered )->totalTaxLine : null;
     592                            $total_line_refunded_tax = ! empty( $refunded_filtered ) ? reset( $refunded_filtered )->totalTaxLine : null;
     593                            $ceretax_refunded_line_item_tax = $item->get_meta( '_ceretax_refunded_line_item_tax' );
     594                            echo '<div class="view">';
     595                                echo wc_price( $total_line_tax, array( 'currency' => $order->get_currency() ) );
     596                                if ( is_array( $order->get_refunds() ) && count( $order->get_refunds() ) > 0 && ! empty( $ceretax_refunded_line_item_tax ) ) {
     597                                    echo '<small class="refunded">' . wc_price( $ceretax_refunded_line_item_tax, array( 'currency' => $order->get_currency() ) ) . '</small>';
     598                                }
     599                            echo '</div>';
     600
     601                            echo '<div class="refund" style="display: none;">
     602                                <input type="text" name="ceretax_line_total[' . absint( $item_id ) . ']" placeholder="' . esc_attr( wc_format_localized_price( 0 ) ) . '" class="refund_line_tax ceretax_line_total wc_input_price" size="4" data-line-tax="' . esc_attr( wc_format_localized_price( $total_line_tax ) ) . '" />
     603                            </div>';
     604                        }
     605                    }
     606                    echo '</td>';
     607               
     608                } elseif ( $item instanceof WC_Order_Item_Fee && $item->get_name() === $cere_tax_name ) {
     609                // } elseif ( isset( $item['name'] ) && $item['name'] === $cere_tax_name ) {
     610                    echo '<td class="ceretax_line_value" width="7%"></td>';
     611                } else {
     612                    echo '<td class="ceretax_line_value" width="7%">';
     613                        // echo '<div class="refund" style="display: none;">
     614                        //  <input type="text" name="ceretax_line_total[' . absint( $item_id ) . ']" placeholder="' . esc_attr( wc_format_localized_price( 0 ) ) . '" class="refund_line_tax ceretax_line_total wc_input_price" size="4" />
     615                        // </div>';
     616                    echo '</td>';
    418617                }
    419 
    420                 /* Hide the 2nd tr of .wc-order-totals if .wc-used-coupons is not found */
    421                 .wc-order-data-row:not(:has(.wc-used-coupons)) .wc-order-totals:first-of-type tr:nth-of-type(2) {
    422                     display: none !important;
    423                 }
    424 
    425             </style>
    426             <?php } if ( ! empty( $order_id ) && ! empty( $ceretax_data ) ) { ?>
    427             <style>
    428                 /* Hide Tax column for ceretax order item list */
    429                 .woocommerce_order_items tr th.line_tax,
    430                 .woocommerce_order_items tr td.line_tax {
    431                     display: none !important;
    432                 }
    433 
    434             </style>
    435             <?php
    436618            }
    437619        }
  • ceretax/trunk/inc/class-cwafc.php

    r3248052 r3259100  
    6666            // Plugin activation hook.
    6767            register_activation_hook( CWAFC_FILE, array( $this, 'action__cwafc_plugin_activation' ) );
    68             // Init hook.
    69             // add_action( 'init', array( $this, 'action__cwafc_init' ) );
    7068            // Make plugin HPOS compatible.
    7169            add_action( 'before_woocommerce_init', array( $this, 'action__cwafc_before_woocommerce_init' ) );
     
    104102            // Modify the fee name dynamically when orders are loaded.
    105103            add_filter( 'woocommerce_order_get_items', array( $this, 'filter__cwafc_modify_fee_name_dynamically' ), 10, 2 );
     104            // Update tax calculation on subscription.
     105            add_action( 'woocommerce_checkout_create_subscription', array( $this, 'action__cwafc_update_tax_calculation_for_subscription' ), 10 );
     106            // Clear Avatax from Ceretax renewal orders.
     107            add_filter( 'wcs_new_order_created', array( $this, 'action__cwafc_clear_avatx_new_order_created' ), 10, 3 );
    106108        }
    107109
     
    115117
    116118            $ceretax_data = get_post_meta( $order_id, 'ceretax_data', true );
     119
     120            // If it's empty, return early.
    117121            if ( empty( $ceretax_data ) ) {
    118122                return;
     
    120124            $ceretax_data      = json_decode( $ceretax_data );
    121125            $cere_tax_name     = get_option( CWAFC_PREFIX . '_cere_tax_name', 'Tax' );
    122             $total_tax_invoice = abs( $ceretax_data->invoice->totalTaxInvoice );
    123 
     126            $total_tax_invoice = $ceretax_data->invoice->totalTaxInvoice;
    124127            $order             = wc_get_order( $order_id );
    125128            $fee_amount        = null;
    126129            $order_total_fees  = $order->get_total_fees();
    127130            $order_remain_fees = 0;
     131
     132            // If refunded order.
     133            if ( is_array( $order->get_refunds() ) && count( $order->get_refunds() ) > 0 ) {
     134                $ceretax_data_lineitem = get_post_meta( $order_id, 'ceretax_data_lineitem', true );
     135                $ceretax_data_lineitem = json_decode( $ceretax_data_lineitem );
     136                $total_tax_invoice     = isset( $ceretax_data_lineitem->invoice->totalTaxInvoice ) ? $ceretax_data_lineitem->invoice->totalTaxInvoice : null;
     137            }
     138
    128139            foreach ( $order->get_fees() as $fee_id => $fee ) {
    129140                if ( $fee->get_name() === $cere_tax_name ) {
     
    136147                }
    137148            }
    138 
    139149            if ( 0 < $order_remain_fees ) {
    140150                echo '<tr>';
    141                 echo '<td class="label">' . __( 'Fees', 'ceretax' ) . ':</td>';
     151                echo '<td class="label">' . esc_html( __( 'Fees', 'ceretax' ) ) . ':</td>';
    142152                echo '<td width="1%"></td>';
    143                 echo '<td class="total">' . wc_price( $order_remain_fees ) . '</td>';
     153                echo '<td class="total">' . wc_price( $order_remain_fees, array( 'currency' => $order->get_currency() ) ) . '</td>';
    144154                echo '</tr>';
    145155            }
     
    147157            echo '<td class="label">' . esc_html( $cere_tax_name ) . ':</td>';
    148158            echo '<td width="1%"></td>';
    149             echo '<td class="total">' . wc_price( $total_tax_invoice ) . '</td>';
     159            echo '<td class="total">' . wc_price( $total_tax_invoice, array( 'currency' => $order->get_currency() ) ) . '</td>';
    150160            echo '</tr>';
    151161        }
     
    254264            $country   = isset( $_POST['country'] ) ? sanitize_text_field( wp_unslash( $_POST['country'] ) ) : '';
    255265            $state     = isset( $_POST['state'] ) ? sanitize_text_field( wp_unslash( $_POST['state'] ) ) : '';
    256             $postcode  = isset( $_POST['postcode'] ) ? sanitize_text_field( wp_unslash( $_POST['postcode'] ) ) : '';
     266            $postcode  = isset( $_POST['postcode'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['postcode'] ) ) ) : '';
    257267
    258268            // Call your third-party API here.
     
    299309            $country            = isset( $_POST['country'] ) ? sanitize_text_field( wp_unslash( $_POST['country'] ) ) : '';
    300310            $state              = isset( $_POST['state'] ) ? sanitize_text_field( wp_unslash( $_POST['state'] ) ) : '';
    301             $postcode           = isset( $_POST['postcode'] ) ? sanitize_text_field( wp_unslash( $_POST['postcode'] ) ) : '';
     311            $postcode           = isset( $_POST['postcode'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['postcode'] ) ) ) : '';
    302312            $address_validation = isset( $_POST['address_validation'] ) ? sanitize_text_field( wp_unslash( $_POST['address_validation'] ) ) : '';
    303313
     
    316326                    'city'         => $city,
    317327                    'state'        => $state,
     328                    'postalCode'   => $postcode,
    318329                ),
    319330            );
     
    366377                    $validated_state          = $data['results'][0]['validatedAddressDetails']['state'];
    367378                    $validated_country        = $data['results'][0]['validatedAddressDetails']['country'];
    368                     $validated_postal_code    = $data['results'][0]['validatedAddressDetails']['postalCode'];
     379                    $validated_postal_code    = strtoupper( $data['results'][0]['submittedAddressDetails']['postalCode'] );
     380
     381                    // Update submitted postal code.
     382                    $validated_address_details['postalCode'] = $validated_postal_code;
    369383
    370384                    if ( 'shipping' === $address_validation ) {
     
    487501                $calc_shipping_city      = isset( $_POST['calc_shipping_city'] ) ? sanitize_text_field( wp_unslash( $_POST['calc_shipping_city'] ) ) : '';
    488502                $calc_shipping_state     = isset( $_POST['calc_shipping_state'] ) ? sanitize_text_field( wp_unslash( $_POST['calc_shipping_state'] ) ) : '';
    489                 $calc_shipping_postcode  = isset( $_POST['calc_shipping_postcode'] ) ? sanitize_text_field( wp_unslash( $_POST['calc_shipping_postcode'] ) ) : '';
     503                $calc_shipping_postcode  = isset( $_POST['calc_shipping_postcode'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['calc_shipping_postcode'] ) ) ) : '';
    490504
    491505                $tax_rate = $this->cwafc_get_tax_rate_from_api(
     
    520534                    $city      = isset( $_POST['s_city'] ) ? sanitize_text_field( wp_unslash( $_POST['s_city'] ) ) : '';
    521535                    $state     = isset( $_POST['s_state'] ) ? sanitize_text_field( wp_unslash( $_POST['s_state'] ) ) : '';
    522                     $postcode  = isset( $_POST['s_postcode'] ) ? sanitize_text_field( wp_unslash( $_POST['s_postcode'] ) ) : '';
     536                    $postcode  = isset( $_POST['s_postcode'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['s_postcode'] ) ) ) : '';
    523537                } else {
    524538                    $address_1 = isset( $_POST['address'] ) ? sanitize_text_field( wp_unslash( $_POST['address'] ) ) : '';
     
    527541                    $city      = isset( $_POST['city'] ) ? sanitize_text_field( wp_unslash( $_POST['city'] ) ) : '';
    528542                    $state     = isset( $_POST['state'] ) ? sanitize_text_field( wp_unslash( $_POST['state'] ) ) : '';
    529                     $postcode  = isset( $_POST['postcode'] ) ? sanitize_text_field( wp_unslash( $_POST['postcode'] ) ) : '';
     543                    $postcode  = isset( $_POST['postcode'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_POST['postcode'] ) ) ) : '';
    530544                }
    531545
     
    747761        public function action__cwafc_checkout_field_update_order_meta( $order_id ) {
    748762            $ceretax_data = WC()->session->get( 'ceretax_data' );
    749             update_post_meta( $order_id, 'ceretax_data', wp_json_encode( $ceretax_data ) );
     763            if ( ! empty( $ceretax_data ) ) {
     764                update_post_meta( $order_id, 'ceretax_data', wp_json_encode( $ceretax_data ) );
     765            }
    750766        }
    751767
     
    763779                $ceretax_items_data = $ceretax_data->invoice->lineItems;
    764780                if ( ! empty( $ceretax_items_data ) ) {
    765                     $tax_table .= '<table class="woocommerce_order_items ceratax-tax-table">';
     781                    $tax_table .= '<tr><td colspan="7"><table class="woocommerce_order_items ceratax-tax-table">';
    766782                    foreach ( $ceretax_items_data as $ceretax_item_data_key => $ceretax_item_data ) {
    767783                        if ( ! empty( $ceretax_item_data->taxes ) ) {
     
    804820                        }
    805821                    }
    806                     $tax_table .= '</table>';
     822                    $tax_table .= '</table></td></tr>';
    807823                }
    808824            }
     
    823839            $order_ceretax_data         = get_post_meta( $order_id, 'ceretax_data', true );
    824840            $order_avatax_data          = get_post_meta( $order_id, '_wc_avatax_tax_calculated', true );
    825             $order_contains_renewal     = ( function_exists( 'wcs_order_contains_renewal' ) ) ? wcs_order_contains_renewal( $order_id ) : true;
    826841            // Check if order have other tax system.
    827842            if ( empty( $order_ceretax_data ) && ! empty( $order_avatax_data ) ) {
     
    860875
    861876            if ( is_admin() && ! empty( $res ) ) {
    862 
     877                $fee_exists = false;
    863878                foreach ( $order->get_fees() as $fee ) {
    864879                    if ( $fee->get_name() === $cere_tax_name ) {
     
    932947            }
    933948
    934             if ( ! empty( $res ) ) {
    935 
     949            if ( isset( $res ) && null !== $res ) {
     950                $fee_exists = false;
    936951                foreach ( $r_order->get_fees() as $fee ) {
    937952                    if ( $fee->get_name() === $cere_tax_name ) {
     
    975990            $order_ceretax_data         = get_post_meta( $order->get_id(), 'ceretax_data', true );
    976991            $order_avatax_data          = get_post_meta( $order->get_id(), '_wc_avatax_tax_calculated', true );
    977             $order_contains_renewal     = ( function_exists( 'wcs_order_contains_renewal' ) ) ? wcs_order_contains_renewal( $order->get_id() ) : true;
    978992            // Check if order have other tax system.
    979993            if ( empty( $order_ceretax_data ) && ! empty( $order_avatax_data ) ) {
     
    10621076            $refund = wc_get_order( $refund_id );
    10631077
     1078            // Save ceretax line item tax in order line items.
     1079            $line_item_result = array();
     1080            if ( isset( $_POST['line_item_tax_totals'] ) && ! empty( $_POST['line_item_tax_totals'] ) ) {
     1081                $line_item_json   = stripslashes( $_POST['line_item_tax_totals'] );
     1082                $line_item_data   = json_decode( $line_item_json, true );
     1083                $line_item_result = array_map( function( $item ) {
     1084                    return $item['undefined'];
     1085                }, $line_item_data );
     1086                $line_item_result = array_filter( $line_item_result, function( $value ) {
     1087                    return ! empty( $value );
     1088                });
     1089                if ( ! empty( $line_item_result ) && ! empty( $order->get_items() ) ) {
     1090                    foreach ( $order->get_items() as $item_id => $item ) {
     1091                        if ( array_key_exists( $item_id, $line_item_result ) ) {
     1092                            $item->add_meta_data( '_ceretax_refunded_line_item_tax', $line_item_result[$item_id], true );
     1093                            $item->save();
     1094                        }
     1095                    }
     1096                }
     1097            }
     1098
    10641099            $cere_tax_post_transactions = get_option( CWAFC_PREFIX . '_cere_tax_post_transactions' );
    10651100            $cere_tax_name              = get_option( CWAFC_PREFIX . '_cere_tax_name', 'Tax' );
    1066 
    1067             if ( 'yes' !== $cere_tax_post_transactions ) {
     1101            $cere_tax_refund_disable    = get_option( CWAFC_PREFIX . '_cere_tax_refund_disable' );
     1102
     1103            if ( 'yes' !== $cere_tax_post_transactions || 'yes' === $cere_tax_refund_disable ) {
    10681104                return false;
    10691105            }
     
    10881124            }
    10891125            $res = '';
    1090             if ( ! empty( $address_data ) && ! empty( $order->get_items() ) ) {
    1091                 $res = $this->cwafc_calculate_cere_tax_refunded( $address_data, $order );
    1092             }
    1093 
    1094             if ( ! empty( $res ) ) {
     1126            if ( ! empty( $address_data ) && ! empty( $refund->get_items() ) ) {
     1127                $res = $this->cwafc_calculate_cere_tax_refunded( $address_data, $refund, $order );
     1128            }
     1129
     1130            $is_run = false;
     1131            if ( $is_run && ! empty( $res ) ) {
    10951132                $fee_exists = false;
    10961133                foreach ( $order->get_fees() as $fee ) {
     
    11111148                    $item_fee->set_amount( $new_fee_amount );
    11121149                    $item_fee->set_total( $new_fee_amount );
    1113                     $order->add_item( $item_fee );
     1150                    $refund->add_item( $item_fee );
    11141151                }
    11151152                // Recalculate order totals.
    1116                 $order->calculate_totals();
     1153                $refund->calculate_totals();
    11171154
    11181155                // Save the order.
    1119                 $order->save();
     1156                $refund->save();
    11201157            }
    11211158        }
     
    11521189            $calculation_type                         = 'S';
    11531190            $invoice_number                           = $calculation_type . '-' . wp_rand( 100000, 99999999 );
    1154             $customer_account                         = ( is_user_logged_in() ) ? get_current_user_id() : wp_rand( 1000, 99999 );
    11551191            $shipping_charges                         = $order->get_shipping_total();
    11561192            $shipping_zones                           = WC_Shipping_Zones::get_zones();
     1193
     1194            // Get order customer id.
     1195            if ( $order->get_customer_id() ) {
     1196                $customer_account = $order->get_customer_id();
     1197            } elseif ( is_user_logged_in() ) {
     1198                $customer_account = get_current_user_id();
     1199            } else {
     1200                $customer_account = wp_rand( 1000, 99999 );
     1201            }
    11571202
    11581203            // Caclulate tax if only CereTax calculation option is not enabled.
     
    11671212            }
    11681213
    1169             $item_count      = 0;
    1170             $order_status    = $order->get_status();
    1171             $created_via     = $order->get_meta( '_created_via' );
    1172             $order_parent_id = $order->get_parent_id();
    1173             $order_type      = $order->get_type();
     1214            $item_count            = 0;
     1215            $order_status          = $order->get_status();
     1216            $created_via           = $order->get_meta( '_created_via' );
     1217            $order_parent_id       = $order->get_parent_id();
     1218            $order_type            = $order->get_type();
     1219            $first_renewal_payment = get_post_meta( $order->get_id(), 'is_first_renewal_payment', true );
    11741220
    11751221            $total_renewal_orders = 0;
     
    11801226                    $total_renewal_orders = count( $renewal_orders );
    11811227                }
     1228            }
     1229            if ( 1 === $total_renewal_orders ) {
     1230                // Update renewal payment meta.
     1231                update_post_meta( $order->get_id(), 'is_first_renewal_payment', 'yes' );
    11821232            }
    11831233
     
    12421292
    12431293                // Check if subscription trial main order.
    1244                 if ( 'subscription' === $created_via && ! empty( $order_item_trial_length ) && 1 == $total_renewal_orders ) {
     1294                if ( 'subscription' === $created_via && ! empty( $order_item_trial_length ) && 'yes' === $first_renewal_payment ) {
    12451295                    $line_items[ $item_count ]['attributes'] = array(
    12461296                        array(
     
    13331383                    }
    13341384                    update_post_meta( $order->get_id(), 'ceretax_data', wp_json_encode( $data ) );
     1385                    update_post_meta( $order->get_id(), 'ceretax_data_lineitem', wp_json_encode( $data ) );
    13351386                    return $data['invoice']['totalTaxInvoice'];
    13361387                }
     
    13721423                    }
    13731424                    update_post_meta( $order->get_id(), 'ceretax_data', wp_json_encode( $data ) );
     1425                    update_post_meta( $order->get_id(), 'ceretax_data_lineitem', wp_json_encode( $data ) );
    13741426                    return $data['invoice']['totalTaxInvoice'];
    13751427                }
     
    13821434         *
    13831435         * @param array  $address_data Address data array.
     1436         * @param object $refund       Order refund object.
    13841437         * @param object $order        Order object.
    13851438         * @param string $tax_status   Cetatax tax status.
    13861439         * @return mix
    13871440         */
    1388         public function cwafc_calculate_cere_tax_refunded( $address_data, $order, $tax_status = 'Posted' ) {
     1441        public function cwafc_calculate_cere_tax_refunded( $address_data, $refund, $order, $tax_status = 'Posted' ) {
    13891442
    13901443            // address is required for tax calulation.
     
    13921445                return false;
    13931446            }
    1394             $order_subtotal = (float) $order->get_subtotal();
    1395             $order_subtotal = ( $order_subtotal > 0 ) ? ( $order_subtotal * -1 ) : -0;
     1447            $order_subtotal = 0;
    13961448            $line_items     = array();
    13971449
     
    14091461            $cere_tax_validate_address_on_transaction = 'yes' === $cere_tax_validate_address_on_transaction ? true : false;
    14101462            $calculation_type                         = 'S';
    1411             $invoice_number                           = $calculation_type . '-' . wp_rand( 100000, 99999999 );
    1412             $customer_account                         = ( is_user_logged_in() ) ? get_current_user_id() : wp_rand( 1000, 99999 );
    1413             $shipping_charges                         = (float) $order->get_shipping_total();
    1414             $shipping_charges                         = ( $shipping_charges > 0 ) ? ( $shipping_charges * -1 ) : -0;
     1463            $shipping_charges                         = (float) $refund->get_shipping_total();
    14151464            $shipping_zones                           = WC_Shipping_Zones::get_zones();
     1465
     1466            // Get order customer id.
     1467            if ( $order->get_customer_id() ) {
     1468                $customer_account = $order->get_customer_id();
     1469            } elseif ( is_user_logged_in() ) {
     1470                $customer_account = get_current_user_id();
     1471            } else {
     1472                $customer_account = wp_rand( 1000, 99999 );
     1473            }
    14161474
    14171475            // Caclulate tax if only CereTax calculation option is not enabled.
     
    14261484            }
    14271485
    1428             $item_count      = 0;
    1429             $order_status    = $order->get_status();
    1430             $created_via     = $order->get_meta( '_created_via' );
    1431             $order_parent_id = $order->get_parent_id();
    1432             $order_type      = $order->get_type();
    1433 
    1434             $total_renewal_orders = 0;
    1435             $order_subscriptions  = ( function_exists( 'wcs_get_subscriptions_for_order' ) ) ? wcs_get_subscriptions_for_order( $order->get_id(), array( 'order_type' => 'any' ) ) : array();
    1436             if ( ! empty( $order_subscriptions ) ) {
    1437                 foreach ( $order_subscriptions as $subscription_id => $subscription ) {
    1438                     $renewal_orders       = ( class_exists( 'WC_Subscriptions' ) && is_object( $subscription ) && method_exists( $subscription, 'get_related_orders' ) ) ? $subscription->get_related_orders( 'all', 'renewal' ) : array();
    1439                     $total_renewal_orders = count( $renewal_orders );
    1440                 }
    1441             }
    1442 
    1443             foreach ( $order->get_items() as $item_id => $item ) {
     1486            $item_count            = 0;
     1487            $order_status          = $order->get_status();
     1488            $created_via           = $order->get_meta( '_created_via' );
     1489            $order_parent_id       = $order->get_parent_id();
     1490            $order_type            = $order->get_type();
     1491            $first_renewal_payment = get_post_meta( $order->get_id(), 'is_first_renewal_payment', true );
     1492
     1493            foreach ( $refund->get_items() as $item_id => $item ) {
    14441494
    14451495                $product_id              = $item->get_product_id();
     
    14661516
    14671517                $item_total                = (float) $item->get_total();
    1468                 $item_total                = ( $item_total > 0 ) ? ( $item_total * -1 ) : -0;
     1518                $order_subtotal            = $order_subtotal + $item_total;
    14691519                $line_items[ $item_count ] = array(
    14701520                    'lineID'             => (string) $item_id,
     
    15031553
    15041554                // Check if subscription trial main order.
    1505                 if ( 'subscription' === $created_via && ! empty( $order_item_trial_length ) && 1 == $total_renewal_orders ) {
     1555                if ( 'subscription' === $created_via && ! empty( $order_item_trial_length ) && 'yes' === $first_renewal_payment ) {
    15061556                    $line_items[ $item_count ]['attributes'] = array(
    15071557                        array(
     
    15191569                    'contentYear'     => gmdate( 'Y' ),
    15201570                    'contentMonth'    => gmdate( 'm' ),
    1521                     'decimals'        => 6,
     1571                    'decimals'        => 2,
    15221572                    'calculationType' => $calculation_type,
    15231573                    'profileId'       => $cere_tax_profile,
     
    15801630                $data = json_decode( $data, true );
    15811631            }
    1582 
     1632           
    15831633            if ( is_wp_error( $response ) ) {
    15841634                return false;
     
    15901640                }
    15911641                update_post_meta( $order->get_id(), 'ceretax_data', wp_json_encode( $data ) );
    1592                 return abs( $data['invoice']['totalTaxInvoice'] );
     1642                return $data['invoice']['totalTaxInvoice'];
    15931643            }
    15941644            return false;
     
    18781928            // Caclulate tax if only CereTax calculation option is not enabled.
    18791929            $cere_tax_enable = get_option( CWAFC_PREFIX . '_cere_tax_enable' );
    1880             return 'yes' === $cere_tax_enable ? true : false;
     1930            return 'yes' === $cere_tax_enable ? true : false;   
    18811931        }
    18821932
     
    19502000            }
    19512001            return $items;
     2002        }
     2003
     2004        /**
     2005         * Update tax calculation for subscription.
     2006         *
     2007         * @param object $subscription Subscription Object.
     2008         * @return void
     2009         */
     2010        public function action__cwafc_update_tax_calculation_for_subscription( $subscription ) {
     2011            if ( ! empty( $subscription ) && $subscription instanceof WC_Subscription ) {
     2012                $subscription->calculate_totals();
     2013            }
     2014        }
     2015
     2016        /**
     2017         * Clear avatax for new create order.
     2018         *
     2019         * @param object $order        Order object.
     2020         * @param object $subscription Subscription object.
     2021         * @param string $type         Type string.
     2022         * @return mix
     2023         */
     2024        public function action__cwafc_clear_avatx_new_order_created( $order, $subscription, $type ) {
     2025
     2026            if ( ! class_exists( 'WC_AvaTax_Order_Handler' ) && ! empty( $subscription->get_meta( '_wc_avatax_tax_calculated' ) ) && $subscription->get_meta( '_wc_avatax_tax_calculated' ) == 'yes' && empty( $order->get_meta( '_wc_avatax_tax_calculated' ) ) ) {
     2027
     2028                // Clear avatax data from order item meta.
     2029                foreach ( $order->get_items( 'line_item' ) as $item ) {
     2030
     2031                    $meta = $item->get_meta_data();
     2032
     2033                    foreach ( $item->get_meta_data() as $meta_data ) {
     2034
     2035                        $data = $meta_data->get_data();
     2036
     2037                        if ( ! empty( $data['key'] ) && str_contains( $data['key'], 'avatax' ) ) {
     2038                            $item->delete_meta_data( $data['key'] );
     2039                        }
     2040                    }
     2041                    $item->save();
     2042                }
     2043
     2044                // Clear avatax data from order shipping meta.
     2045                foreach ( $order->get_items( 'shipping' ) as $item ) {
     2046                    $meta = $item->get_meta_data();
     2047                    foreach ( $item->get_meta_data() as $meta_data ) {
     2048                        $data = $meta_data->get_data();
     2049                        if ( ! empty( $data['key'] ) && str_contains( $data['key'], 'avatax' ) ) {
     2050                            $item->delete_meta_data( $data['key'] );
     2051                        }
     2052                    }
     2053                    $item->save();
     2054                }
     2055
     2056                // Clear old Avatax taxes from Ceretax renewal order.
     2057                $require_recalculation = 0;
     2058                foreach ( $order->get_items( 'tax' ) as $item_id => $item ) {
     2059                    if ( ! empty( $item->get_name() ) && str_contains( $item->get_name(), 'AVATAX' ) ) {
     2060                        $item->delete();
     2061                        $require_recalculation = 1;
     2062                    }
     2063                }
     2064                if ( $require_recalculation == 1 ) {
     2065                    $order->save();
     2066                    $order->calculate_totals();
     2067                }
     2068            }
     2069            return $order;
    19522070        }
    19532071    }
  • ceretax/trunk/readme.txt

    r3248052 r3259100  
    55Tested up to: 6.6.1
    66Requires PHP: 7.4
    7 Stable tag: 1.3.8
     7Stable tag: 1.4.0
    88License: GNU General Public License v3.0
    99URI: http://www.gnu.org/licenses/gpl-3.0.html
     
    3636== Changelog ==
    3737
    38 = 1.3.8 =
    39 * fix - Restore to 1.3.6 functionality
     38= 1.4.0 =
     39* add - Disable CereTax for refund orders
     40
     41= 1.3.9 =
     42* fix - Postcode in lower case causing tax calculation issue
    4043
    4144= 1.3.7 =
     
    7780== Upgrade Notice ==
    7881
    79 = 1.3.8 =
    80 * fix - Restore to 1.3.6 functionality
     82= 1.4.0 =
     83* add - Disable CereTax for refund orders
     84
     85= 1.3.9 =
     86* fix - Postcode in lower case causing tax calculation issue
    8187
    8288= 1.3.7 =
Note: See TracChangeset for help on using the changeset viewer.