]>
Dogcows Code - chaz/homebank/blob - src/hb-import.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "hb-import.h"
24 /****************************************************************************/
26 /****************************************************************************/
35 /* our global datas */
36 extern struct HomeBank
*GLOBALS
;
37 extern struct Preferences
*PREFS
;
40 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
43 static gint
homebank_alienfile_recognize(gchar
*filename
)
46 gint i
, retval
= FILETYPE_UNKNOWN
;
51 DB( g_print("\n[homebank] alienfile_recognize\n") );
53 io
= g_io_channel_new_file(filename
, "r", NULL
);
56 g_io_channel_set_encoding(io
, NULL
, NULL
); /* set to binary mode */
60 if( retval
!= FILETYPE_UNKNOWN
)
63 io_stat
= g_io_channel_read_line(io
, &tmpstr
, NULL
, NULL
, &err
);
64 if( io_stat
== G_IO_STATUS_EOF
)
66 if( io_stat
== G_IO_STATUS_ERROR
)
68 DB (g_print(" + ERROR %s\n",err
->message
));
71 if( io_stat
== G_IO_STATUS_NORMAL
)
75 DB( g_print(" line %d: '%s' retval=%d\n", i
, tmpstr
, retval
) );
78 if( g_strstr_len(tmpstr
, -1, "<OFX>") != NULL
79 || g_strstr_len(tmpstr
, -1, "<ofx>") != NULL
80 /*|| strcasestr(tmpstr, "<OFC>") != NULL*/
83 DB( g_print(" type is OFX\n") );
84 retval
= FILETYPE_OFX
;
89 if( g_str_has_prefix(tmpstr
, "!Type") ||
90 g_str_has_prefix(tmpstr
, "!type") ||
91 g_str_has_prefix(tmpstr
, "!Option") ||
92 g_str_has_prefix(tmpstr
, "!option") ||
93 g_str_has_prefix(tmpstr
, "!Account") ||
94 g_str_has_prefix(tmpstr
, "!account")
97 DB( g_print(" type is QIF\n") );
98 retval
= FILETYPE_QIF
;
102 // CSV homebank format ?
103 if( hb_csv_test_line(tmpstr
) )
105 DB( g_print(" type is CSV homebank\n") );
106 retval
= FILETYPE_CSV_HB
;
110 // native homebank file ?
111 if( g_str_has_prefix(tmpstr
, "<homebank v="))
113 DB( g_print(" type is HomeBank\n") );
114 retval
= FILETYPE_HOMEBANK
;
122 g_io_channel_unref (io
);
133 da_import_context_gen_txn_destroy(ImportContext
*context
)
137 DB( g_print("\n[import] free gen txn list\n") );
138 list
= g_list_first(context
->gen_lst_txn
);
141 GenTxn
*gentxn
= list
->data
;
142 da_gen_txn_free(gentxn
);
143 list
= g_list_next(list
);
145 g_list_free(context
->gen_lst_txn
);
146 context
->gen_lst_txn
= NULL
;
151 da_import_context_gen_acc_destroy(ImportContext
*context
)
155 DB( g_print("\n[import] free gen acc list\n") );
156 list
= g_list_first(context
->gen_lst_acc
);
159 GenAcc
*genacc
= list
->data
;
160 da_gen_acc_free(genacc
);
161 list
= g_list_next(list
);
163 g_list_free(context
->gen_lst_acc
);
164 context
->gen_lst_acc
= NULL
;
170 da_import_context_clear(ImportContext
*context
)
172 DB( g_print("\n[import] context clear\n") );
174 da_import_context_gen_txn_destroy(context
);
175 da_import_context_gen_acc_destroy(context
);
176 context
->gen_next_acckey
= 1;
182 da_import_context_destroy(ImportContext
*context
)
186 DB( g_print("\n[import] context destroy\n") );
188 da_import_context_gen_txn_destroy(context
);
189 da_import_context_gen_acc_destroy(context
);
191 DB( g_print(" free gen file list\n") );
192 list
= g_list_first(context
->gen_lst_file
);
195 GenFile
*genfile
= list
->data
;
196 da_gen_file_free(genfile
);
197 list
= g_list_next(list
);
199 g_list_free(context
->gen_lst_file
);
200 context
->gen_lst_file
= NULL
;
205 da_import_context_new(ImportContext
*context
)
207 context
->gen_lst_file
= NULL
;
209 context
->gen_lst_acc
= NULL
;
210 context
->gen_lst_txn
= NULL
;
211 context
->gen_next_acckey
= 1;
215 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
218 da_gen_file_malloc(void)
220 return g_malloc0(sizeof(GenFile
));
224 da_gen_file_free(GenFile
*genfile
)
228 if(genfile
->filepath
!= NULL
)
229 g_free(genfile
->filepath
);
237 da_gen_file_get(GList
*lst_file
, guint32 key
)
239 GenFile
*existfile
= NULL
;
242 list
= g_list_first(lst_file
);
245 GenFile
*genfile
= list
->data
;
247 if( key
== genfile
->key
)
252 list
= g_list_next(list
);
259 da_gen_file_get_by_name(GList
*lst_file
, gchar
*filepath
)
261 GenFile
*existfile
= NULL
;
264 DB( g_print("da_gen_file_get_by_name\n") );
266 list
= g_list_first(lst_file
);
269 GenFile
*genfile
= list
->data
;
271 DB( g_print(" strcasecmp '%s' '%s'\n", filepath
, genfile
->filepath
) );
273 if(!strcasecmp(filepath
, genfile
->filepath
))
276 DB( g_print(" found\n") );
279 list
= g_list_next(list
);
287 da_gen_file_append_from_filename(ImportContext
*ictx
, gchar
*filename
)
289 GenFile
*genfile
= NULL
;
292 //todo: should check if its a file !!
294 filetype
= homebank_alienfile_recognize(filename
);
296 DB( g_print(" - filename '%s', type is %d\n", filename
, filetype
) );
298 // we keep everything here
299 //if( (filetype == FILETYPE_OFX) || (filetype == FILETYPE_QIF) || (filetype == FILETYPE_CSV_HB) )
301 GenFile
*existgenfile
;
303 existgenfile
= da_gen_file_get_by_name(ictx
->gen_lst_file
, filename
);
304 if(existgenfile
== NULL
)
306 genfile
= da_gen_file_malloc();
307 genfile
->filepath
= g_strdup(filename
);
308 genfile
->filetype
= filetype
;
311 genfile
->key
= g_list_length (ictx
->gen_lst_file
) + 1;
312 ictx
->gen_lst_file
= g_list_append(ictx
->gen_lst_file
, genfile
);
321 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
325 da_gen_acc_malloc(void)
327 return g_malloc0(sizeof(GenAcc
));
331 da_gen_acc_free(GenAcc
*genacc
)
335 if(genacc
->name
!= NULL
)
336 g_free(genacc
->name
);
337 if(genacc
->number
!= NULL
)
338 g_free(genacc
->number
);
346 da_gen_acc_get_by_key(GList
*lst_acc
, guint32 key
)
348 GenAcc
*existacc
= NULL
;
351 list
= g_list_first(lst_acc
);
354 GenAcc
*genacc
= list
->data
;
356 if( key
== genacc
->key
)
361 list
= g_list_next(list
);
368 da_gen_acc_get_by_name(GList
*lst_acc
, gchar
*name
)
370 GenAcc
*existacc
= NULL
;
373 //DB( g_print("da_gen_acc_get_by_name\n") );
375 list
= g_list_first(lst_acc
);
378 GenAcc
*genacc
= list
->data
;
380 //DB( g_print(" strcasecmp '%s' '%s'\n", name, genacc->name) );
382 if(!strcasecmp(name
, genacc
->name
))
385 //DB( g_print(" found\n") );
388 list
= g_list_next(list
);
396 hb_import_acc_find_existing(gchar
*name
, gchar
*number
)
398 Account
*retacc
= NULL
;
401 DB( g_print("\n[import] acc_find_existing\n") );
403 DB( g_print(" - search number '%s'\n", number
) );
404 lacc
= list
= g_hash_table_get_values(GLOBALS
->h_acc
);
407 Account
*acc
= list
->data
;
409 //DB( g_print(" - eval acc '%s' or '%s'\n", acc->name, acc->number) );
410 if(number
!= NULL
&& acc
->number
&& strlen(acc
->number
) )
412 //prefer identifying with number & search number into acc->number
413 if(g_strstr_len(number
, -1, acc
->number
) != NULL
)
415 DB( g_print(" - match number '%s'\n", acc
->number
) );
420 list
= g_list_next(list
);
423 //# 1815964 only test name if all number test failed
424 //if not found try with name
427 DB( g_print(" - search name '%s'\n", name
) );
428 list
= g_list_first(lacc
);
431 Account
*acc
= list
->data
;
433 //DB( g_print(" - eval acc '%s' or '%s'\n", acc->name, acc->number) );
434 if(retacc
== NULL
&& name
!= NULL
)
436 if(g_strstr_len(name
, -1, acc
->name
) != NULL
)
438 DB( g_print(" - match name '%s'\n", acc
->name
) );
443 list
= g_list_next(list
);
454 hb_import_gen_acc_get_next(ImportContext
*ictx
, gint filetype
, gchar
*name
, gchar
*number
)
458 DB( g_print("\n[import] acc_get_next\n") );
460 DB( g_print(" - type='%d', name='%s', number='%s'\n", filetype
, name
, number
) );
462 // try to find a same name account
465 newacc
= da_gen_acc_get_by_name(ictx
->gen_lst_acc
, name
);
468 DB( g_print(" - found existing '%s'\n", name
) );
473 newacc
= da_gen_acc_malloc();
476 newacc
->kfile
= ictx
->curr_kfile
;
477 newacc
->key
= ictx
->gen_next_acckey
++;
478 newacc
->kacc
= DST_ACC_GLOBAL
;
482 newacc
->is_unamed
= FALSE
;
483 newacc
->name
= g_strdup(name
);
490 newacc
->is_unamed
= TRUE
;
492 genfile
= da_gen_file_get (ictx
->gen_lst_file
, newacc
->kfile
);
493 basename
= g_path_get_basename(genfile
->filepath
);
495 newacc
->name
= g_strdup_printf("%s %d", basename
, newacc
->key
);
500 newacc
->number
= g_strdup(number
);
502 ictx
->gen_lst_acc
= g_list_append(ictx
->gen_lst_acc
, newacc
);
505 DB( g_print(" - create new '%s'\n", newacc
->name
) );
508 newacc
->filetype
= filetype
;
509 ictx
->curr_kacc
= newacc
->key
;
515 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
519 da_gen_txn_malloc(void)
521 return g_malloc0(sizeof(GenTxn
));
526 da_gen_txn_free(GenTxn
*gentxn
)
532 if(gentxn
->account
!= NULL
)
533 g_free(gentxn
->account
);
535 if(gentxn
->rawinfo
!= NULL
)
536 g_free(gentxn
->rawinfo
);
537 if(gentxn
->rawpayee
!= NULL
)
538 g_free(gentxn
->rawpayee
);
539 if(gentxn
->rawmemo
!= NULL
)
540 g_free(gentxn
->rawmemo
);
542 if(gentxn
->date
!= NULL
)
543 g_free(gentxn
->date
);
544 if(gentxn
->info
!= NULL
)
545 g_free(gentxn
->info
);
546 if(gentxn
->payee
!= NULL
)
547 g_free(gentxn
->payee
);
548 if(gentxn
->memo
!= NULL
)
549 g_free(gentxn
->memo
);
550 if(gentxn
->category
!= NULL
)
551 g_free(gentxn
->category
);
552 if(gentxn
->tags
!= NULL
)
553 g_free(gentxn
->tags
);
555 for(i
=0;i
<TXN_MAX_SPLIT
;i
++)
557 GenSplit
*s
= &gentxn
->splits
[i
];
561 if(s
->category
!= NULL
)
565 if(gentxn
->lst_existing
!= NULL
)
567 g_list_free(gentxn
->lst_existing
);
568 gentxn
->lst_existing
= NULL
;
576 da_gen_txn_compare_func(GenTxn
*a
, GenTxn
*b
)
578 gint retval
= (gint
)(a
->julian
- b
->julian
);
581 retval
= (ABS(a
->amount
) - ABS(b
->amount
)) > 0 ? 1 : -1;
587 da_gen_txn_sort(GList
*list
)
589 return( g_list_sort(list
, (GCompareFunc
)da_gen_txn_compare_func
));
594 da_gen_txn_move(GenTxn
*sgentxn
, GenTxn
*dgentxn
)
596 if(sgentxn
!= NULL
&& dgentxn
!= NULL
)
598 memcpy(dgentxn
, sgentxn
, sizeof(GenTxn
));
599 memset(sgentxn
, 0, sizeof(GenTxn
));
605 da_gen_txn_append(ImportContext
*ctx
, GenTxn
*gentxn
)
607 gentxn
->kfile
= ctx
->curr_kfile
;
608 gentxn
->kacc
= ctx
->curr_kacc
;
609 gentxn
->to_import
= TRUE
;
610 ctx
->gen_lst_txn
= g_list_append(ctx
->gen_lst_txn
, gentxn
);
614 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
617 static void _string_utf8_ucfirst(gchar
**str
)
625 str_len
= strlen(*str
);
629 first
= g_utf8_strup(*str
, 1);
630 lc
= g_utf8_strdown( g_utf8_next_char(*str
), -1 );
632 *str
= g_strjoin(NULL
, first
, lc
, NULL
);
639 _string_concat(gchar
*str
, gchar
*addon
)
643 DB( g_print(" - concat '%s' + '%s'\n", str
, addon
) );
646 retval
= g_strdup(addon
);
649 retval
= g_strjoin(" ", str
, addon
, NULL
);
653 DB( g_print(" - retval='%s'\n", retval
) );
658 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
660 gchar
*hb_import_filetype_char_get(GenAcc
*genacc
)
664 switch(genacc
->filetype
)
675 case FILETYPE_CSV_HB
:
685 hb_import_load_all(ImportContext
*ictx
)
689 DB( g_print("\n[import] load all\n") );
691 da_import_context_clear (ictx
);
693 list
= g_list_first(ictx
->gen_lst_file
);
696 GenFile
*genfile
= list
->data
;
698 if(genfile
->filetype
!= FILETYPE_UNKNOWN
)
700 //todo: move this to alien analysis
701 genfile
->encoding
= homebank_file_getencoding(genfile
->filepath
);
703 ictx
->curr_kfile
= genfile
->key
;
705 DB( g_print(" -> key = '%d'\n", genfile
->key
) );
706 DB( g_print(" -> filepath = '%s'\n", genfile
->filepath
) );
707 DB( g_print(" -> encoding = '%s'\n", genfile
->encoding
) );
709 genfile
->loaded
= FALSE
;
710 genfile
->invaliddatefmt
= FALSE
;
712 switch(genfile
->filetype
)
716 homebank_ofx_import(ictx
, genfile
);
720 homebank_qif_import(ictx
, genfile
);
723 case FILETYPE_CSV_HB
:
724 homebank_csv_import(ictx
, genfile
);
728 genfile
->loaded
= TRUE
;
731 list
= g_list_next(list
);
735 ictx
->gen_lst_txn
= da_gen_txn_sort(ictx
->gen_lst_txn
);
741 hb_import_gen_acc_count_txn(ImportContext
*ictx
, GenAcc
*genacc
)
746 DB( g_print("\n[import] gen_acc_count_txn\n") );
748 genacc
->n_txnall
= 0;
749 genacc
->n_txnimp
= 0;
751 list
= g_list_first(ictx
->gen_lst_txn
);
754 GenTxn
*gentxn
= list
->data
;
756 if(gentxn
->kacc
== genacc
->key
)
761 DB( g_print(" count %03d: gentxn in=%d dup=%d '%s'\n", count
, gentxn
->to_import
, gentxn
->is_dst_similar
, gentxn
->memo
) );
763 if(gentxn
->to_import
)
766 list
= g_list_next(list
);
773 * uncheck duplicate within the import context files
776 hb_import_gen_txn_check_duplicate(ImportContext
*ictx
, GenAcc
*genacc
)
778 GList
*list1
, *list2
;
781 DB( g_print("\n[import] gen_txn_check_duplicate\n") );
784 list1
= g_list_first(ictx
->gen_lst_txn
);
785 while (list1
!= NULL
)
787 GenTxn
*gentxn1
= list1
->data
;
789 if( (genacc
->key
== gentxn1
->kacc
) && (gentxn1
->julian
!= 0) ) //same account, valid date
791 list2
= g_list_next(list1
);
792 while (list2
!= NULL
)
794 GenTxn
*gentxn2
= list2
->data
;
796 if( (gentxn2
->julian
> gentxn1
->julian
) )
799 //todo: maybe reinforce controls here
800 if( (gentxn2
->kacc
== gentxn1
->kacc
)
801 && (gentxn2
->julian
== gentxn1
->julian
)
802 && (gentxn2
->amount
== gentxn1
->amount
)
803 && (hb_string_compare(gentxn2
->memo
, gentxn1
->memo
) == 0)
804 && (hb_string_compare(gentxn2
->payee
, gentxn1
->payee
) == 0)
807 gentxn1
->to_import
= FALSE
;
808 gentxn1
->is_imp_similar
= TRUE
;
811 DB( g_print(" found import dup %d=%d %.2f %.2f in=%d dup=%d\n", gentxn1
->julian
, gentxn2
->julian
, gentxn2
->amount
, gentxn1
->amount
, gentxn1
->to_import
, gentxn1
->is_imp_similar
) );
814 list2
= g_list_next(list2
);
817 list1
= g_list_next(list1
);
824 * uncheck existing txn into target account
828 hb_import_gen_txn_check_target_similar(ImportContext
*ictx
, GenAcc
*genacc
)
830 GList
*list1
, *list2
;
833 DB( g_print("\n[import] gen_txn_check_target_similar\n") );
835 list1
= g_list_first(ictx
->gen_lst_txn
);
836 while (list1
!= NULL
)
838 GenTxn
*gentxn
= list1
->data
;
840 if(genacc
->key
== gentxn
->kacc
)
842 gentxn
->to_import
= TRUE
;
843 gentxn
->is_dst_similar
= FALSE
;
845 if(genacc
->kacc
== DST_ACC_SKIP
)
847 gentxn
->to_import
= FALSE
;
851 Account
*acc
= da_acc_get(genacc
->kacc
);
855 //clear previous existing
856 if(gentxn
->lst_existing
!= NULL
)
858 g_list_free(gentxn
->lst_existing
);
859 gentxn
->lst_existing
= NULL
;
862 // try to find existing transaction
863 list2
= g_queue_peek_tail_link(acc
->txn_queue
);
864 while (list2
!= NULL
)
866 Transaction
*txn
= list2
->data
;
868 //break if the date goes below the gentxn date + gap
869 if( txn
->date
< (gentxn
->julian
- ictx
->opt_daygap
) )
872 //#1586211 add of date tolerance
873 //todo: maybe reinforce controls here
874 if( ( txn
->kacc
== genacc
->kacc
)
875 && ( gentxn
->julian
<= (txn
->date
+ ictx
->opt_daygap
) )
876 && ( gentxn
->julian
>= (txn
->date
- ictx
->opt_daygap
) )
877 && ( txn
->amount
== gentxn
->amount
)
880 gentxn
->lst_existing
= g_list_append(gentxn
->lst_existing
, txn
);
881 gentxn
->to_import
= FALSE
;
882 gentxn
->is_dst_similar
= TRUE
;
885 DB( g_print(" found dst acc dup %d %.2f '%s' in=%d, dup=%d\n", gentxn
->julian
, gentxn
->amount
, gentxn
->memo
, gentxn
->to_import
, gentxn
->is_dst_similar
) );
888 list2
= g_list_previous(list2
);
895 list1
= g_list_next(list1
);
903 * try to indentify xfer for OFX
907 hb_import_gen_xfer_eval(ImportContext
*ictx
, GList
*list
)
909 GList
*root
, *list1
, *list2
;
913 DB( g_print("\n[import] gen xfer eval\n") );
915 root
= list1
= g_list_first(list
);
916 while (list1
!= NULL
)
918 Transaction
*txn1
= list1
->data
;
921 acc
= da_gen_acc_get_by_key(ictx
->gen_lst_acc
, txn1
->kacc
);
923 DB( g_print(" src: kacc:%d dat:%d amt:%.2f %s kfxacc:%d\n", txn1
->kacc
, txn1
->date
, txn1
->amount
, txn1
->memo
, txn1
->kxferacc
) );
925 if( (acc
!= NULL
) && (acc
->filetype
== FILETYPE_OFX
) )
929 list2
= g_list_next(root
);
930 while (list2
!= NULL
)
932 Transaction
*txn2
= list2
->data
;
934 //DB( g_print(" -- chk: kacc:%d dat:%d amt:%.2f %s\n", txn2->kacc, txn2->date, txn2->amount, txn2->memo) );
935 if( (txn2
->date
> txn1
->date
) )
938 if( (txn2
== txn1
) || (txn2
->paymode
== PAYMODE_INTXFER
) )
941 //todo: maybe reinforce controls here
942 if( (txn2
->kacc
!= txn1
->kacc
)
943 && (txn2
->date
== txn1
->date
)
944 && (txn2
->amount
== -txn1
->amount
)
945 && (hb_string_compare(txn2
->memo
, txn1
->memo
) == 0)
948 DB( g_print(" match: kacc:%d dat:%d amt:%.2f %s kfxacc:%d\n", txn2
->kacc
, txn2
->date
, txn2
->amount
, txn2
->memo
, txn2
->kxferacc
) );
949 match
= g_list_append(match
, txn2
);
953 list2
= g_list_next(list2
);
956 if(count
== 1) //we found a single potential xfer, transform it
960 DB( g_print(" single found => convert both\n") );
962 list2
= g_list_first(match
);
966 txn1
->paymode
= PAYMODE_INTXFER
;
967 transaction_xfer_change_to_child(txn1
, txn2
);
969 /*list2 = g_list_first(match);
972 txn1->paymode = PAYMODE_INTXFER;
973 txn1->kxferacc = txn2->kacc;
975 txn2->paymode = PAYMODE_INTXFER;
976 txn2->kxferacc = txn1->kacc;
979 // if more than one, we cannot be sure
983 list1
= g_list_next(list1
);
991 * apply the user option: date format, payee/memo/info mapping
995 hb_import_option_apply(ImportContext
*ictx
, GenAcc
*genacc
)
999 DB( g_print("\n[import] option apply\n") );
1001 DB( g_print(" - type=%d\n", genacc
->filetype
) );
1003 genacc
->n_txnbaddate
= 0;
1005 list
= g_list_first(ictx
->gen_lst_txn
);
1006 while (list
!= NULL
)
1008 GenTxn
*gentxn
= list
->data
;
1010 if(gentxn
->kacc
== genacc
->key
)
1012 if(genacc
->filetype
!= FILETYPE_OFX
)
1014 gentxn
->julian
= hb_date_get_julian(gentxn
->date
, ictx
->opt_dateorder
);
1015 if( gentxn
->julian
== 0 )
1017 genacc
->n_txnbaddate
++;
1021 if(genacc
->filetype
== FILETYPE_OFX
)
1023 DB( g_print(" - ofx option apply\n") );
1025 g_free(gentxn
->payee
);
1026 g_free(gentxn
->memo
);
1027 g_free(gentxn
->info
);
1028 gentxn
->payee
= NULL
;
1029 gentxn
->memo
= NULL
;
1030 gentxn
->info
= NULL
;
1033 gentxn
->info
= g_strdup(gentxn
->rawinfo
);
1035 //#1791482 map name to info (concat only)
1036 switch(ictx
->opt_ofxname
)
1038 //ofxname is stored into rawpayee
1040 gentxn
->memo
= g_strdup(gentxn
->rawpayee
);
1043 gentxn
->payee
= g_strdup(gentxn
->rawpayee
);
1046 g_free(gentxn
->info
);
1047 gentxn
->info
= _string_concat(gentxn
->rawinfo
, gentxn
->rawpayee
);
1051 if(gentxn
->rawmemo
!= NULL
)
1053 switch(ictx
->opt_ofxmemo
)
1056 case 1: //add to info
1057 gentxn
->info
= _string_concat(gentxn
->info
, gentxn
->rawmemo
);
1060 case 2: //add to memo
1061 gentxn
->memo
= _string_concat(gentxn
->memo
, gentxn
->rawmemo
);
1064 case 3: //add to payee
1065 gentxn
->payee
= _string_concat(gentxn
->payee
, gentxn
->rawmemo
);
1070 DB( g_print(" - payee is '%s'\n", gentxn
->payee
) );
1071 DB( g_print(" - memo is '%s'\n", gentxn
->memo
) );
1072 DB( g_print(" - info is '%s'\n", gentxn
->info
) );
1073 DB( g_print("\n") );
1077 if(genacc
->filetype
== FILETYPE_QIF
)
1079 DB( g_print(" - qif option apply\n") );
1081 g_free(gentxn
->payee
);
1082 g_free(gentxn
->memo
);
1083 gentxn
->payee
= NULL
;
1084 gentxn
->memo
= NULL
;
1086 if(!ictx
->opt_qifswap
)
1088 gentxn
->payee
= g_strdup(gentxn
->rawpayee
);
1089 if(ictx
->opt_qifmemo
)
1090 gentxn
->memo
= g_strdup(gentxn
->rawmemo
);
1094 gentxn
->payee
= g_strdup(gentxn
->rawmemo
);
1095 if(ictx
->opt_qifmemo
)
1096 gentxn
->memo
= g_strdup(gentxn
->rawpayee
);
1099 DB( g_print(" - payee is '%s'\n", gentxn
->payee
) );
1100 DB( g_print(" - memo is '%s'\n", gentxn
->memo
) );
1104 if(genacc
->filetype
== FILETYPE_CSV_HB
)
1106 DB( g_print(" - csv option apply\n") );
1108 //#1791656 missing: info, payee and tagsg_freg_free(gentxn->payee);
1109 g_free(gentxn
->payee
);
1110 g_free(gentxn
->memo
);
1111 g_free(gentxn
->info
);
1113 gentxn
->payee
= g_strdup(gentxn
->rawpayee
);
1114 gentxn
->memo
= g_strdup(gentxn
->rawmemo
);
1115 gentxn
->info
= g_strdup(gentxn
->rawinfo
);
1118 //at last do ucfirst
1119 if( (ictx
->opt_ucfirst
== TRUE
) )
1121 _string_utf8_ucfirst(&gentxn
->memo
);
1122 _string_utf8_ucfirst(&gentxn
->payee
);
1127 list
= g_list_next(list
);
1130 DB( g_print(" - nb_err=%d\n", genacc
->n_txnbaddate
) );
1132 return genacc
->n_txnbaddate
== 0 ? TRUE
: FALSE
;
1137 * convert a GenTxn to a Transaction
1141 hb_import_convert_txn(GenAcc
*genacc
, GenTxn
*gentxn
)
1143 Transaction
*newope
;
1149 DB( g_print("\n[import] convert txn\n") );
1153 DB( g_print(" - gentxt %s %s %s\n", gentxn
->account
, gentxn
->date
, gentxn
->memo
) );
1154 DB( g_print(" - genacc '%s' '%p'\n", gentxn
->account
, genacc
) );
1158 newope
= da_transaction_malloc();
1160 newope
->kacc
= genacc
->kacc
;
1161 newope
->date
= gentxn
->julian
;
1162 newope
->paymode
= gentxn
->paymode
;
1163 newope
->info
= g_strdup(gentxn
->info
);
1164 newope
->memo
= g_strdup(gentxn
->memo
);
1165 newope
->amount
= gentxn
->amount
;
1167 if(newope
->amount
> 0)
1168 newope
->flags
|= OF_INCOME
;
1170 //#773282 invert amount for ccard accounts
1171 //todo: manage this (qif), it is not set to true anywhere
1172 //if(ictx->is_ccard)
1173 // gentxn->amount *= -1;
1176 if( gentxn
->payee
!= NULL
)
1178 payitem
= da_pay_get_by_name(gentxn
->payee
);
1181 //DB( g_print(" -> append pay: '%s'\n", item->payee ) );
1183 payitem
= da_pay_malloc();
1184 payitem
->name
= g_strdup(gentxn
->payee
);
1185 //payitem->imported = TRUE;
1186 da_pay_append(payitem
);
1188 //ictx->cnt_new_pay += 1;
1190 newope
->kpay
= payitem
->key
;
1193 // LCategory of transaction
1194 // L[Transfer account name]
1195 // LCategory of transaction/Class of transaction
1196 // L[Transfer account]/Class of transaction
1197 if( gentxn
->category
!= NULL
)
1199 if(g_str_has_prefix(gentxn
->category
, "[")) // this is a transfer account name
1203 //DB ( g_print(" -> transfer to: '%s'\n", item->category) );
1206 accname
= hb_strdup_nobrackets(gentxn
->category
);
1208 // search target account + append if not exixts
1209 accitem
= da_acc_get_by_name(accname
);
1212 DB( g_print(" -> append int xfer dest acc: '%s'\n", accname
) );
1214 accitem
= da_acc_malloc();
1215 accitem
->name
= g_strdup(accname
);
1216 //accitem->imported = TRUE;
1217 //accitem->imp_name = g_strdup(accname);
1218 da_acc_append(accitem
);
1221 newope
->kxferacc
= accitem
->key
;
1222 newope
->paymode
= PAYMODE_INTXFER
;
1228 //DB ( g_print(" -> append cat: '%s'\n", item->category) );
1230 catitem
= da_cat_append_ifnew_by_fullname(gentxn
->category
);
1231 if( catitem
!= NULL
)
1233 //ictx->cnt_new_cat += 1;
1234 newope
->kcat
= catitem
->key
;
1239 //#1791656 miss tags also...
1240 if( gentxn
->tags
!= NULL
)
1242 g_free(newope
->tags
);
1243 newope
->tags
= tags_parse(gentxn
->tags
);
1246 // splits, if not a xfer
1247 //TODO: it seems this never happen
1248 if( gentxn
->paymode
!= PAYMODE_INTXFER
)
1250 if( gentxn
->nb_splits
> 0 )
1252 newope
->splits
= da_split_new();
1253 for(nsplit
=0;nsplit
<gentxn
->nb_splits
;nsplit
++)
1255 GenSplit
*s
= &gentxn
->splits
[nsplit
];
1259 DB( g_print(" -> append split %d: '%s' '%.2f' '%s'\n", nsplit
, s
->category
, s
->amount
, s
->memo
) );
1261 if( s
->category
!= NULL
)
1263 catitem
= da_cat_append_ifnew_by_fullname(s
->category
);
1264 if( catitem
!= NULL
)
1266 kcat
= catitem
->key
;
1270 //todo: remove this when no more use ||
1271 hb_string_replace_char('|', s
->memo
);
1272 hbs
= da_split_malloc ();
1274 hbs
->memo
= g_strdup(s
->memo
);
1275 hbs
->amount
= s
->amount
;
1276 da_splits_append(newope
->splits
, hbs
);
1282 newope
->flags
|= OF_ADDED
;
1283 if( newope
->amount
> 0 )
1284 newope
->flags
|= OF_INCOME
;
1286 if( gentxn
->reconciled
)
1287 newope
->status
= TXN_STATUS_RECONCILED
;
1289 if( gentxn
->cleared
)
1290 newope
->status
= TXN_STATUS_CLEARED
;
1297 hb_import_apply(ImportContext
*ictx
)
1301 guint32 kcommon
= 0;
1304 DB( g_print("\n[import] apply\n") );
1307 list
= g_list_first(ictx
->gen_lst_acc
);
1308 while (list
!= NULL
)
1310 GenAcc
*genacc
= list
->data
;
1312 DB( g_print(" #1 genacc: %d %s %s => %d\n", genacc
->key
, genacc
->name
, genacc
->number
, genacc
->kacc
) );
1314 //we do create the common account once
1315 if( (genacc
->kacc
== DST_ACC_GLOBAL
) )
1319 Account
*acc
= da_acc_malloc ();
1321 acc
->name
= g_strdup(_("imported account"));
1322 if( da_acc_append(acc
) )
1329 genacc
->kacc
= kcommon
;
1332 if( (genacc
->kacc
== DST_ACC_NEW
) )
1334 Account
*acc
= da_acc_malloc ();
1336 acc
->name
= g_strdup(genacc
->name
);
1337 if( da_acc_append(acc
) )
1339 acc
->number
= g_strdup(genacc
->number
);
1340 acc
->initial
= genacc
->initial
;
1342 //store the target acc key
1343 genacc
->kacc
= acc
->key
;
1348 list
= g_list_next(list
);
1351 // insert every transactions into a temporary list
1352 // we do this to keep a finished real txn list for detect xfer below
1353 DB( g_print(" #2 insert txn\n") );
1356 lacc
= g_list_first(ictx
->gen_lst_acc
);
1357 while (lacc
!= NULL
)
1359 GenAcc
*genacc
= lacc
->data
;
1361 if(genacc
->kacc
!= DST_ACC_SKIP
)
1363 list
= g_list_first(ictx
->gen_lst_txn
);
1364 while (list
!= NULL
)
1366 GenTxn
*gentxn
= list
->data
;
1368 if(gentxn
->kacc
== genacc
->key
&& gentxn
->to_import
== TRUE
)
1370 Transaction
*txn
, *dtxn
;
1372 txn
= hb_import_convert_txn(genacc
, gentxn
);
1375 dtxn
= transaction_add(NULL
, txn
);
1376 txnlist
= g_list_append(txnlist
, dtxn
);
1377 da_transaction_free(txn
);
1378 //#1820618 forgot to report changes count
1382 list
= g_list_next(list
);
1385 lacc
= g_list_next(lacc
);
1389 DB( g_print(" call auto assign\n") );
1390 transaction_auto_assign(txnlist
, 0);
1392 //check for ofx internal xfer
1393 DB( g_print(" call hb_import_gen_xfer_eval\n") );
1394 hb_import_gen_xfer_eval(ictx
, txnlist
);
1396 g_list_free(txnlist
);
1398 DB( g_print(" adding %d changes\n", changes
) );
1399 GLOBALS
->changes_count
+= changes
;
1405 void _import_context_debug_file_list(ImportContext
*ctx
)
1409 g_print("\n--debug-- file list %d\n", g_list_length(ctx
->gen_lst_file
) );
1411 list
= g_list_first(ctx
->gen_lst_file
);
1412 while (list
!= NULL
)
1414 GenFile
*item
= list
->data
;
1416 g_print(" genfile: %d '%s' '%s'\ndf=%d invalid=%d\n", item
->key
, item
->filepath
, item
->encoding
, item
->datefmt
, item
->invaliddatefmt
);
1418 list
= g_list_next(list
);
1423 void _import_context_debug_acc_list(ImportContext
*ctx
)
1427 g_print("\n--debug-- acc list %d\n", g_list_length(ctx
->gen_lst_acc
) );
1429 list
= g_list_first(ctx
->gen_lst_acc
);
1430 while (list
!= NULL
)
1432 GenAcc
*item
= list
->data
;
1434 g_print(" genacc: %d %s %s => %d\n", item
->key
, item
->name
, item
->number
, item
->kacc
);
1436 list
= g_list_next(list
);
1442 void _import_context_debug_txn_list(ImportContext
*ctx
)
1446 g_print("\n--debug-- txn list %d\n", g_list_length(ctx
->gen_lst_txn
) );
1448 list
= g_list_first(ctx
->gen_lst_txn
);
1449 while (list
!= NULL
)
1451 GenTxn
*item
= list
->data
;
1453 g_print(" gentxn: (%d) %s %s (%d) %s %.2f\n", item
->kfile
, item
->account
, item
->date
, item
->julian
, item
->memo
, item
->amount
);
1455 list
= g_list_next(list
);
This page took 0.0955859999999999 seconds and 4 git commands to generate.