00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028
00029 #include <gtk/gtk.h>
00030 #include <glib/gi18n.h>
00031 #include <time.h>
00032
00033 #include "qof.h"
00034 #include "AccountP.h"
00035 #include "Transaction.h"
00036 #include "dialog-chart-export.h"
00037 #include "gnc-ui-util.h"
00038 #include "dialog-utils.h"
00039 #include "gnc-engine.h"
00040 #include "gnc-file.h"
00041 #include "gnc-ui.h"
00042 #include "gnc-session.h"
00043
00044 #define EQUITY_ACCOUNT_NAME _("Opening Balances")
00045 #define OPENING_BALANCE_DESC _("Opening Balance")
00046
00047 void chart_export_response_cb (GtkDialog *dialog, gint response, gpointer user_data);
00048
00049 typedef struct chart_data_s
00050 {
00051 GladeXML *xml;
00052 GtkWidget *dialog;
00053 GtkWidget *calendar;
00054 time_t chart_time_t;
00055 QofSession *chart_session;
00056 Account *equity_account;
00057 GList *param_ref_list;
00058 }chart_data;
00059
00060 static void
00061 chart_collection_cb(QofInstance *ent, gpointer user_data)
00062 {
00063 chart_data *data;
00064 Account *acc;
00065 gboolean success;
00066 const GUID *guid;
00067 QofCollection *copy_coll;
00068 QofBook *book;
00069
00070 g_return_if_fail(user_data != NULL);
00071 data = (chart_data*)user_data;
00072 acc = (Account*)ent;
00073 if(0 == safe_strcmp(EQUITY_ACCOUNT_NAME, xaccAccountGetName(acc))
00074 && (xaccAccountGetType(acc) == ACCT_TYPE_EQUITY))
00075 {
00076 success = qof_instance_copy_to_session(data->chart_session, ent);
00077 if(!success) { return; }
00078 guid = qof_entity_get_guid(ent);
00079 book = qof_session_get_book(data->chart_session);
00080 copy_coll = qof_book_get_collection(book, GNC_ID_ACCOUNT);
00081 data->equity_account = (Account*)qof_collection_lookup_entity(copy_coll, guid);
00082 return;
00083 }
00084 }
00085
00086 static void
00087 chart_reference_cb(QofInstance *ent, gpointer user_data)
00088 {
00089 QofInstanceReference *reference;
00090 QofParam *ref_param;
00091 chart_data *data;
00092
00093 g_return_if_fail(user_data != NULL);
00094 data = (chart_data*)user_data;
00095 while(data->param_ref_list != NULL) {
00096 ref_param = data->param_ref_list->data;
00097 reference = qof_instance_get_reference_from(ent, ref_param);
00098 qof_session_update_reference_list(data->chart_session, reference);
00099 data->param_ref_list = data->param_ref_list->next;
00100 }
00101 }
00102
00103 static void
00104 chart_entity_cb(QofInstance *ent, gpointer user_data)
00105 {
00106 chart_data *data;
00107 Account *acc_ent, *equity_account;
00108 Transaction *trans;
00109 Split *split;
00110 gnc_numeric balance;
00111 QofBook *book;
00112 QofCollection *coll;
00113 const GUID *guid;
00114 time_t trans_time;
00115 GList *ref;
00116 QofInstanceReference *ent_ref;
00117
00118 g_return_if_fail(user_data != NULL);
00119 data = (chart_data*)user_data;
00120 trans_time = data->chart_time_t;
00121 data->param_ref_list = NULL;
00122 guid = qof_entity_get_guid(ent);
00123 acc_ent = (Account*)ent;
00124 ref = NULL;
00125 equity_account = data->equity_account;
00126 g_return_if_fail(equity_account != NULL);
00127 balance = xaccAccountGetBalanceAsOfDate(acc_ent, data->chart_time_t);
00128 qof_instance_copy_to_session(data->chart_session, ent);
00129 book = qof_session_get_book(data->chart_session);
00130 coll = qof_book_get_collection(book, GNC_ID_ACCOUNT);
00131 acc_ent = (Account*)qof_collection_lookup_entity(coll, guid);
00132 if(xaccAccountGetCommodity(acc_ent) == NULL)
00133 {
00134 xaccAccountSetCommodity(acc_ent, gnc_default_currency());
00135 }
00136
00137
00138 xaccAccountBeginEdit (acc_ent);
00139 xaccAccountBeginEdit (equity_account);
00140 trans = xaccMallocTransaction (book);
00141 xaccTransBeginEdit (trans);
00142 xaccTransSetCurrency (trans, xaccAccountGetCommodity (acc_ent));
00143 xaccTransSetDateSecs (trans, trans_time);
00144 xaccTransSetDateEnteredSecs (trans, trans_time);
00145 xaccTransSetDescription (trans, OPENING_BALANCE_DESC);
00146
00147 split = xaccMallocSplit (book);
00148 xaccTransAppendSplit (trans, split);
00149 xaccAccountInsertSplit (acc_ent, split);
00150 xaccSplitSetAmount (split, balance);
00151 xaccSplitSetValue (split, balance);
00152 ref = qof_class_get_referenceList(GNC_ID_SPLIT);
00153 while(ref != NULL) {
00154 ent_ref = qof_instance_get_reference_from(QOF_INSTANCE(split), ref->data);
00155 qof_session_update_reference_list(data->chart_session, ent_ref);
00156 ref = g_list_next(ref);
00157 }
00158 g_list_free(ref);
00159 balance = gnc_numeric_neg (balance);
00160
00161 split = xaccMallocSplit (book);
00162 xaccTransAppendSplit (trans, split);
00163 xaccAccountInsertSplit (equity_account, split);
00164 xaccSplitSetAmount (split, balance);
00165 xaccSplitSetValue (split, balance);
00166 xaccTransCommitEdit (trans);
00167 xaccAccountCommitEdit (equity_account);
00168 xaccAccountCommitEdit (acc_ent);
00169 ref = qof_class_get_referenceList(GNC_ID_TRANS);
00170 while(ref != NULL) {
00171 ent_ref = qof_instance_get_reference_from(QOF_INSTANCE(trans), ref->data);
00172 qof_session_update_reference_list(data->chart_session, ent_ref);
00173 ref = g_list_next(ref);
00174 }
00175 g_list_free(ref);
00176 ref = qof_class_get_referenceList(GNC_ID_SPLIT);
00177 while(ref != NULL) {
00178 ent_ref = qof_instance_get_reference_from(QOF_INSTANCE(split), ref->data);
00179 qof_session_update_reference_list(data->chart_session, ent_ref);
00180 ref = g_list_next(ref);
00181 }
00182 g_list_free(ref);
00183 }
00184
00185 void
00186 gnc_main_window_chart_export(void)
00187 {
00188 GladeXML *xml;
00189 chart_data *data;
00190
00191 xml = gnc_glade_xml_new ("chart-export.glade", "chart-export");
00192 data = g_new0(chart_data, 1);
00193 data->xml = xml;
00194 data->dialog = glade_xml_get_widget(xml, "chart-export");
00195 data->calendar = glade_xml_get_widget(xml, "chart-calendar");
00196 glade_xml_signal_autoconnect_full(xml,
00197 gnc_glade_autoconnect_full_func,
00198 data);
00199 gtk_widget_show(data->dialog);
00200 }
00201
00202 static void
00203 on_dateok_clicked (chart_data *data)
00204 {
00205 guint year, month, day;
00206 struct tm *chart_tm;
00207 gchar *filename;
00208 QofSession *current_session, *chart_session;
00209 QofBook *book;
00210 QofCollection *coll;
00211
00212 data->chart_time_t = time(NULL);
00213 chart_tm = gmtime(&data->chart_time_t);
00214
00215 year = chart_tm->tm_year + 1900;
00216 month = chart_tm->tm_mon + 1;
00217 day = chart_tm->tm_mday;
00218 gtk_calendar_get_date(GTK_CALENDAR(data->calendar),
00219 &year, &month, &day);
00220 if((year + 1900) != chart_tm->tm_year) {
00221 chart_tm->tm_year = year - 1900;
00222 }
00223 if(month != chart_tm->tm_mon) {
00224 chart_tm->tm_mon = month;
00225 }
00226 if(day != chart_tm->tm_yday) {
00227 chart_tm->tm_mday = day;
00228 }
00229 data->chart_time_t = mktime(chart_tm);
00230 current_session = gnc_get_current_session();
00231 book = qof_session_get_book(current_session);
00232 chart_session = qof_session_new();
00233 filename = gnc_file_dialog(_("Export Chart of Accounts to QSF XML"),
00234 NULL, NULL, GNC_FILE_DIALOG_EXPORT);
00235 if (filename)
00236 {
00237 gnc_set_busy_cursor(NULL, TRUE);
00238 qof_event_suspend();
00239 qof_session_begin(chart_session, filename, TRUE, TRUE);
00240 data->chart_session = chart_session;
00241 data->equity_account = NULL;
00242 coll = qof_book_get_collection(book, GNC_ID_ACCOUNT);
00243 qof_collection_foreach(coll, chart_collection_cb, data);
00244 if(data->equity_account == NULL)
00245 {
00246 data->equity_account = xaccMallocAccount (qof_session_get_book(chart_session));
00247 xaccAccountBeginEdit (data->equity_account);
00248 xaccAccountSetName (data->equity_account, EQUITY_ACCOUNT_NAME);
00249 xaccAccountSetDescription(data->equity_account, EQUITY_ACCOUNT_NAME);
00250 xaccAccountSetType (data->equity_account, ACCT_TYPE_EQUITY);
00251 xaccAccountSetCommodity (data->equity_account, gnc_default_currency());
00252 }
00253 qof_object_foreach(GNC_ID_ACCOUNT, book, chart_entity_cb, data);
00254 data->param_ref_list = qof_class_get_referenceList(GNC_ID_TRANS);
00255 qof_object_foreach(GNC_ID_TRANS, book, chart_reference_cb, data);
00256 g_list_free(data->param_ref_list);
00257 data->param_ref_list = qof_class_get_referenceList(GNC_ID_SPLIT);
00258 qof_object_foreach(GNC_ID_SPLIT, book, chart_reference_cb, data);
00259 g_list_free(data->param_ref_list);
00260 qof_session_save(chart_session, NULL);
00261 show_session_error(qof_session_get_error(chart_session),
00262 filename, GNC_FILE_DIALOG_EXPORT);
00263 qof_event_resume();
00264 gnc_unset_busy_cursor(NULL);
00265 }
00266 qof_session_end(chart_session);
00267 gnc_set_current_session(current_session);
00268 }
00269
00270 void
00271 chart_export_response_cb (GtkDialog *dialog, gint response, gpointer user_data)
00272 {
00273 chart_data *data;
00274 data = (chart_data*)user_data;
00275 switch (response) {
00276 case GTK_RESPONSE_OK:
00277 gtk_widget_hide(data->dialog);
00278 on_dateok_clicked(data);
00279 break;
00280
00281 default:
00282
00283 break;
00284 }
00285
00286 gtk_widget_destroy(data->dialog);
00287 g_object_unref(data->xml);
00288 g_free(data);
00289 }