Exemplo n.º 1
0
 def patch(self):
     """Post a cancellation resolution
     """
     auction = self.request.validated['auction']
     if auction.status in ['complete', 'cancelled', 'unsuccessful']:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update cancellation in current ({}) auction status'.
             format(auction.status))
         self.request.errors.status = 403
         return
     if any([
             i.status != 'active' for i in auction.lots
             if i.id == self.request.context.relatedLot
     ]):
         self.request.errors.add(
             'body', 'data',
             'Can update cancellation only in active lot status')
         self.request.errors.status = 403
         return
     apply_patch(self.request,
                 save=False,
                 src=self.request.context.serialize())
     if self.request.context.relatedLot and self.request.context.status == 'active':
         self.cancel_lot()
     elif self.request.context.status == 'active':
         self.cancel_auction()
     if save_auction(self.request):
         self.LOGGER.info('Updated auction cancellation {}'.format(
             self.request.context.id),
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'auction_cancellation_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     self.request.registry.getAdapter(
         self.context, IAuctionManager).change_auction(self.request)
     auction = self.context
     if self.request.authenticated_role != 'Administrator' and auction.status in [
             'complete', 'unsuccessful', 'cancelled'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update auction in current ({}) status'.format(
                 auction.status))
         self.request.errors.status = 403
         return
     if self.request.authenticated_role == 'chronograph' and not auction.suspended:
         apply_patch(self.request,
                     save=False,
                     src=self.request.validated['auction_src'])
         check_status(self.request)
         save_auction(self.request)
     else:
         apply_patch(self.request,
                     src=self.request.validated['auction_src'])
     self.LOGGER.info('Updated auction {}'.format(auction.id),
                      extra=context_unpack(self.request,
                                           {'MESSAGE_ID': 'auction_patch'}))
     return {'data': auction.serialize(auction.status)}
 def patch(self):
     self.request.registry.getAdapter(self.context, IAuctionManager).change_auction(self.request)
     auction = self.context
     forbidden_to_patch_in_terminal_statuses = (
         self.request.authenticated_role != 'Administrator'
         and auction.status in SWIFTSURE_TERMINAL_STATUSES
     )
     forbidden_to_patch_in_pre_terminal_statuses = (
         self.request.authenticated_role not in ('convoy', 'Administrator')
         and auction.status in SWIFTSURE_PRE_TERMINAL_STATUSES
     )
     if forbidden_to_patch_in_terminal_statuses or forbidden_to_patch_in_pre_terminal_statuses:
         self.request.errors.add(
             'body',
             'data',
             'Can\'t update auction in current ({}) status'.format(auction.status))
         self.request.errors.status = 403
         return
     if self.request.authenticated_role == 'chronograph' and not auction.suspended:
         apply_patch(self.request, save=False, src=self.request.validated['auction_src'])
         check_status(self.request)
         save_auction(self.request)
     else:
         apply_patch(self.request, src=self.request.validated['auction_src'])
     self.LOGGER.info(
         'Updated auction {}'.format(auction.id),
         extra=context_unpack(
             self.request, {'MESSAGE_ID': 'auction_patch'}))
     return {'data': auction.serialize(auction.status)}
 def post(self):
     """Report auction results for lot.
     """
     apply_patch(self.request,
                 save=False,
                 src=self.request.validated['auction_src'])
     auction = self.request.validated['auction']
     if all([
             i.auctionPeriod and i.auctionPeriod.endDate
             for i in auction.lots
             if i.numberOfBids > 1 and i.status == 'active'
     ]):
         cleanup_bids_for_cancelled_lots(auction)
         invalidate_bids_under_threshold(auction)
         if any([i.status == 'active' for i in auction.bids]):
             self.request.content_configurator.start_awarding()
         else:
             auction.status = 'unsuccessful'
     if save_auction(self.request):
         self.LOGGER.info('Report auction results',
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'auction_lot_auction_post'}))
         return {
             'data':
             self.request.validated['auction'].serialize(
                 self.request.validated['auction'].status)
         }
 def collection_post(self):
     auction = self.context.serialize()
     adapter = self.request.registry.getAdapter(self.context,
                                                IAuctionManager)
     merge_auction_results(auction, self.request)
     apply_patch(self.request,
                 save=False,
                 src=self.request.validated['auction_src'])
     remove_draft_bids(self.request)
     auction = self.request.validated['auction']
     invalidate_empty_bids(auction)
     if any([i.status == 'active' for i in auction.bids]):
         self.request.content_configurator.start_awarding()
     else:
         adapter.pendify_auction_status('unsuccessful')
     if save_auction(self.request):
         self.LOGGER.info(
             'Report auction results',
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'auction_auction_post'}))
         return {
             'data':
             self.request.validated['auction'].serialize(
                 self.request.validated['auction'].status)
         }
    def change_contract(self, request, **kwargs):
        context = kwargs['context']

        if request.validated['auction_status'] not in ['active.qualification', 'active.awarded']:
            request.errors.add('body', 'data', 'Can\'t update contract in current ({}) auction status'.format(request.validated['auction_status']))
            request.errors.status = 403
            raise error_handler(request)
        auction = request.validated['auction']
        if any([i.status != 'active' for i in auction.lots if i.id in [a.lotID for a in auction.awards if a.id == request.context.awardID]]):
            request.errors.add('body', 'data', 'Can update contract only in active lot status')
            request.errors.status = 403
            raise error_handler(request)
        data = request.validated['data']

        if data['value']:
            for ro_attr in ('valueAddedTaxIncluded', 'currency'):
                if data['value'][ro_attr] != getattr(context.value, ro_attr):
                    request.errors.add('body', 'data', 'Can\'t update {} for contract value'.format(ro_attr))
                    request.errors.status = 403
                    raise error_handler(request)

            award = [a for a in auction.awards if a.id == request.context.awardID][0]
            if data['value']['amount'] < award.value.amount:
                request.errors.add('body', 'data', 'Value amount should be greater or equal to awarded amount ({})'.format(award.value.amount))
                request.errors.status = 403
                raise error_handler(request)

        if request.context.status != 'active' and 'status' in data and data['status'] == 'active':
            award = [a for a in auction.awards if a.id == request.context.awardID][0]
            stand_still_end = award.complaintPeriod.endDate
            if stand_still_end > get_now():
                request.errors.add('body', 'data', 'Can\'t sign contract before stand-still period end ({})'.format(stand_still_end.isoformat()))
                request.errors.status = 403
                raise error_handler(request)
            pending_complaints = [
                i
                for i in auction.complaints
                if i.status in ['claim', 'answered', 'pending'] and i.relatedLot in [None, award.lotID]
            ]
            pending_awards_complaints = [
                i
                for a in auction.awards
                for i in a.complaints
                if i.status in ['claim', 'answered', 'pending'] and a.lotID == award.lotID
            ]
            if pending_complaints or pending_awards_complaints:
                request.errors.add('body', 'data', 'Can\'t sign contract before reviewing all complaints')
                request.errors.status = 403
                raise error_handler(request)
        contract_status = request.context.status
        apply_patch(request, save=False, src=request.context.serialize())
        if contract_status != request.context.status and (contract_status != 'pending' or request.context.status != 'active'):
            request.errors.add('body', 'data', 'Can\'t update contract status')
            request.errors.status = 403
            raise error_handler(request)
        if request.context.status == 'active' and not request.context.dateSigned:
            request.context.dateSigned = get_now()
        check_auction_status(request)
 def post(self):
     """Report auction results for lot.
     """
     apply_patch(self.request, save=False, src=self.request.validated['auction_src'])
     if all([i.auctionPeriod and i.auctionPeriod.endDate for i in self.request.validated['auction'].lots if i.numberOfBids > 1 and i.status == 'active']):
         cleanup_bids_for_cancelled_lots(self.request.validated['auction'])
         add_next_award(self.request)
     if save_auction(self.request):
         self.LOGGER.info('Report auction results', extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_auction_post'}))
         return {'data': self.request.validated['auction'].serialize(self.request.validated['auction'].status)}
Exemplo n.º 8
0
 def patch(self):
     """Auction Document Update"""  # TODO rm black box
     if not self.validate_document_editing_period('update'):
         return
     apply_patch(self.request,
                 save=False,
                 src=self.request.context.serialize())
     if self.request.authenticated_role != "auction":
         invalidate_bids_data(self.request.auction)
     if save_auction(self.request):
         self.LOGGER.info(
             'Updated auction document {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'auction_document_patch'}))
         return {'data': self.request.context.serialize("view")}
 def collection_post(self):
     auction = self.context.serialize()
     merge_auction_results(auction, self.request)
     apply_patch(self.request, save=False, src=self.request.validated['auction_src'])
     remove_draft_bids(self.request)
     auction = self.request.validated['auction']
     invalidate_empty_bids(auction)
     if any([i.status == 'active' for i in auction.bids]):
         create_awards(self.request)
     else:
         auction.status = 'unsuccessful'
     if save_auction(self.request):
         self.LOGGER.info('Report auction results',
                          extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_auction_post'}))
         return {'data': self.request.validated['auction'].serialize(self.request.validated['auction'].status)}
Exemplo n.º 10
0
 def patch(self):
     """Post an Answer
     """
     auction = self.request.validated['auction']
     if auction.status != 'active.tendering':
         self.request.errors.add(
             'body', 'data',
             'Can\'t update question in current ({}) auction status'.format(
                 auction.status))
         self.request.errors.status = 403
         return
     if any([
             i.status != 'active' for i in auction.lots
             if i.id == self.request.context.relatedItem
     ]):
         self.request.errors.add(
             'body', 'data',
             'Can update question only in active lot status')
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info(
             'Updated auction question {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'auction_question_patch'}))
         return {'data': self.request.context.serialize(auction.status)}
 def change(self):
     if self.validate():
         self._context.modified = apply_patch(
             self._request,
             save=False,
             src=self._request.validated['auction_src'])
         return self._context.modified
Exemplo n.º 12
0
 def patch(self):
     """Auction Award Complaint Document Update"""
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction award complaint document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_complaint_document_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 13
0
 def patch(self):
     """Auction Complaint Document Update"""
     if self.request.authenticated_role != self.context.author:
         self.request.errors.add('url', 'role',
                                 'Can update document only author')
         self.request.errors.status = 403
         return
     if self.request.validated['auction_status'] not in [
             'active.tendering', 'active.auction', 'active.qualification',
             'active.awarded'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) auction status'.format(
                 self.request.validated['auction_status']))
         self.request.errors.status = 403
         return
     if self.request.validated['complaint'].status not in STATUS4ROLE.get(
             self.request.authenticated_role, []):
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) complaint status'.
             format(self.request.validated['complaint'].status))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info(
             'Updated auction complaint document {}'.format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request,
                 {'MESSAGE_ID': 'auction_complaint_document_patch'}))
         return {'data': self.request.context.serialize("view")}
    def patch(self):
        """Update of prolongation
            
            Fields, except on `status`, can be updated only when
            Prolongation has status `draft`.
        """
        new_status = self.request.validated['data'].get('status')

        if new_status == 'applied':
            # this method checks intention of long apply
            managed_prolongation = ProlongationManager(self.request.context)
            try:
                managed_prolongation.apply()
            except Exception as e:
                self.request.errors.add('body', 'data', e.message)
                self.request.errors.status = 403
                return
        if apply_patch(self.request):
            self.LOGGER.info(
                'Updated prolongation {}'.format(
                    self.request.context.id
                ),
                extra=context_unpack(
                    self.request,
                    {'MESSAGE_ID': 'contract_prolongation_patch'}
                    )
                )
            return {'data': self.request.context.serialize()}
