Ejemplo n.º 1
0
/**
 * Parse XML book nodes from a gnucash file.
 *
 * Main role of this function is to iterate over XML nodes of the file
 * and determine which account nodes are category nodes and which are
 * real accounts, as in Gnucash, accounts and categories are mixed.
 *
 * \param book_node	Pointer to current XML node.
 */
void recuperation_donnees_gnucash_book ( xmlNodePtr book_node )
{
    xmlNodePtr child_node;

    child_node = book_node -> children;

    while ( child_node )
    {
	/* Books are subdivisions of gnucash files */
	if ( node_strcmp ( child_node, "book" ) )
        {
	    recuperation_donnees_gnucash_book ( child_node );
	}

	if ( node_strcmp(child_node, "account") )
        {
	    gchar * type = child_content ( child_node, "type");
	    if ( strcmp(type, "INCOME") && strcmp(type, "EXPENSE") && strcmp(type, "EXPENSES") &&
	       strcmp(type, "EQUITY") )
	    {
		recuperation_donnees_gnucash_compte ( child_node );
	    }
	    else
	    {
		recuperation_donnees_gnucash_categorie ( child_node );
	    }
	}

	if ( node_strcmp(child_node, "transaction") )
        {
	    recuperation_donnees_gnucash_transaction ( child_node );
	}

	child_node = child_node -> next;
    }
}
Ejemplo n.º 2
0
xmlNodePtr get_child ( xmlNodePtr node, gchar * child_name )
{
  xmlNodePtr iter_node = node -> children;

  if (!node) return NULL;

  while ( iter_node )
    {
      if ( node_strcmp(iter_node, child_name) )
	return iter_node;

      iter_node = iter_node -> next;
    }

  return NULL;
}
Ejemplo n.º 3
0
/**
 * Parse XML transaction node and fill a ImportTransaction with results.
 *
 * \param transaction_node	XML transaction node to parse.
 */
void recuperation_donnees_gnucash_transaction ( xmlNodePtr transaction_node )
{
  struct ImportTransaction * transaction;
  struct ImportAccount * account = NULL;
  struct gnucash_split * split;
  gchar * date_string, *space, *tiers;
  GDate * date;
  xmlNodePtr splits, split_node, date_node;
  GSList * split_list = NULL;
  GsbReal total = { 0 , 0 };

  /* Transaction amount, category, account, etc.. */
  splits = get_child ( transaction_node, "splits" );
  split_node = splits -> children;

  while ( split_node )
    {
      struct ImportAccount * split_account = NULL;
      struct gnucash_category * categ = NULL;
      gint p_r = OPERATION_NORMALE;
      GsbReal amount;

      /**
       * Gnucash transactions are in fact "splits", much like grisbi's
       * splits of transactions.  We need to parse all splits and
       * see whether they are transfers to real accounts or transfers
       * to category accounts.  In that case, we only create one
       * transactions.  The other is discarded as grisbi is not a
       * double part financial engine.
       */
      if ( node_strcmp ( split_node, "split" ) )
	{
	  gchar * account_name = NULL, * categ_name = NULL;

	  split_account = find_imported_account_by_uid ( child_content ( split_node,
									"account" ) );
	  categ = find_imported_categ_by_uid ( child_content ( split_node, "account" ) );
	  amount = gnucash_value ( child_content(split_node, "value") );

	  if ( categ )
	    categ_name = categ -> name;
	  if ( split_account )
	    {
	      /* All of this stuff is here since we are dealing with
		 the account split, not the category one */
	      account_name = split_account -> nom_de_compte;
	      total = gsb_real_add ( total,
				     amount );
	      if ( strcmp(child_content(split_node, "reconciled-state"), "n") )
		p_r = OPERATION_RAPPROCHEE;
	    }

	  split = find_split ( split_list, amount, split_account, categ );
	  if ( split )
	    {
	      update_split ( split, amount, account_name, categ_name );
	    }
	  else
	    {
	      split = new_split ( amount, account_name, categ_name );
	      split_list = g_slist_append ( split_list, split );
	      split -> notes = child_content(split_node, "memo");
	    }
	  if ( p_r != OPERATION_NORMALE )
	      split -> p_r = p_r;
	}

      split_node = split_node -> next;
    }

  if ( ! split_list )
    return;

  /* Transaction date */
  date_node = get_child ( transaction_node, "date-posted" );
  date_string = child_content (date_node, "date");
  space = strchr ( date_string, ' ' );
  if ( space )
    *space = 0;
  date = g_date_new ();
  g_date_set_parse ( date, date_string );
  if ( !g_date_valid ( date ))
    fprintf ( stderr, "grisbi: Can't parse date %s\n", date_string );

  /* Tiers */
  tiers = child_content ( transaction_node, "description" );

  /* Create transaction */
  split = split_list -> data;
  transaction = new_transaction_from_split ( split, tiers, date );
  transaction -> operation_ventilee = 0;
  transaction -> ope_de_ventilation = 0;
  account = find_imported_account_by_name ( split -> account );
  if ( account )
    account -> operations_importees = g_slist_append ( account -> operations_importees, transaction );

  /** Splits of transactions are handled the same way, we process
      them if we find more than one split in transaction node. */
  if ( g_slist_length ( split_list ) > 1 )
    {
      transaction -> operation_ventilee = 1;
      transaction -> montant = total;

      while ( split_list )
	{
	  split = split_list -> data;
	  account = NULL;

	  transaction = new_transaction_from_split ( split, tiers, date );
	  transaction -> ope_de_ventilation = 1;

	  account = find_imported_account_by_name ( split -> account );
	  if ( account )
	    account -> operations_importees = g_slist_append ( account -> operations_importees, transaction );

	  split_list = split_list -> next;
	}
    }
}