Logo Pastebin.fr
Pastebin

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

dash walid

function Write-HistoryLog {
    param(
        [Parameter(Mandatory)]
        [string]$Action,

        [Parameter(Mandatory)]
        [string]$Contrat,

        [Parameter(Mandatory)]
        [string]$Details
    )

    $logPath = "C:\Users\walid\Desktop\test\detail\historique.csv"

    if (-not (Test-Path $logPath)) {
        "Date,Action,Contrat,Details,Utilisateur" | Out-File $logPath -Encoding UTF8
    }

    $logObject = [PSCustomObject]@{
        Date       = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
        Action     = $Action
        Contrat    = $Contrat
        Details    = $Details
        Utilisateur= $currentuser
    }

    $logObject | Export-Csv $logPath -Append -NoTypeInformation -Encoding UTF8
}


$btnHistory = New-Object System.Windows.Forms.Button
$btnHistory.Text = "Historique"
$btnHistory.Location = New-Object System.Drawing.Point(760,120)
$btnHistory.Size = New-Object System.Drawing.Size(140,30)
$btnHistory.BackColor = $colorButton
$btnHistory.ForeColor = [System.Drawing.Color]::White
$btnHistory.Enabled = $True
$grp.Controls.Add($btnHistory)


# Action du bouton Historique
$btnHistory.Add_Click({

    $formHistory = New-Object System.Windows.Forms.Form
    $formHistory.Text = "🕒 Historique des modifications"
    $formHistory.Size = New-Object System.Drawing.Size(850,450)
    $formHistory.StartPosition = "CenterScreen"
    $formHistory.BackColor = [System.Drawing.Color]::FromArgb(20,20,20)
    $formHistory.ForeColor = [System.Drawing.Color]::White
    $formHistory.FormBorderStyle = "FixedSingle"
    $formHistory.MaximizeBox = $false
    $formHistory.Font = New-Object System.Drawing.Font("Segoe UI", 9)

    $lvHistory = New-Object System.Windows.Forms.ListView
    $lvHistory.View = "Details"
    $lvHistory.FullRowSelect = $true
    $lvHistory.GridLines = $false
    $lvHistory.Dock = "Fill"
    $lvHistory.BackColor = [System.Drawing.Color]::FromArgb(30,30,30)
    $lvHistory.ForeColor = [System.Drawing.Color]::Gainsboro
    $lvHistory.BorderStyle = "None"

    $lvHistory.Columns.Add("Date / Heure",140) | Out-Null
    $lvHistory.Columns.Add("Action",110) | Out-Null
    $lvHistory.Columns.Add("Contrat",120) | Out-Null
    $lvHistory.Columns.Add("Détails",280) | Out-Null
    $lvHistory.Columns.Add("Utilisateur",120) | Out-Null

    $logPath = "C:\Users\walid\Desktop\test\detail\historique.csv"

    if (Test-Path $logPath) {
        Import-Csv $logPath | Sort-Object Date -Descending | ForEach-Object {
            $item = New-Object System.Windows.Forms.ListViewItem($_.Date)
            $item.SubItems.Add($_.Action) | Out-Null
            $item.SubItems.Add($_.Contrat) | Out-Null
            $item.SubItems.Add($_.Details) | Out-Null
            $item.SubItems.Add($CurrentUser) | Out-Null
            $lvHistory.Items.Add($item) | Out-Null
        }
    }

    $formHistory.Controls.Add($lvHistory)
    $formHistory.ShowDialog()
})

####################################################### SEARCH

$grpSearch = New-Object System.Windows.Forms.GroupBox
$grpSearch.Text = "🔍 Recherche"
$grpSearch.Location = New-Object System.Drawing.Point(20,520)
$grpSearch.Size = New-Object System.Drawing.Size(1080,70)
$grpSearch.ForeColor = [System.Drawing.Color]::DeepSkyBlue
$grpSearch.BackColor = [System.Drawing.Color]::FromArgb(20,20,35)   # fond sombre futuriste
$grpSearch.Font = New-Object System.Drawing.Font("Segoe UI Semibold", 12, [System.Drawing.FontStyle]::Bold)
$grpSearch.Anchor = "Bottom,Left,Right"
$form.Controls.Add($grpSearch)