Exemplo n.º 15
0
 def patch(self):
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info(
             'Updated lot item {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'lot_item_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Lot Item Update"""
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info(
             'Updated lot item {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'auction_item_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 17
0
 def patch(self):
     """Auction Contract Document Update"""
     if not validate_contract_document(self.request, 'update'):
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction contract document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_contract_document_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Auction Award Document Update"""
     if not self.validate_award_document('update'):
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction award document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_document_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Auction Bid Document Update"""
     if not self.validate_bid_document('update'):
         return
     if self.request.validated['auction_status'] == 'active.tendering':
         self.request.validated['auction'].modified = False
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction bid document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 20
0
 def patch(self):
     """Auction Award Document Update"""
     if self.request.authenticated_role != self.request.context.author:
         self.request.errors.add('url', 'role', 'Can update document only author')
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction award document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_document_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 21
0
 def patch(self):
     """Auction Bid Document Update"""
     if not self.validate_bid_document('update'):
         return
     if self.request.validated['auction_status'] == 'active.tendering':
         self.request.validated['auction'].modified = False
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction bid document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Auction Cancellation Document Update"""
     if self.request.validated['auction_status'] in ['complete', 'cancelled', 'unsuccessful']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction cancellation document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_cancellation_document_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 23
0
 def collection_post(self):
     apply_patch(self.request,
                 save=False,
                 src=self.request.validated['auction_src'])
     auction = self.request.validated['auction']
     invalidate_bids_under_threshold(auction)
     if any([i.status == 'active' for i in auction.bids]):
         self.request.content_configurator.start_awarding()
     else:
         auction.status = 'unsuccessful'
     if save_auction(self.request):
         self.LOGGER.info(
             'Report auction results',
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'auction_auction_post'}))
         return {
             'data':
             self.request.validated['auction'].serialize(
                 self.request.validated['auction'].status)
         }
