import datetime import time import re from DateTime import DateTime from Globals import InitializeClass from AccessControl import ClassSecurityInfo from Products.CMFDefault.DublinCore import DefaultDublinCoreImpl from Products.CMFCore.PortalContent import PortalContent from config import product_name, plone_product_name from config import add_permission, config_permission, view_permission from config import add_txn_permission import houseaccts.core # XXX this should probably be in its own product XXX # Global module assertions for Python scripts from Products.PythonScripts.Utility import allow_module allow_module('base64') allow_module('re') allow_module('DateTime.DateTime') factory_type_information = { 'id': plone_product_name, 'meta_type': product_name, 'description': ('Provides view of houseaccts ledger.'), 'product': product_name, 'factory': 'addPloneHouseAcctsView', 'content_icon': 'houseaccts.png', 'immediate_view': 'view', 'actions': ( {'id': 'view', 'name': 'Overview', 'action': 'houseaccts_view', 'permissions': (view_permission,)}, {'id': 'new_txn', 'name': 'New Transaction', 'action': 'txn_form', 'permissions': (add_txn_permission,)}, {'id': 'statements', 'name': 'Statements', 'action': 'statement', 'permissions': (view_permission,)}, {'id': 'edit', 'name': 'Configuration', 'action': 'houseaccts_edit_form', 'permissions': (config_permission,)}, ), } def addPloneHouseAcctsView(self, id, REQUEST=None): """ This is our factory function and creates an empty PloneHouseAcctsView object inside our Plone site """ obj = PloneHouseAcctsView(id) self._setObject(id, obj) class PloneHouseAcctsView(PortalContent, DefaultDublinCoreImpl): meta_type = product_name __implements__ = ( PortalContent.__implements__, DefaultDublinCoreImpl.__implements__ ) security = ClassSecurityInfo() def __init__(self, id): DefaultDublinCoreImpl.__init__(self) self.id = id self._dsn = "" def _getAccts(self): return houseaccts.core.HouseAccts(self._dsn) # no columns of "portlets" when using this app left_slots = "" right_slots = "" security.declareProtected(config_permission, "edit") def edit(self, dsn, safety_belt=""): """ The edit function, that sets all our parameters """ self._dsn = dsn security.declareProtected(view_permission, "getDSN") def getDSN(self): """ Returns the database connection string """ return self._dsn security.declareProtected(view_permission, "getUser") def getUser(self, id): """Return a single user""" return self._getAccts().getUser(id) security.declareProtected(view_permission, "getUsers") def getUsers(self): """Return list of users""" return self._getAccts().getUsers() security.declareProtected(view_permission, "getActiveUsers") def getActiveUsers(self): """Return list of users""" return self._getAccts().getUsers(active_only=True) security.declareProtected(view_permission, "getVisibleUsers") def getVisibleUsers(self): """Return list of users""" return self._getAccts().getUsers(visible_only=True) security.declareProtected(view_permission, "getBalances") def getBalances(self): """ Returns balances for each user """ return self._getAccts().getBalances() security.declareProtected(view_permission, "getOverviewDays") def getOverviewDays(self): if self.REQUEST.form.has_key('d'): return int(self.REQUEST.form['d']) return 365 security.declareProtected(view_permission, "getRecentTransactions") def getRecentTransactions(self): """ Returns a list of transactions """ d = self.getOverviewDays() return self._getAccts().getTransactionsForOverview(d) security.declareProtected(view_permission, "getTransaction") def getTransaction(self, id): """Return a single transaction""" return self._getAccts().getTransaction(id) security.declareProtected(view_permission, "getEarliestTxnDate") def getEarliestTxnDate(self, user): """Return the date of the earliest transaction for user""" etd = DateTime(str(self._getAccts().getEarliestTxnDate(user))) return etd.parts()[:2] security.declareProtected(view_permission, "getStatementDate") def getStatementYM(self): """Return the year and month of the currently requested statement""" if self.REQUEST.form.has_key('m'): return [int(x) for x in self.REQUEST.form['m'].split('-')[:2]] today = DateTime(time.time()) return today.parts()[:2] security.declareProtected(view_permission, "getTodayTuple") def getTodayTuple(self): today = DateTime(time.time()) return today.parts()[:3] security.declareProtected(view_permission, "getStatement") def getStatement(self, user): """Return a statement for user""" year, month = self.getStatementYM() return self._getAccts().getStatement(user, year, month) security.declareProtected(view_permission, "SearchableText") def SearchableText(self): """ Used by the catalog for basic full text indexing """ return "%s %s" % (self.Title(), self.Description()) security.declareProtected(add_txn_permission, "addTransaction") def addTransaction(self, **kwargs): """Add a new transaction""" accts = self._getAccts() user = self.REQUEST.get('AUTHENTICATED_USER', None) creator = user.getUserName() txn = houseaccts.core.newSplitPurchaseTxn(creator=creator, **kwargs) accts.postTransaction(txn) def today_date(self): return datetime.date.today() def earliest_new_txn_date(self): return datetime.date.today().replace(day=1) def validate_new_txn_date(self, str): if re.compile(r'\d{4}-\d{1,2}-\d{1,2}').match(str) == None: return (False, "Date must be in YYYY-M-D format.") try: year, month, day = [int(x) for x in str.split('-')] thedate = datetime.date(year, month, day) except ValueError: return (False, "Invalid date.") earliest = self.earliest_new_txn_date() if thedate < earliest: return (False, "Date must be %s or later." % earliest) return (True, None) InitializeClass(PloneHouseAcctsView)