c17846b
# gnucash_business.py -- High level python wrapper classes for the business
c17846b
#                        parts of GnuCash
c17846b
#
c17846b
# Copyright (C) 2008,2010 ParIT Worker Co-operative <paritinfo@parit.ca>
c17846b
# This program is free software; you can redistribute it and/or
c17846b
# modify it under the terms of the GNU General Public License as
c17846b
# published by the Free Software Foundation; either version 2 of
c17846b
# the License, or (at your option) any later version.
c17846b
#
c17846b
# This program is distributed in the hope that it will be useful,
c17846b
# but WITHOUT ANY WARRANTY; without even the implied warranty of
c17846b
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
c17846b
# GNU General Public License for more details.
c17846b
#
c17846b
# You should have received a copy of the GNU General Public License
c17846b
# along with this program; if not, contact:
c17846b
# Free Software Foundation           Voice:  +1-617-542-5942
c17846b
# 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
c17846b
# Boston, MA  02110-1301,  USA       gnu@gnu.org
c17846b
#
c17846b
# @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
c17846b
# @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
c17846b
##  @file
c17846b
#   @brief High level python wrapper classes for the business parts of GnuCash
c17846b
#   @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
c17846b
#   @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
c17846b
#   @ingroup python_bindings
c17846b
c17846b
import gnucash_core_c
c17846b
c17846b
from function_class import \
c17846b
     ClassFromFunctions, extract_attributes_with_prefix, \
c17846b
     default_arguments_decorator, method_function_returns_instance, \
c17846b
     methods_return_instance, methods_return_instance_lists
c17846b
c17846b
from gnucash_core import \
c17846b
     GnuCashCoreClass, GncNumeric, GncCommodity, Transaction, \
c17846b
     Split, Book, GncLot, Account
c17846b
c17846b
from gnucash_core_c import GNC_OWNER_CUSTOMER, GNC_OWNER_JOB, \
c17846b
    GNC_OWNER_EMPLOYEE, GNC_OWNER_VENDOR, \
c17846b
    GNC_PAYMENT_CASH, GNC_PAYMENT_CARD, \
c17846b
    GNC_DISC_PRETAX, GNC_DISC_SAMETIME, GNC_DISC_POSTTAX, \
c17846b
    GNC_TAXINCLUDED_YES, GNC_TAXINCLUDED_NO, GNC_TAXINCLUDED_USEGLOBAL, \
c17846b
    GNC_AMT_TYPE_VALUE, GNC_AMT_TYPE_PERCENT, GNC_ID_INVOICE
c17846b
c17846b
import datetime
c17846b
c17846b
class GnuCashBusinessEntity(GnuCashCoreClass):
c17846b
    def __init__(self, book=None, id=None, currency=None, name=None,
c17846b
                 instance=None):
c17846b
        if instance == None:
c17846b
            if book==None or id==None or currency==None:
c17846b
                raise Exception(
c17846b
                    "you must call GnuCashBusinessEntity.__init__ "
c17846b
                    "with either a book, id, and currency, or an existing "
c17846b
                    "low level swig proxy in the argument instance")
c17846b
            GnuCashCoreClass.__init__(self, book)
c17846b
            self.BeginEdit()
c17846b
            self.SetID(id)
c17846b
            self.SetCurrency(currency)
c17846b
            if name != None:
c17846b
                self.SetName(name)
c17846b
            self.CommitEdit()
c17846b
        else:
c17846b
            GnuCashCoreClass.__init__(self, instance=instance)
c17846b
c17846b
class Customer(GnuCashBusinessEntity): pass
c17846b
                         
c17846b
class Employee(GnuCashBusinessEntity): pass
c17846b
c17846b
class Vendor(GnuCashBusinessEntity): pass
c17846b
c17846b
class Job(GnuCashBusinessEntity):
c17846b
    # override the superclass constructor, as Job doesn't require
c17846b
    # a currency but it does require an owner
c17846b
    def __init__(self, book=None, id=None, owner=None, name=None,
c17846b
                 instance=None):
c17846b
        if instance == None:
c17846b
            if book==None or id==None or owner==None:
c17846b
                raise Exception(
c17846b
                    "you must call Job.__init__ "
c17846b
                    "with either a book, id, and owner or an existing "
c17846b
                    "low level swig proxy in the argument instance")
c17846b
            GnuCashCoreClass.__init__(self, book)
c17846b
            self.SetID(id)
