Reopening cases logic
This commit is contained in:
+193
-67
@@ -26,6 +26,7 @@ namespace OutlookCaseHelper
|
||||
{
|
||||
trayMenu = new ContextMenuStrip();
|
||||
trayMenu.Items.Add("Create Rule (Selected Email)", null, ProcessEmail_Click);
|
||||
trayMenu.Items.Add("Create Rule (Manual ID)", null, CreateRuleManual_Click);
|
||||
trayMenu.Items.Add("Remove Rule (Selected Email)", null, RemoveRuleFromSelected_Click);
|
||||
trayMenu.Items.Add("Remove Rule (Manual ID)", null, RemoveRule_Click);
|
||||
trayMenu.Items.Add("-");
|
||||
@@ -42,17 +43,14 @@ namespace OutlookCaseHelper
|
||||
private void InitializeTimer()
|
||||
{
|
||||
monitorTimer = new System.Windows.Forms.Timer();
|
||||
monitorTimer.Interval = 60000; // verifica a cada 60 segundos
|
||||
monitorTimer.Interval = 60000;
|
||||
monitorTimer.Tick += MonitorTimer_Tick;
|
||||
monitorTimer.Start();
|
||||
}
|
||||
|
||||
private void MonitorTimer_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
outlookHelper.ProcessActiveRules();
|
||||
}
|
||||
try { outlookHelper.ProcessActiveRules(); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
@@ -65,30 +63,93 @@ namespace OutlookCaseHelper
|
||||
{
|
||||
MessageBox.Show(
|
||||
"No email selected or ID not found in subject.\n\nExpected format: Title - TrackingID#1111111111111111",
|
||||
"Warning",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = outlookHelper.CreateFolderAndMoveEmails(trackingId);
|
||||
if (success)
|
||||
// Verifica se já existe regra ativa
|
||||
if (outlookHelper.FindRuleByTrackingId(trackingId) != null)
|
||||
{
|
||||
var activeCount = outlookHelper.GetActiveRules().Count;
|
||||
MessageBox.Show(
|
||||
$"Rule created! Emails moved and monitoring started.\n\nTrackingID: {trackingId}\nActive rules: {activeCount}",
|
||||
"Success",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
MessageBox.Show($"Rule for TrackingID#{trackingId} already exists!",
|
||||
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verifica se existe em Closed — reabre sem pedir nome
|
||||
if (outlookHelper.ExistsInClosed(trackingId))
|
||||
{
|
||||
var triggerEmail = outlookHelper.GetSelectedEmail();
|
||||
bool reopened = outlookHelper.ReopenFromClosed(trackingId, triggerEmail);
|
||||
if (reopened)
|
||||
MessageBox.Show(
|
||||
$"Case reopened! Folder moved from Closed to Active.\n\nTrackingID: {trackingId}",
|
||||
"Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Error processing email. Make sure Outlook is open.",
|
||||
"Error",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
MessageBox.Show("Error reopening case.",
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Caso novo — pede nome
|
||||
var ruleForm = new CreateRuleForm(trackingId, readonlyId: true);
|
||||
if (ruleForm.ShowDialog() != DialogResult.OK) return;
|
||||
|
||||
string folderName = ruleForm.FolderName;
|
||||
|
||||
bool success = outlookHelper.CreateFolderAndMoveEmails(trackingId, folderName);
|
||||
if (success)
|
||||
MessageBox.Show(
|
||||
$"Rule created! Emails moved and monitoring started.\n\nFolder: {folderName}\nActive rules: {outlookHelper.GetActiveRules().Count}",
|
||||
"Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
MessageBox.Show("Error processing email. Make sure Outlook is open.",
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateRuleManual_Click(object? sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ruleForm = new CreateRuleForm("", readonlyId: false);
|
||||
if (ruleForm.ShowDialog() != DialogResult.OK) return;
|
||||
|
||||
string trackingId = ruleForm.TrackingId;
|
||||
string folderName = ruleForm.FolderName;
|
||||
|
||||
if (outlookHelper.FindRuleByTrackingId(trackingId) != null)
|
||||
{
|
||||
MessageBox.Show($"Rule for TrackingID#{trackingId} already exists!",
|
||||
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verifica se existe em Closed — reabre sem pedir nome
|
||||
if (outlookHelper.ExistsInClosed(trackingId))
|
||||
{
|
||||
bool reopened = outlookHelper.ReopenFromClosed(trackingId);
|
||||
if (reopened)
|
||||
MessageBox.Show(
|
||||
$"Case reopened! Folder moved from Closed to Active.\n\nTrackingID: {trackingId}",
|
||||
"Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
MessageBox.Show("Error reopening case.",
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = outlookHelper.CreateFolderAndMoveEmails(trackingId, folderName);
|
||||
if (success)
|
||||
MessageBox.Show(
|
||||
$"Rule created! Emails moved and monitoring started.\n\nFolder: {folderName}\nActive rules: {outlookHelper.GetActiveRules().Count}",
|
||||
"Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
MessageBox.Show("Error creating rule. Make sure Outlook is open.",
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -101,25 +162,24 @@ namespace OutlookCaseHelper
|
||||
try
|
||||
{
|
||||
var form = new InputForm("Enter TrackingID to remove:", "Remove Rule");
|
||||
if (form.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(form.TrackingId))
|
||||
if (form.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(form.Value))
|
||||
{
|
||||
bool success = outlookHelper.RemoveRuleAndMoveToClosed(form.TrackingId);
|
||||
string? folderName = outlookHelper.FindRuleByTrackingId(form.Value.Trim());
|
||||
if (folderName == null)
|
||||
{
|
||||
MessageBox.Show($"No active rule found for TrackingID#{form.Value}.",
|
||||
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = outlookHelper.RemoveRuleAndMoveToClosed(folderName);
|
||||
if (success)
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Rule removed!\n\nFolder moved to: Inbox > Cases > Closed\nMonitoring stopped.",
|
||||
"Success",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
}
|
||||
$"Rule removed!\n\nFolder moved to: Inbox > Cases > Closed\nFolder: {folderName}\nMonitoring stopped.",
|
||||
"Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Error removing rule. Check if folder exists.",
|
||||
"Error",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
MessageBox.Show("Error removing rule. Check if folder exists.",
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -137,29 +197,26 @@ namespace OutlookCaseHelper
|
||||
{
|
||||
MessageBox.Show(
|
||||
"No email selected or ID not found in subject.\n\nExpected format: Title - TrackingID#1111111111111111",
|
||||
"Warning",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = outlookHelper.RemoveRuleAndMoveToClosed(trackingId);
|
||||
string? folderName = outlookHelper.FindRuleByTrackingId(trackingId);
|
||||
if (folderName == null)
|
||||
{
|
||||
MessageBox.Show($"No active rule found for TrackingID#{trackingId}.",
|
||||
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = outlookHelper.RemoveRuleAndMoveToClosed(folderName);
|
||||
if (success)
|
||||
{
|
||||
MessageBox.Show(
|
||||
$"Rule removed!\n\nFolder moved to: Inbox > Cases > Closed\nTrackingID: {trackingId}\nMonitoring stopped.",
|
||||
"Success",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
}
|
||||
$"Rule removed!\n\nFolder moved to: Inbox > Cases > Closed\nFolder: {folderName}\nMonitoring stopped.",
|
||||
"Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
else
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Error removing rule. Check if folder exists and Outlook is open.",
|
||||
"Error",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
MessageBox.Show("Error removing rule. Check if folder exists and Outlook is open.",
|
||||
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -179,36 +236,105 @@ namespace OutlookCaseHelper
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
private class CreateRuleForm : Form
|
||||
{
|
||||
private TextBox txtId;
|
||||
private TextBox txtName;
|
||||
private Label lblPreview;
|
||||
public string TrackingId { get; private set; } = "";
|
||||
public string FolderName { get; private set; } = "";
|
||||
|
||||
public CreateRuleForm(string trackingId, bool readonlyId)
|
||||
{
|
||||
this.Text = "Create Rule";
|
||||
this.Size = new Size(420, 230);
|
||||
this.MinimumSize = new Size(420, 230);
|
||||
this.MaximumSize = new Size(420, 230);
|
||||
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.StartPosition = FormStartPosition.CenterScreen;
|
||||
|
||||
var lblId = new Label { Text = "TrackingID (required):", Left = 20, Top = 15, Width = 370, Height = 20 };
|
||||
txtId = new TextBox { Left = 20, Top = 38, Width = 370, Height = 24, Text = trackingId, ReadOnly = readonlyId };
|
||||
if (readonlyId) txtId.BackColor = System.Drawing.SystemColors.Control;
|
||||
|
||||
var lblName = new Label { Text = "Additional name (optional):", Left = 20, Top = 72, Width = 370, Height = 20 };
|
||||
txtName = new TextBox { Left = 20, Top = 95, Width = 370, Height = 24 };
|
||||
|
||||
lblPreview = new Label { Left = 20, Top = 128, Width = 370, Height = 20, ForeColor = System.Drawing.Color.Gray };
|
||||
UpdatePreview(trackingId);
|
||||
|
||||
var btnOk = new Button { Text = "OK", Left = 220, Top = 158, Width = 80, DialogResult = DialogResult.OK };
|
||||
var btnCancel = new Button { Text = "Cancel", Left = 310, Top = 158, Width = 80, DialogResult = DialogResult.Cancel };
|
||||
|
||||
txtId.TextChanged += (s, e) => UpdatePreview(txtId.Text.Trim());
|
||||
txtName.TextChanged += (s, e) => UpdatePreview(txtId.Text.Trim());
|
||||
|
||||
this.Controls.AddRange(new Control[] { lblId, txtId, lblName, txtName, lblPreview, btnOk, btnCancel });
|
||||
this.AcceptButton = btnOk;
|
||||
this.CancelButton = btnCancel;
|
||||
}
|
||||
|
||||
private void UpdatePreview(string id)
|
||||
{
|
||||
string name = txtName?.Text.Trim() ?? "";
|
||||
string preview = string.IsNullOrEmpty(name) ? id : $"{id} | {name}";
|
||||
if (lblPreview != null)
|
||||
lblPreview.Text = $"Folder: {preview}";
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
if (this.DialogResult == DialogResult.OK)
|
||||
{
|
||||
TrackingId = txtId.Text.Trim();
|
||||
string name = txtName.Text.Trim();
|
||||
|
||||
if (string.IsNullOrEmpty(TrackingId))
|
||||
{
|
||||
MessageBox.Show("TrackingID is required!", "Validation",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
e.Cancel = true;
|
||||
return;
|
||||
}
|
||||
|
||||
FolderName = string.IsNullOrEmpty(name) ? TrackingId : $"{TrackingId} | {name}";
|
||||
}
|
||||
base.OnFormClosing(e);
|
||||
}
|
||||
}
|
||||
|
||||
private class InputForm : Form
|
||||
{
|
||||
private TextBox txtInput;
|
||||
public string TrackingId { get; private set; } = "";
|
||||
public string Value { get; private set; } = "";
|
||||
|
||||
public InputForm(string prompt, string title)
|
||||
{
|
||||
this.Text = title;
|
||||
this.Width = 400;
|
||||
this.Height = 150;
|
||||
this.Size = new Size(380, 150);
|
||||
this.MinimumSize = new Size(380, 150);
|
||||
this.MaximumSize = new Size(380, 150);
|
||||
this.FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.StartPosition = FormStartPosition.CenterScreen;
|
||||
|
||||
var label = new Label { Text = prompt, Left = 20, Top = 20, Width = 360, Height = 30 };
|
||||
txtInput = new TextBox { Left = 20, Top = 60, Width = 340, Height = 30 };
|
||||
var label = new Label { Text = prompt, Left = 20, Top = 15, Width = 330, Height = 25 };
|
||||
txtInput = new TextBox { Left = 20, Top = 45, Width = 330, Height = 24 };
|
||||
|
||||
var btnOk = new Button { Text = "OK", Left = 200, Top = 100, Width = 80, DialogResult = DialogResult.OK };
|
||||
var btnCancel = new Button { Text = "Cancel", Left = 290, Top = 100, Width = 80, DialogResult = DialogResult.Cancel };
|
||||
|
||||
this.Controls.Add(label);
|
||||
this.Controls.Add(txtInput);
|
||||
this.Controls.Add(btnOk);
|
||||
this.Controls.Add(btnCancel);
|
||||
var btnOk = new Button { Text = "OK", Left = 155, Top = 80, Width = 80, DialogResult = DialogResult.OK };
|
||||
var btnCancel = new Button { Text = "Cancel", Left = 245, Top = 80, Width = 80, DialogResult = DialogResult.Cancel };
|
||||
|
||||
this.Controls.AddRange(new Control[] { label, txtInput, btnOk, btnCancel });
|
||||
this.AcceptButton = btnOk;
|
||||
this.CancelButton = btnCancel;
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
TrackingId = txtInput.Text;
|
||||
Value = txtInput.Text;
|
||||
base.OnFormClosing(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ namespace OutlookCaseHelper
|
||||
inboxItems = inboxFolder.Items;
|
||||
inboxItems.ItemAdd += OnEmailReceived;
|
||||
}
|
||||
|
||||
if (sentFolder != null)
|
||||
{
|
||||
sentItems = sentFolder.Items;
|
||||
@@ -62,8 +61,9 @@ namespace OutlookCaseHelper
|
||||
if (item is not Outlook.MailItem mail) return;
|
||||
if (mail.Subject == null) return;
|
||||
|
||||
foreach (var trackingId in activeRules)
|
||||
foreach (var folderName in activeRules)
|
||||
{
|
||||
string trackingId = ExtractTrackingId(folderName);
|
||||
if (mail.Subject.Contains($"TrackingID#{trackingId}"))
|
||||
{
|
||||
Outlook.Folder? inboxFolder =
|
||||
@@ -72,7 +72,7 @@ namespace OutlookCaseHelper
|
||||
|
||||
Outlook.Folder casesFolder = GetOrCreateFolder(inboxFolder, "Cases");
|
||||
Outlook.Folder activeFolder = GetOrCreateFolder(casesFolder, "Active");
|
||||
Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, trackingId);
|
||||
Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, folderName);
|
||||
|
||||
mail.Move(trackingFolder);
|
||||
break;
|
||||
@@ -90,8 +90,9 @@ namespace OutlookCaseHelper
|
||||
if (item is not Outlook.MailItem mail) return;
|
||||
if (mail.Subject == null) return;
|
||||
|
||||
foreach (var trackingId in activeRules)
|
||||
foreach (var folderName in activeRules)
|
||||
{
|
||||
string trackingId = ExtractTrackingId(folderName);
|
||||
if (mail.Subject.Contains($"TrackingID#{trackingId}"))
|
||||
{
|
||||
Outlook.Folder? inboxFolder =
|
||||
@@ -100,7 +101,7 @@ namespace OutlookCaseHelper
|
||||
|
||||
Outlook.Folder casesFolder = GetOrCreateFolder(inboxFolder, "Cases");
|
||||
Outlook.Folder activeFolder = GetOrCreateFolder(casesFolder, "Active");
|
||||
Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, trackingId);
|
||||
Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, folderName);
|
||||
|
||||
mail.Move(trackingFolder);
|
||||
break;
|
||||
@@ -110,6 +111,42 @@ namespace OutlookCaseHelper
|
||||
catch { }
|
||||
}
|
||||
|
||||
private string ExtractTrackingId(string folderName)
|
||||
{
|
||||
var match = Regex.Match(folderName, @"^(\d+)");
|
||||
return match.Success ? match.Groups[1].Value : folderName;
|
||||
}
|
||||
|
||||
public string? FindRuleByTrackingId(string trackingId)
|
||||
{
|
||||
foreach (var rule in activeRules)
|
||||
{
|
||||
if (ExtractTrackingId(rule) == trackingId)
|
||||
return rule;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Verifica se existe pasta em Closed com este trackingId
|
||||
public bool ExistsInClosed(string trackingId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Outlook.Folder? inboxFolder =
|
||||
outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder;
|
||||
if (inboxFolder == null) return false;
|
||||
|
||||
Outlook.Folder? casesFolder = GetFolder(inboxFolder, "Cases");
|
||||
if (casesFolder == null) return false;
|
||||
|
||||
Outlook.Folder? closedFolder = GetFolder(casesFolder, "Closed");
|
||||
if (closedFolder == null) return false;
|
||||
|
||||
return GetFolderStartingWith(closedFolder, trackingId) != null;
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
private void LoadRules()
|
||||
{
|
||||
try
|
||||
@@ -159,7 +196,8 @@ namespace OutlookCaseHelper
|
||||
catch { return null; }
|
||||
}
|
||||
|
||||
public bool CreateFolderAndMoveEmails(string trackingId)
|
||||
// Reabre caso existente em Closed e move o email trigger para lá
|
||||
public bool ReopenFromClosed(string trackingId, Outlook.MailItem? triggerEmail = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -169,17 +207,48 @@ namespace OutlookCaseHelper
|
||||
|
||||
Outlook.Folder casesFolder = GetOrCreateFolder(inboxFolder, "Cases");
|
||||
Outlook.Folder activeFolder = GetOrCreateFolder(casesFolder, "Active");
|
||||
Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, trackingId);
|
||||
Outlook.Folder? closedFolder = GetFolder(casesFolder, "Closed");
|
||||
if (closedFolder == null) return false;
|
||||
|
||||
Outlook.Folder? closedTracking = GetFolderStartingWith(closedFolder, trackingId);
|
||||
if (closedTracking == null) return false;
|
||||
|
||||
string existingName = closedTracking.Name;
|
||||
closedTracking.MoveTo(activeFolder);
|
||||
|
||||
// Move o email que originou a reabertura para a pasta
|
||||
if (triggerEmail != null)
|
||||
{
|
||||
Outlook.Folder? movedFolder = GetFolder(activeFolder, existingName);
|
||||
if (movedFolder != null)
|
||||
triggerEmail.Move(movedFolder);
|
||||
}
|
||||
|
||||
activeRules.Add(existingName);
|
||||
SaveRules();
|
||||
return true;
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
public bool CreateFolderAndMoveEmails(string trackingId, string folderName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Outlook.Folder? inboxFolder =
|
||||
outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder;
|
||||
if (inboxFolder == null) return false;
|
||||
|
||||
Outlook.Folder casesFolder = GetOrCreateFolder(inboxFolder, "Cases");
|
||||
Outlook.Folder activeFolder = GetOrCreateFolder(casesFolder, "Active");
|
||||
Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, folderName);
|
||||
|
||||
// Usa Restrict para mover apenas emails com o TrackingID
|
||||
string filter = $"@SQL=\"urn:schemas:httpmail:subject\" LIKE '%TrackingID#{trackingId}%'";
|
||||
|
||||
Outlook.Items restricted = inboxFolder.Items.Restrict(filter);
|
||||
var toMove = new List<Outlook.MailItem>();
|
||||
foreach (object item in restricted)
|
||||
{
|
||||
if (item is Outlook.MailItem mail)
|
||||
toMove.Add(mail);
|
||||
}
|
||||
if (item is Outlook.MailItem mail) toMove.Add(mail);
|
||||
foreach (var mail in toMove)
|
||||
mail.Move(trackingFolder);
|
||||
|
||||
@@ -190,15 +259,12 @@ namespace OutlookCaseHelper
|
||||
Outlook.Items restrictedSent = sentFolder.Items.Restrict(filter);
|
||||
var toMoveSent = new List<Outlook.MailItem>();
|
||||
foreach (object item in restrictedSent)
|
||||
{
|
||||
if (item is Outlook.MailItem mail)
|
||||
toMoveSent.Add(mail);
|
||||
}
|
||||
if (item is Outlook.MailItem mail) toMoveSent.Add(mail);
|
||||
foreach (var mail in toMoveSent)
|
||||
mail.Move(trackingFolder);
|
||||
}
|
||||
|
||||
activeRules.Add(trackingId);
|
||||
activeRules.Add(folderName);
|
||||
SaveRules();
|
||||
|
||||
return true;
|
||||
@@ -210,7 +276,7 @@ namespace OutlookCaseHelper
|
||||
}
|
||||
}
|
||||
|
||||
public bool RemoveRuleAndMoveToClosed(string trackingId)
|
||||
public bool RemoveRuleAndMoveToClosed(string folderName)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -224,13 +290,13 @@ namespace OutlookCaseHelper
|
||||
Outlook.Folder? activeFolder = GetFolder(casesFolder, "Active");
|
||||
if (activeFolder == null) return false;
|
||||
|
||||
Outlook.Folder? trackingFolder = GetFolder(activeFolder, trackingId);
|
||||
Outlook.Folder? trackingFolder = GetFolder(activeFolder, folderName);
|
||||
if (trackingFolder == null) return false;
|
||||
|
||||
Outlook.Folder closedFolder = GetOrCreateFolder(casesFolder, "Closed");
|
||||
trackingFolder.MoveTo(closedFolder);
|
||||
|
||||
activeRules.Remove(trackingId);
|
||||
activeRules.Remove(folderName);
|
||||
SaveRules();
|
||||
|
||||
return true;
|
||||
@@ -238,29 +304,47 @@ namespace OutlookCaseHelper
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
public void ProcessActiveRules()
|
||||
{
|
||||
// Mantido para compatibilidade mas os eventos tratam tudo em tempo real
|
||||
}
|
||||
public void ProcessActiveRules() { }
|
||||
|
||||
private Outlook.Folder GetOrCreateFolder(Outlook.Folder parent, string name)
|
||||
{
|
||||
foreach (Outlook.Folder folder in parent.Folders)
|
||||
{
|
||||
if (folder.Name == name)
|
||||
return folder;
|
||||
}
|
||||
if (folder.Name == name) return folder;
|
||||
return (Outlook.Folder)parent.Folders.Add(name);
|
||||
}
|
||||
|
||||
private Outlook.Folder? GetFolder(Outlook.Folder parent, string name)
|
||||
{
|
||||
foreach (Outlook.Folder folder in parent.Folders)
|
||||
if (folder.Name == name) return folder;
|
||||
return null;
|
||||
}
|
||||
|
||||
private Outlook.Folder? GetFolderStartingWith(Outlook.Folder parent, string trackingId)
|
||||
{
|
||||
if (folder.Name == name)
|
||||
foreach (Outlook.Folder folder in parent.Folders)
|
||||
{
|
||||
string name = folder.Name;
|
||||
if (name == trackingId ||
|
||||
name.StartsWith(trackingId + " ") ||
|
||||
name.StartsWith(trackingId + "|"))
|
||||
return folder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Expõe o email selecionado para ser usado no reopen
|
||||
public Outlook.MailItem? GetSelectedEmail()
|
||||
{
|
||||
try
|
||||
{
|
||||
Outlook.Explorer activeExplorer = outlookApp.ActiveExplorer();
|
||||
if (activeExplorer == null) return null;
|
||||
Outlook.Selection selection = activeExplorer.Selection;
|
||||
if (selection.Count == 0) return null;
|
||||
return selection[1] as Outlook.MailItem;
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Reference in New Issue
Block a user