Exemplo n.º 24
0
    def patch(self):
        """Lot Item Update"""

        if self.request.authenticated_role == 'auction_owner':
            invalidate_bids_data(self.request.auction)

        if apply_patch(self.request, src=self.request.context.serialize()):
            self.LOGGER.info(
                'Updated lot item {}'.format(self.request.context.id),
                extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_item_patch'})
            )
            return {'data': self.request.context.serialize("view")}
Exemplo n.º 25
0
 def patch(self):
     """Update of lot
     """
     auction = self.request.validated['auction']
     if auction.status not in ['active.enquiries']:
         self.request.errors.add('body', 'data', 'Can\'t update lot in current ({}) auction status'.format(auction.status))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info('Updated auction lot {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Post a cancellation resolution
     """
     auction = self.request.validated['auction']
     if auction.status in ['complete', 'cancelled', 'unsuccessful']:
         self.request.errors.add('body', 'data', 'Can\'t update cancellation in current ({}) auction status'.format(auction.status))
         self.request.errors.status = 403
         return
     if any([i.status != 'active' for i in auction.lots if i.id == self.request.context.relatedLot]):
         self.request.errors.add('body', 'data', 'Can update cancellation only in active lot status')
         self.request.errors.status = 403
         return
     apply_patch(self.request, save=False, src=self.request.context.serialize())
     if self.request.context.relatedLot and self.request.context.status == 'active':
         self.cancel_lot()
     elif self.request.context.status == 'active':
         self.cancel_auction()
     if save_auction(self.request):
         self.LOGGER.info('Updated auction cancellation {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_cancellation_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 27
0
 def patch(self):
     """Update of lot
     """
     auction = self.request.validated['auction']
     if auction.status not in ['active.tendering']:
         self.request.errors.add('body', 'data', 'Can\'t update lot in current ({}) auction status'.format(auction.status))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info('Updated auction lot {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_lot_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Auction Document Update"""
     if self.request.authenticated_role != 'auction' and self.request.validated['auction_status'] != 'active.enquiries' or \
        self.request.authenticated_role == 'auction' and self.request.validated['auction_status'] not in ['active.auction', 'active.qualification']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status']))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_document_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 29
0
 def collection_patch(self):
     """Set urls for access to auction.
     """
     if apply_patch(self.request,
                    src=self.request.validated['auction_src']):
         self.LOGGER.info(
             'Updated auction urls',
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'auction_auction_patch'}))
         return {
             'data':
             self.request.validated['auction'].serialize("auction_view")
         }
Exemplo n.º 30
0
 def post(self):
     """Report auction results for lot.
     """
     apply_patch(self.request,
                 save=False,
                 src=self.request.validated['auction_src'])
     if all([
             i.auctionPeriod and i.auctionPeriod.endDate
             for i in self.request.validated['auction'].lots
             if i.numberOfBids > 1 and i.status == 'active'
     ]):
         cleanup_bids_for_cancelled_lots(self.request.validated['auction'])
         add_next_award(self.request)
     if save_auction(self.request):
         self.LOGGER.info('Report auction results',
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'auction_lot_auction_post'}))
         return {
             'data':
             self.request.validated['auction'].serialize(
                 self.request.validated['auction'].status)
         }
