Skip to content

Commit

Permalink
Bug #554394: Income Tax Enhancements
Browse files Browse the repository at this point in the history
Patch by J. Alex Aycinena. Patch does the following:

- update the tax information in 'txf.scm', which is based on V037 of
the TXF Spec,  to V041, the last version issued (bug #554394)
- provide support for multiple copies of certain tax Forms/Schedules
(e.g., Schedule C(1), Schedule C(2), etc.)
- support multiple types of tax entities: partnerships, corporations
and S corporations, in addition to individual tax payers
- support balance sheet accounts, required for these new tax entity types
- add the term 'Income' in several places to avoid confusion with
sales or VAT style taxes in the business features (e.g., change the
menu from 'Tax Options' to 'Income Tax Options')

The following files were changed, as follows, to implement these changes:

1. src/engine/Account.c and
2. src/engine/Account.h: add copy number capability (define
'xaccAccountGetTaxUSCopyNumber' and 'xaccAccountSetTaxUSCopyNumber');
modify 'xaccAccountSetTaxUSCode' to remove KVP when no tax-code
assigned, clean up tax-source descriptions

3. src/gnome/gnc-plugin-basic-commands.c: change 'Tax Options' to
'Income Tax Options'

4. src/app-utils/gnc-ui-util.c and
5. src/app-utils/gnc-ui-util.h: add setter and getter functions for
book tax name and book tax type which are stored in a book KVP, show
copy information in accounts page, tax column, show error messages for
various conditions

6. src/app-utils/app-utils.i: add 'gnc_get_current_book_tax_name' and
'gnc_get_current_book_tax_type' functions

7. src/gnome/dialog-tax-info.c: add copy number and tax entity name
and type, and balance sheet account handling capability

8. src/gnome/glade/tax.glade: add tax entity name, tax entity type,
asset, liability/equity and copy number widgets

9. src/tax/us/txf.scm: update to V041 for individuals, add V041
support for multiple additional tax entity types and balance sheet
accounts and related tax codes, add tax form line data

10. src/tax/us/us.scm: export new functions defined in txf.scm

11. src/report/locale-specific/us/taxtxf.scm: add support for multiple
copies of Forms/Schedules, add support for Format 6, use Form/Schedule
line #'s to sort report, update from "V037" to "V041", add support for
taxpayer types other than F1040, add warning messages if there are
some inconsistent codes assigned and list

12. src/tax/us/txf-de_DE.scm: make functions called from outside (e.g., from
dialog-tax-info.c) have a consistent signature with those same
functions in txf.scm (define tax-entity-type , define getters/setters,
add tax-entity-type as an argument to existing functions)

13. src/tax/us/de_DE.scm: export new functions added to txf-de_DE.scm

14. src/report/locale-specific/us/taxtxf-de_DE.scm: add "" as
tax-entity-type argument to functions
called on txf-de_DE.scm (which defaults to existing codes)

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18413 57a11ea4-9604-0410-9ed3-97b8803252fd
  • Loading branch information
cstim committed Nov 15, 2009
1 parent 127638e commit b5e09a6
Show file tree
Hide file tree
Showing 14 changed files with 4,173 additions and 1,474 deletions.
2 changes: 2 additions & 0 deletions src/app-utils/app-utils.i
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ typedef void (*GNCOptionChangeCallback) (gpointer user_data);
typedef int GNCOptionDBHandle;

QofBook * gnc_get_current_book (void);
const gchar * gnc_get_current_book_tax_name (void);
const gchar * gnc_get_current_book_tax_type (void);
Account * gnc_get_current_root_account (void);

%newobject gnc_gettext_helper;
Expand Down
212 changes: 159 additions & 53 deletions src/app-utils/gnc-ui-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,34 @@ gnc_get_current_book (void)
return qof_session_get_book (gnc_get_current_session ());
}

void
gnc_set_current_book_tax_name (const gchar *tax_name)
{
kvp_frame_set_string (qof_book_get_slots (gnc_get_current_book()),
"book/tax_US/name", tax_name);
}

const gchar *
gnc_get_current_book_tax_name (void)
{
return kvp_frame_get_string (qof_book_get_slots (gnc_get_current_book()),
"book/tax_US/name");
}

void
gnc_set_current_book_tax_type (const gchar *tax_type)
{
kvp_frame_set_string(qof_book_get_slots(gnc_get_current_book()),
"book/tax_US/type", tax_type);
}

