Пример #1
0
 /// <summary>
 /// Gets a Campaign Message Online category by ID.
 /// </summary>
 /// <param name="id">The ID of the category to get.</param>
 /// <returns>The CMO category matching the specified ID if found; otherwise, null.</returns>
 public CmoCategory GetCmoCategory(byte id)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return(CreateCmoCategory(context.CmoCategories.FirstOrDefault(c => c.CategoryId == id)));
     }
 }
Пример #2
0
 /// <summary>
 /// Retrieves all posted messages.
 /// </summary>
 /// <param name="showAllData">true to show all message data; otherwise, false to show only summaric results.</param>
 /// <returns>A collection of all posted messages.</returns>
 public List <CmoMessage> GetCmoPostedMessages(bool showAllData)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return(context.CmoMessages.Where(m => m.PostDate != null).AsEnumerable().Select(m => CreateCmoMessage(m, !showAllData)).ToList());
     }
 }
Пример #3
0
 /// <summary>
 /// Gets a collection of all Campaign Messages Online categories, indexed by category ID.
 /// </summary>
 /// <returns>A collection of all Campaign Messages Online categories, indexed by category ID.</returns>
 public Dictionary <byte, CmoCategory> GetCmoCategories()
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return(context.CmoCategories.ToDictionary(c => c.CategoryId, c => CreateCmoCategory(c)));
     }
 }
Пример #4
0
 /// <summary>
 /// Updates a CMO message instance in the persistence storage medium by overwriting the existing record.
 /// </summary>
 /// <param name="message">The CMO message to update.</param>
 /// <returns>true if the CMO message instance was saved successfuly; otherwise, false.</returns>
 public bool Update(CmoMessage message)
 {
     if (message != null && !message.IsPosted)
     {
         using (Data.CmoEntities context = new Data.CmoEntities())
         {
             var ret = context.CmoSaveMessage(message.CandidateID, message.ID, message.ElectionCycle, message.Title, message.Body, message.Creator, message.OpenReceiptEmail, message.CategoryID, message.Version).FirstOrDefault();
             if (!ret.HasValue || ret.Value != message.ID)
             {
                 return(false);
             }
             // update metadata
             if (!SetCmoMessageAuditReviewNumber(message))
             {
                 return(false);
             }
             if (!SetCmoMessagePostElectionAuditRequestType(message))
             {
                 return(false);
             }
             if (!SetCmoMessageTolling(message))
             {
                 return(false);
             }
         }
         return(true);
     }
     return(false);
 }
Пример #5
0
 /// <summary>
 /// Updates a CMO category instance in the persistence storage medium by overwriting the existing record.
 /// </summary>
 /// <param name="category">The CMO category instance to update.</param>
 /// <returns>true if this instance was saved successfuly; otherwise, false.</returns>
 public bool Update(CmoCategory category)
 {
     if (category != null)
     {
         using (Data.CmoEntities context = new Data.CmoEntities())
         {
             var match = context.CmoCategories.FirstOrDefault(c => c.CategoryId == category.ID);
             if (match != null)
             {
                 match.CategoryName = category.Name;
                 match.Description  = category.Description;
                 match.Hidden       = category.Hidden;
                 if (category.MessageTemplateTitle != null)
                 {
                     match.TemplateTitle = category.MessageTemplateTitle;
                 }
                 if (category.MessageTemplateBody != null)
                 {
                     match.TemplateBody = category.MessageTemplateBody;
                 }
                 match.TemplateEditable = category.MessageTemplateEditable;
                 try
                 {
                     return(context.SaveChanges(SaveOptions.DetectChangesBeforeSave) > 0);
                 }
                 catch (OptimisticConcurrencyException) { }
             }
         }
     }
     return(false);
 }
Пример #6
0
 /// <summary>
 /// Retrieves all posted messages for a single candidate and election cycle.
 /// </summary>
 /// <param name="candidateID">The ID of the candidate to search for.</param>
 /// <param name="electionCycle">The election cycle in which to search.</param>
 /// <returns>A collection of all messages for the specified candidate and election cycle.</returns>
 public List <CmoMessage> GetCmoPostedMessages(string candidateID, string electionCycle = null)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return(context.CmoMessages.Where(m => m.PostDate != null && m.CandidateId == candidateID && (electionCycle == null || m.ElectionCycle == electionCycle)).AsEnumerable().Select(m => CreateCmoMessage(m)).ToList());
     }
 }