c17846b
            self.SetOwner(owner)
c17846b
            if name != None:
c17846b
                self.SetName(name)
c17846b
        else:
c17846b
            GnuCashCoreClass.__init__(self, instance=instance)    
c17846b
c17846b
class Address(GnuCashCoreClass): pass
c17846b
    
c17846b
class BillTerm(GnuCashCoreClass): pass
c17846b
c17846b
class TaxTable(GnuCashCoreClass):
c17846b
    def __init__(self, book=None, name=None, first_entry=None, instance=None):
c17846b
        if instance == None:
c17846b
            if book==None or name==None or first_entry==None:
c17846b
                raise Exception(
c17846b
                    "you must call TaxTable.__init__  with either a "
c17846b
                    "book, name, and first_entry, or an existing "
c17846b
                    "low level swig proxy in the argument instance")
c17846b
            GnuCashCoreClass.__init__(self, book)
c17846b
            self.SetName(name)
c17846b
            self.AddEntry(first_entry)
c17846b
        else:
c17846b
            GnuCashCoreClass.__init__(self, instance=instance)
c17846b
c17846b
class TaxTableEntry(GnuCashCoreClass):
c17846b
    def __init__(self, account=None, percent=True, amount=None, instance=None):
c17846b
        """TaxTableEntry constructor
c17846b
        
c17846b
        You must provide an account, or be initizing this with an existing
c17846b
        swig proxy object via the instance keyword argument.
c17846b
        
c17846b
        You may also optionally set the percent keyword argument to False to get
c17846b
        a fixed value instead of percentage based tax (which is the default, or
c17846b
        when percent=True).
c17846b
        
c17846b
        The tax will be zero percent or zero unless you set the amount keyword
c17846b
        argument to a GncNumeric value as well.
c17846b
        """
c17846b
c17846b
        if instance == None:
c17846b
            if account==None:
c17846b
                raise Exception(
c17846b
                    "you must call TaxTableEntry.__init__  with either a "
c17846b
                    "account or an existing "
c17846b
                    "low level swig proxy in the argument instance")
c17846b
            GnuCashCoreClass.__init__(self)
c17846b
            self.SetAccount(account)
c17846b
            if percent:
c17846b
                self.SetType(GNC_AMT_TYPE_PERCENT)
c17846b
            else:
c17846b
                self.SetType(GNC_AMT_TYPE_VALUE)
c17846b
            if amount != None:
c17846b
                self.SetAmount(amount)
c17846b
        else:
c17846b
            GnuCashCoreClass.__init__(self, instance=instance)        
c17846b
c17846b
class Invoice(GnuCashCoreClass):
c17846b
    def __init__(self, book=None, id=None, currency=None, owner=None,
c17846b
                 date_opened=None, instance=None):
c17846b
        """Invoice Contstructor
c17846b
c17846b
        You must provide a book, id, currency and owner
c17846b
        (Customer, Job, Employee, Vendor) or an existing swig proxy object
c17846b
        in the keyword argument instance.
c17846b
c17846b
        Optionally, you may provide a date the invoice is opened on
c17846b
        (datetime.date or datetime.datetime), otherwise today's date is used.
c17846b
        """
c17846b
        if instance == None:
c17846b
            if book==None or id==None or currency==None or owner==None:
c17846b
                raise Exception(
c17846b
                    "you must call Invoice.__init__ "
c17846b
                    "with either a book, id, currency and owner, or an existing"
c17846b
                    "low level swig proxy in the argument instance")
c17846b
            GnuCashCoreClass.__init__(self, book)
c17846b
            self.BeginEdit()
c17846b
            self.SetID(id)
c17846b
            self.SetCurrency(currency)
c17846b
            self.SetOwner(owner)
c17846b
            if date_opened == None:
c17846b
                date_opened = datetime.date.today()
c17846b
            self.SetDateOpened(date_opened)
c17846b
            self.CommitEdit()
c17846b
        else:
c17846b
            GnuCashCoreClass.__init__(self, instance=instance)
c17846b
c17846b
class Bill(Invoice):
c17846b
    pass
c17846b
c17846b
def decorate_to_return_instance_instead_of_owner(dec_function):
c17846b
    def new_get_owner_function(self):
c17846b
        (owner_type, instance) = dec_function(self)
c17846b
        if owner_type == GNC_OWNER_CUSTOMER:
c17846b
            return Customer(instance=instance)
