motorbike/app/Views/products/editbackup.php
andrymodeste fe80b9c4f8 fix: corrections et améliorations du 01-04-2026
## Recouvrement
- Liste triée par date décroissante
- Pop-up de confirmation anti-doublons
- Affichage avec permission "Voir" seule

## Mise à jour produit
- Correction erreur "Column count doesn't match" (triggers MySQL corrigés)
- Formulaire corrigé (action, catégorie, champs null)
- Catégorie et date d'arrivage correctement préremplis
- Historique affiche le nom de l'utilisateur qui modifie

## Espace commercial
- Colonne "Disponibilité" ajoutée avec statut "En attente de livraison"
- Bouton panier caché pour les motos commandées
- Surbrillance jaune pour les motos en attente

## Notifications
- Caissière reçoit les notifications via notifCommande
- notifSortieCaisse réservé à Direction/Admin

## Avances
- Colonne "N° Série" ajoutée dans toutes les listes
- Compteurs sur les boutons Incomplètes/Complètes

## Facture / BL
- Total, Remise, Total à payer affichés
- "Ariary" ne se répète plus
- Prix individuel par moto
- Impression automatique : 1 produit = Facture, 2+ = BL
- Remise multiple : colonne product changée en TEXT

## Rapports
- Filtre par date dans le rapport stock
- Filtre par commercial et mécanicien dans les performances
- Correction rapport stock (GROUP BY marque)
- Liens absolus (correction erreur 404)

## Sidebar
- Marge en haut supprimée (production)
- Padding en bas ajouté pour scroll complet

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:56:34 +02:00

