Logo Search packages:      
Sourcecode: gacc version File versions

accounts.c

/*
 * accounts.c
 * Thomas Nemeth, le 22.02.2000 (from acclists.c 18.09.1999)
 *
 * Gestion de la liste des données de gAcc, gestionnaire de comptes
 * banquaires personnels avec GTK+.
 *
 *   Copyright (C) 1999  Thomas Nemeth
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "structs.h"
#include "accounts.h"
#include "operations.h"
#include "fileaccess.h"
#include "usefull.h"
#include "locale_formats.h"
#include "oldversions.h"
#include "import.h"


/* ------++++++======*** COMPTES ***** ACCOUNTS ***======++++++------ */

void read_from_last_version (FILE *file) {
    ACC_ELT *acc = NULL, *prevacc = NULL;
    OPE_ELT *ope = NULL, *prevope = NULL, *splited = NULL;
    char     tmpstr [MAXSTRLEN + 1];
#if DEBUG_LEVEL>0
    char    *line;
#endif

#if DEBUG_LEVEL>0
    printf ("Début du chargement...\n");
#endif
    while ( ! feof (file) ) {
        fgets (tmpstr, (int) MAXSTRLEN, file);
#if DEBUG_LEVEL>0
        printf ("Nouveau compte : tmpstr = %s", tmpstr);
#endif
        prevacc      = acc;
        acc          = acc_list_elt_new ();
        acc->account = get_account_from_line (tmpstr);
        if (config.acc_list_head == NULL)
            config.acc_list_head = acc;
        else
            prevacc->next = acc;
#if DEBUG_LEVEL>0
        line = create_line_from_account (acc->account);
        printf ("%s", line);
        free (line);
#endif
        tmpstr[0] = 0;
        fgets (tmpstr, (int) MAXSTRLEN, file);
#if DEBUG_LEVEL>0
        printf ("tmpstr[0] = %c donc ", tmpstr[0]);
        if (tmpstr[0] == '.')
            printf ("il a des opérations :\n");
        else
            printf ("il n'a pas d'opération !\n");
#endif
        while ( ! feof (file) && (tmpstr[0] != '%') ) {
            fgets (tmpstr, (int) MAXSTRLEN, file);
            if ( (tmpstr[0] != '%') && (tmpstr[0] != 0) ) {
#if DEBUG_LEVEL>0
                printf ("> ");
#endif
                prevope        = ope;
                ope            = ope_list_elt_new ();
                ope->operation = get_operation_from_line (tmpstr);
                if (acc->account->ope_list_head == NULL)
                    acc->account->ope_list_head = ope;
                else if ( (ope->operation->parent != 0) && (splited == NULL) ) {
                    splited                    = prevope;
                    splited->operation->splits = ope;
                    prevope                    = NULL;
                } else if ( (ope->operation->parent != 0) && (splited != NULL) )
                    prevope->next = ope;
                else if ( (ope->operation->parent == 0) && (splited != NULL) ) {
                    prevope       = splited;
                    prevope->next = ope;
                    splited       = NULL;
                } else
                    prevope->next = ope;
                ope->prev = prevope;
#if DEBUG_LEVEL>0
                line = create_line_from_operation (ope->operation);
                printf ("%s", line);
                free (line);
#endif
                tmpstr[0] = 0;
            }
        }
#if DEBUG_LEVEL>0
        if (tmpstr[0] == '%') {
            printf ("Il y a un nouveau compte après\n");
        } else {
            printf ("C'était le dernier\n");
        }
#endif
    }
}

void read_accounts_from_file () {
    FILE    *file;
    char    *FileVersion;

    setlocale (LC_NUMERIC, "C");

    FileVersion = open_file (config.accfilename, &file);
    if(FileVersion != NULL) {
#if DEBUG_LEVEL>0
            printf ("Version du fichier   : %s\n", FileVersion);
            printf ("Version du programme : %s\n", VERSION);
#endif
        if (strcmp(FileVersion,"CBB") != 0)
            free_accounts ();
        if (strcmp(FileVersion,"CBB") == 0)
            read_from_cbb (file);
        else if (in_versions ("0.7.5", VERSION, FileVersion) == VRAI)
            read_from_last_version (file);
        else if (in_versions ("0.7.3", "0.7.4", FileVersion) == VRAI)
            read_from_073_to_074 (file);
        else if (in_versions ("0.7.1", "0.7.2", FileVersion) == VRAI)
            read_from_071_to_072 (file);
        else if (in_versions ("0.6.9", "0.7.0", FileVersion) == VRAI)
            read_from_069_to_070 (file);
        else if (in_versions ("0.6.6", "0.6.8", FileVersion) == VRAI)
            read_from_066_to_068 (file);
        else if (in_versions ("0.6.5", "0.6.5", FileVersion) == VRAI)
            read_from_065 (file);
        else if (in_versions ("0.6.4", "0.6.4", FileVersion) == VRAI)
            read_from_064 (file);
        else if (in_versions ("0.6.2", "0.6.3", FileVersion) == VRAI)
            read_from_062_to_063 (file);
        else if (in_versions ("0.0.0", "0.6.1", FileVersion) == VRAI)
            read_from_000_to_061 (file);
        else if (strcmp (FileVersion, VERSION) > 0)
            printf (_("Accounts file version not supported by this one. Sorry !\n") );
        else {
            printf ("File version : %s -- Program version : %s\n",
                    FileVersion, VERSION);
            printf ("Cannot open %s\n", config.accfilename);
        }
        if (strlen (FileVersion) > 3) fclose (file);
        free (FileVersion);
        config.AccDataModified = FAUX;
    }
    setlocale (LC_NUMERIC, num_locale);
}

