LCOV - code coverage report
Current view: top level - libgnucash/tax - gnc-locale-tax.c (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 5.1 % 118 6
Test Date: 2025-02-07 16:25:45 Functions: 33.3 % 3 1
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /*********************************************************************
       2                 :             :  * gnc-locale-tax.c
       3                 :             :  * hack to load the proper guile based tax system
       4                 :             :  *
       5                 :             :  * Copyright (c) 2019 Geert Janssens <geert@kobaltwit.be>
       6                 :             :  *********************************************************************/
       7                 :             : /********************************************************************\
       8                 :             :  * This program is free software; you can redistribute it and/or    *
       9                 :             :  * modify it under the terms of the GNU General Public License as   *
      10                 :             :  * published by the Free Software Foundation; either version 2 of   *
      11                 :             :  * the License, or (at your option) any later version.              *
      12                 :             :  *                                                                  *
      13                 :             :  * This program is distributed in the hope that it will be useful,  *
      14                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      15                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      16                 :             :  * GNU General Public License for more details.                     *
      17                 :             :  *                                                                  *
      18                 :             :  * You should have received a copy of the GNU General Public License*
      19                 :             :  * along with this program; if not, contact:                        *
      20                 :             :  *                                                                  *
      21                 :             :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      22                 :             :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      23                 :             :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      24                 :             :  *                                                                  *
      25                 :             : \********************************************************************/
      26                 :             : 
      27                 :             : 
      28                 :             : #include <config.h>
      29                 :             : #include <string.h>
      30                 :             : #include <locale.h>
      31                 :             : #include <libguile.h>
      32                 :             : #include <glib.h>
      33                 :             : #include <glib/gi18n.h>
      34                 :             : #include <Account.h>
      35                 :             : #include <gnc-ui-util.h>
      36                 :             : #include <guile-mappings.h>
      37                 :             : #include <gnc-guile-utils.h>
      38                 :             : #include "gnc-locale-tax.h"
      39                 :             : 
      40                 :             : 
      41                 :             : 
      42                 :             : void
      43                 :           1 : gnc_locale_tax_init(void)
      44                 :             : {
      45                 :             :     /* This is a very simple hack that loads the (new, special) German
      46                 :             :        tax definition file in a German locale, or (default) loads the
      47                 :             :        US tax file. */
      48                 :             : # ifdef G_OS_WIN32
      49                 :             :     gchar *thislocale = g_win32_getlocale();
      50                 :             :     gboolean is_de_DE = (strncmp(thislocale, "de_DE", 5) == 0);
      51                 :             :     g_free(thislocale);
      52                 :             : # else /* !G_OS_WIN32 */
      53                 :           1 :     const char *thislocale = setlocale(LC_ALL, NULL);
      54                 :           1 :     gboolean is_de_DE = (strncmp(thislocale, "de_DE", 5) == 0);
      55                 :             : # endif /* G_OS_WIN32 */
      56                 :           1 :     if (is_de_DE)
      57                 :           0 :         scm_c_use_module("gnucash locale de_DE tax");
      58                 :             :     else
      59                 :           1 :         scm_c_use_module("gnucash locale us tax");
      60                 :           1 : }
      61                 :             : 
      62                 :             : /* Caller is responsible for g_free'ing returned memory */
      63                 :             : char *
      64                 :           0 : gnc_ui_account_get_tax_info_string (const Account *account)
      65                 :             : {
      66                 :             :     static SCM get_form = SCM_UNDEFINED;
      67                 :             :     static SCM get_desc = SCM_UNDEFINED;
      68                 :             : 
      69                 :           0 :     gboolean tax_related = FALSE;
      70                 :             :     const char *code;
      71                 :             : 
      72                 :           0 :     if (!account)
      73                 :           0 :         return NULL;
      74                 :             : 
      75                 :           0 :     tax_related = xaccAccountGetTaxRelated (account);
      76                 :           0 :     code = xaccAccountGetTaxUSCode (account);
      77                 :             : 
      78                 :           0 :     if (!code)
      79                 :             :     {
      80                 :           0 :         if (!tax_related)
      81                 :           0 :             return NULL;
      82                 :             :         /* tax_related && !code */
      83                 :             :         else
      84                 :             :             /* Translators: This and the following strings appear on
      85                 :             :                the account tab if the Tax Info column is displayed,
      86                 :             :                i.e. if the user wants to record the tax form number
      87                 :             :                and location on that tax form which corresponds to this
      88                 :             :                gnucash account. For the US Income Tax support in
      89                 :             :                gnucash, each tax code that can be assigned to an
      90                 :             :                account generally corresponds to a specific line number
      91                 :             :                on a paper form and each form has a unique
      92                 :             :                identification (e.g., Form 1040, Schedule A). */
      93                 :           0 :             return g_strdup (_("Tax-related but has no tax code"));
      94                 :             :     }
      95                 :             :     else  /* with tax code */
      96                 :             :     {
      97                 :             :         const gchar *tax_type;
      98                 :             :         GNCAccountType atype;
      99                 :             :         SCM tax_entity_type;
     100                 :             :         SCM category;
     101                 :           0 :         gchar *num_code = NULL;
     102                 :           0 :         const gchar *prefix = "N";
     103                 :           0 :         gchar *return_string = NULL;
     104                 :             : 
     105                 :           0 :         tax_type = gnc_get_current_book_tax_type ();
     106                 :           0 :         if (tax_type == NULL || (g_strcmp0 (tax_type, "") == 0))
     107                 :           0 :             return g_strdup (_("Tax entity type not specified"));
     108                 :             : 
     109                 :           0 :         atype = xaccAccountGetType (account);
     110                 :           0 :         tax_entity_type = scm_from_utf8_string (tax_type);
     111                 :             : 
     112                 :           0 :         if (get_form == SCM_UNDEFINED)
     113                 :             :         {
     114                 :             :             /* load the tax info */
     115                 :           0 :             gnc_locale_tax_init ();
     116                 :             : 
     117                 :           0 :             get_form = scm_c_eval_string
     118                 :             :                        ("(false-if-exception gnc:txf-get-form)");
     119                 :           0 :             get_desc = scm_c_eval_string
     120                 :             :                        ("(false-if-exception gnc:txf-get-description)");
     121                 :             :         }
     122                 :             : 
     123                 :           0 :         g_return_val_if_fail (scm_is_procedure (get_form), NULL);
     124                 :           0 :         g_return_val_if_fail (scm_is_procedure (get_desc), NULL);
     125                 :             : 
     126                 :           0 :         category = scm_c_eval_string (atype == ACCT_TYPE_INCOME ?
     127                 :           0 :                                       "txf-income-categories" :
     128                 :             :                                       (atype == ACCT_TYPE_EXPENSE ?
     129                 :             :                                        "txf-expense-categories" :
     130                 :           0 :                                        (((atype == ACCT_TYPE_BANK)      ||
     131                 :           0 :                                          (atype == ACCT_TYPE_CASH)      ||
     132                 :           0 :                                          (atype == ACCT_TYPE_ASSET)     ||
     133                 :           0 :                                          (atype == ACCT_TYPE_STOCK)     ||
     134                 :           0 :                                          (atype == ACCT_TYPE_MUTUAL)    ||
     135                 :             :                                          (atype == ACCT_TYPE_RECEIVABLE)) ?
     136                 :             :                                         "txf-asset-categories" :
     137                 :           0 :                                         (((atype == ACCT_TYPE_CREDIT)    ||
     138                 :           0 :                                           (atype == ACCT_TYPE_LIABILITY) ||
     139                 :           0 :                                           (atype == ACCT_TYPE_EQUITY)    ||
     140                 :             :                                           (atype == ACCT_TYPE_PAYABLE)) ?
     141                 :             :                                          "txf-liab-eq-categories" : ""))));
     142                 :             : 
     143                 :           0 :         if (g_str_has_prefix (code, prefix))
     144                 :             :         {
     145                 :             :             const gchar *num_code_tmp;
     146                 :           0 :             num_code_tmp = g_strdup (code);
     147                 :           0 :             num_code_tmp++; /* to lose the leading N */
     148                 :           0 :             num_code = g_strdup (num_code_tmp);
     149                 :           0 :             num_code_tmp--;
     150                 :           0 :             g_free ((gpointer *) num_code_tmp);
     151                 :             :         }
     152                 :             :         else
     153                 :             :         {
     154                 :           0 :             num_code = g_strdup (code);
     155                 :             :         }
     156                 :             : 
     157                 :           0 :         if (category == SCM_UNDEFINED)
     158                 :             :         {
     159                 :           0 :             if (tax_related)
     160                 :           0 :                 return_string = g_strdup_printf
     161                 :           0 :                                 (_("Tax type %s: invalid code %s for account type"),
     162                 :             :                                  tax_type, num_code);
     163                 :             :             else
     164                 :           0 :                 return_string = g_strdup_printf
     165                 :           0 :                                 (_("Not tax-related; tax type %s: invalid code %s for account type"),
     166                 :             :                                  tax_type, num_code);
     167                 :             :         }
     168                 :             :         else
     169                 :             :         {
     170                 :             :             SCM code_scm;
     171                 :             :             SCM form_scm;
     172                 :           0 :             code_scm = scm_from_locale_symbol (code);
     173                 :           0 :             form_scm = scm_call_3 (get_form, category, code_scm, tax_entity_type);
     174                 :           0 :             if (!scm_is_string (form_scm))
     175                 :             :             {
     176                 :           0 :                 if (tax_related)
     177                 :           0 :                     return_string =  g_strdup_printf
     178                 :           0 :                                      (_("Invalid code %s for tax type %s"),
     179                 :             :                                       num_code, tax_type);
     180                 :             :                 else
     181                 :           0 :                     return_string =  g_strdup_printf
     182                 :           0 :                                      (_("Not tax-related; invalid code %s for tax type %s"),
     183                 :             :                                       num_code, tax_type);
     184                 :             :             }
     185                 :             :             else
     186                 :             :             {
     187                 :           0 :                 gchar *form = NULL;
     188                 :             : 
     189                 :             :                 /* Note: using scm_to_utf8_stringn directly here instead
     190                 :             :                    of our wrapper gnc_scm_to_utf8_string. 'form' should
     191                 :             :                    be freed with 'free' instead of 'g_free'. This will
     192                 :             :                    be taken care of automatically during scm_dynwind_end,
     193                 :             :                    because we inform guile of this memory allocation via
     194                 :             :                    scm_dynwind_free a little further. */
     195                 :           0 :                 form = scm_to_utf8_stringn (form_scm, NULL);
     196                 :           0 :                 if (!form)
     197                 :             :                 {
     198                 :           0 :                     if (tax_related)
     199                 :           0 :                         return_string = g_strdup_printf
     200                 :           0 :                                         (_("No form: code %s, tax type %s"), num_code,
     201                 :             :                                          tax_type);
     202                 :             :                     else
     203                 :           0 :                         return_string = g_strdup_printf
     204                 :           0 :                                         (_("Not tax-related; no form: code %s, tax type %s"),
     205                 :             :                                          num_code, tax_type);
     206                 :             :                 }
     207                 :             :                 else
     208                 :             :                 {
     209                 :             :                     SCM desc_scm;
     210                 :             : 
     211                 :             :                     /* Create a dynwind context because we will be calling (scm) functions
     212                 :             :                        that potentially exit non-locally */
     213                 :           0 :                     scm_dynwind_begin (0);
     214                 :           0 :                     scm_dynwind_free (form);
     215                 :           0 :                     desc_scm = scm_call_3 (get_desc, category, code_scm,
     216                 :             :                                            tax_entity_type);
     217                 :           0 :                     if (!scm_is_string (desc_scm))
     218                 :             :                     {
     219                 :           0 :                         if (tax_related)
     220                 :           0 :                             return_string = g_strdup_printf
     221                 :           0 :                                             (_("No description: form %s, code %s, tax type %s"),
     222                 :             :                                              form, num_code, tax_type);
     223                 :             :                         else
     224                 :           0 :                             return_string = g_strdup_printf
     225                 :           0 :                                             (_("Not tax-related; no description: form %s, code %s, tax type %s"),
     226                 :             :                                              form, num_code, tax_type);
     227                 :             :                     }
     228                 :             :                     else
     229                 :             :                     {
     230                 :           0 :                         gchar *desc = NULL;
     231                 :           0 :                         desc = gnc_scm_to_utf8_string (desc_scm);
     232                 :           0 :                         if (!desc)
     233                 :             :                         {
     234                 :           0 :                             if (tax_related)
     235                 :           0 :                                 return_string = g_strdup_printf
     236                 :           0 :                                                 (_("No description: form %s, code %s, tax type %s"),
     237                 :             :                                                  form, num_code, tax_type);
     238                 :             :                             else
     239                 :           0 :                                 return_string = g_strdup_printf
     240                 :           0 :                                                 (_("Not tax-related; no description: form %s, code %s, tax type %s"),
     241                 :             :                                                  form, num_code, tax_type);
     242                 :             :                         }
     243                 :             :                         else
     244                 :             :                         {
     245                 :             :                             gint64 copy_number;
     246                 :           0 :                             gchar *copy_txt = NULL;
     247                 :           0 :                             copy_number = xaccAccountGetTaxUSCopyNumber (account);
     248                 :           0 :                             copy_txt = (copy_number == 1) ?
     249                 :           0 :                                        g_strdup ("") :
     250                 :           0 :                                        g_strdup_printf ("(%d)",
     251                 :             :                                                         (gint) copy_number);
     252                 :           0 :                             if (tax_related)
     253                 :             :                             {
     254                 :           0 :                                 if (g_strcmp0 (form, "") == 0)
     255                 :           0 :                                     return_string = g_strdup_printf ("%s", desc);
     256                 :             :                                 else
     257                 :           0 :                                     return_string = g_strdup_printf ("%s%s: %s",
     258                 :             :                                                                      form, copy_txt, desc);
     259                 :             :                             }
     260                 :             :                             else
     261                 :             :                             {
     262                 :           0 :                                 return_string = g_strdup_printf
     263                 :           0 :                                                 (_("Not tax-related; %s%s: %s (code %s, tax type %s)"),
     264                 :             :                                                  form, copy_txt, desc, num_code, tax_type);
     265                 :             :                             }
     266                 :           0 :                             g_free (copy_txt);
     267                 :             :                         }
     268                 :           0 :                         g_free (desc);
     269                 :             :                     }
     270                 :           0 :                     scm_dynwind_end ();
     271                 :             :                 }
     272                 :             :             }
     273                 :             :         }
     274                 :           0 :         g_free (num_code);
     275                 :           0 :         return return_string;
     276                 :             :     }
     277                 :             : }
     278                 :             : 
     279                 :             : /* Caller is responsible for g_free'ing returned memory */
     280                 :             : char *
     281                 :           0 : gnc_ui_account_get_tax_info_sub_acct_string (const Account *account)
     282                 :             : {
     283                 :             :     GList *descendant, *account_descendants;
     284                 :             : 
     285                 :           0 :     if (!account)
     286                 :           0 :         return NULL;
     287                 :             : 
     288                 :           0 :     account_descendants = gnc_account_get_descendants (account);
     289                 :           0 :     if (account_descendants)
     290                 :             :     {
     291                 :           0 :         gint sub_acct_tax_number = 0;
     292                 :           0 :         for (descendant = account_descendants; descendant;
     293                 :           0 :                 descendant = g_list_next(descendant))
     294                 :             :         {
     295                 :           0 :             if (xaccAccountGetTaxRelated (descendant->data))
     296                 :           0 :                 sub_acct_tax_number++;
     297                 :             :         }
     298                 :           0 :         g_list_free (account_descendants);
     299                 :           0 :         g_list_free (descendant);
     300                 :             :         /* Translators: This and the following strings appear on
     301                 :             :            the account tab if the Tax Info column is displayed,
     302                 :             :            i.e. if the user wants to record the tax form number
     303                 :             :            and location on that tax form which corresponds to this
     304                 :             :            gnucash account. For the US Income Tax support in
     305                 :             :            gnucash, each tax code that can be assigned to an
     306                 :             :            account generally corresponds to a specific line number
     307                 :             :            on a paper form and each form has a unique
     308                 :             :            identification (e.g., Form 1040, Schedule A). */
     309                 :           0 :         return (sub_acct_tax_number == 0) ? NULL :
     310                 :           0 :                g_strdup_printf (_("(Tax-related subaccounts: %d)"),
     311                 :             :                                 sub_acct_tax_number);
     312                 :             :     }
     313                 :             :     else
     314                 :           0 :         return NULL;
     315                 :             : }
        

Generated by: LCOV version 2.0-1