Compare Linq / SQL compares the unique identifier from the previous / next month to consider continuous

EDIT # 2 * This issue arose as execs want more from this report. Basically, we have a monthly subscription. We want to see by months who joined (seeing when the first payment was made), then who did not make the payment (left), but made a month ago. Now a change has been made, it is also shown whether someone was “reactivated” (left and then returned) and “deactivated”. I solved the problem by writing a rather complicated program, but I have a feeling that some smart one there can tell me an easier way (since it is rather slow).

I need in the near future to filter the initial results by fields in the "Tags" table, which has a list of "tags", the contact with which they are associated, and the date when they are applied. Basically, I will need to connect to the contact table by contacting the date in the tag table, and then request the payment table, as the code below does. Thus, I can see everyone who has been noted in history for the last month throughout the program.

Thanks for the help!

Tables
[Contacts]         [Added Tags]
*Contact Id         Contact Id
                    Tag   
[Payments]          Date Added
*Invoice Id
Contact Id
Date
Pay Type
Pay Amt

And code

public static int CalculateMonthDifference(DateTime startDate, DateTime endDate)
{
int monthsApart = 12 * (startDate.Year - endDate.Year) + startDate.Month - endDate.Month;
return Math.Abs(monthsApart);
}

public static int WriteLinez(int contactId, int monthx, int yearx, int concmos, int concmosreact, bool firstmonth, bool lastmonth, bool reactivated, bool deactivated, StreamWriter sw)
{
Console.WriteLine(contactId + "," + monthx + "/1/" + yearx + "," + concmos +"," + concmosreact  + "," + firstmonth + "," + lastmonth+ "," + reactivated + "," + deactivated);
sw.WriteLine(contactId + "," + monthx + "/1/" + yearx + "," + concmos +"," + concmosreact  + "," + firstmonth + "," + lastmonth+ "," + reactivated + "," + deactivated);
return 1;
}
void Main()
{
        StreamWriter sw = new StreamWriter(@"c:\Users\eboney\Desktop\TestFile.txt");
        //var csvoutput = new wr
        sw.WriteLine("contactId,month,concmos,concmosreact,firstmonth,lastmonth,reactivated,deactivated");
        //AddedTags.Select (atc => atc.ContactId=p.ContactId);
        var query2 =
        from p in Payments//, atc in AddedTags
        where (p.Products == "c30" || p.Products == "c3") && p.PayType != "Credit" && p.PayType != "Adjustment"  
            && p.PayAmt > 0 
        group p by p.ContactId into contactGroup
        // p."Contact Id" ascending
        select new
        {
            Contact = contactGroup.Key,
            Dates = 
                from yg in contactGroup
                group yg.Date by yg.Date.Value into dateGroup
                select new
                {
                    Datex = dateGroup.Key
                }
        };



    //arrayquery.Dump();
query2.OrderByDescending (q => q.Contact);



foreach(var contact in query2)
{
    //declarations and reset variables
    int contactId = contact.Contact;
    int x = contact.Dates.Count();
    int prevmonthDiff = 0;
    int nextmonthDiff = 0;
    int concurrentmos = 1;
    int concurrentmosreact = 0;
    bool firstmo = true;
    bool lastmo = false;
    bool reactflag = false;
    reactflag = false;
    bool reactivated = false;
    bool deactivated = false;
    DateTime prevdate = new DateTime();
    DateTime currentdate = new DateTime();
    DateTime nextdate = new DateTime();
    int monthat = contact.Dates.ElementAt(0).Datex.Month;
    int yearat = contact.Dates.ElementAt(0).Datex.Year;
    //loop through and process dates
    for ( int i = 0; i < x; i++ )
    {
        firstmo = false;
        lastmo = false;
        reactivated = false;
        deactivated = false;

        currentdate = contact.Dates.ElementAt(i).Datex;
        ///// DUPE CHECK ////
        if (prevdate.Year == currentdate.Year && prevdate.Month == currentdate.Month) { continue; }

        //////// if its the ONLY date /////
        if (x == 1) { 
            WriteLinez(contactId, monthat, yearat, 1, 0, firstmo, lastmo, reactivated, deactivated,sw); 
            continue;
            }

        ////  = LAST date to process
        if ( i + 1 == x ) 
        { 
            lastmo = true; if (reactflag) { deactivated=true; } 
        }///// IF THERE IS Next MONTH
        else if ( i + 1 < x ) 
        {   
            //set the next date
            nextdate = contact.Dates.ElementAt( i + 1 ).Datex; 
            //calc diff to next month
            nextmonthDiff =  CalculateMonthDifference(  currentdate, nextdate );  
                    //Console.WriteLine(currentdate + "," + nextdate +"--- >" + nextmonthDiff);

            /*   IF Break in Next Month   */
            if ( nextmonthDiff > 1 ) { 
                lastmo = true; // set it as last month
                deactivated = true; 
                //reactflag = true; //set the flag for break in months
                } 
            /*  IF there is NO BREAK in next month */   
            if ( nextmonthDiff < 2 ) { 
                lastmo = false; 
                deactivated=false;
                }
        }
        if (i == 0) { WriteLinez(contactId, currentdate.Month, currentdate.Year, 1, 0, true, lastmo, false, false,sw); prevdate = currentdate; continue; }
        /////////// PREVIOUS MONTH procs/calcs ///////////////////
        prevmonthDiff = CalculateMonthDifference(prevdate,currentdate);
                //Console.WriteLine(currentdate + "," + prevdate +"--- >" + prevmonthDiff);
        /* IF CONCURRENT MONTHS */
        if ( prevmonthDiff == 1 ) { 
            firstmo = false; //make sure that the first month flag is reset
            if (reactflag) { //if a reactivation has not occurred
                concurrentmosreact += 1; }

                else {
                concurrentmos += 1; } //if reactivation has 
            if (reactivated == true ) { reactivated = false; }
            } 

        if ( prevmonthDiff != 1 )//if its been more than a month since last payment
            { 
            //firstmo = true; //reset the first month
            reactivated = true; //set reactivated
            reactflag = true;
            concurrentmosreact = 1;
            concurrentmos = 0;
            }
        //Console.Write(" Prevmonthdiff = "+prevmonthDiff+", Nextmonthdiff "+nextmonthDiff+"      ");   
        //Console.Write(prevmonthDiff + ", " + nextmonthDiff + ", ");
        WriteLinez(contactId, currentdate.Month, currentdate.Year, concurrentmos, concurrentmosreact, firstmo, lastmo, reactivated, deactivated,sw);

        //if ( nextmonthDiff > 1 ) { reactflag = true; }//set the flag for break in months
        prevdate = currentdate;

    }
}

sw.Close(); 

}

// Define other methods and classes here
+3
source share

All Articles