Files
projet_gestion_commande/backend/gestion/db/db_settings.go
T
2026-06-12 13:33:07 +02:00

270 lines
8.1 KiB
Go

package db
import (
"encoding/json"
"fmt"
"gestion/models"
"strconv"
"gorm.io/gorm"
)
// DefaultDeliverySchedule retourne un planning de livraison par défaut (tous les jours, 9h-20h)
func DefaultDeliverySchedule() models.DeliverySchedule {
day := models.DaySchedule{Enabled: true, OpenTime: "09:00", CloseTime: "20:00"}
return models.DeliverySchedule{
Monday: day, Tuesday: day, Wednesday: day, Thursday: day,
Friday: day, Saturday: day, Sunday: day,
}
}
// CalcPointsFromTiers retourne le nombre de points correspondant au total selon les paliers
func CalcPointsFromTiers(total float64, tiers []models.PointsTier) int {
for _, t := range tiers {
if total >= t.Min && (t.Max == 0 || total <= t.Max) {
return t.Points
}
}
return 0
}
// DefaultSettings retourne les paramètres par défaut
func DefaultSettings() models.AppSettings {
return models.AppSettings{
PenaltiesEnabled: true,
ShowAmendeScore: true,
PenaltyTiers: []models.PenaltyTier{
{MinCancel: 0, Amount: 20},
{MinCancel: 1, Amount: 50},
{MinCancel: 2, Amount: 100},
{MinCancel: 3, Amount: 150},
},
PointsEnabled: true,
ReferralEnabled: true,
ReferralAmount: 0,
PointsPools: []models.PointsPool{
{
Key: "pool_0",
Name: "Pool 1",
Categories: []string{},
Tiers: []models.PointsTier{
{Min: 30, Max: 50, Points: 1},
{Min: 60, Max: 150, Points: 2},
{Min: 160, Max: 300, Points: 3},
{Min: 310, Max: 400, Points: 5},
{Min: 401, Max: 0, Points: 10},
},
},
{
Key: "pool_1",
Name: "Pool 2",
Categories: []string{},
Tiers: []models.PointsTier{
{Min: 30, Max: 100, Points: 1},
{Min: 110, Max: 200, Points: 2},
{Min: 210, Max: 0, Points: 3},
},
},
},
ShopName: "Milieu-Nantais",
ContactTelegram: "MLN44LA",
DeliveryMode: models.DeliveryModeConfig{
Mode: "single",
CategoryRoutes: []models.CategoryRoute{},
},
DeliverySchedule: DefaultDeliverySchedule(),
PostalZones: []models.PostalZone{
{Name: "Zone 30€", MinAmount: 30, Codes: []string{"44000", "44100", "44200", "44300"}},
{Name: "Zone 50€", MinAmount: 50, Codes: []string{
"44400", "44880", "44120", "44230", "44115",
"44980", "44470", "44240", "44700", "44800", "44340", "44620", "44830",
}},
{Name: "Zone 100€", MinAmount: 100, Codes: []string{
"44860", "44220", "44118", "44710", "44690", "44119",
}},
},
Telegram2FAEnabled: false,
}
}
// GetSettings récupère les paramètres depuis la DB
func (d *Database) GetSettings() (models.AppSettings, error) {
settings := DefaultSettings()
var rows []struct {
Key string `gorm:"column:key"`
Value string `gorm:"column:value"`
}
if err := d.GDB.Table("app_settings").Select("key, value").Scan(&rows).Error; err != nil {
return settings, fmt.Errorf("erreur lecture settings: %w", err)
}
for _, row := range rows {
switch row.Key {
case "penalties_enabled":
settings.PenaltiesEnabled = row.Value == "true"
case "show_amende_score":
settings.ShowAmendeScore = row.Value == "true"
case "points_enabled":
settings.PointsEnabled = row.Value == "true"
case "points_pools":
var pools []models.PointsPool
if err := json.Unmarshal([]byte(row.Value), &pools); err == nil {
settings.PointsPools = pools
}
case "points_reward":
var reward models.PointsReward
if err := json.Unmarshal([]byte(row.Value), &reward); err == nil {
settings.PointsReward = &reward
}
case "referral_enabled":
settings.ReferralEnabled = row.Value == "true"
case "referral_amount":
if v, err := strconv.ParseFloat(row.Value, 64); err == nil {
settings.ReferralAmount = v
}
case "crypto_payment_enabled":
settings.CryptoPaymentEnabled = row.Value == "true"
case "crypto_only":
settings.CryptoOnly = row.Value == "true"
case "nowpayments_api_key":
settings.NowPaymentsAPIKey = row.Value
case "nowpayments_ipn_secret":
settings.NowPaymentsIPNSecret = row.Value
case "nowpayments_currencies":
var currencies []string
if err := json.Unmarshal([]byte(row.Value), &currencies); err == nil {
settings.NowPaymentsCurrencies = currencies
}
case "delivery_schedule":
var sched models.DeliverySchedule
if err := json.Unmarshal([]byte(row.Value), &sched); err == nil {
settings.DeliverySchedule = sched
}
case "postal_zones":
var zones []models.PostalZone
if err := json.Unmarshal([]byte(row.Value), &zones); err == nil {
settings.PostalZones = zones
}
case "contact_telegram":
settings.ContactTelegram = row.Value
case "telegram_bot_token":
settings.TelegramBotToken = row.Value
case "telegram_bot_username":
settings.TelegramBotUsername = row.Value
case "telegram_notifications_enabled":
settings.TelegramNotificationsEnabled = row.Value == "true"
case "delivery_mode":
var mode models.DeliveryModeConfig
if err := json.Unmarshal([]byte(row.Value), &mode); err == nil {
settings.DeliveryMode = mode
}
case "telegram_2fa_enabled":
settings.Telegram2FAEnabled = row.Value == "true"
case "shop_name":
settings.ShopName = row.Value
}
}
return settings, nil
}
// UpdateSettings sauvegarde les paramètres dans la DB
func (d *Database) UpdateSettings(s models.AppSettings) error {
boolStr := func(b bool) string {
if b {
return "true"
}
return "false"
}
if s.PointsPools == nil {
s.PointsPools = []models.PointsPool{}
}
for i := range s.PointsPools {
if s.PointsPools[i].Categories == nil {
s.PointsPools[i].Categories = []string{}
}
if s.PointsPools[i].Tiers == nil {
s.PointsPools[i].Tiers = []models.PointsTier{}
}
}
poolsJSON, err := json.Marshal(s.PointsPools)
if err != nil {
return fmt.Errorf("erreur sérialisation pools: %w", err)
}
rewardJSON, err := json.Marshal(s.PointsReward)
if err != nil {
return fmt.Errorf("erreur sérialisation points_reward: %w", err)
}
if s.NowPaymentsCurrencies == nil {
s.NowPaymentsCurrencies = []string{}
}
currenciesJSON, err := json.Marshal(s.NowPaymentsCurrencies)
if err != nil {
return fmt.Errorf("erreur sérialisation nowpayments_currencies: %w", err)
}
schedJSON, err := json.Marshal(s.DeliverySchedule)
if err != nil {
return fmt.Errorf("erreur sérialisation delivery_schedule: %w", err)
}
if s.PostalZones == nil {
s.PostalZones = []models.PostalZone{}
}
zonesJSON, err := json.Marshal(s.PostalZones)
if err != nil {
return fmt.Errorf("erreur sérialisation postal_zones: %w", err)
}
if s.DeliveryMode.CategoryRoutes == nil {
s.DeliveryMode.CategoryRoutes = []models.CategoryRoute{}
}
deliveryModeJSON, err := json.Marshal(s.DeliveryMode)
if err != nil {
return fmt.Errorf("erreur sérialisation delivery_mode: %w", err)
}
if s.ContactTelegram == "" {
s.ContactTelegram = "MLN44LA"
}
pairs := [][2]string{
{"penalties_enabled", boolStr(s.PenaltiesEnabled)},
{"show_amende_score", boolStr(s.ShowAmendeScore)},
{"points_enabled", boolStr(s.PointsEnabled)},
{"points_pools", string(poolsJSON)},
{"points_reward", string(rewardJSON)},
{"referral_enabled", boolStr(s.ReferralEnabled)},
{"referral_amount", strconv.FormatFloat(s.ReferralAmount, 'f', 2, 64)},
{"crypto_payment_enabled", boolStr(s.CryptoPaymentEnabled)},
{"crypto_only", boolStr(s.CryptoOnly)},
{"nowpayments_api_key", s.NowPaymentsAPIKey},
{"nowpayments_ipn_secret", s.NowPaymentsIPNSecret},
{"nowpayments_currencies", string(currenciesJSON)},
{"delivery_schedule", string(schedJSON)},
{"postal_zones", string(zonesJSON)},
{"telegram_bot_token", s.TelegramBotToken},
{"telegram_bot_username", s.TelegramBotUsername},
{"telegram_notifications_enabled", boolStr(s.TelegramNotificationsEnabled)},
{"telegram_2fa_enabled", boolStr(s.Telegram2FAEnabled)},
{"delivery_mode", string(deliveryModeJSON)},
{"shop_name", s.ShopName},
{"contact_telegram", s.ContactTelegram},
}
upsert := `INSERT INTO app_settings (key, value) VALUES (?, ?)
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value`
return d.GDB.Transaction(func(tx *gorm.DB) error {
for _, p := range pairs {
if err := tx.Exec(upsert, p[0], p[1]).Error; err != nil {
return fmt.Errorf("erreur upsert %s: %w", p[0], err)
}
}
return nil
})
}