kundenkarte/tabs/favoriteproducts.php

365 lines
12 KiB
PHP
Executable file

<?php
/* Copyright (C) 2026 Alles Watt lauft
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*/
/**
* \file tabs/favoriteproducts.php
* \brief Tab for favorite products on thirdparty card
*/
// Load Dolibarr environment
$res = 0;
if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php";
if (!$res && file_exists("../../../../main.inc.php")) $res = @include "../../../../main.inc.php";
if (!$res) die("Include of main fails");
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
dol_include_once('/kundenkarte/class/favoriteproduct.class.php');
// Load translation files
$langs->loadLangs(array('companies', 'products', 'orders', 'kundenkarte@kundenkarte'));
// Get parameters
$id = GETPOSTINT('id');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
// Security check
if (!$user->hasRight('kundenkarte', 'read')) {
accessforbidden();
}
// Initialize objects
$object = new Societe($db);
$form = new Form($db);
$favoriteProduct = new FavoriteProduct($db);
// Load thirdparty
if ($id > 0) {
$result = $object->fetch($id);
if ($result <= 0) {
dol_print_error($db, $object->error);
exit;
}
}
$permissiontoread = $user->hasRight('kundenkarte', 'read');
$permissiontoadd = $user->hasRight('kundenkarte', 'write');
$permissiontodelete = $user->hasRight('kundenkarte', 'delete');
/*
* Actions
*/
if ($action == 'add' && $permissiontoadd) {
$productid = GETPOSTINT('productid');
$qty = GETPOSTFLOAT('qty');
if ($productid > 0) {
$favoriteProduct->fk_soc = $id;
$favoriteProduct->fk_product = $productid;
$favoriteProduct->qty = $qty > 0 ? $qty : 1;
$favoriteProduct->active = 1;
$result = $favoriteProduct->create($user);
if ($result > 0) {
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
} else {
setEventMessages($favoriteProduct->error, $favoriteProduct->errors, 'errors');
}
}
header('Location: '.$_SERVER['PHP_SELF'].'?id='.$id);
exit;
}
if ($action == 'delete' && $permissiontodelete) {
$favid = GETPOSTINT('favid');
if ($favid > 0) {
$favoriteProduct->fetch($favid);
$result = $favoriteProduct->delete($user);
if ($result > 0) {
setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs');
} else {
setEventMessages($favoriteProduct->error, $favoriteProduct->errors, 'errors');
}
}
header('Location: '.$_SERVER['PHP_SELF'].'?id='.$id);
exit;
}
if ($action == 'updateqty' && $permissiontoadd) {
$favid = GETPOSTINT('favid');
$qty = GETPOST('qty', 'alpha');
if ($favid > 0 && is_numeric($qty)) {
$favoriteProduct->fetch($favid);
$favoriteProduct->qty = (float) $qty;
$result = $favoriteProduct->update($user);
}
header('Location: '.$_SERVER['PHP_SELF'].'?id='.$id);
exit;
}
if ($action == 'moveup' && $permissiontoadd) {
$favid = GETPOSTINT('favid');
if ($favid > 0) {
$favoriteProduct->moveUp($favid, $id);
}
header('Location: '.$_SERVER['PHP_SELF'].'?id='.$id);
exit;
}
if ($action == 'movedown' && $permissiontoadd) {
$favid = GETPOSTINT('favid');
if ($favid > 0) {
$favoriteProduct->moveDown($favid, $id);
}
header('Location: '.$_SERVER['PHP_SELF'].'?id='.$id);
exit;
}
if ($action == 'confirm_generateorder' && $confirm == 'yes' && $permissiontoadd) {
$selected = GETPOST('selected_products', 'array');
$quantities = GETPOST('quantities', 'array');
if (!empty($selected)) {
$result = $favoriteProduct->generateOrder($user, $id, $selected, $quantities);
if ($result > 0) {
setEventMessages($langs->trans('OrderGenerated', $result), null, 'mesgs');
header('Location: '.DOL_URL_ROOT.'/commande/card.php?id='.$result);
exit;
} else {
setEventMessages($favoriteProduct->error, $favoriteProduct->errors, 'errors');
}
} else {
setEventMessages($langs->trans('NoProductsSelected'), null, 'warnings');
}
}
/*
* View
*/
// Use Dolibarr standard button classes
$title = $langs->trans('FavoriteProducts').' - '.$object->name;
llxHeader('', $title, '', '', 0, 0, array('/kundenkarte/js/kundenkarte.js?v=1769963241'), array('/kundenkarte/css/kundenkarte.css?v=1769964233'));
// Fetch favorites
$favorites = $favoriteProduct->fetchAllBySociete($id);
// Prepare tabs
$head = societe_prepare_head($object);
print dol_get_fiche_head($head, 'favoriteproducts', $langs->trans("ThirdParty"), -1, 'company');
// Thirdparty card
$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
print '<div class="fichecenter">';
// Confirmation dialog for order generation
if ($action == 'generateorder') {
$formquestion = array();
print $form->formconfirm(
$_SERVER['PHP_SELF'].'?id='.$id,
$langs->trans('GenerateOrder'),
$langs->trans('ConfirmGenerateOrder'),
'confirm_generateorder',
$formquestion,
'yes',
1
);
}
print '<div class="underbanner clearboth"></div>';
// Add product form
if ($permissiontoadd) {
print '<div class="kundenkarte-favorites-add">';
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$id.'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add">';
print '<div class="product-search" style="flex:1;">';
print $form->select_produits(0, 'productid', '', 0, 0, 1, 2, '', 0, array(), $id, '1', 0, 'minwidth300', 0, '', -1, 1);
print '</div>';
print '<div style="display:flex;align-items:center;gap:10px;">';
print '<label for="qty">'.$langs->trans('Qty').':</label>';
print '<input type="number" name="qty" id="qty" value="1" step="any" class="flat" style="width:80px;">';
print '<button type="submit" class="button">'.$langs->trans('Add').'</button>';
print '</div>';
print '</form>';
print '</div>';
}
// List of favorites
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" id="form_favorites">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="confirm_generateorder">';
print '<input type="hidden" name="confirm" value="yes">';
if (is_array($favorites) && count($favorites) > 0) {
print '<table class="noborder centpercent kundenkarte-favorites-table">';
print '<thead>';
print '<tr class="liste_titre">';
print '<th class="center" style="width:30px;">';
print '<input type="checkbox" id="kundenkarte-select-all">';
print '</th>';
if ($permissiontoadd) {
print '<th class="center" style="width:60px;">'.$langs->trans('Position').'</th>';
}
print '<th>'.$langs->trans('Product').'</th>';
print '<th class="center" style="width:100px;">'.$langs->trans('DefaultQuantity').'</th>';
print '<th class="right" style="width:100px;">'.$langs->trans('UnitPriceHT').'</th>';
print '<th class="right" style="width:120px;">'.$langs->trans('Total').'</th>';
print '<th class="center" style="width:80px;">'.$langs->trans('Actions').'</th>';
print '</tr>';
print '</thead>';
print '<tbody>';
$totalHT = 0;
$totalItems = count($favorites);
$currentIndex = 0;
foreach ($favorites as $fav) {
$currentIndex++;
$lineTotal = $fav->qty * $fav->product_price;
$totalHT += $lineTotal;
// Format quantity: show as integer if whole number, otherwise 2 decimals
// Use '.' as decimal separator for HTML number input compatibility
$qtyDisplay = (floor($fav->qty) == $fav->qty) ? (int)$fav->qty : round($fav->qty, 2);
print '<tr class="oddeven" data-favorite-id="'.$fav->id.'">';
// Checkbox
print '<td class="center">';
print '<input type="checkbox" name="selected_products[]" value="'.$fav->id.'" checked>';
print '</td>';
// Position (up/down buttons)
if ($permissiontoadd) {
print '<td class="center nowraponall">';
if ($currentIndex > 1) {
print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$id.'&action=moveup&favid='.$fav->id.'&token='.newToken().'" class="reposition" title="'.$langs->trans('Up').'">';
print '<i class="fa fa-arrow-up"></i>';
print '</a> ';
} else {
print '<span class="opacitymedium"><i class="fa fa-arrow-up"></i></span> ';
}
if ($currentIndex < $totalItems) {
print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$id.'&action=movedown&favid='.$fav->id.'&token='.newToken().'" class="reposition" title="'.$langs->trans('Down').'">';
print '<i class="fa fa-arrow-down"></i>';
print '</a>';
} else {
print '<span class="opacitymedium"><i class="fa fa-arrow-down"></i></span>';
}
print '</td>';
}
// Product
print '<td>';
print '<a href="'.DOL_URL_ROOT.'/product/card.php?id='.$fav->fk_product.'">';
print img_object('', 'product', 'class="pictofixedwidth"');
print dol_escape_htmltag($fav->product_ref).' - '.dol_escape_htmltag($fav->product_label);
print '</a>';
print '</td>';
// Quantity
print '<td class="center nowraponall">';
print '<div style="display:inline-flex;align-items:stretch;gap:0;">';
print '<input type="text" name="quantities['.$fav->id.']" value="'.$qtyDisplay.'" class="flat kundenkarte-favorites-qty" style="width:60px;text-align:center;border-radius:4px 0 0 4px;border-right:none;" data-fav-id="'.$fav->id.'">';
print '<button type="button" class="button small kundenkarte-qty-save" data-fav-id="'.$fav->id.'" title="'.$langs->trans('Save').'" style="border-radius:0 4px 4px 0;padding:0 8px;margin:0;"><i class="fa fa-save"></i></button>';
print '</div>';
print '</td>';
// Unit price
print '<td class="right">'.price($fav->product_price).'</td>';
// Total
print '<td class="right">'.price($lineTotal).'</td>';
// Actions
print '<td class="center nowraponall">';
if ($permissiontodelete) {
print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$id.'&action=delete&favid='.$fav->id.'&token='.newToken().'" class="deletelink">';
print img_delete();
print '</a>';
}
print '</td>';
print '</tr>';
}
print '</tbody>';
print '<tfoot>';
print '<tr class="liste_total">';
$colspan = $permissiontoadd ? 5 : 4;
print '<td colspan="'.$colspan.'" class="right"><strong>'.$langs->trans('Total').'</strong></td>';
print '<td class="right"><strong>'.price($totalHT).'</strong></td>';
print '<td></td>';
print '</tr>';
print '</tfoot>';
print '</table>';
// Actions bar
print '<div class="kundenkarte-favorites-actions">';
print '<div>';
print '<input type="checkbox" id="kundenkarte-select-all-bottom"> ';
print '<label for="kundenkarte-select-all-bottom">'.$langs->trans('SelectAll').'</label>';
print '</div>';
if ($permissiontoadd) {
print '<button type="submit" class="butAction" id="btn-generate-order" data-text="'.$langs->trans('GenerateOrder').' (%d)" data-text-none="'.$langs->trans('GenerateOrder').'">';
print $langs->trans('GenerateOrder');
print '</button>';
}
print '</div>';
} else {
print '<div class="opacitymedium">'.$langs->trans('NoFavoriteProducts').'</div>';
}
print '</form>';
print '</div>';
print dol_get_fiche_end();
// JavaScript for checkbox handling
print '<script>
$(document).ready(function() {
function updateSelectAll() {
var total = $("input[name=\'selected_products[]\']").length;
var checked = $("input[name=\'selected_products[]\']:checked").length;
$("#kundenkarte-select-all, #kundenkarte-select-all-bottom").prop("checked", total > 0 && total == checked);
}
$("#kundenkarte-select-all, #kundenkarte-select-all-bottom").on("change", function() {
var isChecked = $(this).prop("checked");
$("input[name=\'selected_products[]\']").prop("checked", isChecked);
$("#kundenkarte-select-all, #kundenkarte-select-all-bottom").prop("checked", isChecked);
});
$("input[name=\'selected_products[]\']").on("change", function() {
updateSelectAll();
});
updateSelectAll();
});
</script>';
llxFooter();
$db->close();