Exemplo n.º 31
0
    def patch(self):
        """Auction Document Update"""
        if self.request.authenticated_role != 'auction' and self.request.validated['auction_status'] != 'active.tendering' or \
           self.request.authenticated_role == 'auction' and self.request.validated['auction_status'] not in ['active.auction', 'active.qualification']:
            self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status']))
            self.request.errors.status = 403
            return

        if self.request.authenticated_role == 'auction_owner':
            invalidate_bids_data(self.request.auction)

        if apply_patch(self.request, src=self.request.context.serialize()):
            update_file_content_type(self.request)
            self.LOGGER.info('Updated auction document {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_document_patch'}))
            return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Update of lot
     """
     auction = self.request.validated["auction"]
     if auction.status not in ["active.enquiries"]:
         self.request.errors.add(
             "body", "data", "Can't update lot in current ({}) auction status".format(auction.status)
         )
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info(
             "Updated auction lot {}".format(self.request.context.id),
             extra=context_unpack(self.request, {"MESSAGE_ID": "auction_lot_patch"}),
         )
         return {"data": self.request.context.serialize("view")}
 def patch(self):
     """Post an Answer
     """
     auction = self.request.validated['auction']
     if auction.status != 'active.tendering':
         self.request.errors.add('body', 'data', 'Can\'t update question in current ({}) auction status'.format(auction.status))
         self.request.errors.status = 403
         return
     if any([i.status != 'active' for i in auction.lots if i.id == self.request.context.relatedItem]):
         self.request.errors.add('body', 'data', 'Can update question only in active lot status')
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         self.LOGGER.info('Updated auction question {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_question_patch'}))
         return {'data': self.request.context.serialize(auction.status)}
 def patch(self):
     """Auction Bid Document Update"""
     if self.request.validated['auction_status'] not in [
             'active.tendering', 'active.qualification'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document in current ({}) auction status'.format(
                 self.request.validated['auction_status']))
         self.request.errors.status = 403
         return
     auction = self.request.validated['auction']
     if self.request.validated['auction_status'] == 'active.tendering' and (
             auction.tenderPeriod.startDate
             and get_now() < auction.tenderPeriod.startDate
             or get_now() > auction.tenderPeriod.endDate):
         self.request.errors.add(
             'body', 'data',
             'Document can be updated only during the tendering period: from ({}) to ({}).'
             .format(
                 auction.auctionPeriod.startDate
                 and auction.auctionPeriod.startDate.isoformat(),
                 auction.auctionPeriod.endDate.isoformat()))
         self.request.errors.status = 403
         return
     if self.request.validated[
             'auction_status'] == 'active.qualification' and not [
                 i for i in self.request.validated['auction'].awards
                 if i.status == 'pending'
                 and i.bid_id == self.request.validated['bid_id']
             ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update document because award of bid is not in pending state'
         )
         self.request.errors.status = 403
         return
     if self.request.validated['auction_status'] == 'active.tendering':
         self.request.validated['auction'].modified = False
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction bid document {}'.format(
             self.request.context.id),
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'auction_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Auction Complaint Document Update"""
     if self.request.authenticated_role != self.context.author:
         self.request.errors.add('url', 'role', 'Can update document only author')
         self.request.errors.status = 403
         return
     if self.request.validated['auction_status'] not in ['active.tendering', 'active.auction', 'active.qualification', 'active.awarded']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status']))
         self.request.errors.status = 403
         return
     if self.request.validated['complaint'].status not in STATUS4ROLE.get(self.request.authenticated_role, []):
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) complaint status'.format(self.request.validated['complaint'].status))
         self.request.errors.status = 403
         return
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction complaint document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_complaint_document_patch'}))
         return {'data': self.request.context.serialize("view")}
 def patch(self):
     """Auction Bid Document Update"""
     if self.request.validated['auction_status'] not in ['active.tendering', 'active.qualification']:
         self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status']))
         self.request.errors.status = 403
         return
     auction = self.request.validated['auction']
     if self.request.validated['auction_status'] == 'active.tendering' and (auction.tenderPeriod.startDate and get_now() < auction.tenderPeriod.startDate or get_now() > auction.tenderPeriod.endDate):
         self.request.errors.add('body', 'data', 'Document can be updated only during the tendering period: from ({}) to ({}).'.format(auction.auctionPeriod.startDate and auction.auctionPeriod.startDate.isoformat(), auction.auctionPeriod.endDate.isoformat()))
         self.request.errors.status = 403
         return
     if self.request.validated['auction_status'] == 'active.qualification' and not [i for i in self.request.validated['auction'].awards if i.status == 'pending' and i.bid_id == self.request.validated['bid_id']]:
         self.request.errors.add('body', 'data', 'Can\'t update document because award of bid is not in pending state')
         self.request.errors.status = 403
         return
     if self.request.validated['auction_status'] == 'active.tendering':
         self.request.validated['auction'].modified = False
     if apply_patch(self.request, src=self.request.context.serialize()):
         update_file_content_type(self.request)
         self.LOGGER.info('Updated auction bid document {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_document_patch'}))
         return {'data': self.request.context.serialize("view")}
Exemplo n.º 37
0
    def patch(self):
        """Update of proposal

        Example request to change bid proposal:

        .. sourcecode:: http

            PATCH /auctions/4879d3f8ee2443169b5fbbc9f89fa607/bids/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "value": {
                        "amount": 600
                    }
                }
            }

        And here is the response to be expected:

        .. sourcecode:: http

            HTTP/1.0 200 OK
            Content-Type: application/json

            {
                "data": {
                    "value": {
                        "amount": 600,
                        "currency": "UAH",
                        "valueAddedTaxIncluded": true
                    }
                }
            }

        """

        if self.request.authenticated_role != 'Administrator' and self.request.validated['auction_status'] != 'active.tendering':
            self.request.errors.add('body', 'data', 'Can\'t update bid in current ({}) auction status'.format(self.request.validated['auction_status']))
            self.request.errors.status = 403
            return
        auction = self.request.validated['auction']
        if self.request.authenticated_role != 'Administrator' and (auction.tenderPeriod.startDate and get_now() < auction.tenderPeriod.startDate or get_now() > auction.tenderPeriod.endDate):
            self.request.errors.add('body', 'data', 'Bid can be updated only during the tendering period: from ({}) to ({}).'.format(auction.tenderPeriod.startDate and auction.tenderPeriod.startDate.isoformat(), auction.tenderPeriod.endDate.isoformat()))
            self.request.errors.status = 403
            return
        if self.request.authenticated_role != 'Administrator':
            bid_status_to = self.request.validated['data'].get("status")
            if bid_status_to != self.request.context.status and bid_status_to != "active":
                self.request.errors.add('body', 'bid', 'Can\'t update bid to ({}) status'.format(bid_status_to))
                self.request.errors.status = 403
                return
        value = self.request.validated['data'].get("value") and self.request.validated['data']["value"].get("amount")
        if value and value != self.request.context.get("value", {}).get("amount"):
            self.request.validated['data']['date'] = get_now().isoformat()
        if self.request.context.lotValues:
            lotValues = dict([(i.relatedLot, i.value.amount) for i in self.request.context.lotValues])
            for lotvalue in self.request.validated['data'].get("lotValues", []):
                if lotvalue['relatedLot'] in lotValues and lotvalue.get("value", {}).get("amount") != lotValues[lotvalue['relatedLot']]:
                    lotvalue['date'] = get_now().isoformat()
        self.request.validated['auction'].modified = False
        if apply_patch(self.request, src=self.request.context.serialize()):
            self.LOGGER.info('Updated auction bid {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_bid_patch'}))
            return {'data': self.request.context.serialize("view")}
