Logo Pastebin.fr
Pastebin

Retrouvez, créez et partagez vos snippets en temps réel.

v 2 walid


function Show-StarTimeline {
    param($selectedItem)
        if ($list.SelectedItems.Count -eq 0) {
    [System.Windows.Forms.MessageBox]::Show("Veuillez sélectionner un dossier dans la liste.")
    return
}
    # Récupération de la première ligne sélectionnée
    $sel = $list.SelectedItems[0] 

    try {
        $dEffet = [datetime]::ParseExact($sel.SubItems[3].Text.Trim(), "dd/MM/yyyy", $null)
        $dCont  = [datetime]::ParseExact($sel.SubItems[4].Text.Trim(), "dd/MM/yyyy", $null)
        $dSusp  = [datetime]::ParseExact($sel.SubItems[5].Text.Trim(), "dd/MM/yyyy", $null)
        $dResil = [datetime]::ParseExact($sel.SubItems[6].Text.Trim(), "dd/MM/yyyy", $null)
        $clientNom = $sel.SubItems[1].Text
        $policeNum = $sel.Text
    } catch { 
        [System.Windows.Forms.MessageBox]::Show("Erreur : Les dates dans le tableau doivent être au format dd/MM/yyyy (ex: 20/01/2026)")
        return 
    }

    # Étape dossier contentieux : toujours à Résiliation + 20 jours
    $dContentieux = $dResil.AddDays(20)

    # Création des étapes
    $etapes = @(
        @{Name="EFFET"; Date=$dEffet; Color=[System.Drawing.Color]::Cyan; Pos="Up"},
        @{Name="MISE EN DEMEURE"; Date=$dCont; Color=[System.Drawing.Color]::Lime; Pos="Down"},
        @{Name="SUSPENSION"; Date=$dSusp; Color=[System.Drawing.Color]::Yellow; Pos="Up"},
        @{Name="RÉSILIATION"; Date=$dResil; Color=[System.Drawing.Color]::OrangeRed; Pos="Down"},
        @{Name="DOSSIER CONTENTIEUX"; Date=$dContentieux; Color=[System.Drawing.Color]::Crimson; Pos="Up"}
    )

    # Configuration fenêtre
    $timelineForm = New-Object System.Windows.Forms.Form
    $timelineForm.Text = "STAR - ANALYSE TEMPORELLE"
    $timelineForm.Size = New-Object System.Drawing.Size(1000, 500)
    $timelineForm.StartPosition = "CenterParent"
    $timelineForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
    $timelineForm.MaximizeBox = $false
    $timelineForm.BackColor = [System.Drawing.Color]::FromArgb(40,40,60)
    $timelineForm.Opacity = 0.95

    $script:animProgress = 0.0
    $script:glowStep = 0.0
    $script:glowDirection = 1
    $timer = New-Object System.Windows.Forms.Timer
    $timer.Interval = 15

    $picTimeline = New-Object System.Windows.Forms.PictureBox
    $picTimeline.Dock = "Fill"
    $timelineForm.Controls.Add($picTimeline)

    $picTimeline.Add_Paint({
        param($sender,$e)
        $g = $e.Graphics
        $g.SmoothingMode = "AntiAlias"
        $g.TextRenderingHint = "ClearTypeGridFit"

        $today = (Get-Date).Date
        # ===== AJOUT COMPLETION CYCLE =====
[double]$completion = 0.0
[string]$completionLabel = ""
$phaseColor = [System.Drawing.Color]::Cyan

if ($today -le $dResil.Date) {
    # Phase 1 : Effet -> Résiliation
    $totalPhase = ($dResil - $dEffet).TotalDays
    if ($totalPhase -le 0) { $totalPhase = 1 }
    $completion = (($today - $dEffet).TotalDays / $totalPhase) * 100
    $completionLabel = "CYCLE CONTRAT"
    $phaseColor = [System.Drawing.Color]::Cyan
}
elseif ($today -le $dContentieux.Date) {
    # Phase 2 : J+1 Résiliation -> Contentieux
    $totalPhase = ($dContentieux - $dResil.AddDays(1)).TotalDays
    if ($totalPhase -le 0) { $totalPhase = 1 }
    $completion = (($today - $dResil.AddDays(1)).TotalDays / $totalPhase) * 100
    $completionLabel = "DOSSIER CLOS"
    $phaseColor = [System.Drawing.Color]::Crimson
}
else {
    $completion = 100
    $completionLabel = "TERMINÉE"
    $phaseColor = [System.Drawing.Color]::OrangeRed
}

if ($completion -lt 0) { $completion = 0 }
if ($completion -gt 100) { $completion = 100 }

$completionTxt = "{0:N2} %" -f $completion
# ================================

        [float]$startX = 100
        [float]$endX   = $sender.Width - 100
        [float]$yBase  = $sender.Height / 2 + 20

        # Tri de la dernière étape pour calcul durée totale
        $lastDate = ($etapes | Sort-Object Date | Select-Object -Last 1).Date
        [double]$totalJours = ($lastDate - $dEffet).TotalDays
        if ($totalJours -le 0) { $totalJours = 1 }

        # Prochaine étape future
        $prochaine = $null
        foreach($et in ($etapes | Sort-Object Date)) {
            if ($et.Date.Date -ge $today) { $prochaine = $et; break }
        }

        # Animation progression
        $easedT = 1 - [Math]::Pow(1 - $script:animProgress, 3)
        [float]$ratioTarget = ($today - $dEffet).TotalDays / $totalJours
        if ($ratioTarget -lt 0) { $ratioTarget = 0 }
        if ($ratioTarget -gt 1) { $ratioTarget = 1 }
        [float]$currentX = $startX + (($ratioTarget * $easedT) * ($endX - $startX))

        # Ligne dégradée
        $rectLine = [System.Drawing.RectangleF]::FromLTRB($startX, $yBase-1, ($currentX + 1), $yBase+1)
        if ($rectLine.Width -gt 1) {
            $brushL = New-Object System.Drawing.Drawing2D.LinearGradientBrush($rectLine, [System.Drawing.Color]::Cyan, [System.Drawing.Color]::OrangeRed, 0.0)
            $g.DrawLine((New-Object System.Drawing.Pen($brushL, 2)), $startX, $yBase, $currentX, $yBase)
        }
        $g.DrawLine((New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(40, 40, 50), 2)), $currentX, $yBase, $endX, $yBase)

        # Dessin des étapes
        foreach ($et in $etapes) {
            [float]$ratioX = ($et.Date - $dEffet).TotalDays / $totalJours
            [float]$posX   = $startX + ($ratioX * ($endX - $startX))
            $isPassed = $today -gt $et.Date.Date

            $alphaBox = if ($isPassed) { 30 } else { 180 }
            $accent = if ($isPassed) { [System.Drawing.Color]::FromArgb(80, 120, 120, 120) } else { $et.Color }
            $textColor = if ($isPassed) { [System.Drawing.Color]::Gray } else { [System.Drawing.Color]::White }

            $boxW = 135; $boxH = 50
            $boxY = if ($et.Pos -eq "Up") { $yBase - 110 } else { $yBase + 60 }

            # Glassmorphism
            $g.FillRectangle((New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb($alphaBox, 10, 10, 20))), ($posX - $boxW/2), $boxY, $boxW, $boxH)
            $g.DrawRectangle((New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(40, 255, 255, 255))), ($posX - $boxW/2), $boxY, $boxW, $boxH)
            
            $barY = if ($et.Pos -eq "Up") { ($boxY + $boxH - 4) } else { $boxY }
            $g.FillRectangle((New-Object System.Drawing.SolidBrush($accent)), ($posX - $boxW/2), $barY, $boxW, 4)

            $g.DrawString($et.Name, (New-Object System.Drawing.Font("Segoe UI", 8, [System.Drawing.FontStyle]::Bold)), (New-Object System.Drawing.SolidBrush($textColor)), ($posX - $boxW/2 + 8), ($boxY + 10))
            $g.DrawString($et.Date.ToString("dd MMM yyyy"), (New-Object System.Drawing.Font("Consolas", 8)), (New-Object System.Drawing.SolidBrush($accent)), ($posX - $boxW/2 + 8), ($boxY + 28))

            $lineYEnd = if ($et.Pos -eq "Up") { $boxY + $boxH } else { $boxY }
            $g.DrawLine((New-Object System.Drawing.Pen($accent, 1)), $posX, $yBase, $posX, $lineYEnd)
            $g.FillEllipse((New-Object System.Drawing.SolidBrush($accent)), ($posX - 6), ($yBase - 6), 12, 12)
        }

        # Triangle et point "aujourd'hui"
        $pSize = 10 + ($script:glowStep * 20)
        $pAlpha = [int](180 * (1.0 - $script:glowStep))
        $g.FillEllipse((New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb($pAlpha, [System.Drawing.Color]::Lime))), ($currentX - $pSize/2), ($yBase - $pSize/2), $pSize, $pSize)
        $g.FillEllipse([System.Drawing.Brushes]::White, ($currentX - 4), ($yBase - 4), 8, 8)

        $triPts = @(
            (New-Object System.Drawing.PointF($currentX, ($yBase - 12))),
            (New-Object System.Drawing.PointF(($currentX - 6), ($yBase - 22))),
            (New-Object System.Drawing.PointF(($currentX + 6), ($yBase - 22)))
        )
        $g.FillPolygon([System.Drawing.Brushes]::White, $triPts)

        # Header
        $g.DrawString("$($clientNom.ToUpper()) | $policeNum", (New-Object System.Drawing.Font("Segoe UI Light", 16)), [System.Drawing.Brushes]::White, 40, 20)

        if ($prochaine) {
            $diff = ($prochaine.Date.Date - $today).Days
            $txt = if ($diff -eq 0) { "ÉCHÉANCE : AUJOURD'HUI ($($prochaine.Name))" } else { "$($prochaine.Name) DANS $diff JOURS" }
            $g.DrawString($txt, (New-Object System.Drawing.Font("Segoe UI", 14, [System.Drawing.FontStyle]::Bold)), (New-Object System.Drawing.SolidBrush($prochaine.Color)), 40, 55)
        } else {
            $g.DrawString("DOSSIER RÉSILLIÉ / CLÔTURÉ", (New-Object System.Drawing.Font("Segoe UI", 16, [System.Drawing.FontStyle]::Bold)), [System.Drawing.Brushes]::OrangeRed, 40, 55)
            $g.DrawString("PROCÉDURE DE RECOUVREMENT TERMINÉE", (New-Object System.Drawing.Font("Segoe UI", 9)), [System.Drawing.Brushes]::Crimson, 43, 85)
        }
        # ===== AJOUT HUD COMPLETION =====
        $hudSize = 140
