/**
 * callback called by the button to launch the automatic association
 * between transactions and reconcile
 *
 * \param button
 * \param assistant
 *
 * \return FALSE
 * */
static gboolean gsb_assistant_reconcile_config_lauch_manu_asso ( GtkWidget *button,
                        GtkWidget *assistant )
{
    GList *tmp_list;
    GtkTreeIter iter;
    GtkTreeModel *model;
    GtkTreeSelection *selection;
    GList *path_list;
    gint account_number = -1;
    GtkWidget *dialog;
    GtkWidget *label;
    GtkWidget *scrolled_window;
    GtkWidget *dialog_tree_view;
    GtkListStore *dialog_store;
    gint return_value;
    gint i;
    enum dialog_column {
	DIALOG_NAME = 0,
	DIALOG_INIT_DATE,
	DIALOG_FINAL_DATE,
	DIALOG_RECONCILE_NUMBER,
	DIALOG_NB_COL
    };
    gint selected_reconcile_number;
    gint transaction_number;

    /* get the selection */
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_transactions_to_link));

    /* get the selected transactions */
    path_list = gtk_tree_selection_get_selected_rows ( GTK_TREE_SELECTION (selection),
						       &model );
    if (!path_list)
	return FALSE;

    /* ok, we have a selection, before continuing,
     * we check that all the transactions are on the same account */
    tmp_list = path_list;
    while (tmp_list)
    {
	GtkTreePath *path;

	path = tmp_list -> data;

	if (gtk_tree_model_get_iter ( GTK_TREE_MODEL (model),
				      &iter,
				      path ))
	{
	    gtk_tree_model_get ( GTK_TREE_MODEL (model),
				 &iter,
				 TRANSACTION_NUMBER, &transaction_number,
				 -1 );
	    if (account_number == -1)
		account_number = gsb_data_transaction_get_account_number (transaction_number);
	    else
	    {
		if (gsb_data_transaction_get_account_number (transaction_number) != account_number)
		{
		    dialogue_error (_("All the selected transactions have to belong to the same account !"));
		    /* erase the path_list */
		    g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL);
		    g_list_free (path_list);
		    return FALSE;
		}
	    }
	}
	tmp_list = tmp_list -> next;
    }

    if (account_number == -1)
    {
	/* erase the path_list */
	g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL);
	g_list_free (path_list);
	return FALSE;
    }

    /* ok, all the transactions belong to the same account, we can
     * show a dialog to select the reconcile */
    dialog = gtk_dialog_new_with_buttons ( _("Selection of a reconciliation"),
					   GTK_WINDOW ( assistant ),
					   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
					   "gtk-cancel", GTK_RESPONSE_CANCEL,
					   "gtk-ok", GTK_RESPONSE_OK,
					   NULL );

    gtk_window_set_default_size ( GTK_WINDOW ( dialog ), 770, 412 );
    gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
    gtk_window_set_resizable ( GTK_WINDOW ( dialog ), TRUE );
    gtk_container_set_border_width ( GTK_CONTAINER ( dialog ), 12 );

    label = gtk_label_new ( _("Select the reconciliation to associate to the selected transactions: ") );
    gtk_misc_set_alignment ( GTK_MISC ( label ), 0.0, 0.0 );
    gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ),
			 label,
			 FALSE, FALSE,
			 10 );

    /* make the list */
    scrolled_window = gtk_scrolled_window_new (FALSE, FALSE);
    gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (scrolled_window),
				     GTK_POLICY_AUTOMATIC,
				     GTK_POLICY_AUTOMATIC );
    gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ),
			 scrolled_window,
			 TRUE, TRUE,
			 0 );

    dialog_store = gtk_list_store_new ( DIALOG_NB_COL,
					G_TYPE_STRING,
					G_TYPE_STRING,
					G_TYPE_STRING,
					G_TYPE_INT );
    dialog_tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog_store));
    g_object_unref (G_OBJECT(dialog_store));
    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (dialog_tree_view), TRUE);
    gtk_container_add ( GTK_CONTAINER (scrolled_window),
			dialog_tree_view );

    /* set the columns */
    for (i=DIALOG_NAME ; i<DIALOG_RECONCILE_NUMBER ; i++)
    {
	GtkTreeViewColumn *column;
	GtkCellRenderer *cell;
	gchar *titles[] = {
	    _("Reconciliation reference"), _("Initial date"), _("Final date")
	};
	gfloat alignment[] = {
	    COLUMN_LEFT, COLUMN_CENTER, COLUMN_CENTER
	};

	cell = gtk_cell_renderer_text_new ();
	g_object_set ( G_OBJECT (cell),
		       "xalign", alignment[i],
		       NULL );
	column = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_sizing ( column,
					  GTK_TREE_VIEW_COLUMN_AUTOSIZE );
	gtk_tree_view_column_set_alignment ( column,
					     alignment[i] );
	gtk_tree_view_column_pack_start ( column, cell, TRUE );
	gtk_tree_view_column_set_title ( column, titles[i] );
	gtk_tree_view_column_set_attributes (column, cell,
					     "text", i,
					     NULL);
	gtk_tree_view_column_set_expand ( column, TRUE );
	gtk_tree_view_column_set_resizable ( column,
					     TRUE );
	gtk_tree_view_append_column ( GTK_TREE_VIEW(dialog_tree_view), column);
    }

    /* fill the tree view */
    tmp_list = gsb_data_reconcile_get_reconcile_list ();
    while (tmp_list)
    {
	gint reconcile_number;

	reconcile_number = gsb_data_reconcile_get_no_reconcile (tmp_list -> data);

	if (gsb_data_reconcile_get_account (reconcile_number) == account_number)
	{
	    gchar *init_date_str;
	    gchar *final_date_str;

	    init_date_str = gsb_format_gdate (gsb_data_reconcile_get_init_date (reconcile_number));
	    final_date_str = gsb_format_gdate (gsb_data_reconcile_get_final_date (reconcile_number));

	    gtk_list_store_append ( GTK_LIST_STORE (dialog_store),
				    &iter );
	    gtk_list_store_set ( GTK_LIST_STORE (dialog_store),
				 &iter,
				 DIALOG_NAME, gsb_data_reconcile_get_name (reconcile_number),
				 DIALOG_INIT_DATE, init_date_str,
				 DIALOG_FINAL_DATE, final_date_str,
				 DIALOG_RECONCILE_NUMBER, reconcile_number,
				 -1 );
	    g_free (init_date_str);
	    g_free (final_date_str);
	}
	tmp_list = tmp_list -> next;
    }

    gtk_widget_show_all (dialog);

    /* launch the dialog */
    return_value = gtk_dialog_run (GTK_DIALOG (dialog));

    if (return_value != GTK_RESPONSE_OK)
    {
	gtk_widget_destroy (dialog);
	return FALSE;
    }

    /* we get the selected reconcile */
    if (!gtk_tree_selection_get_selected ( gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog_tree_view)),
					   NULL,
					   &iter ))
    {
	dialogue_warning (_("No selection found, the transactions are not modified."));
	gtk_widget_destroy (dialog);
	return FALSE;
    }

    gtk_tree_model_get ( GTK_TREE_MODEL (dialog_store),
			 &iter,
			 DIALOG_RECONCILE_NUMBER, &selected_reconcile_number,
			 -1 );
    /* ok we have the reconcile number, we can destroy the dialog */
    gtk_widget_destroy (dialog);

    /* and now, fill the selected transactions with that reconcile number */
    tmp_list = g_list_last (path_list);
    while (tmp_list)
    {
	GtkTreePath *path;

	path = tmp_list -> data;

	if (gtk_tree_model_get_iter ( GTK_TREE_MODEL (model),
				      &iter,
				      path ))
	{
	    gtk_tree_model_get ( GTK_TREE_MODEL (model),
				 &iter,
				 TRANSACTION_NUMBER, &transaction_number,
				 -1 );
	    gtk_list_store_remove ( GTK_LIST_STORE (model),
				    &iter );
	    gsb_data_transaction_set_reconcile_number ( transaction_number,
							selected_reconcile_number );
	    transactions_to_link--;
	}
	tmp_list = tmp_list -> prev;
    }

    /* erase the path_list */
    g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL);
    g_list_free (path_list);

    /* now there is 2 way :
     * either transactions_to_link is 0, we go directly to the succes page
     * either it's not null, and the user should create more reconciles */
    if (transactions_to_link)
    {
	gchar *string;

	/* update the labels */
	string = g_strdup_printf (_("Still %d transactions to link with a reconciliation."),
				  transactions_to_link);
	gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_1),
			     string);
	gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_3),
			     string);
	g_free (string);
	gtk_widget_grab_focus (treeview_transactions_to_link);
    }
    else
    {
	/* go to the success page */
	gsb_assistant_set_next ( assistant,
				 RECONCILE_ASSISTANT_MANUALLY_ASSOCIATE,
				 RECONCILE_ASSISTANT_SUCCESS );
	gsb_assistant_next_page (assistant);
    }
    return FALSE;
}
Esempio n. 2
0
/**
 * \brief Import QIF data.
 *
 * Open a QIF file and fills in data in a struct_compte_importation
 * data structure.
 *
 * \param assistant	Not used.
 * \param imported	A pointer to structure containing name and
 *			format of imported file.
 *
 * \return		TRUE on success.
 */