Пример #7
0
 /// <summary>
 /// Marks a CMO message as opened.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the candidate recipient of the message to open.</param>
 /// <param name="messageID">The ID of the message to open.</param>
 /// <param name="username">The C-Access username of the user who opened the message.</param>
 /// <param name="version">The version of the message to open.</param>
 /// <returns>true if the message was opened successfully; otherwise, false.</returns>
 public bool OpenCmoMessage(string candidateID, int messageID, string username, byte[] version)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         if (context.CmoMessages.Any(m => m.CandidateId == candidateID && m.MessageId == messageID && m.OpenDate.HasValue))
         {
             return(true);
         }
         var ret = context.CmoOpenMessage(candidateID, messageID, username, version).FirstOrDefault();
         if (ret.HasValue && ret.Value > 0)
         {
             try
             {
                 // send open receipt e-mail
                 using (CmoOpenedMessageReceipt receipt = new CmoOpenedMessageReceipt(GetCmoMessage(candidateID, messageID)))
                 {
                     receipt.LoadCandidate += this.GetCandidate;
                     receipt.Send();
                 }
             }
             catch { }
             return(true);
         }
         return(false);
     }
 }
Пример #8
0
 /// <summary>
 /// Gets a specific Campaign Messages Online message.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the candidate who is the message recipient.</param>
 /// <param name="messageID">The message identifier.</param>
 /// <returns>The requested message if found; otherwise, null.</returns>
 public CmoMessage GetCmoMessage(string candidateID, int messageID)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return(CreateCmoMessage(context.CmoMessages.FirstOrDefault(m => m.CandidateId == candidateID && m.MessageId == messageID)));
     }
 }
Пример #9
0
        /// <summary>
        /// Retrieves messages from a candidate's CMO mailbox.
        /// </summary>
        /// <param name="candidateID">The CFIS ID of the desired candidate.</param>
        /// <param name="view">The mailbox view type.</param>
        /// <param name="elections">A collection of election cycles to filter against.</param>
        /// <returns>A collection of <see cref="CmoMessage"/> objects for the specified mailbox sorted according to the properties of the mailbox.</returns>
        public List <CmoMessage> GetMailboxMessages(string candidateID, CmoMailboxView view, HashSet <string> elections)
        {
            using (Data.CmoEntities context = new Data.CmoEntities())
            {
                IQueryable <Data.CmoMessage> matches = context.CmoMessages.Where(m => m.PostDate.HasValue && m.CandidateId == candidateID);
                switch (view)
                {
                case CmoMailboxView.All:
                    break;

                case CmoMailboxView.Archived:
                    matches = matches.Where(m => m.ArchiveDate.HasValue);
                    break;

                case CmoMailboxView.FollowUp:
                    matches = matches.Where(m => m.FollowUp);
                    break;

                case CmoMailboxView.Unopened:
                    matches = matches.Where(m => !m.OpenDate.HasValue);
                    break;

                case CmoMailboxView.Current:
                default:
                    matches = matches.Where(m => !m.ArchiveDate.HasValue);
                    break;
                }
                if (elections != null && elections.Count > 0)
                {
                    matches = matches.Where(m => elections.Contains(m.ElectionCycle));
                }
                return(matches.AsEnumerable().Select(m => CreateCmoMessage(m)).ToList());
            }
        }
Пример #10
0
 /// <summary>
 /// Retrieves an attachment.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the candidate the attachment is for.</param>
 /// <param name="messageID">The ID of the message the attachment is for.</param>
 /// <param name="id">The ID of the attachment to retrieve.</param>
 /// <returns>A <see cref="CmoAttachment"/> instance that matches the specified criteria if found; otherwise, null.</returns>
 public CmoAttachment GetCmoAttachment(string candidateID, int messageID, byte id)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return(CreateCmoAttachment(context.CmoAttachments.FirstOrDefault(a => a.CandidateId == candidateID && a.MessageId == messageID && a.AttachmentId == id)));
     }
 }
Пример #11
0
        /// <summary>
        /// Deletes a CMO message from the persistence storage medium.
        /// </summary>
        /// <param name="candidateID">The CFIS ID of the candidate recipient of the message to delete.</param>
        /// <param name="messageID">The ID of the message to delete.</param>
        /// <param name="version">The version of the message to update.</param>
        /// <returns>true if the CMO message instance was deleted successfully; otherwise, false.</returns>
        public bool Delete(string candidateID, int messageID, byte[] version)
        {
            using (Data.CmoEntities context = new Data.CmoEntities())
            {
                var msg = context.CmoMessages.FirstOrDefault(m => m.CandidateId == candidateID && m.MessageId == messageID && m.Version == version && !m.PostDate.HasValue);
                if (msg != null)
                {
                    // delete attachments first
                    foreach (var a in msg.CmoAttachments)
                    {
                        if (!Delete(GetCmoAttachment(candidateID, messageID, a.AttachmentId)))
                        {
                            return(false);
                        }
                    }

                    context.DeleteObject(msg);
                    try
                    {
                        if (context.SaveChanges() > 0)
                        {
                            return(true);
                        }
                    }
                    catch (OptimisticConcurrencyException) { }
                }
            }
            return(false);
        }
