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

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

Add interface and page for editing official use data. Adjust exporter.

  • Property svn:keywords set to Id
File size: 6.6 KB
RevLine 
[12089]1## $Id: contracts.py 12500 2015-01-20 17:31: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 _
[12258]29from waeup.ikoba.interfaces import (
30    IIkobaUtils, IObjectHistory, VERIFIED, IIDSource)
[12089]31from waeup.ikoba.customers.interfaces import (
[12097]32    IContractsContainer, ICustomerNavigation,
[12500]33    IContract, IContractSelectProduct, ICustomersUtils,
34    ISampleContract, ISampleContractProcess, ISampleContractEdit,
35    ISampleContractOfficialUse)
[12097]36from waeup.ikoba.customers.utils import generate_contract_id
[12089]37from waeup.ikoba.utils.helpers import attrs_to_fields
38
[12097]39class ContractsContainer(grok.Container):
40    """This is a container for customer contracts.
[12089]41    """
[12097]42    grok.implements(IContractsContainer, ICustomerNavigation)
43    grok.provides(IContractsContainer)
[12089]44
[12097]45    def addContract(self, contract):
46        if not IContract.providedBy(contract):
[12089]47            raise TypeError(
[12097]48                'ContractsContainers contain only IContract instances')
49        self[contract.contract_id] = contract
[12089]50        return
51
52    @property
53    def customer(self):
54        return self.__parent__
55
56    def writeLogMessage(self, view, message):
57        return self.__parent__.writeLogMessage(view, message)
58
[12097]59ContractsContainer = attrs_to_fields(ContractsContainer)
[12089]60
[12097]61class ContractBase(grok.Container):
62    """This is a customer contract baseclass.
[12089]63    """
[12486]64    grok.implements(IContractSelectProduct)  # Necesary for the selectproduct page
[12333]65
[12089]66    grok.baseclass()
67
68    def __init__(self):
[12097]69        super(ContractBase, self).__init__()
[12089]70        # The site doesn't exist in unit tests
[12258]71        source = getUtility(IIDSource)
72        self.contract_id = unicode(source.get_hex_uuid())
[12094]73        self.last_product_id = None
[12363]74        self.tc_dict = {}
[12089]75        return
76
77    @property
78    def history(self):
79        history = IObjectHistory(self)
80        return history
81
82    @property
83    def state(self):
84        return IWorkflowState(self).getState()
85
86    @property
87    def translated_state(self):
88        try:
89            TRANSLATED_STATES = getUtility(
[12097]90                ICustomersUtils).TRANSLATED_CONTRACT_STATES
[12089]91            return TRANSLATED_STATES[self.state]
92        except KeyError:
93            return
94
95    @property
96    def class_name(self):
97        return self.__class__.__name__
98
99    @property
100    def formatted_transition_date(self):
101        try:
[12210]102            return self.history.messages[-1].split(' - ')[0]
103        except IndexError:
[12089]104            return
105
106    @property
[12336]107    def title(self):
108        return getattr(
109            getattr(self, 'product_object', None),
110            'contract_autotitle', None)
111
112    @property
[12089]113    def customer(self):
114        try:
115            return self.__parent__.__parent__
116        except AttributeError:
117            return None
118
[12289]119    @property
120    def user_id(self):
121        if self.customer is not None:
122            return self.customer.customer_id
123        return
124
[12089]125    def writeLogMessage(self, view, message):
126        return self.__parent__.__parent__.writeLogMessage(view, message)
127
128    @property
[12337]129    def is_editable(self):
[12089]130        try:
131            # Customer must be approved
132            cond1 = self.customer.state in getUtility(
[12099]133                ICustomersUtils).CONMANAGE_CUSTOMER_STATES
[12097]134            # Contract must be in state created
[12089]135            cond2 = self.state in getUtility(
[12099]136                ICustomersUtils).CONMANAGE_CONTRACT_STATES
[12089]137            if not (cond1 and cond2):
138                return False
139        except AttributeError:
140            pass
141        return True
142
143    @property
[12144]144    def is_approvable(self):
[12352]145        if self.customer and not self.customer.state in getUtility(
146                ICustomersUtils).CONMANAGE_CUSTOMER_STATES:
147            return False, _("Customer has not yet been approved.")
[12144]148        for key, field in getFields(self.check_docs_interface).items():
149            if key.endswith('_object'):
150                obj = getattr(self, key, None)
151                state = getattr(obj, 'state', None)
152                if state and state != VERIFIED:
[12168]153                    return False, _("Attached documents must be verified first.")
154        return True, None
[12144]155
156    @property
[12089]157    def translated_class_name(self):
158        try:
[12099]159            CONTYPES_DICT = getUtility(ICustomersUtils).CONTYPES_DICT
160            return CONTYPES_DICT[self.class_name]
[12089]161        except KeyError:
162            return
163
164
[12097]165class SampleContract(ContractBase):
166    """This is a sample contract.
[12089]167    """
168
[12333]169    grok.implements(
170        ISampleContractProcess, # must come before ISampleContract
171        ISampleContract,
172        ISampleContractEdit,
173        ICustomerNavigation)
[12103]174
[12097]175    contract_category = 'sample'
[12092]176
[12103]177    form_fields_interface = ISampleContract
178
179    edit_form_fields_interface = ISampleContractEdit
180
[12500]181    ou_form_fields_interface = ISampleContractOfficialUse
182
[12144]183    check_docs_interface = ISampleContract
184
[12097]185SampleContract = attrs_to_fields(SampleContract)
[12089]186
187
[12097]188# Contracts must be importable. So we might need a factory.
189class SampleContractFactory(grok.GlobalUtility):
190    """A factory for contracts.
[12089]191    """
192    grok.implements(IFactory)
[12097]193    grok.name(u'waeup.SampleContract')
194    title = u"Create a new contract.",
195    description = u"This factory instantiates new sample contract instances."
[12089]196
197    def __call__(self, *args, **kw):
[12097]198        return SampleContract(*args, **kw)
[12089]199
200    def getInterfaces(self):
[12097]201        return implementedBy(SampleContract)
[12089]202
[12097]203@grok.subscribe(IContract, grok.IObjectAddedEvent)
204def handle_contract_added(contract, event):
205    """If an contract is added the transition create is fired.
[12090]206    The latter produces a logging message.
207    """
[12097]208    if IWorkflowState(contract).getState() is None:
209        IWorkflowInfo(contract).fireTransition('create')
[12090]210    return
Note: See TracBrowser for help on using the repository browser.