Exemplo n.º 38
0
    def collection_post(self):
        """Report auction results.

        Report auction results
        ----------------------

        Example request to report auction results:

        .. sourcecode:: http

            POST /auctions/4879d3f8ee2443169b5fbbc9f89fa607/auction HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "dateModified": "2014-10-27T08:06:58.158Z",
                    "bids": [
                        {
                            "value": {
                                "amount": 400,
                                "currency": "UAH"
                            }
                        },
                        {
                            "value": {
                                "amount": 385,
                                "currency": "UAH"
                            }
                        }
                    ]
                }
            }

        This is what one should expect in response:

        .. sourcecode:: http

            HTTP/1.1 200 OK
            Content-Type: application/json

            {
                "data": {
                    "dateModified": "2014-10-27T08:06:58.158Z",
                    "bids": [
                        {
                            "value": {
                                "amount": 400,
                                "currency": "UAH",
                                "valueAddedTaxIncluded": true
                            }
                        },
                        {
                            "value": {
                                "amount": 385,
                                "currency": "UAH",
                                "valueAddedTaxIncluded": true
                            }
                        }
                    ],
                    "minimalStep":{
                        "amount": 35,
                        "currency": "UAH"
                    },
                    "tenderPeriod":{
                        "startDate": "2014-11-04T08:00:00"
                    }
                }
            }

        """
        apply_patch(self.request,
                    save=False,
                    src=self.request.validated['auction_src'])
        if all([
                i.auctionPeriod and i.auctionPeriod.endDate
                for i in self.request.validated['auction'].lots
                if i.numberOfBids > 1 and i.status == 'active'
        ]):
            add_next_award(self.request)
        if save_auction(self.request):
            self.LOGGER.info(
                'Report auction results',
                extra=context_unpack(self.request,
                                     {'MESSAGE_ID': 'auction_auction_post'}))
            return {
                'data':
                self.request.validated['auction'].serialize(
                    self.request.validated['auction'].status)
            }
Exemplo n.º 39
0
 def patch(self):
     """Post a complaint resolution
     """
     auction = self.request.validated['auction']
     if auction.status not in [
             'active.tendering', 'active.auction', 'active.qualification',
             'active.awarded'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update complaint in current ({}) auction status'.
             format(auction.status))
         self.request.errors.status = 403
         return
     if self.context.status not in [
             'draft', 'claim', 'answered', 'pending'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update complaint in current ({}) status'.format(
                 self.context.status))
         self.request.errors.status = 403
         return
     data = self.request.validated['data']
     # complaint_owner
     if self.request.authenticated_role == 'complaint_owner' and self.context.status in [
             'draft', 'claim', 'answered', 'pending'
     ] and data.get('status', self.context.status) == 'cancelled':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateCanceled = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and auction.status in [
             'active.tendering'
     ] and self.context.status == 'draft' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and auction.status in [
             'active.tendering'
     ] and self.context.status == 'draft' and data.get(
             'status', self.context.status) == 'claim':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateSubmitted = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get(
             'satisfied', self.context.satisfied) is True and data.get(
                 'status', self.context.status) == 'resolved':
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get(
             'satisfied', self.context.satisfied) is False and data.get(
                 'status', self.context.status) == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.type = 'complaint'
         self.context.dateEscalated = get_now()
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get(
             'resolution', self.context.resolution) and data.get(
                 'resolutionType',
                 self.context.resolutionType) and data.get(
                     'status', self.context.status) == 'answered':
         if len(data.get('resolution', self.context.resolution)) < 20:
             self.request.errors.add(
                 'body', 'data',
                 'Can\'t update complaint: resolution too short')
             self.request.errors.status = 403
             return
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateAnswered = get_now()
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
     # reviewers
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get(
             'status',
             self.context.status) in ['resolved', 'invalid', 'declined']:
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateDecision = get_now()
     else:
         self.request.errors.add('body', 'data', 'Can\'t update complaint')
         self.request.errors.status = 403
         return
     if self.context.tendererAction and not self.context.tendererActionDate:
         self.context.tendererActionDate = get_now()
     if self.context.status not in [
             'draft', 'claim', 'answered', 'pending'
     ] and auction.status in ['active.qualification', 'active.awarded']:
         check_auction_status(self.request)
     if save_auction(self.request):
         self.LOGGER.info(
             'Updated auction complaint {}'.format(self.context.id),
             extra=context_unpack(
                 self.request, {'MESSAGE_ID': 'auction_complaint_patch'}))
         return {'data': self.context.serialize("view")}
    def patch(self):
        """Update of award

        Example request to change the award:

        .. sourcecode:: http

            PATCH /auctions/4879d3f8ee2443169b5fbbc9f89fa607/awards/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "value": {
                        "amount": 600
                    }
                }
            }

        And here is the response to be expected:

        .. sourcecode:: http

            HTTP/1.0 200 OK
            Content-Type: application/json

            {
                "data": {
                    "id": "4879d3f8ee2443169b5fbbc9f89fa607",
                    "date": "2014-10-28T11:44:17.947Z",
                    "status": "active",
                    "suppliers": [
                        {
                            "id": {
                                "name": "Державне управління справами",
                                "scheme": "https://ns.openprocurement.org/ua/edrpou",
                                "uid": "00037256",
                                "uri": "http://www.dus.gov.ua/"
                            },
                            "address": {
                                "countryName": "Україна",
                                "postalCode": "01220",
                                "region": "м. Київ",
                                "locality": "м. Київ",
                                "streetAddress": "вул. Банкова, 11, корпус 1"
                            }
                        }
                    ],
                    "value": {
                        "amount": 600,
                        "currency": "UAH",
                        "valueAddedTaxIncluded": true
                    }
                }
            }

        """
        auction = self.request.validated['auction']
        if auction.status not in ['active.qualification', 'active.awarded']:
            self.request.errors.add('body', 'data', 'Can\'t update award in current ({}) auction status'.format(auction.status))
            self.request.errors.status = 403
            return
        award = self.request.context
        if any([i.status != 'active' for i in auction.lots if i.id == award.lotID]):
            self.request.errors.add('body', 'data', 'Can update award only in active lot status')
            self.request.errors.status = 403
            return
        award_status = award.status
        apply_patch(self.request, save=False, src=self.request.context.serialize())
        if award_status == 'pending' and award.status == 'active':
            award.complaintPeriod.endDate = calculate_business_date(get_now(), STAND_STILL_TIME, auction, True)
            auction.contracts.append(type(auction).contracts.model_class({
                'awardID': award.id,
                'suppliers': award.suppliers,
                'value': award.value,
                'date': get_now(),
                'items': [i for i in auction.items if i.relatedLot == award.lotID ],
                'contractID': '{}-{}{}'.format(auction.auctionID, self.server_id, len(auction.contracts) + 1) }))
            add_next_award(self.request)
        elif award_status == 'active' and award.status == 'cancelled':
            now = get_now()
            if award.complaintPeriod.endDate > now:
                award.complaintPeriod.endDate = now
            for j in award.complaints:
                if j.status not in ['invalid', 'resolved', 'declined']:
                    j.status = 'cancelled'
                    j.cancellationReason = 'cancelled'
                    j.dateCanceled = now
            for i in auction.contracts:
                if i.awardID == award.id:
                    i.status = 'cancelled'
            add_next_award(self.request)
        elif award_status == 'pending' and award.status == 'unsuccessful':
            award.complaintPeriod.endDate = calculate_business_date(get_now(), STAND_STILL_TIME, auction, True)
            add_next_award(self.request)
        elif award_status == 'unsuccessful' and award.status == 'cancelled' and any([i.status in ['claim', 'answered', 'pending', 'resolved'] for i in award.complaints]):
            if auction.status == 'active.awarded':
                auction.status = 'active.qualification'
                auction.awardPeriod.endDate = None
            now = get_now()
            award.complaintPeriod.endDate = now
            cancelled_awards = []
            for i in auction.awards[auction.awards.index(award):]:
                if i.lotID != award.lotID:
                    continue
                i.complaintPeriod.endDate = now
                i.status = 'cancelled'
                for j in i.complaints:
                    if j.status not in ['invalid', 'resolved', 'declined']:
                        j.status = 'cancelled'
                        j.cancellationReason = 'cancelled'
                        j.dateCanceled = now
                cancelled_awards.append(i.id)
            for i in auction.contracts:
                if i.awardID in cancelled_awards:
                    i.status = 'cancelled'
            add_next_award(self.request)
        elif self.request.authenticated_role != 'Administrator' and not(award_status == 'pending' and award.status == 'pending'):
            self.request.errors.add('body', 'data', 'Can\'t update award in current ({}) status'.format(award_status))
            self.request.errors.status = 403
            return
        if save_auction(self.request):
            self.LOGGER.info('Updated auction award {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_patch'}))
            return {'data': award.serialize("view")}