Пример #12
0
 /// <summary>
 /// Gets the unique message ID for a specific payment letter's corresponding CMO message.
 /// </summary>
 /// <param name="candidateID">The ID of the candidate context.</param>
 /// <param name="paymentRun">The payment run number.</param>
 /// <returns>The unique ID of the CMO message for the specified payment run if found; otherwise, null.</returns>
 public string GetPaymentMessageID(string candidateID, byte paymentRun)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         var message = context.CmoMessages.OrderByDescending(m => m.PostDate).FirstOrDefault(m => m.CandidateId == candidateID && m.PostDate.HasValue && m.CmoAuditReview.ReviewNumber == paymentRun);
         return(message == null ? null : CmoMessage.ToUniqueID(message.CandidateId, message.MessageId));
     }
 }
Пример #13
0
 /// <summary>
 /// Creates a new Campaign Messages Online message and adds it to the persistence storage medium.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the message recipient candidate.</param>
 /// <param name="electionCycle">The message election cycle context.</param>
 /// <param name="title">The message title.</param>
 /// <param name="body">The message body.</param>
 /// <param name="creator">The internal username of the message creator.</param>
 /// <param name="openReceiptEmail">The receipient address for an open receipt e-mail.</param>
 /// <param name="categoryID">The message category ID.</param>
 /// <returns>A new <see cref="CmoMessage"/> object if the message was added successfully; otherwise, null.</returns>
 public CmoMessage AddCmoMessage(string candidateID, string electionCycle, string title, string body, string creator, string openReceiptEmail, byte categoryID)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         var ret = context.CmoSaveMessage(candidateID, byte.MinValue, electionCycle, title, body, creator, openReceiptEmail, categoryID, new byte[] { }).FirstOrDefault();
         return(ret.HasValue && ret.Value > 0 ? CreateCmoMessage(context.CmoMessages.Where(m => m.CandidateId == candidateID && m.MessageId == ret.Value).FirstOrDefault()) : null);
     }
 }
Пример #14
0
 /// <summary>
 /// Sets the message's follow-up flag status.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the candidate recipient of the message to update.</param>
 /// <param name="messageID">The ID of the message to update.</param>
 /// <param name="flagged">true if the message flag is to be set; otherwise, false to clear the flag.</param>
 /// <param name="username">The C-Access username of the user changing the flag.</param>
 /// <param name="version">The version of the message to update.</param>
 /// <returns>true if the flag change was saved successfully; otherwise, false.</returns>
 public bool SetCmoMessageFlagStatus(string candidateID, int messageID, bool flagged, string username, byte[] version)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         var ret = context.CmoFollowUpMessage(candidateID, messageID, username, flagged, version).FirstOrDefault();
         return(ret.HasValue && ret.Value > 0);
     }
 }
Пример #15
0
 /// <summary>
 /// Retrieves a collection of the usernames of all users who have created messages, mapped to their respective full names.
 /// </summary>
 /// <returns>A collection of the useranmes of all users who have created messages, mapped to their respective full names.</returns>
 public Dictionary <string, string> GetCmoMessageCreators()
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return((from m in context.CmoMessages
                 where m != null
                 select m.CreatorADUserName).Distinct().ToDictionary(n => n, n => CfbDirectorySearcher.GetUser(n).DisplayName ?? n));
     }
 }