const gchar *
gnc_get_current_book_tax_type (void)
{
return kvp_frame_get_string(qof_book_get_slots(gnc_get_current_book()),
"book/tax_US/type");
}

Account *
gnc_get_current_root_account (void)
{
Expand Down Expand Up @@ -430,85 +458,163 @@ gnc_ui_account_get_tax_info_string (const Account *account)
static SCM get_form = SCM_UNDEFINED;
static SCM get_desc = SCM_UNDEFINED;

GNCAccountType atype;
gboolean tax_related = FALSE;
const char *code;
QofBook *this_book;
KvpFrame *book_frame;
const gchar *tax_type;
GNCAccountType atype;
SCM category;
SCM code_scm;
const gchar *form, *desc;
SCM tax_entity_type;
const gchar *form, *desc, *copy_txt;
gint64 copy_number;
SCM scm;

if (get_form == SCM_UNDEFINED)
if (!account)
return NULL;

tax_related = xaccAccountGetTaxRelated (account);
code = xaccAccountGetTaxUSCode (account);

if (!code)
{
if (!tax_related)
return NULL;
else /* tax_related && !code */
return g_strdup (_("Tax-related but has no tax code"));
}
else /* with tax code */
{
GNCModule module;
const gchar *tax_module;
tax_type = gnc_get_current_book_tax_type ();
atype = xaccAccountGetType (account);
/* tax_entity_type = scm_from_locale_string (tax_type); <- requires guile 1.8*/
tax_entity_type = scm_makfrom0str (tax_type); /* <-guile 1.6 */

if (get_form == SCM_UNDEFINED)
{
GNCModule module;
const gchar *tax_module;
/* load the tax info */
#ifdef LOCALE_SPECIFIC_TAX
/* This is a very simple hack that loads the (new, special) German
tax definition file in a German locale, or (default) loads the
previous US tax file. */
# ifdef G_OS_WIN32
gchar *thislocale = g_win32_getlocale();
gboolean is_de_DE = (strncmp(thislocale, "de_DE", 5) == 0);
g_free(thislocale);
gchar *thislocale = g_win32_getlocale();
gboolean is_de_DE = (strncmp(thislocale, "de_DE", 5) == 0);
g_free(thislocale);
# else /* !G_OS_WIN32 */
const char *thislocale = setlocale(LC_ALL, NULL);
gboolean is_de_DE = (strncmp(thislocale, "de_DE", 5) == 0);
const char *thislocale = setlocale(LC_ALL, NULL);
gboolean is_de_DE = (strncmp(thislocale, "de_DE", 5) == 0);
# endif /* G_OS_WIN32 */
#else /* LOCALE_SPECIFIC_TAX */
gboolean is_de_DE = FALSE;
gboolean is_de_DE = FALSE;
#endif /* LOCALE_SPECIFIC_TAX */
tax_module = is_de_DE ?
"gnucash/tax/de_DE" :
"gnucash/tax/us";
tax_module = is_de_DE ?
"gnucash/tax/de_DE" :
"gnucash/tax/us";

module = gnc_module_load ((char *)tax_module, 0);
module = gnc_module_load ((char *)tax_module, 0);

g_return_val_if_fail (module, NULL);
g_return_val_if_fail (module, NULL);

get_form = scm_c_eval_string ("(false-if-exception gnc:txf-get-form)");
get_desc = scm_c_eval_string ("(false-if-exception gnc:txf-get-description)");
}

g_return_val_if_fail (SCM_PROCEDUREP (get_form), NULL);
g_return_val_if_fail (SCM_PROCEDUREP (get_desc), NULL);

if (!account)
return NULL;

if (!xaccAccountGetTaxRelated (account))
return NULL;

atype = xaccAccountGetType (account);
if (atype != ACCT_TYPE_INCOME && atype != ACCT_TYPE_EXPENSE)
return NULL;

code = xaccAccountGetTaxUSCode (account);
if (!code)
return NULL;
get_form = scm_c_eval_string ("(false-if-exception gnc:txf-get-form)");
get_desc = scm_c_eval_string
("(false-if-exception gnc:txf-get-description)");
}

category = scm_c_eval_string (atype == ACCT_TYPE_INCOME ?
"txf-income-categories" :
"txf-expense-categories");
g_return_val_if_fail (SCM_PROCEDUREP (get_form), NULL);
g_return_val_if_fail (SCM_PROCEDUREP (get_desc), NULL);

category = scm_c_eval_string (atype == ACCT_TYPE_INCOME ?
"txf-income-categories" :
(atype == ACCT_TYPE_EXPENSE ?
"txf-expense-categories" :
(((atype == ACCT_TYPE_BANK) ||
(atype == ACCT_TYPE_CASH) ||
(atype == ACCT_TYPE_ASSET) ||
(atype == ACCT_TYPE_STOCK) ||
(atype == ACCT_TYPE_MUTUAL) ||
(atype == ACCT_TYPE_RECEIVABLE)) ?
"txf-asset-categories" :
(((atype == ACCT_TYPE_CREDIT) ||
(atype == ACCT_TYPE_LIABILITY) ||
(atype == ACCT_TYPE_EQUITY) ||
(atype == ACCT_TYPE_PAYABLE)) ?
"txf-liab-eq-categories" : ""))));

if (category == SCM_UNDEFINED)
{
if (tax_related)
return g_strdup_printf
(_("Tax type %s: invalid code %s for account type"), code, tax_type);
else
return g_strdup_printf
(_("Not tax-related; tax type %s: invalid code %s for account type"),
code, tax_type);
}

code_scm = scm_str2symbol (code);
code_scm = scm_str2symbol (code);
scm = scm_call_3 (get_form, category, code_scm, tax_entity_type);
if (!SCM_STRINGP (scm))
{
if (tax_related)
return g_strdup_printf
(_("Invalid code %s for tax type %s"), code, tax_type);
else
return g_strdup_printf
(_("Not tax-related; invalid code %s for tax type %s"), code, tax_type);
}

scm = scm_call_2 (get_form, category, code_scm);
if (!SCM_STRINGP (scm))
return NULL;
form = SCM_STRING_CHARS (scm);
if (!form)
{
if (tax_related)
return g_strdup_printf
(_("No form: code %s, tax type %s"), code, tax_type);
else
return g_strdup_printf
(_("Not tax-related; no form: code %s, tax type %s"), code, tax_type);
}

form = SCM_STRING_CHARS (scm);
if (!form)
return NULL;
scm = scm_call_3 (get_desc, category, code_scm, tax_entity_type);
if (!SCM_STRINGP (scm))
{
if (tax_related)
return g_strdup_printf
(_("No description: form %s, code %s, tax type %s (1)"),
form, code, tax_type);
else
return g_strdup_printf
(_("Not tax-related; no description: form %s, code %s, tax type %s (1)"),
form, code, tax_type);
}

scm = scm_call_2 (get_desc, category, code_scm);
if (!SCM_STRINGP (scm))
return NULL;
desc = SCM_STRING_CHARS (scm);
if (!desc)
{
if (tax_related)
return g_strdup_printf
(_("No description: form %s, code %s, tax type %s (2)"),
form, code, tax_type);
else
return g_strdup_printf
(_("Not tax-related; no description: form %s, code %s, tax type %s (2)"),
form, code, tax_type);
}

desc = SCM_STRING_CHARS (scm);
if (!desc)
return NULL;
copy_number = xaccAccountGetTaxUSCopyNumber (account);
copy_txt = (copy_number == 1) ? "" : g_strdup_printf ("(%d)",
(gint) copy_number);

return g_strdup_printf ("%s %s", form, desc);
if (tax_related)
return g_strdup_printf ("%s%s %s", form, copy_txt, desc);
else
return g_strdup_printf
(_("Not tax-related; %s%s %s (code %s, tax type %s)"),
form, copy_txt, desc, code, tax_type);
}
}