$hudX = $sender.Width - $hudSize - 850
$hudY = $sender.Height - $hudSize - 10


# Fond glass
$g.FillEllipse(
    (New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(40,10,10,20))),
    $hudX, $hudY, $hudSize, $hudSize
)

# Cercle de fond
$g.DrawEllipse(
    (New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(40,255,255,255),6)),
    $hudX + 10, $hudY + 10, $hudSize - 20, $hudSize - 20
)

# Arc de progression
$g.DrawArc(
    (New-Object System.Drawing.Pen($phaseColor,6)),
    $hudX + 10, $hudY + 10, $hudSize - 20, $hudSize - 20,
    -90, ($completion / 100) * 360
)

# Texte %
$g.DrawString(
    $completionTxt,
    (New-Object System.Drawing.Font("Segoe UI",14,[System.Drawing.FontStyle]::Bold)),
    [System.Drawing.Brushes]::White,
    $hudX + 38, $hudY + 55
)

# Libellé phase
$g.DrawString(
    $completionLabel,
    (New-Object System.Drawing.Font("Segoe UI",8)),
    (New-Object System.Drawing.SolidBrush($phaseColor)),
    $hudX + 28, $hudY + 85
)
# ================================
        #footer
        #$g.DrawString("CLIENT : $($clientNom.ToUpper()) | POLICE : $policeNum", (New-Object System.Drawing.Font("Segoe UI", 20)), [System.Drawing.Brushes]::Gray, 130, $sender.Height - 60)
    })

    $timer.Add_Tick({
        if ($script:animProgress -lt 1.0) { $script:animProgress += 0.02 }
        $script:glowStep += (0.05 * $script:glowDirection)
        if ($script:glowStep -ge 1.0 -or $script:glowStep -le 0.0) { $script:glowDirection *= -1 }
        $picTimeline.Invalidate()
    })

    $timelineForm.Add_Load({ $timer.Start() })
    $timelineForm.ShowDialog()
    $timer.Dispose()
}