347 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<?php
function stringToArray($data)
{
// Ensure the string is properly formatted for JSON decoding
$data = str_replace("'", '"', $data); // Convert single quotes to double quotes
return json_decode($data, true);
}
?>
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Gérer les
<small>Produits</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Accueil</a></li>
<li class="active">Produits</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-md-12 col-xs-12">
<div id="messages"></div>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<?php echo session()->getFlashdata('success'); ?>
</div>
<?php elseif (session()->getFlashdata('error')): ?>
<div class="alert alert-error alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<?php echo session()->getFlashdata('error'); ?>
</div>
<?php endif; ?>
<div class="box">
<div class="box-header">
<h3 class="box-title">Mise à jours Moto</h3>
</div>
<form role="form" action="<?php echo base_url('products/update/' . $product_data['id']); ?>" method="post" enctype="multipart/form-data">
<div class="box-body">
<!-- Image actuelle -->
<div class="form-group">
<label>Image: </label>
<img src="<?php echo base_url() . 'assets/images/product_image/' . $product_data['image'] ?>" width="150" height="150" class="img-circle">
</div>
<!-- Nouvelle Image -->
<div class="form-group">
<label for="product_image">Nouvelle Image</label>
<div class="kv-avatar">
<div class="file-loading">
<input id="product_image" name="product_image" type="file" accept="image/*">
</div>
</div>
</div>
<!-- Nom du produit -->
<div class="form-group">
<label for="product_name">Nom de Moto</label>
<input type="text" class="form-control" id="product_name" name="nom_de_produit" placeholder="Nom du moto" autocomplete="off" value="<?php echo $product_data['name']; ?>" />
</div>
<!-- Marque -->
<div class="form-group">
<label for="marque">Marque</label>
<select class="form-control" id="marque" name="marque">
<?php foreach ($marque as $k => $v): ?>
<option value="<?php echo $v['id'] ?>" <?php if ($product_data['marque'] == $v['id']) echo "selected"; ?>><?php echo $v['name'] ?></option>
<?php endforeach ?>
</select>
</div>
<!-- Numéro de moteur -->
<div class="form-group">
<label for="moteur">Numéro de moteur</label>
<input type="text" class="form-control" id="moteur" name="numero_de_moteur" placeholder="Numéro de série" autocomplete="off" value="<?php echo $product_data['numero_de_moteur']; ?>" />
</div>
<!-- Châssis -->
<div class="form-group">
<label for="chassis">Châssis</label>
<input type="text" class="form-control" id="chassis" name="chasis" placeholder="Chassis" autocomplete="off" value="<?php echo $product_data['chasis']; ?>" />
</div>
<!-- Prix d'achat -->
<div class="form-group">
<label for="price">Prix d'Achat</label>
<input type="number" min="0" class="form-control" id="price" name="price" placeholder="Prix d'achat" autocomplete="off" value="<?php echo $product_data['price']; ?>" />
</div>
<!-- Prix de vente -->
<div class="form-group">
<label for="price_vente">Prix de Vente</label>
<input type="number" min="0" class="form-control" id="price_vente" name="price_vente" placeholder="Prix de vente" autocomplete="off" value="<?php echo $product_data['prix_vente']; ?>" required />
</div>
<!-- Prix minimal -->
<div class="form-group">
<label for="price_min">Prix Minimal</label>
<input type="number" min="0" class="form-control" id="price_min" name="price_min" placeholder="Prix de vente minimal autorisé" autocomplete="off" value="<?= old('price_min') ?: $prix_minimal ?>" required />
<small id="price_min_error" style="color:red; display:none;">Le prix minimal ne peut pas être supérieur au prix de vente</small>
</div>
<!-- Date d'arrivage -->
<div class="form-group">
<label for="datea">Date d'arrivage</label>
<input type="date" class="form-control" id="datea" name="datea" autocomplete="off" value="<?php echo !empty($product_data['date_arivage']) ? date('Y-m-d', strtotime($product_data['date_arivage'])) : ''; ?>" />
</div>
<!-- Puissance -->
<div class="form-group">
<label for="puissance">Puissances</label>
<input type="text" class="form-control" id="puissance" name="puissance" placeholder="Puissances" autocomplete="off" value="<?php echo $product_data['puissance']; ?>" />
</div>
<!-- Clé -->
<div class="form-group">
<label for="cler">Clé</label>
<input type="text" class="form-control" id="cler" name="cler" placeholder="Type de clé" autocomplete="off" value="<?php echo $product_data['cler']; ?>" />
</div>
<!-- Description -->
<div class="form-group">
<label for="description">Description</label>
<textarea type="text" class="form-control" id="description" name="description" placeholder="Description" autocomplete="off"><?php echo $product_data['description']; ?></textarea>
</div>
<!-- Numéro de série -->
<div class="form-group">
<label for="sku">Numéro de série</label>
<input type="text" class="form-control" id="sku" name="numero_de_serie" placeholder="Numéro de série" autocomplete="off" value="<?php echo $product_data['sku']; ?>" />
</div>
<!-- Catégories -->
<div class="form-group">
<label for="categorie">Catégories</label>
<?php
$rawCats = $product_data['categorie_id'] ?? null;
$catIds = [];
if (is_array($rawCats)) {
$catIds = array_map('intval', $rawCats);
} elseif (is_string($rawCats)) {
$decoded = json_decode($rawCats, true);
if (is_array($decoded)) {
$catIds = array_map('intval', $decoded);
} else {
$catIds = array_filter(array_map('intval', explode(',', $rawCats)), fn($id) => $id > 0);
}
} elseif (is_int($rawCats) || ctype_digit((string)$rawCats)) {
$catIds = [(int) $rawCats];
}
?>
<select class="form-control select_group" id="categorie" name="categorie[]" multiple="multiple">
<?php foreach ($categorie as $k => $v): ?>
<option value="<?= $v['id']; ?>" <?= in_array((int)$v['id'], $catIds) ? 'selected="selected"' : '' ?>><?= esc($v['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<!-- Magasin -->
<div class="form-group">
<label for="store">Magasin</label>
<select class="form-control select_group" id="store" name="store">
<?php foreach ($stores as $k => $v): ?>
<option value="<?php echo $v['id'] ?>" <?php if ($product_data['store_id'] == $v['id']) echo "selected"; ?>><?php echo $v['name'] ?></option>
<?php endforeach ?>
</select>
</div>
<!-- Disponibilité -->
<div class="form-group">
<label for="availability">Disponibilité</label>
<select class="form-control" id="availability" name="availability">
<option value="1" <?php if ($product_data['availability'] == 1) echo "selected"; ?>>Oui</option>
<option value="0" <?php if ($product_data['availability'] == 0) echo "selected"; ?>>Non</option>
</select>
</div>
<!-- Etats -->
<div class="form-group">
<label for="etat">Etats</label>
<select class="form-control" id="etat" name="etats">
<option value="1" <?php if ($product_data['etats'] == 1) echo "selected"; ?>>Kit</option>
<option value="2" <?php if ($product_data['etats'] != 1) echo "selected"; ?>>Non Kit</option>
</select>
</div>
<div class="form-group" id="boxsuplementairekit"></div>
<!-- Pièce manquante -->
<div class="form-group">
<label for="info">Pièce Manquant</label>
<select class="form-control" id="info" name="info">
<option value="2" <?php if ($product_data['info'] != 1) echo "selected"; ?>>Non</option>
<option value="1" <?php if ($product_data['info'] == 1) echo "selected"; ?>>Oui</option>
</select>
</div>
<div class="form-group" id="boxsuplementaire"></div>
<!-- Type -->
<div class="form-group">
<label for="type">Type</label>
<select class="form-control" id="type" name="type">
<option value="A" <?php if ($product_data['type'] == "A") echo "selected"; ?>>A</option>
<option value="B" <?php if ($product_data['type'] == "B") echo "selected"; ?>>B</option>
<option value="C" <?php if ($product_data['type'] == "C") echo "selected"; ?>>C</option>
<option value="D" <?php if ($product_data['type'] == "D") echo "selected"; ?>>D</option>
</select>
</div>
</div> <!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-primary">Enregistrer</button>
<a href="<?php echo base_url('products/') ?>" class="btn btn-warning">Retour</a>
</div>
</form>
</div> <!-- /.box -->
</div> <!-- /.col-md-12 -->
</div> <!-- /.row -->
</section> <!-- /.content -->
</div> <!-- /.content-wrapper -->
<script type="text/javascript">
$(document).ready(function() {
// --- Initialisations ---
$(".select_group").select2();
$("#description").wysihtml5();
$("#mainProductNav").addClass('active');
$("#manageProductNav").addClass('active');
// --- Gestion image ---
var btnCust = '<button type="button" class="btn btn-secondary" title="Add picture tags" ' +
'onclick="alert(\'Call your custom code here.\')">' +
'<i class="glyphicon glyphicon-tag"></i>' +
'</button>';
$("#product_image").fileinput({
overwriteInitial: true,
maxFileSize: 1500,
showClose: false,
showCaption: false,
browseLabel: '',
removeLabel: '',
browseIcon: '<i class="glyphicon glyphicon-folder-open"></i>',
removeIcon: '<i class="glyphicon glyphicon-remove"></i>',
removeTitle: 'Cancel or reset changes',
elErrorContainer: '#kv-avatar-errors-1',
msgErrorClass: 'alert alert-block alert-danger',
layoutTemplates: { main2: '{preview} ' + btnCust + ' {remove} {browse}' },
allowedFileExtensions: ["jpg", "png", "gif", "jpeg", "webp"]
});
// --- Gestion champs supplémentaires ---
const info = document.getElementById('info');
const divSupp = document.getElementById('boxsuplementaire');
const etat = document.getElementById('etat');
const boxsuplementairekit = document.getElementById('boxsuplementairekit');
function afficherSupplements() {
if (info && info.value == 1) {
divSupp.innerHTML = `<label for="infoManque">Information</label>
<textarea type="text" class="form-control" id="infoManque" name="infoManque" placeholder="Description sur des trucs manquants" autocomplete="off"><?php echo $product_data['infoManque']; ?></textarea>`;
} else {
divSupp.innerHTML = '';
}
if (etat && etat.value == 1) {
boxsuplementairekit.innerHTML = `<label for="infoManquekit">Information sur le kit</label>
<textarea type="text" class="form-control" id="infoManquekit" name="infoManquekit" placeholder="Description sur le kit" autocomplete="off"><?php echo $product_data['infoManquekit']; ?></textarea>`;
} else {
boxsuplementairekit.innerHTML = '';
}
}
window.addEventListener('load', afficherSupplements);
if (info) info.addEventListener('change', afficherSupplements);
if (etat) etat.addEventListener('change', afficherSupplements);
// --- Vérification prix minimal < prix de vente ---
const priceMinInput = document.getElementById('price_min');
const priceVenteInput = document.getElementById('price_vente');
const priceMinError = document.getElementById('price_min_error');
function verifierPrix() {
let prixMin = parseFloat(priceMinInput.value.replace(/\s/g, '')) || 0;
let prixVente = parseFloat(priceVenteInput.value.replace(/\s/g, '')) || 0;
if (prixMin > prixVente) {
priceMinError.style.display = 'block';
} else {
priceMinError.style.display = 'none';
}
}
if (priceMinInput) priceMinInput.addEventListener('input', verifierPrix);
if (priceVenteInput) priceVenteInput.addEventListener('input', verifierPrix);
// --- Formatage automatique des prix (avec affichage initial) ---
['price', 'price_vente', 'price_min'].forEach(id => {
const input = document.getElementById(id);
if (input) {
// Si cest un input number, on le convertit en texte pour garder les espaces
if (input.type === "number") input.type = "text";
// 🟢 Formate dès la frappe
input.addEventListener('input', function(e) {
let val = e.target.value.replace(/\D/g, ''); // garde seulement les chiffres
e.target.value = val.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
});
// 🟢 Formate aussi dès le chargement de la page (valeurs de la base)
let initialVal = input.value.replace(/\D/g, '');
if (initialVal) {
input.value = initialVal.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
}
}
});
// --- Nettoyage des espaces avant soumission du formulaire ---
$("form").on('submit', function(e) {
let prixMin = parseFloat(priceMinInput.value.replace(/\s/g, '')) || 0;
let prixVente = parseFloat(priceVenteInput.value.replace(/\s/g, '')) || 0;
if (prixMin > prixVente) {
e.preventDefault();
alert("❌ Le prix minimal ne peut pas être supérieur au prix de vente !");
priceMinInput.focus();
return false;
}
// 🧹 Supprime les espaces avant envoi
['price', 'price_vente', 'price_min'].forEach(id => {
const input = document.getElementById(id);
if (input) {
input.value = input.value.replace(/\s/g, '');
}
});
});
});
</script>