add_filter( 'sliced_get_gateway_paypal_label', 'sliced_custom_gateway_paypal_label' ); function sliced_custom_gateway_paypal_label() { return 'Pay with Credit Card'; }
Here are several examples of things you can do using the many hooks and filters available in Sliced Invoices. These code snippets are designed to be added to your (child) theme’s functions.php file.
Caution: we do NOT guarantee compatibility between these snippets and future releases of Sliced Invoices. USE AND MODIFY AT YOUR OWN RISK. If you’re not a developer, you probably shouldn’t use these.
add_filter( 'sliced_get_gateway_paypal_label', 'sliced_custom_gateway_paypal_label' ); function sliced_custom_gateway_paypal_label() { return 'Pay with Credit Card'; }
Here’s an example template which adds a “Payments” section. Feel free to modify as needed.
add_action( 'user_register', 'sliced_send_welcome_email', 10, 1 ); function sliced_send_welcome_email( $user_id ) { wp_new_user_notification( $user_id, 'both' ); }
Example #2: add wildcard %payment_method% which represents the gateway used for the last payment:
add_filter( 'sliced_get_email_recipient', 'sliced_custom_add_recipient', 10, 3 ); function sliced_custom_add_recipient( $output, $id, $type ) { if ( $type === 'payment_received' ) { $output .= ', second_email_address@example.com'; } return $output; }
add_filter( 'sliced_get_email_subject', 'sliced_get_email_subject_custom', 20, 3 ); function sliced_get_email_subject_custom( $subject, $id, $type ) { switch ( $type ) { case 'quote_accepted': $subject = "Votre devis %number% a été accepté!"; $subject = str_replace( "%number%", sliced_get_invoice_prefix( $id ) . sliced_get_invoice_number( $id ), $subject ); break; } return $subject; }
You can easily add additional case statements for other email types (for example quote_declined, payment_received, etc).
add_filter( 'sliced_get_email_content', 'sliced_disable_email', 10, 3 ); function sliced_disable_email( $output, $id, $type ) { if ( $type === 'payment_received' || $type === 'payment_received_client' ) { return false; } return $output; }
For Invoices:
add_action( 'sliced_client_accepted_quote', 'sliced_auto_mark_converted_invoice_unpaid', 10, 1 ); function sliced_auto_mark_converted_invoice_unpaid( $id ) { Sliced_Invoice::set_as_unpaid( $id ); }
add_action( 'new_to_publish', 'auto_send_pdf', 10, 1 ); add_action( 'auto_send_pdf_deferred', 'auto_send_pdf_deferred_function', 10, 1 ); function auto_send_pdf( $post ) { if ( $post->post_type === 'sliced_quote' ) { // run in background 1 minute from now wp_schedule_single_event( time() + 60, 'auto_send_pdf_deferred', array( $post ) ); } } function auto_send_pdf_deferred_function( $post ) { if ( $post->post_type === 'sliced_quote' ) { $sliced_notifications = new Sliced_Notifications(); $sliced_notifications->id = $post->ID; $sliced_notifications->type = "quote"; $type = "quote_available"; add_filter( 'wp_mail_content_type', array( $sliced_notifications, 'set_email_type' ) ); $send = wp_mail( $sliced_notifications->settings['from'], // send to admin $sliced_notifications->get_subject( $type ), $sliced_notifications->get_content( $type ), $sliced_notifications->get_headers( $type ), $sliced_notifications->get_attachments() ); remove_filter( 'wp_mail_content_type', array( $sliced_notifications, 'set_email_type' ) ); do_action( 'sliced_after_send_email', $sliced_notifications->id ); } }
add_filter( 'sliced_quote_status_params', 'sliced_enable_custom_statuses' ); add_filter( 'sliced_invoice_status_params', 'sliced_enable_custom_statuses' ); function sliced_enable_custom_statuses( $opts ) { $opts['show_ui'] = TRUE; return $opts; }
add_filter( 'sliced_invoice_line_items_output', 'sliced_invoice_line_items_output_custom' ); function sliced_invoice_line_items_output_custom( $output ) { if ( preg_match_all('#<td class="qty">(.*?)</td>#', $output, $matches) ) { $patterns = array(); $replacements = array(); foreach ( $matches[1] as $match ) { $patterns[] = '#<td class="qty">'.$match.'</td>#'; $replacements[] = '<td class="qty">'.intval($match).'</td>'; } $output = preg_replace($patterns, $replacements, $output); } return $output; }
add_filter( 'sliced_quote_hide_adjust_field', 'sliced_hide_the_adjust_field' ); function sliced_hide_the_adjust_field() { return true; }
You can use basically this same code for both Quotes and Invoices, just change the first line where it says “sliced_quote” to “sliced_invoice”.
Update 2017-10-27: The above snippet is no longer necessary, you can hide the adjust field through the settings pages. See the setting “Hide Adjust Field” under Quote Settings and under Invoice Settings, respectively. This will hide the adjust field from showing on the frontend.
If you want to hide the adjust field on the admin side, use the following code snippet instead:
add_filter( 'sliced_get_invoice_line_items', 'sliced_adjust_the_rate_field', 10, 2 ); function sliced_adjust_the_rate_field( $output, $id ) { if ( get_post_type( $id ) === 'sliced_quote' ) { if( !empty( $output ) && !empty( $output[0] ) ) { foreach ( $output[0] as &$item ) { if ( isset( $item['tax'] ) && $item['tax'] > 0 ) { $item['amount'] = '' . intval( $item['amount'] ) * ( 1 + ( intval( $item['tax'] ) / 100 ) ); $item['tax'] = 0; } } } } return $output; }
add_filter( 'sliced_get_client_email', 'sliced_hide_the_email_address', 10, 3 ); function sliced_hide_the_email_address( $email, $client, $id ) { return ''; }
Example of a custom email footer template:
add_action( 'sliced_invoice_top_bar_left', 'sliced_paypal_standard_checkout', 999 ); function sliced_paypal_standard_checkout() { $paypal_email_address = 'YOUR_EMAIL_ADDRESS_HERE'; $id = sliced_get_invoice_id(); $currency = sliced_get_invoice_currency( $id ); $payments = get_option( 'sliced_payments' ); $gateway = array(); $gateway['currency'] = $payments['paypal_currency']; ?> <script type="text/javascript"> jQuery('a[data-gateway="paypal"]').attr('href', '#' ).removeClass('thickbox').click(function(e){ e.preventDefault(); jQuery('#sliced_paypal_standard_checkout').submit(); }); </script> <form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="sliced_paypal_standard_checkout"> <input type="hidden" name="business" value=""> <input type="hidden" name="cmd" value="_xclick"> <input type="hidden" name="item_name" value=""> <input type="hidden" name="amount" value=""> <input type="hidden" name="currency_code" value=""> </form>
Sliced Invoices stores client fields in the wp_usermeta table, meaning you can access them using standard WordPress functions like in the following examples:
// Print client's business name $user = get_userdata( $user_id ); echo $user->_sliced_client_business; // Update client's business name update_user_meta( $user_id, '_sliced_client_business', 'New Business Name' );
You can also use one of the many User Meta plugins available to access these fields, for example User Meta Pro (http://user-meta.com/).
The fields used by Sliced Invoices are the following:
_sliced_client_business
_sliced_client_address
_sliced_client_extra_info
For example, the following code automatically populates the title field when creating a new Invoice:
if ( @$pagenow === 'post-new.php' && @$_GET['post_type'] === 'sliced_invoice' ) { add_action( 'admin_head', 'sliced_custom_code_20161108' ); } function sliced_custom_code_20161108() { echo '<script type="text/javascript"> jQuery(document).ready(function(){ var invPre = jQuery(".cmb2-id--sliced-invoice-number span.prefix").html(); var invNum = jQuery("#_sliced_invoice_number").val(); jQuery("#title").val( invPre + invNum ); }); </script>'; }
To accept multiple currencies in Braintree, in your Braintree account you must create separate Merchant Account IDs for each currency. (Note: "Merchant Account ID" is not the same as your "Merchant ID"!)
If your default Merchant Account's currency is, for example, USD, then all invoices payments would be in USD, unless you specify a different currency on the Invoice. In that case, if the Invoice is in, for example, AUD, the following code can be used to map the currency to the correct Merchant Account ID.
add_filter( 'sliced_braintree_transaction_sale_args', 'sliced_braintree_add_addl_merchant_ids', 10, 2 ); function sliced_braintree_add_addl_merchant_ids( $args, $id ) { $currency = sliced_get_invoice_currency( $id ); switch ( $currency ) { case "AUD": $args['merchantAccountId'] = 'slicedinvoicesaud'; break; } return $args; }
Be sure to change 'slicedinvoicesaud' to whatever your Merchant Account ID is for the given currency.
The Sliced Invoices Client Area uses the popular FontAwesome CSS icon library. If you already have FontAwesome loaded somewhere else on your site, or if you want to use a different version from the one included with Sliced Invoices, you can prevent Sliced Invoices from loading it with the following code:
Example code:
add_action( 'gform_pre_submission', 'pre_submission_handler' ); function pre_submission_handler( $form ) { $_POST['input_4'] = $_POST['input_1'] . "\r\n" . $_POST['input_2'] . "\r\n" . $_POST['input_3']; }
Another example:
add_action( 'gform_pre_submission', 'pre_submission_handler' ); function pre_submission_handler( $form ) { $_POST['input_6'] = "<table> <tr> <td>Name</td><td>{$_POST['input_1']}</td> </tr> </table>"; }
For example, based on a timestamp:
add_filter( 'gform_field_value_quote_number', 'quote_number_population_function' ); function quote_number_population_function( $value ) { $timestamp = time(); return date( "ymdHis", $timestamp ); }
When setting up the feed you can only choose one field containing the line items. There are basically two ways to get all your line items into one field -- the first, and easiest, is to add a Gravity Forms' "list" field to your form. The "list" field type allows you setup multiple columns/rows, which Gravity Forms automatically combines on the back end into a particular format which our plugin understands and can process.
The only catch here is that, for it to work, you must include 4 columns: Quantity, Title, Amount, Description. You can name the columns anything you like, but there must be 4, and in that order.
If you need more flexibility, the other way you can do this is to setup the form however you want, and use a little custom coding to format the line items on the back end. To do this you would add some code to your site's functions.php file which would take care of the necessary formatting. If you are comfortable with PHP coding, you can use something like the following as a starting point (this is just an example, you would need to adapt it to your particular scenario):
add_action( 'sliced_gravityforms_feed_processed', 'si_2017_04_17_custom_line_items', 10, 4 ); function si_2017_04_17_custom_line_items( $id, $feed, $entry, $form ) { $line_items = array( array( // this is one line item... match the field IDs to // your form. For example if our field ID is 131 // and it is a "product" field type, we would do: "qty" => rgar( $entry, '131.3' ), "title" => rgar( $entry, '131.1' ), "amount" => rgar( $entry, '131.2' ), "description" => '', ), array( // this is another line item "qty" => rgar( $entry, '26.3' ), "title" => rgar( $entry, '26.1' ), "amount" => rgar( $entry, '26.2' ), "description" => '', ), // etc... ); update_post_meta( $id, '_sliced_items', $line_items ); }
//delay processing the feed add_filter( 'gform_is_delayed_pre_process_feed', 'sliced_invoices_delay_feed', 10, 4 ); function sliced_invoices_delay_feed( $is_delayed, $form, $entry, $slug ) { if ( $slug === 'slicedinvoices' ) { return true; } return $is_delayed; } // process the feed on gform_user_registered add_action( 'gform_user_registered', 'send_to_sliced_invoices', 10, 3 ); function send_to_sliced_invoices( $user_id, $feed, $entry ) { $form = GFAPI::get_form( $entry['form_id'] ); $si_feed = GFAPI::get_feeds( null, null, 'slicedinvoices' ); $SIGF = new Sliced_Invoices_GF; $SIGF->process_feed( $si_feed[0], $entry, $form ); }
add_action( 'gform_after_submission', 'sliced_quote_add_adjust', 10, 2 ); function sliced_quote_add_adjust( $entry, $form ) { $hidden_adjust_field = 'input_8'; // change this number to the correct field id $adjust = intval( $_POST[$hidden_adjust_field] ); if ( $adjust > 0 ) { // get last quote $latest_quote_id = null; $args = array( 'post_type' => 'sliced_quote', 'post_status' => 'publish', 'posts_per_page' => 1, 'orderby' => 'date', 'order' => 'DESC', ); $the_query = new WP_Query( $args ); if ( $the_query->have_posts() ) { $latest_quote_id = $the_query->post->ID; } // update line items if ( $latest_quote_id ) { $line_items = get_post_meta( $latest_quote_id, '_sliced_items' ); $new_line_items = array(); foreach ( $line_items as $line_item ) { foreach ( $line_item as $item ) { if ( ! isset( $item['tax'] ) ) { $item['tax'] = $adjust; } $new_line_items[] = $item; } } update_post_meta( $latest_quote_id, '_sliced_items', $new_line_items ); } } }
Alternate, pre-submission approach:
add_action( 'gform_pre_submission', 'sliced_quote_add_adjust', 10, 1 ); function sliced_quote_add_adjust( $form ) { $hidden_adjust_field = 'input_27'; // change this number to the correct field id $line_items_field = 'input_20'; // change this too $adjust = intval( $_POST[$hidden_adjust_field] ); if ( $adjust > 0 ) { $items = $_POST[$line_items_field]; foreach ( $items as $index => $item ) { if ( ( $index - 2 ) % 4 === 0 ) { // every 4th index, starting with [2] $_POST[$line_items_field][$index] = round( $_POST[$line_items_field][$index] * ( 1 + ( $adjust / 100 ) ), 2 ); } } } }
Example code:
add_action( 'publish_sliced_quote', 'auto_save_pdf', 10, 2 ); add_action( 'auto_save_pdf_deferred', 'auto_save_pdf_deferred_function', 10, 2 ); function auto_save_pdf( $id, $post ) { // run in background 1 minute from now wp_schedule_single_event( time() + 60, 'auto_save_pdf_deferred', array( $id, $post ) ); } function auto_save_pdf_deferred_function( $id, $post ) { if ( $post->post_type === 'sliced_quote' ) { $html = Sliced_Shared::request_data( add_query_arg( array( 'create' => 'pdf', 'id' => $id ), sliced_get_the_link( $id ) ) ); $nonce_start = strpos( $html, 'sliced-print-button" href="' ) + 27; $nonce_url = substr( $html, $nonce_start, strpos( $html, '"', $nonce_start ) - $nonce_start ); $pdf = file_get_contents( html_entity_decode( $nonce_url ) ); file_put_contents( '/quote-'.$id.'.pdf', $pdf ); } }
This will change invoice-X-number.pdf to facture-X-number.pdf, and quote-X-number.pdf to quotation-X-number.pdf:
add_filter( 'sliced_get_filename', 'sliced_custom_filename', 10, 2 ); function sliced_custom_filename( $filename, $id ) { $filename = str_replace( 'invoice', 'facture', $filename ); $filename = str_replace( 'quote', 'quotation', $filename ); return $filename; }
***
Another example:
add_filter( 'sliced_get_filename', 'sliced_custom_filename', 10, 2 ); function sliced_custom_filename( $filename, $id ) { if ( sliced_get_the_type( $id ) === 'invoice' ) { $filename = sliced_get_client_business( $id ) . "-facture-" . sliced_get_invoice_prefix( $id ) . sliced_get_invoice_number( $id ) . "-" . date( "Y-m-d" ); } return $filename; }
add_filter( 'sliced_get_gateway_stripe_label', 'sliced_customize_stripe_gateway_label' ); function sliced_customize_stripe_gateway_label( $label ) { return 'Pay by Credit Card'; }