Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# and adjust the related split to rebalance
sp, = trading_splits[cdty]
sp.value -= v
sp.quantity -= q
else:
# otherwise, we must create the split related to the trading account
# assume trading account exists
t_acc = self.book.trading_account(cdty)
sp = Split(account=t_acc,
value=-v,
quantity=-q,
transaction=self,
)
class ScheduledTransaction(DeclarativeBaseGuid):
"""
A GnuCash Scheduled Transaction.
Attributes
adv_creation (int) : days to create in advance (0 if disabled)
adv_notify (int) : days to notify in advance (0 if disabled)
auto_create (bool) :
auto_notify (bool) :
enabled (bool) :
start_date (:class:`datetime.datetime`) : date to start the scheduled transaction
last_occur (:class:`datetime.datetime`) : date of last occurence of the schedule transaction
end_date (:class:`datetime.datetime`) : date to end the scheduled transaction (num/rem_occur should be 0)
instance_count (int) :
name (str) : name of the scheduled transaction
num_occur (int) : number of occurences in total (end_date should be null)
rem_occur (int) : number of remaining occurences (end_date should be null)
import uuid
from sqlalchemy import Column, VARCHAR, BIGINT, INTEGER, ForeignKey
from sqlalchemy.orm import relation
from .._common import hybrid_property_gncnumeric, CallableList
from .._declbase import DeclarativeBaseGuid, DeclarativeBase
from ..sa_extra import ChoiceType
class Taxtable(DeclarativeBaseGuid):
__tablename__ = 'taxtables'
__table_args__ = {}
# column definitions
guid = Column('guid', VARCHAR(length=32), primary_key=True, nullable=False, default=lambda: uuid.uuid4().hex)
name = Column('name', VARCHAR(length=50), nullable=False)
refcount = Column('refcount', BIGINT(), nullable=False)
invisible = Column('invisible', INTEGER(), nullable=False)
parent_guid = Column('parent', VARCHAR(length=32), ForeignKey('taxtables.guid'))
# relation definitions
entries = relation('TaxtableEntry',
back_populates='taxtable',
cascade='all, delete-orphan',
collection_class=CallableList,
def object_to_validate(self, change):
if change[-1] != "deleted":
yield self
def validate(self):
# check uniqueness of namespace/mnemonic
try:
self.book.query(Price).filter_by(commodity=self.commodity,
currency=self.currency,
source=self.source,
date=self.date).one()
except MultipleResultsFound:
raise ValueError("{} already exists in this book".format(self))
class Commodity(DeclarativeBaseGuid):
"""
A GnuCash Commodity.
Attributes:
cusip (str): cusip code
fraction (int): minimal unit of the commodity (e.g. 100 for 1/100)
namespace (str): CURRENCY for currencies, otherwise any string to group multiple commodities together
mnemonic (str): the ISO symbol for a currency or the stock symbol for stocks (used for online quotes)
quote_flag (int): 1 if piecash/GnuCash quotes will retrieve online quotes for the commodity
quote_source (str): the quote source for GnuCash (piecash always use yahoo for stock and quandl for currencies
quote_tz (str): the timezone to assign on the online quotes
base_currency (:class:`Commodity`): The base_currency for a commodity:
- if the commodity is a currency, returns the "default currency" of the book (ie the one of the root_account)
- if the commodity is not a currency, returns the currency encoded in the quoted_currency slot
instance_count = Column('instance_count', INTEGER(), nullable=False)
template_act_guid = Column('template_act_guid', VARCHAR(length=32), ForeignKey('accounts.guid'), nullable=False)
# relation definitions
template_account = relation('Account')
recurrence = relation('Recurrence',
primaryjoin=guid == foreign(Recurrence.obj_guid),
cascade='all, delete-orphan',
uselist=False,
)
def __str__(self):
return "ScheduledTransaction<'{}' {}>".format(self.name, self.recurrence)
class Lot(DeclarativeBaseGuid):
"""
A GnuCash Lot. Each lot is linked to an account. Splits in this account can be associated to a Lot. Whenever
the balance of the splits goes to 0, the Lot is closed (otherwise it is opened)
Attributes:
is_closed (int) : 1 if lot is closed, 0 otherwise
account (:class:`piecash.core.account.Account`): account of the Lot
splits (:class:`piecash.core.transaction.Split`): splits associated to the Lot
"""
__tablename__ = 'lots'
__table_args__ = {}
# column definitions
account_guid = Column('account_guid', VARCHAR(length=32), ForeignKey('accounts.guid'))
is_closed = Column('is_closed', INTEGER(), nullable=False)
primaryjoin=and_(
cls.guid == foreign(Job.owner_guid),
owner_type == Job.owner_type,
),
cascade='all, delete-orphan',
collection_class=CallableList,
)
@event.listens_for(cls.jobs, "append")
def add(target, value, initiator):
value.owner_type = owner_type
value.owner_guid = target.guid
value._assign_id()
class Customer(Person, DeclarativeBaseGuid):
"""
A GnuCash Customer
Attributes:
name (str): name of the Customer
id (str): autonumber id with 5 digits (initialised to book.counter_customer + 1)
notes (str): notes
active (int): 1 if the customer is active, 0 otherwise
discount (:class:`decimal.Decimal`): see Gnucash documentation
credit (:class:`decimal.Decimal`): see Gnucash documentation
currency (:class:`piecash.core.commodity.Commodity`): the currency of the customer
tax_override (int): 1 if tax override, 0 otherwise
address (:class:`Address`): the address of the customer
shipping_address (:class:`Address`): the shipping address of the customer
tax_included (str): 'yes', 'no', 'use global'
taxtable (:class:`piecash.business.tax.TaxTable`): tax table of the customer
discount = hybrid_property_gncnumeric(_discount_num, _discount_denom)
cutoff = Column('cutoff', INTEGER())
# relation definitions
children = relation('Billterm',
back_populates='parent',
cascade='all, delete-orphan',
collection_class=CallableList,
)
parent = relation('Billterm',
back_populates='children',
remote_side=guid,
)
class Entry(DeclarativeBaseGuid):
__tablename__ = 'entries'
__table_args__ = {}
# column definitions
date = Column('date', _DateTime(), nullable=False)
date_entered = Column('date_entered', _DateTime())
description = Column('description', VARCHAR(length=2048))
action = Column('action', VARCHAR(length=2048))
notes = Column('notes', VARCHAR(length=2048))
_quantity_num = Column('quantity_num', BIGINT())
_quantity_denom = Column('quantity_denom', BIGINT())
_quantity_denom_basis = None
quantity = hybrid_property_gncnumeric(_quantity_num, _quantity_denom)
i_acct = Column('i_acct', VARCHAR(length=32))
def __declare_last__(cls):
# do not do it on the DeclarativeBaseGuid as it is an abstract class
if cls == DeclarativeBaseGuid:
return
# assign id of slot when associating to object
@event.listens_for(cls.slots, "remove")
def my_append_listener_slots(target, value, initiator):
s = object_session(value)
if s:
if value in s.new:
s.expunge(value)
else:
s.delete(value)
if "allow-root-subaccounts" in control_mode:
return type_child in ACCOUNT_TYPES
else:
return type_child in (ACCOUNT_TYPES - root_types)
if type_child in root_types:
return (type_parent is None) or ("allow-root-subaccounts" in control_mode)
for acc_types in (assetliab_types, equity_types, incexp_types, trading_types):
if (type_child in acc_types) and (type_parent in acc_types):
return True
return False
class Account(DeclarativeBaseGuid):
"""
A GnuCash Account which is specified by its name, type and commodity.
Attributes:
type (str): type of the Account
sign (int): 1 for accounts with positive balances, -1 for accounts with negative balances
code (str): code of the Account
commodity (:class:`piecash.core.commodity.Commodity`): the commodity of the account
commodity_scu (int): smallest currency unit for the account
non_std_scu (int): 1 if the scu of the account is NOT the same as the commodity
description (str): description of the account
name (str): name of the account
fullname (str): full name of the account (including name of parent accounts separated by ':')
placeholder (int): 1 if the account is a placeholder (should not be involved in transactions)
hidden (int): 1 if the account is hidden
is_template (bool): True if the account is a template account (ie commodity=template/template)
currency = relation('Commodity')
post_account = relation('Account')
post_lot = relation('Lot')
post_txn = relation('Transaction')
entries = relation('Entry',
back_populates='invoice',
cascade='all, delete-orphan',
collection_class=CallableList,
)
def __unirepr__(self):
return "Invoice<{}>".format(self.id)
class Job(DeclarativeBaseGuid):
__tablename__ = 'jobs'
__table_args__ = {}
# column definitions
id = Column('id', VARCHAR(length=2048), nullable=False)
name = Column('name', VARCHAR(length=2048), nullable=False)
reference = Column('reference', VARCHAR(length=2048), nullable=False)
active = Column('active', INTEGER(), nullable=False)
owner_type = Column('owner_type', INTEGER())
owner_guid = Column('owner_guid', VARCHAR(length=32))
# relation definitions
# todo: owner_guid/type links to Vendor or Customer
def __init__(self, name, owner, reference="", active=1):
self.name = name
if book and id is None:
book.add(self)
elif id is not None:
if isinstance(id, int):
self.id = str(id)
else:
self.id = id
_counter_name = "counter_employee"
def on_book_add(self):
self._assign_id()
class Vendor(Person, DeclarativeBaseGuid):
"""
A GnuCash Vendor
Attributes:
name (str): name of the Vendor
id (str): autonumber id with 5 digits (initialised to book.counter_vendor + 1)
notes (str): notes
active (int): 1 if the vendor is active, 0 otherwise
currency (:class:`piecash.core.commodity.Commodity`): the currency of the vendor
tax_override (int): 1 if tax override, 0 otherwise
address (:class:`Address`): the address of the vendor
tax_included (str): 'YES', 'NO', 'USEGLOBAL'
taxtable (:class:`piecash.business.tax.TaxTable`): tax table of the vendor
term (:class:`piecash.business.invoice.Billterm`): bill term of the vendor
"""
__tablename__ = 'vendors'