fix
This commit is contained in:
@@ -328,29 +328,43 @@ func (d *Database) DeleteCommandItem(commandID, itemID int) error {
|
||||
var cmdStatus string
|
||||
d.GDB.Raw(`SELECT status FROM commandes WHERE id = ?`, commandID).Scan(&cmdStatus)
|
||||
|
||||
// Supprimer l'item
|
||||
if err := d.GDB.Exec(`DELETE FROM command_items WHERE id = ?`, itemID).Error; err != nil {
|
||||
noRestoreStatuses := []string{"cancelled", "approved", "livre"}
|
||||
restoreStock := result.ProductID != 0 && !slices.Contains(noRestoreStatuses, cmdStatus)
|
||||
|
||||
tx := d.GDB.Begin()
|
||||
if tx.Error != nil {
|
||||
return fmt.Errorf("erreur démarrage transaction: %w", tx.Error)
|
||||
}
|
||||
|
||||
if err := tx.Exec(`DELETE FROM command_items WHERE id = ?`, itemID).Error; err != nil {
|
||||
tx.Rollback()
|
||||
log.Printf("❌ Erreur DELETE command_items: %v", err)
|
||||
return fmt.Errorf("erreur suppression item: %w", err)
|
||||
}
|
||||
|
||||
// Recalculer le total de la commande
|
||||
if err := d.GDB.Exec(
|
||||
if err := tx.Exec(
|
||||
`UPDATE commandes SET total_prix = GREATEST(0, total_prix - ?) WHERE id = ?`,
|
||||
result.Prix*result.Quantite, commandID,
|
||||
).Error; err != nil {
|
||||
log.Printf("⚠️ [DeleteCommandItem] Erreur maj total commande: %v", err)
|
||||
tx.Rollback()
|
||||
log.Printf("❌ [DeleteCommandItem] Erreur maj total commande: %v", err)
|
||||
return fmt.Errorf("erreur mise à jour total commande: %w", err)
|
||||
}
|
||||
|
||||
// Restaurer le stock si la commande n'est pas déjà terminée
|
||||
noRestoreStatuses := []string{"cancelled", "approved", "livre"}
|
||||
if result.ProductID != 0 && !slices.Contains(noRestoreStatuses, cmdStatus) {
|
||||
if err := d.GDB.Exec(`UPDATE products SET stock = stock + ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`,
|
||||
result.Quantite, result.ProductID).Error; err != nil {
|
||||
log.Printf("⚠️ [DeleteCommandItem] Erreur restauration stock: %v", err)
|
||||
} else {
|
||||
log.Printf("✅ [DeleteCommandItem] Stock restauré: +%.3f pour produit %d", result.Quantite, result.ProductID)
|
||||
if restoreStock {
|
||||
if err := tx.Exec(
|
||||
`UPDATE products SET stock = stock + ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`,
|
||||
result.Quantite, result.ProductID,
|
||||
).Error; err != nil {
|
||||
tx.Rollback()
|
||||
log.Printf("❌ [DeleteCommandItem] Erreur restauration stock: %v", err)
|
||||
return fmt.Errorf("erreur restauration stock: %w", err)
|
||||
}
|
||||
log.Printf("✅ [DeleteCommandItem] Stock restauré: +%.3f pour produit %d", result.Quantite, result.ProductID)
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return fmt.Errorf("erreur commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -903,3 +903,13 @@ func (d *Database) ApproveDeliveryAtomicByStaff(commandID int, staffUsername str
|
||||
|
||||
return totalPoints, pointCategory, clientUsernameOut, nil
|
||||
}
|
||||
|
||||
func (d *Database) SetCommandCancelReason(commandID int, reason string) error {
|
||||
if len(reason) > 500 {
|
||||
reason = reason[:500]
|
||||
}
|
||||
return d.GDB.Exec(
|
||||
`UPDATE commandes SET cancel_reason = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`,
|
||||
reason, commandID,
|
||||
).Error
|
||||
}
|
||||
|
||||
@@ -263,6 +263,14 @@ func UpdateDeliveryStatus(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if req.Status == "cancelled" {
|
||||
cancelMsg := req.Notes
|
||||
if cancelMsg == "" {
|
||||
cancelMsg = "Annulé par le livreur"
|
||||
}
|
||||
database.SetCommandCancelReason(commandID, fmt.Sprintf("[Livreur: %s] %s", usernameStr, cancelMsg))
|
||||
}
|
||||
|
||||
// ✅ SI PASSAGE EN "EN_ROUTE" → CALCULER ET DÉFINIR L'ETA
|
||||
var etaMinutes int
|
||||
var etaMessage string
|
||||
|
||||
@@ -443,6 +443,11 @@ export default function OrdersScreen() {
|
||||
color: colors.textSecondary,
|
||||
fontSize: fontSize.xs,
|
||||
},
|
||||
livreurCancelBadge: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: spacing.xs,
|
||||
},
|
||||
proposedAddressBox: {
|
||||
backgroundColor: colors.bgPrimary,
|
||||
borderRadius: borderRadius.sm,
|
||||
@@ -662,8 +667,18 @@ export default function OrdersScreen() {
|
||||
{/* Raison annulation */}
|
||||
{isCancelled && !!item.cancel_reason && (
|
||||
<View style={styles.cancelReasonBox}>
|
||||
{item.cancel_reason.startsWith("[Livreur:") && (
|
||||
<View style={styles.livreurCancelBadge}>
|
||||
<Ionicons name="bicycle-outline" size={12} color={colors.danger} />
|
||||
<Text style={[styles.cancelReasonText, { color: colors.danger, fontWeight: "600" }]}>
|
||||
{" "}Annulé par le livreur
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text style={styles.cancelReasonText}>
|
||||
Raison : {item.cancel_reason}
|
||||
{item.cancel_reason.startsWith("[Livreur:")
|
||||
? item.cancel_reason.replace(/^\[Livreur: [^\]]+\] /, "")
|
||||
: item.cancel_reason}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"backgroundColor": "#000000"
|
||||
},
|
||||
"edgeToEdgeEnabled": true,
|
||||
"softwareKeyboardLayoutMode": "pan",
|
||||
"predictiveBackGestureEnabled": false,
|
||||
"package": "com.uberstup.clientpanel",
|
||||
"versionCode": 1,
|
||||
|
||||
@@ -65,7 +65,7 @@ export default function Modal({
|
||||
>
|
||||
<KeyboardAvoidingView
|
||||
style={{ flex: 1 }}
|
||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||
behavior="padding"
|
||||
>
|
||||
<View style={styles.overlay}>
|
||||
<Animated.View
|
||||
|
||||
@@ -60,7 +60,7 @@ export default function ChangePasswordScreen() {
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={[styles.container, { backgroundColor: colors.bgPrimary }]}
|
||||
behavior="height"
|
||||
behavior="padding"
|
||||
>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
|
||||
@@ -88,7 +88,7 @@ const LoginClient = () => {
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={[styles.container, { backgroundColor: colors.bgSecondary }]}
|
||||
behavior="height"
|
||||
behavior="padding"
|
||||
>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
|
||||
@@ -657,9 +657,12 @@ export default function CheckoutScreen() {
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={styles.container}
|
||||
behavior={Platform.OS === "ios" ? "padding" : undefined}
|
||||
behavior="padding"
|
||||
>
|
||||
<ScrollView contentContainerStyle={styles.content}>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.content}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
>
|
||||
{/* Résumé commande */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>
|
||||
|
||||
@@ -371,7 +371,7 @@ export default function ProfileScreen() {
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView style={styles.container} behavior={Platform.OS === "ios" ? "padding" : undefined}>
|
||||
<KeyboardAvoidingView style={styles.container} behavior="padding">
|
||||
<ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled">
|
||||
|
||||
{/* Header */}
|
||||
|
||||
Reference in New Issue
Block a user