def collection_post(self):
     """Post a complaint
     """
     tender = self.context
     complaint = self.request.validated['complaint']
     if complaint.status == 'claim':
         validate_submit_claim_time(self.request)
     elif complaint.status == 'pending':
         validate_submit_complaint_time(self.request)
         complaint.dateSubmitted = get_now()
         complaint.type = 'complaint'
     else:
         complaint.status = 'draft'
     complaint.complaintID = '{}.{}{}'.format(tender.tenderID, self.server_id, self.complaints_len(tender) + 1)
     set_ownership(complaint, self.request)
     tender.complaints.append(complaint)
     if save_tender(self.request):
         self.LOGGER.info('Created tender complaint {}'.format(complaint.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_complaint_create'}, {'complaint_id': complaint.id}))
         self.request.response.status = 201
         self.request.response.headers['Location'] = self.request.route_url('{}:Tender Complaints'.format(tender.procurementMethodType), tender_id=tender.id, complaint_id=complaint.id)
         return {
             'data': complaint.serialize(tender.status),
             'access': {
                 'token': complaint.owner_token
             }
         }
 def post(self):
     """Report auction results for lot.
     """
     apply_patch(self.request, save=False, src=self.request.validated['tender_src'])
     if all([i.auctionPeriod and i.auctionPeriod.endDate for i in self.request.validated['tender'].lots if i.numberOfBids > 1 and i.status == 'active']):
         add_next_award(self.request)
     if save_tender(self.request):
         self.LOGGER.info('Report auction results', extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_auction_post'}))
         return {'data': self.request.validated['tender'].serialize(self.request.validated['tender'].status)}
 def delete(self):
     """Lot deleting
     """
     lot = self.request.context
     res = lot.serialize("view")
     tender = self.request.validated['tender']
     tender.lots.remove(lot)
     if self.request.authenticated_role == 'tender_owner':
         tender.invalidate_bids_data()
     if save_tender(self.request):
         self.LOGGER.info('Deleted tender lot {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_delete'}))
         return {'data': res}
    def patch(self):
        tender = self.request.validated['tender']

        set_ownership(tender)
        if save_tender(self.request):
            self.LOGGER.info('Generate Tender stage2 credentials {}'.format(tender.id),
                             extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_patch'}))
            return {
                'data': tender.serialize("view"),
                'access': {
                    'token': tender.owner_token
                }
            }
示例#5
0
 def put(self):
     """Tender Bid Document Update"""
     document = upload_file(self.request)
     self.request.validated['bid'].documents.append(document)
     if self.request.validated['tender_status'] == 'active.tendering':
         self.request.validated['tender'].modified = False
     if save_tender(self.request):
         self.LOGGER.info('Updated tender bid document {}'.format(
             self.request.context.id),
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'tender_bid_document_put'}))
         return {'data': document.serialize("view")}
 def collection_post(self):
     """Tender Award Complaint Document Upload
     """
     document = upload_file(self.request)
     document.author = self.request.authenticated_role
     self.context.documents.append(document)
     if save_tender(self.request):
         self.LOGGER.info('Created tender award complaint document {}'.format(document.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_award_complaint_document_create'}, {'document_id': document.id}))
         self.request.response.status = 201
         document_route = self.request.matched_route.name.replace("collection_", "")
         self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={})
         return {'data': document.serialize("view")}
示例#7
0
 def collection_post(self):
     """Add a lot
     """
     tender = self.request.validated['tender']
     lot = self.request.validated['lot']
     lot.date = get_now()
     tender.lots.append(lot)
     if save_tender(self.request):
         self.LOGGER.info('Created tender lot {}'.format(lot.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_lot_create'}, {'lot_id': lot.id}))
         self.request.response.status = 201
         self.request.response.headers['Location'] = self.request.route_url('{}:Tender Lots'.format(tender.procurementMethodType), tender_id=tender.id, lot_id=lot.id)
         return {'data': lot.serialize("view")}
示例#8
0
 def delete(self):
     """Lot deleting
     """
     tender = self.request.validated["tender"]
     lot = self.request.context
     res = lot.serialize("view")
     tender.lots.remove(lot)
     if save_tender(self.request):
         self.LOGGER.info(
             "Deleted tender lot {}".format(self.request.context.id),
             extra=context_unpack(self.request, {"MESSAGE_ID": "tender_lot_delete"}),
         )
         return {"data": res}
示例#9
0
 def patch(self):
     tender = self.context
     if self.request.authenticated_role == "chronograph":
         apply_patch(self.request,
                     save=False,
                     src=self.request.validated["tender_src"])
         check_status(self.request)
         save_tender(self.request)
     else:
         new_status = self.request.validated["data"].get("status", "")
         data = self.request.validated["data"]
         if tender.status == "draft" and new_status == "draft.publishing" and not tender.noticePublicationDate:
             now = get_now()
             self.request.validated["data"][
                 "noticePublicationDate"] = now.isoformat()
             self.request.validated["data"]["tenderPeriod"][
                 "startDate"] = now.isoformat()
         apply_patch(self.request, src=self.request.validated["tender_src"])
     self.LOGGER.info("Updated tender {}".format(tender.id),
                      extra=context_unpack(self.request,
                                           {"MESSAGE_ID": "tender_patch"}))
     return {"data": tender.serialize(tender.status)}
示例#10
0
 def patch(self):
     """ Update of agreement """
     apply_patch(self.request,
                 save=False,
                 src=self.request.context.serialize())
     check_tender_status(self.request)
     if save_tender(self.request):
         self.LOGGER.info(
             "Updated tender agreement {}".format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {"MESSAGE_ID": "tender_agreement_patch"}),
         )
         return {"data": self.request.context.serialize()}
示例#11
0
    def patch(self):
        requirement_response = self.request.context
        context_name = self.request.context["__parent__"].__class__.__name__.lower()
        apply_patch(self.request, save=False, src=requirement_response.serialize())

        self.pre_save()
        if save_tender(self.request):
            self.LOGGER.info(
                "Updated {} requirement response {}".format(context_name, requirement_response.id),
                extra=context_unpack(self.request, {"MESSAGE_ID": "{}_requirement_response_patch".format(context_name)}),
            )
            return {"data": requirement_response.serialize("view")}
        return
示例#12
0
 def put(self):
     """Tender Award Complaint Document Update"""
     document = upload_file(self.request)
     document.author = self.request.authenticated_role
     self.request.validated['complaint'].documents.append(document)
     if save_tender(self.request):
         self.LOGGER.info(
             'Updated tender award complaint document {}'.format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request,
                 {'MESSAGE_ID': 'tender_award_complaint_document_put'}))
         return {'data': document.serialize("view")}
示例#13
0
 def put(self):
     """Tender Award Document Update"""
     if not self.validate_award_document('update'):
         return
     document = upload_file(self.request)
     self.request.validated['award'].documents.append(document)
     if save_tender(self.request):
         self.LOGGER.info('Updated tender award document {}'.format(
             self.request.context.id),
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'tender_award_document_put'}))
         return {'data': document.serialize("view")}
    def post(self):
        complaint = self.request.context
        tender = self.request.validated['tender']
        award_id = self.request.validated['award_id']
        location = self.request.route_path('{}:Tender Award Complaints'.format(
            tender['procurementMethodType']), tender_id=tender.id, award_id=award_id, complaint_id=complaint.id)
        location = location[len(ROUTE_PREFIX):]  # strips /api/<version>

        if change_ownership(self.request, location) and save_tender(self.request):
            self.LOGGER.info('Updated award {} complaint {} ownership of tender {}'.format(complaint.id, award_id, tender.id),
                             extra=context_unpack(self.request, {'MESSAGE_ID': 'award_complaint_ownership_update'}, {'complaint_id': complaint.id, 'award_id': award_id, 'tender_id': tender.id}))

            return {'data': complaint.serialize('view')}
