Beispiel #1
0
GDate
xaccSchedXactionGetNextInstance (const SchedXaction *sx, SXTmpStateData *tsd)
{
    GDate prev_occur, next_occur;

    g_date_clear( &prev_occur, 1 );
    if ( tsd != NULL )
        prev_occur = tsd->last_date;

    /* If prev_occur is in the "cleared" state and sx->start_date isn't, then
     * we're at the beginning. We want to pretend prev_occur is the day before
     * the start_date in case the start_date is today so that the SX will fire
     * today. If start_date isn't valid either then the SX will fire anyway, no
     * harm done.
     */
    if (! g_date_valid( &prev_occur ) && g_date_valid(&sx->start_date))
    {
        /* We must be at the beginning. */
        prev_occur = sx->start_date;
        g_date_subtract_days( &prev_occur, 1 );
    }

    recurrenceListNextInstance(sx->schedule, &prev_occur, &next_occur);

    if ( xaccSchedXactionHasEndDate( sx ) )
    {
        const GDate *end_date = xaccSchedXactionGetEndDate( sx );
        if ( g_date_compare( &next_occur, end_date ) > 0 )
        {
            g_date_clear( &next_occur, 1 );
        }
    }
    else if ( xaccSchedXactionHasOccurDef( sx ) )
    {
        if ((tsd && tsd->num_occur_rem == 0) ||
            (!tsd && sx->num_occurances_remain == 0 ))
        {
            g_date_clear( &next_occur, 1 );
        }
    }
    return next_occur;
}
Beispiel #2
0
gint gnc_sx_get_num_occur_daterange(const SchedXaction *sx, const GDate* start_date, const GDate* end_date)
{
    gint result = 0;
    SXTmpStateData *tmpState;
    gboolean countFirstDate;

    /* SX still active? If not, return now. */
    if ((xaccSchedXactionHasOccurDef(sx)
            && xaccSchedXactionGetRemOccur(sx) <= 0)
            || (xaccSchedXactionHasEndDate(sx)
                && g_date_compare(xaccSchedXactionGetEndDate(sx), start_date) < 0))
    {
        return result;
    }

    tmpState = gnc_sx_create_temporal_state (sx);

    /* Should we count the first valid date we encounter? Only if the
     * SX has not yet occurred so far, or if its last valid date was
     * before the start date. */
    countFirstDate = !g_date_valid(&tmpState->last_date)
                     || (g_date_compare(&tmpState->last_date, start_date) < 0);

    /* No valid date? SX has never occurred so far. */
    if (!g_date_valid(&tmpState->last_date))
    {
        /* SX has never occurred so far */
        gnc_sx_incr_temporal_state (sx, tmpState);
        if (xaccSchedXactionHasOccurDef(sx) && tmpState->num_occur_rem < 0)
        {
            gnc_sx_destroy_temporal_state (tmpState);
            return result;
        }
    }

    /* Increase the tmpState until we are in our interval of
     * interest. Only calculate anything if the sx hasn't already
     * ended. */
    while (g_date_compare(&tmpState->last_date, start_date) < 0)
    {
        gnc_sx_incr_temporal_state (sx, tmpState);
        if (xaccSchedXactionHasOccurDef(sx) && tmpState->num_occur_rem < 0)
        {
            gnc_sx_destroy_temporal_state (tmpState);
            return result;
        }
    }

    /* Now we are in our interval of interest. Increment the
     * occurrence date until we are beyond the end of our
     * interval. Make sure to check for invalid dates here: It means
     * the SX has ended. */
    while (g_date_valid(&tmpState->last_date)
            && (g_date_compare(&tmpState->last_date, end_date) <= 0)
            && (!xaccSchedXactionHasEndDate(sx)
                || g_date_compare(&tmpState->last_date, xaccSchedXactionGetEndDate(sx)) <= 0)
            && (!xaccSchedXactionHasOccurDef(sx)
                /* The >=0 (i.e. the ==) is important here, otherwise
                 * we miss the last valid occurrence of a SX which is
                 * limited by num_occur */
                || tmpState->num_occur_rem >= 0))
    {
        ++result;
        gnc_sx_incr_temporal_state (sx, tmpState);
    }

    /* If the first valid date shouldn't be counted, decrease the
     * result number by one. */
    if (!countFirstDate && result > 0)
        --result;

    gnc_sx_destroy_temporal_state (tmpState);
    return result;
}
Beispiel #3
0
xmlNodePtr
gnc_schedXaction_dom_tree_create(SchedXaction *sx)
{
    xmlNodePtr	ret;
    const GDate	*date;
    gint        instCount;
    const GncGUID        *templ_acc_guid;
    gboolean allow_2_2_incompat = TRUE;
    gchar *name = g_strdup (xaccSchedXactionGetName(sx));

    templ_acc_guid = xaccAccountGetGUID(sx->template_acct);

    /* FIXME: this should be the same as the def in io-gncxml-v2.c */
    ret = xmlNewNode (NULL, BAD_CAST GNC_SCHEDXACTION_TAG);

    if (allow_2_2_incompat)
        xmlSetProp(ret, BAD_CAST "version", BAD_CAST schedxaction_version2_string);
    else
        xmlSetProp(ret, BAD_CAST "version", BAD_CAST schedxaction_version_string);

    xmlAddChild( ret,
                 guid_to_dom_tree(SX_ID,
                                  xaccSchedXactionGetGUID(sx)) );

    xmlNewTextChild( ret, NULL, BAD_CAST SX_NAME, checked_char_cast (name));
    g_free (name);

    if (allow_2_2_incompat)
    {
        xmlNewTextChild( ret, NULL, BAD_CAST SX_ENABLED,
                         BAD_CAST ( sx->enabled ? "y" : "n" ) );
    }

    xmlNewTextChild( ret, NULL, BAD_CAST SX_AUTOCREATE,
                     BAD_CAST ( sx->autoCreateOption ? "y" : "n" ) );
    xmlNewTextChild( ret, NULL, BAD_CAST SX_AUTOCREATE_NOTIFY,
                     BAD_CAST ( sx->autoCreateNotify ? "y" : "n" ) );
    xmlAddChild(ret, int_to_dom_tree(SX_ADVANCE_CREATE_DAYS,
                                     sx->advanceCreateDays));
    xmlAddChild(ret, int_to_dom_tree(SX_ADVANCE_REMIND_DAYS,
                                     sx->advanceRemindDays));

    instCount = gnc_sx_get_instance_count( sx, NULL );
    xmlAddChild( ret, int_to_dom_tree( SX_INSTANCE_COUNT,
                                       instCount ) );

    xmlAddChild( ret,
                 gdate_to_dom_tree( SX_START,
                                    xaccSchedXactionGetStartDate(sx) ) );

    date = xaccSchedXactionGetLastOccurDate(sx);
    if ( g_date_valid( date ) )
    {
        xmlAddChild( ret, gdate_to_dom_tree( SX_LAST, date ) );
    }

    if ( xaccSchedXactionHasOccurDef(sx) )
    {

        xmlAddChild(ret, int_to_dom_tree( SX_NUM_OCCUR,
                                          xaccSchedXactionGetNumOccur(sx)));
        xmlAddChild(ret, int_to_dom_tree( SX_REM_OCCUR,
                                          xaccSchedXactionGetRemOccur(sx)));

    }
    else if ( xaccSchedXactionHasEndDate(sx) )
    {
        xmlAddChild( ret,
                     gdate_to_dom_tree( SX_END,
                                        xaccSchedXactionGetEndDate(sx) ) );
    }

    /* output template account GncGUID */
    xmlAddChild( ret,
                 guid_to_dom_tree(SX_TEMPL_ACCT,
                                  templ_acc_guid));

    if (allow_2_2_incompat)
    {
        xmlNodePtr schedule_node = xmlNewNode(NULL,
                                              BAD_CAST "sx:schedule");
        GList *schedule = gnc_sx_get_schedule(sx);
        for (; schedule != NULL; schedule = schedule->next)
        {
            xmlAddChild(schedule_node, recurrence_to_dom_tree("gnc:recurrence", (Recurrence*)schedule->data));
        }
        xmlAddChild(ret, schedule_node);
    }

    /* Output deferred-instance list. */
    {
        xmlNodePtr instNode;
        SXTmpStateData *tsd;
        GList *l;

        for ( l = gnc_sx_get_defer_instances( sx ); l; l = l->next )
        {
            tsd = (SXTmpStateData*)l->data;

            instNode = xmlNewNode( NULL, BAD_CAST SX_DEFER_INSTANCE );
            if ( g_date_valid( &tsd->last_date ) )
            {
                xmlAddChild( instNode, gdate_to_dom_tree( SX_LAST,
                             &tsd->last_date ) );
            }
            xmlAddChild( instNode, int_to_dom_tree( SX_REM_OCCUR,
                                                    tsd->num_occur_rem ) );
            xmlAddChild( instNode, int_to_dom_tree( SX_INSTANCE_COUNT,
                                                    tsd->num_inst ) );
            xmlAddChild( ret, instNode );
        }
    }

    /* output kvp_frame */
    {
        xmlNodePtr kvpnode =
            kvp_frame_to_dom_tree( SX_SLOTS,
                                   xaccSchedXactionGetSlots(sx) );
        if ( kvpnode )
        {
            xmlAddChild(ret, kvpnode);
        }
    }

    return ret;
}