gboolean recuperation_donnees_qif ( GtkWidget *assistant, struct imported_file *imported )
{
    gchar *tmp_str;
    struct struct_compte_importation *imported_account;
    gint returned_value = 0;
    gboolean premier_compte = TRUE;
    FILE *qif_file;

    qif_file = utf8_fopen ( imported -> name, "r" );
    if ( ! qif_file )
        return FALSE;

    mismatch_dates = TRUE;

    /* qif_file pointe sur le qif_file qui a été reconnu comme qif */
    rewind ( qif_file );

    imported_account = g_malloc0 ( sizeof ( struct struct_compte_importation ));
    imported_account -> nom_de_compte = unique_imported_name ( _("Invalid QIF file") );
    imported_account -> filename = my_strdup ( imported -> name );
    imported_account -> origine = my_strdup ( "QIF" );

    /* save filename */
    imported_account -> real_filename = my_strdup (imported -> name);

    /* It is positioned on the first line of file */
    returned_value = get_utf8_line_from_file ( qif_file, &tmp_str, imported -> coding_system );

    do
    {
        GSList *tmp_list;
        gchar *account_name = NULL;
        gint order = 0;
        gboolean name_preced = FALSE;
        struct struct_ope_importation *imported_transaction;

        do
        {
            if (  returned_value != EOF
             &&
             tmp_str
             &&
             g_ascii_strncasecmp ( tmp_str, "!Account", 8 ) == 0 )
            {
                /* create and fill the new account */
                imported_account = g_malloc0 ( sizeof ( struct struct_compte_importation ) );
                imported_account -> origine = my_strdup ( "QIF" );

                /* save filename and account_name */
                imported_account -> real_filename = my_strdup ( imported -> name );
                imported_account -> filename = my_strdup ( imported -> name );

                account_name = gsb_qif_get_account_name ( qif_file, imported -> coding_system );
                imported_account -> nom_de_compte = unique_imported_name ( account_name );
                g_free ( account_name );

                name_preced = TRUE;
                premier_compte = FALSE;
                returned_value = get_utf8_line_from_file ( qif_file, &tmp_str, imported -> coding_system );
            }
            else if ( returned_value != EOF
             &&
             tmp_str
             &&
             g_ascii_strncasecmp ( tmp_str, "!Type:Cat", 9 ) == 0 )
            {

                do
                {
                    returned_value = gsb_qif_recupere_categories ( qif_file,
                                        imported -> coding_system );

                    if ( returned_value == 0 )
                        tmp_str = last_header;
                }
                /* continue untill the end of the file or a change of account */
                while ( returned_value != EOF && returned_value != 0 );
            }
            else if ( returned_value != EOF
             &&
             tmp_str
             &&
             g_ascii_strncasecmp ( tmp_str, "!Type", 5 ) == 0 )
            {
                gint account_type;

                account_type = gsb_qif_get_account_type ( tmp_str ) ;
                if ( account_type == -1 )
                {
                    name_preced = FALSE;
                    continue;
                }
                else
                {
                    if ( name_preced == FALSE )
                    {
                        /* create and fill the new account */
                        imported_account = g_malloc0 ( sizeof ( struct struct_compte_importation ) );
                        imported_account -> origine = my_strdup ( "QIF" );

                        /* save filename and account_name */
                        imported_account -> real_filename = my_strdup ( imported -> name );
                        imported_account -> filename = my_strdup ( imported -> name );
                        imported_account -> nom_de_compte = unique_imported_name (
                                                                my_strdup ( _("Imported QIF account" ) ) );

                        premier_compte = FALSE;
                    }

                    if ( account_type == 6 )
                    {
                        /* on considère le imported_account d'investissement comme un imported_account
                         * bancaire mais met un warning car pas implémenté, aucune idée si ça passe ou pas... */
                        gchar *msg;

                        msg = g_strdup_printf ( _("Grisbi found an investment account:\n%s\n"
                                        "which is not implemented yet.  Nevertheless, Grisbi will try "
                                        "to import it as a bank account." ),
                                        imported -> name );
                        dialogue_warning ( msg );
                        g_free ( msg );

                        account_type = 0;
                    }

                    imported_account -> type_de_compte = account_type;
                    returned_value = -2;
                }
            }
            else
                name_preced = FALSE;
        }
        while ( returned_value != EOF && returned_value != -2 );

        if ( returned_value == EOF )
        {
            if ( premier_compte )
            {
            /* no account already saved, so send an error */
                liste_comptes_importes_error = g_slist_append ( liste_comptes_importes_error,
                                        imported_account );
                fclose ( qif_file );
                return FALSE;
            }
            else
            {
                /* we have at least saved an account before, ok, enough for me */
                fclose ( qif_file );
                return TRUE;
            }
        }

        do
        {
            returned_value = gsb_qif_recupere_operations_from_account ( qif_file,
                                        imported -> coding_system,
                                        imported_account );

            if ( returned_value == 0 )
                tmp_str = last_header;
        }
        /* continue untill the end of the file or a change of account */
        while ( returned_value != EOF && returned_value != 0 );

        /* first, we need to check if the first transaction is an opening balance
         * or a normal transaction
         * update : money sometimes translate Opening balance... */
        if ( g_slist_length ( imported_account -> operations_importees) > 0 )
        {
            imported_transaction = imported_account -> operations_importees -> data;
            if ( imported_transaction -> tiers
             &&
             (!g_ascii_strncasecmp ( imported_transaction -> tiers, "Opening Balance", 15 )
             ||
             !g_ascii_strcasecmp ( imported_transaction -> tiers, _("Opening Balance") ) ) )
            {
                /* ok, we are on an opening balance, we transfer the first transaction
                 * to the initial datas of the account */

                /* get the initial amount */
                imported_account -> solde = imported_transaction -> montant;

                /* get the name of account */
                tmp_str = my_strdelimit (imported_transaction -> categ, "[]", "");
                if ( imported_account -> nom_de_compte )
                    g_free ( imported_account -> nom_de_compte );
                imported_account -> nom_de_compte = unique_imported_name ( tmp_str );
                g_free (tmp_str);

                /* get the date of the file */
                imported_account -> date_solde_qif = my_strdup ( imported_transaction -> date_tmp );

                /* now, we can remove the first imported transaction */
                imported_account -> operations_importees = g_slist_remove ( imported_account -> operations_importees,
                                            imported_transaction );
                g_free (imported_transaction);
            }
            /* now we need to transform the dates of transaction into gdate */

            /* try to understand the order */
            order = gsb_qif_get_date_order ( imported_account -> operations_importees );
            if (order == -1)
                dialogue_error ( _("Grisbi couldn't determine the format of the date into the qif file.\n"
                                        "Please contact the Grisbi team ([email protected]) to find "
                                        "the problem.\nFor now, all the dates will be imported as 01.01.1970") );
        }

        tmp_list = imported_account -> operations_importees;
        while (tmp_list)
        {
            imported_transaction = tmp_list -> data;
            if (order == -1)
                /* we didn't find the order */
                imported_transaction -> date = g_date_new_dmy ( 1,1,2000 );
            else
                imported_transaction -> date = gsb_qif_get_date ( imported_transaction -> date_tmp, order );

            tmp_list = tmp_list -> next;
        }

        /* set the date of the qif file */
        if ( imported_account -> date_solde_qif )
            imported_account -> date_fin = gsb_qif_get_date (imported_account -> date_solde_qif, order);

        /* add that account to the others */
        liste_comptes_importes = g_slist_append ( liste_comptes_importes, imported_account );
    }
    /* go to the next account */
    while ( returned_value != EOF );

    fclose ( qif_file );

    return ( TRUE );
}