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