c17846b
        elif owner_type == GNC_OWNER_JOB:
c17846b
            return Job(instance=instance)
c17846b
        elif owner_type == GNC_OWNER_EMPLOYEE:
c17846b
            return Employee(instance=instance)
c17846b
        elif owner_type == GNC_OWNER_VENDOR:
c17846b
            return Vendor(instance=instance)
c17846b
        else:
c17846b
            return None
c17846b
    return new_get_owner_function
c17846b
c17846b
class Entry(GnuCashCoreClass):
c17846b
    def __init__(self, book=None, invoice=None, date=None, instance=None):
c17846b
        """Invoice Entry constructor
c17846b
        
c17846b
        You must provide a book or be initizing this with an existing
c17846b
        swig proxy object via the instance keyword argument.
c17846b
c17846b
        The optional invoice argument can be set to a Bill or Invoice
c17846b
        that you would like to associate the entry with. You might as well
c17846b
        assign one now, as an Entry can't exist without one, but you can
c17846b
        always use Invoice.AddEntry or Bill.AddEntry later on.
c17846b
c17846b
        By default, the entry will be set to today's date unless you
c17846b
        override with the date argument.
c17846b
        """
c17846b
        if instance == None:
c17846b
            if book==None:
c17846b
                raise Exception(
c17846b
                    "you must call Entry.__init__  with either a "
c17846b
                    "book or an existing "
c17846b
                    "low level swig proxy in the argument instance")
c17846b
            GnuCashCoreClass.__init__(self, book)
c17846b
c17846b
            if date == None:
c17846b
                date = datetime.date.today()
c17846b
            self.SetDate(date)
c17846b
            if invoice != None:
c17846b
                invoice.AddEntry(self)
c17846b
        else:
c17846b
c17846b
            GnuCashCoreClass.__init__(self, instance=instance)
c17846b
c17846b
    def test_type(self, invoice):
c17846b
        if invoice.GetTypeString() == "Invoice" and self.GetInvoice() == None:
c17846b
            raise Exception("Entry type error. Check that Entry type matches Invoice.")
c17846b
        if invoice.GetTypeString() == "Bill" and self.GetBill() == None:
c17846b
            raise Exception("Entry type error. Check that Entry type matches Bill.")
c17846b
c17846b
c17846b
# Owner
c17846b
GnuCashBusinessEntity.add_methods_with_prefix('gncOwner')
c17846b
c17846b
owner_dict = {
c17846b
                    'GetCustomer' : Customer,
c17846b
                    'GetVendor' : Vendor,
c17846b
                    'GetEmployee' : Employee,
c17846b
                    'GetJob' : Job,
c17846b
                    'GetAddr' : Address,
c17846b
                    'GetCurrency' : GncCommodity,
c17846b
                    'GetEndOwner': GnuCashBusinessEntity,
c17846b
                    'GetBalanceInCurrency': GncNumeric,
c17846b
              }
c17846b
methods_return_instance(GnuCashBusinessEntity, owner_dict)
c17846b
c17846b
methods_return_instance_lists(
c17846b
    GnuCashBusinessEntity, {
c17846b
        'GetCommoditiesList': GncCommodity
c17846b
    })
c17846b
c17846b
# Customer
c17846b
Customer.add_constructor_and_methods_with_prefix('gncCustomer', 'Create')
c17846b
c17846b
customer_dict = {
c17846b
                    'GetAddr' : Address,
c17846b
                    'GetShipAddr' : Address,
c17846b
                    'GetDiscount' : GncNumeric,
c17846b
                    'GetCredit' : GncNumeric,
c17846b
                    'GetTerms' : BillTerm,
c17846b
                    'GetCurrency' : GncCommodity,
c17846b
                    'GetTaxTable': TaxTable,
c17846b
                }
c17846b
methods_return_instance(Customer, customer_dict)
c17846b
c17846b
# Employee
c17846b
Employee.add_constructor_and_methods_with_prefix('gncEmployee', 'Create')
c17846b
c17846b
employee_dict = {
c17846b
                    'GetBook' : Book,
c17846b
                    'GetAddr' : Address,
c17846b
                    'GetWorkday' : GncNumeric,
c17846b
                    'GetRate' : GncNumeric,
c17846b
                    'GetCurrency' : GncCommodity
c17846b
                }