Exemplo n.º 41
0
    def patch(self):
        """Auction Edit (partial)

        For example here is how procuring entity can change number of items to be procured and total Value of a auction:

        .. sourcecode:: http

            PATCH /auctions/4879d3f8ee2443169b5fbbc9f89fa607 HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "value": {
                        "amount": 600
                    },
                    "itemsToBeProcured": [
                        {
                            "quantity": 6
                        }
                    ]
                }
            }

        And here is the response to be expected:

        .. sourcecode:: http

            HTTP/1.0 200 OK
            Content-Type: application/json

            {
                "data": {
                    "id": "4879d3f8ee2443169b5fbbc9f89fa607",
                    "auctionID": "UA-64e93250be76435397e8c992ed4214d1",
                    "dateModified": "2014-10-27T08:12:34.956Z",
                    "value": {
                        "amount": 600
                    },
                    "itemsToBeProcured": [
                        {
                            "quantity": 6
                        }
                    ]
                }
            }

        """
        auction = self.context
        if self.request.authenticated_role != 'Administrator' and auction.status in ['complete', 'unsuccessful', 'cancelled']:
            self.request.errors.add('body', 'data', 'Can\'t update auction in current ({}) status'.format(auction.status))
            self.request.errors.status = 403
            return
        if self.request.authenticated_role == 'chronograph' and not auction.suspended:
            apply_patch(self.request, save=False, src=self.request.validated['auction_src'])
            check_status(self.request)
            save_auction(self.request)
        else:
            apply_patch(self.request, src=self.request.validated['auction_src'])
        self.LOGGER.info('Updated auction {}'.format(auction.id),
                    extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_patch'}))
        return {'data': auction.serialize(auction.status)}
 def patch(self):
     """Post a complaint resolution for award
     """
     auction = self.request.validated['auction']
     if auction.status not in ['active.qualification', 'active.awarded']:
         self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) auction status'.format(auction.status))
         self.request.errors.status = 403
         return
     if any([i.status != 'active' for i in auction.lots if i.id == self.request.validated['award'].lotID]):
         self.request.errors.add('body', 'data', 'Can update complaint only in active lot status')
         self.request.errors.status = 403
         return
     if self.context.status not in ['draft', 'claim', 'answered', 'pending']:
         self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) status'.format(self.context.status))
         self.request.errors.status = 403
         return
     data = self.request.validated['data']
     complaintPeriod = self.request.validated['award'].complaintPeriod
     is_complaintPeriod = complaintPeriod.startDate < get_now() and complaintPeriod.endDate > get_now() if complaintPeriod.endDate else complaintPeriod.startDate < get_now()
     # complaint_owner
     if self.request.authenticated_role == 'complaint_owner' and self.context.status in ['draft', 'claim', 'answered', 'pending'] and data.get('status', self.context.status) == 'cancelled':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateCanceled = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and is_complaintPeriod and self.context.status == 'draft' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and is_complaintPeriod and self.context.status == 'draft' and data.get('status', self.context.status) == 'claim':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateSubmitted = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is True and data.get('status', self.context.status) == 'resolved':
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is False and data.get('status', self.context.status) == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.type = 'complaint'
         self.context.dateEscalated = get_now()
     # auction_owner
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('resolution', self.context.resolution) and len(data.get('resolution', self.context.resolution or "")) >= 20 and data.get('resolutionType', self.context.resolutionType) and data.get('status', self.context.status) == 'answered':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateAnswered = get_now()
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
     # reviewers
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) in ['resolved', 'invalid', 'declined']:
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateDecision = get_now()
     else:
         self.request.errors.add('body', 'data', 'Can\'t update complaint')
         self.request.errors.status = 403
         return
     if self.context.tendererAction and not self.context.tendererActionDate:
         self.context.tendererActionDate = get_now()
     if self.context.status not in ['draft', 'claim', 'answered', 'pending'] and auction.status in ['active.qualification', 'active.awarded']:
         check_auction_status(self.request)
     if save_auction(self.request):
         self.LOGGER.info('Updated auction award complaint {}'.format(self.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_complaint_patch'}))
         return {'data': self.context.serialize("view")}
 def patch(self):
     """Post a complaint resolution
     """
     auction = self.request.validated['auction']
     if auction.status not in ['active.enquiries', 'active.tendering', 'active.auction', 'active.qualification', 'active.awarded']:
         self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) auction status'.format(auction.status))
         self.request.errors.status = 403
         return
     if self.context.status not in ['draft', 'claim', 'answered', 'pending']:
         self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) status'.format(self.context.status))
         self.request.errors.status = 403
         return
     data = self.request.validated['data']
     # complaint_owner
     if self.request.authenticated_role == 'complaint_owner' and self.context.status in ['draft', 'claim', 'answered', 'pending'] and data.get('status', self.context.status) == 'cancelled':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateCanceled = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and auction.status in ['active.enquiries', 'active.tendering'] and self.context.status == 'draft' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and auction.status in ['active.enquiries', 'active.tendering'] and self.context.status == 'draft' and data.get('status', self.context.status) == 'claim':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateSubmitted = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is True and data.get('status', self.context.status) == 'resolved':
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is False and data.get('status', self.context.status) == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.type = 'complaint'
         self.context.dateEscalated = get_now()
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('resolution', self.context.resolution) and data.get('resolutionType', self.context.resolutionType) and data.get('status', self.context.status) == 'answered':
         if len(data.get('resolution', self.context.resolution)) < 20:
             self.request.errors.add('body', 'data', 'Can\'t update complaint: resolution too short')
             self.request.errors.status = 403
             return
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateAnswered = get_now()
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
     # reviewers
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) in ['resolved', 'invalid', 'declined']:
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateDecision = get_now()
     else:
         self.request.errors.add('body', 'data', 'Can\'t update complaint')
         self.request.errors.status = 403
         return
     if self.context.tendererAction and not self.context.tendererActionDate:
         self.context.tendererActionDate = get_now()
     if self.context.status not in ['draft', 'claim', 'answered', 'pending'] and auction.status in ['active.qualification', 'active.awarded']:
         check_auction_status(self.request)
     if save_auction(self.request):
         self.LOGGER.info('Updated auction complaint {}'.format(self.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_complaint_patch'}))
         return {'data': self.context.serialize("view")}
    def patch(self):
        """Auction Edit (partial)

        For example here is how procuring entity can change number of items to be procured and total Value of a auction:

        .. sourcecode:: http

            PATCH /auctions/4879d3f8ee2443169b5fbbc9f89fa607 HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "value": {
                        "amount": 600
                    },
                    "itemsToBeProcured": [
                        {
                            "quantity": 6
                        }
                    ]
                }
            }

        And here is the response to be expected:

        .. sourcecode:: http

            HTTP/1.0 200 OK
            Content-Type: application/json

            {
                "data": {
                    "id": "4879d3f8ee2443169b5fbbc9f89fa607",
                    "auctionID": "UA-64e93250be76435397e8c992ed4214d1",
                    "dateModified": "2014-10-27T08:12:34.956Z",
                    "value": {
                        "amount": 600
                    },
                    "itemsToBeProcured": [
                        {
                            "quantity": 6
                        }
                    ]
                }
            }

        """
        auction = self.context
        if self.request.authenticated_role != 'Administrator' and auction.status in ['complete', 'unsuccessful', 'cancelled']:
            self.request.errors.add('body', 'data', 'Can\'t update auction in current ({}) status'.format(auction.status))
            self.request.errors.status = 403
            return
        if self.request.authenticated_role == 'chronograph':
            apply_patch(self.request, save=False, src=self.request.validated['auction_src'])
            check_status(self.request)
            save_auction(self.request)
        else:
            apply_patch(self.request, src=self.request.validated['auction_src'])
        self.LOGGER.info('Updated auction {}'.format(auction.id),
                    extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_patch'}))
        return {'data': auction.serialize(auction.status)}
 def collection_patch(self):
     """Set urls for access to auction.
     """
     if apply_patch(self.request, src=self.request.validated['auction_src']):
         self.LOGGER.info('Updated auction urls', extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_auction_patch'}))
         return {'data': self.request.validated['auction'].serialize("auction_view")}
    def collection_post(self):
        """Report auction results.

        Report auction results
        ----------------------

        Example request to report auction results:

        .. sourcecode:: http

            POST /auctions/4879d3f8ee2443169b5fbbc9f89fa607/auction HTTP/1.1
            Host: example.com
            Accept: application/json

            {
                "data": {
                    "dateModified": "2014-10-27T08:06:58.158Z",
                    "bids": [
                        {
                            "value": {
                                "amount": 400,
                                "currency": "UAH"
                            }
                        },
                        {
                            "value": {
                                "amount": 385,
                                "currency": "UAH"
                            }
                        }
                    ]
                }
            }

        This is what one should expect in response:

        .. sourcecode:: http

            HTTP/1.1 200 OK
            Content-Type: application/json

            {
                "data": {
                    "dateModified": "2014-10-27T08:06:58.158Z",
                    "bids": [
                        {
                            "value": {
                                "amount": 400,
                                "currency": "UAH",
                                "valueAddedTaxIncluded": true
                            }
                        },
                        {
                            "value": {
                                "amount": 385,
                                "currency": "UAH",
                                "valueAddedTaxIncluded": true
                            }
                        }
                    ],
                    "minimalStep":{
                        "amount": 35,
                        "currency": "UAH"
                    },
                    "tenderPeriod":{
                        "startDate": "2014-11-04T08:00:00"
                    }
                }
            }

        """
        apply_patch(self.request, save=False, src=self.request.validated['auction_src'])
        if all([i.auctionPeriod and i.auctionPeriod.endDate for i in self.request.validated['auction'].lots if i.numberOfBids > 1 and i.status == 'active']):
            add_next_award(self.request)
        if save_auction(self.request):
            self.LOGGER.info('Report auction results', extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_auction_post'}))
            return {'data': self.request.validated['auction'].serialize(self.request.validated['auction'].status)}
 def patch(self):
     """Post a complaint resolution for award
     """
     auction = self.request.validated['auction']
     if auction.status not in ['active.qualification', 'active.awarded']:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update complaint in current ({}) auction status'.
             format(auction.status))
         self.request.errors.status = 403
         return
     if any([
             i.status != 'active' for i in auction.lots
             if i.id == self.request.validated['award'].lotID
     ]):
         self.request.errors.add(
             'body', 'data',
             'Can update complaint only in active lot status')
         self.request.errors.status = 403
         return
     if self.context.status not in [
             'draft', 'claim', 'answered', 'pending'
     ]:
         self.request.errors.add(
             'body', 'data',
             'Can\'t update complaint in current ({}) status'.format(
                 self.context.status))
         self.request.errors.status = 403
         return
     data = self.request.validated['data']
     complaintPeriod = self.request.validated['award'].complaintPeriod
     is_complaintPeriod = complaintPeriod.startDate < get_now(
     ) and complaintPeriod.endDate > get_now(
     ) if complaintPeriod.endDate else complaintPeriod.startDate < get_now(
     )
     # complaint_owner
     if self.request.authenticated_role == 'complaint_owner' and self.context.status in [
             'draft', 'claim', 'answered', 'pending'
     ] and data.get('status', self.context.status) == 'cancelled':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateCanceled = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and is_complaintPeriod and self.context.status == 'draft' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and is_complaintPeriod and self.context.status == 'draft' and data.get(
             'status', self.context.status) == 'claim':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateSubmitted = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get(
             'satisfied', self.context.satisfied) is True and data.get(
                 'status', self.context.status) == 'resolved':
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get(
             'satisfied', self.context.satisfied) is False and data.get(
                 'status', self.context.status) == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.type = 'complaint'
         self.context.dateEscalated = get_now()
     # auction_owner
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get(
             'resolution', self.context.resolution) and len(
                 data.get('resolution', self.context.resolution
                          or "")) >= 20 and data.get(
                              'resolutionType',
                              self.context.resolutionType) and data.get(
                                  'status',
                                  self.context.status) == 'answered':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateAnswered = get_now()
     elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'pending':
         apply_patch(self.request, save=False, src=self.context.serialize())
     # reviewers
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get(
             'status', self.context.status) == self.context.status:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get(
             'status',
             self.context.status) in ['resolved', 'invalid', 'declined']:
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateDecision = get_now()
     else:
         self.request.errors.add('body', 'data', 'Can\'t update complaint')
         self.request.errors.status = 403
         return
     if self.context.tendererAction and not self.context.tendererActionDate:
         self.context.tendererActionDate = get_now()
     if self.context.status not in [
             'draft', 'claim', 'answered', 'pending'
     ] and auction.status in ['active.qualification', 'active.awarded']:
         check_auction_status(self.request)
     if save_auction(self.request):
         self.LOGGER.info(
             'Updated auction award complaint {}'.format(self.context.id),
             extra=context_unpack(
                 self.request,
                 {'MESSAGE_ID': 'auction_award_complaint_patch'}))
         return {'data': self.context.serialize("view")}
    def patch(self):
        """Update of contract
        """
        if self.request.validated['auction_status'] not in ['active.qualification', 'active.awarded']:
            self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) auction status'.format(self.request.validated['auction_status']))
            self.request.errors.status = 403
            return
        auction = self.request.validated['auction']
        if any([i.status != 'active' for i in auction.lots if i.id in [a.lotID for a in auction.awards if a.id == self.request.context.awardID]]):
            self.request.errors.add('body', 'data', 'Can update contract only in active lot status')
            self.request.errors.status = 403
            return
        data = self.request.validated['data']

        if data['value']:
            for ro_attr in ('valueAddedTaxIncluded', 'currency'):
                if data['value'][ro_attr] != getattr(self.context.value, ro_attr):
                    self.request.errors.add('body', 'data', 'Can\'t update {} for contract value'.format(ro_attr))
                    self.request.errors.status = 403
                    return

            award = [a for a in auction.awards if a.id == self.request.context.awardID][0]
            if data['value']['amount'] < award.value.amount:
                self.request.errors.add('body', 'data', 'Value amount should be greater or equal to awarded amount ({})'.format(award.value.amount))
                self.request.errors.status = 403
                return

        if self.request.context.status != 'active' and 'status' in data and data['status'] == 'active':
            award = [a for a in auction.awards if a.id == self.request.context.awardID][0]
            stand_still_end = award.complaintPeriod.endDate
            if stand_still_end > get_now():
                self.request.errors.add('body', 'data', 'Can\'t sign contract before stand-still period end ({})'.format(stand_still_end.isoformat()))
                self.request.errors.status = 403
                return
            pending_complaints = [
                i
                for i in auction.complaints
                if i.status in ['claim', 'answered', 'pending'] and i.relatedLot in [None, award.lotID]
            ]
            pending_awards_complaints = [
                i
                for a in auction.awards
                for i in a.complaints
                if i.status in ['claim', 'answered', 'pending'] and a.lotID == award.lotID
            ]
            if pending_complaints or pending_awards_complaints:
                self.request.errors.add('body', 'data', 'Can\'t sign contract before reviewing all complaints')
                self.request.errors.status = 403
                return
        contract_status = self.request.context.status
        apply_patch(self.request, save=False, src=self.request.context.serialize())
        if contract_status != self.request.context.status and (contract_status != 'pending' or self.request.context.status != 'active'):
            self.request.errors.add('body', 'data', 'Can\'t update contract status')
            self.request.errors.status = 403
            return
        if self.request.context.status == 'active' and not self.request.context.dateSigned:
            self.request.context.dateSigned = get_now()
        check_auction_status(self.request)
        if save_auction(self.request):
            self.LOGGER.info('Updated auction contract {}'.format(self.request.context.id),
                        extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_contract_patch'}))
            return {'data': self.request.context.serialize()}