Пример #16
0
        /// <summary>
        /// Sets the tolling information for a tolling letter CMO message.
        /// </summary>
        /// <param name="message">The CMO message to update.</param>
        /// <returns>true if the tolling information was set or cleared successfully; otherwise, false.</returns>
        /// <remarks>The tolling information can only be successfully set if the message is a tolling letter and cleared if the message is not a tolling letter. The information will automatically be cleared for messages that are not tolling letters regardless of the message's tolling values.</remarks>
        private bool SetCmoMessageTolling(CmoMessage message)
        {
            if (message == null)
            {
                return(false);
            }

            string        candidateID = message.CandidateID;
            int           messageID   = message.ID;
            TollingLetter letter      = message.TollingLetter;

            if (message.IsInadequateResponseLetter)
            {
                // force interpretation of inadequate response letters as tolling letters
                if (letter == null)
                {
                    letter = message.TollingLetter = GetTollingLetter(CPConvert.ToCfisCode(AuditReportType.IdrInadequateResponse), message.IsIdrAdditionalInadequateLetter || message.IsDarAdditionalInadequateLetter ? "ADDINA" : "INARES", "INAD");
                }
                if (!message.TollingEventNumber.HasValue)
                {
                    message.TollingEventNumber = int.MinValue;
                }
            }
            bool hasTolling = message.TollingEventNumber.HasValue && letter != null;
            bool isTolling  = message.IsTollingLetter;

            using (Data.CmoEntities context = new Data.CmoEntities())
            {
                var tl = context.CmoTollingLetters.FirstOrDefault(l => l.CandidateId == message.CandidateID && l.MessageId == message.ID);
                if (tl != null)
                {
                    if (isTolling)
                    {
                        tl.EventNumber = message.TollingEventNumber ?? int.MinValue;
                    }
                    else
                    {
                        context.DeleteObject(tl);
                    }
                }
                else if (isTolling)
                {
                    context.AddToCmoTollingLetters(Data.CmoTollingLetter.CreateCmoTollingLetter(candidateID, messageID, message.TollingEventNumber ?? int.MinValue, letter.ID));
                }
                try
                {
                    int updates = context.SaveChanges();
                    return(isTolling ? updates > 0 : !hasTolling);
                }
                catch (OptimisticConcurrencyException)
                {
                    return(false);
                }
            }
        }
Пример #17
0
 /// <summary>
 /// Gets the total number of unread messages in a candidate's CMO mailbox.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the desired candidate.</param>
 /// <param name="elections">A collection of election cycles to filter against.</param>
 /// <returns>The total number of unread messges in the specified candidate's mailbox.</returns>
 public uint CountUnopenedMailboxMessages(string candidateID, HashSet <string> elections)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         var messages = context.CmoMessages.Where(m => m.CandidateId == candidateID && m.PostDate.HasValue && !m.OpenDate.HasValue);
         if (elections != null && elections.Count > 0)
         {
             messages = messages.Where(m => elections.Contains(m.ElectionCycle));
         }
         return(Convert.ToUInt32(messages.Count()));
     }
 }
Пример #18
0
 /// <summary>
 /// Searches for all messages matching the specified criteria.
 /// </summary>
 /// <param name="candidateID">A ID of the candidate to search for.</param>
 /// <param name="electionCycle">An election cycle to search for.</param>
 /// <param name="creator">A message creator username to search for.</param>
 /// <param name="category">A message category to search for.</param>
 /// <param name="title">A message title pattern to match against.</param>
 /// <param name="body">A message body pattern to match against.</param>
 /// <param name="postedStart">A posted date range filter start date.</param>
 /// <param name="postedEnd">A posted date range filter end date.</param>
 /// <param name="opened">A message opened status to search for.</param>
 /// <param name="hasAttachments">A message attachment presence to search for.</param>
 /// <returns>A collection of all messages matching the search criteria.</returns>
 public List <CmoMessage> FindCmoMessages(string candidateID, string electionCycle, string creator, byte?category, string title, string body, DateTime?postedStart, DateTime?postedEnd, bool?opened, bool?hasAttachments)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         IQueryable <Data.CmoMessage> results = context.CmoMessages;
         if (candidateID != null)
         {
             results = results.Where(m => m.CandidateId == candidateID);
         }
         if (electionCycle != null)
         {
             results = results.Where(m => m.ElectionCycle == electionCycle);
         }
         if (creator != null)
         {
             results = results.Where(m => m.CreatorADUserName == creator);
         }
         if (category.HasValue)
         {
             results = results.Where(m => m.CmoCategory.CategoryId == category.Value);
         }
         if (title != null)
         {
             results = results.Where(m => m.Title != null && m.Title.Contains(title));
         }
         if (body != null)
         {
             results = results.Where(m => m.Body != null && m.Body.Contains(body));
         }
         if (postedStart.HasValue || postedEnd.HasValue)
         {
             results = results.Where(m => m.PostDate.HasValue);
         }
         if (postedStart.HasValue)
         {
             results = results.Where(m => EntityFunctions.TruncateTime(postedStart) <= m.PostDate);
         }
         if (postedEnd.HasValue)
         {
             results = results.Where(m => EntityFunctions.TruncateTime(m.PostDate) <= EntityFunctions.TruncateTime(postedEnd));
         }
         if (opened.HasValue)
         {
             results = results.Where(m => m.OpenDate.HasValue == opened.Value);
         }
         if (hasAttachments.HasValue)
         {
             results = hasAttachments.Value ? results.Where(m => m.CmoAttachments.Count > 0) : results.Where(m => m.CmoAttachments.Count == 0);
         }
         return(results.AsEnumerable().Select(m => CreateCmoMessage(m, true)).ToList());
     }
 }
