source: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/contracts.py @ 12154

Last change on this file since 12154 was 12144, checked in by Henrik Bettermann, 10 years ago

Add property attribute is_approvable.

  • Property svn:keywords set to Id
File size: 6.0 KB
RevLine 
[12089]1## $Id: contracts.py 12144 2014-12-04 18:10:11Z henrik $
2##
3## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
[12097]19Customer contract components.
[12089]20"""
21import os
22import grok
23from zope.component import queryUtility, getUtility
24from zope.component.interfaces import IFactory
25from zope.interface import implementedBy
[12144]26from zope.schema import getFields
[12089]27from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
28from waeup.ikoba.interfaces import MessageFactory as _
[12144]29from waeup.ikoba.interfaces import IIkobaUtils, IObjectHistory, VERIFIED
[12089]30from waeup.ikoba.customers.interfaces import (
[12097]31    IContractsContainer, ICustomerNavigation,
32    IContract, IContractEdit, ICustomersUtils,
[12103]33    ISampleContract, ISampleContractEdit)
[12097]34from waeup.ikoba.customers.utils import generate_contract_id
[12089]35from waeup.ikoba.utils.helpers import attrs_to_fields
36
[12097]37class ContractsContainer(grok.Container):
38    """This is a container for customer contracts.
[12089]39    """
[12097]40    grok.implements(IContractsContainer, ICustomerNavigation)
41    grok.provides(IContractsContainer)
[12089]42
[12097]43    def addContract(self, contract):
44        if not IContract.providedBy(contract):
[12089]45            raise TypeError(
[12097]46                'ContractsContainers contain only IContract instances')
47        self[contract.contract_id] = contract
[12089]48        return
49
50    @property
51    def customer(self):
52        return self.__parent__
53
54    def writeLogMessage(self, view, message):
55        return self.__parent__.writeLogMessage(view, message)
56
[12097]57ContractsContainer = attrs_to_fields(ContractsContainer)
[12089]58
[12097]59class ContractBase(grok.Container):
60    """This is a customer contract baseclass.
[12089]61    """
[12097]62    grok.implements(IContract, IContractEdit, ICustomerNavigation)
63    grok.provides(IContract)
[12089]64    grok.baseclass()
65
[12144]66    check_docs_interface = None
67
[12097]68    contract_category = None
[12092]69
[12103]70    form_fields_interface = None
71
72    edit_form_fields_interface = None
73
[12089]74    def __init__(self):
[12097]75        super(ContractBase, self).__init__()
[12089]76        # The site doesn't exist in unit tests
77        try:
[12097]78            self.contract_id = generate_contract_id()
[12089]79        except AttributeError:
[12097]80            self.contract_id = u'a123'
[12094]81        self.last_product_id = None
[12089]82        return
83
84    @property
85    def history(self):
86        history = IObjectHistory(self)
87        return history
88
89    @property
90    def state(self):
91        return IWorkflowState(self).getState()
92
93    @property
94    def translated_state(self):
95        try:
96            TRANSLATED_STATES = getUtility(
[12097]97                ICustomersUtils).TRANSLATED_CONTRACT_STATES
[12089]98            return TRANSLATED_STATES[self.state]
99        except KeyError:
100            return
101
102    @property
103    def class_name(self):
104        return self.__class__.__name__
105
106    @property
107    def formatted_transition_date(self):
108        try:
109            return self.last_transition_date.strftime('%Y-%m-%d %H:%M:%S')
110        except AttributeError:
111            return
112
113    @property
114    def customer(self):
115        try:
116            return self.__parent__.__parent__
117        except AttributeError:
118            return None
119
120    def writeLogMessage(self, view, message):
121        return self.__parent__.__parent__.writeLogMessage(view, message)
122
123    @property
124    def is_editable(self):
125        try:
126            # Customer must be approved
127            cond1 = self.customer.state in getUtility(
[12099]128                ICustomersUtils).CONMANAGE_CUSTOMER_STATES
[12097]129            # Contract must be in state created
[12089]130            cond2 = self.state in getUtility(
[12099]131                ICustomersUtils).CONMANAGE_CONTRACT_STATES
[12089]132            if not (cond1 and cond2):
133                return False
134        except AttributeError:
135            pass
136        return True
137
138    @property
[12144]139    def is_approvable(self):
140        for key, field in getFields(self.check_docs_interface).items():
141            if key.endswith('_object'):
142                obj = getattr(self, key, None)
143                state = getattr(obj, 'state', None)
144                if state and state != VERIFIED:
145                    return False
146        return True
147
148    @property
[12089]149    def translated_class_name(self):
150        try:
[12099]151            CONTYPES_DICT = getUtility(ICustomersUtils).CONTYPES_DICT
152            return CONTYPES_DICT[self.class_name]
[12089]153        except KeyError:
154            return
155
156
[12097]157class SampleContract(ContractBase):
158    """This is a sample contract.
[12089]159    """
160
[12103]161    grok.implements(ISampleContract, ISampleContractEdit, ICustomerNavigation)
162
[12097]163    contract_category = 'sample'
[12092]164
[12103]165    form_fields_interface = ISampleContract
166
167    edit_form_fields_interface = ISampleContractEdit
168
[12144]169    check_docs_interface = ISampleContract
170
[12097]171SampleContract = attrs_to_fields(SampleContract)
[12089]172
173
[12097]174# Contracts must be importable. So we might need a factory.
175class SampleContractFactory(grok.GlobalUtility):
176    """A factory for contracts.
[12089]177    """
178    grok.implements(IFactory)
[12097]179    grok.name(u'waeup.SampleContract')
180    title = u"Create a new contract.",
181    description = u"This factory instantiates new sample contract instances."
[12089]182
183    def __call__(self, *args, **kw):
[12097]184        return SampleContract(*args, **kw)
[12089]185
186    def getInterfaces(self):
[12097]187        return implementedBy(SampleContract)
[12089]188
[12097]189@grok.subscribe(IContract, grok.IObjectAddedEvent)
190def handle_contract_added(contract, event):
191    """If an contract is added the transition create is fired.
[12090]192    The latter produces a logging message.
193    """
[12097]194    if IWorkflowState(contract).getState() is None:
195        IWorkflowInfo(contract).fireTransition('create')
[12090]196    return
Note: See TracBrowser for help on using the repository browser.