1 /* 2 * gnc-sx-instance-model.h 3 * 4 * Copyright (C) 2006 Josh Sled <jsled@asynchronous.org> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of version 2 and/or version 3 of the GNU General Public 8 * License as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, contact: 17 * 18 * Free Software Foundation Voice: +1-617-542-5942 19 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 20 * Boston, MA 02110-1301, USA gnu@gnu.org 21 */ 22 23 /** \file 24 */ 25 26 #ifndef _GNC_SX_INSTANCE_MODEL_H 27 #define _GNC_SX_INSTANCE_MODEL_H 28 29 #include <config.h> 30 #include <glib.h> 31 #include <glib-object.h> 32 #include "gnc-numeric.h" 33 #include "SchedXaction.h" 34 35 G_BEGIN_DECLS 36 37 #define GNC_TYPE_SX_INSTANCE_MODEL (gnc_sx_instance_model_get_type ()) 38 #define GNC_SX_INSTANCE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModel)) 39 #define GNC_SX_INSTANCE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModelClass)) 40 #define GNC_IS_SX_INSTANCE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_SX_INSTANCE_MODEL)) 41 #define GNC_IS_SX_INSTANCE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_SX_INSTANCE_MODEL)) 42 #define GNC_SX_INSTANCE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_SX_INSTANCE_MODEL, GncSxInstanceModelClass)) 43 44 typedef struct _GncSxInstanceModel 45 { 46 GObject parent; 47 gboolean disposed; 48 49 /* private */ 50 gint qof_event_handler_id; 51 52 /* signals */ 53 /* void (*added)(SchedXaction *sx); // gpointer user_data */ 54 /* void (*updated)(SchedXaction *sx); // gpointer user_data */ 55 /* void (*removing)(SchedXaction *sx); // gpointer user_data */ 56 57 /* public */ 58 GDate range_end; 59 gboolean include_disabled; 60 GList *sx_instance_list; /* <GncSxInstances*> */ 61 } GncSxInstanceModel; 62 63 typedef struct _GncSxInstanceModelClass 64 { 65 GObjectClass parent; 66 67 guint removing_signal_id; 68 guint updated_signal_id; 69 guint added_signal_id; 70 } GncSxInstanceModelClass; 71 72 typedef struct _GncSxInstances 73 { 74 SchedXaction *sx; 75 GHashTable /** <name:char*,GncSxVariable*> **/ *variable_names; 76 gboolean variable_names_parsed; 77 78 GDate next_instance_date; 79 80 /** GList<GncSxInstance*> **/ 81 GList *instance_list; 82 } GncSxInstances; 83 84 typedef enum 85 { 86 SX_INSTANCE_STATE_IGNORED, 87 SX_INSTANCE_STATE_POSTPONED, 88 SX_INSTANCE_STATE_TO_CREATE, 89 SX_INSTANCE_STATE_REMINDER, 90 SX_INSTANCE_STATE_CREATED, 91 SX_INSTANCE_STATE_MAX_STATE 92 } GncSxInstanceState; 93 94 typedef struct _GncSxVariable 95 { 96 gchar *name; 97 gnc_numeric value; /**< only numeric values are supported. **/ 98 gboolean editable; 99 } GncSxVariable; 100 101 typedef struct _GncSxInstance 102 { 103 GncSxInstances *parent; /**< the parent instances collection. **/ 104 SXTmpStateData *temporal_state; /**< the sx creation temporal state. **/ 105 GncSxInstanceState orig_state; /**< the original state at generation time. **/ 106 GncSxInstanceState state; /**< the current state of the instance (during editing) **/ 107 GDate date; /**< the instance date. **/ 108 GHashTable *variable_bindings; /**< variable bindings. **/ 109 } GncSxInstance; 110 111 typedef struct _GncSxVariableNeeded 112 { 113 GncSxInstance *instance; 114 GncSxVariable *variable; 115 } GncSxVariableNeeded; 116 117 GType gnc_sx_instance_model_get_type(void); 118 119 /** Shorthand for get_instances(now, FALSE); */ 120 GncSxInstanceModel* gnc_sx_get_current_instances(void); 121 122 /** Allocates a new SxInstanceModel and fills it with generated 123 * instances for all scheduled transactions up to the given range_end 124 * date. 125 * 126 * The caller must unref the returned object by 127 * g_object_unref(G_OBJECT(inst_model)); when no longer in use. */ 128 GncSxInstanceModel* gnc_sx_get_instances(const GDate *range_end, gboolean include_disabled); 129 130 /** 131 * Regenerates and updates the GncSxInstances* for the given SX. Model 132 * consumers are probably going to call this in response to seeing the 133 * "update" signal, unless they need to be doing something else like 134 * finishing an iteration over an existing GncSxInstances*. 135 **/ 136 void gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXaction *sx); 137 void gnc_sx_instance_model_remove_sx_instances(GncSxInstanceModel *model, SchedXaction *sx); 138 139 /** Fix up numerics where they've gotten out-of-sync with the formulas. 140 * 141 * Ideally this would be done at load time, but it requires gnc_exp_parser to 142 * work and neither engine nor the backends can depend on it. 143 */ 144 void gnc_sx_scrub_split_numerics (gpointer psplit, gpointer user); 145 146 /** @return GList<GncSxVariable*>. Caller owns the list, but not the items. **/ 147 GList *gnc_sx_instance_get_variables(GncSxInstance *inst); 148 149 Account* gnc_sx_get_template_transaction_account(const SchedXaction *sx); 150 151 /** 152 * @return caller-owned data struct. 153 **/ 154 GHashTable* gnc_sx_instance_get_variables_for_parser(GHashTable *instance_var_hash); 155 156 GncSxVariable* gnc_sx_variable_new_full(gchar *name, gnc_numeric value, gboolean editable); 157 void gnc_sx_variable_free(GncSxVariable *var); 158 159 /** 160 * There is a constraint around a sequence of upcoming instance states. In 161 * short: the last-created state and a list of postponed instances are modeled, 162 * but upcoming reminders are not. As such, a reminder can never be before any 163 * other (modeled) instance type. For instance, the following sequences are 164 * disallowed: 165 * 166 * [...] 167 * remind <- will be lost/skipped over; must be converted to `postponed`. 168 * to-create <- this will be the last-recorded state. 169 * [...] 170 * 171 * [...] 172 * remind <- same as previous; will be lost/skipped; must be `postponed`. 173 * postponed 174 * [...] 175 * 176 * remind <- same... 177 * ignore 178 * [...] 179 * 180 * 181 * As such, the SinceLastRun model will enforce that there are no previous 182 * `remind` instances at every state change. They will be silently converted to 183 * `postponed`-state transactions. 184 **/ 185 void gnc_sx_instance_model_change_instance_state(GncSxInstanceModel *model, 186 GncSxInstance *instance, 187 GncSxInstanceState new_state); 188 189 void gnc_sx_instance_model_set_variable(GncSxInstanceModel *model, 190 GncSxInstance *instance, 191 GncSxVariable *variable, 192 gnc_numeric *new_value); 193 194 /** 195 * @return List<GncSxVariableNeeded> of unbound {instance,variable} pairs; 196 * the caller owns the list and the items. 197 **/ 198 GList* gnc_sx_instance_model_check_variables(GncSxInstanceModel *model); 199 200 /** Really ("effectively") create the transactions from the SX 201 * instances in the given model. */ 202 void gnc_sx_instance_model_effect_change(GncSxInstanceModel *model, 203 gboolean auto_create_only, 204 GList **created_transaction_guids, 205 GList **creation_errors); 206 207 typedef struct _GncSxSummary 208 { 209 gboolean need_dialog; /**< If the dialog needs to be displayed. **/ 210 211 gint num_instances; /**< The number of total instances (in any state). **/ 212 gint num_to_create_instances; /**< The number of (not-auto-create) to-create instances. **/ 213 gint num_auto_create_instances; /**< The total number of auto-create instances. **/ 214 gint num_auto_create_no_notify_instances; /**< The number of automatically-created instances that do no request notification. **/ 215 } GncSxSummary; 216 217 /** 218 * @param summary Caller-provided, populated with a summarization of the 219 * state of the model. Specifically, used to determine if there are SLR SXes 220 * that need either auto-creation or user-interaction. 221 **/ 222 void gnc_sx_instance_model_summarize(GncSxInstanceModel *model, GncSxSummary *summary); 223 224 /** Debug output to trace file */ 225 void gnc_sx_summary_print(const GncSxSummary *summary); 226 227 void gnc_sx_get_variables(SchedXaction *sx, GHashTable *var_hash); 228 int gnc_sx_parse_vars_from_formula(const char *formula, GHashTable *var_hash, gnc_numeric *result); 229 void gnc_sx_randomize_variables(GHashTable *vars); 230 231 /** Returns a GHashTable<GUID*, gnc_numeric*> with no destructor for 232 * the key, but a destructor for the value set. 233 * 234 * The returned value must be free'd with g_hash_table_destroy or 235 * g_hash_table_unref. */ 236 GHashTable* gnc_g_hash_new_guid_numeric(void); 237 238 /** Instantiates the cash flow of all given SXs (in the given 239 * GList<SchedXAction*>) into the GHashTable<GUID*, gnc_numeric*> for the 240 * given date range. Each SX is counted with multiplicity as it has 241 * occurrences in the given date range. 242 * 243 * The creation_errors list, if non-NULL, receive any errors that 244 * occurred during creation, similar as in 245 * gnc_sx_instance_model_effect_change(). */ 246 void gnc_sx_all_instantiate_cashflow(GList *all_sxes, 247 const GDate *range_start, const GDate *range_end, 248 GHashTable* map, GList **creation_errors); 249 250 /** Simplified wrapper around gnc_sx_all_instantiate_cashflow(): Run 251 * that function on all SX of the current book for the given date 252 * range. Ignore any potential error messages. Returns a newly 253 * allocated GHashTable with the result, which is a GHashTable<GUID*, 254 * gnc_numeric*>, identical to what gnc_g_hash_new_guid_numeric() 255 * would return. The returned value must be free'd with 256 * g_hash_table_destroy. */ 257 GHashTable* gnc_sx_all_instantiate_cashflow_all(GDate range_start, GDate range_end); 258 259 G_END_DECLS 260 261 262 #endif // _GNC_SX_INSTANCE_MODEL_H 263