Пример #19
0
 /// <summary>
 /// Gets a collection of IDs for all post election audit tolling messages for a specific candidate and election cycle.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the reviewed candidate.</param>
 /// <param name="electionCycle">The election cycle of the reviews.</param>
 /// <param name="far">true to specify Final Audit Report tolling; otherwise, false to specify Draft Audit Report tolling.</param>
 /// <returns>A collection of unique IDs for all tolling event CMO messages found, indexed by tolling event ID.</returns>
 public Dictionary <int, string> GetTollingMessageIDs(string candidateID, string electionCycle, bool far)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         var letters = GetTollingLetters();
         Dictionary <int, string> ids = new Dictionary <int, string>();
         foreach (var evt in context.CmoGetCandidateTollingEvents(candidateID, electionCycle, far))
         {
             ids[letters.Any(l => l.ID == evt.LetterId && l.IsInadequate) ? -evt.EventNumber : evt.EventNumber] = CmoMessage.ToUniqueID(candidateID, evt.MessageId);
         }
         return(ids);
     }
 }
Пример #20
0
 /// <summary>
 /// Gets a collection of IDs for all audit review messages for a specific candidate and election cycle.
 /// </summary>
 /// <param name="reviewCategoryID">The category ID of the desired audit review type.</param>
 /// <param name="candidateID">The CFIS ID of the reviewed candidate.</param>
 /// <param name="electionCycle">The election cycle of the reviews.</param>
 /// <returns>A collection of unique IDs for all audit review CMO messages found.</returns>
 private Dictionary <byte, string> GetAuditReviewMessageIDs(byte reviewCategoryID, string candidateID, string electionCycle)
 {
     if (!new[] { CmoCategory.StatementReviewCategoryID, CmoCategory.ComplianceVisitCategoryID, CmoCategory.DoingBusinessReviewCategoryID }.Contains(reviewCategoryID))
     {
         return(new Dictionary <byte, string>(0));
     }
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         return((from m in context.CmoMessages
                 join r in context.CmoAuditReviews
                 on new { m.CandidateId, m.MessageId } equals new { r.CandidateId, r.MessageId }
                 where m.PostDate.HasValue && m.CandidateId == candidateID && m.ElectionCycle == electionCycle && m.CmoCategory.CategoryId == reviewCategoryID
                 group r by r.ReviewNumber into rgroup
                 select new { ReviewNumber = rgroup.Key, MessageID = rgroup.Max(r => r.MessageId) }).ToDictionary(r => r.ReviewNumber, r => CmoMessage.ToUniqueID(candidateID, r.MessageID)));
     }
 }
Пример #21
0
 /// <summary>
 /// Deletes a CMO category instance from the persistence storage medium.
 /// </summary>
 /// <param name="category">The CMO category instance to update.</param>
 /// <returns>true if this instance was deleted successfully; otherwise, false.</returns>
 public bool Delete(CmoCategory category)
 {
     if (category != null)
     {
         using (Data.CmoEntities context = new Data.CmoEntities())
         {
             var match = context.CmoCategories.FirstOrDefault(c => c.CategoryId == category.ID);
             if (match != null)
             {
                 context.DeleteObject(match);
                 return(true);
             }
         }
     }
     return(false);
 }
Пример #22
0
 /// <summary>
 /// Updates a CMO message attachment instance in the persistence storage medium by overwriting the existing record.
 /// </summary>
 /// <param name="attachment">The CMO message attachment to update.</param>
 /// <returns>true if this instance was saved successfuly; otherwise, false.</returns>
 public bool Update(CmoAttachment attachment)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         var data = context.CmoAttachments.FirstOrDefault(a => a.CandidateId == attachment.CandidateID && a.MessageId == attachment.MessageID && a.AttachmentId == attachment.ID);
         if (data != null)
         {
             data.AttachmentName = attachment.FileName;
             try
             {
                 return(context.SaveChanges() > 0);
             }
             catch (OptimisticConcurrencyException) { }
         }
         return(false);
     }
 }
