Patch to add References and In-Reply-To parsing and handling to OTRS.

   Created 2004-01-09 by Petter Reinholdtsen <pere@hungry.com>

--- Kernel/Config/Defaults.pm.orig	2003-07-13 21:23:21.000000000 +0200
+++ Kernel/Config/Defaults.pm	2004-01-09 15:21:43.000000000 +0100
@@ -714,6 +714,8 @@
       'Mailing-List',
       'X-Loop',
       'X-No-Loop',
+      'References',
+      'In-Reply-To',
       'X-OTRS-Loop',
       'X-OTRS-Info',
       'X-OTRS-Priority',
--- Kernel/System/PostMaster.pm.orig	2003-06-22 20:37:36.000000000 +0200
+++ Kernel/System/PostMaster.pm	2004-01-09 16:57:48.000000000 +0100
@@ -221,23 +221,91 @@
     my $Self = shift;
     my %Param = @_;
     my $Subject = $Param{Subject} || '';
-    if (my $Tn = $Self->{TicketObject}->GetTNByString($Subject)) {
-        my $TicketID = $Self->{TicketObject}->CheckTicketNr(Tn => $Tn);
+    my $Tn;
+    my $TicketID;
+    if ($Tn = $Self->{TicketObject}->GetTNByString($Subject)) {
+        $TicketID = $Self->{TicketObject}->CheckTicketNr(Tn => $Tn);
         if ($Self->{Debug} > 1) {
             $Self->{LogObject}->Log(
                 Priority => 'debug',
                 Message => "CheckFollowUp: Tn: $Tn found or forward!",
             );
         }
-        if ($TicketID) {
-            if ($Self->{Debug} > 1) {
-                $Self->{LogObject}->Log(
+    } else {
+	# Based on info from <URL:http://www.jwz.org/doc/threading.html>
+	my @msgids = ();
+
+	# Extract Message-id(s) from References and In-Reply-to
+	my $references = $Param{References};
+	my $inreplyto = $Param{'In-Reply-To'}; # XXX Check capitalisation
+
+	push(@msgids, split(/\s+/, $references)) if ($references);
+
+	if ($inreplyto) {
+	    if ($inreplyto =~ m/(<[^>]+>)/) {
+		push(@msgids, $1);
+	    } else {
+		$Self->{LogObject}->Log(
+		      Priority => 'debug',
+		      Message  => "CheckFollowUp: Unhandled In-Reply-To: '$inreplyto'",
+		    );
+	    }
+	}
+	
+	# Look up Message-id(s) using Article::ArticleMsgIdLookup
+	my @ids = ();
+	my %checked;
+	my $msgid;
+	for $msgid (@msgids) {
+	    next if $checked{$msgid};
+	    my @ArticleIDs =
+		$Self->{TicketObject}->ArticleMsgIdLookup(MessageID => $msgid);
+            my @TicketIDs;
+	    my $aid;
+            for $aid (@ArticleIDs) {
+                my %data =
+                   $Self->{TicketObject}->GetArticle(ArticleID => $aid);
+                my $tn = $Self->{TicketObject}->GetTNOfId(ID => $data{TicketID});
+                push(@TicketIDs, $tn);
+            }
+	    push(@ids, @TicketIDs) if (@TicketIDs);
+	    $checked{$msgid} = 1;
+	}
+
+	# Reduce list of IDs to unique IDs only
+	my $id;
+	my %idhash;
+	for $id (sort @ids) {
+	    $idhash{$id} = 1;
+	}
+	@ids = sort keys %idhash;
+
+	# If the Message-id(s) are already in the database, use their
+	# ticked-id
+	if (1 < @ids) {
+	    if ($Self->{Debug} > 1) {
+		$Self->{LogObject}->Log(
+		      Priority => 'debug',
+		      Message => "CheckFollowUp: Several possible ticket ids",
+		    );
+	    }
+	}
+
+	# Just pick the first.  Not sure how we should handle several
+	# ticket ids
+	if (@ids) {
+	    $Tn = $ids[0];
+	    $TicketID = $Self->{TicketObject}->CheckTicketNr(Tn => $Tn);
+	}
+    }
+    if ($TicketID) {
+	if ($Self->{Debug} > 1) {
+	    $Self->{LogObject}->Log(
                   Priority => 'debug',
-                  Message => "CheckFollowUp: ja, it's a follow up ($Tn/$TicketID)",
+                  Message => "CheckFollowUp: yes, it's a follow up ($Tn/$TicketID)",
                 );
-            }
-            return ($Tn, $TicketID);
-        }
+	}
+	return ($Tn, $TicketID);
     }
     return;
 }
--- Kernel/System/Ticket/Article.pm.orig	2003-06-19 00:40:35.000000000 +0200
+++ Kernel/System/Ticket/Article.pm	2004-01-09 15:21:15.000000000 +0100
@@ -621,5 +621,35 @@
     return %Data;
 }
 # --
+sub ArticleMsgIdLookup {
+    my $Self = shift;
+    my %Param = @_;
+    my @Index = (); 
+    # --
+    # check needed stuff
+    # --
+    if (!$Param{MessageID}) {
+      $Self->{LogObject}->Log(Priority => 'error', Message => "Need MessageID!");
+      return;
+    }
+    # --
+    # sql query
+    # --
+    my $SQL = "SELECT id" .
+        " FROM " .
+        " article " .
+        " WHERE " .
+        " a_message_id = '$Param{MessageID}' " .
+	" ORDER BY incoming_time";
+    $Self->{DBObject}->Prepare(SQL => $SQL);
+    while (my @Row = $Self->{DBObject}->FetchrowArray()) {
+        push (@Index, $Row[0]);
+    }
+    # --
+    # return data
+    # --
+    return @Index; 
+}
+# --
 
 1;