示例#15
0
    def delete(self):
        rr = self.request.context
        context_name = rr["__parent__"].__class__.__name__.lower()
        res = rr.serialize("view")
        self.request.validated[context_name].requirementResponses.remove(rr)

        self.pre_save()
        if save_tender(self.request):
            self.LOGGER.info(
                "Deleted {} requirement response {}".format(context_name, self.request.context.id),
                extra=context_unpack(self.request, {"MESSAGE_ID": "{}_requirement_response_delete".format(context_name)}),
            )
            return {"data": res}
示例#16
0
 def put(self):
     """Tender Cancellation Document Update"""
     document = upload_file(self.request)
     self.request.validated["cancellation"].documents.append(document)
     if save_tender(self.request):
         self.LOGGER.info(
             "Updated tender cancellation document {}".format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request,
                 {"MESSAGE_ID": "tender_cancellation_document_put"}),
         )
         return {"data": document.serialize("view")}
示例#17
0
    def patch(self):
        requirement = self.request.context
        apply_patch(self.request, save=False, src=requirement.serialize())
        tender = self.request.validated["tender"]

        if self.request.authenticated_role == "tender_owner" and hasattr(tender, "invalidate_bids_data"):
            tender.invalidate_bids_data()

        if save_tender(self.request):
            self.LOGGER.info(
                "Updated  {}".format(requirement.id),
                extra=context_unpack(self.request, {"MESSAGE_ID": "requirement_group_requirement_patch"}),
            )
            return {"data": requirement.serialize("view")}