Пример #23
0
        /// <summary>
        /// Sets the post election audit request type for an audit review CMO message.
        /// </summary>
        /// <param name="message">The CMO message to update.</param>
        /// <returns>true if the type was set or cleared successfully; otherwise, false.</returns>
        /// <remarks>The post election audit request type can only be successfully set if the message is a post election audit request and cleared if the message is not a post election audit request. The type will automatically be cleared for messages that are not post election audit requests regardless of the value in <paramref name="message"/>.</remarks>
        private bool SetCmoMessagePostElectionAuditRequestType(CmoMessage message)
        {
            if (message == null)
            {
                return(false);
            }
            AuditRequestType?type           = message.PostElectionAuditRequestType;
            bool             hasRequestType = type.HasValue;
            bool             isPea          = message.IsPostElectionAudit && hasRequestType;
            bool             isRepost       = hasRequestType && (type == AuditRequestType.FirstRepost || type == AuditRequestType.SecondRepost);
            bool             isSecond       = hasRequestType && (type == AuditRequestType.SecondRepost || type == AuditRequestType.SecondRequest);

            using (Data.CmoEntities context = new Data.CmoEntities())
            {
                var request = context.CmoPostElectionRequests.FirstOrDefault(r => r.CandidateId == message.CandidateID && r.MessageId == message.ID);
                if (request != null)
                {
                    // update or delete existing row
                    if (isPea)
                    {
                        request.Repost        = isRepost;
                        request.SecondRequest = isSecond;
                    }
                    else
                    {
                        // always delete row if not a request, but return true only if there is no longer a request type
                        context.DeleteObject(request);
                    }
                }
                else if (isPea)
                {
                    // no post election audit request entries were found, so try to add a new one if applicable
                    context.AddToCmoPostElectionRequests(Data.CmoPostElectionRequest.CreateCmoPostElectionRequest(message.CandidateID, message.ID, isRepost, isSecond));
                }
                try
                {
                    int updates = context.SaveChanges();
                    return(isPea ? updates > 0 : !hasRequestType);
                }
                catch (OptimisticConcurrencyException)
                {
                    return(false);
                }
            }
        }
Пример #24
0
 /// <summary>
 /// Gets a collection of IDs for all post election audit reports for a specific candidate and election cycle.
 /// </summary>
 /// <param name="candidateID">The CFIS ID of the reviewed candidate.</param>
 /// <param name="electionCycle">The election cycle of the reviews.</param>
 /// <returns>A collection of unique IDs for all post election audit report CMO messages found.</returns>
 public Dictionary <AuditReportType, string> GetAuditReportMessageIDs(string candidateID, string electionCycle)
 {
     using (Data.CmoEntities context = new Data.CmoEntities())
     {
         var categories = new List <byte> {
             CmoCategory.IdrCategoryID, CmoCategory.IdrInadequateCategoryID, CmoCategory.IdrAdditionalInadequateCategoryID, CmoCategory.DarCategoryID, CmoCategory.DarInadequateCategoryID, CmoCategory.DarAdditionalInadequateCategoryID, CmoCategory.FarCategoryID
         };
         var messages = from m in context.CmoMessages
                        join c in context.CmoCategories
                        on m.CmoCategory.CategoryId equals c.CategoryId
                        where m.CandidateId == candidateID && m.ElectionCycle == electionCycle && m.PostDate.HasValue && categories.Contains(m.CmoCategory.CategoryId)
                        group m by m.CmoCategory.CategoryId into mgroup
                        select new { CategoryID = mgroup.Key, MessageID = mgroup.Max(m => m.MessageId) };
         return((from m in messages.AsEnumerable().Select(m => new { AuditReportType = CmoCategory.ToAuditReportType(m.CategoryID), m.MessageID })
                 where m.AuditReportType.HasValue
                 select m).ToDictionary(m => m.AuditReportType.Value, m => CmoMessage.ToUniqueID(candidateID, m.MessageID)));
     }
 }
