Dacă ai un magazin online cu WooCommerce și vrei să oferi clienților opțiuni de montaj personalizate pentru produsele de tip aer condiționat, acest tutorial îți arată pas cu pas cum să faci acest lucru. Vei putea să afișezi pe pagina produsului opțiuni prin care clientul poate selecta detalii legate de montaj, iar costurile suplimentare să fie calculate automat la finalizarea comenzii.
De ce să implementezi opțiuni personalizate pentru montaj?
Oferirea opțiunilor de montaj personalizate are numeroase beneficii atât pentru afacerea ta, cât și pentru clienți:
- Automatizare completă: Economisești timp automatizând calculul costurilor suplimentare.
- Experiență mai bună pentru client: Clientul poate selecta toate detaliile legate de montaj fără să fie nevoie de intervenția unui operator.
- Reducerea riscului de erori: Calculul automat al costurilor previne greșelile care pot apărea dacă faci aceste calcule manual.
De exemplu, dacă ai un produs precum un aparat de aer condiționat, montajul poate implica costuri suplimentare în funcție de etaj, tipul de perete sau lungimea țevilor folosite. Implementând opțiuni personalizate, clientul poate vedea în timp real costurile și detaliile adăugate.
Implementarea completă a opțiunilor de montaj
<?php
// Adaugă bifa și opțiunile de preț în tab-ul General al produsului în admin
add_action('woocommerce_product_options_general_product_data', 'add_ac_installation_checkbox');
function add_ac_installation_checkbox() {
woocommerce_wp_checkbox([
'id' => '_enable_ac_installation',
'label' => 'Activare opțiuni montaj A/C',
'description' => 'Bifează această opțiune pentru a afișa opțiunile de montaj pe pagina produsului.',
]);
echo '<div id="ac_installation_fields" style="display: none;">';
woocommerce_wp_text_input([
'id' => '_ac_price_floor_2',
'label' => 'Cost montaj etaj 0-2',
'type' => 'number',
'custom_attributes' => ['step' => '0.01', 'min' => '0']
]);
woocommerce_wp_text_input([
'id' => '_ac_price_floor_3',
'label' => 'Cost montaj etaj 3-4',
'type' => 'number',
'custom_attributes' => ['step' => '0.01', 'min' => '0']
]);
woocommerce_wp_text_input([
'id' => '_ac_price_floor_4',
'label' => 'Cost montaj etaj 5+',
'type' => 'number',
'custom_attributes' => ['step' => '0.01', 'min' => '0']
]);
woocommerce_wp_text_input([
'id' => '_ac_price_wall_caramida',
'label' => 'Cost perete cărămidă',
'type' => 'number',
'custom_attributes' => ['step' => '0.01', 'min' => '0']
]);
woocommerce_wp_text_input([
'id' => '_ac_price_wall_beton',
'label' => 'Cost perete beton',
'type' => 'number',
'custom_attributes' => ['step' => '0.01', 'min' => '0']
]);
woocommerce_wp_text_input([
'id' => '_ac_price_pipe',
'label' => 'Cost per metru țeavă',
'type' => 'number',
'custom_attributes' => ['step' => '0.01', 'min' => '0']
]);
echo '</div>';
?>
<script>
jQuery(document).ready(function($) {
function toggleAcFields() {
if ($('#_enable_ac_installation').is(':checked')) {
$('#ac_installation_fields').show();
} else {
$('#ac_installation_fields').hide();
}
}
toggleAcFields();
$('#_enable_ac_installation').change(toggleAcFields);
});
</script>
<?php
}
// Salvează valorile bifei și ale prețurilor
add_action('woocommerce_admin_process_product_object', 'save_ac_installation_checkbox');
function save_ac_installation_checkbox($product) {
$product->update_meta_data('_enable_ac_installation', isset($_POST['_enable_ac_installation']) ? 'yes' : 'no');
$product->update_meta_data('_ac_price_floor_2', sanitize_text_field($_POST['_ac_price_floor_2']));
$product->update_meta_data('_ac_price_floor_3', sanitize_text_field($_POST['_ac_price_floor_3']));
$product->update_meta_data('_ac_price_floor_4', sanitize_text_field($_POST['_ac_price_floor_4']));
$product->update_meta_data('_ac_price_wall_caramida', sanitize_text_field($_POST['_ac_price_wall_caramida']));
$product->update_meta_data('_ac_price_wall_beton', sanitize_text_field($_POST['_ac_price_wall_beton']));
$product->update_meta_data('_ac_price_pipe', sanitize_text_field($_POST['_ac_price_pipe']));
$product->save();
}
// Afișează opțiunile de montaj pe pagina produsului
add_action('woocommerce_before_add_to_cart_button', 'display_ac_installation_options');
function display_ac_installation_options() {
global $product;
if (get_post_meta($product->get_id(), '_enable_ac_installation', true) !== 'yes') {
return;
}
$product_price = floatval($product->get_price());
$price_floor_2 = get_post_meta($product->get_id(), '_ac_price_floor_2', true) ?: 0;
$price_floor_3 = get_post_meta($product->get_id(), '_ac_price_floor_3', true) ?: 0;
$price_floor_4 = get_post_meta($product->get_id(), '_ac_price_floor_4', true) ?: 0;
$price_wall_caramida = get_post_meta($product->get_id(), '_ac_price_wall_caramida', true) ?: 0;
$price_wall_beton = get_post_meta($product->get_id(), '_ac_price_wall_beton', true) ?: 0;
$price_pipe = get_post_meta($product->get_id(), '_ac_price_pipe', true) ?: 0;
?>
<div id="ac_installation_options">
<h3>🔧 Opțiuni montaj aer condiționat</h3>
<label>🏬 Selectează etajul:</label>
<div class="button-group" id="ac_floor">
<button type="button" class="floor-btn" data-value="0-2" data-price="<?= $price_floor_2 ?>">Etaj 0-2 (+<?= $price_floor_2 ?>)</button>
<button type="button" class="floor-btn" data-value="3-4" data-price="<?= $price_floor_3 ?>">Etaj 3-4 (+<?= $price_floor_3 ?>)</button>
<button type="button" class="floor-btn" data-value="5+" data-price="<?= $price_floor_4 ?>">Etaj 5+ (+<?= $price_floor_4 ?>)</button>
</div>
<input type="hidden" name="ac_floor" id="ac_floor_input" value="">
<label>🧱 Selectează tip perete:</label>
<div class="button-group" id="ac_wall">
<button type="button" class="wall-btn" data-value="caramida" data-price="<?= $price_wall_caramida ?>">Cărămidă (+<?= $price_wall_caramida ?>)</button>
<button type="button" class="wall-btn" data-value="beton" data-price="<?= $price_wall_beton ?>">Beton (+<?= $price_wall_beton ?>)</button>
</div>
<input type="hidden" name="ac_wall" id="ac_wall_input" value="">
<label>➖ Selectează lungime țevi:</label>
<div class="button-group" id="ac_pipe_length">
<button type="button" class="pipe-btn" data-value="3" data-price="0">3m (+0)</button>
<button type="button" class="pipe-btn" data-value="6" data-price="<?= $price_pipe * 3 ?>">6m (+<?= $price_pipe * 3 ?>)</button>
<button type="button" class="pipe-btn" data-value="9" data-price="<?= $price_pipe * 6 ?>">9m (+<?= $price_pipe * 6 ?>)</button>
</div>
<input type="hidden" name="ac_pipe_length" id="ac_pipe_input" value="">
<p style="color: red; font-weight: bold; margin-top: 5px;">⚠️ Orice informație eronată va fi facturată de echipa de montaj.</p>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
let basePrice = <?= $product_price ?>;
let priceElement = document.querySelector(".woocommerce-Price-amount bdi");
let addToCartButton = document.querySelector("button.single_add_to_cart_button");
function updatePrice() {
if (!priceElement) return;
let extraCost = 0;
let floorSelected = document.querySelector(".floor-btn.selected");
let wallSelected = document.querySelector(".wall-btn.selected");
let pipeSelected = document.querySelector(".pipe-btn.selected");
if (floorSelected) extraCost += parseFloat(floorSelected.dataset.price) || 0;
if (wallSelected) extraCost += parseFloat(wallSelected.dataset.price) || 0;
if (pipeSelected) extraCost += parseFloat(pipeSelected.dataset.price) || 0;
priceElement.innerHTML = (basePrice + extraCost).toFixed(2);
}
function handleSelection(buttons, hiddenInput) {
buttons.forEach(btn => {
btn.addEventListener("click", function() {
buttons.forEach(b => b.classList.remove("selected"));
this.classList.add("selected");
document.querySelector(hiddenInput).value = this.dataset.value;
updatePrice();
});
});
}
handleSelection(document.querySelectorAll(".floor-btn"), "#ac_floor_input");
handleSelection(document.querySelectorAll(".wall-btn"), "#ac_wall_input");
handleSelection(document.querySelectorAll(".pipe-btn"), "#ac_pipe_input");
addToCartButton.addEventListener("click", function(event) {
let floorSelected = document.querySelector(".floor-btn.selected");
let wallSelected = document.querySelector(".wall-btn.selected");
let pipeSelected = document.querySelector(".pipe-btn.selected");
if (!floorSelected || !wallSelected || !pipeSelected) {
event.preventDefault();
alert("⚠️ Te rugăm să selectezi toate opțiunile înainte de a adăuga produsul în coș!");
}
});
});
</script>
<style>
.button-group {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.button-group button {
background: #ddd;
border: 1px solid #ccc;
padding: 10px;
cursor: pointer;
border-radius: 5px;
font-weight: bold;
}
.button-group button.selected {
background: #0071a1;
color: white;
border-color: #005f8b;
}
</style>
<?php
}
// Adaugă opțiunile selectate în coș
add_filter('woocommerce_add_cart_item_data', 'add_ac_installation_to_cart', 10, 2);
function add_ac_installation_to_cart($cart_item_data, $product_id) {
if (!empty($_POST['ac_floor'])) {
$cart_item_data['ac_floor'] = sanitize_text_field($_POST['ac_floor']);
}
if (!empty($_POST['ac_wall'])) {
$cart_item_data['ac_wall'] = sanitize_text_field($_POST['ac_wall']);
}
if (!empty($_POST['ac_pipe_length'])) {
$cart_item_data['ac_pipe_length'] = sanitize_text_field($_POST['ac_pipe_length']);
}
return $cart_item_data;
}
// Afișează opțiunile în coș și checkout
add_filter('woocommerce_get_item_data', 'display_ac_installation_cart', 10, 2);
function display_ac_installation_cart($item_data, $cart_item) {
if (!empty($cart_item['ac_floor'])) {
$item_data[] = ['name' => 'Inaltime', 'value' => 'Etaj ' . $cart_item['ac_floor']];
}
if (!empty($cart_item['ac_wall'])) {
$tip_perete = $cart_item['ac_wall'] == 'none' ? 'Zid normal' : ucfirst($cart_item['ac_wall']);
$item_data[] = ['name' => 'Tip perete', 'value' => $tip_perete];
}
if (!empty($cart_item['ac_pipe_length'])) {
$item_data[] = ['name' => 'Lungime țevi', 'value' => $cart_item['ac_pipe_length'] . ' metri'];
}
return $item_data;
}
// Recalculare prețuri și adăugare costuri suplimentare la finalizare comandă
add_action('woocommerce_cart_calculate_fees', 'update_ac_installation_price');
function update_ac_installation_price() {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach (WC()->cart->get_cart() as $cart_item) {
$product_id = $cart_item['product_id'];
if (get_post_meta($product_id, '_enable_ac_installation', true) !== 'yes') {
continue;
}
$extra_cost = 0;
if (!empty($cart_item['ac_floor']) && $cart_item['ac_floor'] != '1') {
$extra_cost += get_post_meta($product_id, '_ac_price_floor_' . $cart_item['ac_floor'], true) ?: 0;
}
if (!empty($cart_item['ac_wall']) && $cart_item['ac_wall'] != 'none') {
$extra_cost += get_post_meta($product_id, '_ac_price_wall_' . $cart_item['ac_wall'], true) ?: 0;
}
if (!empty($cart_item['ac_pipe_length']) && $cart_item['ac_pipe_length'] > 3) {
$extra_cost += ($cart_item['ac_pipe_length'] - 3) * get_post_meta($product_id, '_ac_price_pipe', true);
}
if ($extra_cost > 0) {
WC()->cart->add_fee('🔧 Cost suplimentar montaj', $extra_cost, true, '');
}
}
}
// Salvează opțiunile în detaliile comenzii
add_action('woocommerce_checkout_create_order_line_item', 'save_ac_installation_order_items', 10, 4);
function save_ac_installation_order_items($item, $cart_item_key, $values, $order) {
if (!empty($values['ac_floor'])) {
$item->add_meta_data('Etaj', 'Etaj ' . $values['ac_floor'], true);
}
if (!empty($values['ac_wall'])) {
$tip_perete = $values['ac_wall'] == 'none' ? 'Zid normal' : ucfirst($values['ac_wall']);
$item->add_meta_data('Tip perete', $tip_perete, true);
}
if (!empty($values['ac_pipe_length'])) {
$item->add_meta_data('Lungime țevi', $values['ac_pipe_length'] . ' metri', true);
}
}
add_filter('woocommerce_package_rates', 'hide_shipping_when_ac_installation', 10, 2);
function hide_shipping_when_ac_installation($rates, $package) {
foreach (WC()->cart->get_cart() as $cart_item) {
$product_id = $cart_item['product_id'];
// Verifică dacă produsul are montaj activat
if (get_post_meta($product_id, '_enable_ac_installation', true) === 'yes') {
return []; // Elimină toate metodele de transport
}
}
return $rates;
}
Exemplu vizual
Opțiunile de montaj ar trebui să arate cam așa:
Avantajele implementării opțiunilor de montaj
Implementarea acestor opțiuni pe site-ul tău WooCommerce îți aduce numeroase avantaje, printre care:
- Simplificarea procesului de comandă: Clientul vede exact ce opțiuni sunt disponibile și ce costuri implică fiecare.
- Transparență în costuri: Costurile de montaj sunt afișate clar, astfel încât clientul știe exact ce plătește.
- Flexibilitate: Poți personaliza ușor opțiunile și prețurile în funcție de specificul fiecărui produs.
Verificări finale
După ce ai implementat codul, verifică următoarele:
- Asigură-te că opțiunile de montaj apar corect pe pagina produsului.
- Testează dacă prețul se recalculează automat și corect în funcție de opțiunile selectate.
- Verifică dacă detaliile selectate apar corect în coșul de cumpărături și pe pagina de finalizare a comenzii.
Concluzie
Implementarea opțiunilor personalizate de montaj pentru aer condiționat în WooCommerce este o soluție excelentă pentru automatizarea și simplificarea procesului de comandă. Astfel, oferi clienților o experiență mai bună, iar afacerea ta beneficiază de o gestionare mai eficientă a costurilor.
Dacă întâmpini probleme sau ai nevoie de ajustări suplimentare, lasă-mi un mesaj și îți voi oferi ajutorul necesar!