示例#18
0
 def put(self):
     """Tender Complaint Document Update"""
     document = upload_file(self.request)
     document.author = self.request.authenticated_role
     self.request.validated["complaint"].documents.append(document)
     if save_tender(self.request):
         self.LOGGER.info(
             "Updated tender complaint document {}".format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request,
                 {"MESSAGE_ID": "tender_complaint_document_put"}),
         )
         return {"data": document.serialize("view")}
示例#19
0
 def put(self):
     """Tender Bid Document Update"""
     document = upload_file(self.request)
     getattr(self.request.validated["bid"], self.container).append(document)
     if self.request.validated["tender_status"] == "active.tendering":
         self.request.validated["tender"].modified = False
     if save_tender(self.request):
         self.LOGGER.info(
             "Updated tender bid document {}".format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request, {"MESSAGE_ID": "tender_bid_document_put"}),
         )
         return {"data": document.serialize("view")}
示例#20
0
    def patch(self):
        cancellation = self.request.context
        prev_status = cancellation.status
        apply_patch(self.request, save=False, src=cancellation.serialize())

        if cancellation.status == "active" and prev_status != "active":
            self.cancel_tender_lot_method(self.request, cancellation)

        if save_tender(self.request):
            self.LOGGER.info(
                "Updated tender cancellation {}".format(cancellation.id),
                extra=context_unpack(self.request, {"MESSAGE_ID": "tender_cancellation_patch"}),
            )
            return {"data": cancellation.serialize("view")}