c17846b
methods_return_instance(Employee, employee_dict)
c17846b
c17846b
# Vendor
c17846b
Vendor.add_constructor_and_methods_with_prefix('gncVendor', 'Create')
c17846b
c17846b
vendor_dict =   {
c17846b
                    'GetAddr' : Address,
c17846b
                    'GetTerms' : BillTerm,
c17846b
                    'GetCurrency' : GncCommodity,
c17846b
                    'GetTaxTable': TaxTable,
c17846b
                }
c17846b
methods_return_instance(Vendor, vendor_dict)
c17846b
c17846b
# Job
c17846b
Job.add_constructor_and_methods_with_prefix('gncJob', 'Create')
c17846b
Job.decorate_functions(
c17846b
    decorate_to_return_instance_instead_of_owner,
c17846b
    'GetOwner')
c17846b
c17846b
# Address
c17846b
Address.add_constructor_and_methods_with_prefix('gncAddress', 'Create')
c17846b
c17846b
# BillTerm
c17846b
BillTerm.add_constructor_and_methods_with_prefix('gncBillTerm', 'Create')
c17846b
c17846b
billterm_dict = {
c17846b
                    'LookupByName' : BillTerm,
c17846b
                    'GetDiscount' : GncNumeric,
c17846b
                    'GetParent' : BillTerm,
c17846b
                    'ReturnChild' : BillTerm
c17846b
                }
c17846b
methods_return_instance(BillTerm, billterm_dict)
c17846b
c17846b
# TaxTable
c17846b
TaxTable.add_constructor_and_methods_with_prefix('gncTaxTable', 'Create')
c17846b
c17846b
taxtable_dict = {
c17846b
                    'GetParent': TaxTable,
c17846b
                }
c17846b
methods_return_instance(TaxTable, taxtable_dict)
c17846b
c17846b
# TaxTableEntry
c17846b
TaxTableEntry.add_constructor_and_methods_with_prefix(
c17846b
    'gncTaxTableEntry', 'Create')
c17846b
c17846b
taxtableentry_dict = {
c17846b
                         'GetAccount': Account,
c17846b
                         'GetAmount': GncNumeric,
c17846b
                     }
c17846b
c17846b
# Invoice
c17846b
Invoice.add_constructor_and_methods_with_prefix('gncInvoice', 'Create')
c17846b
methods_return_instance_lists(
c17846b
    Invoice, { 'GetEntries': Entry })
c17846b
c17846b
# Bill
c17846b
Bill.add_methods_with_prefix('gncBill')
c17846b
c17846b
invoice_dict = {
c17846b
                   'GetTerms': BillTerm,
c17846b
                   'GetCurrency': GncCommodity,
c17846b
                   'GetToChargeAmount': GncNumeric,
c17846b
                   'GetPostedLot': GncLot,
c17846b
                   'GetPostedTxn': Transaction,
c17846b
                   'GetPostedAcc': Account,
c17846b
                   'GetTotal': GncNumeric,
c17846b
                   'GetTotalOf': GncNumeric,
c17846b
                   'GetTotalSubtotal': GncNumeric,
c17846b
                   'GetTotalTax': GncNumeric,
c17846b
                   'PostToAccount': Transaction,
c17846b
                   'GetBook': Book,
c17846b
               }
c17846b
methods_return_instance(Invoice, invoice_dict)
c17846b
Invoice.decorate_functions(
c17846b
    decorate_to_return_instance_instead_of_owner,
c17846b
    'GetOwner', 'GetBillTo')
c17846b
c17846b
# Entry
c17846b
Entry.add_constructor_and_methods_with_prefix('gncEntry', 'Create')
c17846b
c17846b
entry_dict = {
c17846b
                 'GetQuantity': GncNumeric,
c17846b
                 'GetInvAccount': Account,
c17846b
                 'GetInvPrice': GncNumeric,
c17846b
                 'GetInvDiscount': GncNumeric,
c17846b
                 'GetInvTaxTable': TaxTable,
c17846b
                 'GetBillAccount': Account,
c17846b
                 'GetBillPrice': GncNumeric,
c17846b
                 'GetBillTaxTable': TaxTable,
c17846b
                 'Copy': Entry,
c17846b
                 'GetInvoice': Invoice,
c17846b
                 'GetBill': Invoice
c17846b
             }
c17846b
methods_return_instance(Entry, entry_dict)             
c17846b
Entry.decorate_functions(
c17846b
    decorate_to_return_instance_instead_of_owner,
c17846b
    'GetBillTo' )