void write_accounts_to_file () {
    ACC_ELT *lst;
    OPE_ELT *ope;
    FILE    *file;
    char    *line = NULL;
    char     my_command [MAXSTRLEN + 1];
    char    *today;

    setlocale (LC_NUMERIC, "C");

    /* backup ! */
    today = unformat_today ();
    sprintf (my_command, "%s %s-save%s",
             config.accfilename,
             config.accfilename,
             today);
    my_system ("cp", my_command);
    free (today); 

    /* open for writing */
    lst = config.acc_list_head;
    if ( (file = fopen (config.accfilename, "w") ) == NULL) {
        fatal_error (config.accfilename);
    } else {
        create_file_header (file, "Accounts & operations description file");
        while (lst != NULL) {
            line = create_line_from_account (lst->account);
            fprintf (file, "%s", line);
            free (line);
            ope = lst->account->ope_list_head;
            if (ope != NULL) fprintf (file, ".\n");
            while (ope != NULL) {
                line = create_line_from_operation (ope->operation);
                fprintf (file, "%s", line);
                ope = ope->next;
                free (line);
            }
            lst = lst->next;
            if (lst != NULL) fprintf (file,"%%\n");
        }
        fclose (file);
        config.AccDataModified = FAUX;
        if (chmod (config.accfilename, S_IRUSR | S_IWUSR) == -1) {
            perror (config.accfilename);
        }
    }
    setlocale (LC_NUMERIC, num_locale);
}

void add_account (ACCOUNT *account) {
    ACC_ELT *acc, *prev_acc, *support;

    acc      = config.acc_list_head;
    prev_acc = acc;
    while (acc != NULL) {
        prev_acc = acc;
        acc      = acc->next;
    }
    support                = acc_list_elt_new ();
    support->account       = account;
    support->next          = acc;
    if (prev_acc != NULL)
        prev_acc->next     = support;
    else
        config.acc_list_head  = support;
    config.AccDataModified    = VRAI;
}

void del_account (ACC_ELT *element) {
    ACC_ELT *acc = NULL, *prev = NULL;

    if(config.acc_list_head == element) {
        config.acc_list_head = config.acc_list_head->next;
    } else {
        acc  = config.acc_list_head;
        while ( (acc->next != NULL) && (acc != element) ) {
            prev = acc;
            acc  = acc->next;
        }
    }
    
    if (prev != NULL) prev->next = element->next;

    free (element->account->name);
    free (element->account->num);
    free (element->account->bank);
    free (element->account->date);
    free (element->account);
    free (element);
    config.AccDataModified = VRAI;
}

ACC_ELT *get_account (int acc_num) {
    ACC_ELT *acc;
    int      i = 0;

    acc = config.acc_list_head;
    while ( (i != acc_num) && (acc != NULL) ) {
        acc = acc->next;
        i++;
    }

    return acc;
}

ACC_ELT *get_account_with_name (const char *acc_name) {
    ACC_ELT *acc;

    acc = config.acc_list_head;
    while ( (acc != NULL) && (strcmp (acc_name, acc->account->name) != 0) ) {
        acc = acc->next;
    }

    return acc;
}

void free_accounts () {
    ACC_ELT *p = config.acc_list_head, *q;

    while (p != NULL) {
        q = p->next;
        free_ope_list (&p->account->ope_list_head);
        free (p->account->name);
        free (p->account->num);
        free (p->account->bank);
        free (p->account->date);
        free (p->account);
        free (p);
        p = q;
    }
    config.acc_list_head = NULL;
}

ACCOUNT *account_new () {
    ACCOUNT *acc;

    MY_ALLOC (acc, 1, ACCOUNT);

    acc->name   = NULL;
    acc->num    = NULL;
    acc->bank   = NULL;
    acc->date   = NULL;
    acc->amount = 0.0;
    acc->ope_list_head = NULL;

    return acc;
}