Пример #25
0
        /// <summary>
        /// Retrieves a history of public funds determinations for a specific candidate and election cycle.
        /// </summary>
        /// <param name="candidateID">The ID of the candidate whose public funds determination history is to be retrieved.</param>
        /// <param name="electionCycle">The election cycle in which to search.</param>
        /// <returns>A history of public funds determinations for the specified candidate and election cycle.</returns>
        public PublicFundsHistory GetPublicFundsHistory(string candidateID, string electionCycle)
        {
            // retrieve CMO message IDs
            using (Data.CmoEntities context = new Data.CmoEntities())
            {
                var messages = from m in context.CmoMessages
                               join p in context.CmoAuditReviews
                               on new { m.CandidateId, m.MessageId } equals new { p.CandidateId, p.MessageId }
                where m.CandidateId == candidateID && m.ElectionCycle == electionCycle && m.PostDate.HasValue
                group p by p.ReviewNumber into pgroup
                select new { Run = pgroup.Key, MessageID = pgroup.Max(p => p.MessageId) };

                // retrieve payment records
                using (PaymentPlanTds ds = new PaymentPlanTds())
                {
                    PaymentPlanTds.PublicFundsHistoryDataTable table = ds.PublicFundsHistory;
                    using (PublicFundsHistoryTableAdapter ta = new PublicFundsHistoryTableAdapter())
                    {
                        ta.Fill(table, candidateID, electionCycle);
                    }
                    PublicFundsHistory history = new PublicFundsHistory(table.Count);
                    foreach (PaymentPlanTds.PublicFundsHistoryRow row in table)
                    {
                        PublicFundsDetermination payment = new PublicFundsDetermination(row.Date, row.Amount > 0)
                        {
                            ElectionType  = CPConvert.ToElectionType(row.ElectionTypeCode.Trim()),
                            PaymentAmount = row.Amount,
                            PaymentMethod = string.IsNullOrEmpty(row.CheckNumber.Trim()) ? PaymentMethod.Eft : PaymentMethod.Check,
                            Run           = row.Run
                        };
                        // associate message ID if found
                        var message = messages.FirstOrDefault(m => m.Run == row.Run);
                        if (message != null)
                        {
                            payment.MessageID = message.MessageID;
                        }
                        history.Determinations.Add(payment);
                    }
                    return(history);
                }
            }
        }
Пример #26
0
        /// <summary>
        /// Sets the audit review number for an audit review CMO message.
        /// </summary>
        /// <param name="message">The CMO message to update.</param>
        /// <returns>true if the number was set or cleared successfully; otherwise, false.</returns>
        /// <remarks>The audit review number can only be successfully set if the message is an audit review and cleared if the message is not an audit review. The number will automatically be cleared for messages that are not audit reviews regardless of the message's review number value.</remarks>
        private bool SetCmoMessageAuditReviewNumber(CmoMessage message)
        {
            if (message == null)
            {
                return(false);
            }
            bool hasNumber = message.AuditReviewNumber.HasValue;
            bool isReview  = message.IsAuditReview && hasNumber;

            using (Data.CmoEntities context = new Data.CmoEntities())
            {
                var review = context.CmoAuditReviews.FirstOrDefault(r => r.CandidateId == message.CandidateID && r.MessageId == message.ID);
                if (review != null)
                {
                    // update or delete existing row
                    if (isReview)
                    {
                        review.ReviewNumber = message.AuditReviewNumber.Value;
                    }
                    else
                    {
                        // always delete row if not audit review, but return true only if there is no longer a review number
                        context.DeleteObject(review);
                    }
                }
                else if (isReview)
                {
                    // no audit review entries were found, so try to add a new one if applicable
                    context.AddToCmoAuditReviews(Data.CmoAuditReview.CreateCmoAuditReview(message.CandidateID, message.ID, message.AuditReviewNumber.Value));
                }
                try
                {
                    int updates = context.SaveChanges();
                    return(isReview ? updates > 0 : !hasNumber);
                }
                catch (OptimisticConcurrencyException)
                {
                    return(false);
                }
            }
        }
Пример #27
0
        /// <summary>
        /// Adds an attachment to a CMO message.
        /// </summary>
        /// <param name="candidateID">The CFIS ID of the candidate the attachment is for.</param>
        /// <param name="messageID">The ID of the targeted message.</param>
        /// <param name="name">The attachment file name to be used for display.</param>
        /// <param name="saveAttachment">The delegate method to use for saving the attachment.</param>
        /// <returns>A <see cref="CmoAttachment"/> that represents the newly added attachment.</returns>
        private CmoAttachment AddCmoAttachment(string candidateID, int messageID, string name, SaveAttachmentEventHandler saveAttachment)
        {
            CmoMessage owner = GetCmoMessage(candidateID, messageID);

            if ((owner != null) && (CmoRepository.Repository != null))
            {
                using (Data.CmoEntities context = new Data.CmoEntities())
                {
                    var  ret = context.CmoSaveAttachment(candidateID, messageID, byte.MinValue, name).FirstOrDefault();
                    byte id;
                    if (ret.HasValue && byte.TryParse(ret.Value.ToString(), out id) && id > byte.MinValue)
                    {
                        CmoAttachment attachment = new CmoAttachment(candidateID, messageID, id);
                        attachment.FileName = name;
                        try
                        {
                            if (saveAttachment != null && saveAttachment(attachment))
                            {
                                return(attachment);
                            }
                            else
                            {
                                // rollback attachment if it could not be saved
                                CmoRepository.Repository.Delete(attachment);
                                Delete(attachment);
                            }
                        }
                        catch (Exception e)
                        {
                            // rollback attachment if it could not be saved
                            CmoRepository.Repository.Delete(attachment);
                            Delete(attachment);
                            throw e;
                        }
                    }
                }
            }
            return(null);
        }
