How To Add Custom Charges Fields On Edit Invoice Page
Code goes to your active theme’s functions.php file:
1. Remove default invoice charges hook.
remove_action( 'wpcinvoice_after_package_table_row', 'wpcinvoice_after_package_details_callback', 20, 2 );
2. Replace the removed invoice charges hook.
function wpccustom_wpcinvoice_after_package_table_row_callback($shipment){ global $post, $wpcargo; if( !empty( $shipment ) && wpcinvoice_dashboard_page() == $post->ID ){ $tax = ($wpcargo->tax ?? 0) / 100; $shipment_type = wpcfe_get_shipment_type( $shipment->ID ); $current_user = wp_get_current_user(); $user_roles = $current_user->roles; $colspan = count( wpcargo_package_fields() ) - 1; $pkg_totals = wpcinvoice_get_total_value( $shipment->ID ); $form_control = is_admin() ? '' : 'form-control'; $text_color = ''; $td_width = ''; $nonpq_shiptype = array( 'Shipping Rate', 'Default', 'Delivery', 'Shipment Consolidation' ); $nonins_shiptype = array( 'Default', 'Delivery', 'Shipment Consolidation' ); $non_custom_fields = array('sub_total', 'tax', 'total'); $wpcinvoice_total_fields = wpcinvoice_total_fields(); // unset some array fields based on shipment types if( $shipment_type == 'Parcel Quotation' ) { unset( $wpcinvoice_total_fields['insurance'] ); } if( in_array( $shipment_type, $nonpq_shiptype ) ) { unset( $wpcinvoice_total_fields['freight'] ); unset( $wpcinvoice_total_fields['fuel'] ); unset( $wpcinvoice_total_fields['stops'] ); unset( $wpcinvoice_total_fields['layover'] ); if( in_array( $shipment_type, $nonins_shiptype ) ) { unset( $wpcinvoice_total_fields['insurance'] ); } } if( $shipment_type == 'Delivery' || $shipment_type == 'Shipment Consolidation' ) { $td_width = 100; } if( array_intersect( array( 'administrator', 'wpcargo_employee' ), $user_roles) ){ if( !empty( $wpcinvoice_total_fields ) ){ foreach( $wpcinvoice_total_fields as $field_key => $fields ){ $invoice_total_field_keys = array_keys( $wpcinvoice_total_fields ); $custom_field_class = ''; $value = array_key_exists( $field_key, $pkg_totals )? $pkg_totals[$field_key] : 0; $readonly = ( $fields['readonly'] ) ? 'readonly' : ''; $input_id = $field_key; // change labels based on shipment types $currency = !empty( wpcinvoice_currency() )? '('.wpcinvoice_currency().')' : ''; $subtotal_label = 'Subtotal '.$currency; $label = $fields['label']; if( $label == $subtotal_label && $shipment_type == 'Shipping Rate' ) { $label = wpcinvoice_shipping_cost_label(); } elseif ( $label == $subtotal_label && $shipment_type == 'Delivery' ) { $label = wpcinvoice_delivery_charge_label(); } if( $field_key == 'total' ){ $text_color = ' text-danger'; } if(!in_array($field_key, $non_custom_fields)){ $custom_field_class = 'custom_fields'; } ?> <tr class="total-detail"> <td class="label <?php echo $text_color; ?>" colspan="<?php echo $colspan; ?>" align="right" style="vertical-align: middle;"><strong><?php echo $label; ?></strong></td> <td class="value" colspan="1" width="<?php echo $td_width; ?>"> <?php printf( '<input type="%s" id="%s" class="number %s %s" name="%s" value="%s" %s />', $fields['field'], $input_id, $form_control.$text_color, $custom_field_class, $field_key, wpcinvoice_format_value( $value, false ), $readonly ); ?> </td> <?php if( !is_admin() ): ?> <!-- <td> </td>--> <?php endif; ?> </tr> <?php } } do_action( 'wpcinvoice_additional_details_script' ); } ?> <script> jQuery(document).ready(function($){ let tax = "<?php echo $tax; ?>"; $('body').on('input', 'input.custom_fields', function(){ let fields = $('input.custom_fields'); let unitAmountTotal = 0; let unitAmountTotalTaxed = 0; let unitAmount = $('input.unit-amount'); unitAmount.each(function(){ let unitAmountVal = $(this).val(); if( unitAmountVal && !isNaN(unitAmountVal)){ unitAmountTotal += parseFloat($(this).val()); } }); fields.each(function(){ let customFieldVal = $(this).val(); if(customFieldVal && !isNaN(customFieldVal)){ unitAmountTotal += parseFloat(customFieldVal); } }); unitAmountTotalTaxed = unitAmountTotal * tax; let total_amount = unitAmountTotal + unitAmountTotalTaxed; $('#wpcinvoice_package .total-detail').find( 'input#sub_total' ).val( unitAmountTotal.toFixed(2) ); $('#wpcinvoice_package .total-detail').find( 'input#tax' ).val( unitAmountTotalTaxed.toFixed(2) ); $('#wpcinvoice_package .total-detail').find( 'input#total' ).val( total_amount.toFixed(2) ); }); }); </script> <?php } } add_action('wpcinvoice_after_package_table_row', 'wpccustom_wpcinvoice_after_package_table_row_callback', 20, 1);
3. Add a custom charge field.
function wpccustom_wpcinvoice_total_fields_callback($fields){ $_fields = (array)$fields; $new_field = array( 'custom_fee' => array( 'label' => __('Custom Fee', 'wpcargo-invoice'), 'field' => 'text', 'required' => false, 'readonly' => false ), // add new fields here // 'custom_field' => array( 'label' => __('Custom Field', 'wpcargo-invoice'), 'field' => 'text', 'required' => false, 'readonly' => false ) ); $merged_fields = array_merge($new_field, $_fields); return $merged_fields; } add_filter('wpcinvoice_total_fields', 'wpccustom_wpcinvoice_total_fields_callback', 11, 1);
4. Add saving code for newly added custom charge field.
function wpccustom_after_wpcinvoice_save_shipment_callback($post_id, $data){ $custom_fee = $data['custom_fee'] ?? 0; // get new fields custom meta here: $custom_field = $data['custom_field'] ?? 0; if($custom_fee){ update_post_meta($post_id, 'custom_fee', $custom_fee); } // update post meta for new fields here // if($custom_field){ update_post_meta($post_id, 'custom_field', $custom_field); } } add_action( 'after_wpcinvoice_save_shipment', 'wpccustom_after_wpcinvoice_save_shipment_callback', 11, 2 );
5. Modify total charges by including the amount of newly added custom charge field.
function wpccustom_wpcinvoice_get_total_value_callback($total_values, $post_id){ global $wpcargo; $tax = ($wpcargo->tax ?? 0) / 100; $custom_fee = get_post_meta($post_id, 'custom_fee', true) ?: 0; // get custom fields meta here: $custom_field = get_post_meta($post_id, 'custom_field', true) ?: 0; if($custom_fee){ $total_values['custom_fee'] = (float)$custom_fee; // append new field to total values here: $total_values['custom_field'] = (float)$custom_field; $total_values['sub_total'] += (float)$custom_fee; // for multiple fields, the format for sub_total computation will be $total_values['sub_total'] += ((float)$custom_fee + (float)$custom_field); $total_values['tax'] = (($total_values['sub_total'] ?? 0) * $tax); $total_values['total'] = (($total_values['sub_total'] ?? 0) + ($total_values['tax'] ?? 0)); } return $total_values; } add_filter('wpcinvoice_get_total_value', 'wpccustom_wpcinvoice_get_total_value_callback', 11, 2);
6. Remove default invoice total fields hook on pdf.
remove_action( 'wpcinvoice_total_info', 'wpcinvoice_total_info_callback', 10, 4 );
7. Replace the removed total fields hook on pdf
function wpccustom_wpcinvoice_total_info_callback( $shipmentDetails ){ $invoice_options = get_option( 'wpcinvoice_settings' ); $shipment_id = $shipmentDetails['shipmentID']; $shipment_type = wpcfe_get_shipment_type( $shipment_id ); $order_id = wpcinvoice_get_invoice_order( $shipment_id ); $str_find = array_keys( wpcinvoice_shortcodes_list() ); $str_replace = wpcinvoice_replace_shortcodes_list( $shipment_id ); $total_info = wpcinvoice_get_total_value( $shipment_id ); $thankyou_invoice = wpcinvoice_display_options( $invoice_options, 'thankyou_message' ); $subtotal = $order_id ? wc_price( wpcinvoice_get_order_data( $order_id )->subtotal ) : wpcinvoice_format_value( (float)$total_info['sub_total'], true ); $total_tax = $order_id ? wc_price( wpcinvoice_get_order_data( $order_id )->total_tax ) : wpcinvoice_format_value( (float)$total_info['tax'], true ); $total = $order_id ? wc_price( wpcinvoice_get_order_data( $order_id )->total ) : wpcinvoice_format_value( (float)$total_info['total'], true ); if( empty( $thankyou_invoice ) ){ $thankyou_invoice = wpcinvoice_default_thankyou_invoice(); } // change labels based on shipment types $subtotal_label = apply_filters( 'wpcinvoice_subtotal_label', __('Subtotal', 'wpcargo-invoice' ) ); if( $shipment_type == 'Shipping Rate' ) { $subtotal_label = wpcinvoice_pdf_shipping_cost_label(); } elseif ( $shipment_type == 'Delivery' ) { $subtotal_label = wpcinvoice_pdf_delivery_charge_label(); } $__net = (float)$total_info['sub_total'] + (float)$total_info['tax']; // wpcargo_option_settings[wpcargo_tax] $tax_option = get_option('wpcargo_option_settings'); $__tax = (float)$tax_option['wpcargo_tax']; $totalNoTax = ( array_sum($total_info ) ) - ( (float)$total_info['tax'] + (float)$total_info['total'] ); // get custom fee $custom_fee = get_post_meta($shipment_id, 'custom_fee', true) ?: 0; ?> <thead align = "center" style = "background-color:#cecece;"> <tr style = "padding:0 5px !important;"> <th><?php echo apply_filters( 'charge_description', __( 'Charge Description', 'wpcargo-invoice') ); ?></th> <!-- custom fee --> <th><?php echo apply_filters( 'custom_fee_label', __( 'Custom Fee', 'wpcargo-invoice') ); ?></th> <th><?php echo apply_filters( 'gross_charges', __( 'Gross Charge', 'wpcargo-invoice') ); ?></th> <th><?php echo apply_filters( '__tax', __( 'Tax (%)', 'wpcargo-invoice') ); ?></th> <th><?php echo apply_filters( 'tax', __( 'Tax', 'wpcargo-invoice') ); ?></th> <th><?php echo apply_filters( 'net_charges', __( 'Net Charge', 'wpcargo-invoice') ); ?></th> </tr> </thead> <tbody> <tr align = "center" style = "padding:0 5px !important;"> <td class="no-padding" align = "left" style = "padding:0 5px !important;"><?php echo $subtotal_label; ?></td> <!-- custom fee --> <td class="no-padding"><?php echo wpcinvoice_format_value( ( (float)$custom_fee ), true ); ?></td> <td class="no-padding"><?php echo wpcinvoice_format_value( ( (float)$total_info['sub_total'] ?: 0.00 ), true ); ?></td> <td class="no-padding"><?php echo $__tax; ?></td> <td class="no-padding"><?php echo wpcinvoice_format_value( ( (float)$total_info['tax'] ?: 0.00 ), true ); ?></td> <td class="no-padding"><?php echo wpcinvoice_format_value( ( (float)$__net ?: 0.00 ), true ); ?></td></div> </tr> <?php do_action( 'wpcinvoice_after_invoice_tax', $total_info, $shipment_id, $shipment_type ); ?> <tr align = "center" style = "padding:0 5px !important;"> <td class="no-padding" align = "left" style = "padding:0 5px !important;"><strong style="font-size: 20px;"><?php echo apply_filters( 'wpcinvoice_total_label', __('Total', 'wpcargo-invoice' ) ); ?></strong></td> <!-- custom fee --> <td class="no-padding"><strong style="font-size: 20px;"><?php echo wpcinvoice_format_value( ( (float)$custom_fee ), true ); ?></strong></td> <td class="no-padding"><strong style="font-size: 20px;"><?php echo $totalNoTax; ?></strong></td> <td class="no-padding"> </td> <td class="no-padding"><strong style="font-size: 20px;"><?php echo wpcinvoice_format_value( ( (float)$total_info['tax'] ?: 0.00 ), true ); ?></strong></td> <td class="no-padding"><span><strong style="font-size: 20px;"><?php echo wpcinvoice_format_value( ( (float)$total_info['total'] ?: 0.00 ), true ); ?></strong></span></td> </tr> </tbody> <?php } add_action( 'wpcinvoice_total_info', 'wpccustom_wpcinvoice_total_info_callback', 10, 4 );