示例#21
0
    def patch(self):
        criterion = self.request.context
        tender = self.request.validated["tender"]
        apply_patch(self.request, save=False, src=criterion.serialize())

        if self.request.authenticated_role == "tender_owner" and hasattr(tender, "invalidate_bids_data"):
            tender.invalidate_bids_data()

        if save_tender(self.request):
            self.LOGGER.info(
                "Updated tender criterion {}".format(criterion.id),
                extra=context_unpack(self.request, {"MESSAGE_ID": "tender_criterion_patch"}),
            )
            return {"data": criterion.serialize("view")}
 def patch(self):
     """Post a cancellation resolution
     """
     if not self.validate_cancellation('update'):
         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_tender()
     if save_tender(self.request):
         self.LOGGER.info('Updated tender cancellation {}'.format(self.request.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_cancellation_patch'}))
         return {'data': self.request.context.serialize("view")}
示例#23
0
    def collection_post(self):
        """Post a complaint
        """
        tender = self.request.validated["tender"]
        old_rules = get_first_revision_date(tender) < RELEASE_2020_04_19

        complaint = self.request.validated["complaint"]
        complaint.relatedLot = self.context.lotID
        complaint.date = get_now()
        complaint.bid_id = get_bid_id(self.request)
        if complaint.status == "claim" and complaint.type == "claim":
            complaint.dateSubmitted = get_now()
        elif old_rules and complaint.status == "pending":
            complaint.type = "complaint"
            complaint.dateSubmitted = get_now()
        else:
            complaint.status = "draft"
        if (self.context.status == "unsuccessful"
                and complaint.status == "claim"
                and self.context.bidID != complaint.bid_id):
            raise_operation_error(
                self.request,
                "Can add claim only on unsuccessful qualification of your bid")
        complaint.complaintID = "{}.{}{}".format(
            tender.tenderID,
            self.server_id,
            calculate_total_complaints(tender) + 1,
        )
        access = set_ownership(complaint, self.request)
        self.context.complaints.append(complaint)
        if save_tender(self.request):
            self.LOGGER.info(
                "Created tender qualification complaint {}".format(
                    complaint.id),
                extra=context_unpack(
                    self.request,
                    {"MESSAGE_ID": "tender_qualification_complaint_create"},
                    {"complaint_id": complaint.id},
                ),
            )
            self.request.response.status = 201
            self.request.response.headers["Location"] = self.request.route_url(
                "{}:Tender Qualification Complaints".format(
                    tender.procurementMethodType),
                tender_id=tender.id,
                qualification_id=self.request.validated["qualification_id"],
                complaint_id=complaint["id"],
            )
            return {"data": complaint.serialize("view"), "access": access}
示例#24
0
 def put(self):
     """Tender Contract Document Update"""
     if not self.validate_contract_document("update"):
         return
     document = upload_file(self.request)
     self.request.validated["contract"].documents.append(document)
     if save_tender(self.request):
         self.LOGGER.info(
             "Updated tender contract document {}".format(
                 self.request.context.id),
             extra=context_unpack(
                 self.request,
                 {"MESSAGE_ID": "tender_contract_document_put"}),
         )
         return {"data": document.serialize("view")}
示例#25
0
 def put(self):
     """Tender Document Update"""
     if not self.validate_update_tender():
         raise error_handler(self.request.errors)
     document = upload_file(self.request)
     self.request.validated['tender'].documents.append(document)
     if self.request.authenticated_role == 'tender_owner' and self.request.validated[
             'tender_status'] == 'active.tendering':
         self.request.validated['tender'].invalidate_bids_data()
     if save_tender(self.request):
         self.LOGGER.info(
             'Updated tender document {}'.format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {'MESSAGE_ID': 'tender_document_put'}))
         return {'data': document.serialize("view")}
示例#26
0
 def put(self):
     """Tender Document Update"""
     document = upload_file(self.request)
     tender = self.request.validated["tender"]
     tender.documents.append(document)
     status = self.request.validated["tender_status"]
     if self.request.authenticated_role == "tender_owner" and status == "active.tendering":
         tender.invalidate_bids_data()
     if save_tender(self.request):
         self.LOGGER.info(
             "Updated tender document {}".format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {"MESSAGE_ID": "tender_document_put"}),
         )
         return {"data": document.serialize("view")}
    def patch(self):
        tender = self.request.validated['tender']

        set_ownership(tender)
        if save_tender(self.request):
            self.LOGGER.info(
                'Generate Tender stage2 credentials {}'.format(tender.id),
                extra=context_unpack(self.request,
                                     {'MESSAGE_ID': 'tender_patch'}))
            return {
                'data': tender.serialize("view"),
                'access': {
                    'token': tender.owner_token
                }
            }
 def patch(self):
     """Post a cancellation resolution
     """
     tender = self.request.validated['tender']
     apply_patch(self.request,
                 save=False,
                 src=self.request.context.serialize())
     if self.request.context.status == 'active':
         tender.status = 'cancelled'
     if save_tender(self.request):
         self.LOGGER.info('Updated tender cancellation {}'.format(
             self.request.context.id),
                          extra=context_unpack(
                              self.request,
                              {'MESSAGE_ID': 'tender_cancellation_patch'}))
         return {'data': self.request.context.serialize("view")}
示例#29
0
 def patch(self):
     """
     Update of contract
     """
     apply_patch(self.request,
                 save=False,
                 src=self.request.context.serialize())
     if self.request.context.status == "active" and not self.request.context.dateSigned:
         self.request.context.dateSigned = get_now()
     self.check_tender_status_method(self.request)
     if save_tender(self.request):
         self.LOGGER.info(
             "Updated tender contract {}".format(self.request.context.id),
             extra=context_unpack(self.request,
                                  {"MESSAGE_ID": "tender_contract_patch"}),
         )
         return {"data": self.request.context.serialize()}
示例#30
0
 def collection_post(self):
     """Add a lot
     """
     tender = self.request.validated["tender"]
     lot = self.request.validated["lot"]
     lot.date = get_now()
     tender.lots.append(lot)
     if save_tender(self.request):
         self.LOGGER.info(
             "Created tender lot {}".format(lot.id),
             extra=context_unpack(self.request, {"MESSAGE_ID": "tender_lot_create"}, {"lot_id": lot.id}),
         )
         self.request.response.status = 201
         self.request.response.headers["Location"] = self.request.route_url(
             "{}:Tender Lots".format(tender.procurementMethodType), tender_id=tender.id, lot_id=lot.id
         )
         return {"data": lot.serialize("view")}
