Creating a custom discount/credit field

I have created a form for use in the office backend where staff can process call-in orders. I needed a field where they could enter in an arbitrary credit or discount. I created a plugin to handle this to add the new field type into the editor, and it pretty much works great. There are just 2 issues:

  1. It’s adding the field as a product with a negative price, which works, but ideally I would like it to show up in the Discount field when the order is created, between the Subtotal and the Total.

  2. I have enqueued Javascript that calls gformCalculateTotalPrice() when anything is typed in that box, and it is indeed calling it, but it’s not updating the total.

What would I need to add to the creation of the field type in order for it to behave as an actual discount, instead of just a negatively priced product?

This is the code I am using:

class Custom_GF_Discount {

    public function __construct() {
        add_filter('gform_add_field_buttons', array($this, 'add_discount_field_button'));
        add_filter('gform_field_type_title', array($this, 'set_discount_field_title'), 10, 2);
        add_action('gform_editor_js', array($this, 'editor_script'));
        add_action('gform_field_standard_settings', array($this, 'field_settings'), 10, 2);
        add_filter('gform_product_info', array($this, 'apply_discount'), 10, 3);
        add_filter('gform_field_validation', array($this, 'validate_discount'), 10, 4);
        add_filter('gform_field_input', array($this, 'field_input'), 10, 5);
    }

    public function add_discount_field_button($field_groups) {
        foreach ($field_groups as &$group) {
            if ($group["name"] == "advanced_fields") {
                $group["fields"][] = array(
                    "class"=>"button",
                    "data-type"=>"editable_discount",
                    "value"=>"Editable Discount"
                );
                break;
            }
        }
        return $field_groups;
    }

    public function set_discount_field_title($type) {
        if ($type == 'editable_discount') {
            return __('Editable Discount', 'gravityforms');
        }
        return $type;
    }

    public function editor_script() {
        ?>
        <script type='text/javascript'>
            fieldSettings.editable_discount = '.label_setting, .description_setting, .admin_label_setting, .discount_setting';
        </script>
        <?php
    }

    public function field_settings($position, $form_id) {
        if ($position == 25) {
            ?>
            <li class="discount_setting field_setting">
                <label for="field_admin_label">
                    <?php _e("Discount Label", "gravityforms"); ?>
                    <?php gform_tooltip("form_field_discount_value") ?>
                </label>
                <input type="text" id="field_discount_label" onchange="SetFieldProperty('discountLabel', this.value);" />
            </li>
            <?php
        }
    }

    public function apply_discount($product_info, $form, $entry) {
        foreach ($form['fields'] as $field) {
            if ($field->type == 'editable_discount' && !empty($entry[$field->id])) {
                $discount = floatval($entry[$field->id]);
                $product_info["products"]['Discount'] = array(
                    'name' => 'Discount',
                    'price' => -$discount,
                    'quantity' => 1,
                    'isProduct' => false
                );
            }
        }
        return $product_info;
    }

    
/**
 * Displays the input field on the frontend.
 */
public function field_input($input, $field, $value, $lead_id, $form_id) {
    if ($field->type != 'editable_discount') {
        return $input;
    }

    $input_id = 'input_' . $form_id . '_' . $field->id;
    $tabindex = GFCommon::get_tabindex();
    $input .= sprintf("<input name='input_%s' id='%s' type='text' class='' value='%s' %s/>", $field->id, $input_id, esc_attr($value), $tabindex);
    return $input;
}

public function validate_discount($result, $value, $form, $field) {
        if ($field->type == 'editable_discount') {
            if ((!empty($value) && !is_numeric($value)) || floatval($value) < 0) {
                $result['is_valid'] = false;
                $result['message'] = 'Please enter a valid discount amount.';
            }
            if (isset($field->maxDiscount) && floatval($value) > floatval($field->maxDiscount)) {
                $result['is_valid'] = false;
                $result['message'] = "Discount cannot be more than {$field->maxDiscount}.";
            }
        }
        return $result;
    }

}

new Custom_GF_Discount();

add_action('wp_enqueue_scripts', 'custom_discount_enqueue_discount_script');

function custom_discount_enqueue_discount_script() {
    if (class_exists('GFForms')) { // Ensure Gravity Forms is active
        wp_enqueue_script('custom-discount-handler', plugin_dir_url(__FILE__) . 'discount-handler.js', array('jquery'), '1.0.0', true);
    }
}

Thanks!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.