ACCOUNT *get_account_from_line (const char *line) {
    ACCOUNT *acc = account_new ();
    char    *elt = NULL;
    int      i = 0, j = 0, k = 0;

    MY_ALLOC (elt, MAXSTRLEN + 1, char);
    for (i = 0 ; i < strlen (line) ; i++) {
        if ( (line[i] != '\t') && (line[i] != '\n') ){
            elt[j] = line[i];
            j++;
        } else {
            elt[j] = 0;
            j      = 0;
#if DEBUG_LEVEL>1
            printf ("Niveau %s -- ",
                    k == 0 ? "NAME  " :
                    k == 1 ? "NUM   " :
                    k == 2 ? "BANK  " :
                    k == 3 ? "DATE  " :
                    k == 4 ? "EURO"   : "AMOUNT");
            printf ("Élement reconnu : %s\n", elt);
#endif
            switch (k) {
                case  0 :
                    if (elt[0] != 0) {
                        MY_ALLOC (acc->name, strlen (elt) + 1, char);
                        strcpy (acc->name, elt);
                    } else acc->name = NULL;
                    break;
                case  1 :
                    if (elt[0] != 0) {
                        MY_ALLOC (acc->num, strlen (elt) + 1, char);
                        strcpy (acc->num, elt);
                    } else acc->num = NULL;
                    break;
                case  2 :
                    if (elt[0] != 0) {
                        MY_ALLOC (acc->bank, strlen (elt) + 1, char);
                        strcpy (acc->bank, elt);
                    } else acc->bank = NULL;
                    break;
                case  3 :
                    if (elt[0] != 0) {
                        MY_ALLOC (acc->date, strlen (elt) + 1, char);
                        strcpy (acc->date, elt);
                    } else acc->date = NULL;
                    break;
                case  4 : acc->euro      = atoi (elt);
                case  5 : acc->amount    = atof (elt);
                    break;
                default : MY_STOP;
            }
            k++;
        }
    }
    free (elt);
    return acc;
}

char *create_line_from_account (ACCOUNT *acc) {
    char *line;

    MY_ALLOC (line, MAXSTRLEN + 1, char);
    sprintf (line, "%s\t%s\t%s\t%s\t%d\t%.5f\n",
             ( (acc != NULL) && (acc->name != NULL) ) ? acc->name   : "",
             ( (acc != NULL) && (acc->num  != NULL) ) ? acc->num    : "",
             ( (acc != NULL) && (acc->bank != NULL) ) ? acc->bank   : "",
             ( (acc != NULL) && (acc->date != NULL) ) ? acc->date   : "",
             ( (acc != NULL) )                        ? acc->euro   :  0,
             ( (acc != NULL) )                        ? acc->amount :  0);
    return line;
}

ACC_ELT *acc_list_elt_new () {
    ACC_ELT *elt;
    
    MY_ALLOC (elt, 1, ACC_ELT);

    elt->account = NULL;
    elt->next    = NULL;

    return elt;
}

void acc_set_name (ACCOUNT *acc, const char *name) {
    if (name != NULL) {
        if (acc->name != NULL) free (acc->name);
        MY_ALLOC (acc->name, (strlen (name) + 1), char);
        strcpy (acc->name, name);
        config.AccDataModified = VRAI;
    }
}

void acc_set_num (ACCOUNT *acc, const char *num) {
    if (num != NULL) {
        if (acc->num != NULL) free (acc->num);
        MY_ALLOC (acc->num, (strlen (num) + 1), char);
        strcpy (acc->num, num);
        config.AccDataModified = VRAI;
    }
}

void acc_set_bank (ACCOUNT *acc, const char *bank) {
    if (bank != NULL) {
        if (acc->bank != NULL) free (acc->bank);
        MY_ALLOC (acc->bank, (strlen (bank) + 1), char);
        strcpy (acc->bank, bank);
        config.AccDataModified = VRAI;
    }
}

void acc_set_date (ACCOUNT *acc, const char *date) {
    if (date != NULL) {
        if (acc->date != NULL) free (acc->date);
        MY_ALLOC (acc->date, (strlen (date) + 1), char);
        strcpy (acc->date, date);
        config.AccDataModified = VRAI;
    }
}

void acc_set_amount (ACCOUNT *acc, float amount) {
    acc->amount = amount;
    config.AccDataModified = VRAI;
}

int nb_ope (ACC_ELT *acc) {
    OPE_ELT *ope = acc->account->ope_list_head;
    int      nb  = 0;

    while (ope != NULL) {
        nb++;
        ope = ope->next;
    }
    return nb;
}



Generated by  Doxygen 1.6.0   Back to index