Ignore:
Timestamp:
29 Dec 2014, 23:05:40 (10 years ago)
Author:
Henrik Bettermann
Message:

Improve contract management. Tests will follow which show that customers can only do what they are allowed to do.

Location:
main/waeup.ikoba/trunk/src/waeup/ikoba
Files:
7 edited
1 moved

Legend:

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

    r12333 r12337  
    8888    view.redirect(view.url(view.context))
    8989    return
     90
     91def isCustomer(principal):
     92    return getattr(principal, 'user_type', None) == 'customer'
    9093
    9194
     
    10931096
    10941097
    1095 class ContractsManageFormPage(IkobaEditFormPage):
    1096     """ Page to manage the customer contracts
    1097 
    1098     This manage form page is for both customers and officers.
     1098class ContractsFormPage(IkobaEditFormPage):
     1099    """ Page to display, edit or manage customer contracts
     1100
     1101    This form page is for both customers and officers.
    10991102    """
    11001103    grok.context(IContractsContainer)
     
    11061109
    11071110    @property
    1108     def manage_contracts_allowed(self):
     1111    def edit_contracts_allowed(self):
     1112        right_customer_state = self.context.customer.state in getUtility(
     1113            ICustomersUtils).CONMANAGE_CUSTOMER_STATES
     1114        if isCustomer(self.request.principal) and not right_customer_state:
     1115            return False
    11091116        return checkPermission('waeup.editContracts', self.context)
    11101117
    1111     def unremovable(self, contract):
    1112         usertype = getattr(self.request.principal, 'user_type', None)
    1113         if not usertype:
    1114             return False
    1115         if not self.manage_contracts_allowed:
    1116             return True
    1117         return (self.request.principal.user_type == 'customer' and \
    1118             contract.state in (APPROVED, REJECTED, EXPIRED))
     1118    def remove_contract_allowed(self, contract):
     1119        if isCustomer(self.request.principal):
     1120            right_customer_state = self.context.customer.state in getUtility(
     1121                ICustomersUtils).CONMANAGE_CUSTOMER_STATES
     1122            if not right_customer_state:
     1123                return False
     1124            if contract.state in (APPROVED, REJECTED, EXPIRED):
     1125                return False
     1126        return checkPermission('waeup.editContracts', self.context)
    11191127
    11201128    @property
     
    11431151            # Customers are not allowed to remove used contracts
    11441152            contract = self.context.get(id, None)
    1145             if contract is not None and not self.unremovable(contract):
     1153            if contract is not None and self.remove_contract_allowed(contract):
    11461154                del self.context[id]
    11471155                deleted.append(id)
     
    11551163
    11561164
    1157 class ContractAddFormPage(IkobaAddFormPage):
     1165class ContractAddPage(IkobaAddFormPage):
    11581166    """ Page to add an contract
     1167
     1168    This page is for both customers and officers.
    11591169    """
    11601170    grok.context(IContractsContainer)
    11611171    grok.name('addcontract')
    1162     grok.template('contractaddform')
     1172    grok.template('contractaddpage')
    11631173    grok.require('waeup.editContracts')
    11641174    label = _('Add contract')
     
    11671177    form_fields = grok.AutoFields(IContract).omit(
    11681178        'product_object', 'contract_id', 'product_options')
     1179
     1180    @property
     1181    def edit_contracts_allowed(self):
     1182        right_customer_state = self.context.customer.state in getUtility(
     1183            ICustomersUtils).CONMANAGE_CUSTOMER_STATES
     1184        if isCustomer(self.request.principal) and not right_customer_state:
     1185            return False
     1186        return True
     1187
     1188    def update(self):
     1189        if not self.edit_contracts_allowed:
     1190            emit_lock_message(self)
     1191            return
     1192        return super(ContractAddPage, self).update()
    11691193
    11701194    @property
     
    11871211        self.context.writeLogMessage(
    11881212            self,'added: %s %s' % (contype, contract.contract_id))
    1189         self.redirect(self.url(self.context))
     1213        self.redirect(self.url(contract, 'selectproduct'))
    11901214        return
    11911215
     
    11931217    def cancel(self, **data):
    11941218        self.redirect(self.url(self.context))
     1219
     1220
     1221class ContractSelectProductPage(IkobaAddFormPage):
     1222    """ Page to select a contract product
     1223
     1224    This page is for both customers and officers.
     1225    """
     1226    grok.context(IContract)
     1227    grok.name('selectproduct')
     1228    grok.require('waeup.editContracts')
     1229    label = _('Select product')
     1230    pnav = 4
     1231
     1232    form_fields = grok.AutoFields(IContract).select('product_object')
     1233
     1234    def update(self):
     1235        if not self.context.is_editable and self.context.product_options == []:
     1236            emit_lock_message(self)
     1237            return
     1238        return super(ContractSelectProductPage, self).update()
     1239
     1240    @action(_('Save and proceed'), style='primary')
     1241    def save(self, **data):
     1242        msave(self, **data)
     1243        isCustomer = getattr(
     1244            self.request.principal, 'user_type', None) == 'customer'
     1245        if isCustomer:
     1246            self.redirect(self.url(self.context, 'edit'))
     1247        else:
     1248            self.redirect(self.url(self.context, 'manage'))
     1249        return
    11951250
    11961251
     
    12271282    deletion_warning = _('Are you sure?')
    12281283
     1284    def update(self):
     1285        if not self.context.is_editable:
     1286            emit_lock_message(self)
     1287            return
     1288        return super(ContractManageFormPage, self).update()
     1289
    12291290    @property
    12301291    def form_fields(self):
     
    12431304
    12441305class ContractEditFormPage(ContractManageFormPage):
    1245     """ Page to edit a contract
     1306    """ Page to edit a contract by customer only
    12461307    """
    12471308    grok.name('edit')
     
    12511312    def form_fields(self):
    12521313        return grok.AutoFields(self.context.edit_form_fields_interface).omit(
    1253             'contract_id')
    1254 
    1255     def update(self):
    1256         if not self.context.is_editable_by_customer:
    1257             emit_lock_message(self)
    1258             return
    1259         return super(ContractEditFormPage, self).update()
     1314            'contract_id', 'product_object')
    12601315
    12611316    @action(_('Save'), style='primary')
     
    13421397    def render(self):
    13431398        portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
    1344         Id = translate(_('Id'), 'waeup.ikoba', target_language=portal_language)
     1399        #Id = translate(_('Id'), 'waeup.ikoba', target_language=portal_language)
    13451400        Title = translate(_('Title'), 'waeup.ikoba', target_language=portal_language)
    13461401        Type = translate(_('Type'), 'waeup.ikoba', target_language=portal_language)
     
    13531408            tabledata.append(sorted(
    13541409                [value for value in self.context.values()]))
    1355             tableheader.append([(Id, 'contract_id', 2),
     1410            tableheader.append([
     1411                             #(Id, 'contract_id', 2),
    13561412                             (Title, 'title', 6),
    13571413                             (Type, 'translated_class_name', 6),
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser_templates/contractsmanagepage.pt

    r12097 r12337  
    55    <thead>
    66    <tr>
    7       <th>&nbsp;</th>
     7      <th tal:condition="view/edit_contracts_allowed">&nbsp;</th>
    88      <th i18n:translate="">Id</th>
    99      <th i18n:translate="">Title</th>
     
    1414    </thead>
    1515    <tbody>
    16       <tr tal:repeat="cl context/values">
    17          <td>
     16      <tr tal:repeat="contract context/values">
     17         <td tal:condition="view/edit_contracts_allowed">
    1818          <input type="checkbox"
    19                  name="val_id"
    20                  tal:attributes="value cl/__name__"
    21          tal:condition="python: not view.unremovable(cl)" />
     19                 name="val_id"
     20                 tal:attributes="value contract/__name__"
     21           tal:condition="python: view.remove_contract_allowed(contract)" />
    2222        </td>
    2323        <td>
    24           <a tal:attributes="href python: view.url(cl)">
    25           <span tal:content="cl/contract_id">CONID</span></a>
     24          <a tal:attributes="href python: view.url(contract)">
     25          <span tal:content="contract/contract_id">CONID</span></a>
    2626        </td>
    2727        <td>
    28           <span tal:content="cl/title">TITLE</span>
     28          <span tal:content="contract/title">TITLE</span>
    2929        </td>
    3030        <td>
    31           <span tal:content="cl/translated_class_name">CLASSNAME</span>
     31          <span tal:content="contract/translated_class_name">CLASSNAME</span>
    3232        </td>
    3333        <td>
    34           <span tal:content="cl/translated_state">STATE</span>
     34          <span tal:content="contract/translated_state">STATE</span>
    3535        </td>
    3636        <td>
    37           <span tal:content="cl/formatted_transition_date">
     37          <span tal:content="contract/formatted_transition_date">
    3838              LASTTRANSITIONDATE
    3939          </span>
     
    4343  </table>
    4444
    45   <div tal:condition="python: view.availableActions and view.manage_contracts_allowed">
     45  <div tal:condition="python: view.availableActions and view.edit_contracts_allowed">
    4646    <span tal:repeat="action view/actions"
    4747          tal:omit-tag="">
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/contracts.py

    r12336 r12337  
    132132
    133133    @property
    134     def is_editable_by_customer(self):
     134    def is_editable(self):
    135135        try:
    136136            # Customer must be approved
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/export.py

    r12330 r12337  
    214214                      'formatted_transition_date',
    215215                      'translated_class_name',
    216                       'is_editable_by_customer',
     216                      'is_editable',
    217217                      'is_approvable'])))
    218218
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py

    r12336 r12337  
    290290    last_product_id = Attribute(
    291291        'Id of product recently stored with the contract')
    292     is_editable_by_customer = Attribute('Contract editable by customer')
     292    is_editable = Attribute('Contract editable by customer and manager')
    293293    is_approvable = Attribute('Contract approvable by officer')
    294294    translated_class_name = Attribute('Translatable class name')
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/viewlets.py

    r12214 r12337  
    3333    CustomerBaseDisplayFormPage,
    3434    DocumentsManageFormPage, DocumentDisplayFormPage, DocumentManageFormPage,
    35     ContractsManageFormPage, ContractDisplayFormPage,
     35    ContractsFormPage, ContractDisplayFormPage,
    3636    ContractManageFormPage)
    3737
     
    375375    grok.order(2)
    376376    grok.context(IContractsContainer)
    377     grok.view(ContractsManageFormPage)
     377    grok.view(ContractsFormPage)
    378378    grok.require('waeup.viewCustomer')
    379379    icon = 'actionicon_pdf.png'
     
    401401    @property
    402402    def target_url(self):
    403         if not self.context.is_editable_by_customer:
     403        if not self.context.is_editable:
    404404            return ''
    405405        return self.view.url(self.view.context, self.target)
  • main/waeup.ikoba/trunk/src/waeup/ikoba/products/interfaces.py

    r12336 r12337  
    5858
    5959    contract_title = schema.TextLine(
    60         title = _(u'Product Title'),
    61         description = _('Product title if empty'),
     60        title = _(u'Contract Title'),
     61        description = _('Product title is used if empty.'),
    6262        required = False,
    6363        )
Note: See TracChangeset for help on using the changeset viewer.