Changeset 12213


Ignore:
Timestamp:
13 Dec 2014, 10:51:17 (10 years ago)
Author:
Henrik Bettermann
Message:

We need different workflows for customer documents and central 'public' documents.

Location:
main/waeup.ikoba/trunk/src/waeup/ikoba
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/documents.py

    r12211 r12213  
    2222import grok
    2323from hashlib import md5
     24from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
    2425from zope.component import queryUtility, getUtility
    2526from zope.component.interfaces import IFactory
     
    7677    filenames = ()
    7778
     79    @property
     80    def state(self):
     81        state = IWorkflowState(self).getState()
     82        return state
     83
     84    @property
     85    def translated_state(self):
     86        try:
     87            TRANSLATED_STATES = getUtility(
     88                IDocumentsUtils).TRANSLATED_DOCUMENT_STATES
     89            return TRANSLATED_STATES[self.state]
     90        except KeyError:
     91            return
    7892    @property
    7993    def customer(self):
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py

    r12207 r12213  
    5050from waeup.ikoba.authentication import LocalRoleSetEvent
    5151from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
    52 from waeup.ikoba.documents.workflow import VERIFIED
     52from waeup.ikoba.interfaces import VERIFIED
    5353from waeup.ikoba.browser.tests.test_pdf import samples_dir
    5454
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/workflow.py

    r12212 r12213  
    3333from waeup.ikoba.customers.interfaces import (
    3434    ICustomer, ICustomersUtils,
    35     IContract)
     35    IContract, ICustomerDocument)
    3636from waeup.ikoba.utils.helpers import get_current_principal
    37 from waeup.ikoba.documents.workflow import VERIFICATION_TRANSITIONS
    3837
    3938# Customer workflow
     
    214213    )
    215214
    216 
    217215contract_workflow = IkobaWorkflow(CONTRACT_TRANSITIONS)
     216
    218217
    219218class ContractWorkflowState(WorkflowState, grok.Adapter):
     
    225224    state_key = 'wf.contract.state'
    226225    state_id = 'wf.contract.id'
     226
    227227
    228228class ContractWorkflowInfo(IkobaWorkflowInfo, grok.Adapter):
     
    258258        pass
    259259    return
     260
     261# Customer document workflow
     262
     263VERIFICATION_TRANSITIONS = (
     264    Transition(
     265        transition_id = 'create',
     266        title = _('Create document'),
     267        source = None,
     268        condition = NullCondition,
     269        msg = _('Document created'),
     270        destination = CREATED),
     271
     272    Transition(
     273        transition_id = 'submit',
     274        title = _('Submit for verification'),
     275        msg = _('Submitted for verification'),
     276        source = CREATED,
     277        destination = SUBMITTED),
     278
     279    Transition(
     280        transition_id = 'verify',
     281        title = _('Verify'),
     282        msg = _('Verified'),
     283        source = SUBMITTED,
     284        destination = VERIFIED),
     285
     286    Transition(
     287        transition_id = 'reject',
     288        title = _('Reject'),
     289        msg = _('REJECTED'),
     290        source = SUBMITTED,
     291        destination = REJECTED),
     292
     293    Transition(
     294        transition_id = 'reset1',
     295        title = _('Reset to initial state'),
     296        msg = _('Reset to initial state'),
     297        source = REJECTED,
     298        destination = CREATED),
     299
     300    Transition(
     301        transition_id = 'reset2',
     302        title = _('Reset to initial state'),
     303        msg = _('Reset to initial state'),
     304        source = VERIFIED,
     305        destination = CREATED),
     306
     307    Transition(
     308        transition_id = 'reset3',
     309        title = _('Reset to initial state'),
     310        msg = _('Reset to initial state'),
     311        source = SUBMITTED,
     312        destination = CREATED),
     313
     314    Transition(
     315        transition_id = 'expire',
     316        title = _('Set to expired'),
     317        msg = _('Set to expired'),
     318        source = VERIFIED,
     319        destination = EXPIRED),
     320
     321    Transition(
     322        transition_id = 'reset4',
     323        title = _('Reset to initial state'),
     324        msg = _('Reset to initial state'),
     325        source = EXPIRED,
     326        destination = CREATED),
     327    )
     328
     329verification_workflow = IkobaWorkflow(VERIFICATION_TRANSITIONS)
     330
     331
     332class VerificationWorkflowState(WorkflowState, grok.Adapter):
     333    """An adapter to adapt CustomerDocument objects to workflow states.
     334    """
     335    grok.context(ICustomerDocument)
     336    grok.provides(IWorkflowState)
     337
     338    state_key = 'wf.verification.state'
     339    state_id = 'wf.verification.id'
     340
     341
     342class VerificationWorkflowInfo(IkobaWorkflowInfo, grok.Adapter):
     343    """Adapter to adapt CustomerDocument objects to workflow info objects.
     344    """
     345    grok.context(ICustomerDocument)
     346    grok.provides(IIkobaWorkflowInfo)
     347
     348    def __init__(self, context):
     349        self.context = context
     350        self.wf = verification_workflow
     351
     352@grok.subscribe(ICustomerDocument, IWorkflowTransitionEvent)
     353def handle_customer_document_transition_event(obj, event):
     354    """Append message to document history and log file.
     355
     356    Undo the verification of document and raise an exception if document
     357    does not meet the requirements for verification.
     358    """
     359    if event.transition.destination == VERIFIED:
     360        verifiable, error = obj.is_verifiable
     361        if not verifiable:
     362            # Undo transition and raise an exception.
     363            IWorkflowState(obj).setState(event.transition.source)
     364            raise InvalidTransitionError(error)
     365    if event.transition.transition_id == 'verify':
     366        obj.setMD5()
     367    msg = event.transition.user_data['msg']
     368    history = IObjectHistory(obj)
     369    history.addMessage(msg)
     370    try:
     371        customers_container = grok.getSite()['customers']
     372        customers_container.logger.info('%s - %s' % (obj.customer_id,msg))
     373    except (TypeError, AttributeError):
     374        pass
     375    return
  • main/waeup.ikoba/trunk/src/waeup/ikoba/documents/browser.py

    r12206 r12213  
    125125    @action(_('Create document'), style='primary')
    126126    def addDocument(self, **data):
    127         document = createObject(u'waeup.Document')
     127        document = createObject(u'waeup.PublicDocument')
    128128        self.applyData(document, **data)
    129129        try:
  • main/waeup.ikoba/trunk/src/waeup/ikoba/documents/container.py

    r12207 r12213  
    2424from waeup.ikoba.documents.interfaces import IDocumentsContainer, IDocument
    2525from waeup.ikoba.utils.helpers import attrs_to_fields
     26from waeup.ikoba.utils.logger import Logger
    2627
    27 class DocumentsContainer(grok.Container):
     28class DocumentsContainer(grok.Container, Logger):
    2829    """This is a container for all kind of documents.
    2930    """
  • main/waeup.ikoba/trunk/src/waeup/ikoba/documents/document.py

    r12211 r12213  
    3838from waeup.ikoba.utils.helpers import attrs_to_fields, get_current_principal
    3939from waeup.ikoba.documents.interfaces import (
    40     IDocument, IDocument, IDocumentsUtils,
     40    IDocument, IPublicDocument, IDocumentsUtils,
    4141    IPDFDocument, IHTMLDocument)
    4242from waeup.ikoba.documents.utils import generate_document_id
     
    5454
    5555    user_id = None
     56    state = None
     57    translated_state = None
    5658
    5759    def __init__(self):
     
    7072
    7173    @property
     74    def class_name(self):
     75        return self.__class__.__name__
     76
     77    @property
     78    def formatted_transition_date(self):
     79        try:
     80            return self.history.messages[-1].split(' - ')[0]
     81        except IndexError:
     82            return
     83
     84    @property
     85    def connected_files(self):
     86        return
     87
     88    @property
     89    def is_verifiable(self):
     90        return True, None
     91
     92    def setMD5(self):
     93        """Determine md5 checksum of all files and store checksums as
     94        document attributes.
     95        """
     96        return
     97       
     98class PublicDocumentBase(Document):
     99    """This is a customer document baseclass.
     100    """
     101    grok.implements(IPublicDocument)
     102    grok.provides(IPublicDocument)
     103    grok.baseclass()
     104
     105    @property
    72106    def state(self):
    73107        state = IWorkflowState(self).getState()
     
    83117            return
    84118
    85     @property
    86     def class_name(self):
    87         return self.__class__.__name__
    88 
    89     @property
    90     def formatted_transition_date(self):
    91         try:
    92             return self.history.messages[-1].split(' - ')[0]
    93         except IndexError:
    94             return
    95 
    96     @property
    97     def connected_files(self):
    98         return
    99 
    100     @property
    101     def is_verifiable(self):
    102         return True, None
    103 
    104     def setMD5(self):
    105         """Determine md5 checksum of all files and store checksums as
    106         document attributes.
    107         """
    108         return
    109        
    110 Document = attrs_to_fields(Document)
    111 
    112 
    113 class PDFDocument(Document):
     119
     120class PDFDocument(PublicDocumentBase):
    114121    """This is a  document for a single pdf upload file.
    115122    """
     
    120127
    121128
    122 class HTMLDocument(Document):
     129class HTMLDocument(PublicDocumentBase):
    123130    """This is a  document to render html-coded text.
    124131    """
     
    133140    """
    134141    grok.implements(IFactory)
    135     grok.name(u'waeup.Document')
    136     title = u"Create a new document.",
    137     description = u"This factory instantiates new documents."
     142    grok.name(u'waeup.PublicDocument')
     143    title = u"Create a new public document.",
     144    description = u"This factory instantiates new public documents."
    138145
    139146    def __call__(self, *args, **kw):
    140         return Document(*args, **kw)
     147        return PublicDocument(*args, **kw)
    141148
    142149    def getInterfaces(self):
    143         return implementedBy(Document)
     150        return implementedBy(PublicDocument)
    144151
    145152
  • main/waeup.ikoba/trunk/src/waeup/ikoba/documents/interfaces.py

    r12210 r12213  
    5959        """
    6060
    61 class IPDFDocument(IDocument):
     61class IPublicDocument(IDocument):
     62    """A base representation of public documents.
     63
     64    """
     65
     66
     67class IPDFDocument(IPublicDocument):
    6268    """A base representation of PDF documents.
    6369
     
    6571
    6672
    67 class IHTMLDocument(IDocument):
     73class IHTMLDocument(IPublicDocument):
    6874    """A base representation of HTML documents.
    6975
  • main/waeup.ikoba/trunk/src/waeup/ikoba/documents/tests/test_document.py

    r12204 r12213  
    3030from waeup.ikoba.imagestorage import DefaultStorage
    3131from waeup.ikoba.documents.interfaces import (
    32     IDocumentsContainer, IDocument, IPDFDocument, IHTMLDocument)
     32    IDocumentsContainer, IPublicDocument, IPDFDocument, IHTMLDocument)
    3333from waeup.ikoba.documents.container import DocumentsContainer
    3434from waeup.ikoba.documents.document import (
    35     Document, PDFDocument, HTMLDocument,
     35    PDFDocument, HTMLDocument,
    3636    DocumentFileNameChooser, DocumentFileStoreHandler)
    3737from waeup.ikoba.testing import (FunctionalLayer, FunctionalTestCase)
     
    5353        self.assertTrue(
    5454            verifyClass(
    55                 IDocument, Document)
    56             )
    57         self.assertTrue(
    58             verifyObject(
    59                 IDocument, Document())
    60             )
    61 
    62         self.assertTrue(
    63             verifyClass(
    6455                IPDFDocument, PDFDocument)
    6556            )
     
    6859                IPDFDocument, PDFDocument())
    6960            )
    70 
    7161        self.assertTrue(
    7262            verifyClass(
     
    9383        IWorkflowInfo(document).fireTransition('create')
    9484        self.assertEqual(IWorkflowState(document).getState(), 'created')
    95         IWorkflowInfo(document).fireTransition('submit')
    96         self.assertEqual(IWorkflowState(document).getState(), 'submitted')
    97         IWorkflowInfo(document).fireTransition('verify')
    98         self.assertEqual(IWorkflowState(document).getState(), 'verified')
    99         IWorkflowInfo(document).fireTransition('reset2')
    100         self.assertEqual(IWorkflowState(document).getState(), 'created')
    101         self.assertRaises(InvalidTransitionError,
    102             IWorkflowInfo(document).fireTransition, 'verify')
    103         IWorkflowInfo(document).fireTransition('submit')
    104         IWorkflowInfo(document).fireTransition('reset3')
    105         self.assertEqual(IWorkflowState(document).getState(), 'created')
    106         IWorkflowInfo(document).fireTransition('publish')
    107         self.assertEqual(IWorkflowState(document).getState(), 'published')
    10885        return
    10986
     
    166143    def test_name_chooser_available(self):
    167144        # we can get a name chooser for document objects as adapter
    168         doc = Document()
     145        doc = PDFDocument()
    169146        chooser = IFileStoreNameChooser(doc)
    170147        self.assertTrue(chooser is not None)
     
    173150    def test_name_chooser_document(self):
    174151        # we can get an image filename for documents not in a container
    175         doc = Document()
     152        doc = PDFDocument()
    176153        chooser = IFileStoreNameChooser(doc)
    177154        result = chooser.chooseName('sample.jpg')
  • main/waeup.ikoba/trunk/src/waeup/ikoba/documents/workflow.py

    r12212 r12213  
    1919"""
    2020import grok
    21 from datetime import datetime
    2221from zope.component import getUtility
    2322from hurry.workflow.workflow import Transition, WorkflowState, NullCondition
     
    2726    IObjectHistory, IIkobaWorkflowInfo,
    2827    SimpleIkobaVocabulary,
    29     CREATED, SUBMITTED, VERIFIED, REJECTED, EXPIRED, PUBLISHED)
     28    CREATED, PUBLISHED)
    3029from waeup.ikoba.interfaces import MessageFactory as _
    3130from waeup.ikoba.workflow import IkobaWorkflow, IkobaWorkflowInfo
    32 from waeup.ikoba.utils.helpers import get_current_principal
    33 from waeup.ikoba.documents.interfaces import IDocument
     31from waeup.ikoba.documents.interfaces import IPublicDocument
    3432
    35 VERIFICATION_TRANSITIONS = (
     33
     34PUBLISHING_TRANSITIONS = (
    3635    Transition(
    3736        transition_id = 'create',
     
    4140        msg = _('Document created'),
    4241        destination = CREATED),
    43 
    44     Transition(
    45         transition_id = 'submit',
    46         title = _('Submit for verification'),
    47         msg = _('Submitted for verification'),
    48         source = CREATED,
    49         destination = SUBMITTED),
    50 
    51     Transition(
    52         transition_id = 'verify',
    53         title = _('Verify'),
    54         msg = _('Verified'),
    55         source = SUBMITTED,
    56         destination = VERIFIED),
    57 
    58     Transition(
    59         transition_id = 'reject',
    60         title = _('Reject'),
    61         msg = _('REJECTED'),
    62         source = SUBMITTED,
    63         destination = REJECTED),
    64 
    65     Transition(
    66         transition_id = 'reset1',
    67         title = _('Reset to initial state'),
    68         msg = _('Reset to initial state'),
    69         source = REJECTED,
    70         destination = CREATED),
    71 
    72     Transition(
    73         transition_id = 'reset2',
    74         title = _('Reset to initial state'),
    75         msg = _('Reset to initial state'),
    76         source = VERIFIED,
    77         destination = CREATED),
    78 
    79     Transition(
    80         transition_id = 'reset3',
    81         title = _('Reset to initial state'),
    82         msg = _('Reset to initial state'),
    83         source = SUBMITTED,
    84         destination = CREATED),
    85 
    86     Transition(
    87         transition_id = 'expire',
    88         title = _('Set to expired'),
    89         msg = _('Set to expired'),
    90         source = VERIFIED,
    91         destination = EXPIRED),
    92 
    93     Transition(
    94         transition_id = 'reset4',
    95         title = _('Reset to initial state'),
    96         msg = _('Reset to initial state'),
    97         source = EXPIRED,
    98         destination = CREATED),
    99 
    100     Transition(
    101         transition_id = 'publish',
    102         title = _('Publish'),
    103         msg = _('Published'),
    104         source = CREATED,
    105         destination = PUBLISHED),
    10642    )
    10743
     44publishing_workflow = IkobaWorkflow(PUBLISHING_TRANSITIONS)
    10845
    109 verification_workflow = IkobaWorkflow(VERIFICATION_TRANSITIONS)
    110 
    111 class VerificationWorkflowState(WorkflowState, grok.Adapter):
     46class PublishingWorkflowState(WorkflowState, grok.Adapter):
    11247    """An adapter to adapt Document objects to workflow states.
    11348    """
    114     grok.context(IDocument)
     49    grok.context(IPublicDocument)
    11550    grok.provides(IWorkflowState)
    11651
    117     state_key = 'wf.verification.state'
    118     state_id = 'wf.verification.id'
     52    state_key = 'wf.publishing.state'
     53    state_id = 'wf.publishing.id'
    11954
    120 class VerificationWorkflowInfo(IkobaWorkflowInfo, grok.Adapter):
    121     """Adapter to adapt Document objects to workflow info objects.
     55
     56class PublishingWorkflowInfo(IkobaWorkflowInfo, grok.Adapter):
     57    """Adapter to adapt CustomerDocument objects to workflow info objects.
    12258    """
    123     grok.context(IDocument)
     59    grok.context(IPublicDocument)
    12460    grok.provides(IIkobaWorkflowInfo)
    12561
    12662    def __init__(self, context):
    12763        self.context = context
    128         self.wf = verification_workflow
     64        self.wf = publishing_workflow
    12965
    130 @grok.subscribe(IDocument, IWorkflowTransitionEvent)
    131 def handle_document_transition_event(obj, event):
     66
     67@grok.subscribe(IPublicDocument, IWorkflowTransitionEvent)
     68def handle_public_document_transition_event(obj, event):
    13269    """Append message to document history and log file.
    13370
    134     Undo the verification of document and raise an exception if document
    135     does not meet the requirements for verification.
    13671    """
    137     if event.transition.destination == VERIFIED:
    138         verifiable, error = obj.is_verifiable
    139         if not verifiable:
    140             # Undo transition and raise an exception.
    141             IWorkflowState(obj).setState(event.transition.source)
    142             raise InvalidTransitionError(error)
    143     if event.transition.transition_id == 'verify':
    144         obj.setMD5()
    14572    msg = event.transition.user_data['msg']
    14673    history = IObjectHistory(obj)
    14774    history.addMessage(msg)
    14875    try:
    149         customers_container = grok.getSite()['customers']
    150         customers_container.logger.info('%s - %s' % (obj.customer_id,msg))
     76        grok.getSite().logger.info('%s' % msg)
    15177    except (TypeError, AttributeError):
    15278        pass
  • main/waeup.ikoba/trunk/src/waeup/ikoba/products/container.py

    r12064 r12213  
    2323from waeup.ikoba.products.interfaces import IProductsContainer, IProduct
    2424from waeup.ikoba.utils.helpers import attrs_to_fields
     25from waeup.ikoba.utils.logger import Logger
    2526
    26 class ProductsContainer(grok.Container):
     27class ProductsContainer(grok.Container, Logger):
    2728    """This is a container for all kind of products.
    2829    """
  • main/waeup.ikoba/trunk/src/waeup/ikoba/products/tests/test_browser.py

    r12186 r12213  
    4141from waeup.ikoba.authentication import LocalRoleSetEvent
    4242from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
    43 from waeup.ikoba.documents.workflow import VERIFIED
    4443from waeup.ikoba.browser.tests.test_pdf import samples_dir
    4544
Note: See TracChangeset for help on using the changeset viewer.