Пример #28
0
 /// <summary>
 /// Deletes a CMO message attachment instance from the persistence storage medium.
 /// </summary>
 /// <param name="attachment">The CMO message attachment to delete.</param>
 /// <returns>true if this instance was deleted successfully; otherwise, false.</returns>
 public bool Delete(CmoAttachment attachment)
 {
     if (attachment != null)
     {
         using (Data.CmoEntities context = new Data.CmoEntities())
         {
             var data = context.CmoAttachments.FirstOrDefault(a => a.CandidateId == attachment.CandidateID && a.MessageId == attachment.MessageID && a.AttachmentId == attachment.ID);
             if (data != null)
             {
                 context.DeleteObject(data);
                 try
                 {
                     return(CmoRepository.Repository != null && context.SaveChanges() > 0 && CmoRepository.Repository.Delete(attachment));
                 }
                 catch (OptimisticConcurrencyException)
                 {
                     return(false);
                 }
             }
         }
     }
     return(true);
 }
Пример #29
0
        /// <summary>
        /// Posts a CMO message for viewing by C-Access accounts and .
        /// </summary>
        /// <param name="candidateID">The CFIS ID of the candidate recipient of the message to post.</param>
        /// <param name="messageID">The ID of the message to post.</param>
        /// <param name="version">The version of the message to post.</param>
        /// <param name="notify">true if posted message notifications should be sent; otherwise, false.</param>
        /// <returns>true if the message was succesfully posted; otherwise, false.</returns>
        /// <remarks>For Post Election Audit messages, posting will fail if the CFIS dates were unsuccessfully updated, the post election audit workflow would be disrupted, or a response was already received.</remarks>
        public bool PostCmoMessage(string candidateID, int messageID, byte[] version, bool notify)
        {
            CmoMessage message = GetCmoMessage(candidateID, messageID);

            if (message != null)
            {
                if (!message.IsPosted)
                {
                    if (RequiresPostElectionDateUpdate(message))
                    {
                        // check for post election audit workflow violation
                        AuditReportBase pear = null;
                        if (message.IsInitialDocumentationRequest)
                        {
                            pear = GetInitialDocumentationRequest(candidateID, message.ElectionCycle, false);
                        }
                        else if (message.IsIdrInadequateResponseLetter)
                        {
                            pear = GetIdrInadequateEvent(candidateID, message.ElectionCycle, false);
                        }
                        else if (message.IsDraftAuditReport)
                        {
                            pear = GetDraftAuditReport(candidateID, message.ElectionCycle, false);
                        }
                        if (pear != null && (pear.ResponseReceived || !HasValidPostElectionRequestType(message, pear.IsSecondRequest)))
                        {
                            return(false);
                        }

                        // update CFIS dates for post election audit messages
                        if (!UpdatePostElectionDates(message))
                        {
                            return(false);
                        }
                    }
                    using (Data.CmoEntities context = new Data.CmoEntities())
                    {
                        var ret = context.CmoPostMessage(candidateID, messageID, version).FirstOrDefault();
                        if (ret.HasValue && ret.Value > 0)
                        {
                            // secure all attachments
                            if ((CmoRepository.Repository != null) && message.HasAttachment)
                            {
                                CmoRepository.Repository.LockDown(message);
                            }
                            message.Reload();

                            // send notification
                            if (notify)
                            {
                                // BUGFIX #60: To prevent timeout of long-running email notification operations, failed recipient notification
                                // will be included in the internal carbon-copy, and sending will be executed asynchronously.
                                Func <CmoMessage, LoadCandidateEventHandler, IEnumerable <CPUser>, bool> notifyAsync = CmoPostedMessageNotice.SendFor;
                                notifyAsync.BeginInvoke(message, this.GetCandidate, null, null, null);
                            }

                            return(true);
                        }
                    }
                }
            }
            return(false);
        }