I hope someone could help me :-)
I try to trigger an action after each product imported (via csv file) in a woocommerce shop. Products are variable products with all the same attributes and variations. That's why, to simplify the csv file (just a raw per product), I added a "save_post" action in my theme function.php.
Here is the code :
add_action( 'save_post', 'auto_add_product_attributes', 50, 3 );
function auto_add_product_attributes( $post_id, $post, $update ) {
// Echape la fonction si le post n'est pas de type produit, fonctionne s'il s'agit d'un enregistrement automatique, d'une mise à jour et si l'utilisateur n'est pas autorisé à modifier le produit
if ( $post->post_type != 'product') return; // Only products
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
if( $update )
return;
if ( ! current_user_can( 'edit_product', $post_id ) )
return $post_id;
// convertit le produit en produit variable autorisant les variations et visible en front
wp_set_object_terms( $post_id, 'variable', 'product_type' );
$visible = '1';
$variation = '1';
// Récupère tous les attributs du menu ATTRIBUTS, crée un tableau vide avec curseur à la postion 0
global $wpdb;
$attributes = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_attribute_taxonomies" );
$position = 0;
$data = array();
// Boucle relative à tous les attributs récupérés
foreach( $attributes as $attribute ){
// Récupère noms et ids des attributs
$taxonomy = 'pa_'.$attribute->attribute_name;
$attribute_id = $attribute->attribute_id;
// Récupères les ids des termes de l'attribut courant
$term_ids = get_terms(array('taxonomy' => $taxonomy, 'fields' => 'ids'));
// Crée une instance vide de l'objet WC_Product_Attribute
$product_attribute = new WC_Product_Attribute();
// Initialise les données suivantes dans l'objet WC_Product_Attribute
$product_attribute->set_id( $attribute_id );
$product_attribute->set_name( $taxonomy );
$product_attribute->set_options( $term_ids );
$product_attribute->set_position( $position );
$product_attribute->set_visible( $visible );
$product_attribute->set_variation( $variation );
// Ajoute les données de l'objet WC_Product_Attribute dans un tableau et incremente la position
$data[$taxonomy] = $product_attribute;
$position++;
}
// Récupère les données du produit par son id
$product = wc_get_product( $post_id );
// Met à jour les données récupérées par la boucle
$product->set_attributes( $data );
// Crée toutes les variations associé aux attributs mis à jour
wc_maybe_define_constant( 'WC_MAX_LINKED_VARIATIONS', 50 );
wc_set_time_limit( 0 );
if ( ! $post_id ) {
wp_die();
}
$data_store = $product->get_data_store();
if ( ! is_callable( array( $data_store, 'create_all_product_variations' ) ) ) {
wp_die();
}
echo esc_html( $data_store->create_all_product_variations( $product, WC_MAX_LINKED_VARIATIONS ) );
$data_store->sort_all_product_variations( $product->get_id() );
// sauvegarde le produit
$product->save();
// Fonction de génération d'un mdp aléatoire
function generateStrongPassword($length = 9, $add_dashes = false, $available_sets = 'luds')
{
$sets = array();
if(strpos($available_sets, 'l') !== false)
$sets[] = 'abcdefghjkmnpqrstuvwxyz';
if(strpos($available_sets, 'u') !== false)
$sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ';
if(strpos($available_sets, 'd') !== false)
$sets[] = '23456789';
if(strpos($available_sets, 's') !== false)
$sets[] = '!##$%&*?';
$all = '';
$password = '';
foreach($sets as $set)
{
$password .= $set[array_rand(str_split($set))];
$all .= $set;
}
$all = str_split($all);
for($i = 0; $i < $length - count($sets); $i++)
$password .= $all[array_rand($all)];
$password = str_shuffle($password);
if(!$add_dashes)
return $password;
$dash_len = floor(sqrt($length));
$dash_str = '';
while(strlen($password) > $dash_len)
{
$dash_str .= substr($password, 0, $dash_len) . '-';
$password = substr($password, $dash_len);
}
$dash_str .= $password;
return $dash_str;
}
//Génère un mdp aléatoire
$mdp_secure_generated = generateStrongPassword();
//Tableau stockant les nouvelles valeurs à mettre à jour
$args_update_mdp = array(
'ID' => $post_id,
'post_password' => $mdp_secure_generated,
);
// Mise à jour du mdp
wp_update_post( $args_update_mdp );
// Récupère les données du produit par son id
$product = wc_get_product( $post_id );
foreach( $product->get_children() as $variation_id ){
//Récupère les data de la variation par son id
$variation_data = wc_get_product($variation_id);
//Récupère le nom de cette variation
$variation_name = $variation_data->get_name();
// Ote le préfixe composé du nom du produit au nom de la variation
$chaine_a_oter = $product->get_name()." - ";
$variation_name = str_replace($chaine_a_oter, "", $variation_name);
// Récupère descriptions et noms des termes de l'attribut de menu "FORMATS"
$format_children = get_terms("pa_formats");
foreach ( $format_children as $term ) {
$term_description = get_term_field( 'description', $term );
$term_name = get_term_field( 'name', $term );
$term_price = get_field( 'prix_en_cours', $term );
if ($term_name == $variation_name) {
update_post_meta( $variation_id, '_variation_description', $term_description );
update_post_meta( $variation_id, '_regular_price', $term_price );
update_post_meta( $variation_id, '_price', $term_price );
}
}
// Vide le cache de la variation
wc_delete_product_transients( $variation_id );
}
// Vide le cache du produit variable
wc_delete_product_transients( $post_id );
// sauvegarde le produit
$product->save();
}
The first product is correctly imported/created with its attributes/terms/variations/variations values... but import process breaks after import of the second product without running action hook (backend, import process is never completed).
I suspect that the problem occurs when hook runs for the second time... but I don't know where is the issue !
Sorry for my poor english... hope you will understand what I mean :-)
Thanks in advance for your help !
I finally fixed my issue with that code
add_action( 'woocommerce_new_product', 'auto_add_product_attributes', 50, 3 );
function auto_add_product_attributes( $product_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $product_id ;
if ( ! current_user_can( 'edit_product', $product_id ) )
return $product_id ;
//Génère un mdp aléatoire
$mdp_secure_generated = generateStrongPassword();
//Tableau stockant les nouvelles valeurs à mettre à jour
$args_update_mdp = array(
'ID' => $product_id,
'post_password' => $mdp_secure_generated,
);
// convertit le produit en produit variable autorisant les variations et visible en front
wp_set_object_terms( $product_id, 'variable', 'product_type' );
$visible = '1';
$variation = '1';
// Récupère tous les attributs du menu ATTRIBUTS, crée un tableau vide avec curseur à la postion 0
global $wpdb;
$attributes = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_attribute_taxonomies" );
$position = 0;
$data = array();
// Boucle relative à tous les attributs récupérés
foreach( $attributes as $attribute ){
// Récupère noms et ids des attributs
$taxonomy = 'pa_'.$attribute->attribute_name;
$attribute_id = $attribute->attribute_id;
// Récupères les ids des termes de l'attribut courant
$term_ids = get_terms(array('taxonomy' => $taxonomy, 'fields' => 'ids'));
// Crée une instance vide de l'objet WC_Product_Attribute
$product_attribute = new WC_Product_Attribute();
// Initialise les données suivantes dans l'objet WC_Product_Attribute
$product_attribute->set_id( $attribute_id );
$product_attribute->set_name( $taxonomy );
$product_attribute->set_options( $term_ids );
$product_attribute->set_position( $position );
$product_attribute->set_visible( $visible );
$product_attribute->set_variation( $variation );
// Ajoute les données de l'objet WC_Product_Attribute dans un tableau et incremente la position
$data[$taxonomy] = $product_attribute;
$position++;
}
// Récupère les données du produit par son id
$product = wc_get_product( $product_id );
// Mise à jour du mdp
wp_update_post( $args_update_mdp );
// Met à jour les données récupérées par la boucle
$product->set_attributes( $data );
// Crée toutes les variations associées aux attributs mis à jour
$data_store = $product->get_data_store();
$data_store->create_all_product_variations($product, $maxVariations);
$data_store->sort_all_product_variations($product->get_id());
$product->save();
$product_on = wc_get_product( $product_id );
foreach( $product_on->get_children() as $variation_id ){
//Récupère les data de la variation par son id
$variation_data = wc_get_product($variation_id);
//Récupère le nom de cette variation
$variation_name = $variation_data->get_name();
// Ote le préfixe composé du nom du produit au nom de la variation
$chaine_a_oter = $product_on->get_name().' - ';
$variation_name = str_replace($chaine_a_oter, '', $variation_name);
// Récupère descriptions et noms des termes de l'attribut de menu "FORMATS"
$format_children = get_terms("pa_formats");
foreach ( $format_children as $term ) {
$term_description = get_term_field( 'description', $term );
$term_name = get_term_field( 'name', $term );
$term_price = get_field( 'prix_en_cours', $term );
if ($term_name == $variation_name) {
update_post_meta( $variation_id, '_variation_description', $term_description );
update_post_meta( $variation_id, '_regular_price', $term_price );
update_post_meta( $variation_id, '_price', $term_price );
}
}
// Vide le cache de la variation
wc_delete_product_transients( $variation_id );
}
// Vide le cache du produit variable
wc_delete_product_transients( $product_id );
// sauvegarde le produit
$product_on->save();
}
The problem was the generateStrongPassword() function which was declared twice, and the $product->save() function.
Code tested and works.
Hope it will help :-)
Related
I can't add the HT in my cart.
I have to have the TTC and HT displayed here.
The TTC is 22,80 €.
And the HT, it is 19 €.
The VAT is 3,80€.
I have this code
// For Woocommerce 2.5+ (2.6.x and 3.0)
add_action('woocommerce_cart_calculate_fees', 'prefix_add_tva_line', 10, 1);
function prefix_add_tva_line($cart)
{
// is_admin Détermine si la demande actuelle concerne une page
//d'interface administrative.
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
$discount = 0;
// Get the unformated taxes array.
// Obtenez le tableau des taxes non formées.
// $cart->get_taxes(); il y a deux tableaux array(1){[1]=>float(3.8)} array(1){[1]=>float(3.8)}.
$taxes = $cart->get_taxes();
// Ajouter chaque taxe à $discount.
// $taxes c'est le tableaux a parcourir et $taxe c'est la valeur taxe est assignée
foreach ($taxes as $tax) {
$discount = $tax;
}
// Applying a discount if not null or equal to zero.
// applique a discount si elle n'est pas nulle ou égale à zéro.
if ($discount > 0 && !empty($discount)) {
$cart->add_fee(__('TVA', 'HT'), + $discount);
}
}
which gives me 3,80€ in Tax, but that in positive (+),
that makes 22,80€ + 3.80€ = 26,60€.
Even if I do $cart->add_fee(__('VAT', 'HT'), **-** $discount); the calculation of the VAT will still be done.
Hello i have try to code my own plugin for wordpress and woocommerce but i have somes little problems : wen the user send the order
<?php
/**
* Plugin Name: WooCommerce Order to Excel
* Description: Replaces WooCommerce order emails with an Excel file attachment
* Version: 1.0
* Author: Marin
* Author URI: monsite.com
* License: GPL2
*/
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
// Ajouter un filtre pour remplacer l'email de commande par un fichier Excel
add_filter( 'woocommerce_email_attachments', 'replace_order_email_with_excel', 10, 3 );
function replace_order_email_with_excel( $attachments, $email_id, $order ) {
if ( 'new_order' === $email_id && $order ) {
$excel_file = generate_excel_from_order( $order );
$attachments[] = $excel_file;
}
return $attachments;
}
function generate_excel_from_order( $order ) {
// Répertoire de sauvegarde
$dir = './backup/';
// Vérifier si le répertoire existe et est accessible en écriture
if (!is_dir($dir)) {
// Répertoire n'existe pas, le créer
if (!mkdir($dir, 0777, true)) {
trigger_error('Impossible de créer le répertoire de sauvegarde', E_USER_WARNING);
return false;
}
}
if (!is_writable($dir)) {
// Répertoire n'est pas accessible en écriture
trigger_error('Répertoire de sauvegarde non accessible en écriture', E_USER_WARNING);
return false;
}
$locale = get_locale();
switch ( $locale ) {
case 'fr_FR':
$template_file = 'template-fr.xlsx';
break;
case 'zh_CN':
$template_file = 'template-zh.xlsx';
break;
case 'en_US':
default:
$template_file = 'template-en.xlsx';
break;
}
// Créer un nouveau classeur
$spreadsheet = new Spreadsheet();
// Obtenir la première feuille
$sheet = $spreadsheet->getActiveSheet();
// Définir le numéro de commande
$sheet->setCellValue( 'G1', $order->get_order_number() );
// Définir la date de la commande
$sheet->setCellValue( 'A4', $order->get_date_created()->format( 'Y-m-d' ) );
// Définir les informations client
$sheet->setCellValue( 'C4', $order->get_billing_company() );
$sheet->setCellValue( 'A5', $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() );
$sheet->setCellValue( 'C5', $order->get_billing_email() );
$sheet->setCellValue( 'E5', $order->get_billing_phone() );
$sheet->setCellValue( 'G5', $order->get_billing_address_1() . ' ' . $order->get_billing_address_2() );
$sheet->setCellValue( 'G6', $order->get_billing_city() . ', ' . $order->get_billing_state() . ' ' . $order->get_billing_postcode() );
$sheet->setCellValue( 'G7', $order->get_billing_country() );
// Obtenir les articles de la commande
$items = $order->get_items();
$row = 18;
foreach ( $items as $item ) {
$sheet->setCellValue( 'B' . $row, $item->get_name() );
$sheet->setCellValue( 'H' . $row, $item->get_quantity() );
$sheet->setCellValue( 'K' . $row, $item->get_total() );
// Add the serial number
$sheet->setCellValue( 'G' . $row, get_serial_number( $item ) );
$row++;
}
// Enregistrer le fichier Excel
$file_name = $dir . $order->get_order_number() . '.xlsx';
$writer = IOFactory::createWriter( $spreadsheet, 'Xlsx' );
$writer->save( $file_name );
return $file_name;
}
?>
I have coded a plugin to replace the email received at each order by the woocommerce administrator, I want to replace this email with an excel file generated with the order information using an excel file template that I put in the plugin folder
The problem is that when I place an order I have an error message in front-end as the order does not pass, but I still received a confirmation email but without the excel file.
I tried to debug but without really having any result, do you think my code is a problem?
I already installed the PHPspreadseeet library, manually but also with a plugin : CBX PhpSpreedSheet Library
I see you don't have any get_serial_number and here it is:
function get_serial_number( $item ) {
// You can generate the serial number here
return $serial_number;
}
TLDR:
I'm trying to remove the discount totals added with a coupon without removing the coupon.
So far the best option seems to be:
$woocommerce->cart->set_discount_total(0);
But it doesn't work.
The full history:
Due some business rules I need to apply the coupon discount to electible products in cart, while the others keep it full price.
After all the validations I'm setting the new price like this:
$cart_item['data']->set_price( $new_price );
And trying to remove the discount totals like this:
$woocommerce->cart->set_discount_total(0);
I can't remove the coupon from the cart because it is the subject of all validations, if it's removed the prices will be back to normal.
I've found the add_fee() method earlier but it mess up too much to be worth as a work around.
Here's the complete code:
It's a WIP and need refactoring, I'm sorry for the big chunk of code.
dd_action( 'woocommerce_before_calculate_totals', 'ne_wc_apply_price_for_seller_restriction_coupons', 999, 1);
function ne_wc_apply_price_for_seller_restriction_coupons( $cart_obj ) {
// var_dump($cart_obj);wp_die();
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
return;
}
// Avoiding hook repetition (when using price calculations for example)
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ){
return;
}
global $woocommerce;
//Array com os codigos dos cupons no carrinho
$coupon_ids = [];
//Array com os ids do sellers dos cupons
$coupon_seller_ids = [];
// Pegamos os codigos dos cupons existentes no carrinho
if ( count( $coupon_ids ) <= 0) {
$coupon_codes = $cart_obj->get_applied_coupons();
// o carrinho armazena os códigos, não os IDs, então pegamos um por um
foreach ($coupon_codes as $code) {
$coupon = new WC_Coupon($code);
array_push($coupon_ids, $coupon->get_id());
}
}
//Pegamos os sellers de cada cupom
foreach ($coupon_ids as $id) {
$coupon_seller_ids[$id]['ne_wc_sellers'] = get_post_meta( $id, 'ne_wc_sellers', true );
$coupon_seller_ids[$id]['discount_type'] = get_post_meta( $id, 'discount_type', true );
$coupon_seller_ids[$id]['coupon_amount'] = get_post_meta( $id, 'coupon_amount', true );
$coupon_seller_ids[$id]['prorate_quantity'] = 0; // será a quantidade a dividir o valor do cupom entre os itens
$coupon_seller_ids[$id]['prorate_value'] = 0; // será o valor final unitario a subtrair de cada item
}
// Pegamos os produtos do carrinho
$cart_items = $cart_obj->cart_contents;
foreach ($cart_items as $cart_item_key => $cart_item) {
$product_seller_id = get_post_field( 'post_author', $cart_item['data']->get_id() );
//Verificamos se este produto pertece ao seller de um dos cupons
foreach ($coupon_seller_ids as $coupon_id => $coupon_data) {
if ( in_array( $product_seller_id, $coupon_data['ne_wc_sellers'] ) ) {
//guardamos os dados do cupom para fazer o rateio do desconto
$coupon_seller_ids[$coupon_id]['prorate_quantity'] += $cart_item['quantity'];
}
}
}
foreach ($coupon_seller_ids as $id => $coupon_data) {
//para cada tipo de desconto uma abordagem diferente vai ser tomada
switch ($coupon_data['discount_type']) {
//o tipo `fixed_product` concede o desconto no valor unitario do produto
case 'fixed_product':
foreach ( $cart_obj->get_cart() as $cart_item ) {
//novamente pegamos o seller desse produto
$product_seller_id = get_post_field( 'post_author', $cart_item['data']->get_id() );
//verificamos se ele está entre os sellers elegíveis
if ( in_array( $product_seller_id, $coupon_data['ne_wc_sellers'] ) ) {
$current_price = $cart_item['data']->get_price();
$new_price = $current_price - $coupon_seller_ids[$id]['coupon_amount'];
//definimos o novo preço se ele for maior que zero, se não definimos o menor preço possivel
$cart_item['data']->set_price( ($new_price > 0) ? $new_price : 0.01 );
}
}
//removemos o desconto padrão do cupom
$woocommerce->cart->set_discount_total(0);
break;
//o tipo `fixed_cart` rateia o valor total do desconto em cada unidade de produtos elegiveis
case 'fixed_cart':
//calculamos o valor a ser debitado de cada um dos itens
$coupon_seller_ids[$id]['prorate_value'] = $coupon_data['coupon_amount'] / $coupon_data['prorate_quantity'];
foreach ( $cart_obj->get_cart() as $cart_item ) {
$product_seller_id = get_post_field( 'post_author', $cart_item['data']->get_id() );
if ( in_array( $product_seller_id, $coupon_data['ne_wc_sellers'] ) ) {
$current_price = $cart_item['data']->get_price();
$new_price = $current_price - $coupon_seller_ids[$id]['prorate_value'];
//definimos o novo preço se ele for maior que zero, se não definimos o menor preço possivel
$cart_item['data']->set_price( ($new_price > 0) ? $new_price : 0.01 );
}
}
//removemos o desconto padrão do cupom
$woocommerce->cart->set_discount_total(0);
break;
// o tipo `percent` aplicará o desconto percentual sobre o valor unitario do item
case 'percent':
foreach ( $cart_obj->get_cart() as $cart_item ) {
$product_seller_id = get_post_field( 'post_author', $cart_item['data']->get_id() );
if ( in_array( $product_seller_id, $coupon_data['ne_wc_sellers'] ) ) {
$current_price = $cart_item['data']->get_price();
$new_price = $current_price - ($current_price * ($coupon_data['coupon_amount'] / 100));
//definimos o novo preço se ele for maior que zero, se não definimos o menor preço possivel
$cart_item['data']->set_price( ($new_price > 0) ? $new_price : 0.01 );
}
}
//removemos o desconto padrão do cupom
$woocommerce->cart->set_discount_total(0);
break;
default:
# code...
break;
}
}
}
I am trying to make a store that the products have multiple prices, one for every supplier. And when i choose the products , show in the cart the prices and subtotals of each supplier. For example, i enter the store, then choose sugar and milk without knowing the prices, proceed to cart and in the cart page i can see: Sugar- Store 1 $10- Store 2 $20 / Milk - Store 1 $20 - Store 2 $30---Subtotal Store 1=$30 Store 2=$50. And that's it, i dont need to proceed with checkout, it's only to compare stores prices from equal products. i try variable products, i get to show the prices on cart but i can't make more than one subtotal array by the variable id. Any ideas?
well, maybe this answer will help someone else in the future, i figure it out, i leave the function here just in case
// Muestra los custom fields en el carrito
add_filter( 'woocommerce_get_item_data', 'super_custom_field', 10, 2 );
function super_custom_field( $cart_data, $cart_item )
{
$items_super = array();
if( !empty( $cart_data ) )
$custom_items = $cart_data;
// Los busca desde el id
$product_id = $cart_item['product_id'];
$supermercado_1 = get_field('super_1',7);
$supermercado_2 = get_field('super_2',7);
$supermercado_3 = get_field('super_3',7);
if( $precio_1 = get_post_meta( $product_id, 'precio_1', true ))
if( $precio_2 = get_post_meta( $product_id, 'precio_2', true ))
if( $precio_3 = get_post_meta( $product_id, 'precio_3', true ))
$items_super[] = array(
'name' => __( 'Precios en supermercados', 'woocommerce'),
'display' => '<div>
<p class="super1 supermercados"><strong>' . ($supermercado_1). '</strong> <span>$' . ($precio_1). '</span></p>
<p class="super2 supermercados"><strong>' . ($supermercado_2). '</strong> <span>$' . ($precio_2). '</span></p>
<p class="super3 supermercados"><strong>' . ($supermercado_3). '</strong> <span>$' . ($precio_3). '</span></p>
</div>',
);
return $items_super;
}
//Suma los custom field de precio 1
//Elige el lugar donde lo muestra
add_filter( 'woocommerce_after_cart_contents', 'suma_precio_1', 10, 2 );
//este es despues del carro antes del checkout
add_action( 'woocommerce_cart_totals_before_shipping', 'suma_precio_1', 20 );
//este es en el checkout
add_action( 'woocommerce_review_order_before_shipping', 'suma_precio_1', 20 );
function suma_precio_1() {
$total_1 = 0;
$supermercado_1 = get_field('super_1',7);
// Busca en el loop del carro el cutom field en cada producto y los suma y multiplica por la cantidad
foreach( WC()->cart->get_cart() as $cart_item ){
$precio_super_1 = (float) get_post_meta( $cart_item['product_id'], 'precio_1', true );
$total_1 += $precio_super_1 * $cart_item['quantity'];
}
if( $total_1 > 0 ){
// The Output
echo ' <tr class="super1">
<td colspan="5"><p><strong>' .$supermercado_1. '</strong></td> <td colspan="" style="text-align:right;"><span>$' . number_format($total_1, 2) . '</span></p></td>
</tr>';
}
}
//Suma los custom field de precio 1
//Elige el lugar donde lo muestra
add_filter( 'woocommerce_after_cart_contents', 'suma_precio_2', 10, 2 );
//este es despues del carro antes del checkout
add_action( 'woocommerce_cart_totals_before_shipping', 'suma_precio_2', 20 );
//este es en el checkout
add_action( 'woocommerce_review_order_before_shipping', 'suma_precio_2', 20 );
function suma_precio_2() {
$total_2 = 0;
$supermercado_2 = get_field('super_2', 7);
// Busca en el loop del carro el cutom field en cada producto y los suma y multiplica por la cantidad
foreach( WC()->cart->get_cart() as $cart_item ){
$precio_super_2 = (float) get_post_meta( $cart_item['product_id'], 'precio_2', true );
$total_2 += $precio_super_2 * $cart_item['quantity'];
}
if( $total_2 > 0 ){
// The Output
echo ' <tr class="super2">
<td colspan="5"><p><strong>' .$supermercado_2. '</strong></td> <td colspan="" style="text-align:right;"><span>$' . number_format($total_2, 2) . '</span></p></td>
</tr>';
}
}
//Suma los custom field de precio 1
//Elige el lugar donde lo muestra
add_filter( 'woocommerce_after_cart_contents', 'suma_precio_3', 10, 2 );
//este es despues del carro antes del checkout
add_action( 'woocommerce_cart_totals_before_shipping', 'suma_precio_3', 20 );
//este es en el checkout
add_action( 'woocommerce_review_order_before_shipping', 'suma_precio_3', 20 );
function suma_precio_3() {
$total_3 = 0;
$supermercado_3 = get_field('super_3', 7);
// Busca en el loop del carro el custom field en cada producto y los suma y multiplica por la cantidad
foreach( WC()->cart->get_cart() as $cart_item ){
$precio_super_3 = (float) get_post_meta( $cart_item['product_id'], 'precio_3', true );
$total_3 += $precio_super_3 * $cart_item['quantity'];
}
if( $total_3 > 0 ){
// The Output
echo ' <tr class="super3">
<td colspan="5"><p><strong>' .$supermercado_3. '</strong></td> <td colspan="" style="text-align:right;"><span>$' . number_format($total_3, 2) . '</span></p></td>
</tr>';
}
}
Inspired from Minimum cart amount for specific product categories in WooCommerce I have the following code
add_action( 'woocommerce_check_cart_items', 'checkout_required_min_weight_mood' );
function checkout_required_min_weight_mood () {
// soltanto sulle pagine carrello e check out
if( ! ( is_cart() || is_checkout() ) ) return;
// qui il minimo del peso
$minimum_weight = 20; // 20 kg
// Get the Cart's content total weight
$total_weight = WC()->cart->get_cart_contents_weight();
// Se il peso totale è inferiore al minimo, evitiamo il pagamento e visualizziamo un avviso di errore
if( $total_weight < $minimum_weight ) {
// Visualizza un avviso di errore dinamico
wc_add_notice( sprintf(
'<strong>Il minimo peso di %s è richiesto prima di acquistare.</strong>'
. '<br />Il peso totale dei prodotti nel tuo carrello al momento è di %s',
wc_format_weight($minimum_weight),
wc_format_weight($total_weight)
), 'error' );
}
}
I would have liked it applied to the category (slug: special-box) and hide the "proceed to check out button" until the minimum is reached.
The following code checks whether a product in the shopping cart belongs to the category: special-box and hides the "proceed to checkout button" if the minimum weight has not been reached.
function checkout_required_min_weight_mood () {
// Only on cart and check out pages
if( ! ( is_cart() || is_checkout() ) ) return;
// The minimum weight
$minimum_weight = 20; // 20 kg
// Get the Cart's content total weight
$total_weight = WC()->cart->get_cart_contents_weight();
// Set $cat_in_cart to false
$cat_in_cart = false;
// Loop through all products in the Cart
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// If Cart has category "special-box", set $cat_in_cart to true
if ( has_term( 'special-box', 'product_cat', $cart_item['product_id'] ) ) {
$cat_in_cart = true;
break;
}
}
// If the total weight is less than the minimum, we avoid payment and display an error notice & category is in the Cart
if( $total_weight < $minimum_weight && $cat_in_cart ) {
// Displays a dynamic error warning
wc_add_notice( sprintf(
'<strong>Il minimo peso di %s è richiesto prima di acquistare.</strong>'
. '<br />Il peso totale dei prodotti nel tuo carrello al momento è di %s',
wc_format_weight($minimum_weight),
wc_format_weight($total_weight)
), 'error' );
// Removing the Proceed to checkout button from the Cart page
remove_action( 'woocommerce_proceed_to_checkout','woocommerce_button_proceed_to_checkout', 20);
}
}
add_action( 'woocommerce_check_cart_items', 'checkout_required_min_weight_mood' );