having bit of trouble adding an option to reduce stock on a product within a deposit plugin (woo commerce deposits). Currently the options as standard are: 'deposit' or 'full payment' - I wish to also add 'both deposit or full payment' so stock would be reduced if either deposit or full payment is taken.
Help, much appreciated!
Updated function#1:
public function payment_complete_reduce_order_stock($reduce, $order_id) {
$order = wc_get_order($order_id);
$status = $order->get_status();
$reduce_on = get_option('wc_deposits_reduce_stock', 'full');
if ($status === 'partially-paid' && $reduce_on === 'full') {
$reduce = false;
}
else if ($status !== 'partially-paid' && $reduce_on === 'deposit') {
$reduce = false;
} //added in...
else if ( $status == 'partially-paid' && $reduce_on === 'both'){ // added to allow reduction on both Deposit and Full
$reduce = true;
}
else if ($status == !'partially-paid' && $order->wc_deposits_remaining_paid == 'yes') { // Added to NOT reduce if prepayment taken then completing order
$reduce = false;
}
Updated function#2:
'deposits_stock' => array(
'name' => __('Reduce Stocks On', 'woocommerce-deposits'),
'type' => 'radio',
'desc' => __('Choose when to reduce stocks.', 'woocommerce-deposits'),
'id' => 'wc_deposits_reduce_stock',
'options' => array(
'deposit' => __('Deposit Payment', 'woocommerce-deposits'),
'full' => __('Full Payment', 'woocommerce-deposits'),
// added in...
'both' => __('Both Full Payment or Deposit', 'woocommerce-deposits')
),
'default' => 'full'
),
This is where I think I fall down:
Original 'Save all settings' function:
$reduce_stock = isset($_POST['wc_deposits_reduce_stock']) ?
($_POST['wc_deposits_reduce_stock'] === 'deposit' ? 'deposit' : 'full') : 'full';
I'm not sure how to add in the additional option, this doesn't work!:
$reduce_stock = isset($_POST['wc_deposits_reduce_stock']) ?
($_POST['wc_deposits_reduce_stock'] === 'deposit' ? 'deposit' : 'full' ? 'both' : 'full' ) : 'full';
Related
I'm using "set minimum and maximum allowable product quantities to be added in WooCommerce Cart" to require a minimum and maximum quantity order.
Now, i need to impose for several products (not all) a mulitple quantity.
For example : 6 bottles, 12 bottles, 18 bottles (multiple of 6) or for other 12 bottles, 24 bottles (multiple of 12)
I found a solution but it's for every product with a unique value and I cant' manage it in the back office for each product individually.
I have to manage the multiple quantity in Backoffice.
Thank you if you can help me
Updated December 2020
The following revisited code will allow in addition to handle quantity steps.
I have changed quantity fields settings location to "General" settings tab.
I have added a checkbox that enables or disables those additional quantity settings at product level (showing or hiding the setting fields dynamically):
When checkbox unchecked (fields are not visible and quantity settings are disabled):
When checkbox is checked (fields are visible and quantity settings are enabled):
I have merged all settings in a unique custom field as an indexed array of values, to improve performance.
Since WooCommerce version 3, things have changed a lot, so I have made some changes enhancing and updating code to something more newer.
Also works nicely on Ajax add to cart for simple products, for product variations from variable products and also on the cart quantity input field.
All the code:
// Displaying quantity setting fields on admin product pages
add_action( 'woocommerce_product_options_pricing', 'wc_qty_add_product_field' );
function wc_qty_add_product_field() {
global $product_object;
$values = $product_object->get_meta('_qty_args');
echo '</div><div class="options_group quantity hide_if_grouped">
<style>div.qty-args.hidden { display:none; }</style>';
woocommerce_wp_checkbox( array( // Checkbox.
'id' => 'qty_args',
'label' => __( 'Quantity settings', 'woocommerce' ),
'value' => empty($values) ? 'no' : 'yes',
'description' => __( 'Enable this to show and enable the additional quantity setting fields.', 'woocommerce' ),
) );
echo '<div class="qty-args hidden">';
woocommerce_wp_text_input( array(
'id' => 'qty_min',
'type' => 'number',
'label' => __( 'Minimum Quantity', 'woocommerce-max-quantity' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'Set a minimum allowed quantity limit (a number greater than 0).', 'woocommerce' ),
'custom_attributes' => array( 'step' => 'any', 'min' => '0'),
'value' => isset($values['qty_min']) && $values['qty_min'] > 0 ? (int) $values['qty_min'] : 0,
) );
woocommerce_wp_text_input( array(
'id' => 'qty_max',
'type' => 'number',
'label' => __( 'Maximum Quantity', 'woocommerce-max-quantity' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'Set the maximum allowed quantity limit (a number greater than 0). Value "-1" is unlimited', 'woocommerce' ),
'custom_attributes' => array( 'step' => 'any', 'min' => '-1'),
'value' => isset($values['qty_max']) && $values['qty_max'] > 0 ? (int) $values['qty_max'] : -1,
) );
woocommerce_wp_text_input( array(
'id' => 'qty_step',
'type' => 'number',
'label' => __( 'Quantity step', 'woocommerce-quantity-step' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'Optional. Set quantity step (a number greater than 0)', 'woocommerce' ),
'custom_attributes' => array( 'step' => 'any', 'min' => '1'),
'value' => isset($values['qty_step']) && $values['qty_step'] > 1 ? (int) $values['qty_step'] : 1,
) );
echo '</div>';
}
// Show/hide setting fields (admin product pages)
add_action( 'admin_footer', 'product_type_selector_filter_callback' );
function product_type_selector_filter_callback() {
global $pagenow, $post_type;
if( in_array($pagenow, array('post-new.php', 'post.php') ) && $post_type === 'product' ) :
?>
<script>
jQuery(function($){
if( $('input#qty_args').is(':checked') && $('div.qty-args').hasClass('hidden') ) {
$('div.qty-args').removeClass('hidden')
}
$('input#qty_args').click(function(){
if( $(this).is(':checked') && $('div.qty-args').hasClass('hidden')) {
$('div.qty-args').removeClass('hidden');
} else if( ! $(this).is(':checked') && ! $('div.qty-args').hasClass('hidden')) {
$('div.qty-args').addClass('hidden');
}
});
});
</script>
<?php
endif;
}
// Save quantity setting fields values
add_action( 'woocommerce_admin_process_product_object', 'wc_save_product_quantity_settings' );
function wc_save_product_quantity_settings( $product ) {
if ( isset($_POST['qty_args']) ) {
$values = $product->get_meta('_qty_args');
$product->update_meta_data( '_qty_args', array(
'qty_min' => isset($_POST['qty_min']) && $_POST['qty_min'] > 0 ? (int) wc_clean($_POST['qty_min']) : 0,
'qty_max' => isset($_POST['qty_max']) && $_POST['qty_max'] > 0 ? (int) wc_clean($_POST['qty_max']) : -1,
'qty_step' => isset($_POST['qty_step']) && $_POST['qty_step'] > 1 ? (int) wc_clean($_POST['qty_step']) : 1,
) );
} else {
$product->update_meta_data( '_qty_args', array() );
}
}
// The quantity settings in action on front end
add_filter( 'woocommerce_quantity_input_args', 'filter_wc_quantity_input_args', 99, 2 );
function filter_wc_quantity_input_args( $args, $product ) {
if ( $product->is_type('variation') ) {
$parent_product = wc_get_product( $product->get_parent_id() );
$values = $parent_product->get_meta( '_qty_args' );
} else {
$values = $product->get_meta( '_qty_args' );
}
if ( ! empty( $values ) ) {
// Min value
if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
$args['min_value'] = $values['qty_min'];
if( ! is_cart() ) {
$args['input_value'] = $values['qty_min']; // Starting value
}
}
// Max value
if ( isset( $values['qty_max'] ) && $values['qty_max'] > 0 ) {
$args['max_value'] = $values['qty_max'];
if ( $product->managing_stock() && ! $product->backorders_allowed() ) {
$args['max_value'] = min( $product->get_stock_quantity(), $args['max_value'] );
}
}
// Step value
if ( isset( $values['qty_step'] ) && $values['qty_step'] > 1 ) {
$args['step'] = $values['qty_step'];
}
}
return $args;
}
// Ajax add to cart, set "min quantity" as quantity on shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_args', 'filter_loop_add_to_cart_quantity_arg', 10, 2 );
function filter_loop_add_to_cart_quantity_arg( $args, $product ) {
$values = $product->get_meta( '_qty_args' );
if ( ! empty( $values ) ) {
// Min value
if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
$args['quantity'] = $values['qty_min'];
}
}
return $args;
}
// The quantity settings in action on front end (For variable productsand their variations)
add_filter( 'woocommerce_available_variation', 'filter_wc_available_variation_price_html', 10, 3);
function filter_wc_available_variation_price_html( $data, $product, $variation ) {
$values = $product->get_meta( '_qty_args' );
if ( ! empty( $values ) ) {
if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
$data['min_qty'] = $values['qty_min'];
}
if ( isset( $values['qty_max'] ) && $values['qty_max'] > 0 ) {
$data['max_qty'] = $values['qty_max'];
if ( $variation->managing_stock() && ! $variation->backorders_allowed() ) {
$data['max_qty'] = min( $variation->get_stock_quantity(), $data['max_qty'] );
}
}
}
return $data;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I'm using "set minimum and maximum allowable product quantities to be added in WooCommerce Cart" to require a minimum and maximum quantity order.
Now, i need to impose for several products (not all) a mulitple quantity.
For example : 6 bottles, 12 bottles, 18 bottles (multiple of 6) or for other 12 bottles, 24 bottles (multiple of 12)
I found a solution but it's for every product with a unique value and I cant' manage it in the back office for each product individually.
I have to manage the multiple quantity in Backoffice.
Thank you if you can help me
Updated December 2020
The following revisited code will allow in addition to handle quantity steps.
I have changed quantity fields settings location to "General" settings tab.
I have added a checkbox that enables or disables those additional quantity settings at product level (showing or hiding the setting fields dynamically):
When checkbox unchecked (fields are not visible and quantity settings are disabled):
When checkbox is checked (fields are visible and quantity settings are enabled):
I have merged all settings in a unique custom field as an indexed array of values, to improve performance.
Since WooCommerce version 3, things have changed a lot, so I have made some changes enhancing and updating code to something more newer.
Also works nicely on Ajax add to cart for simple products, for product variations from variable products and also on the cart quantity input field.
All the code:
// Displaying quantity setting fields on admin product pages
add_action( 'woocommerce_product_options_pricing', 'wc_qty_add_product_field' );
function wc_qty_add_product_field() {
global $product_object;
$values = $product_object->get_meta('_qty_args');
echo '</div><div class="options_group quantity hide_if_grouped">
<style>div.qty-args.hidden { display:none; }</style>';
woocommerce_wp_checkbox( array( // Checkbox.
'id' => 'qty_args',
'label' => __( 'Quantity settings', 'woocommerce' ),
'value' => empty($values) ? 'no' : 'yes',
'description' => __( 'Enable this to show and enable the additional quantity setting fields.', 'woocommerce' ),
) );
echo '<div class="qty-args hidden">';
woocommerce_wp_text_input( array(
'id' => 'qty_min',
'type' => 'number',
'label' => __( 'Minimum Quantity', 'woocommerce-max-quantity' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'Set a minimum allowed quantity limit (a number greater than 0).', 'woocommerce' ),
'custom_attributes' => array( 'step' => 'any', 'min' => '0'),
'value' => isset($values['qty_min']) && $values['qty_min'] > 0 ? (int) $values['qty_min'] : 0,
) );
woocommerce_wp_text_input( array(
'id' => 'qty_max',
'type' => 'number',
'label' => __( 'Maximum Quantity', 'woocommerce-max-quantity' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'Set the maximum allowed quantity limit (a number greater than 0). Value "-1" is unlimited', 'woocommerce' ),
'custom_attributes' => array( 'step' => 'any', 'min' => '-1'),
'value' => isset($values['qty_max']) && $values['qty_max'] > 0 ? (int) $values['qty_max'] : -1,
) );
woocommerce_wp_text_input( array(
'id' => 'qty_step',
'type' => 'number',
'label' => __( 'Quantity step', 'woocommerce-quantity-step' ),
'placeholder' => '',
'desc_tip' => 'true',
'description' => __( 'Optional. Set quantity step (a number greater than 0)', 'woocommerce' ),
'custom_attributes' => array( 'step' => 'any', 'min' => '1'),
'value' => isset($values['qty_step']) && $values['qty_step'] > 1 ? (int) $values['qty_step'] : 1,
) );
echo '</div>';
}
// Show/hide setting fields (admin product pages)
add_action( 'admin_footer', 'product_type_selector_filter_callback' );
function product_type_selector_filter_callback() {
global $pagenow, $post_type;
if( in_array($pagenow, array('post-new.php', 'post.php') ) && $post_type === 'product' ) :
?>
<script>
jQuery(function($){
if( $('input#qty_args').is(':checked') && $('div.qty-args').hasClass('hidden') ) {
$('div.qty-args').removeClass('hidden')
}
$('input#qty_args').click(function(){
if( $(this).is(':checked') && $('div.qty-args').hasClass('hidden')) {
$('div.qty-args').removeClass('hidden');
} else if( ! $(this).is(':checked') && ! $('div.qty-args').hasClass('hidden')) {
$('div.qty-args').addClass('hidden');
}
});
});
</script>
<?php
endif;
}
// Save quantity setting fields values
add_action( 'woocommerce_admin_process_product_object', 'wc_save_product_quantity_settings' );
function wc_save_product_quantity_settings( $product ) {
if ( isset($_POST['qty_args']) ) {
$values = $product->get_meta('_qty_args');
$product->update_meta_data( '_qty_args', array(
'qty_min' => isset($_POST['qty_min']) && $_POST['qty_min'] > 0 ? (int) wc_clean($_POST['qty_min']) : 0,
'qty_max' => isset($_POST['qty_max']) && $_POST['qty_max'] > 0 ? (int) wc_clean($_POST['qty_max']) : -1,
'qty_step' => isset($_POST['qty_step']) && $_POST['qty_step'] > 1 ? (int) wc_clean($_POST['qty_step']) : 1,
) );
} else {
$product->update_meta_data( '_qty_args', array() );
}
}
// The quantity settings in action on front end
add_filter( 'woocommerce_quantity_input_args', 'filter_wc_quantity_input_args', 99, 2 );
function filter_wc_quantity_input_args( $args, $product ) {
if ( $product->is_type('variation') ) {
$parent_product = wc_get_product( $product->get_parent_id() );
$values = $parent_product->get_meta( '_qty_args' );
} else {
$values = $product->get_meta( '_qty_args' );
}
if ( ! empty( $values ) ) {
// Min value
if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
$args['min_value'] = $values['qty_min'];
if( ! is_cart() ) {
$args['input_value'] = $values['qty_min']; // Starting value
}
}
// Max value
if ( isset( $values['qty_max'] ) && $values['qty_max'] > 0 ) {
$args['max_value'] = $values['qty_max'];
if ( $product->managing_stock() && ! $product->backorders_allowed() ) {
$args['max_value'] = min( $product->get_stock_quantity(), $args['max_value'] );
}
}
// Step value
if ( isset( $values['qty_step'] ) && $values['qty_step'] > 1 ) {
$args['step'] = $values['qty_step'];
}
}
return $args;
}
// Ajax add to cart, set "min quantity" as quantity on shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_args', 'filter_loop_add_to_cart_quantity_arg', 10, 2 );
function filter_loop_add_to_cart_quantity_arg( $args, $product ) {
$values = $product->get_meta( '_qty_args' );
if ( ! empty( $values ) ) {
// Min value
if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
$args['quantity'] = $values['qty_min'];
}
}
return $args;
}
// The quantity settings in action on front end (For variable productsand their variations)
add_filter( 'woocommerce_available_variation', 'filter_wc_available_variation_price_html', 10, 3);
function filter_wc_available_variation_price_html( $data, $product, $variation ) {
$values = $product->get_meta( '_qty_args' );
if ( ! empty( $values ) ) {
if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
$data['min_qty'] = $values['qty_min'];
}
if ( isset( $values['qty_max'] ) && $values['qty_max'] > 0 ) {
$data['max_qty'] = $values['qty_max'];
if ( $variation->managing_stock() && ! $variation->backorders_allowed() ) {
$data['max_qty'] = min( $variation->get_stock_quantity(), $data['max_qty'] );
}
}
}
return $data;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I have this code which I use to filter Woocommerce product page, products by attributes, please can someone help me tweak this to filter Woocommerce shop orders by attribute such as 'brand' or 'weight'.
I have tried changing it myself but it doesn't return any results, any help would be very much appreciated.
Original code found here> Add a filter dropdown for specific product attribute in woocommerce admin product list
add_action('restrict_manage_posts', 'product_attribute_sorting_dropdown');
function product_attribute_sorting_dropdown() {
global $typenow;
$taxonomy = 'pa_brand';
if ( $typenow == 'product' ) {
$selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
$info_taxonomy = get_taxonomy($taxonomy);
wp_dropdown_categories(array(
'show_option_all' => __("Attribute {$info_taxonomy->label}"),
'taxonomy' => $taxonomy,
'name' => $taxonomy,
'orderby' => 'name',
'selected' => $selected,
'show_count' => true,
'hide_empty' => true,
));
};
}
add_action('parse_query', 'product_attribute_sorting_query');
function product_attribute_sorting_query( $query ) {
global $pagenow;
$taxonomy = 'pa_brand';
$q_vars = &$query->query_vars;
if ( $pagenow == 'edit.php' && isset($q_vars['post_type']) && $q_vars['post_type'] == 'product' && isset($q_vars[$taxonomy]) && is_numeric($q_vars[$taxonomy]) && $q_vars[$taxonomy] != 0 ) {
$term = get_term_by('id', $q_vars[$taxonomy], $taxonomy);
$q_vars[$taxonomy] = $term->slug;
}
}
How can I add rel next and previous in drupal-7 term pages programmatically? and how important is rel for google?
some of my pages are listed here:
کاردستی
سوپ ساده
عکس کودک
کاردستی
کاردستی
there was no solution for it as a module i myself developed a module myself.
i wish it could help you
first of all we user hook_preprocess_html
and i checked if this page is a term page or not
if (arg(0) == 'taxonomy' && arg(1) == 'term') {
and then with use of page argument and function taxonomy_select_nodes you can find on what page your are and what is the next and prevoius page
but one important this,
First page has no previous page
Last page has no next page
and there is no page with argument page=1, this is the first page
function your_theme_preprocess_html(&$variables) {
if (arg(0) == 'taxonomy' && arg(1) == 'term') {
$term = taxonomy_term_load(arg(2));
if( $_GET && $_GET['page'] && is_numeric(#$_GET['page']) ){
$prev = $_GET['page']-1;
$next = $_GET['page']+1;
$url = url('taxonomy/term/'.arg(2));
if( $_GET['page'] > 1 ){
$head_link = array(
'rel' => 'prev',
'href' => 'http://yourdomain.com'.$url.'?page='.$prev
);
drupal_add_html_head_link($head_link);
}
if( $_GET['page'] == 1 ){
$head_link = array(
'rel' => 'prev',
'href' => 'http://yourdomain.com'.$url
);
drupal_add_html_head_link($head_link);
}
$numbers = taxonomy_select_nodes( arg(2),true ,1000 );
if( count($numbers) > $next * 100 ){
$head_link = array(
'rel' => 'next',
'href' => 'http://yourdomain.com'.$url.'?page='.$next
);
drupal_add_html_head_link($head_link);
}
}
else {
$numbers = taxonomy_select_nodes( arg(2),true ,1000 );
if( count($numbers) > 100 ){
$url = url('taxonomy/term/'.arg(2));
$head_link = array(
'rel' => 'next',
'href' => 'http://yourdomain.com'.$url.'?page=1'
);
drupal_add_html_head_link($head_link);
}
}
}
}
this function taxonomy_select_nodes is really awesome, you give it "tid" of a term, it tells you how node is tagged with this term.
even you can add class to body with hook_preprocess_html
write all this code in template.php file in your theme
This is my code at checkout page. I was developed custom payment gateway plugin for it, but when i am try to click on place order button it is not submitting the request parameters and not getting response ?
public function process_payment( $order_id ) {
global $woocommerce;
// Get this Order's information so that we know
// who to charge and how much
$customer_order = new WC_Order( $order_id );
// Are we testing right now or is it a real transaction
$Mode = ( $this->Mode == "yes" ) ? 'TRUE' : 'FALSE';
// Decide which URL to post to
$environment_url = ( "FALSE" == $Mode )
? 'https://www.qpayindia.com/wwws/Payment/PaymentDetails.aspx'
: 'https://www.qpayindia.com/wwws/Payment/PaymentDetails.aspx';
// This is where the fun stuff begins
$payload = array(
// Authorize.net Credentials and API Info
"QPayID" => $this->QPayID,
"QPayPWD" => $this->QPayPWD,
"CaseNumber" => $this->CaseNumber,
"Mode" => $this->Mode,
"Currency" => $this->Currency,
"Amount" => $customer_order->order_total,
"ResponseURL" => $customer_order->get_checkout_payment_url(),
"OrderID" => str_replace( "#", "", $customer_order->get_order_number() ),
// Some Customer Information
"x_cust_id" => $customer_order->user_id,
"x_customer_ip" => $_SERVER['REMOTE_ADDR'],*/
);
// Send this payload to Authorize.net for processing
$response = wp_remote_post( $environment_url, array(
'method' => 'POST',
'body' => http_build_query( $payload ),
'timeout' => 90,
'sslverify' => false,
) );
if ( is_wp_error( $response ) )
throw new Exception( __( 'We are currently experiencing problems trying to connect to this payment gateway. Sorry for the inconvenience.', 'spyr-authorizenet-aim' ) );
if ( empty( $response['body'] ) )
throw new Exception( __( 'Authorize.net\'s Response was empty.', 'spyr-authorizenet-aim' ) );
// Retrieve the body's resopnse if no errors found
$response_body = wp_remote_retrieve_body( $response );
// Parse the response into something we can read
foreach ( preg_split( "/\r?\n/", $response_body ) as $line ) {
$resp = explode( "|", $line );
}
// Get the values we need
$r['ResponseCode'] = $resp[0];
$r['response_sub_code'] = $resp[1];
$r['response_reason_code'] = $resp[2];
$r['Message'] = $resp[3];
// Test the code to know if the transaction went through or not.
// 1 or 4 means the transaction was a success
if ( ( $r['ResponseCode'] == 100 ) || ( $r['ResponseCode'] == 200 ) ) {
// Payment has been successful
$customer_order->add_order_note( __( 'Qpay payment completed.', 'spyr-authorizenet-aim' ) );
// Mark order as Paid
$customer_order->payment_complete();
// Empty the cart (Very important step)
$woocommerce->cart->empty_cart();
// Redirect to thank you page
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $customer_order ),
);
} else {
// Transaction was not succesful
// Add notice to the cart
wc_add_notice( $r['Message'], 'error' );
// Add note to the order for your reference
$customer_order->add_order_note( 'Error: '. $r['Message'] );
}
}