示例#31
0
    def put(self):
        old_requirement = self.request.context
        requirement = old_requirement
        if self.request.validated["data"].get("status") != "cancelled":
            model = type(old_requirement)
            data = copy(self.request.validated["data"])
            for attr_name in type(old_requirement)._fields:
                if data.get(attr_name) is None:
                    data[attr_name] = getattr(old_requirement, attr_name)
            # To avoid new version creation if no changes and only id's were regenerated
            if "eligibleEvidences" not in self.request.json.get("data", {}):
                data["eligibleEvidences"] = [
                    evidence.to_primitive(role="create") for evidence in
                    getattr(old_requirement, "eligibleEvidences")
                ]

            requirement = model(data)
            if old_requirement.to_primitive() == requirement.to_primitive():
                return {"data": (old_requirement.serialize("view"), )}

            requirement.datePublished = get_now()
            requirement.dateModified = None
            self.request.validated["requirement_group"].requirements.append(
                requirement)

        if old_requirement.status == "active":
            old_requirement.status = "cancelled"
            old_requirement.dateModified = get_now()

        tender = self.request.validated["tender"]
        if (self.request.authenticated_role == "tender_owner"
                and tender.status == "active.tendering"
                and hasattr(tender, "invalidate_bids_data")):
            tender.invalidate_bids_data()

        if save_tender(self.request):
            self.LOGGER.info(
                "New version of requirement {}".format(requirement.id),
                extra=context_unpack(
                    self.request,
                    {"MESSAGE_ID": "requirement_group_requirement_put"}),
            )
            return {
                "data": (requirement.serialize("view"),
                         old_requirement.serialize("view_old"))
            }
示例#32
0
 def post(self):
     """Report auction results for lot.
     """
     apply_patch(self.request, save=False, src=self.request.validated["tender_src"])
     if all(
         [
             i.auctionPeriod and i.auctionPeriod.endDate
             for i in self.request.validated["tender"].lots
             if i.numberOfBids > 1 and i.status == "active"
         ]
     ):
         add_next_award(self.request)
     if save_tender(self.request):
         self.LOGGER.info(
             "Report auction results", extra=context_unpack(self.request, {"MESSAGE_ID": "tender_lot_auction_post"})
         )
         return {"data": self.request.validated["tender"].serialize(self.request.validated["tender"].status)}
示例#33
0
    def patch(self):
        tender = self.request.validated["tender"]
        award = self.request.context
        is_awarded = [
            a for a in tender.awards
            if a.bid_id == award.bid_id and a.id != award.id
        ]
        award_status = award.status
        apply_patch(self.request, save=False, src=self.request.context.serialize())

        now = get_now()
        if is_awarded and award.status not in ('unsuccessful', 'pending'):
            raise_operation_error(
                self.request,
                "Can't change award status to {} from {}".format(award.status, award_status)
            )

        if award_status == "pending" and award.status == "active":
            add_contracts(self.request, award, now)
            add_next_award(self.request)
        elif award_status == "active" and award.status == "cancelled":
            for i in tender.contracts:
                if i.awardID == award.id:
                    i.status = "cancelled"
            add_next_award(self.request)
        elif award_status == "pending" and award.status == "unsuccessful":
            if is_awarded:
                tender.status = 'unsuccessful'
            else:
                add_next_award(self.request)
        elif self.request.authenticated_role != "Administrator" and not (
            award_status == "pending" and award.status == "pending"
        ):
            raise_operation_error(
                self.request,
                "Can't update award in current ({}) status".format(award_status)
            )
        if save_tender(self.request):
            self.LOGGER.info(
                "Updated tender award {}".format(self.request.context.id),
                extra=context_unpack(
                    self.request,
                    {"MESSAGE_ID": "tender_award_patch"}
                ),
            )
            return {"data": award.serialize("view")}