###########################################################


function Get-Client {
    param(
        [string]$Contrat,
        [string]$CsvFile
    )

    if (Test-Path $CsvFile) {
        $client = Import-Csv $CsvFile | Where-Object { $_.Police -eq $Contrat }
        if ($client) { return $client[0] } else { return $null }
    } else {
        return $null
    }
}

function Get-ClientsByYear {
    param(
        [int]$Year,
        [string]$RootPath
    )

    $csvFile = Join-Path $RootPath "detail\detail$Year.csv"
    if (Test-Path $csvFile) {
        return Import-Csv $csvFile
    } else {
        return @()
    }
}

function Save-Client {
    param(
        [pscustomobject]$Client,
        [string]$CsvFile
    )

    # Crée le fichier si inexistant
    if (-not (Test-Path $CsvFile)) {
        $Client | Export-Csv -Path $CsvFile -NoTypeInformation
        return
    }

    # Lire le CSV existant
    $clients = Import-Csv -Path $CsvFile

    # Remplacer si Police existe déjà
    $clients = $clients | Where-Object { $_.Police -ne $Client.Police }

    # Ajouter le nouveau client
    $clients += $Client

    # Sauvegarder
    $clients | Export-Csv -Path $CsvFile -NoTypeInformation
}

# =========================
# FONCTION AJOUT CHAMPS FORM
# =========================

