| 1 | # |
|---|
| 2 | # ShoeBox |
|---|
| 3 | # A start product for Plone - ShoeBox |
|---|
| 4 | # |
|---|
| 5 | # ShoeBox.py |
|---|
| 6 | # The Product |
|---|
| 7 | # |
|---|
| 8 | # Author: Christian Koller <admin@iecw.net> |
|---|
| 9 | # |
|---|
| 10 | # Released under GNU GPL v2 or later |
|---|
| 11 | # |
|---|
| 12 | |
|---|
| 13 | from zLOG import LOG, INFO |
|---|
| 14 | |
|---|
| 15 | from Products.Archetypes.public import * |
|---|
| 16 | from Products.ShoeBox.config import PROJECTNAME |
|---|
| 17 | from Products.CMFCore import CMFCorePermissions |
|---|
| 18 | from Products.CMFCore.WorkflowCore import ObjectMoved |
|---|
| 19 | from Products.validation import V_REQUIRED |
|---|
| 20 | from AccessControl import ClassSecurityInfo |
|---|
| 21 | |
|---|
| 22 | from Products.ATContentTypes.content.schemata import ATContentTypeSchema |
|---|
| 23 | from Products.ATContentTypes.content.schemata import finalizeATCTSchema |
|---|
| 24 | |
|---|
| 25 | from Products.ShoeBox.config import DIRECTIONS, PROJECTNAME |
|---|
| 26 | |
|---|
| 27 | class ShoeBoxEntry(BaseContent): |
|---|
| 28 | """ ShoeBox line entry """ |
|---|
| 29 | meta_type = 'ShoeBoxEntry' |
|---|
| 30 | |
|---|
| 31 | security = ClassSecurityInfo() |
|---|
| 32 | # _at_rename_after_creation = True # Don't do this, else duplicate titles will conflict |
|---|
| 33 | |
|---|
| 34 | schema = ATContentTypeSchema.copy() + Schema(( |
|---|
| 35 | StringField('account', |
|---|
| 36 | searchable=0, |
|---|
| 37 | required=1, |
|---|
| 38 | #validators=('isAllowedUrl'), |
|---|
| 39 | vocabulary = 'getAccounts', |
|---|
| 40 | default_method='getDefaultAccount', |
|---|
| 41 | widget=SelectionWidget( |
|---|
| 42 | label='Account', |
|---|
| 43 | label_msgid='account', |
|---|
| 44 | i18n_domain='ShoeBox', |
|---|
| 45 | format='flex', |
|---|
| 46 | ), |
|---|
| 47 | ), |
|---|
| 48 | StringField('direction', |
|---|
| 49 | searchable=0, |
|---|
| 50 | required=1, |
|---|
| 51 | vocabulary = DIRECTIONS, |
|---|
| 52 | widget=SelectionWidget( |
|---|
| 53 | label='Incoming/outgoing', |
|---|
| 54 | label_msgid='direction', |
|---|
| 55 | i18n_domain='ShoeBox', |
|---|
| 56 | format='flex', |
|---|
| 57 | ), |
|---|
| 58 | ), |
|---|
| 59 | # This is required, but it can be 0.00 which is the default |
|---|
| 60 | FixedPointField('amount', |
|---|
| 61 | searchable=0, |
|---|
| 62 | required=0, |
|---|
| 63 | widget=DecimalWidget( |
|---|
| 64 | label='Amount', |
|---|
| 65 | label_msgid='amount', |
|---|
| 66 | description='The amount of money involved.', |
|---|
| 67 | description_msgid='amount_description', |
|---|
| 68 | size='10', |
|---|
| 69 | i18n_domain='ShoeBox', |
|---|
| 70 | dollars_and_cents=True, |
|---|
| 71 | ), |
|---|
| 72 | ), |
|---|
| 73 | StringField('thirdparty', |
|---|
| 74 | searchable=1, |
|---|
| 75 | required=1, |
|---|
| 76 | widget=StringWidget( |
|---|
| 77 | label='Third party', |
|---|
| 78 | label_msgid='thirdparty', |
|---|
| 79 | description='The other party involved.', |
|---|
| 80 | description_msgid='thirdparty_description', |
|---|
| 81 | size='20', |
|---|
| 82 | i18n_domain='ShoeBox', |
|---|
| 83 | ), |
|---|
| 84 | ), |
|---|
| 85 | StringField('reference', |
|---|
| 86 | searchable=1, |
|---|
| 87 | required=0, |
|---|
| 88 | widget=StringWidget( |
|---|
| 89 | label='Reference', |
|---|
| 90 | label_msgid='reference', |
|---|
| 91 | description='The documentation.', |
|---|
| 92 | description_msgid='reference_description', |
|---|
| 93 | size='20', |
|---|
| 94 | i18n_domain='ShoeBox', |
|---|
| 95 | ), |
|---|
| 96 | ), |
|---|
| 97 | DateTimeField('date', |
|---|
| 98 | searchable=0, |
|---|
| 99 | required=1, |
|---|
| 100 | widget=CalendarWidget( |
|---|
| 101 | label='Date', |
|---|
| 102 | label_msgid='date', |
|---|
| 103 | description='The date of the transaction.', |
|---|
| 104 | description_msgid='date_description', |
|---|
| 105 | i18n_domain='ShoeBox', |
|---|
| 106 | show_hm=False, |
|---|
| 107 | ), |
|---|
| 108 | ), |
|---|
| 109 | |
|---|
| 110 | )) |
|---|
| 111 | |
|---|
| 112 | finalizeATCTSchema(schema) |
|---|
| 113 | ## |
|---|
| 114 | ## The Schema includes two variables, on for the Repository itself and one for a Path within the Repository |
|---|
| 115 | ## |
|---|
| 116 | |
|---|
| 117 | def getAmount(self): |
|---|
| 118 | """ |
|---|
| 119 | Returns amount as a float |
|---|
| 120 | """ |
|---|
| 121 | return self.amount[0] + float(self.amount[1])/100.0 |
|---|
| 122 | |
|---|
| 123 | ## Set the icon for the ShoeBox |
|---|
| 124 | content_icon = 'shoebox.png' |
|---|
| 125 | |
|---|
| 126 | def getAccounts(self): |
|---|
| 127 | """ |
|---|
| 128 | Returns a list of accounts available to this entry |
|---|
| 129 | """ |
|---|
| 130 | accounts = self.getShoeBox().getAccounts() |
|---|
| 131 | result = DisplayList() |
|---|
| 132 | for account in accounts: |
|---|
| 133 | result.add(account.getId(), account.Title()) |
|---|
| 134 | return result |
|---|
| 135 | |
|---|
| 136 | def getShoeBox(self): |
|---|
| 137 | """ |
|---|
| 138 | Return the showbox which contains this entry |
|---|
| 139 | """ |
|---|
| 140 | p = self.getFolderWhenPortalFactory() |
|---|
| 141 | if p.meta_type == 'ShoeBoxAccount': |
|---|
| 142 | p = p.getParentNode() |
|---|
| 143 | return p |
|---|
| 144 | |
|---|
| 145 | def getIncomingOutgoingSelection(self): |
|---|
| 146 | """ |
|---|
| 147 | Return a list which has incoming as false and outgoing as true |
|---|
| 148 | """ |
|---|
| 149 | result = DisplayList() |
|---|
| 150 | result.add(0, "Incoming") |
|---|
| 151 | result.add(1, "Outgoing") |
|---|
| 152 | return result |
|---|
| 153 | |
|---|
| 154 | def getDefaultAccount(self): |
|---|
| 155 | p = self.getFolderWhenPortalFactory() |
|---|
| 156 | if p.meta_type == 'ShoeBoxAccount': |
|---|
| 157 | LOG("ShoeBoxEntry",INFO,'Setting parent to %s'%p.getId()) |
|---|
| 158 | return p.getId() |
|---|
| 159 | else: |
|---|
| 160 | return None |
|---|
| 161 | |
|---|
| 162 | # def manage_afterAdd(self, item, container): |
|---|
| 163 | # LOG("ShoeBoxEntry",INFO,"manage_afterAdd") |
|---|
| 164 | # super(ShoeBoxEntry, self).manage_afterAdd(item, container) |
|---|
| 165 | |
|---|
| 166 | def at_post_edit_script(self): |
|---|
| 167 | LOG("ShoeBoxEntry",INFO,"at_post_edit_script") |
|---|
| 168 | super(ShoeBoxEntry, self).at_post_edit_script() |
|---|
| 169 | self.moveToAccount() |
|---|
| 170 | |
|---|
| 171 | def at_post_create_script(self): |
|---|
| 172 | LOG("ShoeBoxEntry",INFO,"at_post_create_script") |
|---|
| 173 | super(ShoeBoxEntry, self).at_post_create_script() |
|---|
| 174 | self.moveToAccount() |
|---|
| 175 | |
|---|
| 176 | def moveToAccount(self): |
|---|
| 177 | """ |
|---|
| 178 | Move the entry to the correct account |
|---|
| 179 | """ |
|---|
| 180 | LOG("ShoeBoxEntry",INFO,"Moving from %s to %s"%(self.getParentNode(), self.account)) |
|---|
| 181 | if self.getParentNode().getId() != self.account: |
|---|
| 182 | dest = self.getShoeBox()[self.account] |
|---|
| 183 | dest.manage_pasteObjects( self.getParentNode().manage_cutObjects(self.getId()) ) |
|---|
| 184 | new = dest[self.getId()] |
|---|
| 185 | # def manage_beforeDelete(self, item, container): |
|---|
| 186 | # LOG("ShoeBoxEntry",INFO,"manage_beforeDelete") |
|---|
| 187 | # super(ShoeBoxEntry, self).manage_beforeDelete(item, container) |
|---|
| 188 | |
|---|
| 189 | ## Register the new type within Zope |
|---|
| 190 | registerType(ShoeBoxEntry,PROJECTNAME) |
|---|