$tbSearch = New-Object System.Windows.Forms.TextBox
$tbSearch.Location = New-Object System.Drawing.Point(20,26)
$tbSearch.Size = New-Object System.Drawing.Size(450,28)
$tbSearch.BackColor = [System.Drawing.Color]::FromArgb(30,30,50)
$tbSearch.ForeColor = [System.Drawing.Color]::Lime
$tbSearch.Font = New-Object System.Drawing.Font("Consolas", 11, [System.Drawing.FontStyle]::Bold)
$tbSearch.BorderStyle = "FixedSingle"
$grpSearch.Controls.Add($tbSearch)

# Bouton Réinitialiser
$btnReset = New-Object System.Windows.Forms.Button
$btnReset.Text = "⟲"
$btnReset.Location = New-Object System.Drawing.Point(480,24)
$btnReset.Size = New-Object System.Drawing.Size(45,30)
$btnReset.BackColor = [System.Drawing.Color]::FromArgb(50,50,80)
$btnReset.ForeColor = [System.Drawing.Color]::Cyan
$btnReset.FlatStyle = "Flat"
$btnReset.Font = New-Object System.Drawing.Font("Segoe UI", 14, [System.Drawing.FontStyle]::Bold)
$grpSearch.Controls.Add($btnReset)

$form.Add_Shown({ Refresh-AllItems })

# Filtrage automatique sur toutes les colonnes
$tbSearch.Add_TextChanged({
    $searchText = $tbSearch.Text.ToLower()

    $list.BeginUpdate()
    $list.Items.Clear()

    $results = $allItems | Where-Object {
        $_.SubItems.Text.ToLower()  -match $searchText
    }

    if($results) { 
        foreach ($res in $results) { 
            $null = $list.Items.Add($res.Clone())
        }
    }

    $list.EndUpdate()
   
})

# Réinitialisation
$btnReset.Add_Click({
    $tbSearch.Clear()
    $list.Items.Clear()
    foreach ($i in $allItems) { $list.Items.Add($i.Clone()) | Out-Null }
})

##################################################### EXCEL

$btnExportExcel = New-Object System.Windows.Forms.Button
$btnExportExcel.Text = "Export Excel"
$btnExportExcel.Location = New-Object System.Drawing.Point(920,120)
$btnExportExcel.Size = New-Object System.Drawing.Size(140,30)
$btnExportExcel.BackColor = $colorButton
$btnExportExcel.ForeColor = [System.Drawing.Color]::White
$btnExportExcel.Enabled = $True
$grp.Controls.Add($btnExportExcel)

####################################################### timeline