function Add-Field {
    param(
        [System.Windows.Forms.Panel]$Panel,
        [ref]$Y,
        [string]$Label,
        [string]$Type = 'TextBox',
        $Value = $null,
        [int]$Height = 28,
        [bool]$Multiline = $false,
        [bool]$ReadOnly = $false,
        [string[]]$Items = @()
    )

    # Label
    $lbl = New-Object System.Windows.Forms.Label
    $lbl.Text = $Label
    $lbl.Location = New-Object System.Drawing.Point(20, $Y.Value)
    $lbl.AutoSize = $true
    $Panel.Controls.Add($lbl)

    # Contrôle
    switch ($Type) {
        'TextBox' {
            $ctrl = New-Object System.Windows.Forms.TextBox
            $ctrl.Multiline = $Multiline
            $ctrl.ReadOnly  = $ReadOnly
            $ctrl.Text      = $Value
            $ctrl.Height    = if ($Multiline) { [Math]::Max($Height, 60) } else { $Height }
            $ctrl.Width     = 620
        }
        'ComboBox' {
            $ctrl = New-Object System.Windows.Forms.ComboBox
            $ctrl.DropDownStyle = 'DropDownList'
            if ($Items) { $ctrl.Items.AddRange($Items) }
            if ($Value) { $ctrl.SelectedItem = $Value }
            $ctrl.Size = New-Object System.Drawing.Size(620,28)
        }
        'DateTimePicker' {
            $ctrl = New-Object System.Windows.Forms.DateTimePicker
            try { if ($Value) { $ctrl.Value = [datetime]$Value } } catch {}
            $ctrl.Size = New-Object System.Drawing.Size(620,28)
        }
        'NumericUpDown' {
            $ctrl = New-Object System.Windows.Forms.NumericUpDown
            $ctrl.Maximum = 1000
            $ctrl.Minimum = 0
            $ctrl.Value   = if ($Value) { [decimal]$Value } else { 0 }
            $ctrl.Size = New-Object System.Drawing.Size(620,28)
        }
        default { throw "Type inconnu: $Type" }
    }

    $ctrl.Location = New-Object System.Drawing.Point(20, ($Y.Value + 20))
    $Panel.Controls.Add($ctrl)
    $Y.Value += $ctrl.Height + 25
    return $ctrl
}