def stage2_bid_post(self):
    tender = self.request.validated['tender']
    bid = self.request.validated['bid']
    # TODO can't move validator because of self.allowed_bid_status_on_create
    if bid.status not in self.allowed_bid_status_on_create:
        raise_operation_error(self.request, 'Bid can be added only with status: {}.'.format(self.allowed_bid_status_on_create))
    tender.modified = False
    api_set_ownership(bid, self.request)
    tender.bids.append(bid)
    if save_tender(self.request):
        self.LOGGER.info('Created tender bid {}'.format(bid.id),
                         extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_bid_create'},
                                              {'bid_id': bid.id}))
        self.request.response.status = 201
        self.request.response.headers['Location'] = self.request.route_url('{}:Tender Bids'.format(tender.procurementMethodType), tender_id=tender.id,
                                                                           bid_id=bid['id'])
        return {
            'data': bid.serialize('view'),
            'access': {
                'token': bid.owner_token
            }
        }
    def patch(self):
        """Tender Edit (partial)

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

        .. sourcecode:: http

            PATCH /tenders/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",
                    "tenderID": "UA-64e93250be76435397e8c992ed4214d1",
                    "dateModified": "2014-10-27T08:12:34.956Z",
                    "value": {
                        "amount": 600
                    },
                    "itemsToBeProcured": [
                        {
                            "quantity": 6
                        }
                    ]
                }
            }

        """
        tender = self.context
        data = self.request.validated['data']

        if self.request.authenticated_role == 'tender_owner' and \
                self.request.validated['tender_status'] in ['active.tendering', STAGE2_STATUS]:
            if 'tenderPeriod' in data and 'endDate' in data['tenderPeriod']:
                self.request.validated['tender'].tenderPeriod.import_data(data['tenderPeriod'])
                validate_tender_period_extension(self.request)
                self.request.registry.notify(TenderInitializeEvent(self.request.validated['tender']))
                self.request.validated['data']["enquiryPeriod"] = self.request.validated['tender'].enquiryPeriod.serialize()

        apply_patch(self.request, save=False, src=self.request.validated['tender_src'])
        if self.request.authenticated_role == 'chronograph':
            check_status_ua(self.request)
        elif self.request.authenticated_role == 'tender_owner' and tender.status == 'active.tendering':
            # invalidate bids on tender change
            tender.invalidate_bids_data()
        save_tender(self.request)
        self.LOGGER.info('Updated tender {}'.format(tender.id),
                         extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_patch'}))
        return {'data': tender.serialize(tender.status)}
def patch_eu(self):
    """Tender Edit (partial)

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

            .. sourcecode:: http

                PATCH /tenders/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",
                        "tenderID": "UA-64e93250be76435397e8c992ed4214d1",
                        "dateModified": "2014-10-27T08:12:34.956Z",
                        "value": {
                            "amount": 600
                        },
                        "itemsToBeProcured": [
                            {
                                "quantity": 6
                            }
                        ]
                    }
                }

            """
    tender = self.context
    data = self.request.validated['data']
    if self.request.authenticated_role == 'tender_owner' \
            and self.request.validated['tender_status'] == 'active.tendering':
        if 'tenderPeriod' in data and 'endDate' in data['tenderPeriod']:
            self.request.validated['tender'].tenderPeriod.import_data(data['tenderPeriod'])
            validate_tender_period_extension(self.request)
            self.request.registry.notify(TenderInitializeEvent(self.request.validated['tender']))
            self.request.validated['data']["enquiryPeriod"] = self.request.validated[
                'tender'].enquiryPeriod.serialize()

    apply_patch(self.request, save=False, src=self.request.validated['tender_src'])
    if self.request.authenticated_role == 'chronograph':
        check_status(self.request)
    elif self.request.authenticated_role == 'tender_owner' and tender.status == 'active.tendering':
        tender.invalidate_bids_data()
    elif self.request.authenticated_role == 'tender_owner' and \
            self.request.validated['tender_status'] == 'active.pre-qualification' and \
            tender.status == "active.pre-qualification.stand-still":
        if all_bids_are_reviewed(self.request):
            tender.qualificationPeriod.endDate = calculate_business_date(get_now(), COMPLAINT_STAND_STILL,
                                                                         self.request.validated['tender'])
            tender.check_auction_time()
        else:
            raise_operation_error(self.request, 'Can\'t switch to \'active.pre-qualification.stand-still\' while not all bids are qualified')
    elif self.request.authenticated_role == 'tender_owner' and \
            self.request.validated['tender_status'] == 'active.pre-qualification' and \
            tender.status != "active.pre-qualification.stand-still":
        raise_operation_error(self.request, 'Can\'t update tender status')

    save_tender(self.request)
    self.LOGGER.info('Updated tender {}'.format(tender.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_patch'}))
    return {'data': tender.serialize(tender.status)}
 def patch(self):
     """Post a complaint resolution
     """
     tender = self.request.validated['tender']
     data = self.request.validated['data']
     # complaint_owner
     if self.request.authenticated_role == 'complaint_owner' and self.context.status in ['draft', 'claim', 'answered'] 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 self.context.status in ['pending', 'accepted'] and data.get('status', self.context.status) == 'stopping':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateCanceled = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and tender.status == '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 tender.status == 'active.tendering' and self.context.status == 'draft' and data.get('status', self.context.status) == 'claim':
         if get_now() > calculate_business_date(tender.tenderPeriod.endDate, -CLAIM_SUBMIT_TIME, tender, True):
             raise_operation_error(self.request, 'Can submit claim not later than {0.days} days before tenderPeriod end'.format(CLAIM_SUBMIT_TIME))
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateSubmitted = get_now()
     elif self.request.authenticated_role == 'complaint_owner' and tender.status == 'active.tendering' and self.context.status in ['draft', 'claim'] and data.get('status', self.context.status) == 'pending':
         if get_now() > tender.complaintPeriod.endDate:
             raise_operation_error(self.request, 'Can submit complaint not later than {0.days} days before tenderPeriod end'.format(COMPLAINT_SUBMIT_TIME))
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.type = 'complaint'
         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':
         if get_now() > tender.complaintPeriod.endDate:
             raise_operation_error(self.request, 'Can submit complaint not later than {0.days} days before tenderPeriod end'.format(COMPLAINT_SUBMIT_TIME))
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.type = 'complaint'
         self.context.dateEscalated = get_now()
     # tender_owner
     elif self.request.authenticated_role == 'tender_owner' and self.context.status == 'claim' and data.get('status', self.context.status) == self.context.status:
         now = get_now()
         if now > tender.enquiryPeriod.clarificationsUntil:
             raise_operation_error(self.request, 'Can update claim only before enquiryPeriod.clarificationsUntil')
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'tender_owner' and self.context.status == 'satisfied' 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 == 'tender_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':
         now = get_now()
         if now > tender.enquiryPeriod.clarificationsUntil:
             raise_operation_error(self.request, 'Can update claim only before enquiryPeriod.clarificationsUntil')
         if len(data.get('resolution', self.context.resolution)) < 20:
             raise_operation_error(self.request, 'Can\'t update complaint: resolution too short')
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateAnswered = get_now()
     elif self.request.authenticated_role == 'tender_owner' and self.context.status in ['pending', 'accepted']:
         apply_patch(self.request, save=False, src=self.context.serialize())
     elif self.request.authenticated_role == 'tender_owner' and self.context.status == 'satisfied' and data.get('tendererAction', self.context.tendererAction) and data.get('status', self.context.status) == 'resolved':
         apply_patch(self.request, save=False, src=self.context.serialize())
     # aboveThresholdReviewers
     elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status in ['pending', 'accepted', 'stopping'] 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 == 'aboveThresholdReviewers' and self.context.status in ['pending', 'stopping'] and data.get('status', self.context.status) in ['invalid', 'mistaken']:
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateDecision = get_now()
         self.context.acceptance = False
     elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status == 'pending' and data.get('status', self.context.status) == 'accepted':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateAccepted = get_now()
         self.context.acceptance = True
     elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status in ['accepted', 'stopping'] and data.get('status', self.context.status) in ['declined', 'satisfied']:
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateDecision = get_now()
     elif self.request.authenticated_role == 'aboveThresholdReviewers' and self.context.status in ['pending', 'accepted', 'stopping'] and data.get('status', self.context.status) == 'stopped':
         apply_patch(self.request, save=False, src=self.context.serialize())
         self.context.dateDecision = get_now()
         self.context.dateCanceled = self.context.dateCanceled or get_now()
     else:
         raise_operation_error(self.request, 'Can\'t update complaint')
     if self.context.tendererAction and not self.context.tendererActionDate:
         self.context.tendererActionDate = get_now()
     if self.context.status not in ['draft', 'claim', 'answered', 'pending', 'accepted', 'stopping'] and tender.status in ['active.qualification', 'active.awarded']:
         check_tender_status(self.request)
     if save_tender(self.request):
         self.LOGGER.info('Updated tender complaint {}'.format(self.context.id),
                     extra=context_unpack(self.request, {'MESSAGE_ID': 'tender_complaint_patch'}))
         return {'data': self.context.serialize("view")}