function Show-StarTimeline {
    param($selectedItem)

    # 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 2026"
    $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
        [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("STAR - CYCLE TEMPOREL", (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)
        }

        $g.DrawString("CLIENT : $($clientNom.ToUpper()) | POLICE : $policeNum", (New-Object System.Drawing.Font("Segoe UI", 9)), [System.Drawing.Brushes]::Gray, 40, $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 Show-DetailedAudit {
    param (
        [Parameter(Mandatory=$true)]
        [System.Windows.Forms.ListView]$list
    )

    if ($list.Items.Count -eq 0) {
        [System.Windows.Forms.MessageBox]::Show("⚠️ Pas de données dans la liste !")
        return
    }

    # --- Fenêtre ---
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "🕵️ Audit détaillé des contrats"
    $form.Size = New-Object System.Drawing.Size(1000,600)
    $form.StartPosition = "CenterScreen"
    $form.BackColor = [System.Drawing.Color]::FromArgb(18,18,32)
    $form.Opacity = 0.95
    $form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
    $form.MaximizeBox = $false

    # --- RichTextBox ---
    $txt = New-Object System.Windows.Forms.RichTextBox
    $txt.Multiline = $true
    $txt.ScrollBars = "Vertical"
    $txt.ReadOnly = $true
    $txt.Font = New-Object System.Drawing.Font("Consolas",10)
    $txt.BackColor = [System.Drawing.Color]::FromArgb(25,25,50)
    $txt.ForeColor = [System.Drawing.Color]::White
    $txt.Dock = "Fill"
    $form.Controls.Add($txt)

    $today = (Get-Date).Date

    function Calculate-RiskScore {
        param($item)
        $score = 0
        try {
            $dEffet = [datetime]::ParseExact($item.SubItems[3].Text.Trim(),"dd/MM/yyyy",$null)
            $dMDR = [datetime]::ParseExact($item.SubItems[4].Text.Trim(),"dd/MM/yyyy",$null)
            $dSusp = [datetime]::ParseExact($item.SubItems[5].Text.Trim(),"dd/MM/yyyy",$null)
            $dResil = [datetime]::ParseExact($item.SubItems[6].Text.Trim(),"dd/MM/yyyy",$null)

            $daysToResil = ($dResil - $today).TotalDays
            if ($daysToResil -le 0) { $score += 50 } else { $score += [math]::Max(0,30 - $daysToResil) }

            if ($dMDR -le $today) { $score += 20 }
            if ($dSusp -le $today) { $score += 20 }

            if ($score -gt 100) { $score = 100 }
        } catch { $score = 0 }
        return [math]::Round($score,1)
    }

    $txt.AppendText("📝 Audit détaillé des contrats au $($today.ToShortDateString())`r`n")
    $txt.AppendText("==============================================================`r`n`r`n")

    foreach ($item in $list.Items) {
        try { $dEffet = [datetime]::ParseExact($item.SubItems[3].Text.Trim(),"dd/MM/yyyy",$null) } catch { $dEffet=$null }
        try { $dMDR = [datetime]::ParseExact($item.SubItems[4].Text.Trim(),"dd/MM/yyyy",$null) } catch { $dMDR=$null }
        try { $dSusp = [datetime]::ParseExact($item.SubItems[5].Text.Trim(),"dd/MM/yyyy",$null) } catch { $dSusp=$null }
        try { $dResil = [datetime]::ParseExact($item.SubItems[6].Text.Trim(),"dd/MM/yyyy",$null) } catch { $dResil=$null }

        $client = $item.SubItems[1].Text
        $police = $item.SubItems[0].Text

        $statuts = @()
        if ($dResil -ne $null) {
            if ($dResil -gt $today) { $statuts += "✅ Actif" } else { $statuts += "❌ Résilié" }
        } else { $statuts += "❓ Résiliation inconnue" }
        if ($dMDR -ne $null -and $dMDR -le $today) { $statuts += "💌 Mise en demeure" }
        if ($dSusp -ne $null -and $dSusp -le $today) { $statuts += "⏸ Suspension" }
        if ($dResil -ne $null -and ($dResil.AddDays(20) -le $today)) { $statuts += "⚠️ Contentieux" }

        $score = Calculate-RiskScore -item $item
        if ($score -ge 70) { $color = "Red" }
        elseif ($score -ge 40) { $color = "Orange" }
        else { $color = "Lime" }

        # --- Préparer affichage dates sans ?. ---
        if ($dEffet -ne $null) { $effetStr = $dEffet.ToShortDateString() } else { $effetStr = "N/A" }
        if ($dMDR -ne $null) { $mdrStr = $dMDR.ToShortDateString() } else { $mdrStr = "N/A" }
        if ($dSusp -ne $null) { $suspStr = $dSusp.ToShortDateString() } else { $suspStr = "N/A" }
        if ($dResil -ne $null) { $resilStr = $dResil.ToShortDateString() } else { $resilStr = "N/A" }

        $txt.SelectionStart = $txt.TextLength
        $txt.SelectionColor = [System.Drawing.Color]::$color
        $txt.AppendText("📃 Police: $police | Client: $client`r`n")
        $txt.SelectionColor = [System.Drawing.Color]::White
        $txt.AppendText("    Statuts : $([string]::Join(", ", $statuts))`r`n")
        $txt.AppendText("    Dates   : Effet: $effetStr ; MDR: $mdrStr ; Suspension: $suspStr ; Résiliation: $resilStr`r`n")
        $txt.AppendText("    Score risque : $score / 100`r`n")
        $txt.AppendText("--------------------------------------------------------------`r`n`r`n")
    }

    # --- Bouton Fermer ---
    $btnClose = New-Object System.Windows.Forms.Button
    $btnClose.Text = "Fermer"
    $btnClose.Font = New-Object System.Drawing.Font("Segoe UI",10,[System.Drawing.FontStyle]::Bold)
    $btnClose.Size = New-Object System.Drawing.Size(120,35)
    $btnX = $form.ClientSize.Width - 140
    $btnY = $form.ClientSize.Height - 50
    $btnClose.Location = New-Object System.Drawing.Point($btnX,$btnY)
    $btnClose.Anchor = "Bottom,Right"
    $btnClose.Add_Click({ $form.Close() })
    $form.Controls.Add($btnClose)

    $form.ShowDialog()
}



#Show-DetailedAudit -list $list



function Show-Dashboard {
    param (
        [System.Windows.Forms.ListView]$list
    )

    if ($list.Items.Count -eq 0) {
        [System.Windows.Forms.MessageBox]::Show("⚠️ Pas de données à afficher.", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
        return
    }

    # --- Couleurs et styles pro ---
    $bgColor = [System.Drawing.Color]::FromArgb(40, 44, 52)        # fond gris foncé
    $fgColorTitle = [System.Drawing.Color]::FromArgb(230, 230, 230) # texte clair
    $colorGreen = [System.Drawing.Color]::FromArgb(88, 184, 84)
    $colorOrange = [System.Drawing.Color]::FromArgb(255, 140, 0)
    $colorRed = [System.Drawing.Color]::FromArgb(220, 53, 69)
    $colorYellow = [System.Drawing.Color]::FromArgb(255, 193, 7)
    $colorBlue = [System.Drawing.Color]::FromArgb(23, 162, 184)
    $colorMagenta = [System.Drawing.Color]::FromArgb(155, 89, 182)
    $colorLightGray = [System.Drawing.Color]::FromArgb(200, 200, 200)

    $today = (Get-Date).Date

    # --- Compteurs ---
    $total = $list.Items.Count
    $actifs=0; $resilies=0; $contentieux=0; $miseEnDemeure=0; $suspension=0
    $delais = @(); $clients=@{}; $contratsParMois=@{}

    # --- Fonction calcul score de risque ---
    function Calculate-RiskScore {
        param($item)
        $score = 0
        try {
            $dEffet = [datetime]::ParseExact($item.SubItems[3].Text.Trim(),"dd/MM/yyyy",$null)
            $dMDR = [datetime]::ParseExact($item.SubItems[4].Text.Trim(),"dd/MM/yyyy",$null)
            $dSusp = [datetime]::ParseExact($item.SubItems[5].Text.Trim(),"dd/MM/yyyy",$null)
            $dResil = [datetime]::ParseExact($item.SubItems[6].Text.Trim(),"dd/MM/yyyy",$null)

            $daysToResil = ($dResil - $today).TotalDays
            if ($daysToResil -le 0) { $score += 50 } else { $score += [math]::Max(0, 30 - $daysToResil) }
            if ($dMDR -le $today) { $score += 20 }
            if ($dSusp -le $today) { $score += 20 }
            if ($score -gt 100) { $score = 100 }
        }
        catch { $score = 0 }
        return [math]::Round($score,1)
    }

    # --- Parcours contrats ---
    foreach ($item in $list.Items) {
        try {
            $dEffet = [datetime]::ParseExact($item.SubItems[3].Text.Trim(),"dd/MM/yyyy",$null)
            $dCont  = [datetime]::ParseExact($item.SubItems[4].Text.Trim(),"dd/MM/yyyy",$null)
            $dSusp  = [datetime]::ParseExact($item.SubItems[5].Text.Trim(),"dd/MM/yyyy",$null)
            $dResil = [datetime]::ParseExact($item.SubItems[6].Text.Trim(),"dd/MM/yyyy",$null)
        }
        catch { continue }

        $dContentieux = $dResil.AddDays(20)
        $client = $item.SubItems[1].Text

        if ($dResil -gt $today) { $actifs++ } else { $resilies++ }
        if ($dContentieux -le $today) { $contentieux++ }
        if ($dCont -le $today) { $miseEnDemeure++ }
        if ($dSusp -le $today) { $suspension++ }

        $delais += ($dResil - $dEffet).TotalDays

        if (-not $clients.ContainsKey($client)) { $clients[$client] = @() }
        $clients[$client] += $item.Text

        $mois = $dEffet.ToString("MM/yyyy")
        if (-not $contratsParMois.ContainsKey($mois)) { $contratsParMois[$mois] = 0 }
        $contratsParMois[$mois]++
    }

    # --- Moyennes et ratios ---
    $delaiMoy = if ($delais.Count) {[math]::Round(($delais|Measure-Object -Average).Average,1)} else {0}
    $delaiMin = if ($delais.Count) {[math]::Round(($delais|Measure-Object -Minimum).Minimum,1)} else {0}
    $delaiMax = if ($delais.Count) {[math]::Round(($delais|Measure-Object -Maximum).Maximum,1)} else {0}

    $ratioActif = if ($total -gt 0) { [math]::Round(($actifs/$total)*100,1) } else { 0 }
    $ratioResil = if ($total -gt 0) { [math]::Round(($resilies/$total)*100,1) } else { 0 }
    $ratioContentieux = if ($total -gt 0) { [math]::Round(($contentieux/$total)*100,1) } else { 0 }
    $ratioSuspension = if ($total -gt 0) { [math]::Round(($suspension/$total)*100,1) } else { 0 }
    $ratioMiseDemeure = if ($total -gt 0) { [math]::Round(($miseEnDemeure/$total)*100,1) } else { 0 }

    # --- Score risques clients ---
    $clientsRisk = @{}
    foreach ($item in $list.Items) {
        $client = $item.SubItems[1].Text
        $score = Calculate-RiskScore -item $item
        if (-not $clientsRisk.ContainsKey($client)) { $clientsRisk[$client] = @() }
        $clientsRisk[$client] += $score
    }

    $clientsRiskAverage = $clientsRisk.GetEnumerator() | ForEach-Object {
        [PSCustomObject]@{
            Client = $_.Key
            AvgScore = if ($_.Value.Count) { [math]::Round(($_.Value | Measure-Object -Average).Average,1) } else {0}
        }
    }

    $topClients = $clientsRiskAverage | Sort-Object AvgScore -Descending | Select-Object -First 5

    # --- Alertes intelligentes ---
    $contractsSoonContentieux = 0
    foreach ($item in $list.Items) {
        try {
            $dResil = [datetime]::ParseExact($item.SubItems[6].Text.Trim(),"dd/MM/yyyy",$null)
            $dContentieux = $dResil.AddDays(20)
            $daysToContentieux = ($dContentieux - $today).TotalDays
            if ($daysToContentieux -ge 0 -and $daysToContentieux -le 20) { $contractsSoonContentieux++ }
        }
        catch { }
    }

    $alertMessage = if ($contractsSoonContentieux -gt 0) {
        "⚠️ Attention, $contractsSoonContentieux contrat(s) risquent d'entrer en contentieux dans les 20 prochains jours."
    } else {
        "✅ Aucun contrat ne semble entrer en contentieux prochainement."
    }

    # --- Création formulaire ---
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "🛰 STAR DASHBOARD PRO - Professionnel"
    $form.Size = New-Object System.Drawing.Size(1100,700)
    $form.StartPosition = "CenterScreen"
    $form.BackColor = $bgColor
    $form.Opacity = 0.97
    $form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
    $form.MaximizeBox = $false

    # --- Titre ---
    $lblTitle = New-Object System.Windows.Forms.Label
    $lblTitle.Text = "🛰 STAR DASHBOARD PRO"
    $lblTitle.Font = New-Object System.Drawing.Font("Segoe UI Semibold",26,[System.Drawing.FontStyle]::Bold)
    $lblTitle.ForeColor = $fgColorTitle
    $lblTitle.AutoSize = $true
    $lblTitle.Location = New-Object System.Drawing.Point(30,20)
    $form.Controls.Add($lblTitle)

    # --- Stats globales ---
    $y = 80; $spacing = 36
    $stats = @(
        @{Text = "📦 Total contrats : $total"; Color = $fgColorTitle},
        @{Text = "✅ Actifs : $actifs ($ratioActif%)"; Color = $colorGreen},
        @{Text = "❌ Résiliés : $resilies ($ratioResil%)"; Color = $colorRed},
        @{Text = "⚠️ Contentieux : $contentieux ($ratioContentieux%)"; Color = $colorOrange},
        @{Text = "💌 Mise en demeure : $miseEnDemeure ($ratioMiseDemeure%)"; Color = $colorYellow},
        @{Text = "⏸ Suspension : $suspension ($ratioSuspension%)"; Color = $colorBlue},
        @{Text = "⏱ Délai moyen : $delaiMoy jours (min $delaiMin / max $delaiMax)"; Color = $colorLightGray},
        @{Text = "👥 Clients distincts : $($clients.Keys.Count)"; Color = $colorMagenta}
    )

    foreach ($stat in $stats) {
        $lbl = New-Object System.Windows.Forms.Label
        $lbl.Text = $stat.Text
        $lbl.ForeColor = $stat.Color
        $lbl.Font = New-Object System.Drawing.Font("Segoe UI",14,[System.Drawing.FontStyle]::Bold)
        $lbl.AutoSize = $true
        $lbl.Location = New-Object System.Drawing.Point(40,$y)
        $y += $spacing
        $form.Controls.Add($lbl)
    }

    # --- Top 5 clients à risque ---
    $lblTopClientsTitle = New-Object System.Windows.Forms.Label
    $lblTopClientsTitle.Text = "🔥 Top 5 clients à risque"
    $lblTopClientsTitle.ForeColor = $colorOrange
    $lblTopClientsTitle.Font = New-Object System.Drawing.Font("Segoe UI Semibold",16,[System.Drawing.FontStyle]::Bold)
    $lblTopClientsTitle.AutoSize = $true
    $lblTopClientsTitle.Location = New-Object System.Drawing.Point(600, 80)
    $form.Controls.Add($lblTopClientsTitle)

    $yTop = 120
    foreach ($clientRisk in $topClients) {
        $lblClient = New-Object System.Windows.Forms.Label
        $lblClient.Text = "$($clientRisk.Client) : Score risque moyen $($clientRisk.AvgScore)/100"
        $lblClient.ForeColor = $fgColorTitle
        $lblClient.Font = New-Object System.Drawing.Font("Segoe UI",12,[System.Drawing.FontStyle]::Regular)
        $lblClient.AutoSize = $true
        $lblClient.Location = New-Object System.Drawing.Point(600, $yTop)
        $form.Controls.Add($lblClient)
        $yTop += 30
    }

    # --- Alertes ---
    $lblAlert = New-Object System.Windows.Forms.Label
    $lblAlert.Text = $alertMessage
    $lblAlert.ForeColor = $colorRed
    $lblAlert.Font = New-Object System.Drawing.Font("Segoe UI Semibold",14,[System.Drawing.FontStyle]::Bold)
    $lblAlert.AutoSize = $true
    $lblAlert.Location = New-Object System.Drawing.Point(40, ($y + 20))
    $form.Controls.Add($lblAlert)

    # --- TextBox détails clients ---
    $txtDetails = New-Object System.Windows.Forms.TextBox
    $txtDetails.Multiline = $true
    $txtDetails.ScrollBars = "Vertical"
    $txtDetails.ReadOnly = $true
    $txtDetails.Font = New-Object System.Drawing.Font("Consolas",11)
    $txtDetails.BackColor = [System.Drawing.Color]::FromArgb(25,25,40)
    $txtDetails.ForeColor = $fgColorTitle
    $txtDetails.Size = New-Object System.Drawing.Size(1000, 350)
    $txtDetails.Location = New-Object System.Drawing.Point(40, ($y + 60))
    $form.Controls.Add($txtDetails)

    # Remplissage textbox détails
    $txtDetails.AppendText("🚀 === CONTRATS PAR CLIENT ===`r`n")
    foreach ($c in $clients.Keys) {
        $txtDetails.AppendText("👤 $c | Contrats : $($clients[$c].Count)`r`n")
        $txtDetails.AppendText("   Polices : $($clients[$c] -join ', ')`r`n`r`n")
    }

    $txtDetails.AppendText("📊 === CONTRATS PAR MOIS ===`r`n")
    foreach ($m in $contratsParMois.Keys | Sort-Object) {
        $txtDetails.AppendText("📅 $m : $($contratsParMois[$m]) contrats`r`n")
    }

    # --- Bouton Détails Client ---
    $btnDetail = New-Object System.Windows.Forms.Button
    $btnDetail.Text = "🕵️ Détails client"
    $btnDetail.Font = New-Object System.Drawing.Font("Segoe UI",12,[System.Drawing.FontStyle]::Bold)
    $btnDetail.Size = New-Object System.Drawing.Size(200,40)
    $btnDetail.Location = New-Object System.Drawing.Point(800, ($y + 20))
    $btnDetail.BackColor = [System.Drawing.Color]::FromArgb(50,50,70)
    $btnDetail.ForeColor = [System.Drawing.Color]::White
    $btnDetail.FlatStyle = "Flat"
    $btnDetail.FlatAppearance.BorderSize = 0

    $btnDetail.Add_Click({
        if ($list.Items.Count -eq 0) {
            [System.Windows.Forms.MessageBox]::Show("⚠️ Pas de contrats à afficher.", "Info")
        } else {
            Show-DetailedAudit -list $list
        }
    })
    $form.Controls.Add($btnDetail)

    # --- Affichage dashboard ---
    $form.ShowDialog()
}


$btnDashboard = New-Object System.Windows.Forms.Button
$btnDashboard.Text = "Dashboard"
$btnDashboard.Location = New-Object System.Drawing.Point(330, 120)
$btnDashboard.Size = New-Object System.Drawing.Size(250,30)
$btnDashboard.BackColor = $colorButton
$btnDashboard.ForeColor = [System.Drawing.Color]::White
$grp.Controls.Add($btnDashboard)

$btnDashboard.Add_Click({
    Show-Dashboard $list 
})

Créé il y a 2 semaines.

Rechercher un Pastebin

Aucun paste trouvé.