# =========================
# FONCTION FORM DETAIL CLIENT
# =========================

function Show-ClientDetailForm {
    param(
        [System.Windows.Forms.ListView]$List,
        [string]$RootPath
    )

    if ($List.SelectedItems.Count -eq 0) { return $false }

    $policeId = $List.SelectedItems[0].Text
    $year = ($policeId -replace '\D','')

    $detailFolder = Join-Path $RootPath "detail"
    if (-not (Test-Path $detailFolder)) { New-Item -ItemType Directory $detailFolder | Out-Null }

    $csvFile = Join-Path $detailFolder "detail$year.csv"
    $client  = Get-Client -Contrat $policeId -CsvFile $csvFile

    # ========= FORM =========
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "Fiche Client – $($List.SelectedItems[0].SubItems[1].Text)"
    $form.Size = '800,600'
    $form.StartPosition = 'CenterParent'
    $form.FormBorderStyle = 'FixedDialog'
    $form.MaximizeBox = $false
    $form.Font = New-Object System.Drawing.Font("Segoe UI",10)

    $tabs = New-Object System.Windows.Forms.TabControl
    $tabs.Dock = 'Top'
    $tabs.Height = 500
    $form.Controls.Add($tabs)

    function New-Tab($name) {
        $tab = New-Object System.Windows.Forms.TabPage
        $tab.Text = $name
        $panel = New-Object System.Windows.Forms.Panel
        $panel.Dock = 'Fill'
        $panel.AutoScroll = $true
        $tab.Controls.Add($panel)
        $tabs.TabPages.Add($tab)
        return $panel
    }

    # ========= ASSURÉ =========
    $y = 15
    $pAssure = New-Tab "Assuré"
    $tbNom        = Add-Field $pAssure ([ref]$y) "Nom" 'TextBox' $($List.SelectedItems[0].SubItems[1].Text) 28 $false $true
    $cbCategorie  = Add-Field $pAssure ([ref]$y) "Catégorie" 'ComboBox' $client.Categorie $null $false $false @("Personne Physique","Personne Morale")
    $cbGenre      = Add-Field $pAssure ([ref]$y) "Genre" 'ComboBox' $client.Genre $null $false $false @("Homme","Femme")
    $dpDateNaiss  = Add-Field $pAssure ([ref]$y) "Date de naissance" 'DateTimePicker' $client.DateNaissance
    $tbCin        = Add-Field $pAssure ([ref]$y) "CIN / MF" 'TextBox' $client.CIN
    $tbPro        = Add-Field $pAssure ([ref]$y) "Situation professionnelle" 'TextBox' $client.SituationPro
    $cbFamilial   = Add-Field $pAssure ([ref]$y) "Situation familiale" 'ComboBox' $client.SituationFamilial $null $false $false @("Marié","Divorcé","Célibataire")
    $nudEnfant    = Add-Field $pAssure ([ref]$y) "Nombre d'enfants" 'NumericUpDown' $client.NbEnfants
    $tbAdresse    = Add-Field $pAssure ([ref]$y) "Adresse" 'TextBox' $client.Adresse 60 $true

    # ========= CONTRAT =========
    $y = 15
    $pContrat = New-Tab "Contrat"
    $tbPolice     = Add-Field $pContrat ([ref]$y) "Police" 'TextBox' $policeId 28 $false $true
    $dpDateOrigine= Add-Field $pContrat ([ref]$y) "Date d'origine" 'DateTimePicker' $client.DateOrigine

    # ========= VEHICULE =========
    $y = 15
    $pVehicule = New-Tab "Véhicule"
    $tbType      = Add-Field $pVehicule ([ref]$y) "Type" 'TextBox' $client.Type
    $tbImmat     = Add-Field $pVehicule ([ref]$y) "Immatriculation" 'TextBox' $client.Immatriculation
    $dpMC        = Add-Field $pVehicule ([ref]$y) "1.M.C" 'DateTimePicker' $client.DateMC
    $tbValeur    = Add-Field $pVehicule ([ref]$y) "Valeur vénale" 'TextBox' $client.ValeurVenale

    # ========= CONTACT =========
    $y = 15
    $pContact = New-Tab "Contact"
    $tbTel1     = Add-Field $pContact ([ref]$y) "Téléphone 1" 'TextBox' $client.Tel1
    $tbTel2     = Add-Field $pContact ([ref]$y) "Téléphone 2" 'TextBox' $client.Tel2
    $tbEmail    = Add-Field $pContact ([ref]$y) "Email" 'TextBox' $client.Email

    # ========= NOTES =========
    $y = 15
    $pNotes = New-Tab "Notes"
    $tbNotes = Add-Field $pNotes ([ref]$y) "Observations" 'TextBox' $client.Notes 90 $true

    # ========= BOUTONS =========
    $btnSave = New-Object System.Windows.Forms.Button
    $btnSave.Text = "Enregistrer"
    $btnSave.Location = '600,520'
    $btnSave.Size = '150,35'
    $form.Controls.Add($btnSave)

    $btnClose = New-Object System.Windows.Forms.Button
    $btnClose.Text = "Fermer"
    $btnClose.Location = '430,520'
    $btnClose.Size = '150,35'
    $form.Controls.Add($btnClose)

    # ========= LOGIQUE =========
    $updateControls = {
        $cbGenre.Enabled  = ($cbCategorie.SelectedItem -eq "Personne Physique")
        $nudEnfant.Enabled = ($cbFamilial.SelectedItem -in @("Marié","Divorcé"))
    }

    $updateControls.Invoke()
    $cbCategorie.Add_SelectedIndexChanged($updateControls)
    $cbFamilial.Add_SelectedIndexChanged($updateControls)

    # ======= EVENTS =======
    $btnSave.Add_Click({
        if ([string]::IsNullOrWhiteSpace($tbPolice.Text)) { 
            [System.Windows.Forms.MessageBox]::Show("Police obligatoire","Erreur",'OK','Error')
            return
        }

        # Création de l'objet client
        $new = [pscustomobject]@{
            Nom = $tbNom.Text
            Categorie = $cbCategorie.SelectedItem
            Genre = $cbGenre.SelectedItem
            DateNaissance = $dpDateNaiss.Value.ToShortDateString()
            CIN = $tbCin.Text
            SituationPro = $tbPro.Text
            SituationFamilial = $cbFamilial.SelectedItem
            NbEnfants = [int]$nudEnfant.Value
            Adresse = $tbAdresse.Text
            Police = $tbPolice.Text
            DateOrigine = $dpDateOrigine.Value.ToShortDateString()
            Type = $tbType.Text
            Immatriculation = $tbImmat.Text
            DateMC = $dpMC.Value.ToShortDateString()
            ValeurVenale = $tbValeur.Text
            Tel1 = $tbTel1.Text
            Tel2 = $tbTel2.Text
            Email = $tbEmail.Text
            Notes = $tbNotes.Text
        }

        try {
            Save-Client -Client $new -CsvFile $csvFile
            [System.Windows.Forms.MessageBox]::Show("Client enregistré !","Succès")
            $form.Tag = $true
            $form.Close()
        }
        catch {
            [System.Windows.Forms.MessageBox]::Show($_.Exception.Message,"Erreur",'OK','Error')
        }
    })

    $btnClose.Add_Click({ $form.Close() })

    $form.ShowDialog() | Out-Null
    return [bool]$form.Tag
}

# =========================
# BOUTON DETAIL LISTVIEW
# =========================



$btnDetail.Add_Click({
    Show-ClientDetailForm -List $list -RootPath $PSScriptRoot
})

Créé il y a 1 semaine.

Rechercher un Pastebin

Aucun paste trouvé.