Expand Down
4 changes: 4 additions & 0 deletions src/app-utils/gnc-ui-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ void gnc_set_default_directory (const gchar *gconf_section,

/* Engine enhancements & i18n ***************************************/
QofBook * gnc_get_current_book (void);
void gnc_set_current_book_tax_name (const gchar *tax_name);
const gchar * gnc_get_current_book_tax_name (void);
void gnc_set_current_book_tax_type (const gchar *tax_type);
const gchar * gnc_get_current_book_tax_type (void);
Account * gnc_get_current_root_account (void);
gnc_commodity_table * gnc_get_current_commodities (void);

Expand Down
61 changes: 60 additions & 1 deletion src/engine/Account.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ enum {
PROP_TAX_RELATED,
PROP_TAX_CODE,
PROP_TAX_SOURCE,
PROP_TAX_COPY_NUMBER,

PROP_HIDDEN,
PROP_PLACEHOLDER,
Expand Down Expand Up @@ -350,6 +351,10 @@ gnc_account_get_property (GObject *object,
g_value_set_string(value,
xaccAccountGetTaxUSPayerNameSource(account));
break;
case PROP_TAX_COPY_NUMBER:
g_value_set_int64(value,
xaccAccountGetTaxUSCopyNumber(account));
break;
case PROP_HIDDEN:
g_value_set_boolean(value, xaccAccountGetHidden(account));
break;
Expand Down Expand Up @@ -434,6 +439,10 @@ gnc_account_set_property (GObject *object,
case PROP_TAX_SOURCE:
xaccAccountSetTaxUSPayerNameSource(account,
g_value_get_string(value));
case PROP_TAX_COPY_NUMBER:
xaccAccountSetTaxUSCopyNumber(account,
g_value_get_int64(value));
break;
case PROP_HIDDEN:
xaccAccountSetHidden(account, g_value_get_boolean(value));
break;
Expand Down Expand Up @@ -733,10 +742,22 @@ gnc_account_class_init (AccountClass *klass)
PROP_TAX_SOURCE,
g_param_spec_string ("tax-source",
"Tax Source",
"This is an unknown tax related field.",
"This specifies where exported name comes from.",
NULL,
G_PARAM_READWRITE));

g_object_class_install_property
(gobject_class,
PROP_TAX_COPY_NUMBER,
g_param_spec_int ("tax-copy-number",
"Tax Copy Number",
"This specifies the copy number of the tax "
"form/schedule.",
1,
G_MAXINT16,
1,
G_PARAM_READWRITE));

g_object_class_install_property
(gobject_class,
PROP_HIDDEN,
Expand Down Expand Up @@ -3482,6 +3503,11 @@ xaccAccountSetTaxUSCode (Account *acc, const char *code)

xaccAccountBeginEdit (acc);
kvp_frame_set_string (acc->inst.kvp_data, "/tax-US/code", code);
if (!code)
{
KvpFrame *frame = NULL;
kvp_frame_set_frame (acc->inst.kvp_data, "/tax-US", frame);
}
mark_account (acc);
xaccAccountCommitEdit (acc);
}
Expand All @@ -3506,6 +3532,39 @@ xaccAccountSetTaxUSPayerNameSource (Account *acc, const char *source)
xaccAccountCommitEdit (acc);
}

gint64
xaccAccountGetTaxUSCopyNumber (const Account *acc)
{
gint64 copy_number;

g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 1);
copy_number = kvp_frame_get_gint64(acc->inst.kvp_data,
"tax-US/copy-number");
return (copy_number == 0) ? 1: copy_number;
}

void
xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number)
{
g_return_if_fail(GNC_IS_ACCOUNT(acc));

xaccAccountBeginEdit (acc);
if (copy_number != 0)
kvp_frame_set_gint64 (acc->inst.kvp_data, "/tax-US/copy-number", copy_number);
else
{
KvpFrame * frame;
KvpValue *value;

value = NULL;
frame = kvp_frame_set_value_nc (acc->inst.kvp_data,
"/tax-US/copy-number", value);
if (!frame) kvp_value_delete (value);
}
mark_account (acc);
xaccAccountCommitEdit (acc);
}

/********************************************************************\
\********************************************************************/

Expand Down
4 changes: 4 additions & 0 deletions src/engine/Account.h
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,10 @@ void xaccAccountSetTaxUSCode (Account *account, const char *code);
const char * xaccAccountGetTaxUSPayerNameSource (const Account *account);
/** DOCUMENT ME! */
void xaccAccountSetTaxUSPayerNameSource (Account *account, const char *source);
/** DOCUMENT ME! */
gint64 xaccAccountGetTaxUSCopyNumber (const Account *account);
/** DOCUMENT ME! */
void xaccAccountSetTaxUSCopyNumber (Account *account, gint64 copy_number);
/** @} */


Expand Down

0 comments on commit b5e09a6

Please sign in to comment.